123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538 |
- //
- // main.m
- // octalConversion
- //
- // Created by Kevin Bradley on 6/28/18.
- // Copyright © 2018 nito. All rights reserved.
- //
- #import <Foundation/Foundation.h>
- #include <stdio.h>
- #include <errno.h>
- #include <libgen.h>
- #include <string.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <getopt.h>
- #import <sys/utsname.h>
- #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"
- char *progname;
- 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' },
- { "delete", required_argument, NULL, 'd' },
- { "help", no_argument, NULL, 'h' },
- { "clean", no_argument, NULL, 'c' },
- { "repackage", no_argument, NULL, 'r' },
- { NULL, 0, NULL, 0 }
- };
- void cmd_help(){
- printf("Usage: bootstrapTool [OPTIONS] FILE\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(" -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("\n");
- }
- int main(int argc, const char * argv[]) {
- @autoreleasepool {
-
- 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 repackage = FALSE;
- BOOL clean = FALSE;
- while ((flag = getopt_long(argc, argv, OPTION_FLAGS, longopts, NULL)) != -1) {
- switch(flag) {
- case 'o':
- octalFile = [NSString stringWithUTF8String:optarg];
- break;
-
- case 'i':
-
- debFile = [NSString stringWithUTF8String:optarg];
- break;
-
- case 'b':
-
- bootstrapPath = [NSString stringWithUTF8String:optarg];
- break;
-
- case 'l':
-
- bootstrapListPath = [NSString stringWithUTF8String:optarg];
- break;
-
- case 'd':
-
- deletePackage = [NSString stringWithUTF8String:optarg];
- break;
-
- case 'r':
-
- repackage = TRUE;
- break;
-
- case 'c':
-
- clean = TRUE;
- break;
-
- default:
- cmd_help();
- return -1;
-
- }
- }
-
- if (repackage == TRUE && debFile) {
-
- DLog(@"\n [INFO] Repackaging file: %@...\n", debFile);
- InputPackage *output = [HelperClass packageForDeb:debFile];
- [output repackageInCurrentDirectoryWithArch:@"appletvos-arm64"];
- return 0;
- }
-
- //DLog(@"folder: %@ project: %@", folder, project);
-
- if (clean && bootstrapPath) {
-
- NSString *statusFile = [bootstrapPath stringByAppendingPathComponent:@"Library/dpkg/status"];
-
- 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"];
- [listContents writeToFile:statusFile atomically:TRUE];
-
- DLog(@"\n [INFO] Cleaning status file: %@", statusFile);
-
- NSString *testStatusFile = [bootstrapPath stringByAppendingPathComponent:@"Library/dpkg/status"];
- 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 pacakge: %@", 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);
-
- [newStatusFile writeToFile:testStatusFile atomically:TRUE];
-
- DLog(@"\n Done!\n\n");
-
- return 0;
-
- }
-
- if (deletePackage && bootstrapPath) {
-
- __block NSString *postInstFile = nil;
-
- NSString *statusFile = [bootstrapPath stringByAppendingPathComponent:@"Library/dpkg/status"];
- 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 stringByAppendingPathComponent:@"Library/dpkg/info"];
- 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:@"postinst"]){
- postInstFile = 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];
-
- }];
-
- //TODO: delete the files here!
-
-
- NSString *statusFile = [bootstrapPath stringByAppendingPathComponent:@"Library/dpkg/status"];
- [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);
-
- }
-
- }];
-
- [newStatusFile writeToFile:statusFile atomically:TRUE];
-
-
- if (postInstFile) {
-
- 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\n%@ contents:\n%@\n\n", postInstFile, [NSString stringWithContentsOfFile:postInstFile encoding:NSUTF8StringEncoding error:nil]);
-
-
-
- }
-
- }
-
-
- return 0;
- }
-
- if (octalFile) {
-
- NSString *octal = [HelperClass octalFromSymbols:octalFile];
- DLog(@"%@", octal);
- return 0;
- }
-
- if (bootstrapListPath) {
-
- NSString *statusFile = [bootstrapListPath stringByAppendingPathComponent:@"Library/dpkg/status"];
- NSArray *installedPackages = [HelperClass statusInstalledPackagesFromFile:statusFile];
- DLog(@"%@", installedPackages);
- return 0;
-
- }
-
-
- 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;
- }
- //if we got this far.. nothing happened, print help.
- cmd_help();
-
- }
- return 0;
- }
|