|
@@ -19,15 +19,7 @@
|
|
|
#import "HelperClass.h"
|
|
|
|
|
|
|
|
|
-/*
|
|
|
-
|
|
|
- fileType, @"fileType",octalPermissions, @"octalPermissions", octalUG, @"octalUG", size, @"size", date, @"date", time, @"time", linkDest, @"linkDest", fullPath, @"fullPath", nil];
|
|
|
-
|
|
|
- */
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-#define OPTION_FLAGS "o:i:b:l:d:hcr"
|
|
|
+#define OPTION_FLAGS "o:i:ld:hcr"
|
|
|
|
|
|
|
|
|
char *progname;
|
|
@@ -36,26 +28,24 @@ char *path;
|
|
|
static struct option longopts[] = {
|
|
|
{ "octal", required_argument, NULL, 'o' },
|
|
|
{ "input", required_argument, NULL, 'i' },
|
|
|
- { "bootstrap", required_argument, NULL, 'b' },
|
|
|
- { "list", required_argument, NULL, 'l' },
|
|
|
+ { "list", no_argument, NULL, 'l' },
|
|
|
{ "delete", required_argument, NULL, 'd' },
|
|
|
{ "help", no_argument, NULL, 'h' },
|
|
|
{ "clean", no_argument, NULL, 'c' },
|
|
|
- { "repackage", no_argument, NULL, 'r' },
|
|
|
+ { "repackage", no_argument, NULL, 'r' },
|
|
|
{ NULL, 0, NULL, 0 }
|
|
|
};
|
|
|
|
|
|
void cmd_help(){
|
|
|
- printf("Usage: bootstrapTool [OPTIONS] FILE\n");
|
|
|
+ printf("Usage: bootstrapTool [OPTIONS] BOOTSTRAP_FOLDER\n");
|
|
|
printf("Makes various modifications to a raw bootstrap folder\n\n");
|
|
|
|
|
|
printf(" -h, --help\t\t\tprints usage information\n");
|
|
|
- printf(" -i, --inoput\t\t\tthe deb package to install\n");
|
|
|
- printf(" -b, --bootstrap\t\tthe bootstrap folder\n");
|
|
|
+ printf(" -i, --input\t\t\tthe deb package to process\n");
|
|
|
printf(" -d, --delete\t\t\tthe package to delete\n");
|
|
|
printf(" -l, --list\t\t\tlist all the packages installed on this bootstrap\n");
|
|
|
printf(" -c, --clean\t\t\tclean a bad status file from duplicate entries\n");
|
|
|
- printf(" -r, --repackage\t\t\trepackage to fix bad locations and to change architecture\n");
|
|
|
+ printf(" -r, --repackage\t\trepackage to fix bad locations and to change architecture\n");
|
|
|
printf("\n");
|
|
|
}
|
|
|
|
|
@@ -64,15 +54,14 @@ int main(int argc, const char * argv[]) {
|
|
|
|
|
|
setuid(0);
|
|
|
setgid(0);
|
|
|
- // insert code here...
|
|
|
progname = basename(argv[0]);
|
|
|
path = dirname(argv[0]);
|
|
|
int flag;
|
|
|
NSString *octalFile = nil;
|
|
|
NSString *debFile = nil;
|
|
|
NSString *bootstrapPath = nil;
|
|
|
- NSString *bootstrapListPath = nil;
|
|
|
NSString *deletePackage = nil;
|
|
|
+ BOOL listPackage = FALSE;
|
|
|
BOOL repackage = FALSE;
|
|
|
BOOL clean = FALSE;
|
|
|
while ((flag = getopt_long(argc, argv, OPTION_FLAGS, longopts, NULL)) != -1) {
|
|
@@ -86,14 +75,9 @@ int main(int argc, const char * argv[]) {
|
|
|
debFile = [NSString stringWithUTF8String:optarg];
|
|
|
break;
|
|
|
|
|
|
- case 'b':
|
|
|
-
|
|
|
- bootstrapPath = [NSString stringWithUTF8String:optarg];
|
|
|
- break;
|
|
|
-
|
|
|
case 'l':
|
|
|
|
|
|
- bootstrapListPath = [NSString stringWithUTF8String:optarg];
|
|
|
+ listPackage = TRUE;
|
|
|
break;
|
|
|
|
|
|
case 'd':
|
|
@@ -118,6 +102,15 @@ int main(int argc, const char * argv[]) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (argc-optind == 1) {
|
|
|
+ argc -= optind;
|
|
|
+ argv += optind;
|
|
|
+
|
|
|
+ bootstrapPath = [NSString stringWithUTF8String:argv[0]];
|
|
|
+ NSLog(@"bootstrap path: %@?", bootstrapPath);
|
|
|
+ //return 0;
|
|
|
+ }
|
|
|
+
|
|
|
if (repackage == TRUE && debFile) {
|
|
|
|
|
|
DLog(@"\n [INFO] Repackaging file: %@...\n", debFile);
|
|
@@ -193,11 +186,16 @@ int main(int argc, const char * argv[]) {
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
+ } else if (clean) {
|
|
|
+
|
|
|
+ DLog(@"\nYou need to choose a bootstrap path to clean!\n\n");
|
|
|
+ return 1;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
if (deletePackage && bootstrapPath) {
|
|
|
|
|
|
- __block NSString *postInstFile = nil;
|
|
|
+ __block NSString *postRmFile = nil;
|
|
|
|
|
|
NSString *statusFile = [bootstrapPath stringByAppendingPathComponent:@"Library/dpkg/status"];
|
|
|
NSArray <StatusPackageModel*> *installedPackages = [HelperClass statusInstalledPackagesFromFile:statusFile];
|
|
@@ -240,8 +238,8 @@ int main(int argc, const char * argv[]) {
|
|
|
NSString *fullPath = [infoPath stringByAppendingPathComponent:obj];
|
|
|
if([FM fileExistsAtPath:fullPath]){
|
|
|
|
|
|
- if ([[obj pathExtension] isEqualToString:@"postinst"]){
|
|
|
- postInstFile = fullPath;
|
|
|
+ if ([[obj pathExtension] isEqualToString:@"postrm"]){
|
|
|
+ postRmFile = fullPath;
|
|
|
}
|
|
|
[filesToProcess addObject:fullPath];
|
|
|
|
|
@@ -303,11 +301,11 @@ int main(int argc, const char * argv[]) {
|
|
|
[newStatusFile writeToFile:statusFile atomically:TRUE];
|
|
|
|
|
|
|
|
|
- if (postInstFile) {
|
|
|
+ if (postRmFile) {
|
|
|
|
|
|
- DLog(@"\n [WARNING] We found a postinst file, will not run this due to potential unexpected consequences off of the target device, displaying contents so you can determine if any additional steps are necessary\n");
|
|
|
+ DLog(@"\n [WARNING] We found a postrm file, will not run this due to potential unexpected consequences off of the target device, displaying contents so you can determine if any additional steps are necessary\n");
|
|
|
|
|
|
- DLog(@"\n\n%@ contents:\n%@\n\n", postInstFile, [NSString stringWithContentsOfFile:postInstFile encoding:NSUTF8StringEncoding error:nil]);
|
|
|
+ DLog(@"\n\n%@ contents:\n%@\n\n", postRmFile, [NSString stringWithContentsOfFile:postRmFile encoding:NSUTF8StringEncoding error:nil]);
|
|
|
|
|
|
|
|
|
|
|
@@ -317,6 +315,11 @@ int main(int argc, const char * argv[]) {
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
+ } else if (deletePackage) {
|
|
|
+
|
|
|
+ DLog(@"\nYou need to choose a bootstrap path to delete from!\n\n");
|
|
|
+ return 1;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
if (octalFile) {
|
|
@@ -326,208 +329,30 @@ int main(int argc, const char * argv[]) {
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- if (bootstrapListPath) {
|
|
|
+ if (listPackage && bootstrapPath) {
|
|
|
|
|
|
- NSString *statusFile = [bootstrapListPath stringByAppendingPathComponent:@"Library/dpkg/status"];
|
|
|
+ NSString *statusFile = [bootstrapPath stringByAppendingPathComponent:@"Library/dpkg/status"];
|
|
|
NSArray *installedPackages = [HelperClass statusInstalledPackagesFromFile:statusFile];
|
|
|
DLog(@"%@", installedPackages);
|
|
|
return 0;
|
|
|
|
|
|
+ } else if (listPackage) {
|
|
|
+
|
|
|
+ DLog(@"\nYou need to choose a bootstrap path to list packages from!\n\n");
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
|
|
|
if (debFile && bootstrapPath) {
|
|
|
|
|
|
- NSString *statusFile = [bootstrapPath stringByAppendingPathComponent:@"Library/dpkg/status"];
|
|
|
- NSArray *installedPackages = [HelperClass statusInstalledPackagesFromFile:statusFile];
|
|
|
-
|
|
|
- //DLog(@"installedPackages: %@", installedPackages);
|
|
|
-
|
|
|
+
|
|
|
DLog(@"\nProcessing file: %@\n", debFile);
|
|
|
InputPackage *output = [HelperClass packageForDeb:debFile];
|
|
|
-
|
|
|
- DLog(@"\nFound package: '%@' at version: '%@'...\n", output.packageName, output.version );
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- StatusPackageModel *model = [[installedPackages filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"package == %@", output.packageName]] lastObject];
|
|
|
-
|
|
|
- if (model) {
|
|
|
-
|
|
|
- DLog(@"\n [WARNING] This package has already been installed! %@", model);
|
|
|
- NSComparisonResult result = [output.version compare:model.version options:NSNumericSearch];
|
|
|
- DLog(@"\n [WARNING] Comparing version numbers...");
|
|
|
- switch (result) {
|
|
|
- case NSOrderedSame:
|
|
|
- DLog(@"\n [WARNING] %@ and %@ match!", output.version, model.version);
|
|
|
- break;
|
|
|
-
|
|
|
- case NSOrderedAscending:
|
|
|
- DLog(@"\n [WARNING] Package version %@ is less than installed version %@!", output.version, model.version);
|
|
|
- break;
|
|
|
-
|
|
|
- case NSOrderedDescending:
|
|
|
- DLog(@"\n [WARNING] Package version %@ is greater than installed version %@!", output.version, model.version);
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- ErrorReturn *safePackage = [output errorReturnForBootstrap:bootstrapPath];
|
|
|
-
|
|
|
- if (safePackage.returnStatus != 0) { //zero is success
|
|
|
-
|
|
|
- if (safePackage.returnStatus == 1) //ovewrwrites, just warnings!
|
|
|
- {
|
|
|
-
|
|
|
- NSString *error = [NSString stringWithFormat:@" [WARNING] %@ will overwrite the following files: \n\n\t%@\n\n", debFile.lastPathComponent, [safePackage.overwriteFiles componentsJoinedByString:@"\n\t"]];
|
|
|
-
|
|
|
- if(![HelperClass shouldContinueWithError:error]){
|
|
|
-
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- } else if (safePackage.returnStatus == 2) //bail!!"
|
|
|
- {
|
|
|
- return 2;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //NSString *runPath = [NSString stringWithUTF8String:path];
|
|
|
- NSString *pwd = [[HelperClass returnForProcess:@"/bin/pwd"] componentsJoinedByString:@"\n"];
|
|
|
- //DLog(@"run path: %@", runPath);
|
|
|
- //DLog(@"pwd: %@", pwd);
|
|
|
- //DLog(@"%@", output);
|
|
|
- //DLog(@"list: %@", output.listfile);
|
|
|
- NSFileManager *man = [NSFileManager defaultManager];
|
|
|
- NSString *tmpPath = [pwd stringByAppendingPathComponent:output.packageName];
|
|
|
- NSString *debian = [tmpPath stringByAppendingPathComponent:@"DEBIAN"];
|
|
|
- [man createDirectoryAtPath:tmpPath withIntermediateDirectories:TRUE attributes:nil error:nil];
|
|
|
- DLog(@"\nExtracting deb for processing...\n");
|
|
|
- [HelperClass returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -x %@ %@", debFile, tmpPath]];
|
|
|
-
|
|
|
- NSString *bootstrapInfoPath = [bootstrapPath stringByAppendingPathComponent:@"Library/dpkg/info"];
|
|
|
-
|
|
|
- NSString *listFile = [bootstrapInfoPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.list", output.packageName]];
|
|
|
- NSString *md5s = [bootstrapInfoPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.md5sums", output.packageName]];
|
|
|
-
|
|
|
- DLog(@"\nCreating list file '%@'...\n", listFile);
|
|
|
-
|
|
|
- [output.listfile writeToFile:listFile atomically:TRUE encoding:NSUTF8StringEncoding error:nil];
|
|
|
-
|
|
|
- DLog(@"\nGenerating md5sums...\n");
|
|
|
- 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];
|
|
|
- NSString *outputs = [[HelperClass returnForProcess:runString] componentsJoinedByString:@"\n"];
|
|
|
-
|
|
|
- DLog(@"\nCreating md5sum file '%@'...\n", md5s);
|
|
|
-
|
|
|
- [outputs writeToFile:md5s atomically:TRUE encoding:NSUTF8StringEncoding error:nil];
|
|
|
-
|
|
|
- [man createDirectoryAtPath:debian withIntermediateDirectories:TRUE attributes:nil error:nil];
|
|
|
-
|
|
|
- DLog(@"\nExtracting DEBIAN files for processing...\n");
|
|
|
-
|
|
|
- [HelperClass returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -e %@ %@", debFile, debian]];
|
|
|
- //NSString *nextPath = [tmpPath stringByAppendingPathComponent:@"DEBIAN"];
|
|
|
-
|
|
|
- DLog(@"\nCopying any necessary DEBIAN files to new locations...\n\n");
|
|
|
-
|
|
|
- NSArray *files = [man contentsOfDirectoryAtPath:debian error:nil];
|
|
|
- [files enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
|
|
-
|
|
|
- NSString *fullPath = [debian stringByAppendingPathComponent:obj];
|
|
|
- if (![obj isEqualToString:@"control"]){
|
|
|
-
|
|
|
- DLog(@"Copying file... %@\n\n", fullPath);
|
|
|
- NSString *fileName = [NSString stringWithFormat:@"%@.%@", output.packageName, obj];
|
|
|
- NSString *newPath = [bootstrapPath stringByAppendingPathComponent:@"Library/dpkg/info"];
|
|
|
- newPath = [newPath stringByAppendingPathComponent:fileName];
|
|
|
- //DLog(@"newPath: %@", newPath);
|
|
|
- [man copyItemAtPath:fullPath toPath:newPath error:nil];
|
|
|
- } else {
|
|
|
-
|
|
|
- NSMutableString *controlFile = [[NSMutableString alloc] initWithContentsOfFile:fullPath encoding:NSUTF8StringEncoding error:nil];
|
|
|
-
|
|
|
-
|
|
|
- [controlFile replaceOccurrencesOfString:@"iphoneos-arm" withString:@"appletvos-arm64" options:NSLiteralSearch range:NSMakeRange(0, [controlFile length])];
|
|
|
-
|
|
|
- [controlFile appendString:@"Status: install ok installed"];
|
|
|
-
|
|
|
- //DLog(@"control file: -%@-\n", controlFile);
|
|
|
-
|
|
|
- NSString *statusFile = [bootstrapPath stringByAppendingPathComponent:@"Library/dpkg/status"];
|
|
|
-
|
|
|
- [FM copyItemAtPath:statusFile toPath:[statusFile stringByAppendingPathExtension:@"bak"] error:nil];
|
|
|
-
|
|
|
- NSMutableString *statusContents = [[NSMutableString alloc] initWithContentsOfFile:statusFile encoding:NSUTF8StringEncoding error:nil];
|
|
|
-
|
|
|
- if (model) { //we found the package model, just replace the old string with our new one
|
|
|
-
|
|
|
-
|
|
|
- DLog(@"Updating status file for new package version...\n\n");
|
|
|
-
|
|
|
- [statusContents replaceOccurrencesOfString:model.rawString withString:controlFile options:NSLiteralSearch range:NSMakeRange(0, [statusContents length])];
|
|
|
-
|
|
|
- //[statusContents writeToFileWithoutAttributes:statusFile];
|
|
|
- [statusContents writeToFile:statusFile atomically:TRUE encoding:NSUTF8StringEncoding error:nil];
|
|
|
-
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- DLog(@"Updating status file for new package...\n\n");
|
|
|
-
|
|
|
- //DLog(@"down here??: -%@-\n", controlFile);
|
|
|
-
|
|
|
- [statusContents appendFormat:@"%@\n", controlFile];
|
|
|
-
|
|
|
- //DLog(@"\nnew status file: %@\n", statusContents);
|
|
|
-
|
|
|
- //[statusContents writeToFileWithoutAttributes:statusFile];
|
|
|
-
|
|
|
- [statusContents writeToFile:statusFile atomically:TRUE encoding:NSUTF8StringEncoding error:nil];
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- //DLog(@"\n\nwe down here??\n\n");
|
|
|
-
|
|
|
- //NSString *newString = [[HelperClass returnForProcess:[NSString stringWithFormat:@"/bin/cat %@", statusFile]] componentsJoinedByString:@"\n"];
|
|
|
-
|
|
|
- //DLog(@"%@", newString);
|
|
|
-
|
|
|
- //DLog(@"status contents: %@", statusContents);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- // [statusContents writeToFile:statusFile atomically:TRUE encoding:NSUTF8StringEncoding error:nil];
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- }];
|
|
|
-
|
|
|
- //finally actually install the package onto the bootstrap
|
|
|
-
|
|
|
- DLog(@"Extracting package onto bootstrap folder...\n\n");
|
|
|
-
|
|
|
- [HelperClass returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -x %@ %@", debFile, bootstrapPath]];
|
|
|
- //DLog(@"outputs: %@", outputs);
|
|
|
-
|
|
|
- ///usr/bin/find "$TARGET_DIR" -type f -not -path "$TARGET_DIR/DEBIAN/*" -exec "/sbin/md5 -r" {} \; | /usr/bin/awk '{ print $1 " " $2 }' | /usr/bin/sed "s|$TARGET_DIR/||g"
|
|
|
-
|
|
|
- DLog(@"Done!\n\n");
|
|
|
- return 0;
|
|
|
+ return [output installToBootstrapPath:bootstrapPath];
|
|
|
+
|
|
|
+ } else if (debFile) {
|
|
|
+ DLog(@"\nYou need to choose a bootstrap path to install the package to!\n\n");
|
|
|
+ return 1;
|
|
|
}
|
|
|
//if we got this far.. nothing happened, print help.
|
|
|
cmd_help();
|