|
@@ -16,7 +16,7 @@
|
|
|
#import <sys/utsname.h>
|
|
|
#import "HelperClass.h"
|
|
|
|
|
|
-#define OPTION_FLAGS "o:i:ld:hcrbp:su:y"
|
|
|
+#define OPTION_FLAGS "o:i:ld:hcrbp:su:yn:"
|
|
|
|
|
|
char *progname;
|
|
|
char *path;
|
|
@@ -34,6 +34,7 @@ static struct option longopts[] = {
|
|
|
{ "skip", no_argument, NULL, 's' },
|
|
|
{ "unique", required_argument, NULL, 'u' },
|
|
|
{ "yes", no_argument, NULL, 'y' },
|
|
|
+ { "new", required_argument, NULL, 'n' },
|
|
|
{ NULL, 0, NULL, 0 }
|
|
|
};
|
|
|
|
|
@@ -42,6 +43,7 @@ void cmd_help(void){
|
|
|
printf("Makes various modifications to a raw bootstrap folder\n\n");
|
|
|
|
|
|
printf(" -h, --help\t\t\tprints usage information\n");
|
|
|
+ printf(" -n, --new\t\t\tcreates a brand new bootstrap with debs specified by this 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");
|
|
@@ -68,12 +70,14 @@ int main(int argc, char **argv) {
|
|
|
NSString *bootstrapPath = nil;
|
|
|
NSString *deletePackage = nil;
|
|
|
NSString *prefix = nil;
|
|
|
+ NSString *packagesFolder = nil;
|
|
|
BOOL listPackage = FALSE;
|
|
|
BOOL repackage = FALSE;
|
|
|
BOOL skip = FALSE;
|
|
|
BOOL bump = FALSE;
|
|
|
BOOL clean = FALSE;
|
|
|
BOOL forceYes = FALSE;
|
|
|
+ BOOL new = FALSE;
|
|
|
/*
|
|
|
NSString *searchPathString = @"/Users/bradleyk/.rbenv/shims:/Users/bradleyk/Library/Python/3.9/bin:/Users/bradleyk/Library/Python/3.8/bin:/usr/local/lib/ruby/gems/3.0.0/bin:/usr/local/lib/ruby/gems/bin:/usr/local/opt/ruby/bin:/opt/local/bin:/opt/local/sbin:/Users/bradleyk/local/bin:/usr/local/mysql/bin:/opt/local/bin:/opt/local/sbin:/usr/bin:/Users/bradleyk/Projects/goprojects/bin:/Users/bradleyk/Projects/theos/bin:/usr/local/bin/:/usr/local/bin:/bin/:/sbin/:/usr/sbin/";
|
|
|
NSString *target = @"dpkg-deb";
|
|
@@ -126,6 +130,10 @@ int main(int argc, char **argv) {
|
|
|
case 'u':
|
|
|
up = [NSString stringWithUTF8String:optarg];
|
|
|
break;
|
|
|
+ case 'n':
|
|
|
+ new = TRUE;
|
|
|
+ packagesFolder = [NSString stringWithUTF8String:optarg];
|
|
|
+ break;
|
|
|
|
|
|
default:
|
|
|
cmd_help();
|
|
@@ -152,143 +160,22 @@ int main(int argc, char **argv) {
|
|
|
}
|
|
|
|
|
|
if (bump == TRUE && debFile) {
|
|
|
- DLog(@"\n [INFO] Bumping version number for file: %@...\n", debFile);
|
|
|
- InputPackage *output = [HelperClass packageForDeb:debFile];
|
|
|
- output.appendedPrefix = prefix;
|
|
|
- output.skipSignatureChecks = skip;
|
|
|
- [output bumpVersionInCurrentDirectory];
|
|
|
- return 0;
|
|
|
+ return [HelperClass bumpPackageAtPath:debFile withPrefix:prefix sigChecks:skip];
|
|
|
}
|
|
|
|
|
|
if (repackage == TRUE && debFile) {
|
|
|
- DLog(@"\n [INFO] Repackaging file: %@...\n", debFile);
|
|
|
- InputPackage *output = [HelperClass packageForDeb:debFile];
|
|
|
- output.appendedPrefix = prefix;
|
|
|
- output.skipSignatureChecks = skip;
|
|
|
- [output repackageInCurrentDirectoryWithArch:@"appletvos-arm64"];
|
|
|
- return 0;
|
|
|
+ return [HelperClass repackagePackageAtPath:debFile withPrefix:prefix sigChecks:skip];
|
|
|
}
|
|
|
|
|
|
//DLog(@"folder: %@ project: %@", folder, project);
|
|
|
if (clean && bootstrapPath) {
|
|
|
- NSString *statusFile = [bootstrapPath relativeStatusFilePath];
|
|
|
- NSString *listContents = [NSString stringWithContentsOfFile:statusFile encoding:NSUTF8StringEncoding error:nil];
|
|
|
- //clean up any errant spaces
|
|
|
- listContents = [listContents stringByReplacingOccurrencesOfString:@"\n\n\n" withString:@"\n\n"];
|
|
|
- listContents = [listContents stringByReplacingOccurrencesOfString:@"\n\n\n\n" withString:@"\n\n"];
|
|
|
-#pragma clang diagnostic push
|
|
|
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
|
- [listContents writeToFile:statusFile atomically:TRUE];
|
|
|
-#pragma clang diagnostic pop
|
|
|
- DLog(@"\n [INFO] Cleaning status file: %@", statusFile);
|
|
|
-
|
|
|
- NSString *testStatusFile = [bootstrapPath relativeStatusFilePath];
|
|
|
- NSArray <StatusPackageModel*> *installedPackages = [HelperClass statusInstalledPackagesFromFile:statusFile];
|
|
|
- __block NSMutableString *newStatusFile = [NSMutableString new];
|
|
|
- __block NSMutableArray *alreadyAdded = [NSMutableArray new];
|
|
|
-
|
|
|
- [installedPackages enumerateObjectsUsingBlock:^(StatusPackageModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
|
|
- DLog(@"\n [INFO] Processing package: %@", obj.package);
|
|
|
- if (![alreadyAdded containsObject:obj.package]){
|
|
|
- //duplicate check first
|
|
|
- NSArray *doubleCheck = [installedPackages filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"package == %@", obj.package]];
|
|
|
- if (doubleCheck.count > 1){
|
|
|
- NSSortDescriptor *sortDesc = [NSSortDescriptor sortDescriptorWithKey:@"version" ascending:FALSE];
|
|
|
- StatusPackageModel *latestVersion = [[doubleCheck sortedArrayUsingDescriptors:@[sortDesc]] firstObject];
|
|
|
- DLog(@"\n [INFO] We found a duplicate package, choosing latestVersion: %@", latestVersion);
|
|
|
- [newStatusFile appendFormat:@"%@\n\n", latestVersion.rawString];
|
|
|
- [alreadyAdded addObject:obj.package];
|
|
|
- } else {
|
|
|
- [newStatusFile appendFormat:@"%@\n\n", obj.rawString];
|
|
|
- }
|
|
|
- } else {
|
|
|
- DLog(@"\n [INFO] We already had this package, skipping older duplicate: %@\n", obj.package);
|
|
|
- }
|
|
|
- }];
|
|
|
- testStatusFile = [testStatusFile stringByReplacingOccurrencesOfString:@"\n\n\n" withString:@"\n\n"];
|
|
|
- DLog(@"\n Writing new output file: %@\n", testStatusFile);
|
|
|
-#pragma clang diagnostic push
|
|
|
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
|
- [newStatusFile writeToFile:testStatusFile atomically:TRUE];
|
|
|
-#pragma clang diagnostic pop
|
|
|
- DLog(@"\n Done!\n\n");
|
|
|
- return 0;
|
|
|
-
|
|
|
+ return [HelperClass cleanBootstrapAtPath:bootstrapPath];
|
|
|
} else if (clean) {
|
|
|
DLog(@"\nYou need to choose a bootstrap path to clean!\n\n");
|
|
|
return 1;
|
|
|
}
|
|
|
if (deletePackage && bootstrapPath) {
|
|
|
- __block NSString *postRmFile = nil;
|
|
|
- NSString *statusFile = [bootstrapPath relativeStatusFilePath];
|
|
|
- NSArray <StatusPackageModel*> *installedPackages = [HelperClass statusInstalledPackagesFromFile:statusFile];
|
|
|
- StatusPackageModel *model = [[installedPackages filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"package == %@", deletePackage]] lastObject];
|
|
|
- if (model) {
|
|
|
- NSString *listName = [NSString stringWithFormat:@"%@.list", deletePackage];
|
|
|
- NSString *infoPath = [bootstrapPath relativeInfoFolderPath];
|
|
|
- NSString *listFile = [infoPath stringByAppendingPathComponent:listName];
|
|
|
- NSArray *listFiles = [FM contentsOfDirectoryAtPath:infoPath error:nil];
|
|
|
- NSPredicate *blockPred = [NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
|
|
|
- if ([evaluatedObject containsString:deletePackage]){
|
|
|
- return TRUE;
|
|
|
- }
|
|
|
- return FALSE;
|
|
|
- }];
|
|
|
- NSArray *relatedFiles = [listFiles filteredArrayUsingPredicate:blockPred]; //any files in dpkg/info/deletePackage.*
|
|
|
- DLog(@"\nWe have found the package, determining list details from: %@", listFile);
|
|
|
- NSString *listContents = [NSString stringWithContentsOfFile:listFile encoding:NSUTF8StringEncoding error:nil];
|
|
|
- DLog(@"\nContents: %@\n", listContents);
|
|
|
- DLog(@"\nFound package info files: %@\n", relatedFiles);
|
|
|
- NSArray *files = [listContents componentsSeparatedByString:@"\n"];
|
|
|
- __block NSMutableArray *filesToProcess = [NSMutableArray new];
|
|
|
- [relatedFiles enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
|
|
- NSString *fullPath = [infoPath stringByAppendingPathComponent:obj];
|
|
|
- if([FM fileExistsAtPath:fullPath]){
|
|
|
- if ([[obj pathExtension] isEqualToString:@"postrm"]){
|
|
|
- postRmFile = fullPath;
|
|
|
- }
|
|
|
- [filesToProcess addObject:fullPath];
|
|
|
- }
|
|
|
- }];
|
|
|
- [files enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
|
|
- NSString *fullPath = [bootstrapPath stringByAppendingPathComponent:obj];
|
|
|
- BOOL isDir = FALSE;
|
|
|
- if([FM fileExistsAtPath:fullPath isDirectory:&isDir]){
|
|
|
- if (!isDir){
|
|
|
- DLog(@"found file: %@", fullPath);
|
|
|
- [filesToProcess addObject:fullPath];
|
|
|
- }
|
|
|
- }
|
|
|
- }];
|
|
|
- DLog(@"\nFiles to process: %@\n", filesToProcess);
|
|
|
- NSString *error = [NSString stringWithFormat:@" [WARNING] We are about to delete '%@' from the bootstrap, this cannot be undone!", deletePackage];
|
|
|
- if(![HelperClass shouldContinueWithError:error]){
|
|
|
- return -1;
|
|
|
- }
|
|
|
- [filesToProcess enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
|
|
- [FM removeItemAtPath:obj error:nil];
|
|
|
- }];
|
|
|
-
|
|
|
- NSString *statusFile = [bootstrapPath relativeStatusFilePath];
|
|
|
- [FM copyItemAtPath:statusFile toPath:[statusFile stringByAppendingPathExtension:@"bak"] error:nil];
|
|
|
- __block NSMutableString *newStatusFile = [NSMutableString new];
|
|
|
- [installedPackages enumerateObjectsUsingBlock:^(StatusPackageModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
|
|
- if (obj != model){
|
|
|
- [newStatusFile appendFormat:@"%@\n\n", obj.rawString];
|
|
|
- } else {
|
|
|
- DLog(@"skipping the model we want to delete: %@", obj);
|
|
|
- }
|
|
|
- }];
|
|
|
-#pragma clang diagnostic push
|
|
|
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
|
- [newStatusFile writeToFile:statusFile atomically:TRUE];
|
|
|
-#pragma clang diagnostic pop
|
|
|
- if (postRmFile) {
|
|
|
- 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", postRmFile, [NSString stringWithContentsOfFile:postRmFile encoding:NSUTF8StringEncoding error:nil]);
|
|
|
- }
|
|
|
- }
|
|
|
- return 0;
|
|
|
+ return [HelperClass deletePackage:deletePackage inBootstrap:bootstrapPath];
|
|
|
} else if (deletePackage) {
|
|
|
DLog(@"\nYou need to choose a bootstrap path to delete from!\n\n");
|
|
|
return 1;
|
|
@@ -317,6 +204,14 @@ int main(int argc, char **argv) {
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
+ if (new && bootstrapPath && packagesFolder) {
|
|
|
+ return [HelperClass createNewBootstrap:bootstrapPath withPackages:packagesFolder];
|
|
|
+ } else if (new && bootstrapPath) {
|
|
|
+ DLog(@"you need to choose a packages folder to install from when creating a new bootstrap!");
|
|
|
+ } else if (new) {
|
|
|
+ DLog(@"you need to choose a packages folder to install from when creating a new bootstrap, and a bootstrap folder needs to be specified as well.");
|
|
|
+ }
|
|
|
+
|
|
|
if (debFile && bootstrapPath) {
|
|
|
DLog(@"\nProcessing file: %@\n", debFile);
|
|
|
InputPackage *output = [HelperClass packageForDeb:debFile];
|