InputPackage.m 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. #import "InputPackage.h"
  2. #import "ErrorReturn.h"
  3. #import "HelperClass.h"
  4. @implementation InputPackage
  5. - (NSString*) description {
  6. NSString *orig = [super description];
  7. NSMutableDictionary *details = [NSMutableDictionary new];
  8. NSArray *props = [self properties];
  9. [props enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  10. NSString *cv = [self valueForKey:obj];
  11. if (cv){
  12. details[obj] = cv;
  13. }
  14. }];
  15. return [NSString stringWithFormat:@"%@ = %@", orig, details];
  16. }
  17. - (NSString *)listfile {
  18. __block NSMutableArray *outFiles = [NSMutableArray new];
  19. [self.files enumerateObjectsUsingBlock:^(InputPackageFile * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  20. if ([obj.fileType isEqualToString:@"link"]){ //does this need to handle things differently?
  21. [outFiles addObject:obj.path];
  22. } else {
  23. [outFiles addObject:obj.path];
  24. }
  25. }];
  26. return [outFiles componentsJoinedByString:@"\n"];
  27. }
  28. - (int)installToBootstrapPath:(NSString *)bootstrapPath {
  29. DLog(@"\nFound package: '%@' at version: '%@'...\n", self.packageName, self.version );
  30. NSString *statusFile = [bootstrapPath stringByAppendingPathComponent:@"Library/dpkg/status"];
  31. NSArray *installedPackages = [HelperClass statusInstalledPackagesFromFile:statusFile];
  32. //DLog(@"installedPackages: %@", installedPackages);
  33. StatusPackageModel *model = [[installedPackages filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"package == %@", self.packageName]] lastObject];
  34. if (model) {
  35. DLog(@"\n [WARNING] This package has already been installed! %@", model);
  36. NSComparisonResult result = [self.version compare:model.version options:NSNumericSearch];
  37. DLog(@"\n [WARNING] Comparing version numbers...");
  38. switch (result) {
  39. case NSOrderedSame:
  40. DLog(@"\n [WARNING] %@ and %@ match!", self.version, model.version);
  41. break;
  42. case NSOrderedAscending:
  43. DLog(@"\n [WARNING] Package version %@ is less than installed version %@!", self.version, model.version);
  44. break;
  45. case NSOrderedDescending:
  46. DLog(@"\n [WARNING] Package version %@ is greater than installed version %@!", self.version, model.version);
  47. break;
  48. default:
  49. break;
  50. }
  51. }
  52. ErrorReturn *safePackage = [self errorReturnForBootstrap:bootstrapPath];
  53. if (safePackage.returnStatus != 0) { //zero is success
  54. if (safePackage.returnStatus == 1) //ovewrwrites, just warnings!
  55. {
  56. NSString *error = [NSString stringWithFormat:@" [WARNING] %@ will overwrite the following files: \n\n\t%@\n\n", self.path.lastPathComponent, [safePackage.overwriteFiles componentsJoinedByString:@"\n\t"]];
  57. if(![HelperClass shouldContinueWithError:error]){
  58. return -1;
  59. }
  60. } else if (safePackage.returnStatus == 2) //bail!!"
  61. {
  62. return 2;
  63. }
  64. }
  65. NSString *pwd = [[HelperClass returnForProcess:@"/bin/pwd"] componentsJoinedByString:@"\n"];
  66. NSFileManager *man = [NSFileManager defaultManager];
  67. NSString *tmpPath = [pwd stringByAppendingPathComponent:self.packageName];
  68. NSString *debian = [tmpPath stringByAppendingPathComponent:@"DEBIAN"];
  69. [man createDirectoryAtPath:tmpPath withIntermediateDirectories:TRUE attributes:nil error:nil];
  70. DLog(@"\nExtracting deb for processing...\n");
  71. [HelperClass returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -x %@ %@", self.path, tmpPath]];
  72. NSString *bootstrapInfoPath = [bootstrapPath stringByAppendingPathComponent:@"Library/dpkg/info"];
  73. NSString *listFile = [bootstrapInfoPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.list", self.packageName]];
  74. NSString *md5s = [bootstrapInfoPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.md5sums", self.packageName]];
  75. DLog(@"\nCreating list file '%@'...\n", listFile);
  76. NSString *listString = [NSString stringWithFormat:@"/usr/bin/find %@ -type f -not -path \"*.DS_Store*\" | /usr/bin/sed \"s|%@||g\" >> \"%@\"", tmpPath, tmpPath, listFile];
  77. NSString *listOutput = [HelperClass singleLineReturnForProcess:listString];
  78. //DLog(@"list output: %@", listOutput);
  79. //[listOutput writeToFile:listFile atomically:TRUE encoding:NSASCIIStringEncoding error:nil];
  80. //find "$BUILD_ROOT/$WORKING_DIR/deb" -type f -not -path "$BUILD_ROOT/$WORKING_DIR/deb/DEBIAN/*" | sed "s|$BUILD_ROOT/$WORKING_DIR/deb||g" >> "$SKEL_PREFIX/var/lib/dpkg/info/$PKG_NAME.list"
  81. //find "$BUILD_ROOT/$WORKING_DIR/deb" -type f -not -path "$BUILD_ROOT/$WORKING_DIR/deb/DEBIAN/*" -exec $MD5 {} \; | awk '{ print $1 " " $2 }' | sed "s|$BUILD_ROOT/$WORKING_DIR/deb/||g" >> "$SKEL_PREFIX/var/lib/dpkg/info/$PKG_NAME.md5sums"
  82. //[self.listfile writeToFile:listFile atomically:TRUE encoding:NSASCIIStringEncoding error:nil];
  83. DLog(@"\nGenerating md5sums...\n");
  84. NSString *runString = [NSString stringWithFormat:@"/usr/bin/find %@ -type f -not -path \"*.DS_Store*\" -exec /sbin/md5 -r {} \\; | /usr/bin/awk '{ print $1 \" \" $2 }' | /usr/bin/sed \"s|%@||g\" >> \"%@\"", tmpPath, tmpPath, md5s];
  85. NSString *outputs = [[HelperClass returnForProcess:runString] componentsJoinedByString:@"\n"];
  86. DLog(@"\nCreating md5sum file '%@'...\n", md5s);
  87. //[outputs writeToFile:md5s atomically:TRUE encoding:NSASCIIStringEncoding error:nil];
  88. [man createDirectoryAtPath:debian withIntermediateDirectories:TRUE attributes:nil error:nil];
  89. DLog(@"\nExtracting DEBIAN files for processing...\n");
  90. [HelperClass returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -e %@ %@", self.path, debian]];
  91. //NSString *nextPath = [tmpPath stringByAppendingPathComponent:@"DEBIAN"];
  92. DLog(@"\nCopying any necessary DEBIAN files to new locations...\n\n");
  93. __block NSString *postInstFile = nil;
  94. NSArray *files = [man contentsOfDirectoryAtPath:debian error:nil];
  95. [files enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  96. NSString *fullPath = [debian stringByAppendingPathComponent:obj];
  97. if (![obj isEqualToString:@"control"]){
  98. if ([obj isEqualToString:@"postinst"]){
  99. postInstFile = fullPath;
  100. }
  101. DLog(@"Copying file... %@\n\n", fullPath);
  102. NSString *fileName = [NSString stringWithFormat:@"%@.%@", self.packageName, obj];
  103. NSString *newPath = [bootstrapPath stringByAppendingPathComponent:@"Library/dpkg/info"];
  104. newPath = [newPath stringByAppendingPathComponent:fileName];
  105. //DLog(@"newPath: %@", newPath);
  106. [man copyItemAtPath:fullPath toPath:newPath error:nil];
  107. } else {
  108. NSMutableString *controlFile = [[NSMutableString alloc] initWithContentsOfFile:fullPath encoding:NSASCIIStringEncoding error:nil];
  109. [controlFile replaceOccurrencesOfString:@"iphoneos-arm" withString:@"appletvos-arm64" options:NSLiteralSearch range:NSMakeRange(0, [controlFile length])];
  110. [controlFile appendString:@"Status: install ok installed"];
  111. //DLog(@"control file: -%@-\n", controlFile);
  112. NSString *statusFile = [bootstrapPath stringByAppendingPathComponent:@"Library/dpkg/status"];
  113. [FM copyItemAtPath:statusFile toPath:[statusFile stringByAppendingPathExtension:@"bak"] error:nil];
  114. NSMutableString *statusContents = [[NSMutableString alloc] initWithContentsOfFile:statusFile encoding:NSASCIIStringEncoding error:nil];
  115. if (model) { //we found the package model, just replace the old string with our new one
  116. DLog(@"Updating status file for new package version...\n\n");
  117. [statusContents replaceOccurrencesOfString:model.rawString withString:controlFile options:NSLiteralSearch range:NSMakeRange(0, [statusContents length])];
  118. //[statusContents writeToFileWithoutAttributes:statusFile];
  119. [statusContents writeToFile:statusFile atomically:TRUE encoding:NSASCIIStringEncoding error:nil];
  120. } else {
  121. DLog(@"Updating status file for new package...\n\n");
  122. //DLog(@"down here??: -%@-\n", controlFile);
  123. [statusContents appendFormat:@"%@\n", controlFile];
  124. //DLog(@"\nnew status file: %@\n", statusContents);
  125. //[statusContents writeToFileWithoutAttributes:statusFile];
  126. [statusContents writeToFile:statusFile atomically:TRUE encoding:NSASCIIStringEncoding error:nil];
  127. }
  128. }
  129. }];
  130. //finally actually install the package onto the bootstrap
  131. DLog(@"Extracting package onto bootstrap folder...\n");
  132. [HelperClass returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -x %@ %@", self.path, bootstrapPath]];
  133. if (postInstFile) {
  134. DLog(@"\n [WARNING] We found a postinst file, will not run this due to potential unexpected consequences in your run environment! Displaying contents so you can determine if any additional steps are necessary. Contents will be delimited by a line -----\n");
  135. DLog(@"\n%@ Contents:\n\n---------------------\n\n%@\n\n---------------------\n\n", postInstFile, [NSString stringWithContentsOfFile:postInstFile encoding:NSASCIIStringEncoding error:nil]);
  136. }
  137. [FM removeItemAtPath:tmpPath error:nil];
  138. DLog(@"Done!\n\n");
  139. return 0;
  140. }
  141. - (void)codesignIfNecessary:(NSString *)file {
  142. if (![[[file pathExtension] lowercaseString] isEqualToString:@"dylib"]){
  143. return;
  144. }
  145. NSString *jtp = [HelperClass singleLineReturnForProcess:@"/usr/bin/which jtool"];
  146. if (jtp){
  147. NSString *proc = [[HelperClass arrayReturnForTask:jtp withArguments:@[@"--sig", file]] componentsJoinedByString:@"\n"];
  148. NSLog(@"proc: %@", proc);
  149. if ([proc containsString:@"No Code Signing blob detected in this file"]){
  150. NSString *runCommand = [NSString stringWithFormat:@"%@ --sign platform %@ --inplace", jtp, file];
  151. NSLog(@"running codesign command: %@", runCommand);
  152. NSString *returnValue = [HelperClass singleLineReturnForProcess:runCommand];
  153. NSLog(@"returnValue: %@", returnValue);
  154. }
  155. }
  156. }
  157. - (void)validateSignaturesInPath:(NSString *)thePath {
  158. [self.files enumerateObjectsUsingBlock:^(InputPackageFile * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  159. NSString *file = [thePath stringByAppendingPathComponent:obj.path];
  160. NSLog(@"check sig file: %@", file);
  161. [self codesignIfNecessary:file];
  162. }];
  163. }
  164. - (void)bumpVersionInCurrentDirectory {
  165. NSString *fakeRoot = [HelperClass singleLineReturnForProcess:@"/usr/bin/which fakeroot"];
  166. NSString *pwd = [HelperClass singleLineReturnForProcess:@"/bin/pwd"];
  167. DLog(@"\nProcessing file: %@\n", self.path);
  168. InputPackage *output = self;
  169. DLog(@"\nFound package: '%@' at version: '%@'...\n", output.packageName, output.version );
  170. NSString *tmpPath = [pwd stringByAppendingPathComponent:output.packageName];
  171. NSString *debian = [tmpPath stringByAppendingPathComponent:@"DEBIAN"];
  172. [FM createDirectoryAtPath:tmpPath withIntermediateDirectories:TRUE attributes:nil error:nil];
  173. DLog(@"\nExtracting package contents for processing...\n");
  174. [HelperClass returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -x %@ %@", self.path, tmpPath]];
  175. [FM createDirectoryAtPath:debian withIntermediateDirectories:TRUE attributes:nil error:nil];
  176. DLog(@"\nExtracting DEBIAN files for processing...\n");
  177. [HelperClass returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -e %@ %@", self.path, debian]];
  178. NSString *controlPath = [debian stringByAppendingPathComponent:@"control"];
  179. NSMutableString *controlFile = [[NSMutableString alloc] initWithContentsOfFile:controlPath encoding:NSASCIIStringEncoding error:nil];
  180. //@"appletvos-arm64"
  181. [controlFile replaceOccurrencesOfString:self.version withString:[self.version nextVersionNumber] options:NSLiteralSearch range:NSMakeRange(0, [controlFile length])];
  182. [controlFile writeToFile:controlPath atomically:TRUE];
  183. //at this point we have the files extracted, time to determine what needs to be changed
  184. NSArray *ignoreFiles = @[@".fauxsu", @".DS_Store"];
  185. NSArray *forbiddenRoots = @[@"etc", @"var", @"tmp"];
  186. [self validateSignaturesInPath:tmpPath];
  187. //__block NSMutableArray *_overwriteArray = [NSMutableArray new];
  188. [self.files enumerateObjectsUsingBlock:^(InputPackageFile * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  189. if (obj.type == BSPackageFileTypeFile || obj.type == BSPackageFileTypeDirectory){
  190. //DLog(@"processing path: %@", obj.path);
  191. if ([obj.path isEqualToString:@"/private/var/mobile/Applications/"]){
  192. NSString *badPath = [tmpPath stringByAppendingPathComponent:obj.path];
  193. NSString *newPath = [tmpPath stringByAppendingPathComponent:@"Applications"];
  194. DLog(@"\n [INFO] Moving %@ to %@...", badPath, newPath);
  195. [FM moveItemAtPath:badPath toPath:newPath error:nil];
  196. [FM removeItemAtPath:[tmpPath stringByAppendingPathComponent:@"private"] error:nil];
  197. *stop = TRUE;
  198. }
  199. NSString *fullPath = [tmpPath stringByAppendingPathComponent:obj.path];
  200. if ([ignoreFiles containsObject:obj.path.lastPathComponent]){
  201. DLog(@"in ignore file list, purge");
  202. [FM removeItemAtPath:fullPath error:nil];
  203. }
  204. NSArray *pathComponents = [obj.path pathComponents];
  205. if ([pathComponents count] > 1)
  206. {
  207. NSString *rootPath = [pathComponents objectAtIndex:1];
  208. //DLog(@"\n Checking root path: %@ for file %@\n", rootPath, obj.path);
  209. if ([forbiddenRoots containsObject:rootPath])
  210. {
  211. DLog(@"\n [WARNING] package file: '%@' would overwrite symbolic link at '%@'\n", obj.path, rootPath);
  212. NSString *privateDir = [tmpPath stringByAppendingPathComponent:@"private"];
  213. if (![FM fileExistsAtPath:privateDir]){
  214. [FM createDirectoryAtPath:privateDir withIntermediateDirectories:TRUE attributes:nil error:nil];
  215. }
  216. //take <package_name>/[rootPath] (could be etc, var, tmp) and move to <package_name>/private/[rootPath]
  217. NSString *badPath = [tmpPath stringByAppendingPathComponent:rootPath];
  218. NSString *newPath = [privateDir stringByAppendingPathComponent:rootPath];
  219. DLog(@"\n [INFO] Moving %@ to %@...", badPath, newPath);
  220. [FM moveItemAtPath:badPath toPath:newPath error:nil];
  221. }
  222. }
  223. }
  224. }];
  225. NSString *depArchiveInfo = [NSString stringWithFormat:@"/usr/local/bin/dpkg -b %@", self.packageName];
  226. if (fakeRoot) {
  227. depArchiveInfo = [NSString stringWithFormat:@"%@ /usr/local/bin/dpkg -b %@", fakeRoot, self.packageName];
  228. }
  229. [[HelperClass returnForProcess:depArchiveInfo] componentsJoinedByString:@"\n"];
  230. DLog(@"\nDone!\n\n");
  231. //return er;
  232. }
  233. - (void)repackageInCurrentDirectoryWithArch:(NSString *)newArch {
  234. NSString *fakeRoot = [HelperClass singleLineReturnForProcess:@"/usr/bin/which fakeroot"];
  235. NSString *pwd = [HelperClass singleLineReturnForProcess:@"/bin/pwd"];
  236. DLog(@"\nProcessing file: %@\n", self.path);
  237. InputPackage *output = self;
  238. DLog(@"\nFound package: '%@' at version: '%@'...\n", output.packageName, output.version );
  239. NSString *tmpPath = [pwd stringByAppendingPathComponent:output.packageName];
  240. NSString *debian = [tmpPath stringByAppendingPathComponent:@"DEBIAN"];
  241. [FM createDirectoryAtPath:tmpPath withIntermediateDirectories:TRUE attributes:nil error:nil];
  242. DLog(@"\nExtracting package contents for processing...\n");
  243. [HelperClass returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -x %@ %@", self.path, tmpPath]];
  244. [FM createDirectoryAtPath:debian withIntermediateDirectories:TRUE attributes:nil error:nil];
  245. DLog(@"\nExtracting DEBIAN files for processing...\n");
  246. [HelperClass returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -e %@ %@", self.path, debian]];
  247. if (newArch != nil) {
  248. NSString *controlPath = [debian stringByAppendingPathComponent:@"control"];
  249. NSMutableString *controlFile = [[NSMutableString alloc] initWithContentsOfFile:controlPath encoding:NSASCIIStringEncoding error:nil];
  250. //@"appletvos-arm64"
  251. [controlFile replaceOccurrencesOfString:@"iphoneos-arm" withString:newArch options:NSLiteralSearch range:NSMakeRange(0, [controlFile length])];
  252. [controlFile writeToFile:controlPath atomically:TRUE];
  253. }
  254. //at this point we have the files extracted, time to determine what needs to be changed
  255. NSArray *ignoreFiles = @[@".fauxsu", @".DS_Store"];
  256. NSArray *forbiddenRoots = @[@"etc", @"var", @"tmp"];
  257. //__block NSMutableArray *_overwriteArray = [NSMutableArray new];
  258. [self.files enumerateObjectsUsingBlock:^(InputPackageFile * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  259. if (obj.type == BSPackageFileTypeFile || obj.type == BSPackageFileTypeDirectory){
  260. //DLog(@"processing path: %@", obj.path);
  261. if ([obj.path isEqualToString:@"/private/var/mobile/Applications/"]){
  262. NSString *badPath = [tmpPath stringByAppendingPathComponent:obj.path];
  263. NSString *newPath = [tmpPath stringByAppendingPathComponent:@"Applications"];
  264. DLog(@"\n [INFO] Moving %@ to %@...", badPath, newPath);
  265. [FM moveItemAtPath:badPath toPath:newPath error:nil];
  266. [FM removeItemAtPath:[tmpPath stringByAppendingPathComponent:@"private"] error:nil];
  267. *stop = TRUE;
  268. }
  269. NSString *fullPath = [tmpPath stringByAppendingPathComponent:obj.path];
  270. if ([ignoreFiles containsObject:obj.path.lastPathComponent]){
  271. DLog(@"in ignore file list, purge");
  272. [FM removeItemAtPath:fullPath error:nil];
  273. }
  274. NSArray *pathComponents = [obj.path pathComponents];
  275. if ([pathComponents count] > 1)
  276. {
  277. NSString *rootPath = [pathComponents objectAtIndex:1];
  278. //DLog(@"\n Checking root path: %@ for file %@\n", rootPath, obj.path);
  279. if ([forbiddenRoots containsObject:rootPath])
  280. {
  281. DLog(@"\n [WARNING] package file: '%@' would overwrite symbolic link at '%@'\n", obj.path, rootPath);
  282. NSString *privateDir = [tmpPath stringByAppendingPathComponent:@"private"];
  283. if (![FM fileExistsAtPath:privateDir]){
  284. [FM createDirectoryAtPath:privateDir withIntermediateDirectories:TRUE attributes:nil error:nil];
  285. }
  286. //take <package_name>/[rootPath] (could be etc, var, tmp) and move to <package_name>/private/[rootPath]
  287. NSString *badPath = [tmpPath stringByAppendingPathComponent:rootPath];
  288. NSString *newPath = [privateDir stringByAppendingPathComponent:rootPath];
  289. DLog(@"\n [INFO] Moving %@ to %@...", badPath, newPath);
  290. [FM moveItemAtPath:badPath toPath:newPath error:nil];
  291. }
  292. }
  293. }
  294. }];
  295. NSString *depArchiveInfo = [NSString stringWithFormat:@"/usr/local/bin/dpkg -b %@", self.packageName];
  296. if (fakeRoot) {
  297. depArchiveInfo = [NSString stringWithFormat:@"%@ /usr/local/bin/dpkg -b %@", fakeRoot, self.packageName];
  298. }
  299. [[HelperClass returnForProcess:depArchiveInfo] componentsJoinedByString:@"\n"];
  300. DLog(@"\nDone!\n\n");
  301. //return er;
  302. }
  303. - (ErrorReturn *)errorReturnForBootstrap:(NSString *)bootstrapPath
  304. {
  305. NSArray *ignoreFiles = @[@".fauxsu", @".DS_Store"];
  306. NSArray *forbiddenRoots = @[@"etc", @"var", @"tmp"];
  307. NSFileManager *man = [NSFileManager defaultManager];
  308. __block NSInteger returnValue = 0; //0 = good to go 1 = over write warning, 2 = no go
  309. __block NSMutableArray *_overwriteArray = [NSMutableArray new];
  310. [self.files enumerateObjectsUsingBlock:^(InputPackageFile * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  311. if ([obj.fileType isEqualToString:@"file"]){
  312. NSString *fullPath = [bootstrapPath stringByAppendingPathComponent:obj.path];
  313. if ([man fileExistsAtPath:fullPath] && ![ignoreFiles containsObject:obj.basename]){
  314. //DLog(@"[WARNING] overwriting a file that already exists and isn't DS_Store or .fauxsu: %@", fullPath);
  315. [_overwriteArray addObject:obj.path];
  316. //*stop = TRUE;//return FALSE;
  317. returnValue = 1;
  318. }
  319. NSArray *pathComponents = [obj.path pathComponents];
  320. if ([pathComponents count] > 1)
  321. {
  322. NSString *rootPath = [pathComponents objectAtIndex:1];
  323. if ([forbiddenRoots containsObject:rootPath])
  324. {
  325. DLog(@"\n [ERROR] package file: '%@' would overwrite symbolic link at '%@'! Exiting!\n\n", obj.path, rootPath);
  326. *stop = TRUE;
  327. returnValue = 2;
  328. }
  329. }
  330. }
  331. }];
  332. ErrorReturn *er = [ErrorReturn new];
  333. er.returnStatus = returnValue;
  334. er.overwriteFiles = _overwriteArray;
  335. return er;
  336. }
  337. @end