From bae91c9945c7b98b5221e18a6e346a2959b2d8f6 Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Thu, 16 Jan 2020 13:31:10 -0300 Subject: [PATCH] Patch rn-fetch-blob with CBA support (#3816) --- ios/Podfile.lock | 4 +- package-lock.json | 5 +- package.json | 2 +- patches/rn-fetch-blob+0.12.0.patch | 7593 ++++++++++++++++++++++++++++ 4 files changed, 7599 insertions(+), 5 deletions(-) create mode 100644 patches/rn-fetch-blob+0.12.0.patch diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 5e1ffed32..9724437ad 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -266,7 +266,7 @@ PODS: - React - ReactNativePermissions (1.1.1): - React - - rn-fetch-blob (0.10.6): + - rn-fetch-blob (0.12.0): - React-Core - RNCAsyncStorage (1.6.2): - React @@ -532,7 +532,7 @@ SPEC CHECKSUMS: ReactNativeExceptionHandler: 8025d98049c25f186835a3af732dd7c9974d6dce ReactNativeNavigation: aad255980f20cc5d2001ed37972319f3789fea70 ReactNativePermissions: 2e324bb3baf12702e3ec27f76c8ae1158fa69fc6 - rn-fetch-blob: 3258c6483235bb7daf16cf921306ffb18406071f + rn-fetch-blob: 17961aec08caae68bb8fc0e5b40f93b3acfa6932 RNCAsyncStorage: 5ae4d57458804e99f73d427214442a6b10a53856 RNDeviceInfo: fd8296de6fca8b743cdc499b896f48e8a9f1faf5 RNFastImage: 9b0c22643872bb7494c8d87bbbb66cc4c0d9e7a2 diff --git a/package-lock.json b/package-lock.json index 071880f07..6db85224b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10785,8 +10785,9 @@ } }, "rn-fetch-blob": { - "version": "github:mattermost/react-native-fetch-blob#1df88c681a4f4096693adf287ea2f78b94f5eb7c", - "from": "github:mattermost/react-native-fetch-blob#1df88c681a4f4096693adf287ea2f78b94f5eb7c", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/rn-fetch-blob/-/rn-fetch-blob-0.12.0.tgz", + "integrity": "sha512-+QnR7AsJ14zqpVVUbzbtAjq0iI8c9tCg49tIoKO2ezjzRunN7YL6zFSFSWZm6d+mE/l9r+OeDM3jmb2tBb2WbA==", "requires": { "base-64": "0.1.0", "glob": "7.0.6" diff --git a/package.json b/package.json index 13edfc910..df11359ae 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "redux-persist-transform-filter": "0.0.20", "redux-thunk": "2.3.0", "reselect": "4.0.0", - "rn-fetch-blob": "github:mattermost/react-native-fetch-blob#1df88c681a4f4096693adf287ea2f78b94f5eb7c", + "rn-fetch-blob": "0.12.0", "rn-placeholder": "github:mattermost/rn-placeholder#02c629c65d0123a2eee623ada0fd17186415d3c3", "semver": "6.3.0", "shallow-equals": "1.0.0", diff --git a/patches/rn-fetch-blob+0.12.0.patch b/patches/rn-fetch-blob+0.12.0.patch new file mode 100644 index 000000000..12a04b68b --- /dev/null +++ b/patches/rn-fetch-blob+0.12.0.patch @@ -0,0 +1,7593 @@ +diff --git a/node_modules/rn-fetch-blob/android/build.gradle b/node_modules/rn-fetch-blob/android/build.gradle +index a4ca7a4..f3cd184 100644 +--- a/node_modules/rn-fetch-blob/android/build.gradle ++++ b/node_modules/rn-fetch-blob/android/build.gradle +@@ -37,10 +37,13 @@ android { + } + productFlavors { + } ++ compileOptions { ++ sourceCompatibility 1.8 ++ targetCompatibility 1.8 ++ } + } + + dependencies { + implementation "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}" +- //compile 'com.squareup.okhttp3:okhttp:+' +- //{RNFetchBlob_PRE_0.28_DEPDENDENCY} ++ implementation "com.squareup.okhttp3:okhttp:3.13.1" + } +diff --git a/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlob.java b/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlob.java +index 602d51d..78b7929 100644 +--- a/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlob.java ++++ b/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlob.java +@@ -179,6 +179,11 @@ public class RNFetchBlob extends ReactContextBaseJavaModule { + RNFetchBlobFS.exists(path, callback); + } + ++ @ReactMethod ++ public void existsWithDiffExt(String path, Callback callback) { ++ RNFetchBlobFS.existsWithDiffExt(path, callback); ++ } ++ + @ReactMethod + public void cp(final String path, final String dest, final Callback callback) { + threadPool.execute(new Runnable() { +diff --git a/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlobBody.java b/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlobBody.java +index adbe48b..b87d383 100644 +--- a/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlobBody.java ++++ b/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlobBody.java +@@ -195,8 +195,8 @@ class RNFetchBlobBody extends RequestBody{ + ReactApplicationContext ctx = RNFetchBlob.RCTContext; + + for(FormField field : fields) { +- String data = field.data; +- String name = field.name; ++ String data = field.data.trim(); ++ String name = field.name.trim(); + // skip invalid fields + if(name == null || data == null) + continue; +@@ -256,8 +256,7 @@ class RNFetchBlobBody extends RequestBody{ + } + // data field + else { +- header += "Content-Disposition: form-data; name=\"" + name + "\"\r\n"; +- header += "Content-Type: " + field.mime + "\r\n\r\n"; ++ header += "Content-Disposition: form-data; name=\"" + name + "\"\r\n\r\n"; + os.write(header.getBytes()); + byte[] fieldData = field.data.getBytes(); + os.write(fieldData); +diff --git a/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java b/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java +index a4d7015..f430865 100644 +--- a/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java ++++ b/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java +@@ -29,6 +29,7 @@ import java.util.ArrayList; + import java.util.HashMap; + import java.util.Map; + import java.util.UUID; ++import java.util.regex.Pattern; + + class RNFetchBlobFS { + +@@ -677,6 +678,46 @@ class RNFetchBlobFS { + } + } + ++ /** ++ * Check if the file exists with a different extension and, if so, ++ * return the file path. ++ * @param path Path to check ++ * @param callback JS context callback ++ */ ++ static void existsWithDiffExt(String path, Callback callback) { ++ File file = new File(path); ++ String parent = file.getParent(); ++ if (parent == null) { ++ callback.invoke(""); ++ return; ++ } ++ ++ File directory = new File(parent); ++ if (!directory.exists()) { ++ callback.invoke(""); ++ return; ++ } ++ ++ String filename = file.getName(); ++ int extIndex = filename.lastIndexOf("."); ++ filename = extIndex == -1 ? filename : filename.substring(0, extIndex); ++ ++ final Pattern p = Pattern.compile(filename + "\\.[a-z]{3,4}"); ++ File[] files = directory.listFiles(new FileFilter() { ++ @Override ++ public boolean accept(File file) { ++ return p.matcher(file.getName()).matches(); ++ } ++ }); ++ ++ String filePath = ""; ++ if (files != null && files.length != 0) { ++ filePath = files[0].getAbsolutePath(); ++ } ++ ++ callback.invoke(filePath); ++ } ++ + /** + * List content of folder + * @param path Target folder +diff --git a/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java b/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java +index a8abd71..7bcd052 100644 +--- a/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java ++++ b/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java +@@ -407,6 +407,7 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable { + extended = new RNFetchBlobFileResp( + RNFetchBlob.RCTContext, + taskId, ++ originalResponse.headers(), + originalResponse.body(), + destPath, + options.overwrite); +@@ -556,16 +557,13 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable { + return; + } + try { +- encoder.encode(ByteBuffer.wrap(b).asCharBuffer()); +- // if the data contains invalid characters the following lines will be +- // skipped. ++ // Trying to decode the response directly as UTF-8. + String utf8 = new String(b); + callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_UTF8, utf8); + } +- // This usually mean the data is contains invalid unicode characters but still valid data, +- // it's binary data, so send it as a normal string +- catch(CharacterCodingException ignored) { +- ++ // This usually mean the data is contains invalid unicode characters, it's ++ // binary data ++ catch(Exception ignored) { + if(responseFormat == ResponseFormat.UTF8) { + String utf8 = new String(b); + callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_UTF8, utf8); +diff --git a/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/Response/RNFetchBlobFileResp.java b/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/Response/RNFetchBlobFileResp.java +index 2470eef..d46be3f 100644 +--- a/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/Response/RNFetchBlobFileResp.java ++++ b/node_modules/rn-fetch-blob/android/src/main/java/com/RNFetchBlob/Response/RNFetchBlobFileResp.java +@@ -14,6 +14,7 @@ import java.io.File; + import java.io.FileOutputStream; + import java.io.IOException; + ++import okhttp3.Headers; + import okhttp3.MediaType; + import okhttp3.ResponseBody; + import okio.Buffer; +@@ -28,6 +29,7 @@ import okio.Timeout; + public class RNFetchBlobFileResp extends ResponseBody { + + String mTaskId; ++ Headers headers; + ResponseBody originalBody; + String mPath; + long bytesDownloaded = 0; +@@ -35,10 +37,11 @@ public class RNFetchBlobFileResp extends ResponseBody { + FileOutputStream ofStream; + boolean isEndMarkerReceived; + +- public RNFetchBlobFileResp(ReactApplicationContext ctx, String taskId, ResponseBody body, String path, boolean overwrite) throws IOException { ++ public RNFetchBlobFileResp(ReactApplicationContext ctx, String taskId, Headers headers, ResponseBody body, String path, boolean overwrite) throws IOException { + super(); + this.rctContext = ctx; + this.mTaskId = taskId; ++ this.headers = headers; + this.originalBody = body; + assert path != null; + this.mPath = path; +@@ -94,6 +97,14 @@ public class RNFetchBlobFileResp extends ResponseBody { + // End marker has been received for chunked download + isEndMarkerReceived = true; + } ++ ++ long expectedBytes = contentLength(); ++ String uncompressedLength = headers.get("X-Uncompressed-Content-Length"); ++ ++ if (uncompressedLength != null && uncompressedLength.length() > 0) { ++ expectedBytes = Long.parseLong(uncompressedLength); ++ } ++ + RNFetchBlobProgressConfig reportConfig = RNFetchBlobReq.getReportProgress(mTaskId); + + if (contentLength() != 0) { +diff --git a/node_modules/rn-fetch-blob/cba/index.js b/node_modules/rn-fetch-blob/cba/index.js +new file mode 100644 +index 0000000..f3730ac +--- /dev/null ++++ b/node_modules/rn-fetch-blob/cba/index.js +@@ -0,0 +1,7 @@ ++import {NativeModules} from 'react-native' ++ ++const RNFetchBlob = NativeModules.RNFetchBlob ++ ++export default { ++ selectCertificate: RNFetchBlob.selectCertificate ++} +diff --git a/node_modules/rn-fetch-blob/fs.js b/node_modules/rn-fetch-blob/fs.js +index 77bbe7a..c0292ec 100644 +--- a/node_modules/rn-fetch-blob/fs.js ++++ b/node_modules/rn-fetch-blob/fs.js +@@ -348,6 +348,27 @@ function exists(path: string): Promise { + + } + ++/** ++ * Check if the file exists with a different extension. ++ * @param {string} path Path to check ++ * @return {Promise} ++ */ ++function existsWithDiffExt(path: string): Promise { ++ return new Promise((resolve, reject) => { ++ if (typeof path !== 'string') { ++ return reject(addCode('EINVAL', new TypeError('Missing argument "path" '))) ++ } ++ try { ++ RNFetchBlob.existsWithDiffExt(path, (fileWithExt) => { ++ resolve(fileWithExt) ++ }) ++ }catch (err){ ++ reject(addCode('EUNSPECIFIED', new Error(err))) ++ } ++ }) ++ ++} ++ + function slice(src: string, dest: string, start: number, end: number): Promise { + if (typeof src !== 'string' || typeof dest !== 'string') { + return reject(addCode('EINVAL', new TypeError('Missing argument "src" and/or "destination"'))) +@@ -419,6 +440,7 @@ export default { + readFile, + hash, + exists, ++ existsWithDiffExt, + createFile, + isDir, + stat, +@@ -427,5 +449,5 @@ export default { + dirs, + slice, + asset, +- df ++ df, + } +diff --git a/node_modules/rn-fetch-blob/index.js b/node_modules/rn-fetch-blob/index.js +index 8ab5e96..66b0b60 100644 +--- a/node_modules/rn-fetch-blob/index.js ++++ b/node_modules/rn-fetch-blob/index.js +@@ -25,6 +25,8 @@ import _ from 'lodash' + import android from './android' + import ios from './ios' + import JSONStream from './json-stream' ++import cba from './cba'; ++ + const { + RNFetchBlobSession, + readStream, +@@ -574,5 +576,6 @@ export default { + fs, + wrap, + polyfill, +- JSONStream ++ JSONStream, ++ cba, + } +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer.storyboard b/node_modules/rn-fetch-blob/ios/KeyShareConsumer.storyboard +new file mode 100644 +index 0000000..19e70b9 +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer.storyboard +@@ -0,0 +1,74 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/CBAViewController.h b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/CBAViewController.h +new file mode 100644 +index 0000000..09017a1 +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/CBAViewController.h +@@ -0,0 +1,39 @@ ++// ++// ViewController.h ++// KeyShareConsumer ++ ++#import ++#import "KeyChainDataSource.h" ++#import ++ ++@interface CBAViewController : UIViewController ++{ ++ //provides information about key chain contents ++ KeyChainDataSource* keyChain; ++ ++ //table view to display summary of key chain contents ++ IBOutlet UITableView* tableViewKeyChain; ++ ++ //string to receive password entered by user ++ NSString* passwordFromUser; ++ ++ //buffer to receive PKCS12 file read from iCloud ++ NSData* pkcs12Data; ++} ++ ++//Callbacks used by KeyDetailViewController for iTunes file sharing ++- (void)import:(int)index; ++- (void)dismissWithoutImporting:(int)index; ++- (void)setCallback:(RCTResponseSenderBlock)callback; ++ ++//Button click handlers ++- (IBAction)openImportDocumentPicker:(id)sender; ++- (IBAction)close:(id)sender; ++ ++@property (nonatomic, retain) UITableView *tableViewKeyChain; ++@property (nonatomic, retain) KeyChainDataSource *keyChain; ++@property (nonatomic, strong) NSMutableArray *composeCallbacks; ++@property (nonatomic, assign) int imageWidth; ++ ++@end ++ +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/CBAViewController.m b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/CBAViewController.m +new file mode 100644 +index 0000000..102d2d6 +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/CBAViewController.m +@@ -0,0 +1,459 @@ ++// ++// ViewController.m ++// KeyShareConsumer ++ ++#import "CBAViewController.h" ++#import ++#import ++#import ++ ++#import "ZipFile.h" ++#import "FileInZipInfo.h" ++#import "ZipReadStream.h" ++ ++@interface CBAViewController () ++@end ++ ++@implementation CBAViewController ++@synthesize tableViewKeyChain; ++@synthesize keyChain; ++ ++//------------------------------------------------------------------------------ ++#pragma mark - View controller functions ++//------------------------------------------------------------------------------ ++- (void)viewDidLoad ++{ ++ [super viewDidLoad]; ++ ++ //Set this class as the table delegate ++ [tableViewKeyChain setDelegate:self]; ++ ++ //Create a key chain data source object targeting identities ++ keyChain = [[KeyChainDataSource alloc] initWithMode:KSM_Identities]; ++ ++ //load the key chain to serve as backend for the table view ++ [keyChain LoadKeyChainContents]; ++} ++ ++- (void)setCallback:(RCTResponseSenderBlock)callback { ++ if (_composeCallbacks == nil) { ++ _composeCallbacks = [[NSMutableArray alloc] init]; ++ } ++ ++ [_composeCallbacks addObject:callback]; ++} ++ ++- (RCTResponseSenderBlock)getCallback { ++ RCTResponseSenderBlock callback = [_composeCallbacks lastObject]; ++ [_composeCallbacks removeLastObject]; ++ return callback; ++} ++ ++- (void)didReceiveMemoryWarning ++{ ++ [super didReceiveMemoryWarning]; ++ // Dispose of any resources that can be recreated. ++} ++ ++//------------------------------------------------------------------------------ ++#pragma mark - Button click handlers ++//------------------------------------------------------------------------------ ++- (IBAction)openImportDocumentPicker:(id)sender ++{ ++ //Clear the pasteboard, since a password may be provided via that mechanism ++ UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; ++ [pasteboard setString:@""]; ++ passwordFromUser = @""; ++ ++ NSUserDefaults* standardDefaults = [NSUserDefaults standardUserDefaults]; ++ [standardDefaults synchronize]; ++ ++ NSMutableArray* utis = [[NSMutableArray alloc]init]; ++ ++ if([standardDefaults boolForKey:@"toggle_com_rsa_pkcs12"]) ++ [utis addObject:@"com.rsa.pkcs-12"]; ++ if([standardDefaults boolForKey:@"toggle_purebred_select_all"]) ++ [utis addObject:@"purebred.select.all"]; ++ if([standardDefaults boolForKey:@"toggle_purebred_select_all_user"]) ++ [utis addObject:@"purebred.select.all_user"]; ++ if([standardDefaults boolForKey:@"toggle_purebred_select_signature"]) ++ [utis addObject:@"purebred.select.signature"]; ++ if([standardDefaults boolForKey:@"toggle_purebred_select_encryption"]) ++ [utis addObject:@"purebred.select.encryption"]; ++ if([standardDefaults boolForKey:@"toggle_purebred_select_authentication"]) ++ [utis addObject:@"purebred.select.authentication"]; ++ if([standardDefaults boolForKey:@"toggle_purebred_select_device"]) ++ [utis addObject:@"purebred.select.device"]; ++ if([standardDefaults boolForKey:@"toggle_purebred_select_no_filter"]) ++ [utis addObject:@"purebred.select.no_filter"]; ++ if([standardDefaults boolForKey:@"toggle_purebred_zip_all"]) ++ [utis addObject:@"purebred.zip.all"]; ++ if([standardDefaults boolForKey:@"toggle_purebred_zip_all_user"]) ++ [utis addObject:@"purebred.zip.all_user"]; ++ if([standardDefaults boolForKey:@"toggle_purebred_zip_signature"]) ++ [utis addObject:@"purebred.zip.signature"]; ++ if([standardDefaults boolForKey:@"toggle_purebred_zip_encryption"]) ++ [utis addObject:@"purebred.zip.encryption"]; ++ if([standardDefaults boolForKey:@"toggle_purebred_zip_authentication"]) ++ [utis addObject:@"purebred.zip.authentication"]; ++ if([standardDefaults boolForKey:@"toggle_purebred_zip_device"]) ++ [utis addObject:@"purebred.zip.device"]; ++ if([standardDefaults boolForKey:@"toggle_purebred_zip_no_filter"]) ++ [utis addObject:@"purebred.zip.no_filter"]; ++ ++ if(0 == [utis count]) ++ [utis addObject:@"com.rsa.pkcs-12"]; ++ ++ //Display the UIDocumentPickerViewController to enable the user to select a key to import. Purebred Registration only works with UIDocumentPickerModeOpen mode. ++ UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:utis inMode:UIDocumentPickerModeOpen]; ++ documentPicker.delegate = self; ++ documentPicker.modalPresentationStyle = UIModalPresentationFormSheet; ++ [self presentViewController:documentPicker animated:YES completion:nil]; ++} ++ ++- (IBAction)close:(id)sender ++{ ++ [self getCallback](@[[NSNull null]]); ++ [self dismissViewControllerAnimated:@YES completion:nil]; ++} ++ ++//------------------------------------------------------------------------------ ++#pragma mark - UIDocumentPickerViewController delegate functions ++//------------------------------------------------------------------------------ ++- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller ++{ ++ NSLog(@"Cancelled"); ++} ++ ++- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url { ++ if(controller.documentPickerMode == UIDocumentPickerModeOpen) ++ { ++ BOOL startAccessingWorked = [url startAccessingSecurityScopedResource]; ++ NSURL *ubiquityURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; ++ NSLog(@"ubiquityURL %@",ubiquityURL); ++ NSLog(@"start %d",startAccessingWorked); ++ ++ NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init]; ++ NSError *error; ++ [fileCoordinator coordinateReadingItemAtURL:url options:0 error:&error byAccessor:^(NSURL *newURL) { ++ NSData *data = [NSData dataWithContentsOfURL:newURL]; ++ ++ NSLog(@"error %@",error); ++ NSLog(@"data %@",data); ++ if(nil == data) ++ return; ++ ++ // Read the password from the pasteboard ++ UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; ++ NSString* pw = [pasteboard string]; ++ ++ if(nil != pw && 0 != [pw length]) ++ { ++ passwordFromUser = pw; ++ } ++ ++ pkcs12Data = data; ++ }]; ++ [url stopAccessingSecurityScopedResource]; ++ ++ if(nil == passwordFromUser || 0 == [passwordFromUser length]) ++ { ++ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Enter Password" message:@"Please enter the password for the selected PKCS #12 file" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles: @"OK", nil]; ++ alert.alertViewStyle = UIAlertViewStyleSecureTextInput; ++ [alert show]; ++ } ++ else{ ++ [self importP12:pkcs12Data password:passwordFromUser]; ++ } ++ } ++} ++ ++//------------------------------------------------------------------------------ ++#pragma mark - Table view data source ++//------------------------------------------------------------------------------ ++- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView ++{ ++ return 1; ++} ++ ++- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section ++{ ++ //The KeyChainDataSource is written to supply cells in groups where each group is an identity. ++ //This view is written to list each identity on one row. Thus, return the number of sections ++ //recognized by the data source. ++ return [keyChain numItems]; ++} ++#define FONT_SIZE 14.0f ++#define CELL_CONTENT_MARGIN 10.0f ++ ++- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; ++{ ++ NSString *text = [keyChain GetIdentityNameAtIndex:indexPath.row]; ++ ++ CGRect frameRect = [tableView frame]; ++ CGSize constraint = CGSizeMake(frameRect.size.width - (CELL_CONTENT_MARGIN * 2), 20000.0f); ++ ++ CGSize size = [text boundingRectWithSize:constraint ++ options:NSStringDrawingUsesLineFragmentOrigin ++ attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:FONT_SIZE]} ++ context:nil].size; ++ ++ CGFloat height = MAX(size.height, 44.0f); ++ ++ return height + (CELL_CONTENT_MARGIN * 2); ++} ++ ++- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath ++{ ++ static NSString *CellIdentifier = @"Cell"; ++ ++ UILabel* label = nil; ++ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; ++ if (cell == nil) ++ { ++ cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ; ++ ++ label = [[UILabel alloc] initWithFrame:CGRectZero] ; ++ [label setLineBreakMode:NSLineBreakByCharWrapping]; ++ [label setMinimumScaleFactor:FONT_SIZE]; ++ [label setNumberOfLines:0]; ++ [label setFont:[UIFont systemFontOfSize:FONT_SIZE]]; ++ [label setTag:1]; ++ ++ [[cell contentView] addSubview:label]; ++ ++ } ++ NSString *text = [keyChain GetIdentityNameAtIndex:indexPath.row]; ++ ++ CGRect frameRect = [tableView frame]; ++ CGSize constraint = CGSizeMake(frameRect.size.width - (CELL_CONTENT_MARGIN * 2), 20000.0f); ++ ++ CGSize size = [text boundingRectWithSize:constraint ++ options:NSStringDrawingUsesLineFragmentOrigin ++ attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:FONT_SIZE]} ++ context:nil].size; ++ ++ if (!label) ++ label = (UILabel*)[cell viewWithTag:1]; ++ ++ //display the keys icon for each entry in the table ++ UIImage* image = [UIImage imageNamed:@"0155-keys.png"]; ++ if (image != nil) { ++ [cell.imageView setImage:image]; ++ [cell setSeparatorInset:UIEdgeInsetsZero]; ++ } ++ ++ self.imageWidth = 44; ++ ++ [label setText:text]; ++ [label setFrame:CGRectMake((CELL_CONTENT_MARGIN*2) + self.imageWidth, CELL_CONTENT_MARGIN, frameRect.size.width - (CELL_CONTENT_MARGIN * 2) - self.imageWidth, MAX(size.height, 44.0f))]; ++ ++ return cell; ++} ++ ++- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView ++ editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath ++{ ++ return UITableViewCellEditingStyleDelete; ++} ++ ++- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath ++{ ++ // If the table view is asking to commit a delete command... ++ if (editingStyle == UITableViewCellEditingStyleDelete) ++ { ++ // We remove the row being deleted from the source ++ [keyChain removeObjectAtIndex:[indexPath row]]; ++ ++ [tableView reloadData]; ++ } ++} ++ ++//------------------------------------------------------------------------------ ++#pragma mark - Table view delegate ++//------------------------------------------------------------------------------ ++- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath ++{ ++ NSString *identityToUse = [keyChain GetIdentityNameAtIndex:indexPath.row]; ++ [self getCallback](@[identityToUse]); ++ [self dismissViewControllerAnimated:@YES completion:nil]; ++} ++ ++ ++//------------------------------------------------------------------------------ ++#pragma mark - Utility functions ++//------------------------------------------------------------------------------ ++-(void)resetKeychain { ++ [self deleteAllKeysForSecClass:kSecClassGenericPassword]; ++ [self deleteAllKeysForSecClass:kSecClassInternetPassword]; ++ [self deleteAllKeysForSecClass:kSecClassCertificate]; ++ [self deleteAllKeysForSecClass:kSecClassKey]; ++ [self deleteAllKeysForSecClass:kSecClassIdentity]; ++} ++ ++-(void)deleteAllKeysForSecClass:(CFTypeRef)secClass { ++ NSMutableDictionary* dict = [NSMutableDictionary dictionary]; ++ [dict setObject:(__bridge id)secClass forKey:(__bridge id)kSecClass]; ++ OSStatus result = SecItemDelete((__bridge CFDictionaryRef) dict); ++ NSAssert(result == noErr || result == errSecItemNotFound, @"Error deleting keychain data (%ld)", (long)result); ++} ++ ++//Called to solicit password from user when file is chosen from iCloud (or other non-Purebred source) ++- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex ++{ ++ if(1 == buttonIndex) ++ { ++ passwordFromUser = [[alertView textFieldAtIndex:0] text]; ++ if(nil != passwordFromUser && 0 != [passwordFromUser length]) ++ { ++ [self importP12:pkcs12Data password:passwordFromUser]; ++ } ++ } ++} ++ ++//Called to parse a PKCS12 object, decrypt it and import it into app's key chain ++- (void)importP12:(NSData*) pkcs12DataToImport password:(NSString*)password ++{ ++ CFDataRef inPKCS12Data = (__bridge CFDataRef)pkcs12DataToImport; ++ ++ OSStatus securityError = errSecSuccess; ++ ++ //SecPKCS12Import requires a dictionary with a single value (only one option is supported) ++ NSMutableDictionary * optionsDictionary = [[NSMutableDictionary alloc] init]; ++ [optionsDictionary setObject:(id)password forKey:(id)kSecImportExportPassphrase]; ++ [optionsDictionary setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnRef]; ++ [optionsDictionary setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData]; ++ [optionsDictionary setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes]; ++ ++ //Create an array to receive the data parsed from the PKCS12 blob ++ CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL); ++ ++ //Parse the PKCS12 blob ++ securityError = SecPKCS12Import(inPKCS12Data, (CFDictionaryRef)optionsDictionary, &items); ++ if (securityError == errSecAuthFailed) { ++ NSString *alertMessage = [NSString stringWithFormat:@"Failed to import key from PKCS #12 file with wrong password\nerror code= %d", (int)securityError]; ++ NSLog(@"%@", alertMessage); ++ dispatch_async(dispatch_get_main_queue(), ^{ ++ UIAlertController *alertController = [UIAlertController ++ alertControllerWithTitle:@"Import Error" ++ message:alertMessage ++ preferredStyle:UIAlertControllerStyleAlert]; ++ [alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:nil]]; ++ [self presentViewController:alertController animated:YES completion:nil]; ++ }); ++ } ++ else if(securityError == errSecSuccess) ++ { ++ long count = CFArrayGetCount(items); ++ if(count > 1) ++ { ++ NSLog(@"%s %d %s - %s", __FILE__, __LINE__, __PRETTY_FUNCTION__, "SecPKCS12Import returned more than one item. Ignoring all but the first item."); ++ } ++ ++ for(long ii = 0; ii < count; ++ii) ++ { ++ //get the first time from the array populated by SecPKCS12Import ++ if (CFArrayGetCount(items) > 0) { ++ CFDictionaryRef pkcs12Contents = (CFDictionaryRef)CFArrayGetValueAtIndex(items, ii); ++ ++ //we're primarily interested in the identity value ++ if(CFDictionaryContainsKey(pkcs12Contents, kSecImportItemIdentity)) ++ { ++ //Grab the identity from the dictionary ++ SecIdentityRef identity = (SecIdentityRef)CFDictionaryGetValue(pkcs12Contents, kSecImportItemIdentity); ++ ++ SecCertificateRef certRef = NULL; ++ SecIdentityCopyCertificate(identity, &certRef); ++ CFStringRef summaryRef = SecCertificateCopySubjectSummary(certRef); ++ NSString *tagstr = (__bridge_transfer NSString*)summaryRef; ++ ++ NSMutableDictionary* dict = [[NSMutableDictionary alloc]init]; ++ [dict setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnPersistentRef]; ++ [dict setObject:(__bridge id)identity forKey:(id)kSecValueRef]; ++ [dict setObject:tagstr forKey:(id)kSecAttrLabel]; ++// [optionsDictionary setObject:(id)kSecAttrAccessGroup forKey:(id)kSecAttrAccessGroup]; ++ CFTypeRef persistent_ref; ++ securityError = SecItemAdd((CFDictionaryRef)dict, &persistent_ref); ++ ++ if(errSecSuccess != securityError) ++ { ++ NSLog(@"%s %d %s - %s %s", __FILE__, __LINE__, __PRETTY_FUNCTION__, "SecItemAdd failed to import identity harvested from PKCS #12 data with error code ", [[[NSNumber numberWithInt:securityError] stringValue] UTF8String]); ++ ++ if(errSecDuplicateItem == securityError) ++ { ++ NSLog(@"Failed to import because item is there already"); ++ } ++ else ++ { ++ NSString *alertMessage = [NSString stringWithFormat:@"Failed to import key from PKCS #12 file with error code %d", (int)securityError]; ++ NSLog(@"%@", alertMessage); ++ dispatch_async(dispatch_get_main_queue(), ^{ ++ UIAlertController *alertController = [UIAlertController ++ alertControllerWithTitle:@"Import Error" ++ message:alertMessage ++ preferredStyle:UIAlertControllerStyleAlert]; ++ [alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:nil]]; ++ [self presentViewController:alertController animated:YES completion:nil]; ++ }); ++ } ++ } ++ ++ [keyChain LoadKeyChainContents]; ++ [[self tableViewKeyChain] reloadData]; ++ } ++ } ++ } ++ } ++ else ++ { ++ //Get the destination folder for the files ++ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); ++ NSString *documentsDirectory = [paths objectAtIndex:0]; ++ ++ //Generate a file name using the sha1 hash of the certificate with .p8 extension for private key and .der for certificate ++ NSString* zipFile = @"tmp.zip"; ++ NSString *zipPath = [documentsDirectory stringByAppendingPathComponent:zipFile]; ++ ++ [pkcs12DataToImport writeToFile:zipPath atomically:YES]; ++ ++ ZipFile *unzipFile= [[ZipFile alloc] initWithFileName:zipPath mode:ZipFileModeUnzip]; ++ if(NULL != unzipFile) ++ { ++ NSArray *infos= [unzipFile listFileInZipInfos]; ++ [unzipFile goToFirstFileInZip]; ++ ++ for (FileInZipInfo *info in infos) ++ { ++ ZipReadStream *read1= [unzipFile readCurrentFileInZip]; ++ ++ NSData *data= [read1 readDataOfLength:info.length]; ++ ++ if(data) ++ { ++ [self importP12:data password:password]; ++ } ++ ++ ++ [read1 finishedReading]; ++ [unzipFile goToNextFileInZip]; ++ } ++ ++ [unzipFile close]; ++ [[NSFileManager defaultManager] removeItemAtPath:zipPath error:nil]; ++ } ++ else{ ++ NSString *alertMessage = [NSString stringWithFormat:@"Failed to parse or decrypt PKCS #12 file with error code %d", (int)securityError]; ++ NSLog(@"%@", alertMessage); ++ dispatch_async(dispatch_get_main_queue(), ^{ ++ UIAlertController *alertController = [UIAlertController ++ alertControllerWithTitle:@"Import Error" ++ message:alertMessage ++ preferredStyle:UIAlertControllerStyleAlert]; ++ [alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:nil]]; ++ [self presentViewController:alertController animated:YES completion:nil]; ++ }); ++ } ++ } ++} ++ ++@end +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/KeyChainDataSource.h b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/KeyChainDataSource.h +new file mode 100644 +index 0000000..7a7ccbe +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/KeyChainDataSource.h +@@ -0,0 +1,85 @@ ++// ++// KeyChainDataSource.h ++// KeyShareConsumer ++ ++#import ++ ++/** ++ KeyChainDataSource has three modes of usage, each defined by the type of ++ item sought in the key chain. ++ */ ++enum KeyChainDataSourceMode ++{ ++ KSM_Certificates, ++ KSM_Identities, ++ KSM_Keys ++}; ++ ++/** ++ The KeyChainDataSource class is intended to function as a data source for table views displaying ++ various information from a key chain. Each KeyStore instance is associated with a type ++ of key chain item, i.e., identity, certificate, key. ++ ++ Each item is a section in the table with various information appropriate to the item ++ displayed in the section. ++ ++ Should only be used with tables with table style UITableViewStyleGrouped. ++ */ ++@interface KeyChainDataSource : NSObject ++{ ++ ++@public ++ //!When false, empty attributes are not returned, when true empty attributes are returned with ++ // empty string value. ++ bool displayEmptyAttributes; ++ ++ //!userQuery can be specified to change the search behavior applied by KeyChainDataSource ++ // before serving data to a table view. ++ NSMutableDictionary* userQuery; ++ ++ //!mode indicates the type of object associated with an instance (set upon instantiation) ++ enum KeyChainDataSourceMode mode; ++ ++@private ++ //!initialized indicates whether LoadKeyChainContents has been successfully executed. ++ bool initialized; ++ ++ //!items contains the values retrieved from the key chain ++ NSMutableArray* items; ++ ++ //!dictionary with friendly attribute names (prepared in init) ++ NSMutableDictionary* attrNames; ++} ++ ++//Public properties ++@property (nonatomic, assign) bool displayEmptyAttributes; ++@property (nonatomic, retain) NSMutableDictionary* userQuery; ++ ++//Private properties ++@property (nonatomic, retain) NSArray* items; ++@property (nonatomic, assign) enum KeyChainDataSourceMode mode; ++@property (nonatomic, assign) bool initialized; ++@property (nonatomic, retain) NSMutableDictionary* attrNames; ++ ++- (id) initWithMode:(enum KeyChainDataSourceMode)mode; ++- (void) ClearContents; ++- (void) LoadKeyChainContents; ++- (NSString*) GetIdentityNameAtIndex:(long)index; ++- (NSString*) GetEmailAddressAtIndex:(long)index; ++- (void) removeObjectAtIndex:(long)index; ++- (int) numItems; ++- (SecIdentityRef) GetIdentityAtIndex:(long)index; ++- (NSData*) GetPKCS12AtIndex:(long)index; ++- (NSData*) GetPrivateKeyAtIndex:(long)index; ++ ++- (int) numAttrGroups:(long)index; ++- (NSString*) getAttrStringAtIndex:(long)index attrGroup:(long)attrGroup; ++ ++- (NSString*) getAttrNameAtSection:(long)sectionIndex attrIndex:(long)attrIndex; ++- (NSString*) getAttrValueAtSection:(long)sectionIndex attrIndex:(long)attrIndex; ++- (NSString*) getAttrValueAtSection:(long)sectionIndex attrType:(CFTypeRef)attrType; ++ ++- (SecCertificateRef) getCertificateAt:(long)index; ++- (SecIdentityRef) GetIdentityByName:(NSString *)name; ++ ++@end +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/KeyChainDataSource.mm b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/KeyChainDataSource.mm +new file mode 100644 +index 0000000..ceb52a8 +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/KeyChainDataSource.mm +@@ -0,0 +1,947 @@ ++// ++// KeyChainDataSource.mm ++// KeyShareConsumer ++ ++#import "KeyChainDataSource.h" ++#import ++ ++#include ++ ++//-------------------------------------------------------------- ++// Arrays containing attributes for each type of item associated ++// with this class: certificate, key, identity ++//-------------------------------------------------------------- ++CFTypeRef g_certAttrs[] = { ++ kSecAttrAccessible, ++ kSecAttrAccessGroup, ++ kSecAttrCertificateType, ++ kSecAttrCertificateEncoding, ++ kSecAttrLabel, ++ kSecAttrSubject, ++ kSecAttrIssuer, ++ kSecAttrSerialNumber, ++ kSecAttrSubjectKeyID, ++ kSecAttrPublicKeyHash, ++ NULL ++}; ++ ++CFTypeRef g_keyAttrs[] = { ++ kSecAttrAccessible, ++ kSecAttrAccessGroup, ++ kSecAttrKeyClass, ++ kSecAttrLabel, ++ kSecAttrApplicationLabel, ++ kSecAttrIsPermanent, ++ kSecAttrApplicationTag, ++ kSecAttrKeyType, ++ kSecAttrKeySizeInBits, ++ kSecAttrEffectiveKeySize, ++ kSecAttrCanEncrypt, ++ kSecAttrCanDecrypt, ++ kSecAttrCanDerive, ++ kSecAttrCanSign, ++ kSecAttrCanVerify, ++ kSecAttrCanWrap, ++ kSecAttrCanUnwrap, ++ NULL ++}; ++ ++CFTypeRef g_identityAttrs[] = { ++ kSecAttrAccessible, ++ kSecAttrAccessGroup, ++ kSecAttrCertificateType, ++ kSecAttrCertificateEncoding, ++ kSecAttrLabel, ++ kSecAttrSubject, ++ kSecAttrIssuer, ++ kSecAttrSerialNumber, ++ kSecAttrSubjectKeyID, ++ kSecAttrPublicKeyHash, ++ kSecAttrKeyClass, ++ kSecAttrApplicationLabel, ++ kSecAttrIsPermanent, ++ kSecAttrApplicationTag, ++ kSecAttrKeyType, ++ kSecAttrKeySizeInBits, ++ kSecAttrEffectiveKeySize, ++ kSecAttrCanEncrypt, ++ kSecAttrCanDecrypt, ++ kSecAttrCanDerive, ++ kSecAttrCanSign, ++ kSecAttrCanVerify, ++ kSecAttrCanWrap, ++ kSecAttrCanUnwrap, ++ NULL ++}; ++ ++//-------------------------------------------------------------- ++// Arrays containing attributes that are grouped together in a ++// single table cell for display purposes, i.e., a single string ++// is returned containing information for all attributes in the ++// group. ++//-------------------------------------------------------------- ++CFTypeRef g_keyRelatedAttrs[] = { ++ kSecAttrKeyClass, ++ kSecAttrKeyType, ++ kSecAttrKeySizeInBits, ++ kSecAttrEffectiveKeySize, ++ NULL ++}; ++ ++CFTypeRef g_capabilityRelatedAttrs[] = { ++ kSecAttrCanEncrypt, ++ kSecAttrCanDecrypt, ++ kSecAttrCanDerive, ++ kSecAttrCanSign, ++ kSecAttrCanVerify, ++ kSecAttrCanWrap, ++ kSecAttrCanUnwrap, ++ NULL ++}; ++ ++CFTypeRef g_certRelatedAttrs[] = { ++ kSecAttrCertificateType, ++ kSecAttrCertificateEncoding, ++ kSecAttrSubject, ++ kSecAttrIssuer, ++ kSecAttrSerialNumber, ++ kSecAttrSubjectKeyID, ++ kSecAttrPublicKeyHash, ++ NULL ++}; ++ ++CFTypeRef g_miscRelatedAttrs[] = { ++ kSecAttrLabel, ++ kSecAttrAccessible, ++ kSecAttrAccessGroup, ++ kSecAttrApplicationLabel, ++ kSecAttrIsPermanent, ++ kSecAttrApplicationTag, ++ NULL ++}; ++ ++//-------------------------------------------------------------- ++// Internal conversion helper functions ++//-------------------------------------------------------------- ++@interface KeyChainDataSource (ConversionRoutines) ++ ++ //These return strings that should be autoreleased ++ + (NSString*) getCFDateAsString:(CFDateRef) date; ++ + (NSString*) getCFNumberAsString:(CFNumberRef) number; ++ + (NSString*) getCFBooleanAsString:(CFBooleanRef) cfBool; ++ + (NSString*) getCertificateTypeAsString:(CFNumberRef) number; ++ + (NSString*) getKeyTypeAsString:(CFNumberRef) number; ++ + (NSString*) getKeyClassAsString:(CFNumberRef) number; ++ + (NSString*) getCertificateEncodingAsString:(CFNumberRef) number; ++ + (NSString*) getAttrAccessibleAsString:(CFStringRef) attrAccessible; ++ ++ //The return freshly alloc'ed string ++ + (NSString*) getDataAsAsciiHexString:(NSData*)data; ++ + (NSString*) getDataAsNameString:(NSData*)data; ++ ++@end ++ ++@implementation KeyChainDataSource (ConversionRoutines) ++ +++ (NSString*) getCFDateAsString:(CFDateRef) date ++{ ++ NSDate* nsDate = (__bridge NSDate*)date; ++ return [nsDate description]; ++} ++ +++ (NSString*) getCFNumberAsString:(CFNumberRef) number ++{ ++ NSNumber* nsNumber = (__bridge NSNumber*)number; ++ return [nsNumber stringValue]; ++} ++ +++ (NSString*) getCFBooleanAsString:(CFBooleanRef) cfBool ++{ ++ if(CFBooleanGetValue(cfBool)) ++ return NSLocalizedString(@"Yes", nil); ++ else ++ return NSLocalizedString(@"No", nil); ++} ++ +++ (NSString*) getCertificateTypeAsString:(CFNumberRef) number ++{ ++ NSNumber* nsNumber = (__bridge NSNumber*)number; ++ switch([nsNumber intValue]) ++ { ++ case 1: ++ return NSLocalizedString(@"X509v1", nil); ++ case 2: ++ return NSLocalizedString(@"X509v2", nil); ++ case 3: ++ return NSLocalizedString(@"X509v3", nil); ++ default: ++ return NSLocalizedString(@"Unknown type", nil); ++ } ++} ++ +++ (NSString*) getKeyClassAsString:(CFNumberRef) number ++{ ++ NSString* nStr = [self getCFNumberAsString:number]; ++ ++ if(NSOrderedSame == [(NSString*)kSecAttrKeyClassPublic compare:nStr]) ++ return NSLocalizedString(@"Public key", nil); ++ else if(NSOrderedSame == [(NSString*)kSecAttrKeyClassPrivate compare:nStr]) ++ return NSLocalizedString(@"Private key", nil); ++ else if(NSOrderedSame == [(NSString*)kSecAttrKeyClassSymmetric compare:nStr]) ++ return NSLocalizedString(@"Symmetric key", nil); ++ else ++ return NSLocalizedString(@"Unknown type", nil); ++} ++ +++ (NSString*) getKeyTypeAsString:(CFNumberRef) number ++{ ++ NSString* nStr = [self getCFNumberAsString:number]; ++ ++ if(NSOrderedSame == [(NSString*)kSecAttrKeyTypeRSA compare:nStr]) ++ return NSLocalizedString(@"RSA", nil); ++ else if(NSOrderedSame == [(NSString*)kSecAttrKeyTypeRSA compare:nStr]) ++ return NSLocalizedString(@"Elliptic curve", nil); ++ else ++ return NSLocalizedString(@"Unknown type", nil); ++} ++ +++ (NSString*) getAttrAccessibleAsString:(CFStringRef) attrAccessible ++{ ++ NSString* nStr = (__bridge NSString*)attrAccessible; ++ ++ if(NSOrderedSame == [(NSString*)kSecAttrAccessibleWhenUnlocked compare:nStr]) ++ return NSLocalizedString(@"kSecAttrAccessibleWhenUnlocked", nil); ++ else if(NSOrderedSame == [(NSString*)kSecAttrAccessibleAfterFirstUnlock compare:nStr]) ++ return NSLocalizedString(@"kSecAttrAccessibleAfterFirstUnlock", nil); ++ else if(NSOrderedSame == [(NSString*)kSecAttrAccessibleAlways compare:nStr]) ++ return NSLocalizedString(@"kSecAttrAccessibleAlways", nil); ++ else if(NSOrderedSame == [(NSString*)kSecAttrAccessibleWhenUnlockedThisDeviceOnly compare:nStr]) ++ return NSLocalizedString(@"kSecAttrAccessibleWhenUnlockedThisDeviceOnly", nil); ++ else if(NSOrderedSame == [(NSString*)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly compare:nStr]) ++ return NSLocalizedString(@"kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly", nil); ++ else if(NSOrderedSame == [(NSString*)kSecAttrAccessibleAlwaysThisDeviceOnly compare:nStr]) ++ return NSLocalizedString(@"kSecAttrAccessibleAlwaysThisDeviceOnly", nil); ++ else ++ return NSLocalizedString(@"Unknown type", nil); ++} ++ +++ (NSString*) getCertificateEncodingAsString:(CFNumberRef) number ++{ ++ NSNumber* nsNumber = (__bridge NSNumber*)number; ++ if(3 == [nsNumber intValue]) ++ return NSLocalizedString(@"DER", nil); ++ else ++ return NSLocalizedString(@"Unknown type", nil); ++} ++ +++ (NSString *) hexString:(NSData*)data ++{ ++ NSUInteger bytesCount = [data length]; ++ if (bytesCount) { ++ const char *hexChars = "0123456789ABCDEF"; ++ const unsigned char *dataBuffer = (unsigned char*)[data bytes]; ++ char *chars = (char*)malloc(sizeof(char) * (bytesCount * 2 + 1)); ++ char *s = chars; ++ for (unsigned i = 0; i < bytesCount; ++i) { ++ *s++ = hexChars[((*dataBuffer & 0xF0) >> 4)]; ++ *s++ = hexChars[(*dataBuffer & 0x0F)]; ++ dataBuffer++; ++ } ++ *s = '\0'; ++ NSString *hexString = [NSString stringWithUTF8String:chars]; ++ free(chars); ++ return hexString; ++ } ++ return @""; ++} ++ +++ (NSString*) getDataAsAsciiHexString:(NSData*)data ++{ ++ return [self hexString:data]; ++} ++ +++ (NSString*) getDataAsNameString:(NSData*)data ++{ ++ //Implement after linking useful PKE support ++ return nil; ++} ++ ++@end ++ ++//-------------------------------------------------------------- ++// Internal conversion helper functions ++//-------------------------------------------------------------- ++@interface KeyChainDataSource (PrivateMethods) ++ ++- (void) populateAttrMap; ++- (int) countAttributesAtIndex:(long)index; ++- (NSString*) getAttrValueAsString:(CFTypeRef)attribute value:(CFTypeRef)value; ++ ++@end ++ ++@implementation KeyChainDataSource (PrivateMethods) ++ ++- (void) populateAttrMap ++{ ++ if(attrNames) ++ { ++ //[attrNames release]; ++ attrNames = nil; ++ } ++ ++ attrNames = [[NSMutableDictionary alloc] init]; ++ ++ //Set up the friendly names for each attribute that can be read from one ++ //of the three types of items this class cares about. ++ [attrNames setObject:(id)@"Accessible" forKey:(id)kSecAttrAccessible]; ++ [attrNames setObject:(id)@"Access group" forKey:(id)kSecAttrAccessGroup]; ++ [attrNames setObject:(id)@"Certificate type" forKey:(id)kSecAttrCertificateType]; ++ [attrNames setObject:(id)@"Certificate encoding" forKey:(id)kSecAttrCertificateEncoding]; ++ [attrNames setObject:(id)@"Label" forKey:(id)kSecAttrLabel]; ++ ++ //Re-enable these if linking in a certificate parser ++ //[attrNames setObject:(id)@"Subject" forKey:(id)kSecAttrSubject]; ++ //[attrNames setObject:(id)@"Issuer" forKey:(id)kSecAttrIssuer]; ++ [attrNames setObject:(id)@"Serial number" forKey:(id)kSecAttrSerialNumber]; ++ [attrNames setObject:(id)@"Subject key ID" forKey:(id)kSecAttrSubjectKeyID]; ++ [attrNames setObject:(id)@"Public key hash" forKey:(id)kSecAttrPublicKeyHash]; ++ [attrNames setObject:(id)@"Key class" forKey:(id)kSecAttrKeyClass]; ++ [attrNames setObject:(id)@"Application label" forKey:(id)kSecAttrApplicationLabel]; ++ [attrNames setObject:(id)@"Is permanent" forKey:(id)kSecAttrIsPermanent]; ++ [attrNames setObject:(id)@"Application tag" forKey:(id)kSecAttrApplicationTag]; ++ [attrNames setObject:(id)@"Key type" forKey:(id)kSecAttrKeyType]; ++ [attrNames setObject:(id)@"Key size in bits" forKey:(id)kSecAttrKeySizeInBits]; ++ [attrNames setObject:(id)@"Effective key size" forKey:(id)kSecAttrEffectiveKeySize]; ++ [attrNames setObject:(id)@"Can encrypt" forKey:(id)kSecAttrCanEncrypt]; ++ [attrNames setObject:(id)@"Can decrypt" forKey:(id)kSecAttrCanDecrypt]; ++ [attrNames setObject:(id)@"Can derive" forKey:(id)kSecAttrCanDerive]; ++ [attrNames setObject:(id)@"Can sign" forKey:(id)kSecAttrCanSign]; ++ [attrNames setObject:(id)@"Can verify" forKey:(id)kSecAttrCanVerify]; ++ [attrNames setObject:(id)@"Can wrap" forKey:(id)kSecAttrCanWrap]; ++ [attrNames setObject:(id)@"Can unwrap" forKey:(id)kSecAttrCanUnwrap]; ++} ++ ++- (int) countAttributesAtIndex:(long)index ++{ ++ int count = 0; ++ ++ CFTypeRef* attrs = NULL; ++ ++ switch (mode) { ++ case KSM_Certificates: ++ attrs = g_certAttrs; ++ break; ++ case KSM_Identities: ++ attrs = g_identityAttrs; ++ break; ++ case KSM_Keys: ++ attrs = g_keyAttrs; ++ break; ++ default: ++ return 0; ++ } ++ ++ @try ++ { ++ CFDictionaryRef dict = (__bridge CFDictionaryRef)[items objectAtIndex:index]; ++ ++ for(int ii = 0; attrs[ii]; ++ii) ++ { ++ if(true == CFDictionaryGetValueIfPresent(dict, attrs[ii], NULL)) ++ ++count; ++ } ++ } ++ @catch (NSException* rangeException) ++ { ++ return 0; ++ } ++ ++ return count; ++} ++ ++- (NSString*) getAttrValueAsString:(CFTypeRef)attribute value:(CFTypeRef)value ++ { ++ NSString* attributeValueString = nil; ++ ++ if(kSecAttrAccessible == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getAttrAccessibleAsString:(CFStringRef)value]; ++ } ++ else if(kSecAttrAccessGroup == attribute) ++ { ++ attributeValueString = [[NSString alloc] initWithString:(__bridge NSString*)value] ; ++ } ++ else if(kSecAttrCertificateType == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getCertificateTypeAsString:(CFNumberRef)value]; ++ } ++ else if(kSecAttrCertificateEncoding == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getCertificateEncodingAsString:(CFNumberRef)value]; ++ } ++ else if(kSecAttrLabel == attribute) ++ { ++ attributeValueString = [[NSString alloc] initWithString:(__bridge NSString*)value] ; ++ } ++ else if(kSecAttrSubject == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getDataAsNameString:(__bridge NSData*)value]; ++ } ++ else if(kSecAttrIssuer == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getDataAsNameString:(__bridge NSData*)value]; ++ } ++ else if(kSecAttrSerialNumber == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getDataAsAsciiHexString:(__bridge NSData*)value]; ++ } ++ else if(kSecAttrSubjectKeyID == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getDataAsAsciiHexString:(__bridge NSData*)value]; ++ } ++ else if(kSecAttrPublicKeyHash == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getDataAsAsciiHexString:(__bridge NSData*)value]; ++ } ++ else if(kSecAttrKeyClass == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getKeyClassAsString:(CFNumberRef)value]; ++ } ++ else if(kSecAttrApplicationLabel == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getDataAsAsciiHexString:(__bridge NSData*)value]; ++ } ++ else if(kSecAttrIsPermanent == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getCFBooleanAsString:(CFBooleanRef)value]; ++ } ++ else if(kSecAttrApplicationTag == attribute) ++ { ++ if(CFGetTypeID(value) == CFDataGetTypeID()) ++ { ++ NSData* d = (__bridge NSData*)value; ++ attributeValueString = [NSString stringWithUTF8String:(char*)[d bytes]]; ++ } ++ else ++ { ++ attributeValueString = [[NSString alloc] initWithString:(__bridge NSString*)value] ; ++ } ++ } ++ else if(kSecAttrKeyType == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getKeyTypeAsString:(CFNumberRef)value]; ++ } ++ else if(kSecAttrKeySizeInBits == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getCFNumberAsString:(CFNumberRef)value]; ++ } ++ else if(kSecAttrEffectiveKeySize == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getCFNumberAsString:(CFNumberRef)value]; ++ } ++ else if(kSecAttrCanEncrypt == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getCFBooleanAsString:(CFBooleanRef)value]; ++ } ++ else if(kSecAttrCanDecrypt == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getCFBooleanAsString:(CFBooleanRef)value]; ++ } ++ else if(kSecAttrCanDerive == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getCFBooleanAsString:(CFBooleanRef)value]; ++ } ++ else if(kSecAttrCanSign == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getCFBooleanAsString:(CFBooleanRef)value]; ++ } ++ else if(kSecAttrCanVerify == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getCFBooleanAsString:(CFBooleanRef)value]; ++ } ++ else if(kSecAttrCanWrap == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getCFBooleanAsString:(CFBooleanRef)value]; ++ } ++ else if(kSecAttrCanUnwrap == attribute) ++ { ++ attributeValueString = [KeyChainDataSource getCFBooleanAsString:(CFBooleanRef)value]; ++ } ++ else ++ { ++ attributeValueString = @"Unknown value"; ++ } ++ ++ return attributeValueString; ++} ++ ++@end ++ ++//-------------------------------------------------------------- ++// KeyChainDataSource implementation ++//-------------------------------------------------------------- ++@implementation KeyChainDataSource ++ ++//Public members ++@synthesize displayEmptyAttributes; ++@synthesize userQuery; ++ ++//Private members ++@synthesize items; ++@synthesize mode; ++@synthesize initialized; ++@synthesize attrNames; ++ ++- (int) numAttrGroups:(long)index ++{ ++ return [self countAttributesAtIndex:index]; ++} ++ ++- (NSString*) getAttrStringForGroup:(CFTypeRef*)attrArray forItem:(long)index ++{ ++ std::ostringstream oss; ++ for(int ii = 0; attrArray[ii]; ++ii) ++ { ++ NSString* attrName = (NSString*)[attrNames objectForKey:(__bridge id)attrArray[ii]]; ++ if(attrName) ++ { ++ NSString* attrValue = [self getAttrValueAtSection:index attrType:attrArray[ii]]; ++ if(attrValue) ++ { ++ oss << [attrName UTF8String] << ": " << [attrValue UTF8String] << std::endl; ++ } ++ } ++ } ++ NSString* retVal = [[NSString alloc] initWithCString:oss.str().c_str() encoding:NSUTF8StringEncoding] ; ++ return retVal; ++} ++ ++- (NSString*) getAttrStringAtIndex:(long)index attrGroup:(long)attrGroup ++{ ++ return [self getAttrValueAtSection:index attrIndex:attrGroup]; ++} ++ ++/** ++ LoadKeyChainContents prepares a dictionary containing a query filter based on the current mode. ++ The results are stored in the items member variable with mode-specific contents. ++ */ ++- (void) LoadKeyChainContents ++{ ++ [self ClearContents]; ++ ++ OSStatus resultCode = noErr; ++ ++ if(nil == userQuery) ++ { ++ NSMutableDictionary * query = [[NSMutableDictionary alloc] init]; ++ ++ //Set up the invariant pieces of the query ++ [query setObject:(id)kSecMatchLimitAll forKey:(id)kSecMatchLimit]; ++ [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnRef]; ++ [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData]; ++ [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes]; ++// [query setObject:@"com.mattermost.rnbeta" forKey:(id)kSecAttrAccessGroup]; ++ ++ //Set up the mode-specific pieces of the query ++ switch(mode) ++ { ++ case KSM_Certificates: ++ { ++ [query setObject:(id)kSecClassCertificate forKey:(id)kSecClass]; ++ break; ++ } ++ case KSM_Identities: ++ { ++ [query setObject:(id)kSecClassIdentity forKey:(id)kSecClass]; ++ break; ++ } ++ case KSM_Keys: ++ { ++ [query setObject:(id)kSecClassKey forKey:(id)kSecClass]; ++ break; ++ } ++ } ++ ++ CFTypeRef result = nil; ++ //Execute the query saving the results in items. ++ resultCode = SecItemCopyMatching((CFDictionaryRef)query, &result); ++ items = (__bridge_transfer NSMutableArray*)result; ++ ++ //[query release]; ++ } ++ else ++ { ++ CFTypeRef result = nil; ++ resultCode = SecItemCopyMatching((CFDictionaryRef)userQuery, &result); ++ items = (__bridge_transfer NSMutableArray*)result; ++ } ++ ++ if(resultCode != noErr) ++ { ++ //clean up anything that might have landed in items ++ [self ClearContents]; ++ } ++ else ++ { ++ //set the initialized flag ++ initialized = true; ++ } ++ ++ return; ++} ++ ++- (SecIdentityRef) GetIdentityByName:(NSString *)name ++{ ++ ++ NSMutableDictionary * query = [[NSMutableDictionary alloc] init]; ++ NSData* tag = [name dataUsingEncoding:NSUTF8StringEncoding]; ++ ++ //Set up the invariant pieces of the query ++ [query setObject:(id)kSecMatchLimitAll forKey:(id)kSecMatchLimit]; ++ [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnRef]; ++ [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData]; ++ [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes]; ++ [query setObject:(id)kSecClassIdentity forKey:(id)kSecClass]; ++ [query setObject:name forKey:(id)kSecAttrLabel]; ++ ++ OSStatus resultCode = noErr; ++ CFTypeRef result = nil; ++ //Execute the query saving the results in items. ++ resultCode = SecItemCopyMatching((CFDictionaryRef)query, &result); ++ if (CFArrayGetCount((CFArrayRef)result) > 0) { ++ CFDictionaryRef item = (CFDictionaryRef)CFArrayGetValueAtIndex((CFArrayRef)result, 0); ++ if (item != nil) { ++ SecIdentityRef identity = nil; ++ CFTypeRef value; ++ if(CFDictionaryGetValueIfPresent(item, kSecValueRef, &value)) ++ { ++ identity = (SecIdentityRef)value; ++ } ++ ++ return identity; ++ } ++ } ++ return nil; ++} ++ ++//-------------------------------------------------------------- ++// KeyChainDataSource initialization/destruction ++//-------------------------------------------------------------- ++- (id) init ++{ ++ self = [super init]; ++ if(self) ++ { ++ mode = KSM_Identities; ++ initialized = false; ++ items = nil; ++ displayEmptyAttributes = false; ++ [self populateAttrMap]; ++ } ++ return self; ++} ++ ++- (id) initWithMode:(enum KeyChainDataSourceMode)kcdsMode ++{ ++ self = [super init]; ++ if(self) ++ { ++ mode = kcdsMode; ++ initialized = false; ++ items = nil; ++ displayEmptyAttributes = false; ++ [self populateAttrMap]; ++ } ++ return self; ++} ++ ++- (void)dealloc ++{ ++ //[items release]; ++ items = nil; ++ ++ //[attrNames release]; ++ attrNames = nil; ++ ++ //[userQuery release]; ++ userQuery = nil; ++ ++ [self ClearContents]; ++ //[super dealloc]; ++} ++ ++- (void) ClearContents ++{ ++ //[items release]; ++ items = nil; ++ ++ initialized = false; ++} ++ ++- (int) numItems ++{ ++ //each item gets its own section ++ if(nil == items) ++ return 0; ++ else ++ return [items count]; ++} ++ ++- (NSString*) GetEmailAddressAtIndex:(long)index ++{ ++ //Implement after linking useful PKE support ++ return nil; ++} ++ ++- (NSString*) GetCommonNameAtIndex:(long)index ++{ ++ SecCertificateRef certRef = [self getCertificateAt:index]; ++ if(certRef) ++ { ++ CFStringRef summaryRef = SecCertificateCopySubjectSummary(certRef); ++ return (__bridge_transfer NSString*)summaryRef; ++ } ++ ++ return nil; ++} ++- (NSString*) GetIdentityNameAtIndex:(long)index ++{ ++ //look for email address first, failing that use the default keychain label ++ NSString* emailAddress = [self GetEmailAddressAtIndex:index]; ++ if(!emailAddress) ++ { ++ NSString* subject = [self GetCommonNameAtIndex:index]; ++ if(!subject) ++ return [self getAttrValueAtSection:index attrType:kSecAttrLabel]; ++ else ++ return subject; ++ } ++ else ++ return emailAddress; ++} ++ ++- (SecIdentityRef) GetIdentityAtIndex:(long)index ++{ ++ if(index >= [items count]) ++ return nil; ++ CFDictionaryRef item = (__bridge CFDictionaryRef)[items objectAtIndex:index]; ++ ++ SecIdentityRef identity = nil; ++ CFTypeRef value; ++ if(CFDictionaryGetValueIfPresent(item, kSecValueRef, &value)) ++ { ++ identity = (SecIdentityRef)value; ++ } ++ ++ return identity; ++} ++ ++- (NSData*) GetPrivateKeyAtIndex:(long)index ++{ ++ if(index >= [items count]) ++ return nil; ++ CFDictionaryRef item = (__bridge CFDictionaryRef)[items objectAtIndex:index]; ++ ++ NSData* privateKey = nil; ++ CFTypeRef label; ++ if(CFDictionaryGetValueIfPresent(item, kSecValueData, &label)) ++ { ++ CFDataRef aCFString = (CFDataRef)label; ++ privateKey = (__bridge NSData *)aCFString; ++ } ++ return privateKey; ++} ++ ++- (void) removeObjectAtIndex:(long)index ++{ ++ if(index >= [items count]) ++ return; ++ ++ CFDictionaryRef item = (__bridge CFDictionaryRef)[items objectAtIndex:index]; ++ ++ CFTypeRef value; ++ if(CFDictionaryGetValueIfPresent(item, kSecValueRef, &value)) ++ { ++ SecIdentityRef identity = (SecIdentityRef)value; ++ ++ NSMutableDictionary * query = [[NSMutableDictionary alloc] init]; ++ ++ //Set up the invariant pieces of the query ++ [query setObject:(__bridge id)identity forKey:(id)kSecValueRef]; ++ ++ //Execute the query saving the results in items. ++ OSStatus resultCode = SecItemDelete((CFDictionaryRef) query); ++ query = nil; ++ ++ if(errSecSuccess == resultCode) ++ { ++ [self LoadKeyChainContents]; ++ } ++ else ++ { ++ NSLog(@"Failed to delete selected identity with error code %d.", (int)resultCode); ++ ++ } ++ } ++} ++ ++- (NSString*) getAttrNameAtSection:(long)sectionIndex attrIndex:(long)attrIndex ++{ ++ CFTypeRef attribute, value; ++ NSString* attrFriendlyName = nil; ++ ++ @try ++ { ++ CFDictionaryRef dict = (__bridge CFDictionaryRef)[items objectAtIndex:sectionIndex]; ++ CFTypeRef* attrs = NULL; ++ ++ switch (mode) { ++ case KSM_Certificates: ++ attrs = g_certAttrs; ++ break; ++ case KSM_Identities: ++ attrs = g_identityAttrs; ++ break; ++ case KSM_Keys: ++ attrs = g_keyAttrs; ++ break; ++ default: ++ return 0; ++ } ++ ++ for(int ii = 0, jj = 0; attrs[ii]; ++ii) ++ { ++ if(CFDictionaryGetValueIfPresent(dict, attrs[ii], &value)) ++ { ++ if(jj == attrIndex) ++ { ++ attribute = attrs[ii]; ++ break; ++ } ++ else ++ ++jj; ++ } ++ } ++ } ++ @catch (NSException* rangeException) ++ { ++ return 0; ++ } ++ ++ //get the friendly name of the attribute ++ attrFriendlyName = (NSString*)[attrNames objectForKey:(__bridge id)attribute]; ++ if(nil == attrFriendlyName) ++ attrFriendlyName = NSLocalizedString(@"Unrecognized attribute",nil); ++ ++ return attrFriendlyName; ++} ++ ++/** ++ This function returns the attrIndex-th present value from the sectionIndex-th item ++ */ ++- (NSString*) getAttrValueAtSection:(long)sectionIndex attrIndex:(long)attrIndex ++{ ++ CFTypeRef attribute, value; ++ ++ @try ++ { ++ CFDictionaryRef dict = (__bridge CFDictionaryRef)[items objectAtIndex:sectionIndex]; ++ CFTypeRef* attrs = NULL; ++ ++ switch (mode) { ++ case KSM_Certificates: ++ attrs = g_certAttrs; ++ break; ++ case KSM_Identities: ++ attrs = g_identityAttrs; ++ break; ++ case KSM_Keys: ++ attrs = g_keyAttrs; ++ break; ++ default: ++ return 0; ++ } ++ ++ for(int ii = 0, jj = 0; attrs[ii]; ++ii) ++ { ++ if(CFDictionaryGetValueIfPresent(dict, attrs[ii], &value)) ++ { ++ if(jj == attrIndex) ++ { ++ attribute = attrs[ii]; ++ break; ++ } ++ else ++ ++jj; ++ } ++ } ++ } ++ @catch (NSException* rangeException) ++ { ++ return nil; ++ } ++ ++ return [self getAttrValueAsString:attribute value:value]; ++} ++ ++- (NSString*) getAttrValueAtSection:(long)sectionIndex attrType:(CFTypeRef)attrType ++{ ++ CFTypeRef value; ++ ++ @try ++ { ++ CFDictionaryRef dict = (__bridge CFDictionaryRef)[items objectAtIndex:sectionIndex]; ++ if(!CFDictionaryGetValueIfPresent(dict, attrType, &value)) ++ { ++ return nil; ++ } ++ } ++ @catch (NSException* rangeException) ++ { ++ return nil; ++ } ++ ++ return [self getAttrValueAsString:attrType value:value]; ++} ++ ++- (SecCertificateRef) getCertificateAt:(long)index ++{ ++ if(index >= [items count]) ++ return nil; ++ ++ switch (mode) { ++ case KSM_Certificates: ++ { ++ CFDictionaryRef dict = (__bridge CFDictionaryRef)[items objectAtIndex:index]; ++ SecCertificateRef cert = (SecCertificateRef)CFDictionaryGetValue(dict, kSecValueRef); ++ return cert; ++ } ++ case KSM_Identities: ++ { ++ CFDictionaryRef dict = (__bridge CFDictionaryRef)[items objectAtIndex:index]; ++ SecIdentityRef identity = (SecIdentityRef)CFDictionaryGetValue(dict, kSecValueRef); ++ SecCertificateRef cert = nil; ++ OSStatus stat = SecIdentityCopyCertificate(identity, &cert); ++ if(errSecSuccess == stat) ++ return cert; ++ else ++ return nil; ++ } ++ case KSM_Keys: ++ { ++ return nil; ++ } ++ default: ++ { ++ return nil; ++ } ++ } ++} ++ ++- (NSData*) GetPKCS12AtIndex:(long)index ++{ ++ //Implement after linking useful PKE support ++ return nil; ++} ++ ++@end +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/ioapi.c b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/ioapi.c +new file mode 100644 +index 0000000..f1bee23 +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/ioapi.c +@@ -0,0 +1,177 @@ ++/* ioapi.c -- IO base function header for compress/uncompress .zip ++ files using zlib + zip or unzip API ++ ++ Version 1.01e, February 12th, 2005 ++ ++ Copyright (C) 1998-2005 Gilles Vollant ++*/ ++ ++#include ++#include ++#include ++ ++#include "zlib.h" ++#include "ioapi.h" ++ ++ ++ ++/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ ++ ++#ifndef SEEK_CUR ++#define SEEK_CUR 1 ++#endif ++ ++#ifndef SEEK_END ++#define SEEK_END 2 ++#endif ++ ++#ifndef SEEK_SET ++#define SEEK_SET 0 ++#endif ++ ++voidpf ZCALLBACK fopen_file_func OF(( ++ voidpf opaque, ++ const char* filename, ++ int mode)); ++ ++uLong ZCALLBACK fread_file_func OF(( ++ voidpf opaque, ++ voidpf stream, ++ void* buf, ++ uLong size)); ++ ++uLong ZCALLBACK fwrite_file_func OF(( ++ voidpf opaque, ++ voidpf stream, ++ const void* buf, ++ uLong size)); ++ ++long ZCALLBACK ftell_file_func OF(( ++ voidpf opaque, ++ voidpf stream)); ++ ++long ZCALLBACK fseek_file_func OF(( ++ voidpf opaque, ++ voidpf stream, ++ uLong offset, ++ int origin)); ++ ++int ZCALLBACK fclose_file_func OF(( ++ voidpf opaque, ++ voidpf stream)); ++ ++int ZCALLBACK ferror_file_func OF(( ++ voidpf opaque, ++ voidpf stream)); ++ ++ ++voidpf ZCALLBACK fopen_file_func (opaque, filename, mode) ++ voidpf opaque; ++ const char* filename; ++ int mode; ++{ ++ FILE* file = NULL; ++ const char* mode_fopen = NULL; ++ if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) ++ mode_fopen = "rb"; ++ else ++ if (mode & ZLIB_FILEFUNC_MODE_EXISTING) ++ mode_fopen = "r+b"; ++ else ++ if (mode & ZLIB_FILEFUNC_MODE_CREATE) ++ mode_fopen = "wb"; ++ ++ if ((filename!=NULL) && (mode_fopen != NULL)) ++ file = fopen(filename, mode_fopen); ++ return file; ++} ++ ++ ++uLong ZCALLBACK fread_file_func (opaque, stream, buf, size) ++ voidpf opaque; ++ voidpf stream; ++ void* buf; ++ uLong size; ++{ ++ uLong ret; ++ ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); ++ return ret; ++} ++ ++ ++uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size) ++ voidpf opaque; ++ voidpf stream; ++ const void* buf; ++ uLong size; ++{ ++ uLong ret; ++ ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); ++ return ret; ++} ++ ++long ZCALLBACK ftell_file_func (opaque, stream) ++ voidpf opaque; ++ voidpf stream; ++{ ++ long ret; ++ ret = ftell((FILE *)stream); ++ return ret; ++} ++ ++long ZCALLBACK fseek_file_func (opaque, stream, offset, origin) ++ voidpf opaque; ++ voidpf stream; ++ uLong offset; ++ int origin; ++{ ++ int fseek_origin=0; ++ long ret; ++ switch (origin) ++ { ++ case ZLIB_FILEFUNC_SEEK_CUR : ++ fseek_origin = SEEK_CUR; ++ break; ++ case ZLIB_FILEFUNC_SEEK_END : ++ fseek_origin = SEEK_END; ++ break; ++ case ZLIB_FILEFUNC_SEEK_SET : ++ fseek_origin = SEEK_SET; ++ break; ++ default: return -1; ++ } ++ ret = 0; ++ fseek((FILE *)stream, offset, fseek_origin); ++ return ret; ++} ++ ++int ZCALLBACK fclose_file_func (opaque, stream) ++ voidpf opaque; ++ voidpf stream; ++{ ++ int ret; ++ ret = fclose((FILE *)stream); ++ return ret; ++} ++ ++int ZCALLBACK ferror_file_func (opaque, stream) ++ voidpf opaque; ++ voidpf stream; ++{ ++ int ret; ++ ret = ferror((FILE *)stream); ++ return ret; ++} ++ ++void fill_fopen_filefunc (pzlib_filefunc_def) ++ zlib_filefunc_def* pzlib_filefunc_def; ++{ ++ pzlib_filefunc_def->zopen_file = fopen_file_func; ++ pzlib_filefunc_def->zread_file = fread_file_func; ++ pzlib_filefunc_def->zwrite_file = fwrite_file_func; ++ pzlib_filefunc_def->ztell_file = ftell_file_func; ++ pzlib_filefunc_def->zseek_file = fseek_file_func; ++ pzlib_filefunc_def->zclose_file = fclose_file_func; ++ pzlib_filefunc_def->zerror_file = ferror_file_func; ++ pzlib_filefunc_def->opaque = NULL; ++} +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/ioapi.h b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/ioapi.h +new file mode 100644 +index 0000000..7d457ba +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/ioapi.h +@@ -0,0 +1,75 @@ ++/* ioapi.h -- IO base function header for compress/uncompress .zip ++ files using zlib + zip or unzip API ++ ++ Version 1.01e, February 12th, 2005 ++ ++ Copyright (C) 1998-2005 Gilles Vollant ++*/ ++ ++#ifndef _ZLIBIOAPI_H ++#define _ZLIBIOAPI_H ++ ++ ++#define ZLIB_FILEFUNC_SEEK_CUR (1) ++#define ZLIB_FILEFUNC_SEEK_END (2) ++#define ZLIB_FILEFUNC_SEEK_SET (0) ++ ++#define ZLIB_FILEFUNC_MODE_READ (1) ++#define ZLIB_FILEFUNC_MODE_WRITE (2) ++#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) ++ ++#define ZLIB_FILEFUNC_MODE_EXISTING (4) ++#define ZLIB_FILEFUNC_MODE_CREATE (8) ++ ++ ++#ifndef ZCALLBACK ++ ++#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) ++#define ZCALLBACK CALLBACK ++#else ++#define ZCALLBACK ++#endif ++#endif ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); ++typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); ++typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); ++typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); ++typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); ++typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); ++typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); ++ ++typedef struct zlib_filefunc_def_s ++{ ++ open_file_func zopen_file; ++ read_file_func zread_file; ++ write_file_func zwrite_file; ++ tell_file_func ztell_file; ++ seek_file_func zseek_file; ++ close_file_func zclose_file; ++ testerror_file_func zerror_file; ++ voidpf opaque; ++} zlib_filefunc_def; ++ ++ ++ ++void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); ++ ++#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) ++#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) ++#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) ++#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) ++#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) ++#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) ++ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif ++ +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/mztools.c b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/mztools.c +new file mode 100644 +index 0000000..b51d0e0 +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/mztools.c +@@ -0,0 +1,282 @@ ++/* ++ Additional tools for Minizip ++ Code: Xavier Roche '2004 ++ License: Same as ZLIB (www.gzip.org) ++*/ ++ ++/* Code */ ++#include ++#include ++#include ++#include "zlib.h" ++#include "unzip.h" ++#include "mztools.h" ++ ++#define READ_8(adr) ((unsigned char)*(adr)) ++#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) ) ++#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) ) ++ ++#define WRITE_8(buff, n) do { \ ++ *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \ ++} while(0) ++#define WRITE_16(buff, n) do { \ ++ WRITE_8((unsigned char*)(buff), n); \ ++ WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \ ++} while(0) ++#define WRITE_32(buff, n) do { \ ++ WRITE_16((unsigned char*)(buff), (n) & 0xffff); \ ++ WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \ ++} while(0) ++ ++extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered) ++const char* file; ++const char* fileOut; ++const char* fileOutTmp; ++uLong* nRecovered; ++uLong* bytesRecovered; ++{ ++ int err = Z_OK; ++ FILE* fpZip = fopen(file, "rb"); ++ FILE* fpOut = fopen(fileOut, "wb"); ++ FILE* fpOutCD = fopen(fileOutTmp, "wb"); ++ if (fpZip != NULL && fpOut != NULL) { ++ int entries = 0; ++ uLong totalBytes = 0; ++ char header[30]; ++ char filename[256]; ++ char extra[1024]; ++ int offset = 0; ++ int offsetCD = 0; ++ while ( fread(header, 1, 30, fpZip) == 30 ) { ++ int currentOffset = offset; ++ ++ /* File entry */ ++ if (READ_32(header) == 0x04034b50) { ++ unsigned int version = READ_16(header + 4); ++ unsigned int gpflag = READ_16(header + 6); ++ unsigned int method = READ_16(header + 8); ++ unsigned int filetime = READ_16(header + 10); ++ unsigned int filedate = READ_16(header + 12); ++ unsigned int crc = READ_32(header + 14); /* crc */ ++ unsigned int cpsize = READ_32(header + 18); /* compressed size */ ++ unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */ ++ unsigned int fnsize = READ_16(header + 26); /* file name length */ ++ unsigned int extsize = READ_16(header + 28); /* extra field length */ ++ filename[0] = extra[0] = '\0'; ++ ++ /* Header */ ++ if (fwrite(header, 1, 30, fpOut) == 30) { ++ offset += 30; ++ } else { ++ err = Z_ERRNO; ++ break; ++ } ++ ++ /* Filename */ ++ if (fnsize > 0) { ++ if (fread(filename, 1, fnsize, fpZip) == fnsize) { ++ if (fwrite(filename, 1, fnsize, fpOut) == fnsize) { ++ offset += fnsize; ++ } else { ++ err = Z_ERRNO; ++ break; ++ } ++ } else { ++ err = Z_ERRNO; ++ break; ++ } ++ } else { ++ err = Z_STREAM_ERROR; ++ break; ++ } ++ ++ /* Extra field */ ++ if (extsize > 0) { ++ if (fread(extra, 1, extsize, fpZip) == extsize) { ++ if (fwrite(extra, 1, extsize, fpOut) == extsize) { ++ offset += extsize; ++ } else { ++ err = Z_ERRNO; ++ break; ++ } ++ } else { ++ err = Z_ERRNO; ++ break; ++ } ++ } ++ ++ /* Data */ ++ { ++ int dataSize = cpsize; ++ if (dataSize == 0) { ++ dataSize = uncpsize; ++ } ++ if (dataSize > 0) { ++ char* data = malloc(dataSize); ++ if (data != NULL) { ++ if ((int)fread(data, 1, dataSize, fpZip) == dataSize) { ++ if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) { ++ offset += dataSize; ++ totalBytes += dataSize; ++ } else { ++ err = Z_ERRNO; ++ } ++ } else { ++ err = Z_ERRNO; ++ } ++ free(data); ++ if (err != Z_OK) { ++ break; ++ } ++ } else { ++ err = Z_MEM_ERROR; ++ break; ++ } ++ } ++ } ++ ++ /* Central directory entry */ ++ { ++ char cdeHeader[46]; ++ char* comment = ""; ++ int comsize = (int) strlen(comment); ++ WRITE_32(cdeHeader, 0x02014b50); ++ WRITE_16(cdeHeader + 4, version); ++ WRITE_16(cdeHeader + 6, version); ++ WRITE_16(cdeHeader + 8, gpflag); ++ WRITE_16(cdeHeader + 10, method); ++ WRITE_16(cdeHeader + 12, filetime); ++ WRITE_16(cdeHeader + 14, filedate); ++ WRITE_32(cdeHeader + 16, crc); ++ WRITE_32(cdeHeader + 20, cpsize); ++ WRITE_32(cdeHeader + 24, uncpsize); ++ WRITE_16(cdeHeader + 28, fnsize); ++ WRITE_16(cdeHeader + 30, extsize); ++ WRITE_16(cdeHeader + 32, comsize); ++ WRITE_16(cdeHeader + 34, 0); /* disk # */ ++ WRITE_16(cdeHeader + 36, 0); /* int attrb */ ++ WRITE_32(cdeHeader + 38, 0); /* ext attrb */ ++ WRITE_32(cdeHeader + 42, currentOffset); ++ /* Header */ ++ if (fwrite(cdeHeader, 1, 46, fpOutCD) == 46) { ++ offsetCD += 46; ++ ++ /* Filename */ ++ if (fnsize > 0) { ++ if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) { ++ offsetCD += fnsize; ++ } else { ++ err = Z_ERRNO; ++ break; ++ } ++ } else { ++ err = Z_STREAM_ERROR; ++ break; ++ } ++ ++ /* Extra field */ ++ if (extsize > 0) { ++ if (fwrite(extra, 1, extsize, fpOutCD) == extsize) { ++ offsetCD += extsize; ++ } else { ++ err = Z_ERRNO; ++ break; ++ } ++ } ++ ++ /* Comment field */ ++ if (comsize > 0) { ++ if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) { ++ offsetCD += comsize; ++ } else { ++ err = Z_ERRNO; ++ break; ++ } ++ } ++ ++ ++ } else { ++ err = Z_ERRNO; ++ break; ++ } ++ } ++ ++ /* Success */ ++ entries++; ++ ++ } else { ++ break; ++ } ++ } ++ ++ /* Final central directory */ ++ { ++ int entriesZip = entries; ++ char fcdHeader[22]; ++ char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools"; ++ int comsize = (int) strlen(comment); ++ if (entriesZip > 0xffff) { ++ entriesZip = 0xffff; ++ } ++ WRITE_32(fcdHeader, 0x06054b50); ++ WRITE_16(fcdHeader + 4, 0); /* disk # */ ++ WRITE_16(fcdHeader + 6, 0); /* disk # */ ++ WRITE_16(fcdHeader + 8, entriesZip); /* hack */ ++ WRITE_16(fcdHeader + 10, entriesZip); /* hack */ ++ WRITE_32(fcdHeader + 12, offsetCD); /* size of CD */ ++ WRITE_32(fcdHeader + 16, offset); /* offset to CD */ ++ WRITE_16(fcdHeader + 20, comsize); /* comment */ ++ ++ /* Header */ ++ if (fwrite(fcdHeader, 1, 22, fpOutCD) == 22) { ++ ++ /* Comment field */ ++ if (comsize > 0) { ++ if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) { ++ err = Z_ERRNO; ++ } ++ } ++ ++ } else { ++ err = Z_ERRNO; ++ } ++ } ++ ++ /* Final merge (file + central directory) */ ++ fclose(fpOutCD); ++ if (err == Z_OK) { ++ fpOutCD = fopen(fileOutTmp, "rb"); ++ if (fpOutCD != NULL) { ++ int nRead; ++ char buffer[8192]; ++ while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) { ++ if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) { ++ err = Z_ERRNO; ++ break; ++ } ++ } ++ fclose(fpOutCD); ++ } ++ } ++ ++ /* Close */ ++ fclose(fpZip); ++ fclose(fpOut); ++ ++ /* Wipe temporary file */ ++ (void)remove(fileOutTmp); ++ ++ /* Number of recovered entries */ ++ if (err == Z_OK) { ++ if (nRecovered != NULL) { ++ *nRecovered = entries; ++ } ++ if (bytesRecovered != NULL) { ++ *bytesRecovered = totalBytes; ++ } ++ } ++ } else { ++ err = Z_STREAM_ERROR; ++ } ++ return err; ++} +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/mztools.h b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/mztools.h +new file mode 100644 +index 0000000..eee78dc +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/mztools.h +@@ -0,0 +1,31 @@ ++/* ++ Additional tools for Minizip ++ Code: Xavier Roche '2004 ++ License: Same as ZLIB (www.gzip.org) ++*/ ++ ++#ifndef _zip_tools_H ++#define _zip_tools_H ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#ifndef _ZLIB_H ++#include "zlib.h" ++#endif ++ ++#include "unzip.h" ++ ++/* Repair a ZIP file (missing central directory) ++ file: file to recover ++ fileOut: output file after recovery ++ fileOutTmp: temporary file name used for recovery ++*/ ++extern int ZEXPORT unzRepair(const char* file, ++ const char* fileOut, ++ const char* fileOutTmp, ++ uLong* nRecovered, ++ uLong* bytesRecovered); ++ ++#endif +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/unzip.c b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/unzip.c +new file mode 100644 +index 0000000..2cca7e3 +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/unzip.c +@@ -0,0 +1,1600 @@ ++/* unzip.c -- IO for uncompress .zip files using zlib ++ Version 1.01e, February 12th, 2005 ++ ++ Copyright (C) 1998-2005 Gilles Vollant ++ ++ Read unzip.h for more info ++*/ ++ ++/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of ++compatibility with older software. The following is from the original crypt.c. Code ++woven in by Terry Thorsen 1/2003. ++*/ ++/* ++ Copyright (c) 1990-2000 Info-ZIP. All rights reserved. ++ ++ See the accompanying file LICENSE, version 2000-Apr-09 or later ++ (the contents of which are also included in zip.h) for terms of use. ++ If, for some reason, all these files are missing, the Info-ZIP license ++ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html ++*/ ++/* ++ crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] ++ ++ The encryption/decryption parts of this source code (as opposed to the ++ non-echoing password parts) were originally written in Europe. The ++ whole source package can be freely distributed, including from the USA. ++ (Prior to January 2000, re-export from the US was a violation of US law.) ++ */ ++ ++/* ++ This encryption code is a direct transcription of the algorithm from ++ Roger Schlafly, described by Phil Katz in the file appnote.txt. This ++ file (appnote.txt) is distributed with the PKZIP program (even in the ++ version without encryption capabilities). ++ */ ++ ++#define NOCRYPT ++#define NOUNCRYPT ++ ++#include ++#include ++#include ++#include "zlib.h" ++#include "unzip.h" ++ ++#ifdef STDC ++# include ++# include ++# include ++#endif ++#ifdef NO_ERRNO_H ++ extern int errno; ++#else ++# include ++#endif ++ ++ ++#ifndef local ++# define local static ++#endif ++/* compile with -Dlocal if your debugger can't find static symbols */ ++ ++ ++#ifndef CASESENSITIVITYDEFAULT_NO ++# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) ++# define CASESENSITIVITYDEFAULT_NO ++# endif ++#endif ++ ++ ++#ifndef UNZ_BUFSIZE ++#define UNZ_BUFSIZE (16384) ++#endif ++ ++#ifndef UNZ_MAXFILENAMEINZIP ++#define UNZ_MAXFILENAMEINZIP (256) ++#endif ++ ++#ifndef ALLOC ++# define ALLOC(size) (malloc(size)) ++#endif ++#ifndef TRYFREE ++# define TRYFREE(p) {if (p) free(p);} ++#endif ++ ++#define SIZECENTRALDIRITEM (0x2e) ++#define SIZEZIPLOCALHEADER (0x1e) ++ ++ ++ ++ ++const char unz_copyright[] = ++ " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; ++ ++/* unz_file_info_interntal contain internal info about a file in zipfile*/ ++typedef struct unz_file_info_internal_s ++{ ++ uLong offset_curfile;/* relative offset of local header 4 bytes */ ++} unz_file_info_internal; ++ ++ ++/* file_in_zip_read_info_s contain internal information about a file in zipfile, ++ when reading and decompress it */ ++typedef struct ++{ ++ char *read_buffer; /* internal buffer for compressed data */ ++ z_stream stream; /* zLib stream structure for inflate */ ++ ++ uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ ++ uLong stream_initialised; /* flag set if stream structure is initialised*/ ++ ++ uLong offset_local_extrafield;/* offset of the local extra field */ ++ uInt size_local_extrafield;/* size of the local extra field */ ++ uLong pos_local_extrafield; /* position in the local extra field in read*/ ++ ++ uLong crc32; /* crc32 of all data uncompressed */ ++ uLong crc32_wait; /* crc32 we must obtain after decompress all */ ++ uLong rest_read_compressed; /* number of byte to be decompressed */ ++ uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ ++ zlib_filefunc_def z_filefunc; ++ voidpf filestream; /* io structore of the zipfile */ ++ uLong compression_method; /* compression method (0==store) */ ++ uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ ++ int raw; ++} file_in_zip_read_info_s; ++ ++ ++/* unz_s contain internal information about the zipfile ++*/ ++typedef struct ++{ ++ zlib_filefunc_def z_filefunc; ++ voidpf filestream; /* io structore of the zipfile */ ++ unz_global_info gi; /* public global information */ ++ uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ ++ uLong num_file; /* number of the current file in the zipfile*/ ++ uLong pos_in_central_dir; /* pos of the current file in the central dir*/ ++ uLong current_file_ok; /* flag about the usability of the current file*/ ++ uLong central_pos; /* position of the beginning of the central dir*/ ++ ++ uLong size_central_dir; /* size of the central directory */ ++ uLong offset_central_dir; /* offset of start of central directory with ++ respect to the starting disk number */ ++ ++ unz_file_info cur_file_info; /* public info about the current file in zip*/ ++ unz_file_info_internal cur_file_info_internal; /* private info about it*/ ++ file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current ++ file if we are decompressing it */ ++ int encrypted; ++# ifndef NOUNCRYPT ++ unsigned long keys[3]; /* keys defining the pseudo-random sequence */ ++ const unsigned long* pcrc_32_tab; ++# endif ++} unz_s; ++ ++ ++#ifndef NOUNCRYPT ++#include "crypt.h" ++#endif ++ ++/* =========================================================================== ++ Read a byte from a gz_stream; update next_in and avail_in. Return EOF ++ for end of file. ++ IN assertion: the stream s has been sucessfully opened for reading. ++*/ ++ ++ ++local int unzlocal_getByte OF(( ++ const zlib_filefunc_def* pzlib_filefunc_def, ++ voidpf filestream, ++ int *pi)); ++ ++local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi) ++ const zlib_filefunc_def* pzlib_filefunc_def; ++ voidpf filestream; ++ int *pi; ++{ ++ unsigned char c; ++ int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); ++ if (err==1) ++ { ++ *pi = (int)c; ++ return UNZ_OK; ++ } ++ else ++ { ++ if (ZERROR(*pzlib_filefunc_def,filestream)) ++ return UNZ_ERRNO; ++ else ++ return UNZ_EOF; ++ } ++} ++ ++ ++/* =========================================================================== ++ Reads a long in LSB order from the given gz_stream. Sets ++*/ ++local int unzlocal_getShort OF(( ++ const zlib_filefunc_def* pzlib_filefunc_def, ++ voidpf filestream, ++ uLong *pX)); ++ ++local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX) ++ const zlib_filefunc_def* pzlib_filefunc_def; ++ voidpf filestream; ++ uLong *pX; ++{ ++ uLong x ; ++ int i; ++ int err; ++ ++ err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); ++ x = (uLong)i; ++ ++ if (err==UNZ_OK) ++ err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); ++ x += ((uLong)i)<<8; ++ ++ if (err==UNZ_OK) ++ *pX = x; ++ else ++ *pX = 0; ++ return err; ++} ++ ++local int unzlocal_getLong OF(( ++ const zlib_filefunc_def* pzlib_filefunc_def, ++ voidpf filestream, ++ uLong *pX)); ++ ++local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX) ++ const zlib_filefunc_def* pzlib_filefunc_def; ++ voidpf filestream; ++ uLong *pX; ++{ ++ uLong x ; ++ int i; ++ int err; ++ ++ err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); ++ x = (uLong)i; ++ ++ if (err==UNZ_OK) ++ err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); ++ x += ((uLong)i)<<8; ++ ++ if (err==UNZ_OK) ++ err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); ++ x += ((uLong)i)<<16; ++ ++ if (err==UNZ_OK) ++ err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); ++ x += ((uLong)i)<<24; ++ ++ if (err==UNZ_OK) ++ *pX = x; ++ else ++ *pX = 0; ++ return err; ++} ++ ++ ++/* My own strcmpi / strcasecmp */ ++local int strcmpcasenosensitive_internal (fileName1,fileName2) ++ const char* fileName1; ++ const char* fileName2; ++{ ++ for (;;) ++ { ++ char c1=*(fileName1++); ++ char c2=*(fileName2++); ++ if ((c1>='a') && (c1<='z')) ++ c1 -= 0x20; ++ if ((c2>='a') && (c2<='z')) ++ c2 -= 0x20; ++ if (c1=='\0') ++ return ((c2=='\0') ? 0 : -1); ++ if (c2=='\0') ++ return 1; ++ if (c1c2) ++ return 1; ++ } ++} ++ ++ ++#ifdef CASESENSITIVITYDEFAULT_NO ++#define CASESENSITIVITYDEFAULTVALUE 2 ++#else ++#define CASESENSITIVITYDEFAULTVALUE 1 ++#endif ++ ++#ifndef STRCMPCASENOSENTIVEFUNCTION ++#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal ++#endif ++ ++/* ++ Compare two filename (fileName1,fileName2). ++ If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) ++ If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi ++ or strcasecmp) ++ If iCaseSenisivity = 0, case sensitivity is defaut of your operating system ++ (like 1 on Unix, 2 on Windows) ++ ++*/ ++extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) ++ const char* fileName1; ++ const char* fileName2; ++ int iCaseSensitivity; ++{ ++ if (iCaseSensitivity==0) ++ iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; ++ ++ if (iCaseSensitivity==1) ++ return strcmp(fileName1,fileName2); ++ ++ return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); ++} ++ ++#ifndef BUFREADCOMMENT ++#define BUFREADCOMMENT (0x400) ++#endif ++ ++/* ++ Locate the Central directory of a zipfile (at the end, just before ++ the global comment) ++*/ ++local uLong unzlocal_SearchCentralDir OF(( ++ const zlib_filefunc_def* pzlib_filefunc_def, ++ voidpf filestream)); ++ ++local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream) ++ const zlib_filefunc_def* pzlib_filefunc_def; ++ voidpf filestream; ++{ ++ unsigned char* buf; ++ uLong uSizeFile; ++ uLong uBackRead; ++ uLong uMaxBack=0xffff; /* maximum size of global comment */ ++ uLong uPosFound=0; ++ ++ if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) ++ return 0; ++ ++ ++ uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); ++ ++ if (uMaxBack>uSizeFile) ++ uMaxBack = uSizeFile; ++ ++ buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); ++ if (buf==NULL) ++ return 0; ++ ++ uBackRead = 4; ++ while (uBackReaduMaxBack) ++ uBackRead = uMaxBack; ++ else ++ uBackRead+=BUFREADCOMMENT; ++ uReadPos = uSizeFile-uBackRead ; ++ ++ uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? ++ (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); ++ if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) ++ break; ++ ++ if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) ++ break; ++ ++ for (i=(int)uReadSize-3; (i--)>0;) ++ if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ++ ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) ++ { ++ uPosFound = uReadPos+i; ++ break; ++ } ++ ++ if (uPosFound!=0) ++ break; ++ } ++ TRYFREE(buf); ++ return uPosFound; ++} ++ ++/* ++ Open a Zip file. path contain the full pathname (by example, ++ on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer ++ "zlib/zlib114.zip". ++ If the zipfile cannot be opened (file doesn't exist or in not valid), the ++ return value is NULL. ++ Else, the return value is a unzFile Handle, usable with other function ++ of this unzip package. ++*/ ++extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def) ++ const char *path; ++ zlib_filefunc_def* pzlib_filefunc_def; ++{ ++ unz_s us; ++ unz_s *s; ++ uLong central_pos,uL; ++ ++ uLong number_disk; /* number of the current dist, used for ++ spaning ZIP, unsupported, always 0*/ ++ uLong number_disk_with_CD; /* number the the disk with central dir, used ++ for spaning ZIP, unsupported, always 0*/ ++ uLong number_entry_CD; /* total number of entries in ++ the central dir ++ (same than number_entry on nospan) */ ++ ++ int err=UNZ_OK; ++ ++ if (unz_copyright[0]!=' ') ++ return NULL; ++ ++ if (pzlib_filefunc_def==NULL) ++ fill_fopen_filefunc(&us.z_filefunc); ++ else ++ us.z_filefunc = *pzlib_filefunc_def; ++ ++ us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque, ++ path, ++ ZLIB_FILEFUNC_MODE_READ | ++ ZLIB_FILEFUNC_MODE_EXISTING); ++ if (us.filestream==NULL) ++ return NULL; ++ ++ central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream); ++ if (central_pos==0) ++ err=UNZ_ERRNO; ++ ++ if (ZSEEK(us.z_filefunc, us.filestream, ++ central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) ++ err=UNZ_ERRNO; ++ ++ /* the signature, already checked */ ++ if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ /* number of this disk */ ++ if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ /* number of the disk with the start of the central directory */ ++ if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ /* total number of entries in the central dir on this disk */ ++ if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ /* total number of entries in the central dir */ ++ if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ if ((number_entry_CD!=us.gi.number_entry) || ++ (number_disk_with_CD!=0) || ++ (number_disk!=0)) ++ err=UNZ_BADZIPFILE; ++ ++ /* size of the central directory */ ++ if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ /* offset of start of central directory with respect to the ++ starting disk number */ ++ if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ /* zipfile comment length */ ++ if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ if ((central_pospfile_in_zip_read!=NULL) ++ unzCloseCurrentFile(file); ++ ++ ZCLOSE(s->z_filefunc, s->filestream); ++ TRYFREE(s); ++ return UNZ_OK; ++} ++ ++ ++/* ++ Write info about the ZipFile in the *pglobal_info structure. ++ No preparation of the structure is needed ++ return UNZ_OK if there is no problem. */ ++extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info) ++ unzFile file; ++ unz_global_info *pglobal_info; ++{ ++ unz_s* s; ++ if (file==NULL) ++ return UNZ_PARAMERROR; ++ s=(unz_s*)file; ++ *pglobal_info=s->gi; ++ return UNZ_OK; ++} ++ ++ ++/* ++ Translate date/time from Dos format to tm_unz (readable more easilty) ++*/ ++local void unzlocal_DosDateToTmuDate (ulDosDate, ptm) ++ uLong ulDosDate; ++ tm_unz* ptm; ++{ ++ uLong uDate; ++ uDate = (uLong)(ulDosDate>>16); ++ ptm->tm_mday = (uInt)(uDate&0x1f) ; ++ ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; ++ ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; ++ ++ ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); ++ ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; ++ ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; ++} ++ ++/* ++ Get Info about the current file in the zipfile, with internal only info ++*/ ++local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, ++ unz_file_info *pfile_info, ++ unz_file_info_internal ++ *pfile_info_internal, ++ char *szFileName, ++ uLong fileNameBufferSize, ++ void *extraField, ++ uLong extraFieldBufferSize, ++ char *szComment, ++ uLong commentBufferSize)); ++ ++local int unzlocal_GetCurrentFileInfoInternal (file, ++ pfile_info, ++ pfile_info_internal, ++ szFileName, fileNameBufferSize, ++ extraField, extraFieldBufferSize, ++ szComment, commentBufferSize) ++ unzFile file; ++ unz_file_info *pfile_info; ++ unz_file_info_internal *pfile_info_internal; ++ char *szFileName; ++ uLong fileNameBufferSize; ++ void *extraField; ++ uLong extraFieldBufferSize; ++ char *szComment; ++ uLong commentBufferSize; ++{ ++ unz_s* s; ++ unz_file_info file_info; ++ unz_file_info_internal file_info_internal; ++ int err=UNZ_OK; ++ uLong uMagic; ++ long lSeek=0; ++ ++ if (file==NULL) ++ return UNZ_PARAMERROR; ++ s=(unz_s*)file; ++ if (ZSEEK(s->z_filefunc, s->filestream, ++ s->pos_in_central_dir+s->byte_before_the_zipfile, ++ ZLIB_FILEFUNC_SEEK_SET)!=0) ++ err=UNZ_ERRNO; ++ ++ ++ /* we check the magic */ ++ if (err==UNZ_OK) ++ if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) ++ err=UNZ_ERRNO; ++ else if (uMagic!=0x02014b50) ++ err=UNZ_BADZIPFILE; ++ ++ if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); ++ ++ if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ lSeek+=file_info.size_filename; ++ if ((err==UNZ_OK) && (szFileName!=NULL)) ++ { ++ uLong uSizeRead ; ++ if (file_info.size_filename0) && (fileNameBufferSize>0)) ++ if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) ++ err=UNZ_ERRNO; ++ lSeek -= uSizeRead; ++ } ++ ++ ++ if ((err==UNZ_OK) && (extraField!=NULL)) ++ { ++ uLong uSizeRead ; ++ if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) ++ lSeek=0; ++ else ++ err=UNZ_ERRNO; ++ if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) ++ if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead) ++ err=UNZ_ERRNO; ++ lSeek += file_info.size_file_extra - uSizeRead; ++ } ++ else ++ lSeek+=file_info.size_file_extra; ++ ++ ++ if ((err==UNZ_OK) && (szComment!=NULL)) ++ { ++ uLong uSizeRead ; ++ if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) ++ lSeek=0; ++ else ++ err=UNZ_ERRNO; ++ if ((file_info.size_file_comment>0) && (commentBufferSize>0)) ++ if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) ++ err=UNZ_ERRNO; ++ lSeek+=file_info.size_file_comment - uSizeRead; ++ } ++ else ++ lSeek+=file_info.size_file_comment; ++ ++ if ((err==UNZ_OK) && (pfile_info!=NULL)) ++ *pfile_info=file_info; ++ ++ if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) ++ *pfile_info_internal=file_info_internal; ++ ++ return err; ++} ++ ++ ++ ++/* ++ Write info about the ZipFile in the *pglobal_info structure. ++ No preparation of the structure is needed ++ return UNZ_OK if there is no problem. ++*/ ++extern int ZEXPORT unzGetCurrentFileInfo (file, ++ pfile_info, ++ szFileName, fileNameBufferSize, ++ extraField, extraFieldBufferSize, ++ szComment, commentBufferSize) ++ unzFile file; ++ unz_file_info *pfile_info; ++ char *szFileName; ++ uLong fileNameBufferSize; ++ void *extraField; ++ uLong extraFieldBufferSize; ++ char *szComment; ++ uLong commentBufferSize; ++{ ++ return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, ++ szFileName,fileNameBufferSize, ++ extraField,extraFieldBufferSize, ++ szComment,commentBufferSize); ++} ++ ++/* ++ Set the current file of the zipfile to the first file. ++ return UNZ_OK if there is no problem ++*/ ++extern int ZEXPORT unzGoToFirstFile (file) ++ unzFile file; ++{ ++ int err=UNZ_OK; ++ unz_s* s; ++ if (file==NULL) ++ return UNZ_PARAMERROR; ++ s=(unz_s*)file; ++ s->pos_in_central_dir=s->offset_central_dir; ++ s->num_file=0; ++ err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, ++ &s->cur_file_info_internal, ++ NULL,0,NULL,0,NULL,0); ++ s->current_file_ok = (err == UNZ_OK); ++ return err; ++} ++ ++/* ++ Set the current file of the zipfile to the next file. ++ return UNZ_OK if there is no problem ++ return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. ++*/ ++extern int ZEXPORT unzGoToNextFile (file) ++ unzFile file; ++{ ++ unz_s* s; ++ int err; ++ ++ if (file==NULL) ++ return UNZ_PARAMERROR; ++ s=(unz_s*)file; ++ if (!s->current_file_ok) ++ return UNZ_END_OF_LIST_OF_FILE; ++ if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ ++ if (s->num_file+1==s->gi.number_entry) ++ return UNZ_END_OF_LIST_OF_FILE; ++ ++ s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + ++ s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; ++ s->num_file++; ++ err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, ++ &s->cur_file_info_internal, ++ NULL,0,NULL,0,NULL,0); ++ s->current_file_ok = (err == UNZ_OK); ++ return err; ++} ++ ++ ++/* ++ Try locate the file szFileName in the zipfile. ++ For the iCaseSensitivity signification, see unzipStringFileNameCompare ++ ++ return value : ++ UNZ_OK if the file is found. It becomes the current file. ++ UNZ_END_OF_LIST_OF_FILE if the file is not found ++*/ ++extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity) ++ unzFile file; ++ const char *szFileName; ++ int iCaseSensitivity; ++{ ++ unz_s* s; ++ int err; ++ ++ /* We remember the 'current' position in the file so that we can jump ++ * back there if we fail. ++ */ ++ unz_file_info cur_file_infoSaved; ++ unz_file_info_internal cur_file_info_internalSaved; ++ uLong num_fileSaved; ++ uLong pos_in_central_dirSaved; ++ ++ ++ if (file==NULL) ++ return UNZ_PARAMERROR; ++ ++ if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) ++ return UNZ_PARAMERROR; ++ ++ s=(unz_s*)file; ++ if (!s->current_file_ok) ++ return UNZ_END_OF_LIST_OF_FILE; ++ ++ /* Save the current state */ ++ num_fileSaved = s->num_file; ++ pos_in_central_dirSaved = s->pos_in_central_dir; ++ cur_file_infoSaved = s->cur_file_info; ++ cur_file_info_internalSaved = s->cur_file_info_internal; ++ ++ err = unzGoToFirstFile(file); ++ ++ while (err == UNZ_OK) ++ { ++ char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; ++ err = unzGetCurrentFileInfo(file,NULL, ++ szCurrentFileName,sizeof(szCurrentFileName)-1, ++ NULL,0,NULL,0); ++ if (err == UNZ_OK) ++ { ++ if (unzStringFileNameCompare(szCurrentFileName, ++ szFileName,iCaseSensitivity)==0) ++ return UNZ_OK; ++ err = unzGoToNextFile(file); ++ } ++ } ++ ++ /* We failed, so restore the state of the 'current file' to where we ++ * were. ++ */ ++ s->num_file = num_fileSaved ; ++ s->pos_in_central_dir = pos_in_central_dirSaved ; ++ s->cur_file_info = cur_file_infoSaved; ++ s->cur_file_info_internal = cur_file_info_internalSaved; ++ return err; ++} ++ ++ ++/* ++/////////////////////////////////////////// ++// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) ++// I need random access ++// ++// Further optimization could be realized by adding an ability ++// to cache the directory in memory. The goal being a single ++// comprehensive file read to put the file I need in a memory. ++*/ ++ ++/* ++typedef struct unz_file_pos_s ++{ ++ uLong pos_in_zip_directory; // offset in file ++ uLong num_of_file; // # of file ++} unz_file_pos; ++*/ ++ ++extern int ZEXPORT unzGetFilePos(file, file_pos) ++ unzFile file; ++ unz_file_pos* file_pos; ++{ ++ unz_s* s; ++ ++ if (file==NULL || file_pos==NULL) ++ return UNZ_PARAMERROR; ++ s=(unz_s*)file; ++ if (!s->current_file_ok) ++ return UNZ_END_OF_LIST_OF_FILE; ++ ++ file_pos->pos_in_zip_directory = s->pos_in_central_dir; ++ file_pos->num_of_file = s->num_file; ++ ++ return UNZ_OK; ++} ++ ++extern int ZEXPORT unzGoToFilePos(file, file_pos) ++ unzFile file; ++ unz_file_pos* file_pos; ++{ ++ unz_s* s; ++ int err; ++ ++ if (file==NULL || file_pos==NULL) ++ return UNZ_PARAMERROR; ++ s=(unz_s*)file; ++ ++ /* jump to the right spot */ ++ s->pos_in_central_dir = file_pos->pos_in_zip_directory; ++ s->num_file = file_pos->num_of_file; ++ ++ /* set the current file */ ++ err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, ++ &s->cur_file_info_internal, ++ NULL,0,NULL,0,NULL,0); ++ /* return results */ ++ s->current_file_ok = (err == UNZ_OK); ++ return err; ++} ++ ++/* ++// Unzip Helper Functions - should be here? ++/////////////////////////////////////////// ++*/ ++ ++/* ++ Read the local header of the current zipfile ++ Check the coherency of the local header and info in the end of central ++ directory about this file ++ store in *piSizeVar the size of extra info in local header ++ (filename and size of extra field data) ++*/ ++local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, ++ poffset_local_extrafield, ++ psize_local_extrafield) ++ unz_s* s; ++ uInt* piSizeVar; ++ uLong *poffset_local_extrafield; ++ uInt *psize_local_extrafield; ++{ ++ uLong uMagic,uData,uFlags; ++ uLong size_filename; ++ uLong size_extra_field; ++ int err=UNZ_OK; ++ ++ *piSizeVar = 0; ++ *poffset_local_extrafield = 0; ++ *psize_local_extrafield = 0; ++ ++ if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + ++ s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) ++ return UNZ_ERRNO; ++ ++ ++ if (err==UNZ_OK) ++ if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) ++ err=UNZ_ERRNO; ++ else if (uMagic!=0x04034b50) ++ err=UNZ_BADZIPFILE; ++ ++ if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) ++ err=UNZ_ERRNO; ++/* ++ else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) ++ err=UNZ_BADZIPFILE; ++*/ ++ if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) ++ err=UNZ_ERRNO; ++ ++ if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) ++ err=UNZ_ERRNO; ++ else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) ++ err=UNZ_BADZIPFILE; ++ ++ if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && ++ (s->cur_file_info.compression_method!=Z_DEFLATED)) ++ err=UNZ_BADZIPFILE; ++ ++ if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ ++ err=UNZ_ERRNO; ++ ++ if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ ++ err=UNZ_ERRNO; ++ else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ++ ((uFlags & 8)==0)) ++ err=UNZ_BADZIPFILE; ++ ++ if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ ++ err=UNZ_ERRNO; ++ else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ++ ((uFlags & 8)==0)) ++ err=UNZ_BADZIPFILE; ++ ++ if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ ++ err=UNZ_ERRNO; ++ else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ++ ((uFlags & 8)==0)) ++ err=UNZ_BADZIPFILE; ++ ++ ++ if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) ++ err=UNZ_ERRNO; ++ else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) ++ err=UNZ_BADZIPFILE; ++ ++ *piSizeVar += (uInt)size_filename; ++ ++ if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) ++ err=UNZ_ERRNO; ++ *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + ++ SIZEZIPLOCALHEADER + size_filename; ++ *psize_local_extrafield = (uInt)size_extra_field; ++ ++ *piSizeVar += (uInt)size_extra_field; ++ ++ return err; ++} ++ ++/* ++ Open for reading data the current file in the zipfile. ++ If there is no error and the file is opened, the return value is UNZ_OK. ++*/ ++extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password) ++ unzFile file; ++ int* method; ++ int* level; ++ int raw; ++ const char* password; ++{ ++ int err=UNZ_OK; ++ uInt iSizeVar; ++ unz_s* s; ++ file_in_zip_read_info_s* pfile_in_zip_read_info; ++ uLong offset_local_extrafield; /* offset of the local extra field */ ++ uInt size_local_extrafield; /* size of the local extra field */ ++# ifndef NOUNCRYPT ++ char source[12]; ++# else ++ if (password != NULL) ++ return UNZ_PARAMERROR; ++# endif ++ ++ if (file==NULL) ++ return UNZ_PARAMERROR; ++ s=(unz_s*)file; ++ if (!s->current_file_ok) ++ return UNZ_PARAMERROR; ++ ++ if (s->pfile_in_zip_read != NULL) ++ unzCloseCurrentFile(file); ++ ++ if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, ++ &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) ++ return UNZ_BADZIPFILE; ++ ++ pfile_in_zip_read_info = (file_in_zip_read_info_s*) ++ ALLOC(sizeof(file_in_zip_read_info_s)); ++ if (pfile_in_zip_read_info==NULL) ++ return UNZ_INTERNALERROR; ++ ++ pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); ++ pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; ++ pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; ++ pfile_in_zip_read_info->pos_local_extrafield=0; ++ pfile_in_zip_read_info->raw=raw; ++ ++ if (pfile_in_zip_read_info->read_buffer==NULL) ++ { ++ TRYFREE(pfile_in_zip_read_info); ++ return UNZ_INTERNALERROR; ++ } ++ ++ pfile_in_zip_read_info->stream_initialised=0; ++ ++ if (method!=NULL) ++ *method = (int)s->cur_file_info.compression_method; ++ ++ if (level!=NULL) ++ { ++ *level = 6; ++ switch (s->cur_file_info.flag & 0x06) ++ { ++ case 6 : *level = 1; break; ++ case 4 : *level = 2; break; ++ case 2 : *level = 9; break; ++ } ++ } ++ ++ if ((s->cur_file_info.compression_method!=0) && ++ (s->cur_file_info.compression_method!=Z_DEFLATED)) ++ err=UNZ_BADZIPFILE; ++ ++ pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; ++ pfile_in_zip_read_info->crc32=0; ++ pfile_in_zip_read_info->compression_method = ++ s->cur_file_info.compression_method; ++ pfile_in_zip_read_info->filestream=s->filestream; ++ pfile_in_zip_read_info->z_filefunc=s->z_filefunc; ++ pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; ++ ++ pfile_in_zip_read_info->stream.total_out = 0; ++ ++ if ((s->cur_file_info.compression_method==Z_DEFLATED) && ++ (!raw)) ++ { ++ pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; ++ pfile_in_zip_read_info->stream.zfree = (free_func)0; ++ pfile_in_zip_read_info->stream.opaque = (voidpf)0; ++ pfile_in_zip_read_info->stream.next_in = (voidpf)0; ++ pfile_in_zip_read_info->stream.avail_in = 0; ++ ++ err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); ++ if (err == Z_OK) ++ pfile_in_zip_read_info->stream_initialised=1; ++ else ++ { ++ TRYFREE(pfile_in_zip_read_info); ++ return err; ++ } ++ /* windowBits is passed < 0 to tell that there is no zlib header. ++ * Note that in this case inflate *requires* an extra "dummy" byte ++ * after the compressed stream in order to complete decompression and ++ * return Z_STREAM_END. ++ * In unzip, i don't wait absolutely Z_STREAM_END because I known the ++ * size of both compressed and uncompressed data ++ */ ++ } ++ pfile_in_zip_read_info->rest_read_compressed = ++ s->cur_file_info.compressed_size ; ++ pfile_in_zip_read_info->rest_read_uncompressed = ++ s->cur_file_info.uncompressed_size ; ++ ++ ++ pfile_in_zip_read_info->pos_in_zipfile = ++ s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + ++ iSizeVar; ++ ++ pfile_in_zip_read_info->stream.avail_in = (uInt)0; ++ ++ s->pfile_in_zip_read = pfile_in_zip_read_info; ++ ++# ifndef NOUNCRYPT ++ if (password != NULL) ++ { ++ int i; ++ s->pcrc_32_tab = get_crc_table(); ++ init_keys(password,s->keys,s->pcrc_32_tab); ++ if (ZSEEK(s->z_filefunc, s->filestream, ++ s->pfile_in_zip_read->pos_in_zipfile + ++ s->pfile_in_zip_read->byte_before_the_zipfile, ++ SEEK_SET)!=0) ++ return UNZ_INTERNALERROR; ++ if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12) ++ return UNZ_INTERNALERROR; ++ ++ for (i = 0; i<12; i++) ++ zdecode(s->keys,s->pcrc_32_tab,source[i]); ++ ++ s->pfile_in_zip_read->pos_in_zipfile+=12; ++ s->encrypted=1; ++ } ++# endif ++ ++ ++ return UNZ_OK; ++} ++ ++extern int ZEXPORT unzOpenCurrentFile (file) ++ unzFile file; ++{ ++ return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); ++} ++ ++extern int ZEXPORT unzOpenCurrentFilePassword (file, password) ++ unzFile file; ++ const char* password; ++{ ++ return unzOpenCurrentFile3(file, NULL, NULL, 0, password); ++} ++ ++extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw) ++ unzFile file; ++ int* method; ++ int* level; ++ int raw; ++{ ++ return unzOpenCurrentFile3(file, method, level, raw, NULL); ++} ++ ++/* ++ Read bytes from the current file. ++ buf contain buffer where data must be copied ++ len the size of buf. ++ ++ return the number of byte copied if somes bytes are copied ++ return 0 if the end of file was reached ++ return <0 with error code if there is an error ++ (UNZ_ERRNO for IO error, or zLib error for uncompress error) ++*/ ++extern int ZEXPORT unzReadCurrentFile (file, buf, len) ++ unzFile file; ++ voidp buf; ++ unsigned len; ++{ ++ int err=UNZ_OK; ++ uInt iRead = 0; ++ unz_s* s; ++ file_in_zip_read_info_s* pfile_in_zip_read_info; ++ if (file==NULL) ++ return UNZ_PARAMERROR; ++ s=(unz_s*)file; ++ pfile_in_zip_read_info=s->pfile_in_zip_read; ++ ++ if (pfile_in_zip_read_info==NULL) ++ return UNZ_PARAMERROR; ++ ++ ++ if (pfile_in_zip_read_info->read_buffer == NULL) ++ return UNZ_END_OF_LIST_OF_FILE; ++ if (len==0) ++ return 0; ++ ++ pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; ++ ++ pfile_in_zip_read_info->stream.avail_out = (uInt)len; ++ ++ if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && ++ (!(pfile_in_zip_read_info->raw))) ++ pfile_in_zip_read_info->stream.avail_out = ++ (uInt)pfile_in_zip_read_info->rest_read_uncompressed; ++ ++ if ((len>pfile_in_zip_read_info->rest_read_compressed+ ++ pfile_in_zip_read_info->stream.avail_in) && ++ (pfile_in_zip_read_info->raw)) ++ pfile_in_zip_read_info->stream.avail_out = ++ (uInt)pfile_in_zip_read_info->rest_read_compressed+ ++ pfile_in_zip_read_info->stream.avail_in; ++ ++ while (pfile_in_zip_read_info->stream.avail_out>0) ++ { ++ if ((pfile_in_zip_read_info->stream.avail_in==0) && ++ (pfile_in_zip_read_info->rest_read_compressed>0)) ++ { ++ uInt uReadThis = UNZ_BUFSIZE; ++ if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; ++ if (uReadThis == 0) ++ return UNZ_EOF; ++ if (ZSEEK(pfile_in_zip_read_info->z_filefunc, ++ pfile_in_zip_read_info->filestream, ++ pfile_in_zip_read_info->pos_in_zipfile + ++ pfile_in_zip_read_info->byte_before_the_zipfile, ++ ZLIB_FILEFUNC_SEEK_SET)!=0) ++ return UNZ_ERRNO; ++ if (ZREAD(pfile_in_zip_read_info->z_filefunc, ++ pfile_in_zip_read_info->filestream, ++ pfile_in_zip_read_info->read_buffer, ++ uReadThis)!=uReadThis) ++ return UNZ_ERRNO; ++ ++ ++# ifndef NOUNCRYPT ++ if(s->encrypted) ++ { ++ uInt i; ++ for(i=0;iread_buffer[i] = ++ zdecode(s->keys,s->pcrc_32_tab, ++ pfile_in_zip_read_info->read_buffer[i]); ++ } ++# endif ++ ++ ++ pfile_in_zip_read_info->pos_in_zipfile += uReadThis; ++ ++ pfile_in_zip_read_info->rest_read_compressed-=uReadThis; ++ ++ pfile_in_zip_read_info->stream.next_in = ++ (Bytef*)pfile_in_zip_read_info->read_buffer; ++ pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; ++ } ++ ++ if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) ++ { ++ uInt uDoCopy,i ; ++ ++ if ((pfile_in_zip_read_info->stream.avail_in == 0) && ++ (pfile_in_zip_read_info->rest_read_compressed == 0)) ++ return (iRead==0) ? UNZ_EOF : iRead; ++ ++ if (pfile_in_zip_read_info->stream.avail_out < ++ pfile_in_zip_read_info->stream.avail_in) ++ uDoCopy = pfile_in_zip_read_info->stream.avail_out ; ++ else ++ uDoCopy = pfile_in_zip_read_info->stream.avail_in ; ++ ++ for (i=0;istream.next_out+i) = ++ *(pfile_in_zip_read_info->stream.next_in+i); ++ ++ pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, ++ pfile_in_zip_read_info->stream.next_out, ++ uDoCopy); ++ pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; ++ pfile_in_zip_read_info->stream.avail_in -= uDoCopy; ++ pfile_in_zip_read_info->stream.avail_out -= uDoCopy; ++ pfile_in_zip_read_info->stream.next_out += uDoCopy; ++ pfile_in_zip_read_info->stream.next_in += uDoCopy; ++ pfile_in_zip_read_info->stream.total_out += uDoCopy; ++ iRead += uDoCopy; ++ } ++ else ++ { ++ uLong uTotalOutBefore,uTotalOutAfter; ++ const Bytef *bufBefore; ++ uLong uOutThis; ++ int flush=Z_SYNC_FLUSH; ++ ++ uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; ++ bufBefore = pfile_in_zip_read_info->stream.next_out; ++ ++ /* ++ if ((pfile_in_zip_read_info->rest_read_uncompressed == ++ pfile_in_zip_read_info->stream.avail_out) && ++ (pfile_in_zip_read_info->rest_read_compressed == 0)) ++ flush = Z_FINISH; ++ */ ++ err=inflate(&pfile_in_zip_read_info->stream,flush); ++ ++ if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) ++ err = Z_DATA_ERROR; ++ ++ uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; ++ uOutThis = uTotalOutAfter-uTotalOutBefore; ++ ++ pfile_in_zip_read_info->crc32 = ++ crc32(pfile_in_zip_read_info->crc32,bufBefore, ++ (uInt)(uOutThis)); ++ ++ pfile_in_zip_read_info->rest_read_uncompressed -= ++ uOutThis; ++ ++ iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); ++ ++ if (err==Z_STREAM_END) ++ return (iRead==0) ? UNZ_EOF : iRead; ++ if (err!=Z_OK) ++ break; ++ } ++ } ++ ++ if (err==Z_OK) ++ return iRead; ++ return err; ++} ++ ++ ++/* ++ Give the current position in uncompressed data ++*/ ++extern z_off_t ZEXPORT unztell (file) ++ unzFile file; ++{ ++ unz_s* s; ++ file_in_zip_read_info_s* pfile_in_zip_read_info; ++ if (file==NULL) ++ return UNZ_PARAMERROR; ++ s=(unz_s*)file; ++ pfile_in_zip_read_info=s->pfile_in_zip_read; ++ ++ if (pfile_in_zip_read_info==NULL) ++ return UNZ_PARAMERROR; ++ ++ return (z_off_t)pfile_in_zip_read_info->stream.total_out; ++} ++ ++ ++/* ++ return 1 if the end of file was reached, 0 elsewhere ++*/ ++extern int ZEXPORT unzeof (file) ++ unzFile file; ++{ ++ unz_s* s; ++ file_in_zip_read_info_s* pfile_in_zip_read_info; ++ if (file==NULL) ++ return UNZ_PARAMERROR; ++ s=(unz_s*)file; ++ pfile_in_zip_read_info=s->pfile_in_zip_read; ++ ++ if (pfile_in_zip_read_info==NULL) ++ return UNZ_PARAMERROR; ++ ++ if (pfile_in_zip_read_info->rest_read_uncompressed == 0) ++ return 1; ++ else ++ return 0; ++} ++ ++ ++ ++/* ++ Read extra field from the current file (opened by unzOpenCurrentFile) ++ This is the local-header version of the extra field (sometimes, there is ++ more info in the local-header version than in the central-header) ++ ++ if buf==NULL, it return the size of the local extra field that can be read ++ ++ if buf!=NULL, len is the size of the buffer, the extra header is copied in ++ buf. ++ the return value is the number of bytes copied in buf, or (if <0) ++ the error code ++*/ ++extern int ZEXPORT unzGetLocalExtrafield (file,buf,len) ++ unzFile file; ++ voidp buf; ++ unsigned len; ++{ ++ unz_s* s; ++ file_in_zip_read_info_s* pfile_in_zip_read_info; ++ uInt read_now; ++ uLong size_to_read; ++ ++ if (file==NULL) ++ return UNZ_PARAMERROR; ++ s=(unz_s*)file; ++ pfile_in_zip_read_info=s->pfile_in_zip_read; ++ ++ if (pfile_in_zip_read_info==NULL) ++ return UNZ_PARAMERROR; ++ ++ size_to_read = (pfile_in_zip_read_info->size_local_extrafield - ++ pfile_in_zip_read_info->pos_local_extrafield); ++ ++ if (buf==NULL) ++ return (int)size_to_read; ++ ++ if (len>size_to_read) ++ read_now = (uInt)size_to_read; ++ else ++ read_now = (uInt)len ; ++ ++ if (read_now==0) ++ return 0; ++ ++ if (ZSEEK(pfile_in_zip_read_info->z_filefunc, ++ pfile_in_zip_read_info->filestream, ++ pfile_in_zip_read_info->offset_local_extrafield + ++ pfile_in_zip_read_info->pos_local_extrafield, ++ ZLIB_FILEFUNC_SEEK_SET)!=0) ++ return UNZ_ERRNO; ++ ++ if (ZREAD(pfile_in_zip_read_info->z_filefunc, ++ pfile_in_zip_read_info->filestream, ++ buf,read_now)!=read_now) ++ return UNZ_ERRNO; ++ ++ return (int)read_now; ++} ++ ++/* ++ Close the file in zip opened with unzipOpenCurrentFile ++ Return UNZ_CRCERROR if all the file was read but the CRC is not good ++*/ ++extern int ZEXPORT unzCloseCurrentFile (file) ++ unzFile file; ++{ ++ int err=UNZ_OK; ++ ++ unz_s* s; ++ file_in_zip_read_info_s* pfile_in_zip_read_info; ++ if (file==NULL) ++ return UNZ_PARAMERROR; ++ s=(unz_s*)file; ++ pfile_in_zip_read_info=s->pfile_in_zip_read; ++ ++ if (pfile_in_zip_read_info==NULL) ++ return UNZ_PARAMERROR; ++ ++ ++ if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && ++ (!pfile_in_zip_read_info->raw)) ++ { ++ if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) ++ err=UNZ_CRCERROR; ++ } ++ ++ ++ TRYFREE(pfile_in_zip_read_info->read_buffer); ++ pfile_in_zip_read_info->read_buffer = NULL; ++ if (pfile_in_zip_read_info->stream_initialised) ++ inflateEnd(&pfile_in_zip_read_info->stream); ++ ++ pfile_in_zip_read_info->stream_initialised = 0; ++ TRYFREE(pfile_in_zip_read_info); ++ ++ s->pfile_in_zip_read=NULL; ++ ++ return err; ++} ++ ++ ++/* ++ Get the global comment string of the ZipFile, in the szComment buffer. ++ uSizeBuf is the size of the szComment buffer. ++ return the number of byte copied or an error code <0 ++*/ ++extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf) ++ unzFile file; ++ char *szComment; ++ uLong uSizeBuf; ++{ ++// int err=UNZ_OK; ++ unz_s* s; ++ uLong uReadThis ; ++ if (file==NULL) ++ return UNZ_PARAMERROR; ++ s=(unz_s*)file; ++ ++ uReadThis = uSizeBuf; ++ if (uReadThis>s->gi.size_comment) ++ uReadThis = s->gi.size_comment; ++ ++ if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) ++ return UNZ_ERRNO; ++ ++ if (uReadThis>0) ++ { ++ *szComment='\0'; ++ if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) ++ return UNZ_ERRNO; ++ } ++ ++ if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) ++ *(szComment+s->gi.size_comment)='\0'; ++ return (int)uReadThis; ++} ++ ++/* Additions by RX '2004 */ ++extern uLong ZEXPORT unzGetOffset (file) ++ unzFile file; ++{ ++ unz_s* s; ++ ++ if (file==NULL) ++ return UNZ_PARAMERROR; ++ s=(unz_s*)file; ++ if (!s->current_file_ok) ++ return 0; ++ if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) ++ if (s->num_file==s->gi.number_entry) ++ return 0; ++ return s->pos_in_central_dir; ++} ++ ++extern int ZEXPORT unzSetOffset (file, pos) ++ unzFile file; ++ uLong pos; ++{ ++ unz_s* s; ++ int err; ++ ++ if (file==NULL) ++ return UNZ_PARAMERROR; ++ s=(unz_s*)file; ++ ++ s->pos_in_central_dir = pos; ++ s->num_file = s->gi.number_entry; /* hack */ ++ err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, ++ &s->cur_file_info_internal, ++ NULL,0,NULL,0,NULL,0); ++ s->current_file_ok = (err == UNZ_OK); ++ return err; ++} +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/unzip.h b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/unzip.h +new file mode 100644 +index 0000000..b247937 +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/unzip.h +@@ -0,0 +1,354 @@ ++/* unzip.h -- IO for uncompress .zip files using zlib ++ Version 1.01e, February 12th, 2005 ++ ++ Copyright (C) 1998-2005 Gilles Vollant ++ ++ This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g ++ WinZip, InfoZip tools and compatible. ++ ++ Multi volume ZipFile (span) are not supported. ++ Encryption compatible with pkzip 2.04g only supported ++ Old compressions used by old PKZip 1.x are not supported ++ ++ ++ I WAIT FEEDBACK at mail info@winimage.com ++ Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution ++ ++ Condition of use and distribution are the same than zlib : ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++ ++ ++*/ ++ ++/* for more info about .ZIP format, see ++ http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip ++ http://www.info-zip.org/pub/infozip/doc/ ++ PkWare has also a specification at : ++ ftp://ftp.pkware.com/probdesc.zip ++*/ ++ ++#ifndef _unz_H ++#define _unz_H ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#ifndef _ZLIB_H ++#include "zlib.h" ++#endif ++ ++#ifndef _ZLIBIOAPI_H ++#include "ioapi.h" ++#endif ++ ++#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) ++/* like the STRICT of WIN32, we define a pointer that cannot be converted ++ from (void*) without cast */ ++typedef struct TagunzFile__ { int unused; } unzFile__; ++typedef unzFile__ *unzFile; ++#else ++typedef voidp unzFile; ++#endif ++ ++ ++#define UNZ_OK (0) ++#define UNZ_END_OF_LIST_OF_FILE (-100) ++#define UNZ_ERRNO (Z_ERRNO) ++#define UNZ_EOF (0) ++#define UNZ_PARAMERROR (-102) ++#define UNZ_BADZIPFILE (-103) ++#define UNZ_INTERNALERROR (-104) ++#define UNZ_CRCERROR (-105) ++ ++/* tm_unz contain date/time info */ ++typedef struct tm_unz_s ++{ ++ uInt tm_sec; /* seconds after the minute - [0,59] */ ++ uInt tm_min; /* minutes after the hour - [0,59] */ ++ uInt tm_hour; /* hours since midnight - [0,23] */ ++ uInt tm_mday; /* day of the month - [1,31] */ ++ uInt tm_mon; /* months since January - [0,11] */ ++ uInt tm_year; /* years - [1980..2044] */ ++} tm_unz; ++ ++/* unz_global_info structure contain global data about the ZIPfile ++ These data comes from the end of central dir */ ++typedef struct unz_global_info_s ++{ ++ uLong number_entry; /* total number of entries in ++ the central dir on this disk */ ++ uLong size_comment; /* size of the global comment of the zipfile */ ++} unz_global_info; ++ ++ ++/* unz_file_info contain information about a file in the zipfile */ ++typedef struct unz_file_info_s ++{ ++ uLong version; /* version made by 2 bytes */ ++ uLong version_needed; /* version needed to extract 2 bytes */ ++ uLong flag; /* general purpose bit flag 2 bytes */ ++ uLong compression_method; /* compression method 2 bytes */ ++ uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ ++ uLong crc; /* crc-32 4 bytes */ ++ uLong compressed_size; /* compressed size 4 bytes */ ++ uLong uncompressed_size; /* uncompressed size 4 bytes */ ++ uLong size_filename; /* filename length 2 bytes */ ++ uLong size_file_extra; /* extra field length 2 bytes */ ++ uLong size_file_comment; /* file comment length 2 bytes */ ++ ++ uLong disk_num_start; /* disk number start 2 bytes */ ++ uLong internal_fa; /* internal file attributes 2 bytes */ ++ uLong external_fa; /* external file attributes 4 bytes */ ++ ++ tm_unz tmu_date; ++} unz_file_info; ++ ++extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, ++ const char* fileName2, ++ int iCaseSensitivity)); ++/* ++ Compare two filename (fileName1,fileName2). ++ If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) ++ If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi ++ or strcasecmp) ++ If iCaseSenisivity = 0, case sensitivity is defaut of your operating system ++ (like 1 on Unix, 2 on Windows) ++*/ ++ ++ ++extern unzFile ZEXPORT unzOpen OF((const char *path)); ++/* ++ Open a Zip file. path contain the full pathname (by example, ++ on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer ++ "zlib/zlib113.zip". ++ If the zipfile cannot be opened (file don't exist or in not valid), the ++ return value is NULL. ++ Else, the return value is a unzFile Handle, usable with other function ++ of this unzip package. ++*/ ++ ++extern unzFile ZEXPORT unzOpen2 OF((const char *path, ++ zlib_filefunc_def* pzlib_filefunc_def)); ++/* ++ Open a Zip file, like unzOpen, but provide a set of file low level API ++ for read/write the zip file (see ioapi.h) ++*/ ++ ++extern int ZEXPORT unzClose OF((unzFile file)); ++/* ++ Close a ZipFile opened with unzipOpen. ++ If there is files inside the .Zip opened with unzOpenCurrentFile (see later), ++ these files MUST be closed with unzipCloseCurrentFile before call unzipClose. ++ return UNZ_OK if there is no problem. */ ++ ++extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, ++ unz_global_info *pglobal_info)); ++/* ++ Write info about the ZipFile in the *pglobal_info structure. ++ No preparation of the structure is needed ++ return UNZ_OK if there is no problem. */ ++ ++ ++extern int ZEXPORT unzGetGlobalComment OF((unzFile file, ++ char *szComment, ++ uLong uSizeBuf)); ++/* ++ Get the global comment string of the ZipFile, in the szComment buffer. ++ uSizeBuf is the size of the szComment buffer. ++ return the number of byte copied or an error code <0 ++*/ ++ ++ ++/***************************************************************************/ ++/* Unzip package allow you browse the directory of the zipfile */ ++ ++extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); ++/* ++ Set the current file of the zipfile to the first file. ++ return UNZ_OK if there is no problem ++*/ ++ ++extern int ZEXPORT unzGoToNextFile OF((unzFile file)); ++/* ++ Set the current file of the zipfile to the next file. ++ return UNZ_OK if there is no problem ++ return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. ++*/ ++ ++extern int ZEXPORT unzLocateFile OF((unzFile file, ++ const char *szFileName, ++ int iCaseSensitivity)); ++/* ++ Try locate the file szFileName in the zipfile. ++ For the iCaseSensitivity signification, see unzStringFileNameCompare ++ ++ return value : ++ UNZ_OK if the file is found. It becomes the current file. ++ UNZ_END_OF_LIST_OF_FILE if the file is not found ++*/ ++ ++ ++/* ****************************************** */ ++/* Ryan supplied functions */ ++/* unz_file_info contain information about a file in the zipfile */ ++typedef struct unz_file_pos_s ++{ ++ uLong pos_in_zip_directory; /* offset in zip file directory */ ++ uLong num_of_file; /* # of file */ ++} unz_file_pos; ++ ++extern int ZEXPORT unzGetFilePos( ++ unzFile file, ++ unz_file_pos* file_pos); ++ ++extern int ZEXPORT unzGoToFilePos( ++ unzFile file, ++ unz_file_pos* file_pos); ++ ++/* ****************************************** */ ++ ++extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, ++ unz_file_info *pfile_info, ++ char *szFileName, ++ uLong fileNameBufferSize, ++ void *extraField, ++ uLong extraFieldBufferSize, ++ char *szComment, ++ uLong commentBufferSize)); ++/* ++ Get Info about the current file ++ if pfile_info!=NULL, the *pfile_info structure will contain somes info about ++ the current file ++ if szFileName!=NULL, the filemane string will be copied in szFileName ++ (fileNameBufferSize is the size of the buffer) ++ if extraField!=NULL, the extra field information will be copied in extraField ++ (extraFieldBufferSize is the size of the buffer). ++ This is the Central-header version of the extra field ++ if szComment!=NULL, the comment string of the file will be copied in szComment ++ (commentBufferSize is the size of the buffer) ++*/ ++ ++/***************************************************************************/ ++/* for reading the content of the current zipfile, you can open it, read data ++ from it, and close it (you can close it before reading all the file) ++ */ ++ ++extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); ++/* ++ Open for reading data the current file in the zipfile. ++ If there is no error, the return value is UNZ_OK. ++*/ ++ ++extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, ++ const char* password)); ++/* ++ Open for reading data the current file in the zipfile. ++ password is a crypting password ++ If there is no error, the return value is UNZ_OK. ++*/ ++ ++extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, ++ int* method, ++ int* level, ++ int raw)); ++/* ++ Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) ++ if raw==1 ++ *method will receive method of compression, *level will receive level of ++ compression ++ note : you can set level parameter as NULL (if you did not want known level, ++ but you CANNOT set method parameter as NULL ++*/ ++ ++extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, ++ int* method, ++ int* level, ++ int raw, ++ const char* password)); ++/* ++ Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) ++ if raw==1 ++ *method will receive method of compression, *level will receive level of ++ compression ++ note : you can set level parameter as NULL (if you did not want known level, ++ but you CANNOT set method parameter as NULL ++*/ ++ ++ ++extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); ++/* ++ Close the file in zip opened with unzOpenCurrentFile ++ Return UNZ_CRCERROR if all the file was read but the CRC is not good ++*/ ++ ++extern int ZEXPORT unzReadCurrentFile OF((unzFile file, ++ voidp buf, ++ unsigned len)); ++/* ++ Read bytes from the current file (opened by unzOpenCurrentFile) ++ buf contain buffer where data must be copied ++ len the size of buf. ++ ++ return the number of byte copied if somes bytes are copied ++ return 0 if the end of file was reached ++ return <0 with error code if there is an error ++ (UNZ_ERRNO for IO error, or zLib error for uncompress error) ++*/ ++ ++extern z_off_t ZEXPORT unztell OF((unzFile file)); ++/* ++ Give the current position in uncompressed data ++*/ ++ ++extern int ZEXPORT unzeof OF((unzFile file)); ++/* ++ return 1 if the end of file was reached, 0 elsewhere ++*/ ++ ++extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, ++ voidp buf, ++ unsigned len)); ++/* ++ Read extra field from the current file (opened by unzOpenCurrentFile) ++ This is the local-header version of the extra field (sometimes, there is ++ more info in the local-header version than in the central-header) ++ ++ if buf==NULL, it return the size of the local extra field ++ ++ if buf!=NULL, len is the size of the buffer, the extra header is copied in ++ buf. ++ the return value is the number of bytes copied in buf, or (if <0) ++ the error code ++*/ ++ ++/***************************************************************************/ ++ ++/* Get the current file offset */ ++extern uLong ZEXPORT unzGetOffset (unzFile file); ++ ++/* Set the current file offset */ ++extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); ++ ++ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _unz_H */ +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/zip.c b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/zip.c +new file mode 100644 +index 0000000..e261706 +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/zip.c +@@ -0,0 +1,1214 @@ ++/* zip.c -- IO on .zip files using zlib ++ Version 1.01e, February 12th, 2005 ++ ++ 27 Dec 2004 Rolf Kalbermatter ++ Modification to zipOpen2 to support globalComment retrieval. ++ ++ Copyright (C) 1998-2005 Gilles Vollant ++ ++ Read zip.h for more info ++*/ ++ ++#define NOCRYPT ++#define NOUNCRYPT ++ ++#include ++#include ++#include ++#include ++#include "zlib.h" ++#include "zip.h" ++ ++#ifdef STDC ++# include ++# include ++# include ++#endif ++#ifdef NO_ERRNO_H ++ extern int errno; ++#else ++# include ++#endif ++ ++ ++#ifndef local ++# define local static ++#endif ++/* compile with -Dlocal if your debugger can't find static symbols */ ++ ++#ifndef VERSIONMADEBY ++# define VERSIONMADEBY (0x0) /* platform depedent */ ++#endif ++ ++#ifndef Z_BUFSIZE ++#define Z_BUFSIZE (16384) ++#endif ++ ++#ifndef Z_MAXFILENAMEINZIP ++#define Z_MAXFILENAMEINZIP (256) ++#endif ++ ++#ifndef ALLOC ++# define ALLOC(size) (malloc(size)) ++#endif ++#ifndef TRYFREE ++# define TRYFREE(p) {if (p) free(p);} ++#endif ++ ++/* ++#define SIZECENTRALDIRITEM (0x2e) ++#define SIZEZIPLOCALHEADER (0x1e) ++*/ ++ ++/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ ++ ++#ifndef SEEK_CUR ++#define SEEK_CUR 1 ++#endif ++ ++#ifndef SEEK_END ++#define SEEK_END 2 ++#endif ++ ++#ifndef SEEK_SET ++#define SEEK_SET 0 ++#endif ++ ++#ifndef DEF_MEM_LEVEL ++#if MAX_MEM_LEVEL >= 8 ++# define DEF_MEM_LEVEL 8 ++#else ++# define DEF_MEM_LEVEL MAX_MEM_LEVEL ++#endif ++#endif ++const char zip_copyright[] = ++ " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; ++ ++ ++#define SIZEDATA_INDATABLOCK (4096-(4*4)) ++ ++#define LOCALHEADERMAGIC (0x04034b50) ++#define CENTRALHEADERMAGIC (0x02014b50) ++#define ENDHEADERMAGIC (0x06054b50) ++ ++#define FLAG_LOCALHEADER_OFFSET (0x06) ++#define CRC_LOCALHEADER_OFFSET (0x0e) ++ ++#define SIZECENTRALHEADER (0x2e) /* 46 */ ++ ++typedef struct linkedlist_datablock_internal_s ++{ ++ struct linkedlist_datablock_internal_s* next_datablock; ++ uLong avail_in_this_block; ++ uLong filled_in_this_block; ++ uLong unused; /* for future use and alignement */ ++ unsigned char data[SIZEDATA_INDATABLOCK]; ++} linkedlist_datablock_internal; ++ ++typedef struct linkedlist_data_s ++{ ++ linkedlist_datablock_internal* first_block; ++ linkedlist_datablock_internal* last_block; ++} linkedlist_data; ++ ++ ++typedef struct ++{ ++ z_stream stream; /* zLib stream structure for inflate */ ++ int stream_initialised; /* 1 is stream is initialised */ ++ uInt pos_in_buffered_data; /* last written byte in buffered_data */ ++ ++ uLong pos_local_header; /* offset of the local header of the file ++ currenty writing */ ++ char* central_header; /* central header data for the current file */ ++ uLong size_centralheader; /* size of the central header for cur file */ ++ uLong flag; /* flag of the file currently writing */ ++ ++ int method; /* compression method of file currenty wr.*/ ++ int raw; /* 1 for directly writing raw data */ ++ Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ ++ uLong dosDate; ++ uLong crc32; ++ int encrypt; ++#ifndef NOCRYPT ++ unsigned long keys[3]; /* keys defining the pseudo-random sequence */ ++ const unsigned long* pcrc_32_tab; ++ int crypt_header_size; ++#endif ++} curfile_info; ++ ++typedef struct ++{ ++ zlib_filefunc_def z_filefunc; ++ voidpf filestream; /* io structore of the zipfile */ ++ linkedlist_data central_dir;/* datablock with central dir in construction*/ ++ int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ ++ curfile_info ci; /* info on the file curretly writing */ ++ ++ uLong begin_pos; /* position of the beginning of the zipfile */ ++ uLong add_position_when_writting_offset; ++ uLong number_entry; ++#ifndef NO_ADDFILEINEXISTINGZIP ++ char *globalcomment; ++#endif ++} zip_internal; ++ ++ ++ ++#ifndef NOCRYPT ++#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED ++#include "crypt.h" ++#endif ++ ++local linkedlist_datablock_internal* allocate_new_datablock() ++{ ++ linkedlist_datablock_internal* ldi; ++ ldi = (linkedlist_datablock_internal*) ++ ALLOC(sizeof(linkedlist_datablock_internal)); ++ if (ldi!=NULL) ++ { ++ ldi->next_datablock = NULL ; ++ ldi->filled_in_this_block = 0 ; ++ ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; ++ } ++ return ldi; ++} ++ ++local void free_datablock(ldi) ++ linkedlist_datablock_internal* ldi; ++{ ++ while (ldi!=NULL) ++ { ++ linkedlist_datablock_internal* ldinext = ldi->next_datablock; ++ TRYFREE(ldi); ++ ldi = ldinext; ++ } ++} ++ ++local void init_linkedlist(ll) ++ linkedlist_data* ll; ++{ ++ ll->first_block = ll->last_block = NULL; ++} ++ ++local int add_data_in_datablock(ll,buf,len) ++ linkedlist_data* ll; ++ const void* buf; ++ uLong len; ++{ ++ linkedlist_datablock_internal* ldi; ++ const unsigned char* from_copy; ++ ++ if (ll==NULL) ++ return ZIP_INTERNALERROR; ++ ++ if (ll->last_block == NULL) ++ { ++ ll->first_block = ll->last_block = allocate_new_datablock(); ++ if (ll->first_block == NULL) ++ return ZIP_INTERNALERROR; ++ } ++ ++ ldi = ll->last_block; ++ from_copy = (unsigned char*)buf; ++ ++ while (len>0) ++ { ++ uInt copy_this; ++ uInt i; ++ unsigned char* to_copy; ++ ++ if (ldi->avail_in_this_block==0) ++ { ++ ldi->next_datablock = allocate_new_datablock(); ++ if (ldi->next_datablock == NULL) ++ return ZIP_INTERNALERROR; ++ ldi = ldi->next_datablock ; ++ ll->last_block = ldi; ++ } ++ ++ if (ldi->avail_in_this_block < len) ++ copy_this = (uInt)ldi->avail_in_this_block; ++ else ++ copy_this = (uInt)len; ++ ++ to_copy = &(ldi->data[ldi->filled_in_this_block]); ++ ++ for (i=0;ifilled_in_this_block += copy_this; ++ ldi->avail_in_this_block -= copy_this; ++ from_copy += copy_this ; ++ len -= copy_this; ++ } ++ return ZIP_OK; ++} ++ ++ ++ ++/****************************************************************************/ ++ ++#ifndef NO_ADDFILEINEXISTINGZIP ++/* =========================================================================== ++ Inputs a long in LSB order to the given file ++ nbByte == 1, 2 or 4 (byte, short or long) ++*/ ++ ++local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def, ++ voidpf filestream, uLong x, int nbByte)); ++local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte) ++ const zlib_filefunc_def* pzlib_filefunc_def; ++ voidpf filestream; ++ uLong x; ++ int nbByte; ++{ ++ unsigned char buf[4]; ++ int n; ++ for (n = 0; n < nbByte; n++) ++ { ++ buf[n] = (unsigned char)(x & 0xff); ++ x >>= 8; ++ } ++ if (x != 0) ++ { /* data overflow - hack for ZIP64 (X Roche) */ ++ for (n = 0; n < nbByte; n++) ++ { ++ buf[n] = 0xff; ++ } ++ } ++ ++ if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) ++ return ZIP_ERRNO; ++ else ++ return ZIP_OK; ++} ++ ++local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte)); ++local void ziplocal_putValue_inmemory (dest, x, nbByte) ++ void* dest; ++ uLong x; ++ int nbByte; ++{ ++ unsigned char* buf=(unsigned char*)dest; ++ int n; ++ for (n = 0; n < nbByte; n++) { ++ buf[n] = (unsigned char)(x & 0xff); ++ x >>= 8; ++ } ++ ++ if (x != 0) ++ { /* data overflow - hack for ZIP64 */ ++ for (n = 0; n < nbByte; n++) ++ { ++ buf[n] = 0xff; ++ } ++ } ++} ++ ++/****************************************************************************/ ++ ++ ++local uLong ziplocal_TmzDateToDosDate(ptm,dosDate) ++ const tm_zip* ptm; ++ uLong dosDate; ++{ ++ uLong year = (uLong)ptm->tm_year; ++ if (year>1980) ++ year-=1980; ++ else if (year>80) ++ year-=80; ++ return ++ (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | ++ ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); ++} ++ ++ ++/****************************************************************************/ ++ ++local int ziplocal_getByte OF(( ++ const zlib_filefunc_def* pzlib_filefunc_def, ++ voidpf filestream, ++ int *pi)); ++ ++local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi) ++ const zlib_filefunc_def* pzlib_filefunc_def; ++ voidpf filestream; ++ int *pi; ++{ ++ unsigned char c; ++ int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); ++ if (err==1) ++ { ++ *pi = (int)c; ++ return ZIP_OK; ++ } ++ else ++ { ++ if (ZERROR(*pzlib_filefunc_def,filestream)) ++ return ZIP_ERRNO; ++ else ++ return ZIP_EOF; ++ } ++} ++ ++ ++/* =========================================================================== ++ Reads a long in LSB order from the given gz_stream. Sets ++*/ ++local int ziplocal_getShort OF(( ++ const zlib_filefunc_def* pzlib_filefunc_def, ++ voidpf filestream, ++ uLong *pX)); ++ ++local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX) ++ const zlib_filefunc_def* pzlib_filefunc_def; ++ voidpf filestream; ++ uLong *pX; ++{ ++ uLong x = 0; ++ int i = 0; ++ int err = 0; ++ ++ err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); ++ x = (uLong)i; ++ ++ if (err==ZIP_OK) ++ err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); ++ x += ((uLong)i)<<8; ++ ++ if (err==ZIP_OK) ++ *pX = x; ++ else ++ *pX = 0; ++ return err; ++} ++ ++local int ziplocal_getLong OF(( ++ const zlib_filefunc_def* pzlib_filefunc_def, ++ voidpf filestream, ++ uLong *pX)); ++ ++local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX) ++ const zlib_filefunc_def* pzlib_filefunc_def; ++ voidpf filestream; ++ uLong *pX; ++{ ++ uLong x =0; ++ int i=0; ++ int err=0; ++ ++ err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); ++ x = (uLong)i; ++ ++ if (err==ZIP_OK) ++ err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); ++ x += ((uLong)i)<<8; ++ ++ if (err==ZIP_OK) ++ err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); ++ x += ((uLong)i)<<16; ++ ++ if (err==ZIP_OK) ++ err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); ++ x += ((uLong)i)<<24; ++ ++ if (err==ZIP_OK) ++ *pX = x; ++ else ++ *pX = 0; ++ return err; ++} ++ ++#ifndef BUFREADCOMMENT ++#define BUFREADCOMMENT (0x400) ++#endif ++/* ++ Locate the Central directory of a zipfile (at the end, just before ++ the global comment) ++*/ ++local uLong ziplocal_SearchCentralDir OF(( ++ const zlib_filefunc_def* pzlib_filefunc_def, ++ voidpf filestream)); ++ ++local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream) ++ const zlib_filefunc_def* pzlib_filefunc_def; ++ voidpf filestream; ++{ ++ unsigned char* buf; ++ uLong uSizeFile; ++ uLong uBackRead; ++ uLong uMaxBack=0xffff; /* maximum size of global comment */ ++ uLong uPosFound=0; ++ ++ if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) ++ return 0; ++ ++ ++ uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); ++ ++ if (uMaxBack>uSizeFile) ++ uMaxBack = uSizeFile; ++ ++ buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); ++ if (buf==NULL) ++ return 0; ++ ++ uBackRead = 4; ++ while (uBackReaduMaxBack) ++ uBackRead = uMaxBack; ++ else ++ uBackRead+=BUFREADCOMMENT; ++ uReadPos = uSizeFile-uBackRead ; ++ ++ uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? ++ (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); ++ if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) ++ break; ++ ++ if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) ++ break; ++ ++ for (i=(int)uReadSize-3; (i--)>0;) ++ if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ++ ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) ++ { ++ uPosFound = uReadPos+i; ++ break; ++ } ++ ++ if (uPosFound!=0) ++ break; ++ } ++ TRYFREE(buf); ++ return uPosFound; ++} ++#endif /* !NO_ADDFILEINEXISTINGZIP*/ ++ ++/************************************************************/ ++extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def) ++ const char *pathname; ++ int append; ++ zipcharpc* globalcomment; ++ zlib_filefunc_def* pzlib_filefunc_def; ++{ ++ zip_internal ziinit; ++ zip_internal* zi; ++ int err=ZIP_OK; ++ ++ ++ if (pzlib_filefunc_def==NULL) ++ fill_fopen_filefunc(&ziinit.z_filefunc); ++ else ++ ziinit.z_filefunc = *pzlib_filefunc_def; ++ ++ ziinit.filestream = (*(ziinit.z_filefunc.zopen_file)) ++ (ziinit.z_filefunc.opaque, ++ pathname, ++ (append == APPEND_STATUS_CREATE) ? ++ (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : ++ (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); ++ ++ if (ziinit.filestream == NULL) ++ return NULL; ++ ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream); ++ ziinit.in_opened_file_inzip = 0; ++ ziinit.ci.stream_initialised = 0; ++ ziinit.number_entry = 0; ++ ziinit.add_position_when_writting_offset = 0; ++ init_linkedlist(&(ziinit.central_dir)); ++ ++ ++ zi = (zip_internal*)ALLOC(sizeof(zip_internal)); ++ if (zi==NULL) ++ { ++ ZCLOSE(ziinit.z_filefunc,ziinit.filestream); ++ return NULL; ++ } ++ ++ /* now we add file in a zipfile */ ++# ifndef NO_ADDFILEINEXISTINGZIP ++ ziinit.globalcomment = NULL; ++ if (append == APPEND_STATUS_ADDINZIP) ++ { ++ uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ ++ ++ uLong size_central_dir; /* size of the central directory */ ++ uLong offset_central_dir; /* offset of start of central directory */ ++ uLong central_pos,uL; ++ ++ uLong number_disk; /* number of the current dist, used for ++ spaning ZIP, unsupported, always 0*/ ++ uLong number_disk_with_CD; /* number the the disk with central dir, used ++ for spaning ZIP, unsupported, always 0*/ ++ uLong number_entry; ++ uLong number_entry_CD; /* total number of entries in ++ the central dir ++ (same than number_entry on nospan) */ ++ uLong size_comment; ++ ++ central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream); ++ if (central_pos==0) ++ err=ZIP_ERRNO; ++ ++ if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, ++ central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) ++ err=ZIP_ERRNO; ++ ++ /* the signature, already checked */ ++ if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK) ++ err=ZIP_ERRNO; ++ ++ /* number of this disk */ ++ if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK) ++ err=ZIP_ERRNO; ++ ++ /* number of the disk with the start of the central directory */ ++ if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK) ++ err=ZIP_ERRNO; ++ ++ /* total number of entries in the central dir on this disk */ ++ if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK) ++ err=ZIP_ERRNO; ++ ++ /* total number of entries in the central dir */ ++ if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK) ++ err=ZIP_ERRNO; ++ ++ if ((number_entry_CD!=number_entry) || ++ (number_disk_with_CD!=0) || ++ (number_disk!=0)) ++ err=ZIP_BADZIPFILE; ++ ++ /* size of the central directory */ ++ if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK) ++ err=ZIP_ERRNO; ++ ++ /* offset of start of central directory with respect to the ++ starting disk number */ ++ if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK) ++ err=ZIP_ERRNO; ++ ++ /* zipfile global comment length */ ++ if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK) ++ err=ZIP_ERRNO; ++ ++ if ((central_pos0) ++ { ++ ziinit.globalcomment = ALLOC(size_comment+1); ++ if (ziinit.globalcomment) ++ { ++ size_comment = ZREAD(ziinit.z_filefunc, ziinit.filestream,ziinit.globalcomment,size_comment); ++ ziinit.globalcomment[size_comment]=0; ++ } ++ } ++ ++ byte_before_the_zipfile = central_pos - ++ (offset_central_dir+size_central_dir); ++ ziinit.add_position_when_writting_offset = byte_before_the_zipfile; ++ ++ { ++ uLong size_central_dir_to_read = size_central_dir; ++ size_t buf_size = SIZEDATA_INDATABLOCK; ++ void* buf_read = (void*)ALLOC(buf_size); ++ if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, ++ offset_central_dir + byte_before_the_zipfile, ++ ZLIB_FILEFUNC_SEEK_SET) != 0) ++ err=ZIP_ERRNO; ++ ++ while ((size_central_dir_to_read>0) && (err==ZIP_OK)) ++ { ++ uLong read_this = SIZEDATA_INDATABLOCK; ++ if (read_this > size_central_dir_to_read) ++ read_this = size_central_dir_to_read; ++ if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this) ++ err=ZIP_ERRNO; ++ ++ if (err==ZIP_OK) ++ err = add_data_in_datablock(&ziinit.central_dir,buf_read, ++ (uLong)read_this); ++ size_central_dir_to_read-=read_this; ++ } ++ TRYFREE(buf_read); ++ } ++ ziinit.begin_pos = byte_before_the_zipfile; ++ ziinit.number_entry = number_entry_CD; ++ ++ if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, ++ offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) ++ err=ZIP_ERRNO; ++ } ++ ++ if (globalcomment) ++ { ++ *globalcomment = ziinit.globalcomment; ++ } ++# endif /* !NO_ADDFILEINEXISTINGZIP*/ ++ ++ if (err != ZIP_OK) ++ { ++# ifndef NO_ADDFILEINEXISTINGZIP ++ TRYFREE(ziinit.globalcomment); ++# endif /* !NO_ADDFILEINEXISTINGZIP*/ ++ TRYFREE(zi); ++ return NULL; ++ } ++ else ++ { ++ *zi = ziinit; ++ return (zipFile)zi; ++ } ++} ++ ++extern zipFile ZEXPORT zipOpen (pathname, append) ++ const char *pathname; ++ int append; ++{ ++ return zipOpen2(pathname,append,NULL,NULL); ++} ++ ++extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi, ++ extrafield_local, size_extrafield_local, ++ extrafield_global, size_extrafield_global, ++ comment, method, level, raw, ++ windowBits, memLevel, strategy, ++ password, crcForCrypting) ++ zipFile file; ++ const char* filename; ++ const zip_fileinfo* zipfi; ++ const void* extrafield_local; ++ uInt size_extrafield_local; ++ const void* extrafield_global; ++ uInt size_extrafield_global; ++ const char* comment; ++ int method; ++ int level; ++ int raw; ++ int windowBits; ++ int memLevel; ++ int strategy; ++ const char* password; ++ uLong crcForCrypting; ++{ ++ zip_internal* zi; ++ uInt size_filename; ++ uInt size_comment; ++ uInt i; ++ int err = ZIP_OK; ++ ++# ifdef NOCRYPT ++ if (password != NULL) ++ return ZIP_PARAMERROR; ++# endif ++ ++ if (file == NULL) ++ return ZIP_PARAMERROR; ++ if ((method!=0) && (method!=Z_DEFLATED)) ++ return ZIP_PARAMERROR; ++ ++ zi = (zip_internal*)file; ++ ++ if (zi->in_opened_file_inzip == 1) ++ { ++ err = zipCloseFileInZip (file); ++ if (err != ZIP_OK) ++ return err; ++ } ++ ++ ++ if (filename==NULL) ++ filename="-"; ++ ++ if (comment==NULL) ++ size_comment = 0; ++ else ++ size_comment = (uInt)strlen(comment); ++ ++ size_filename = (uInt)strlen(filename); ++ ++ if (zipfi == NULL) ++ zi->ci.dosDate = 0; ++ else ++ { ++ if (zipfi->dosDate != 0) ++ zi->ci.dosDate = zipfi->dosDate; ++ else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate); ++ } ++ ++ zi->ci.flag = 0; ++ if ((level==8) || (level==9)) ++ zi->ci.flag |= 2; ++ if (level==2) ++ zi->ci.flag |= 4; ++ if (level==1) ++ zi->ci.flag |= 6; ++ if (password != NULL) ++ zi->ci.flag |= 1; ++ ++ zi->ci.crc32 = 0; ++ zi->ci.method = method; ++ zi->ci.encrypt = 0; ++ zi->ci.stream_initialised = 0; ++ zi->ci.pos_in_buffered_data = 0; ++ zi->ci.raw = raw; ++ zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ; ++ zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + ++ size_extrafield_global + size_comment; ++ zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader); ++ ++ ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); ++ /* version info */ ++ ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2); ++ ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); ++ ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); ++ ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); ++ ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); ++ ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ ++ ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ ++ ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ ++ ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); ++ ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); ++ ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); ++ ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ ++ ++ if (zipfi==NULL) ++ ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); ++ else ++ ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); ++ ++ if (zipfi==NULL) ++ ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); ++ else ++ ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); ++ ++ ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4); ++ ++ for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); ++ ++ for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = ++ *(((const char*)extrafield_global)+i); ++ ++ for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ ++ size_extrafield_global+i) = *(comment+i); ++ if (zi->ci.central_header == NULL) ++ return ZIP_INTERNALERROR; ++ ++ /* write the local header */ ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4); ++ ++ if (err==ZIP_OK) ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ ++ if (err==ZIP_OK) ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); ++ ++ if (err==ZIP_OK) ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); ++ ++ if (err==ZIP_OK) ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); ++ ++ if (err==ZIP_OK) ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ ++ if (err==ZIP_OK) ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ ++ if (err==ZIP_OK) ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ ++ ++ if (err==ZIP_OK) ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); ++ ++ if (err==ZIP_OK) ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2); ++ ++ if ((err==ZIP_OK) && (size_filename>0)) ++ if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) ++ err = ZIP_ERRNO; ++ ++ if ((err==ZIP_OK) && (size_extrafield_local>0)) ++ if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local) ++ !=size_extrafield_local) ++ err = ZIP_ERRNO; ++ ++ zi->ci.stream.avail_in = (uInt)0; ++ zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; ++ zi->ci.stream.next_out = zi->ci.buffered_data; ++ zi->ci.stream.total_in = 0; ++ zi->ci.stream.total_out = 0; ++ ++ if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) ++ { ++ zi->ci.stream.zalloc = (alloc_func)0; ++ zi->ci.stream.zfree = (free_func)0; ++ zi->ci.stream.opaque = (voidpf)0; ++ ++ if (windowBits>0) ++ windowBits = -windowBits; ++ ++ err = deflateInit2(&zi->ci.stream, level, ++ Z_DEFLATED, windowBits, memLevel, strategy); ++ ++ if (err==Z_OK) ++ zi->ci.stream_initialised = 1; ++ } ++# ifndef NOCRYPT ++ zi->ci.crypt_header_size = 0; ++ if ((err==Z_OK) && (password != NULL)) ++ { ++ unsigned char bufHead[RAND_HEAD_LEN]; ++ unsigned int sizeHead; ++ zi->ci.encrypt = 1; ++ zi->ci.pcrc_32_tab = get_crc_table(); ++ /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ ++ ++ sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); ++ zi->ci.crypt_header_size = sizeHead; ++ ++ if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) ++ err = ZIP_ERRNO; ++ } ++# endif ++ ++ if (err==Z_OK) ++ zi->in_opened_file_inzip = 1; ++ return err; ++} ++ ++extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi, ++ extrafield_local, size_extrafield_local, ++ extrafield_global, size_extrafield_global, ++ comment, method, level, raw) ++ zipFile file; ++ const char* filename; ++ const zip_fileinfo* zipfi; ++ const void* extrafield_local; ++ uInt size_extrafield_local; ++ const void* extrafield_global; ++ uInt size_extrafield_global; ++ const char* comment; ++ int method; ++ int level; ++ int raw; ++{ ++ return zipOpenNewFileInZip3 (file, filename, zipfi, ++ extrafield_local, size_extrafield_local, ++ extrafield_global, size_extrafield_global, ++ comment, method, level, raw, ++ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, ++ NULL, 0); ++} ++ ++extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, ++ extrafield_local, size_extrafield_local, ++ extrafield_global, size_extrafield_global, ++ comment, method, level) ++ zipFile file; ++ const char* filename; ++ const zip_fileinfo* zipfi; ++ const void* extrafield_local; ++ uInt size_extrafield_local; ++ const void* extrafield_global; ++ uInt size_extrafield_global; ++ const char* comment; ++ int method; ++ int level; ++{ ++ return zipOpenNewFileInZip2 (file, filename, zipfi, ++ extrafield_local, size_extrafield_local, ++ extrafield_global, size_extrafield_global, ++ comment, method, level, 0); ++} ++ ++local int zipFlushWriteBuffer(zi) ++ zip_internal* zi; ++{ ++ int err=ZIP_OK; ++ ++ if (zi->ci.encrypt != 0) ++ { ++#ifndef NOCRYPT ++ uInt i; ++ int t; ++ for (i=0;ici.pos_in_buffered_data;i++) ++ zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, ++ zi->ci.buffered_data[i],t); ++#endif ++ } ++ if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) ++ !=zi->ci.pos_in_buffered_data) ++ err = ZIP_ERRNO; ++ zi->ci.pos_in_buffered_data = 0; ++ return err; ++} ++ ++extern int ZEXPORT zipWriteInFileInZip (file, buf, len) ++ zipFile file; ++ const void* buf; ++ unsigned len; ++{ ++ zip_internal* zi; ++ int err=ZIP_OK; ++ ++ if (file == NULL) ++ return ZIP_PARAMERROR; ++ zi = (zip_internal*)file; ++ ++ if (zi->in_opened_file_inzip == 0) ++ return ZIP_PARAMERROR; ++ ++ zi->ci.stream.next_in = (void*)buf; ++ zi->ci.stream.avail_in = len; ++ zi->ci.crc32 = crc32(zi->ci.crc32,buf,len); ++ ++ while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) ++ { ++ if (zi->ci.stream.avail_out == 0) ++ { ++ if (zipFlushWriteBuffer(zi) == ZIP_ERRNO) ++ err = ZIP_ERRNO; ++ zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; ++ zi->ci.stream.next_out = zi->ci.buffered_data; ++ } ++ ++ ++ if(err != ZIP_OK) ++ break; ++ ++ if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) ++ { ++ uLong uTotalOutBefore = zi->ci.stream.total_out; ++ err=deflate(&zi->ci.stream, Z_NO_FLUSH); ++ zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; ++ ++ } ++ else ++ { ++ uInt copy_this,i; ++ if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) ++ copy_this = zi->ci.stream.avail_in; ++ else ++ copy_this = zi->ci.stream.avail_out; ++ for (i=0;ici.stream.next_out)+i) = ++ *(((const char*)zi->ci.stream.next_in)+i); ++ { ++ zi->ci.stream.avail_in -= copy_this; ++ zi->ci.stream.avail_out-= copy_this; ++ zi->ci.stream.next_in+= copy_this; ++ zi->ci.stream.next_out+= copy_this; ++ zi->ci.stream.total_in+= copy_this; ++ zi->ci.stream.total_out+= copy_this; ++ zi->ci.pos_in_buffered_data += copy_this; ++ } ++ } ++ } ++ ++ return err; ++} ++ ++extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32) ++ zipFile file; ++ uLong uncompressed_size; ++ uLong crc32; ++{ ++ zip_internal* zi; ++ uLong compressed_size; ++ int err=ZIP_OK; ++ ++ if (file == NULL) ++ return ZIP_PARAMERROR; ++ zi = (zip_internal*)file; ++ ++ if (zi->in_opened_file_inzip == 0) ++ return ZIP_PARAMERROR; ++ zi->ci.stream.avail_in = 0; ++ ++ if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) ++ while (err==ZIP_OK) ++ { ++ uLong uTotalOutBefore; ++ if (zi->ci.stream.avail_out == 0) ++ { ++ if (zipFlushWriteBuffer(zi) == ZIP_ERRNO) ++ err = ZIP_ERRNO; ++ zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; ++ zi->ci.stream.next_out = zi->ci.buffered_data; ++ } ++ uTotalOutBefore = zi->ci.stream.total_out; ++ err=deflate(&zi->ci.stream, Z_FINISH); ++ zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; ++ } ++ ++ if (err==Z_STREAM_END) ++ err=ZIP_OK; /* this is normal */ ++ ++ if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) ++ if (zipFlushWriteBuffer(zi)==ZIP_ERRNO) ++ err = ZIP_ERRNO; ++ ++ if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) ++ { ++ err=deflateEnd(&zi->ci.stream); ++ zi->ci.stream_initialised = 0; ++ } ++ ++ if (!zi->ci.raw) ++ { ++ crc32 = (uLong)zi->ci.crc32; ++ uncompressed_size = (uLong)zi->ci.stream.total_in; ++ } ++ compressed_size = (uLong)zi->ci.stream.total_out; ++# ifndef NOCRYPT ++ compressed_size += zi->ci.crypt_header_size; ++# endif ++ ++ ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ ++ ziplocal_putValue_inmemory(zi->ci.central_header+20, ++ compressed_size,4); /*compr size*/ ++ if (zi->ci.stream.data_type == Z_ASCII) ++ ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); ++ ziplocal_putValue_inmemory(zi->ci.central_header+24, ++ uncompressed_size,4); /*uncompr size*/ ++ ++ if (err==ZIP_OK) ++ err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header, ++ (uLong)zi->ci.size_centralheader); ++ free(zi->ci.central_header); ++ ++ if (err==ZIP_OK) ++ { ++ long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream); ++ if (ZSEEK(zi->z_filefunc,zi->filestream, ++ zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) ++ err = ZIP_ERRNO; ++ ++ if (err==ZIP_OK) ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ ++ ++ if (err==ZIP_OK) /* compressed size, unknown */ ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); ++ ++ if (err==ZIP_OK) /* uncompressed size, unknown */ ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); ++ ++ if (ZSEEK(zi->z_filefunc,zi->filestream, ++ cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) ++ err = ZIP_ERRNO; ++ } ++ ++ zi->number_entry ++; ++ zi->in_opened_file_inzip = 0; ++ ++ return err; ++} ++ ++extern int ZEXPORT zipCloseFileInZip (file) ++ zipFile file; ++{ ++ return zipCloseFileInZipRaw (file,0,0); ++} ++ ++extern int ZEXPORT zipClose (file, global_comment) ++ zipFile file; ++ const char* global_comment; ++{ ++ zip_internal* zi; ++ int err = 0; ++ uLong size_centraldir = 0; ++ uLong centraldir_pos_inzip; ++ uInt size_global_comment; ++ if (file == NULL) ++ return ZIP_PARAMERROR; ++ zi = (zip_internal*)file; ++ ++ if (zi->in_opened_file_inzip == 1) ++ { ++ err = zipCloseFileInZip (file); ++ } ++ ++#ifndef NO_ADDFILEINEXISTINGZIP ++ if (global_comment==NULL) ++ global_comment = zi->globalcomment; ++#endif ++ if (global_comment==NULL) ++ size_global_comment = 0; ++ else ++ size_global_comment = (uInt)strlen(global_comment); ++ ++ centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream); ++ if (err==ZIP_OK) ++ { ++ linkedlist_datablock_internal* ldi = zi->central_dir.first_block ; ++ while (ldi!=NULL) ++ { ++ if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) ++ if (ZWRITE(zi->z_filefunc,zi->filestream, ++ ldi->data,ldi->filled_in_this_block) ++ !=ldi->filled_in_this_block ) ++ err = ZIP_ERRNO; ++ ++ size_centraldir += ldi->filled_in_this_block; ++ ldi = ldi->next_datablock; ++ } ++ } ++ free_datablock(zi->central_dir.first_block); ++ ++ if (err==ZIP_OK) /* Magic End */ ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); ++ ++ if (err==ZIP_OK) /* number of this disk */ ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); ++ ++ if (err==ZIP_OK) /* number of the disk with the start of the central directory */ ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); ++ ++ if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); ++ ++ if (err==ZIP_OK) /* total number of entries in the central dir */ ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); ++ ++ if (err==ZIP_OK) /* size of the central directory */ ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); ++ ++ if (err==ZIP_OK) /* offset of start of central directory with respect to the ++ starting disk number */ ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream, ++ (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); ++ ++ if (err==ZIP_OK) /* zipfile comment length */ ++ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); ++ ++ if ((err==ZIP_OK) && (size_global_comment>0)) ++ if (ZWRITE(zi->z_filefunc,zi->filestream, ++ global_comment,size_global_comment) != size_global_comment) ++ err = ZIP_ERRNO; ++ ++ if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0) ++ if (err == ZIP_OK) ++ err = ZIP_ERRNO; ++ ++#ifndef NO_ADDFILEINEXISTINGZIP ++ TRYFREE(zi->globalcomment); ++#endif ++ TRYFREE(zi); ++ ++ return err; ++} +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/zip.h b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/zip.h +new file mode 100644 +index 0000000..acacce8 +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/MiniZip/zip.h +@@ -0,0 +1,235 @@ ++/* zip.h -- IO for compress .zip files using zlib ++ Version 1.01e, February 12th, 2005 ++ ++ Copyright (C) 1998-2005 Gilles Vollant ++ ++ This unzip package allow creates .ZIP file, compatible with PKZip 2.04g ++ WinZip, InfoZip tools and compatible. ++ Multi volume ZipFile (span) are not supported. ++ Encryption compatible with pkzip 2.04g only supported ++ Old compressions used by old PKZip 1.x are not supported ++ ++ For uncompress .zip file, look at unzip.h ++ ++ ++ I WAIT FEEDBACK at mail info@winimage.com ++ Visit also http://www.winimage.com/zLibDll/unzip.html for evolution ++ ++ Condition of use and distribution are the same than zlib : ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++ ++ ++*/ ++ ++/* for more info about .ZIP format, see ++ http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip ++ http://www.info-zip.org/pub/infozip/doc/ ++ PkWare has also a specification at : ++ ftp://ftp.pkware.com/probdesc.zip ++*/ ++ ++#ifndef _zip_H ++#define _zip_H ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#ifndef _ZLIB_H ++#include "zlib.h" ++#endif ++ ++#ifndef _ZLIBIOAPI_H ++#include "ioapi.h" ++#endif ++ ++#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) ++/* like the STRICT of WIN32, we define a pointer that cannot be converted ++ from (void*) without cast */ ++typedef struct TagzipFile__ { int unused; } zipFile__; ++typedef zipFile__ *zipFile; ++#else ++typedef voidp zipFile; ++#endif ++ ++#define ZIP_OK (0) ++#define ZIP_EOF (0) ++#define ZIP_ERRNO (Z_ERRNO) ++#define ZIP_PARAMERROR (-102) ++#define ZIP_BADZIPFILE (-103) ++#define ZIP_INTERNALERROR (-104) ++ ++#ifndef DEF_MEM_LEVEL ++# if MAX_MEM_LEVEL >= 8 ++# define DEF_MEM_LEVEL 8 ++# else ++# define DEF_MEM_LEVEL MAX_MEM_LEVEL ++# endif ++#endif ++/* default memLevel */ ++ ++/* tm_zip contain date/time info */ ++typedef struct tm_zip_s ++{ ++ uInt tm_sec; /* seconds after the minute - [0,59] */ ++ uInt tm_min; /* minutes after the hour - [0,59] */ ++ uInt tm_hour; /* hours since midnight - [0,23] */ ++ uInt tm_mday; /* day of the month - [1,31] */ ++ uInt tm_mon; /* months since January - [0,11] */ ++ uInt tm_year; /* years - [1980..2044] */ ++} tm_zip; ++ ++typedef struct ++{ ++ tm_zip tmz_date; /* date in understandable format */ ++ uLong dosDate; /* if dos_date == 0, tmu_date is used */ ++/* uLong flag; */ /* general purpose bit flag 2 bytes */ ++ ++ uLong internal_fa; /* internal file attributes 2 bytes */ ++ uLong external_fa; /* external file attributes 4 bytes */ ++} zip_fileinfo; ++ ++typedef const char* zipcharpc; ++ ++ ++#define APPEND_STATUS_CREATE (0) ++#define APPEND_STATUS_CREATEAFTER (1) ++#define APPEND_STATUS_ADDINZIP (2) ++ ++extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); ++/* ++ Create a zipfile. ++ pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on ++ an Unix computer "zlib/zlib113.zip". ++ if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip ++ will be created at the end of the file. ++ (useful if the file contain a self extractor code) ++ if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will ++ add files in existing zip (be sure you don't add file that doesn't exist) ++ If the zipfile cannot be opened, the return value is NULL. ++ Else, the return value is a zipFile Handle, usable with other function ++ of this zip package. ++*/ ++ ++/* Note : there is no delete function into a zipfile. ++ If you want delete file into a zipfile, you must open a zipfile, and create another ++ Of couse, you can use RAW reading and writing to copy the file you did not want delte ++*/ ++ ++extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, ++ int append, ++ zipcharpc* globalcomment, ++ zlib_filefunc_def* pzlib_filefunc_def)); ++ ++extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, ++ const char* filename, ++ const zip_fileinfo* zipfi, ++ const void* extrafield_local, ++ uInt size_extrafield_local, ++ const void* extrafield_global, ++ uInt size_extrafield_global, ++ const char* comment, ++ int method, ++ int level)); ++/* ++ Open a file in the ZIP for writing. ++ filename : the filename in zip (if NULL, '-' without quote will be used ++ *zipfi contain supplemental information ++ if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local ++ contains the extrafield data the the local header ++ if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global ++ contains the extrafield data the the local header ++ if comment != NULL, comment contain the comment string ++ method contain the compression method (0 for store, Z_DEFLATED for deflate) ++ level contain the level of compression (can be Z_DEFAULT_COMPRESSION) ++*/ ++ ++ ++extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, ++ const char* filename, ++ const zip_fileinfo* zipfi, ++ const void* extrafield_local, ++ uInt size_extrafield_local, ++ const void* extrafield_global, ++ uInt size_extrafield_global, ++ const char* comment, ++ int method, ++ int level, ++ int raw)); ++ ++/* ++ Same than zipOpenNewFileInZip, except if raw=1, we write raw file ++ */ ++ ++extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, ++ const char* filename, ++ const zip_fileinfo* zipfi, ++ const void* extrafield_local, ++ uInt size_extrafield_local, ++ const void* extrafield_global, ++ uInt size_extrafield_global, ++ const char* comment, ++ int method, ++ int level, ++ int raw, ++ int windowBits, ++ int memLevel, ++ int strategy, ++ const char* password, ++ uLong crcForCtypting)); ++ ++/* ++ Same than zipOpenNewFileInZip2, except ++ windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 ++ password : crypting password (NULL for no crypting) ++ crcForCtypting : crc of file to compress (needed for crypting) ++ */ ++ ++ ++extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, ++ const void* buf, ++ unsigned len)); ++/* ++ Write data in the zipfile ++*/ ++ ++extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); ++/* ++ Close the current file in the zipfile ++*/ ++ ++extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, ++ uLong uncompressed_size, ++ uLong crc32)); ++/* ++ Close the current file in the zipfile, for fiel opened with ++ parameter raw=1 in zipOpenNewFileInZip2 ++ uncompressed_size and crc32 are value for the uncompressed size ++*/ ++ ++extern int ZEXPORT zipClose OF((zipFile file, ++ const char* global_comment)); ++/* ++ Close the zipfile ++*/ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _zip_H */ +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/FileInZipInfo.h b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/FileInZipInfo.h +new file mode 100644 +index 0000000..76d3ae5 +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/FileInZipInfo.h +@@ -0,0 +1,60 @@ ++// ++// FileInZipInfo.h ++// Objective-Zip v. 0.7.2 ++// ++// Created by Gianluca Bertani on 27/12/09. ++// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. ++// ++// Redistribution and use in source and binary forms, with or without ++// modification, are permitted provided that the following conditions ++// are met: ++// ++// * Redistributions of source code must retain the above copyright notice, ++// this list of conditions and the following disclaimer. ++// * Redistributions in binary form must reproduce the above copyright notice, ++// this list of conditions and the following disclaimer in the documentation ++// and/or other materials provided with the distribution. ++// * Neither the name of Gianluca Bertani nor the names of its contributors ++// may be used to endorse or promote products derived from this software ++// without specific prior written permission. ++// ++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++// POSSIBILITY OF SUCH DAMAGE. ++// ++ ++#import ++#import "ZipFile.h" ++ ++ ++@interface FileInZipInfo : NSObject { ++ ++@private ++ NSUInteger _length; ++ ZipCompressionLevel _level; ++ BOOL _crypted; ++ NSUInteger _size; ++ NSDate *_date; ++ NSUInteger _crc32; ++ NSString *_name; ++} ++ ++- (id) initWithName:(NSString *)name length:(NSUInteger)length level:(ZipCompressionLevel)level crypted:(BOOL)crypted size:(NSUInteger)size date:(NSDate *)date crc32:(NSUInteger)crc32; ++ ++@property (nonatomic, readonly) NSString *name; ++@property (nonatomic, readonly) NSUInteger length; ++@property (nonatomic, readonly) ZipCompressionLevel level; ++@property (nonatomic, readonly) BOOL crypted; ++@property (nonatomic, readonly) NSUInteger size; ++@property (nonatomic, readonly) NSDate *date; ++@property (nonatomic, readonly) NSUInteger crc32; ++ ++@end +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/FileInZipInfo.m b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/FileInZipInfo.m +new file mode 100644 +index 0000000..1b5ab21 +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/FileInZipInfo.m +@@ -0,0 +1,61 @@ ++// ++// FileInZipInfo.m ++// Objective-Zip v. 0.7.2 ++// ++// Created by Gianluca Bertani on 27/12/09. ++// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. ++// ++// Redistribution and use in source and binary forms, with or without ++// modification, are permitted provided that the following conditions ++// are met: ++// ++// * Redistributions of source code must retain the above copyright notice, ++// this list of conditions and the following disclaimer. ++// * Redistributions in binary form must reproduce the above copyright notice, ++// this list of conditions and the following disclaimer in the documentation ++// and/or other materials provided with the distribution. ++// * Neither the name of Gianluca Bertani nor the names of its contributors ++// may be used to endorse or promote products derived from this software ++// without specific prior written permission. ++// ++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++// POSSIBILITY OF SUCH DAMAGE. ++// ++ ++#import "FileInZipInfo.h" ++ ++ ++@implementation FileInZipInfo ++ ++- (id) initWithName:(NSString *)name length:(NSUInteger)length level:(ZipCompressionLevel)level crypted:(BOOL)crypted size:(NSUInteger)size date:(NSDate *)date crc32:(NSUInteger)crc32 { ++ if ((self = [super init])) { ++ _name= name; ++ _length= length; ++ _level= level; ++ _crypted= crypted; ++ _size= size; ++ _date= date; ++ _crc32= crc32; ++ } ++ ++ return self; ++} ++ ++@synthesize name= _name; ++@synthesize length= _length; ++@synthesize level= _level; ++@synthesize crypted= _crypted; ++@synthesize size= _size; ++@synthesize date= _date; ++@synthesize crc32= _crc32; ++ ++@end +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipException.h b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipException.h +new file mode 100644 +index 0000000..0ae2728 +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipException.h +@@ -0,0 +1,48 @@ ++// ++// ZipException.h ++// Objective-Zip v. 0.7.2 ++// ++// Created by Gianluca Bertani on 25/12/09. ++// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. ++// ++// Redistribution and use in source and binary forms, with or without ++// modification, are permitted provided that the following conditions ++// are met: ++// ++// * Redistributions of source code must retain the above copyright notice, ++// this list of conditions and the following disclaimer. ++// * Redistributions in binary form must reproduce the above copyright notice, ++// this list of conditions and the following disclaimer in the documentation ++// and/or other materials provided with the distribution. ++// * Neither the name of Gianluca Bertani nor the names of its contributors ++// may be used to endorse or promote products derived from this software ++// without specific prior written permission. ++// ++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++// POSSIBILITY OF SUCH DAMAGE. ++// ++ ++#import ++ ++ ++@interface ZipException : NSException { ++ ++@private ++ NSInteger _error; ++} ++ ++- (id) initWithReason:(NSString *)reason; ++- (id) initWithError:(NSInteger)error reason:(NSString *)reason; ++ ++@property (nonatomic, readonly) NSInteger error; ++ ++@end +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipException.m b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipException.m +new file mode 100644 +index 0000000..f0b26d9 +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipException.m +@@ -0,0 +1,57 @@ ++// ++// ZipException.m ++// Objective-Zip v. 0.7.2 ++// ++// Created by Gianluca Bertani on 25/12/09. ++// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. ++// ++// Redistribution and use in source and binary forms, with or without ++// modification, are permitted provided that the following conditions ++// are met: ++// ++// * Redistributions of source code must retain the above copyright notice, ++// this list of conditions and the following disclaimer. ++// * Redistributions in binary form must reproduce the above copyright notice, ++// this list of conditions and the following disclaimer in the documentation ++// and/or other materials provided with the distribution. ++// * Neither the name of Gianluca Bertani nor the names of its contributors ++// may be used to endorse or promote products derived from this software ++// without specific prior written permission. ++// ++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++// POSSIBILITY OF SUCH DAMAGE. ++// ++ ++#import "ZipException.h" ++ ++ ++@implementation ZipException ++ ++- (id) initWithReason:(NSString *)reason { ++ if ((self= [super initWithName:@"ZipException" reason:reason userInfo:nil])) { ++ _error= 0; ++ } ++ ++ return self; ++} ++ ++- (id) initWithError:(NSInteger)error reason:(NSString *)reason { ++ if ((self= [super initWithName:@"ZipException" reason:reason userInfo:nil])) { ++ _error= error; ++ } ++ ++ return self; ++} ++ ++@synthesize error= _error; ++ ++@end +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipFile.h b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipFile.h +new file mode 100644 +index 0000000..79642fd +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipFile.h +@@ -0,0 +1,86 @@ ++// ++// ZipFile.h ++// Objective-Zip v. 0.7.2 ++// ++// Created by Gianluca Bertani on 25/12/09. ++// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. ++// ++// Redistribution and use in source and binary forms, with or without ++// modification, are permitted provided that the following conditions ++// are met: ++// ++// * Redistributions of source code must retain the above copyright notice, ++// this list of conditions and the following disclaimer. ++// * Redistributions in binary form must reproduce the above copyright notice, ++// this list of conditions and the following disclaimer in the documentation ++// and/or other materials provided with the distribution. ++// * Neither the name of Gianluca Bertani nor the names of its contributors ++// may be used to endorse or promote products derived from this software ++// without specific prior written permission. ++// ++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++// POSSIBILITY OF SUCH DAMAGE. ++// ++ ++#import ++ ++#include "zip.h" ++#include "unzip.h" ++ ++ ++typedef enum { ++ ZipFileModeUnzip, ++ ZipFileModeCreate, ++ ZipFileModeAppend ++} ZipFileMode; ++ ++typedef enum { ++ ZipCompressionLevelDefault= -1, ++ ZipCompressionLevelNone= 0, ++ ZipCompressionLevelFastest= 1, ++ ZipCompressionLevelBest= 9 ++} ZipCompressionLevel; ++ ++@class ZipReadStream; ++@class ZipWriteStream; ++@class FileInZipInfo; ++ ++@interface ZipFile : NSObject { ++ NSString *_fileName; ++ ZipFileMode _mode; ++ ++@private ++ zipFile _zipFile; ++ unzFile _unzFile; ++} ++ ++- (id) initWithFileName:(NSString *)fileName mode:(ZipFileMode)mode; ++ ++- (ZipWriteStream *) writeFileInZipWithName:(NSString *)fileNameInZip compressionLevel:(ZipCompressionLevel)compressionLevel; ++- (ZipWriteStream *) writeFileInZipWithName:(NSString *)fileNameInZip fileDate:(NSDate *)fileDate compressionLevel:(ZipCompressionLevel)compressionLevel; ++- (ZipWriteStream *) writeFileInZipWithName:(NSString *)fileNameInZip fileDate:(NSDate *)fileDate compressionLevel:(ZipCompressionLevel)compressionLevel password:(NSString *)password crc32:(NSUInteger)crc32; ++ ++- (NSUInteger) numFilesInZip; ++- (NSArray *) listFileInZipInfos; ++ ++- (void) goToFirstFileInZip; ++- (BOOL) goToNextFileInZip; ++- (BOOL) locateFileInZip:(NSString *)fileNameInZip; ++ ++- (FileInZipInfo *) getCurrentFileInZipInfo; ++ ++- (ZipReadStream *) readCurrentFileInZip; ++- (ZipReadStream *) readCurrentFileInZipWithPassword:(NSString *)password; ++ ++- (void) close; ++ ++@end +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipFile.m b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipFile.m +new file mode 100644 +index 0000000..ea8a115 +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipFile.m +@@ -0,0 +1,418 @@ ++// ++// ZipFile.m ++// Objective-Zip v. 0.7.2 ++// ++// Created by Gianluca Bertani on 25/12/09. ++// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. ++// ++// Redistribution and use in source and binary forms, with or without ++// modification, are permitted provided that the following conditions ++// are met: ++// ++// * Redistributions of source code must retain the above copyright notice, ++// this list of conditions and the following disclaimer. ++// * Redistributions in binary form must reproduce the above copyright notice, ++// this list of conditions and the following disclaimer in the documentation ++// and/or other materials provided with the distribution. ++// * Neither the name of Gianluca Bertani nor the names of its contributors ++// may be used to endorse or promote products derived from this software ++// without specific prior written permission. ++// ++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++// POSSIBILITY OF SUCH DAMAGE. ++// ++ ++#import "ZipFile.h" ++#import "ZipException.h" ++#import "ZipReadStream.h" ++#import "ZipWriteStream.h" ++#import "FIleInZipInfo.h" ++ ++#define FILE_IN_ZIP_MAX_NAME_LENGTH (256) ++ ++ ++@implementation ZipFile ++ ++ ++- (id) initWithFileName:(NSString *)fileName mode:(ZipFileMode)mode { ++ if ((self= [super init])) { ++ _fileName= fileName; ++ _mode= mode; ++ ++ switch (mode) { ++ case ZipFileModeUnzip: ++ _unzFile= unzOpen([_fileName cStringUsingEncoding:NSUTF8StringEncoding]); ++ if (_unzFile == NULL) { ++ NSString *reason= [NSString stringWithFormat:@"Can't open '%@'", _fileName]; ++ @throw [[ZipException alloc] initWithReason:reason]; ++ } ++ break; ++ ++ case ZipFileModeCreate: ++ _zipFile= zipOpen([_fileName cStringUsingEncoding:NSUTF8StringEncoding], APPEND_STATUS_CREATE); ++ if (_zipFile == NULL) { ++ NSString *reason= [NSString stringWithFormat:@"Can't open '%@'", _fileName]; ++ @throw [[ZipException alloc] initWithReason:reason]; ++ } ++ break; ++ ++ case ZipFileModeAppend: ++ _zipFile= zipOpen([_fileName cStringUsingEncoding:NSUTF8StringEncoding], APPEND_STATUS_ADDINZIP); ++ if (_zipFile == NULL) { ++ NSString *reason= [NSString stringWithFormat:@"Can't open '%@'", _fileName]; ++ @throw [[ZipException alloc] initWithReason:reason]; ++ } ++ break; ++ ++ default: { ++ NSString *reason= [NSString stringWithFormat:@"Unknown mode %d", _mode]; ++ @throw [[ZipException alloc] initWithReason:reason]; ++ } ++ } ++ } ++ ++ return self; ++} ++ ++- (ZipWriteStream *) writeFileInZipWithName:(NSString *)fileNameInZip compressionLevel:(ZipCompressionLevel)compressionLevel { ++ if (_mode == ZipFileModeUnzip) { ++ NSString *reason= [NSString stringWithFormat:@"Operation not permitted with Unzip mode"]; ++ @throw [[ZipException alloc] initWithReason:reason]; ++ } ++ ++ NSDate *now= [NSDate date]; ++ NSCalendar *calendar= [NSCalendar currentCalendar]; ++ NSDateComponents *date= [calendar components:(NSSecondCalendarUnit | NSMinuteCalendarUnit | NSHourCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:now]; ++ zip_fileinfo zi; ++ zi.tmz_date.tm_sec= (uInt)[date second]; ++ zi.tmz_date.tm_min= (uInt)[date minute]; ++ zi.tmz_date.tm_hour= (uInt)[date hour]; ++ zi.tmz_date.tm_mday= (uInt)[date day]; ++ zi.tmz_date.tm_mon= (uInt)[date month] -1; ++ zi.tmz_date.tm_year= (uInt)[date year]; ++ zi.internal_fa= 0; ++ zi.external_fa= 0; ++ zi.dosDate= 0; ++ ++ int err= zipOpenNewFileInZip3( ++ _zipFile, ++ [fileNameInZip cStringUsingEncoding:NSUTF8StringEncoding], ++ &zi, ++ NULL, 0, NULL, 0, NULL, ++ (compressionLevel != ZipCompressionLevelNone) ? Z_DEFLATED : 0, ++ compressionLevel, 0, ++ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, ++ NULL, 0); ++ if (err != ZIP_OK) { ++ NSString *reason= [NSString stringWithFormat:@"Error in opening '%@' in zipfile", fileNameInZip]; ++ @throw [[ZipException alloc] initWithError:err reason:reason]; ++ } ++ ++ return [[ZipWriteStream alloc] initWithZipFileStruct:_zipFile fileNameInZip:fileNameInZip]; ++} ++ ++- (ZipWriteStream *) writeFileInZipWithName:(NSString *)fileNameInZip fileDate:(NSDate *)fileDate compressionLevel:(ZipCompressionLevel)compressionLevel { ++ if (_mode == ZipFileModeUnzip) { ++ NSString *reason= [NSString stringWithFormat:@"Operation not permitted with Unzip mode"]; ++ @throw [[ZipException alloc] initWithReason:reason]; ++ } ++ ++ NSCalendar *calendar= [NSCalendar currentCalendar]; ++ NSDateComponents *date= [calendar components:(NSSecondCalendarUnit | NSMinuteCalendarUnit | NSHourCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:fileDate]; ++ zip_fileinfo zi; ++ zi.tmz_date.tm_sec= (uInt)[date second]; ++ zi.tmz_date.tm_min= (uInt)[date minute]; ++ zi.tmz_date.tm_hour= (uInt)[date hour]; ++ zi.tmz_date.tm_mday= (uInt)[date day]; ++ zi.tmz_date.tm_mon= (uInt)[date month] -1; ++ zi.tmz_date.tm_year= (uInt)[date year]; ++ zi.internal_fa= 0; ++ zi.external_fa= 0; ++ zi.dosDate= 0; ++ ++ int err= zipOpenNewFileInZip3( ++ _zipFile, ++ [fileNameInZip cStringUsingEncoding:NSUTF8StringEncoding], ++ &zi, ++ NULL, 0, NULL, 0, NULL, ++ (compressionLevel != ZipCompressionLevelNone) ? Z_DEFLATED : 0, ++ compressionLevel, 0, ++ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, ++ NULL, 0); ++ if (err != ZIP_OK) { ++ NSString *reason= [NSString stringWithFormat:@"Error in opening '%@' in zipfile", fileNameInZip]; ++ @throw [[ZipException alloc] initWithError:err reason:reason]; ++ } ++ ++ return [[ZipWriteStream alloc] initWithZipFileStruct:_zipFile fileNameInZip:fileNameInZip]; ++} ++ ++- (ZipWriteStream *) writeFileInZipWithName:(NSString *)fileNameInZip fileDate:(NSDate *)fileDate compressionLevel:(ZipCompressionLevel)compressionLevel password:(NSString *)password crc32:(NSUInteger)crc32 { ++ if (_mode == ZipFileModeUnzip) { ++ NSString *reason= [NSString stringWithFormat:@"Operation not permitted with Unzip mode"]; ++ @throw [[ZipException alloc] initWithReason:reason]; ++ } ++ ++ NSCalendar *calendar= [NSCalendar currentCalendar]; ++ NSDateComponents *date= [calendar components:(NSSecondCalendarUnit | NSMinuteCalendarUnit | NSHourCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:fileDate]; ++ zip_fileinfo zi; ++ zi.tmz_date.tm_sec= (uInt)[date second]; ++ zi.tmz_date.tm_min= (uInt)[date minute]; ++ zi.tmz_date.tm_hour= (uInt)[date hour]; ++ zi.tmz_date.tm_mday= (uInt)[date day]; ++ zi.tmz_date.tm_mon= (uInt)[date month] -1; ++ zi.tmz_date.tm_year= (uInt)[date year]; ++ zi.internal_fa= 0; ++ zi.external_fa= 0; ++ zi.dosDate= 0; ++ ++ int err= zipOpenNewFileInZip3( ++ _zipFile, ++ [fileNameInZip cStringUsingEncoding:NSUTF8StringEncoding], ++ &zi, ++ NULL, 0, NULL, 0, NULL, ++ (compressionLevel != ZipCompressionLevelNone) ? Z_DEFLATED : 0, ++ compressionLevel, 0, ++ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, ++ [password cStringUsingEncoding:NSUTF8StringEncoding], crc32); ++ if (err != ZIP_OK) { ++ NSString *reason= [NSString stringWithFormat:@"Error in opening '%@' in zipfile", fileNameInZip]; ++ @throw [[ZipException alloc] initWithError:err reason:reason]; ++ } ++ ++ return [[ZipWriteStream alloc] initWithZipFileStruct:_zipFile fileNameInZip:fileNameInZip]; ++} ++ ++- (NSUInteger) numFilesInZip { ++ if (_mode != ZipFileModeUnzip) { ++ NSString *reason= [NSString stringWithFormat:@"Operation not permitted without Unzip mode"]; ++ @throw [[ZipException alloc] initWithReason:reason]; ++ } ++ ++ unz_global_info gi; ++ int err= unzGetGlobalInfo(_unzFile, &gi); ++ if (err != UNZ_OK) { ++ NSString *reason= [NSString stringWithFormat:@"Error in getting global info in '%@'", _fileName]; ++ @throw [[ZipException alloc] initWithError:err reason:reason]; ++ } ++ ++ return gi.number_entry; ++} ++ ++- (NSArray *) listFileInZipInfos { ++ int num= (uInt)[self numFilesInZip]; ++ if (num < 1) ++ return [[NSArray alloc] init]; ++ ++ NSMutableArray *files= [[NSMutableArray alloc] initWithCapacity:num]; ++ ++ [self goToFirstFileInZip]; ++ for (int i= 0; i < num; i++) { ++ FileInZipInfo *info= [self getCurrentFileInZipInfo]; ++ [files addObject:info]; ++ ++ if ((i +1) < num) ++ [self goToNextFileInZip]; ++ } ++ ++ return files; ++} ++ ++- (void) goToFirstFileInZip { ++ if (_mode != ZipFileModeUnzip) { ++ NSString *reason= [NSString stringWithFormat:@"Operation not permitted without Unzip mode"]; ++ @throw [[ZipException alloc] initWithReason:reason]; ++ } ++ ++ int err= unzGoToFirstFile(_unzFile); ++ if (err != UNZ_OK) { ++ NSString *reason= [NSString stringWithFormat:@"Error in going to first file in zip in '%@'", _fileName]; ++ @throw [[ZipException alloc] initWithError:err reason:reason]; ++ } ++} ++ ++- (BOOL) goToNextFileInZip { ++ if (_mode != ZipFileModeUnzip) { ++ NSString *reason= [NSString stringWithFormat:@"Operation not permitted without Unzip mode"]; ++ @throw [[ZipException alloc] initWithReason:reason]; ++ } ++ ++ int err= unzGoToNextFile(_unzFile); ++ if (err == UNZ_END_OF_LIST_OF_FILE) ++ return NO; ++ ++ if (err != UNZ_OK) { ++ NSString *reason= [NSString stringWithFormat:@"Error in going to next file in zip in '%@'", _fileName]; ++ @throw [[ZipException alloc] initWithError:err reason:reason]; ++ } ++ ++ return YES; ++} ++ ++- (BOOL) locateFileInZip:(NSString *)fileNameInZip { ++ if (_mode != ZipFileModeUnzip) { ++ NSString *reason= [NSString stringWithFormat:@"Operation not permitted without Unzip mode"]; ++ @throw [[ZipException alloc] initWithReason:reason]; ++ } ++ ++ int err= unzLocateFile(_unzFile, [fileNameInZip cStringUsingEncoding:NSUTF8StringEncoding], 1); ++ if (err == UNZ_END_OF_LIST_OF_FILE) ++ return NO; ++ ++ if (err != UNZ_OK) { ++ NSString *reason= [NSString stringWithFormat:@"Error in going to next file in zip in '%@'", _fileName]; ++ @throw [[ZipException alloc] initWithError:err reason:reason]; ++ } ++ ++ return YES; ++} ++ ++- (FileInZipInfo *) getCurrentFileInZipInfo { ++ if (_mode != ZipFileModeUnzip) { ++ NSString *reason= [NSString stringWithFormat:@"Operation not permitted without Unzip mode"]; ++ @throw [[ZipException alloc] initWithReason:reason]; ++ } ++ ++ char filename_inzip[FILE_IN_ZIP_MAX_NAME_LENGTH]; ++ unz_file_info file_info; ++ ++ int err= unzGetCurrentFileInfo(_unzFile, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0); ++ if (err != UNZ_OK) { ++ NSString *reason= [NSString stringWithFormat:@"Error in getting current file info in '%@'", _fileName]; ++ @throw [[ZipException alloc] initWithError:err reason:reason]; ++ } ++ ++ NSString *name= [NSString stringWithCString:filename_inzip encoding:NSUTF8StringEncoding]; ++ ++ ZipCompressionLevel level= ZipCompressionLevelNone; ++ if (file_info.compression_method != 0) { ++ switch ((file_info.flag & 0x6) / 2) { ++ case 0: ++ level= ZipCompressionLevelDefault; ++ break; ++ ++ case 1: ++ level= ZipCompressionLevelBest; ++ break; ++ ++ default: ++ level= ZipCompressionLevelFastest; ++ break; ++ } ++ } ++ ++ BOOL crypted= ((file_info.flag & 1) != 0); ++ ++ NSDateComponents *components= [[NSDateComponents alloc] init]; ++ [components setDay:file_info.tmu_date.tm_mday]; ++ [components setMonth:file_info.tmu_date.tm_mon +1]; ++ [components setYear:file_info.tmu_date.tm_year]; ++ [components setHour:file_info.tmu_date.tm_hour]; ++ [components setMinute:file_info.tmu_date.tm_min]; ++ [components setSecond:file_info.tmu_date.tm_sec]; ++ NSCalendar *calendar= [NSCalendar currentCalendar]; ++ NSDate *date= [calendar dateFromComponents:components]; ++ ++ FileInZipInfo *info= [[FileInZipInfo alloc] initWithName:name length:file_info.uncompressed_size level:level crypted:crypted size:file_info.compressed_size date:date crc32:file_info.crc]; ++ return info; ++} ++ ++- (ZipReadStream *) readCurrentFileInZip { ++ if (_mode != ZipFileModeUnzip) { ++ NSString *reason= [NSString stringWithFormat:@"Operation not permitted without Unzip mode"]; ++ @throw [[ZipException alloc] initWithReason:reason]; ++ } ++ ++ char filename_inzip[FILE_IN_ZIP_MAX_NAME_LENGTH]; ++ unz_file_info file_info; ++ ++ int err= unzGetCurrentFileInfo(_unzFile, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0); ++ if (err != UNZ_OK) { ++ NSString *reason= [NSString stringWithFormat:@"Error in getting current file info in '%@'", _fileName]; ++ @throw [[ZipException alloc] initWithError:err reason:reason]; ++ } ++ ++ NSString *fileNameInZip= [NSString stringWithCString:filename_inzip encoding:NSUTF8StringEncoding]; ++ ++ err= unzOpenCurrentFilePassword(_unzFile, NULL); ++ if (err != UNZ_OK) { ++ NSString *reason= [NSString stringWithFormat:@"Error in opening current file in '%@'", _fileName]; ++ @throw [[ZipException alloc] initWithError:err reason:reason]; ++ } ++ ++ return [[ZipReadStream alloc] initWithUnzFileStruct:_unzFile fileNameInZip:fileNameInZip]; ++} ++ ++- (ZipReadStream *) readCurrentFileInZipWithPassword:(NSString *)password { ++ if (_mode != ZipFileModeUnzip) { ++ NSString *reason= [NSString stringWithFormat:@"Operation not permitted without Unzip mode"]; ++ @throw [[ZipException alloc] initWithReason:reason]; ++ } ++ ++ char filename_inzip[FILE_IN_ZIP_MAX_NAME_LENGTH]; ++ unz_file_info file_info; ++ ++ int err= unzGetCurrentFileInfo(_unzFile, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0); ++ if (err != UNZ_OK) { ++ NSString *reason= [NSString stringWithFormat:@"Error in getting current file info in '%@'", _fileName]; ++ @throw [[ZipException alloc] initWithError:err reason:reason]; ++ } ++ ++ NSString *fileNameInZip= [NSString stringWithCString:filename_inzip encoding:NSUTF8StringEncoding]; ++ ++ err= unzOpenCurrentFilePassword(_unzFile, [password cStringUsingEncoding:NSUTF8StringEncoding]); ++ if (err != UNZ_OK) { ++ NSString *reason= [NSString stringWithFormat:@"Error in opening current file in '%@'", _fileName]; ++ @throw [[ZipException alloc] initWithError:err reason:reason]; ++ } ++ ++ return [[ZipReadStream alloc] initWithUnzFileStruct:_unzFile fileNameInZip:fileNameInZip]; ++} ++ ++- (void) close { ++ switch (_mode) { ++ case ZipFileModeUnzip: { ++ int err= unzClose(_unzFile); ++ if (err != UNZ_OK) { ++ NSString *reason= [NSString stringWithFormat:@"Error in closing '%@'", _fileName]; ++ @throw [[ZipException alloc] initWithError:err reason:reason]; ++ } ++ break; ++ } ++ ++ case ZipFileModeCreate: { ++ int err= zipClose(_zipFile, NULL); ++ if (err != ZIP_OK) { ++ NSString *reason= [NSString stringWithFormat:@"Error in closing '%@'", _fileName]; ++ @throw [[ZipException alloc] initWithError:err reason:reason]; ++ } ++ break; ++ } ++ ++ case ZipFileModeAppend: { ++ int err= zipClose(_zipFile, NULL); ++ if (err != ZIP_OK) { ++ NSString *reason= [NSString stringWithFormat:@"Error in closing '%@'", _fileName]; ++ @throw [[ZipException alloc] initWithError:err reason:reason]; ++ } ++ break; ++ } ++ ++ default: { ++ NSString *reason= [NSString stringWithFormat:@"Unknown mode %d", _mode]; ++ @throw [[ZipException alloc] initWithReason:reason]; ++ } ++ } ++} ++ ++ ++@end +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipReadStream.h b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipReadStream.h +new file mode 100644 +index 0000000..0966611 +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipReadStream.h +@@ -0,0 +1,51 @@ ++// ++// ZipReadStream.h ++// Objective-Zip v. 0.7.2 ++// ++// Created by Gianluca Bertani on 28/12/09. ++// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. ++// ++// Redistribution and use in source and binary forms, with or without ++// modification, are permitted provided that the following conditions ++// are met: ++// ++// * Redistributions of source code must retain the above copyright notice, ++// this list of conditions and the following disclaimer. ++// * Redistributions in binary form must reproduce the above copyright notice, ++// this list of conditions and the following disclaimer in the documentation ++// and/or other materials provided with the distribution. ++// * Neither the name of Gianluca Bertani nor the names of its contributors ++// may be used to endorse or promote products derived from this software ++// without specific prior written permission. ++// ++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++// POSSIBILITY OF SUCH DAMAGE. ++// ++ ++#import ++ ++#include "unzip.h" ++ ++ ++@interface ZipReadStream : NSObject { ++ NSString *_fileNameInZip; ++ ++@private ++ unzFile _unzFile; ++} ++ ++- (id) initWithUnzFileStruct:(unzFile)unzFile fileNameInZip:(NSString *)fileNameInZip; ++ ++- (NSData *)readDataOfLength:(NSUInteger)length; ++- (void) finishedReading; ++ ++@end +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipReadStream.m b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipReadStream.m +new file mode 100644 +index 0000000..6144a1f +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipReadStream.m +@@ -0,0 +1,73 @@ ++// ++// ZipReadStream.m ++// Objective-Zip v. 0.7.2 ++// ++// Created by Gianluca Bertani on 28/12/09. ++// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. ++// ++// Redistribution and use in source and binary forms, with or without ++// modification, are permitted provided that the following conditions ++// are met: ++// ++// * Redistributions of source code must retain the above copyright notice, ++// this list of conditions and the following disclaimer. ++// * Redistributions in binary form must reproduce the above copyright notice, ++// this list of conditions and the following disclaimer in the documentation ++// and/or other materials provided with the distribution. ++// * Neither the name of Gianluca Bertani nor the names of its contributors ++// may be used to endorse or promote products derived from this software ++// without specific prior written permission. ++// ++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++// POSSIBILITY OF SUCH DAMAGE. ++// ++ ++#import "ZipReadStream.h" ++#import "ZipException.h" ++ ++#include "unzip.h" ++ ++ ++@implementation ZipReadStream ++ ++ ++- (id) initWithUnzFileStruct:(unzFile)unzFile fileNameInZip:(NSString *)fileNameInZip { ++ if ((self= [super init])) { ++ _unzFile= unzFile; ++ _fileNameInZip= fileNameInZip; ++ } ++ ++ return self; ++} ++ ++- (NSData *)readDataOfLength:(NSUInteger)length { ++ NSMutableData *data = [NSMutableData dataWithLength:length]; ++ int bytes = unzReadCurrentFile(_unzFile, [data mutableBytes], (unsigned)length); ++ if (bytes < 0) { ++ NSString *reason= [NSString stringWithFormat:@"Error in reading '%@' in the zipfile", _fileNameInZip]; ++ @throw [[ZipException alloc] initWithError:bytes reason:reason]; ++ } ++ ++ [data setLength:bytes]; ++ return data; ++} ++ ++- (void) finishedReading { ++ int err= unzCloseCurrentFile(_unzFile); ++ if (err != UNZ_OK) { ++ NSString *reason= [NSString stringWithFormat:@"Error in closing '%@' in the zipfile", _fileNameInZip]; ++ @throw [[ZipException alloc] initWithError:err reason:reason]; ++ } ++} ++ ++ ++@end +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipWriteStream.h b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipWriteStream.h +new file mode 100644 +index 0000000..5836172 +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipWriteStream.h +@@ -0,0 +1,51 @@ ++// ++// ZipWriteStream.h ++// Objective-Zip v. 0.7.2 ++// ++// Created by Gianluca Bertani on 25/12/09. ++// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. ++// ++// Redistribution and use in source and binary forms, with or without ++// modification, are permitted provided that the following conditions ++// are met: ++// ++// * Redistributions of source code must retain the above copyright notice, ++// this list of conditions and the following disclaimer. ++// * Redistributions in binary form must reproduce the above copyright notice, ++// this list of conditions and the following disclaimer in the documentation ++// and/or other materials provided with the distribution. ++// * Neither the name of Gianluca Bertani nor the names of its contributors ++// may be used to endorse or promote products derived from this software ++// without specific prior written permission. ++// ++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++// POSSIBILITY OF SUCH DAMAGE. ++// ++ ++#import ++ ++#include "zip.h" ++ ++ ++@interface ZipWriteStream : NSObject { ++ NSString *_fileNameInZip; ++ ++@private ++ zipFile _zipFile; ++} ++ ++- (id) initWithZipFileStruct:(zipFile)zipFile fileNameInZip:(NSString *)fileNameInZip; ++ ++- (void) writeData:(NSData *)data; ++- (void) finishedWriting; ++ ++@end +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipWriteStream.m b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipWriteStream.m +new file mode 100644 +index 0000000..4eec235 +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Objective-Zip/ZipWriteStream.m +@@ -0,0 +1,69 @@ ++// ++// ZipWriteStream.m ++// Objective-Zip v. 0.7.2 ++// ++// Created by Gianluca Bertani on 25/12/09. ++// Copyright 2009-10 Flying Dolphin Studio. All rights reserved. ++// ++// Redistribution and use in source and binary forms, with or without ++// modification, are permitted provided that the following conditions ++// are met: ++// ++// * Redistributions of source code must retain the above copyright notice, ++// this list of conditions and the following disclaimer. ++// * Redistributions in binary form must reproduce the above copyright notice, ++// this list of conditions and the following disclaimer in the documentation ++// and/or other materials provided with the distribution. ++// * Neither the name of Gianluca Bertani nor the names of its contributors ++// may be used to endorse or promote products derived from this software ++// without specific prior written permission. ++// ++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++// POSSIBILITY OF SUCH DAMAGE. ++// ++ ++#import "ZipWriteStream.h" ++#import "ZipException.h" ++ ++#include "zip.h" ++ ++ ++@implementation ZipWriteStream ++ ++ ++- (id) initWithZipFileStruct:(zipFile)zipFile fileNameInZip:(NSString *)fileNameInZip { ++ if ((self= [super init])) { ++ _zipFile= zipFile; ++ _fileNameInZip= fileNameInZip; ++ } ++ ++ return self; ++} ++ ++- (void) writeData:(NSData *)data { ++ int err= zipWriteInFileInZip(_zipFile, [data bytes], (unsigned)[data length]); ++ if (err < 0) { ++ NSString *reason= [NSString stringWithFormat:@"Error in writing '%@' in the zipfile", _fileNameInZip]; ++ @throw [[ZipException alloc] initWithError:err reason:reason]; ++ } ++} ++ ++- (void) finishedWriting { ++ int err= zipCloseFileInZip(_zipFile); ++ if (err != ZIP_OK) { ++ NSString *reason= [NSString stringWithFormat:@"Error in closing '%@' in the zipfile", _fileNameInZip]; ++ @throw [[ZipException alloc] initWithError:err reason:reason]; ++ } ++} ++ ++ ++@end +diff --git a/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Settings.bundle/Root.plist b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Settings.bundle/Root.plist +new file mode 100644 +index 0000000..f64434e +--- /dev/null ++++ b/node_modules/rn-fetch-blob/ios/KeyShareConsumer/Settings.bundle/Root.plist +@@ -0,0 +1,167 @@ ++ ++ ++ ++ ++ StringsTable ++ Root ++ PreferenceSpecifiers ++ ++ ++ Title ++ User selected keys ++ Type ++ PSGroupSpecifier ++ ++ ++ Type ++ PSToggleSwitchSpecifier ++ Title ++ All keys (com.rsa.pkcs-12) ++ Key ++ toggle_com_rsa_pkcs12 ++ DefaultValue ++ ++ ++ ++ Type ++ PSToggleSwitchSpecifier ++ Title ++ All keys (purebred.select.all) ++ Key ++ toggle_purebred_select_all ++ DefaultValue ++ ++ ++ ++ Type ++ PSToggleSwitchSpecifier ++ Title ++ All user keys (purebred.select.all.user) ++ Key ++ toggle_purebred_select_all_user ++ DefaultValue ++ ++ ++ ++ Type ++ PSToggleSwitchSpecifier ++ Title ++ Signature keys (purebred.select.signature) ++ Key ++ toggle_purebred_select_signature ++ DefaultValue ++ ++ ++ ++ Type ++ PSToggleSwitchSpecifier ++ Title ++ All encryption keys (purebred.select.encryption) ++ Key ++ toggle_purebred_select_encryption ++ DefaultValue ++ ++ ++ ++ Type ++ PSToggleSwitchSpecifier ++ Title ++ All authentication keys (purebred.select.authentication) ++ Key ++ toggle_purebred_select_authentication ++ DefaultValue ++ ++ ++ ++ Type ++ PSToggleSwitchSpecifier ++ Title ++ All device keys (purebred.select.device) ++ Key ++ toggle_purebred_select_device ++ DefaultValue ++ ++ ++ ++ Type ++ PSToggleSwitchSpecifier ++ Title ++ All device keys (purebred.zip.all) ++ Key ++ toggle_purebred_zip_all ++ DefaultValue ++ ++ ++ ++ Type ++ PSToggleSwitchSpecifier ++ Title ++ All user keys (purebred.zip.all.user) ++ Key ++ toggle_purebred_zip_all_user ++ DefaultValue ++ ++ ++ ++ Type ++ PSToggleSwitchSpecifier ++ Title ++ Signature keys (purebred.zip.signature) ++ Key ++ toggle_purebred_zip_signature ++ DefaultValue ++ ++ ++ ++ Type ++ PSToggleSwitchSpecifier ++ Title ++ All encryption keys (purebred.zip.encryption) ++ Key ++ toggle_purebred_zip_encryption ++ DefaultValue ++ ++ ++ ++ Type ++ PSToggleSwitchSpecifier ++ Title ++ All authentication keys (purebred.zip.authentication) ++ Key ++ toggle_purebred_zip_authentication ++ DefaultValue ++ ++ ++ ++ Type ++ PSToggleSwitchSpecifier ++ Title ++ All device keys (purebred.zip.device) ++ Key ++ toggle_purebred_zip_device ++ DefaultValue ++ ++ ++ ++ Type ++ PSToggleSwitchSpecifier ++ Title ++ Do not filter on notBefore for zip files (purebred.zip.no_filter) ++ Key ++ toggle_purebred_zip_no_filter ++ DefaultValue ++ ++ ++ ++ Type ++ PSToggleSwitchSpecifier ++ Title ++ Do not filter on notBefore (purebred.select.no_filter) ++ Key ++ toggle_purebred_select_no_filter ++ DefaultValue ++ ++ ++ ++ ++ +diff --git a/node_modules/rn-fetch-blob/ios/RNFetchBlob.xcodeproj/project.pbxproj b/node_modules/rn-fetch-blob/ios/RNFetchBlob.xcodeproj/project.pbxproj +index 4fbdc00..dfc9cba 100644 +--- a/node_modules/rn-fetch-blob/ios/RNFetchBlob.xcodeproj/project.pbxproj ++++ b/node_modules/rn-fetch-blob/ios/RNFetchBlob.xcodeproj/project.pbxproj +@@ -7,6 +7,17 @@ + objects = { + + /* Begin PBXBuildFile section */ ++ 7FF31BB72132F76F00680B75 /* unzip.c in Sources */ = {isa = PBXBuildFile; fileRef = 7FF31BA22132F76F00680B75 /* unzip.c */; }; ++ 7FF31BB82132F76F00680B75 /* zip.c in Sources */ = {isa = PBXBuildFile; fileRef = 7FF31BA32132F76F00680B75 /* zip.c */; }; ++ 7FF31BB92132F76F00680B75 /* ioapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 7FF31BA42132F76F00680B75 /* ioapi.c */; }; ++ 7FF31BBA2132F76F00680B75 /* mztools.c in Sources */ = {isa = PBXBuildFile; fileRef = 7FF31BA52132F76F00680B75 /* mztools.c */; }; ++ 7FF31BBB2132F76F00680B75 /* KeyChainDataSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7FF31BAA2132F76F00680B75 /* KeyChainDataSource.mm */; }; ++ 7FF31BBC2132F76F00680B75 /* CBAViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FF31BAB2132F76F00680B75 /* CBAViewController.m */; }; ++ 7FF31BBD2132F76F00680B75 /* ZipWriteStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FF31BB02132F76F00680B75 /* ZipWriteStream.m */; }; ++ 7FF31BBE2132F76F00680B75 /* ZipFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FF31BB12132F76F00680B75 /* ZipFile.m */; }; ++ 7FF31BBF2132F76F00680B75 /* ZipReadStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FF31BB22132F76F00680B75 /* ZipReadStream.m */; }; ++ 7FF31BC02132F76F00680B75 /* ZipException.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FF31BB32132F76F00680B75 /* ZipException.m */; }; ++ 7FF31BC12132F76F00680B75 /* FileInZipInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FF31BB42132F76F00680B75 /* FileInZipInfo.m */; }; + 8C4801A6200CF71700FED7ED /* RNFetchBlobRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C4801A5200CF71700FED7ED /* RNFetchBlobRequest.m */; }; + A158F4271D052E49006FFD38 /* RNFetchBlobFS.m in Sources */ = {isa = PBXBuildFile; fileRef = A158F4261D052E49006FFD38 /* RNFetchBlobFS.m */; }; + A158F42D1D0535BB006FFD38 /* RNFetchBlobConst.m in Sources */ = {isa = PBXBuildFile; fileRef = A158F42C1D0535BB006FFD38 /* RNFetchBlobConst.m */; }; +@@ -30,6 +41,29 @@ + /* End PBXCopyFilesBuildPhase section */ + + /* Begin PBXFileReference section */ ++ 7FF31B9E2132F76F00680B75 /* CBAViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CBAViewController.h; sourceTree = ""; }; ++ 7FF31B9F2132F76F00680B75 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; ++ 7FF31BA02132F76F00680B75 /* KeyChainDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeyChainDataSource.h; sourceTree = ""; }; ++ 7FF31BA22132F76F00680B75 /* unzip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unzip.c; sourceTree = ""; }; ++ 7FF31BA32132F76F00680B75 /* zip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = zip.c; sourceTree = ""; }; ++ 7FF31BA42132F76F00680B75 /* ioapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioapi.c; sourceTree = ""; }; ++ 7FF31BA52132F76F00680B75 /* mztools.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mztools.c; sourceTree = ""; }; ++ 7FF31BA62132F76F00680B75 /* zip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = zip.h; sourceTree = ""; }; ++ 7FF31BA72132F76F00680B75 /* unzip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unzip.h; sourceTree = ""; }; ++ 7FF31BA82132F76F00680B75 /* mztools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mztools.h; sourceTree = ""; }; ++ 7FF31BA92132F76F00680B75 /* ioapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ioapi.h; sourceTree = ""; }; ++ 7FF31BAA2132F76F00680B75 /* KeyChainDataSource.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyChainDataSource.mm; sourceTree = ""; }; ++ 7FF31BAB2132F76F00680B75 /* CBAViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CBAViewController.m; sourceTree = ""; }; ++ 7FF31BAD2132F76F00680B75 /* ZipReadStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZipReadStream.h; sourceTree = ""; }; ++ 7FF31BAE2132F76F00680B75 /* FileInZipInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileInZipInfo.h; sourceTree = ""; }; ++ 7FF31BAF2132F76F00680B75 /* ZipException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZipException.h; sourceTree = ""; }; ++ 7FF31BB02132F76F00680B75 /* ZipWriteStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZipWriteStream.m; sourceTree = ""; }; ++ 7FF31BB12132F76F00680B75 /* ZipFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZipFile.m; sourceTree = ""; }; ++ 7FF31BB22132F76F00680B75 /* ZipReadStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZipReadStream.m; sourceTree = ""; }; ++ 7FF31BB32132F76F00680B75 /* ZipException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZipException.m; sourceTree = ""; }; ++ 7FF31BB42132F76F00680B75 /* FileInZipInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileInZipInfo.m; sourceTree = ""; }; ++ 7FF31BB52132F76F00680B75 /* ZipWriteStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZipWriteStream.h; sourceTree = ""; }; ++ 7FF31BB62132F76F00680B75 /* ZipFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZipFile.h; sourceTree = ""; }; + 8C4801A4200CF71700FED7ED /* RNFetchBlobRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNFetchBlobRequest.h; sourceTree = ""; }; + 8C4801A5200CF71700FED7ED /* RNFetchBlobRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNFetchBlobRequest.m; sourceTree = ""; }; + A158F4261D052E49006FFD38 /* RNFetchBlobFS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFetchBlobFS.m; sourceTree = ""; }; +@@ -59,6 +93,52 @@ + /* End PBXFrameworksBuildPhase section */ + + /* Begin PBXGroup section */ ++ 7FF31B9D2132F76F00680B75 /* KeyShareConsumer */ = { ++ isa = PBXGroup; ++ children = ( ++ 7FF31BAC2132F76F00680B75 /* Objective-Zip */, ++ 7FF31BA12132F76F00680B75 /* MiniZip */, ++ 7FF31B9E2132F76F00680B75 /* CBAViewController.h */, ++ 7FF31BAB2132F76F00680B75 /* CBAViewController.m */, ++ 7FF31BA02132F76F00680B75 /* KeyChainDataSource.h */, ++ 7FF31BAA2132F76F00680B75 /* KeyChainDataSource.mm */, ++ 7FF31B9F2132F76F00680B75 /* Settings.bundle */, ++ ); ++ path = KeyShareConsumer; ++ sourceTree = ""; ++ }; ++ 7FF31BA12132F76F00680B75 /* MiniZip */ = { ++ isa = PBXGroup; ++ children = ( ++ 7FF31BA22132F76F00680B75 /* unzip.c */, ++ 7FF31BA32132F76F00680B75 /* zip.c */, ++ 7FF31BA42132F76F00680B75 /* ioapi.c */, ++ 7FF31BA52132F76F00680B75 /* mztools.c */, ++ 7FF31BA62132F76F00680B75 /* zip.h */, ++ 7FF31BA72132F76F00680B75 /* unzip.h */, ++ 7FF31BA82132F76F00680B75 /* mztools.h */, ++ 7FF31BA92132F76F00680B75 /* ioapi.h */, ++ ); ++ path = MiniZip; ++ sourceTree = ""; ++ }; ++ 7FF31BAC2132F76F00680B75 /* Objective-Zip */ = { ++ isa = PBXGroup; ++ children = ( ++ 7FF31BAD2132F76F00680B75 /* ZipReadStream.h */, ++ 7FF31BAE2132F76F00680B75 /* FileInZipInfo.h */, ++ 7FF31BAF2132F76F00680B75 /* ZipException.h */, ++ 7FF31BB02132F76F00680B75 /* ZipWriteStream.m */, ++ 7FF31BB12132F76F00680B75 /* ZipFile.m */, ++ 7FF31BB22132F76F00680B75 /* ZipReadStream.m */, ++ 7FF31BB32132F76F00680B75 /* ZipException.m */, ++ 7FF31BB42132F76F00680B75 /* FileInZipInfo.m */, ++ 7FF31BB52132F76F00680B75 /* ZipWriteStream.h */, ++ 7FF31BB62132F76F00680B75 /* ZipFile.h */, ++ ); ++ path = "Objective-Zip"; ++ sourceTree = ""; ++ }; + 8BD9ABDFAF76406291A798F2 /* Libraries */ = { + isa = PBXGroup; + children = ( +@@ -69,6 +149,7 @@ + A15C30051CD25C330074CB35 = { + isa = PBXGroup; + children = ( ++ 7FF31B9D2132F76F00680B75 /* KeyShareConsumer */, + A19B48241D98102400E6868A /* RNFetchBlobProgress.m */, + A19B48231D98100800E6868A /* RNFetchBlobProgress.h */, + A1F950181D7E9134002A95A6 /* IOS7Polyfill.h */, +@@ -153,12 +234,23 @@ + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( ++ 7FF31BC12132F76F00680B75 /* FileInZipInfo.m in Sources */, ++ 7FF31BB72132F76F00680B75 /* unzip.c in Sources */, ++ 7FF31BBB2132F76F00680B75 /* KeyChainDataSource.mm in Sources */, + A166D1AA1CE0647A00273590 /* RNFetchBlob.h in Sources */, ++ 7FF31BBA2132F76F00680B75 /* mztools.c in Sources */, + 8C4801A6200CF71700FED7ED /* RNFetchBlobRequest.m in Sources */, ++ 7FF31BB82132F76F00680B75 /* zip.c in Sources */, ++ 7FF31BBD2132F76F00680B75 /* ZipWriteStream.m in Sources */, ++ 7FF31BBE2132F76F00680B75 /* ZipFile.m in Sources */, + A158F42D1D0535BB006FFD38 /* RNFetchBlobConst.m in Sources */, + A158F4271D052E49006FFD38 /* RNFetchBlobFS.m in Sources */, ++ 7FF31BBF2132F76F00680B75 /* ZipReadStream.m in Sources */, ++ 7FF31BC02132F76F00680B75 /* ZipException.m in Sources */, + A158F4301D0539DB006FFD38 /* RNFetchBlobNetwork.m in Sources */, ++ 7FF31BBC2132F76F00680B75 /* CBAViewController.m in Sources */, + A19B48251D98102400E6868A /* RNFetchBlobProgress.m in Sources */, ++ 7FF31BB92132F76F00680B75 /* ioapi.c in Sources */, + A1AAE2991D300E4D0051D11C /* RNFetchBlobReqBuilder.m in Sources */, + A15C30141CD25C330074CB35 /* RNFetchBlob.m in Sources */, + ); +diff --git a/node_modules/rn-fetch-blob/ios/RNFetchBlob/RNFetchBlob.m b/node_modules/rn-fetch-blob/ios/RNFetchBlob/RNFetchBlob.m +index 671aa69..0522ffc 100644 +--- a/node_modules/rn-fetch-blob/ios/RNFetchBlob/RNFetchBlob.m ++++ b/node_modules/rn-fetch-blob/ios/RNFetchBlob/RNFetchBlob.m +@@ -10,6 +10,7 @@ + #import "RNFetchBlobConst.h" + #import "RNFetchBlobReqBuilder.h" + #import "RNFetchBlobProgress.h" ++#import "CBAViewController.h" + + + __strong RCTBridge * bridgeRef; +@@ -250,6 +251,11 @@ - (NSDictionary *)constantsToExport + [RNFetchBlobFS exists:path callback:callback]; + } + ++#pragma mark - fs.existsWithDiffExt ++RCT_EXPORT_METHOD(existsWithDiffExt:(NSString *)path callback:(RCTResponseSenderBlock)callback) { ++ [RNFetchBlobFS existsWithDiffExt:path callback:callback]; ++} ++ + #pragma mark - fs.writeFile + RCT_EXPORT_METHOD(writeFile:(NSString *)path encoding:(NSString *)encoding data:(NSString *)data append:(BOOL)append resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) + { +@@ -649,7 +655,16 @@ - (UIViewController *) documentInteractionControllerViewControllerForPreview: (U + [RNFetchBlobNetwork emitExpiredTasks]; + } + +- ++# pragma mark - Select certificate to use in Mutual TLS ++RCT_EXPORT_METHOD(selectCertificate:(RCTResponseSenderBlock)callback) { ++ dispatch_async(dispatch_get_main_queue(), ^{ ++ UIStoryboard *sb = [UIStoryboard storyboardWithName:@"KeyShareConsumer" bundle: nil]; ++ CBAViewController *vc = [sb instantiateInitialViewController]; ++ [vc setCallback:callback]; ++ UIViewController *rootViewController = [[[[UIApplication sharedApplication]delegate] window] rootViewController]; ++ [rootViewController presentViewController:vc animated:YES completion:nil]; ++ }); ++} + + + @end +diff --git a/node_modules/rn-fetch-blob/ios/RNFetchBlobConst.h b/node_modules/rn-fetch-blob/ios/RNFetchBlobConst.h +index 7d09c3a..f2ddcdf 100644 +--- a/node_modules/rn-fetch-blob/ios/RNFetchBlobConst.h ++++ b/node_modules/rn-fetch-blob/ios/RNFetchBlobConst.h +@@ -22,6 +22,7 @@ extern NSString *const EVENT_PROGRESS; + extern NSString *const EVENT_SERVER_PUSH; + extern NSString *const EVENT_PROGRESS_UPLOAD; + extern NSString *const EVENT_STATE_CHANGE; ++extern NSString *const EVENT_CERTIFICATE_NEEDED; + + extern NSString *const FILE_PREFIX; + extern NSString *const ASSET_PREFIX; +@@ -51,6 +52,4 @@ extern NSString *const RESP_TYPE_BASE64; + extern NSString *const RESP_TYPE_UTF8; + extern NSString *const RESP_TYPE_PATH; + +- +- + #endif /* RNFetchBlobConst_h */ +diff --git a/node_modules/rn-fetch-blob/ios/RNFetchBlobConst.m b/node_modules/rn-fetch-blob/ios/RNFetchBlobConst.m +index 1376d69..9608be3 100644 +--- a/node_modules/rn-fetch-blob/ios/RNFetchBlobConst.m ++++ b/node_modules/rn-fetch-blob/ios/RNFetchBlobConst.m +@@ -26,6 +26,7 @@ + NSString *const EVENT_PROGRESS = @"RNFetchBlobProgress"; + NSString *const EVENT_PROGRESS_UPLOAD = @"RNFetchBlobProgress-upload"; + NSString *const EVENT_EXPIRE = @"RNFetchBlobExpire"; ++NSString *const EVENT_CERTIFICATE_NEEDED = @"RNFetchBlobCertificate"; + + NSString *const MSG_EVENT = @"RNFetchBlobMessage"; + NSString *const MSG_EVENT_LOG = @"log"; +diff --git a/node_modules/rn-fetch-blob/ios/RNFetchBlobFS.h b/node_modules/rn-fetch-blob/ios/RNFetchBlobFS.h +index 5141201..21ee470 100644 +--- a/node_modules/rn-fetch-blob/ios/RNFetchBlobFS.h ++++ b/node_modules/rn-fetch-blob/ios/RNFetchBlobFS.h +@@ -70,6 +70,7 @@ + rejecter:(RCTPromiseRejectBlock)reject; + + (NSDictionary *) stat:(NSString *) path error:(NSError **) error; + + (void) exists:(NSString *) path callback:(RCTResponseSenderBlock)callback; +++ (void) existsWithDiffExt:(NSString *) path callback:(RCTResponseSenderBlock)callback; + + (void) writeFileArray:(NSString *)path data:(NSArray *)data append:(BOOL)append resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject; + + (void) writeFile:(NSString *)path encoding:(NSString *)encoding data:(NSString *)data append:(BOOL)append resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject; + + (void) readFile:(NSString *)path encoding:(NSString *)encoding onComplete:(void (^)(NSData * content, NSString* code, NSString * errMsg))onComplete; +diff --git a/node_modules/rn-fetch-blob/ios/RNFetchBlobFS.m b/node_modules/rn-fetch-blob/ios/RNFetchBlobFS.m +index e597ee5..fa19a7b 100644 +--- a/node_modules/rn-fetch-blob/ios/RNFetchBlobFS.m ++++ b/node_modules/rn-fetch-blob/ios/RNFetchBlobFS.m +@@ -689,6 +689,33 @@ + (void) exists:(NSString *) path callback:(RCTResponseSenderBlock)callback + }]; + } + ++# pragma mark - existsWithDiffExt ++ +++ (void) existsWithDiffExt:(NSString *)path callback:(RCTResponseSenderBlock)callback ++{ ++ NSFileManager *manager = [NSFileManager defaultManager]; ++ NSString *directory = [path stringByDeletingLastPathComponent]; ++ BOOL isDir = NO; ++ BOOL exists = NO; ++ exists = [manager fileExistsAtPath:directory isDirectory: &isDir]; ++ ++ if (exists && isDir) { ++ NSArray *contents = [manager contentsOfDirectoryAtPath:directory error:nil]; ++ NSString *fileName = [[path lastPathComponent] stringByDeletingPathExtension]; ++ NSString *item; ++ for (item in contents) ++ { ++ NSString *itemName = [[item lastPathComponent] stringByDeletingPathExtension]; ++ if ([itemName isEqualToString:fileName]) { ++ callback(@[[directory stringByAppendingPathComponent:item]]); ++ return; ++ } ++ } ++ } ++ ++ callback(@[@""]); ++} ++ + # pragma mark - open file stream + + // Create file stream for write data +diff --git a/node_modules/rn-fetch-blob/ios/RNFetchBlobReqBuilder.m b/node_modules/rn-fetch-blob/ios/RNFetchBlobReqBuilder.m +index 16963bb..db278db 100644 +--- a/node_modules/rn-fetch-blob/ios/RNFetchBlobReqBuilder.m ++++ b/node_modules/rn-fetch-blob/ios/RNFetchBlobReqBuilder.m +@@ -205,10 +205,8 @@ void __block (^getFieldData)(id field) = ^(id field) + // field is a text field + if([field valueForKey:@"filename"] == nil || content == nil) { + contentType = contentType == nil ? @"text/plain" : contentType; +- [formData appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; +- [formData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n", name] dataUsingEncoding:NSUTF8StringEncoding]]; +- [formData appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", contentType] dataUsingEncoding:NSUTF8StringEncoding]]; +- [formData appendData:[[NSString stringWithFormat:@"%@\r\n", content] dataUsingEncoding:NSUTF8StringEncoding]]; ++ [formData appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; ++ [formData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\";\r\n\r\n%@", name, content] dataUsingEncoding:NSUTF8StringEncoding]]; + } + // field contains a file + else { +@@ -229,7 +227,7 @@ void __block (^getFieldData)(id field) = ^(id field) + return; + } + NSString * filename = [field valueForKey:@"filename"]; +- [formData appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; ++ [formData appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; + [formData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", name, filename] dataUsingEncoding:NSUTF8StringEncoding]]; + [formData appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", contentType] dataUsingEncoding:NSUTF8StringEncoding]]; + [formData appendData:content]; +diff --git a/node_modules/rn-fetch-blob/ios/RNFetchBlobRequest.h b/node_modules/rn-fetch-blob/ios/RNFetchBlobRequest.h +index b550ac2..b603f44 100644 +--- a/node_modules/rn-fetch-blob/ios/RNFetchBlobRequest.h ++++ b/node_modules/rn-fetch-blob/ios/RNFetchBlobRequest.h +@@ -12,6 +12,7 @@ + #import + + #import "RNFetchBlobProgress.h" ++#import "KeyChainDataSource.h" + + #if __has_include() + #import +@@ -33,6 +34,7 @@ + @property (nullable, nonatomic) RNFetchBlobProgress *progressConfig; + @property (nullable, nonatomic) RNFetchBlobProgress *uploadProgressConfig; + @property (nullable, nonatomic, weak) NSURLSessionDataTask *task; ++@property (nonatomic, retain) KeyChainDataSource *keyChain; + + - (void) sendRequest:(NSDictionary * _Nullable )options + contentLength:(long)contentLength +diff --git a/node_modules/rn-fetch-blob/ios/RNFetchBlobRequest.m b/node_modules/rn-fetch-blob/ios/RNFetchBlobRequest.m +index cdbe6b1..56e97eb 100644 +--- a/node_modules/rn-fetch-blob/ios/RNFetchBlobRequest.m ++++ b/node_modules/rn-fetch-blob/ios/RNFetchBlobRequest.m +@@ -51,7 +51,6 @@ @implementation RNFetchBlobRequest + @synthesize options; + @synthesize error; + +- + - (NSString *)md5:(NSString *)input { + const char* str = [input UTF8String]; + unsigned char result[CC_MD5_DIGEST_LENGTH]; +@@ -81,6 +80,10 @@ - (void) sendRequest:(__weak NSDictionary * _Nullable )options + self.receivedBytes = 0; + self.options = options; + ++ if (!self.keyChain) { ++ self.keyChain = [[KeyChainDataSource alloc] initWithMode:KSM_Identities]; ++ } ++ + backgroundTask = [[options valueForKey:@"IOSBackgroundTask"] boolValue]; + // when followRedirect not set in options, defaults to TRUE + followRedirect = [options valueForKey:@"followRedirect"] == nil ? YES : [[options valueForKey:@"followRedirect"] boolValue]; +@@ -129,6 +132,14 @@ - (void) sendRequest:(__weak NSDictionary * _Nullable )options + } + + defaultConfigObject.HTTPMaximumConnectionsPerHost = 10; ++ BOOL waitsForConnectivity = [[options valueForKey:@"waitsForConnectivity"] boolValue] ?: NO; ++ float timeoutIntervalForResource = [options valueForKey:@"timeoutIntervalForResource"] == nil ? -1 : [[options valueForKey:@"timeoutIntervalForResource"] floatValue]; ++ if (waitsForConnectivity) { ++ if (@available(iOS 11.0, *)) { ++ defaultConfigObject.waitsForConnectivity = YES; ++ defaultConfigObject.timeoutIntervalForResource = timeoutIntervalForResource; ++ } ++ } + session = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue:operationQueue]; + + if (path || [self.options valueForKey:CONFIG_USE_TEMP]) { +@@ -189,6 +200,13 @@ - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dat + expectedBytes = [response expectedContentLength]; + + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; ++ ++ NSDictionary *headers = [httpResponse allHeaderFields]; ++ NSString *uncompressedLength = headers[@"X-Uncompressed-Content-Length"]; ++ if (uncompressedLength != (id)[NSNull null] && uncompressedLength.length > 0) { ++ expectedBytes = [uncompressedLength intValue]; ++ } ++ + NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; + NSString * respType = @""; + respStatus = statusCode; +@@ -453,6 +471,30 @@ - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSen + + - (void) URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable credantial))completionHandler + { ++ if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodClientCertificate]) { ++ NSString *certificateName = [options valueForKey:@"certificate"]; ++ if (![certificateName isKindOfClass:[NSNull class]] && certificateName) { ++ SecIdentityRef identity = [self.keyChain GetIdentityByName:certificateName]; ++ if (identity != nil) { ++ SecCertificateRef certificate = NULL; ++ OSStatus status = SecIdentityCopyCertificate(identity, &certificate); ++ if (!status) { ++ const void *certs[] = {certificate}; ++ CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, certs, 1, NULL); ++ NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:(__bridge NSArray*)certArray persistence:NSURLCredentialPersistencePermanent]; ++ [challenge.sender useCredential:credential forAuthenticationChallenge:challenge]; ++ completionHandler(NSURLSessionAuthChallengeUseCredential,credential); ++ return; ++ } ++ } ++ } else { ++ [self.bridge.eventDispatcher ++ sendDeviceEventWithName:EVENT_CERTIFICATE_NEEDED ++ body: nil ++ ]; ++ } ++ } ++ + if ([[options valueForKey:CONFIG_TRUSTY] boolValue]) { + completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + } else { +@@ -480,5 +522,4 @@ - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPe + } + } + +- + @end +diff --git a/node_modules/rn-fetch-blob/polyfill/Fetch.js b/node_modules/rn-fetch-blob/polyfill/Fetch.js +index 3ecb591..2cfb8a5 100644 +--- a/node_modules/rn-fetch-blob/polyfill/Fetch.js ++++ b/node_modules/rn-fetch-blob/polyfill/Fetch.js +@@ -29,7 +29,7 @@ class RNFetchBlobFetchPolyfill { + options.headers = options.headers || {} + let ctype = options['Content-Type'] || options['content-type'] + let ctypeH = options.headers['Content-Type'] || options.headers['content-type'] +- options.headers['Content-Type'] = ctype || ctypeH ++ options.headers['Content-Type'] = ctype || ctypeH || 'application/json' + options.headers['content-type'] = ctype || ctypeH + options.method = options.method || 'GET' + if(body) { +@@ -46,8 +46,6 @@ class RNFetchBlobFetchPolyfill { + // When request body is a Blob, use file URI of the Blob as request body. + else if (body.isRNFetchBlobPolyfill) + promise = Promise.resolve(RNFetchBlob.wrap(body.blobPath)) +- else if (typeof body !== 'object' && options.headers['Content-Type'] !== 'application/json') +- promise = Promise.resolve(JSON.stringify(body)) + else if (typeof body !== 'string') + promise = Promise.resolve(body.toString()) + // send it as-is, leave the native module decide how to send the body. +@@ -60,7 +58,9 @@ class RNFetchBlobFetchPolyfill { + let progressHandler, uploadHandler, cancelHandler + let statefulPromise = promise + .then((body) => { +- let task = RNFetchBlob.config(config) ++ let waitsForConnectivity = options.waitsForConnectivity || false; ++ let timeoutIntervalForResource = options.timeoutIntervalForResource || 30; ++ let task = RNFetchBlob.config({...config, waitsForConnectivity, timeoutIntervalForResource}) + .fetch(options.method, url, options.headers, body) + if(progressHandler) + task.progress(progressHandler) +diff --git a/node_modules/rn-fetch-blob/rn-fetch-blob.podspec b/node_modules/rn-fetch-blob/rn-fetch-blob.podspec +index 4edbd5c..e3ef80c 100644 +--- a/node_modules/rn-fetch-blob/rn-fetch-blob.podspec ++++ b/node_modules/rn-fetch-blob/rn-fetch-blob.podspec +@@ -10,7 +10,7 @@ Pod::Spec.new do |s| + s.homepage = 'n/a' + s.source = { :git => "https://github.com/joltup/rn-fetch-blob" } + s.author = 'Joltup' +- s.source_files = 'ios/**/*.{h,m}' ++ s.source_files = 'ios/**/*.{h,m,mm,c}' + s.platform = :ios, "8.0" + s.dependency 'React-Core' + end +diff --git a/node_modules/rn-fetch-blob/types.js b/node_modules/rn-fetch-blob/types.js +index da256af..3eeb51f 100644 +--- a/node_modules/rn-fetch-blob/types.js ++++ b/node_modules/rn-fetch-blob/types.js +@@ -6,6 +6,8 @@ type RNFetchBlobConfig = { + session : string, + addAndroidDownloads : any, + indicator : bool, ++ certificate?: string, ++ waitsForConnectivity: bool, + followRedirect : bool, + trusty : bool, + wifiOnly : bool