Browse Source

refactored into multiple files for better organization

Kevin Bradley 5 years ago
parent
commit
4c089d6703

+ 30 - 0
bootstrapTool/Classes/DebPackageModel.h

@@ -0,0 +1,30 @@
+
+
+@interface DebPackageModel : NSObject
+
+@property (nonatomic, copy) NSString *name;
+@property (nonatomic, copy) NSString *package;
+@property (nonatomic, copy) NSString *source;
+@property (nonatomic, copy) NSString *version;
+@property (nonatomic, copy) NSString *priority;
+@property (nonatomic, copy) NSString *essential;
+@property (nonatomic, copy) NSArray *depends;
+@property (nonatomic, copy) NSString *maintainer;
+@property (nonatomic, copy) NSString *packageDescription; //cant be description, that is reservered
+@property (nonatomic, copy) NSString *homepage;
+@property (nonatomic, copy) NSString *author;
+@property (nonatomic, copy) NSString *icon;
+@property (nonatomic, copy) NSString *depiction;
+@property (nonatomic, copy) NSString *preDepends;
+@property (nonatomic, copy) NSString *breaks;
+@property (nonatomic, copy) NSString *status;
+@property (nonatomic, copy) NSString *tag;
+@property (nonatomic, copy) NSString *architecture;
+@property (nonatomic, copy) NSString *section;
+@property (nonatomic, copy) NSString *rawString;
+
+
+- (instancetype)initWithRawControlString:(NSString *)controlString;
+
+
+@end

+ 173 - 0
bootstrapTool/Classes/DebPackageModel.m

@@ -0,0 +1,173 @@
+
+@implementation DebPackageModel
+
+- (NSString *)description {
+    
+    NSString *orig = [super description];
+    return [NSString stringWithFormat:@"%@ = %@ (%@)", orig, self.package, self.version];
+}
+
+- (NSString*) fullDescription {
+    
+    NSString *orig = [super description];
+    NSMutableDictionary *details = [NSMutableDictionary new];
+    NSArray *props = [self properties];
+    [props enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        
+        NSString *cv = [self valueForKey:obj];
+        if (cv){
+            details[obj] = cv;
+        }
+        
+    }];
+    return [NSString stringWithFormat:@"%@ = %@", orig, details];
+    
+}
+
++ (NSDictionary *)dependencyDictionaryFromString:(NSString *)depend
+{
+    NSMutableCharacterSet *whitespaceAndPunctuationSet = [NSMutableCharacterSet characterSetWithCharactersInString:@"()"];
+    [whitespaceAndPunctuationSet formUnionWithCharacterSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+    
+    NSScanner *stringScanner = [[NSScanner alloc] initWithString:depend];
+    stringScanner.charactersToBeSkipped = whitespaceAndPunctuationSet;
+    
+    NSString *name = nil;
+    NSInteger i = 0;
+    NSMutableDictionary *predicate = [NSMutableDictionary new];
+    while ([stringScanner scanUpToCharactersFromSet:whitespaceAndPunctuationSet intoString:&name]) {
+        // NSLog(@"%@ pass %li", name, (long)i);
+        switch (i) {
+            case 0 :
+                predicate[@"package"] = name;
+                break;
+            case 1:
+                predicate[@"predicate"] = name;
+                break;
+            case 2:
+                predicate[@"requirement"] = name;
+                break;
+            default:
+                break;
+        }
+        i++;
+    }
+    return predicate;
+}
+
+
++ (NSArray *)dependencyArrayFromString:(NSString *)depends
+{
+    NSMutableArray *cleanArray = [[NSMutableArray alloc] init];
+    NSArray *dependsArray = [depends componentsSeparatedByString:@","];
+    for (id depend in dependsArray)
+    {
+        NSArray *spaceDelimitedArray = [depend componentsSeparatedByString:@" "];
+        NSString *isolatedDependency = [[spaceDelimitedArray objectAtIndex:0] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+        if ([isolatedDependency length] == 0)
+            isolatedDependency = [[spaceDelimitedArray objectAtIndex:1] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+        
+        NSDictionary *dependDict = [self dependencyDictionaryFromString:depend];
+        //DLog(@"depend dict: %@", dependDict);
+        [cleanArray addObject:dependDict];
+    }
+    
+    return cleanArray;
+}
+
++ (NSDictionary *)JSONKeyPathsByPropertyKey {
+    return @{
+             @"name": @"Name",
+             @"package": @"Package",
+             @"source": @"Source",
+             @"version": @"Version",
+             @"priority": @"Priority",
+             @"essential": @"Essential",
+             @"depends": @"Depends",
+             @"maintainer": @"Maintainer",
+             @"packageDescription": @"Description",
+             @"homepage": @"Homepage",
+             @"icon": @"Icon",
+             @"author": @"Author",
+             @"preDepends": @"Pre-Depends",
+             @"breaks": @"Breaks",
+             @"depiction": @"Depiction",
+             @"tag": @"Tag",
+             @"architecture": @"Architecture",
+             @"section": @"Section",
+             @"osMax": @"osMax",
+             @"osMin": @"osMin",
+             @"banner": @"Banner",
+             @"topShelfImage": @"TopShelfImage"
+             };
+}
+
+- (instancetype)initWithRawControlString:(NSString *)controlString
+{
+    NSArray *packageArray = [controlString componentsSeparatedByString:@"\n"];
+    NSMutableDictionary *currentPackage = [[NSMutableDictionary alloc] init];
+    for (id currentLine in packageArray)
+    {
+        NSArray *itemArray = [currentLine componentsSeparatedByString:@": "];
+        if ([itemArray count] >= 2)
+        {
+            NSString *key = [itemArray objectAtIndex:0];
+            NSString *object = [itemArray objectAtIndex:1];
+            
+            if ([key isEqualToString:@"Depends"]) //process the array
+            {
+                NSArray *dependsObject = [DebPackageModel dependencyArrayFromString:object];
+                
+                [currentPackage setObject:dependsObject forKey:key];
+                
+            } else { //every other key, even if it has an array is treated as a string
+                
+                [currentPackage setObject:object forKey:key];
+            }
+        }
+    }
+    
+    if ([[currentPackage allKeys] count] > 4)
+    {
+        self = [super init];
+        self.rawString = controlString;
+        [self mapDictionaryToProperties:currentPackage];
+        return self;
+    }
+    return nil;
+    
+    
+}
+
+- (void)mapDictionaryToProperties:(NSDictionary *)theProps {
+    
+    NSArray *ourProps = [self properties];
+    NSArray *allKeys = [theProps allKeys];
+    NSDictionary *mappedKeys = [DebPackageModel JSONKeyPathsByPropertyKey];
+    [ourProps enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        
+        NSString *mappedProp = mappedKeys[obj];
+        
+        //DLog(@"allkeys: %@", allKeys);
+        
+        if ([allKeys containsObject:mappedProp]){
+            if ([self respondsToSelector:NSSelectorFromString(obj)]){ //redudant
+                
+                id value = theProps[mappedProp];
+                //DLog(@"setting value: %@ for key: %@ from mapped key: %@", value, obj, mappedProp);
+                [self setValue:value forKey:obj];
+                
+            }
+        } else {
+            
+            //DLog(@"%@ doesnt respond to %@", self, mappedProp);
+            
+        }
+        
+        
+    }];
+    
+}
+
+
+@end

+ 26 - 0
bootstrapTool/Classes/Defines.h

@@ -0,0 +1,26 @@
+
+#import <Foundation/Foundation.h>
+#import "NSObject+Additions.h"
+#import "NSString+Additions.h"
+#import "ErrorReturn.h"
+#import "Package.h"
+#import "PackageFile.h"
+#import "DebPackageModel.h"
+
+typedef NS_ENUM(NSInteger, BSPackageFileType)
+{
+    
+    BSPackageFileTypeFile,
+    BSPackageFileTypeDirectory,
+    BSPackageFileTypeBlock,
+    BSPackageFileTypeCharacter,
+    BSPackageFileTypeLink,
+    BSPackageFileTypePipe,
+    BSPackageFileTypeSocket,
+    BSPackageFileTypeUnknown
+    
+};
+
+
+#define DLog(format, ...) CFShow((__bridge CFStringRef)[NSString stringWithFormat:format, ## __VA_ARGS__]);
+#define FM [NSFileManager defaultManager]

+ 8 - 0
bootstrapTool/Classes/ErrorReturn.h

@@ -0,0 +1,8 @@
+
+@interface ErrorReturn: NSObject
+
+@property (nonatomic, strong) NSArray *overwriteFiles;
+@property (readwrite, assign) NSInteger returnStatus;
+
+
+@end

+ 6 - 0
bootstrapTool/Classes/ErrorReturn.m

@@ -0,0 +1,6 @@
+
+#import "ErrorReturn.h"
+
+@implementation ErrorReturn
+
+@end

+ 10 - 0
bootstrapTool/Classes/HelperClass.h

@@ -0,0 +1,10 @@
+
+@interface HelperClass: NSObject
+
++ (BOOL)shouldContinueWithError:(NSString *)errorMessage;
++ (NSArray *)returnForProcess:(NSString *)call;
++ (Package *)packageForDeb:(NSString *)debFile;
++ (NSString *)octalFromSymbols:(NSString *)theSymbols;
++ (NSArray <DebPackageModel*>*)statusInstalledPackagesFromFile:(NSString *)statusFile;
+
+@end

+ 367 - 0
bootstrapTool/Classes/HelperClass.m

@@ -0,0 +1,367 @@
+
+#import "HelperClass.h"
+#import "DebPackageModel.h"
+
+@implementation HelperClass
+
++ (NSArray <DebPackageModel*>*)statusInstalledPackagesFromFile:(NSString *)statusFile
+{
+    
+    if (![FM fileExistsAtPath:statusFile]) {
+        return nil;
+    }
+    NSString *packageString = [NSString stringWithContentsOfFile:statusFile encoding:NSUTF8StringEncoding error:nil];
+    NSArray *lineArray = [packageString componentsSeparatedByString:@"\n\n"];
+    //DDLogInfo(@"lineArray: %@", lineArray);
+    NSMutableArray *mutableList = [[NSMutableArray alloc] init];
+    //NSMutableDictionary *mutableDict = [[NSMutableDictionary alloc] init];
+    for (id currentItem in lineArray)
+    {
+        
+        DebPackageModel *debModel = [[DebPackageModel alloc] initWithRawControlString:currentItem];
+        if (debModel != nil)
+            [mutableList addObject:debModel];
+    }
+    
+    NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES
+                                                                    selector:@selector(localizedCaseInsensitiveCompare:)];
+    NSSortDescriptor *packageDescriptor = [[NSSortDescriptor alloc] initWithKey:@"package" ascending:YES
+                                                                       selector:@selector(localizedCaseInsensitiveCompare:)];
+    NSArray *descriptors = [NSArray arrayWithObjects:nameDescriptor, packageDescriptor, nil];
+    NSArray *sortedArray = [mutableList sortedArrayUsingDescriptors:descriptors];
+    
+    
+    mutableList = nil;
+    
+    return sortedArray;
+}
+
++ (BOOL)shouldContinueWithError:(NSString *)errorMessage {
+    
+    NSString *errorString = [NSString stringWithFormat:@"\n%@ Are you sure you want to continue? [y/n]?", errorMessage];
+    
+    char c;
+    printf("%s", [errorString UTF8String] );
+    c=getchar();
+    while(c!='y' && c!='n')
+    {
+        if (c!='\n'){
+            printf("[y/n]");
+        }
+        c=getchar();
+    }
+    
+    if (c == 'n')
+    {
+        DLog(@"\n smart move... exiting\n\n");
+        return FALSE;
+    } else if (c == 'y') {
+        DLog(@"\n its your funeral....\n\n");
+    }
+    
+    return TRUE;
+    
+}
+
++ (NSArray *)returnForProcess:(NSString *)call
+{
+    if (call==nil)
+        return 0;
+    char line[200];
+    //DDLogInfo(@"running process: %@", call);
+    FILE* fp = popen([call UTF8String], "r");
+    NSMutableArray *lines = [[NSMutableArray alloc]init];
+    if (fp)
+    {
+        while (fgets(line, sizeof line, fp))
+        {
+            NSString *s = [NSString stringWithCString:line encoding:NSUTF8StringEncoding];
+            s = [s stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+            [lines addObject:s];
+        }
+    }
+    pclose(fp);
+    return lines;
+}
+
++ (PackageFile *)packageFileFromLine:(NSString *)inputLine {
+    //    "-rwxr-xr-x  0 root   wheel   69424 Oct 22 03:56 ./Library/MobileSubstrate/DynamicLibraries/beigelist7.dylib\n",
+    
+    //-rwxr-xr-x root/staff    10860 2011-02-02 03:55 ./Library/Frameworks/CydiaSubstrate.framework/Commands/cycc
+    
+    inputLine = [inputLine stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+    inputLine = [inputLine stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\t"]];
+    NSMutableString *newString = [[NSMutableString alloc] initWithString:inputLine];
+    [newString replaceOccurrencesOfString:@"      " withString:@" " options:NSLiteralSearch range:NSMakeRange(0, [newString length])];
+    [newString replaceOccurrencesOfString:@"     " withString:@" " options:NSLiteralSearch range:NSMakeRange(0, [newString length])];
+    [newString replaceOccurrencesOfString:@"    " withString:@" " options:NSLiteralSearch range:NSMakeRange(0, [newString length])];
+    [newString replaceOccurrencesOfString:@"   " withString:@" " options:NSLiteralSearch range:NSMakeRange(0, [newString length])];
+    [newString replaceOccurrencesOfString:@"  " withString:@" " options:NSLiteralSearch range:NSMakeRange(0, [newString length])];
+    
+    NSArray *lineObjects = [newString componentsSeparatedByString:@" "];
+    
+    //NSLog(@"lineObjects: %@", lineObjects);
+    
+    
+    /*
+     
+     "drwxr-xr-x",
+     "root/wheel",
+     0,
+     "2018-06-27",
+     "01:21",
+     "./"
+     */
+    
+    
+    NSString *permissionsAndType = [lineObjects objectAtIndex:0];
+    NSString *userGroup = [lineObjects objectAtIndex:1];
+    NSString *size = [lineObjects objectAtIndex:2];
+    NSString *date = [lineObjects objectAtIndex:3];
+    NSString *time = [lineObjects objectAtIndex:4];
+    NSString *path = [lineObjects objectAtIndex:5];
+    
+    //@"drwxr-xr-x"
+    NSString *fileTypeChar = [permissionsAndType substringWithRange:NSMakeRange(0, 1)];
+    
+    NSString *octalPermissions = [self octalFromSymbols:permissionsAndType];
+    NSString *octalUG = [self octalFromGroupSymbols:userGroup];
+    NSString *fileName = [path lastPathComponent];
+    //NSString *fullPath = [NSString stringWithFormat:@"/%@", path];
+    NSString *fullPath = [path substringFromIndex:1];
+    
+    PackageFile *pf = [PackageFile new];
+    [pf _setFileTypeFromRaw:fileTypeChar];
+    
+    switch (pf.type) {
+        case BSPackageFileTypeLink:
+        {
+            
+            fullPath = [lineObjects objectAtIndex:7];
+            NSString *linkDest = [NSString stringWithFormat:@"/%@", path];
+            pf.permissions = octalPermissions;
+            pf.owner = octalUG;
+            pf.size = size;
+            pf.time = time;
+            pf.date = date;
+            pf.path = fullPath;
+            pf.basename = fileName;
+            pf.linkDestination = linkDest;
+            
+            return pf;
+        }
+            break;
+            
+        case BSPackageFileTypeDirectory: //return for now
+            
+            //DLog(@"we dont want directory entries do we %@", lineObjects);
+            pf.permissions = octalPermissions;
+            pf.owner = octalUG;
+            pf.size = size;
+            pf.time = time;
+            pf.date = date;
+            pf.path = fullPath;
+            pf.basename = fileName;
+            return pf;
+            break;
+            
+        default:
+            break;
+    }
+    
+    
+    pf.permissions = octalPermissions;
+    pf.owner = octalUG;
+    pf.size = size;
+    pf.time = time;
+    pf.date = date;
+    pf.path = fullPath;
+    pf.basename = fileName;
+    return pf;
+    // return [NSDictionary dictionaryWithObjectsAndKeys:fileType, @"fileType",octalPermissions, @"octalPermissions", octalUG, @"octalUG", size, @"size", date, @"date", time, @"time", fileName, @"fileName", fullPath, @"fullPath",  nil];
+    
+}
+
+
++ (NSString *)octalFromGroupSymbols:(NSString *)theSymbols
+{
+    NSArray *groupArray = [theSymbols componentsSeparatedByString:@"/"];
+    NSString *user = [groupArray objectAtIndex:0];
+    NSString *group = [groupArray objectAtIndex:1];
+    
+    NSString *octalUser = nil;
+    NSString *octalGroup = nil;
+    //uid=0(root) gid=0(wheel) groups=0(wheel),1(daemon),2(kmem),3(sys),4(tty),5(operator),8(procview),9(procmod),20(staff),29(certusers),80(admin)
+    if ([user isEqualToString:@"root"])
+    {
+        octalUser = @"0";
+    } else if ([user isEqualToString:@"mobile"])
+    {
+        octalUser = @"501";
+    }
+    //obviously more cases!! FIXME:
+    
+    if ([group isEqualToString:@"staff"])
+    {
+        octalGroup = @"20";
+    } else if ([group isEqualToString:@"admin"])
+    {
+        octalGroup = @"80";
+    } else if ([group isEqualToString:@"wheel"])
+    {
+        octalGroup = @"0";
+    } else if ([group isEqualToString:@"daemon"])
+    {
+        octalGroup = @"1";
+    } else if ([group isEqualToString:@"kmem"])
+    {
+        octalGroup = @"2";
+    } else if ([group isEqualToString:@"sys"])
+    {
+        octalGroup = @"3";
+    } else if ([group isEqualToString:@"tty"])
+    {
+        octalGroup = @"4";
+    } else if ([group isEqualToString:@"operator"])
+    {
+        octalGroup = @"5";
+    } else if ([group isEqualToString:@"procview"])
+    {
+        octalGroup = @"8";
+    } else if ([group isEqualToString:@"procmod"])
+    {
+        octalGroup = @"9";
+    } else if ([group isEqualToString:@"certusers"])
+    {
+        octalGroup = @"29";
+    } else
+    {
+        octalGroup = @"501"; //default to mobile
+    }
+    //uid=0(root) gid=0(wheel) groups=0(wheel),1(daemon),2(kmem),3(sys),4(tty),5(operator),8(procview),9(procmod),20(staff),29(certusers),80(admin)
+    return [NSString stringWithFormat:@"%@:%@", octalUser, octalGroup];
+    
+}
+
+
+
+
+
++ (Package *)packageForDeb:(NSString *)debFile {
+    
+    NSString *packageName = [[self returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -f %@ Package", debFile]] componentsJoinedByString:@"\n"];
+    NSString *packageVersion = [[self returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -f %@ Version", debFile]] componentsJoinedByString:@"\n"];
+    NSArray <PackageFile *> *fileList = [self returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -c %@", debFile]];
+    
+    __block NSMutableArray *finalArray = [NSMutableArray new];
+    
+    [fileList enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        
+        PackageFile *file = [self packageFileFromLine:obj];
+        if (file) {
+            //DLog(@"%@", file);
+            [finalArray addObject:file];
+        }
+        
+    }];
+    
+    Package *pkg = [Package new];
+    pkg.files = finalArray;
+    pkg.packageName = packageName;
+    pkg.version = packageVersion;
+    return pkg;
+    
+}
+
++ (NSString *)octalFromSymbols:(NSString *)theSymbols
+{
+    //NSLog(@"%@ %s", self, _cmd);
+    NSString *U = [theSymbols substringWithRange:NSMakeRange(1, 3)];
+    NSString *G = [theSymbols substringWithRange:NSMakeRange(4, 3)];
+    NSString *O = [theSymbols substringWithRange:NSMakeRange(7, 3)];
+    //NSLog(@"fileTypeChar: %@", fileTypeChar);
+    //NSLog(@"U; %@", U);
+    //NSLog(@"G; %@", G);
+    //NSLog(@"O; %@", O);
+    
+    //USER
+    
+    int sIdBit = 0;
+    
+    int uOctal = 0;
+    
+    const char *uArray = [U cStringUsingEncoding:NSASCIIStringEncoding];
+    int stringLength = [U length];
+    
+    int x;
+    for( x=0; x<stringLength; x++ )
+    {
+        unsigned int aCharacter = uArray[x];
+        if (aCharacter == 'r')
+        {
+            uOctal += 4;
+        } else     if (aCharacter == 'w')
+        {
+            uOctal += 2;
+        } else     if (aCharacter == 'x')
+        {
+            uOctal += 1;
+        } else     if (aCharacter == 's')
+        {
+            sIdBit += 4;
+        }
+    }
+    
+    //GROUP
+    
+    int gOctal = 0;
+    const char *gArray = [G cStringUsingEncoding:NSASCIIStringEncoding];
+    stringLength = [G length];
+    
+    int y;
+    for( y=0; y<stringLength; y++ )
+    {
+        unsigned int aCharacter = gArray[y];
+        if (aCharacter == 'r')
+        {
+            gOctal += 4;
+        } else     if (aCharacter == 'w')
+        {
+            gOctal += 2;
+        } else     if (aCharacter == 'x')
+        {
+            gOctal += 1;
+        } else     if (aCharacter == 's')
+        {
+            gOctal += 2;
+        }
+    }
+    
+    //OTHERS
+    int z;
+    int oOctal = 0;
+    const char *oArray = [O cStringUsingEncoding:NSASCIIStringEncoding];
+    stringLength = [O length];
+    
+    
+    for( z=0; z<stringLength; z++ )
+    {
+        unsigned int aCharacter = oArray[z];
+        if (aCharacter == 'r')
+        {
+            oOctal += 4;
+        } else     if (aCharacter == 'w')
+        {
+            oOctal += 2;
+        } else     if (aCharacter == 'x')
+        {
+            oOctal += 1;
+        }
+    }
+    
+    
+    return [NSString stringWithFormat:@"%i%i%i%i", sIdBit, uOctal, gOctal, oOctal];
+    
+}
+
+@end

+ 7 - 0
bootstrapTool/Classes/NSObject+Additions.h

@@ -0,0 +1,7 @@
+
+@interface NSObject (Additions)
+
+-(NSArray *)ivars;
+-(NSArray *)properties;
+
+@end

+ 38 - 0
bootstrapTool/Classes/NSObject+Additions.m

@@ -0,0 +1,38 @@
+
+#import "NSObject+Additions.h"
+#import <objc/runtime.h>
+
+@implementation NSObject (Additions)
+
+- (NSArray *)properties
+{
+    u_int count;
+    objc_property_t* properties = class_copyPropertyList(self.class, &count);
+    NSMutableArray* propArray = [NSMutableArray arrayWithCapacity:count];
+    for (int i = 0; i < count ; i++)
+    {
+        const char* propertyName = property_getName(properties[i]);
+        NSString *propName = [NSString  stringWithCString:propertyName encoding:NSUTF8StringEncoding];
+        [propArray addObject:propName];
+    }
+    free(properties);
+    return propArray;
+}
+
+-(NSArray *)ivars
+{
+    Class clazz = [self class];
+    u_int count;
+    Ivar* ivars = class_copyIvarList(clazz, &count);
+    NSMutableArray* ivarArray = [NSMutableArray arrayWithCapacity:count];
+    for (int i = 0; i < count ; i++)
+    {
+        const char* ivarName = ivar_getName(ivars[i]);
+        [ivarArray addObject:[NSString  stringWithCString:ivarName encoding:NSUTF8StringEncoding]];
+    }
+    free(ivars);
+    return ivarArray;
+}
+
+
+@end

+ 8 - 0
bootstrapTool/Classes/NSString+Additions.h

@@ -0,0 +1,8 @@
+
+
+@interface NSString (Additions)
+
+- (void)writeToFileWithoutAttributes:(NSString *)theFile;
+
+
+@end

+ 20 - 0
bootstrapTool/Classes/NSString+Additions.m

@@ -0,0 +1,20 @@
+
+
+#import "NSString+Additions.h"
+
+@implementation NSString (Additions)
+
+- (void)writeToFileWithoutAttributes:(NSString *)theFile {
+    
+    if ([FM fileExistsAtPath:theFile]){
+        
+        DLog(@"overwriting file: %@", theFile);
+    }
+    FILE *fd = fopen([theFile UTF8String], "w+");
+    const char *text = self.UTF8String;
+    fwrite(text, strlen(text) + 1, 1, fd);
+    fclose(fd);
+    
+}
+
+@end

+ 13 - 0
bootstrapTool/Classes/Package.h

@@ -0,0 +1,13 @@
+
+#import "PackageFile.h"
+
+@interface Package: NSObject
+
+@property (nonatomic, strong) NSArray <PackageFile *> *files;
+@property (nonatomic, strong) NSArray  *controlFiles;
+@property (nonatomic, strong) NSString *packageName;
+@property (nonatomic, strong) NSString *version;
+
+- (ErrorReturn *)errorReturnForBootstrap:(NSString *)bootstrapPath;
+- (NSString *)listfile;
+@end

+ 154 - 0
bootstrapTool/Classes/Package.m

@@ -0,0 +1,154 @@
+#import "Package.h"
+#import "ErrorReturn.h"
+#import "HelperClass.h"
+
+@implementation Package
+
+- (NSString*) description {
+    
+    NSString *orig = [super description];
+    NSMutableDictionary *details = [NSMutableDictionary new];
+    NSArray *props = [self properties];
+    [props enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        
+        NSString *cv = [self valueForKey:obj];
+        if (cv){
+            details[obj] = cv;
+        }
+        
+    }];
+    return [NSString stringWithFormat:@"%@ = %@", orig, details];
+    
+}
+
+- (NSString *)listfile {
+    
+    __block NSMutableArray *outFiles = [NSMutableArray new];
+    [self.files enumerateObjectsUsingBlock:^(PackageFile * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        
+        if ([obj.fileType isEqualToString:@"link"]){ //does this need to handle things differently?
+            [outFiles addObject:obj.path];
+        } else {
+            [outFiles addObject:obj.path];
+        }
+    }];
+    return [outFiles componentsJoinedByString:@"\n"];
+    
+}
+
+- (void)repackageFile:(DebPackageModel *)file arch:(NSString *)newArch {
+/*
+    NSString *pwd = [[HelperClass returnForProcess:@"/bin/pwd"] componentsJoinedByString:@"\n"];
+    DLog(@"\nProcessing file: %@\n", file);
+    Package *output = [HelperClass packageForDeb:repackage];
+    
+    DLog(@"\nFound package: '%@' at version: '%@'...\n", output.packageName, output.version );
+    
+    NSString *tmpPath = [pwd stringByAppendingPathComponent:output.packageName];
+    NSString *debian = [tmpPath stringByAppendingPathComponent:@"DEBIAN"];
+    [FM createDirectoryAtPath:tmpPath withIntermediateDirectories:TRUE attributes:nil error:nil];
+    DLog(@"\nExtracting package contents for processing...\n");
+    [HelperClass returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -x %@ %@", debFile, tmpPath]];
+    [FM 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 *controlPath = [debian stringByAppendingPathComponent:@"control"];
+    
+    NSMutableString *controlFile = [[NSMutableString alloc] initWithContentsOfFile:controlPath encoding:NSUTF8StringEncoding error:nil];
+    
+    [controlFile replaceOccurrencesOfString:@"iphoneos-arm" withString:@"appletvos-arm64" options:NSLiteralSearch range:NSMakeRange(0, [controlFile length])];
+    
+    [controlFile writeToFile:controlPath atomically:TRUE];
+    
+    
+    NSArray *ignoreFiles = @[@".fauxsu", @".DS_Store"];
+    NSArray *forbiddenRoots = @[@"etc", @"var", @"tmp"];
+    NSFileManager *man = [NSFileManager defaultManager];
+    __block NSInteger returnValue = 0; //0 = good to go 1 = over write warning, 2 = no go
+    __block NSMutableArray *_overwriteArray = [NSMutableArray new];
+    [self.files enumerateObjectsUsingBlock:^(PackageFile * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        
+        if ([obj.fileType isEqualToString:@"file"]){
+            
+            NSString *fullPath = [bootstrapPath stringByAppendingPathComponent:obj.path];
+            if ([man fileExistsAtPath:fullPath] && ![ignoreFiles containsObject:obj.basename]){
+                
+                //DLog(@"[WARNING] overwriting a file that already exists and isn't DS_Store or .fauxsu: %@", fullPath);
+                [_overwriteArray addObject:obj.path];
+                //*stop = TRUE;//return FALSE;
+                returnValue = 1;
+            }
+            
+            NSArray *pathComponents = [obj.path pathComponents];
+            if ([pathComponents count] > 1)
+            {
+                NSString *rootPath = [pathComponents objectAtIndex:1];
+                if ([forbiddenRoots containsObject:rootPath])
+                {
+                    DLog(@"\n [ERROR] package file: '%@' would overwrite symbolic link at '%@'! Exiting!\n\n", obj.path, rootPath);
+                    *stop = TRUE;
+                    returnValue = 2;
+                }
+            }
+            
+            
+        }
+        
+        
+    }];
+    
+    ErrorReturn *er = [ErrorReturn new];
+    er.returnStatus = returnValue;
+    er.overwriteFiles = _overwriteArray;
+    */
+    //return er;
+}
+
+- (ErrorReturn *)errorReturnForBootstrap:(NSString *)bootstrapPath
+{
+    NSArray *ignoreFiles = @[@".fauxsu", @".DS_Store"];
+    NSArray *forbiddenRoots = @[@"etc", @"var", @"tmp"];
+    NSFileManager *man = [NSFileManager defaultManager];
+    __block NSInteger returnValue = 0; //0 = good to go 1 = over write warning, 2 = no go
+    __block NSMutableArray *_overwriteArray = [NSMutableArray new];
+    [self.files enumerateObjectsUsingBlock:^(PackageFile * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        
+        if ([obj.fileType isEqualToString:@"file"]){
+            
+            NSString *fullPath = [bootstrapPath stringByAppendingPathComponent:obj.path];
+            if ([man fileExistsAtPath:fullPath] && ![ignoreFiles containsObject:obj.basename]){
+                
+                //DLog(@"[WARNING] overwriting a file that already exists and isn't DS_Store or .fauxsu: %@", fullPath);
+                [_overwriteArray addObject:obj.path];
+                //*stop = TRUE;//return FALSE;
+                returnValue = 1;
+            }
+            
+            NSArray *pathComponents = [obj.path pathComponents];
+            if ([pathComponents count] > 1)
+            {
+                NSString *rootPath = [pathComponents objectAtIndex:1];
+                if ([forbiddenRoots containsObject:rootPath])
+                {
+                    DLog(@"\n [ERROR] package file: '%@' would overwrite symbolic link at '%@'! Exiting!\n\n", obj.path, rootPath);
+                    *stop = TRUE;
+                    returnValue = 2;
+                }
+            }
+            
+            
+        }
+        
+        
+    }];
+    
+    ErrorReturn *er = [ErrorReturn new];
+    er.returnStatus = returnValue;
+    er.overwriteFiles = _overwriteArray;
+    
+    return er;
+}
+
+
+@end

+ 18 - 0
bootstrapTool/Classes/PackageFile.h

@@ -0,0 +1,18 @@
+
+
+@interface PackageFile: NSObject
+
+@property (nonatomic, strong) NSString *fileType;
+@property (nonatomic, strong) NSString *permissions;
+@property (nonatomic, strong) NSString *owner;
+@property (nonatomic, strong) NSString *size;
+@property (nonatomic, strong) NSString *date;
+@property (nonatomic, strong) NSString *time;
+@property (nonatomic, strong) NSString *linkDestination;
+@property (nonatomic, strong) NSString *path;
+@property (nonatomic, strong) NSString *basename;
+@property (readwrite, assign) NSInteger type;
+
+- (void)_setFileTypeFromRaw:(NSString *)rawType;
+
+@end

+ 87 - 0
bootstrapTool/Classes/PackageFile.m

@@ -0,0 +1,87 @@
+
+#import "PackageFile.h"
+
+@implementation PackageFile
+
+- (void)_setFileTypeFromRaw:(NSString *)rawType {
+    
+    _fileType = [PackageFile readableFileTypeForRawMode:rawType];
+    _type = [PackageFile fileTypeForRawMode:rawType];
+    
+    
+}
+
+/*
+ - denotes a regular file
+ d denotes a directory
+ b denotes a block special file
+ c denotes a character special file
+ l denotes a symbolic link
+ p denotes a named pipe
+ s denotes a domain socket
+ */
+
++ (NSString* )readableFileTypeForRawMode:(NSString *)fileTypeChar {
+    
+    NSString *fileType = nil;
+    
+    if ([fileTypeChar isEqualToString:@"-"])
+    { fileType = @"file"; }
+    else if ([fileTypeChar isEqualToString:@"d"])
+    { fileType = @"directory"; }
+    else if ([fileTypeChar isEqualToString:@"b"])
+    { fileType = @"block"; }
+    else if ([fileTypeChar isEqualToString:@"c"])
+    { fileType = @"character"; }
+    else if ([fileTypeChar isEqualToString:@"l"])
+    { fileType = @"link"; }
+    else if ([fileTypeChar isEqualToString:@"p"])
+    { fileType = @"pipe"; }
+    else if ([fileTypeChar isEqualToString:@"s"])
+    { fileType = @"socket"; }
+    
+    return fileType;
+    
+}
+
++ (BSPackageFileType)fileTypeForRawMode:(NSString *)fileTypeChar {
+    
+    BSPackageFileType type = BSPackageFileTypeUnknown;
+    
+    if ([fileTypeChar isEqualToString:@"-"])
+    { type = BSPackageFileTypeFile; }
+    else if ([fileTypeChar isEqualToString:@"d"])
+    { type = BSPackageFileTypeDirectory; }
+    else if ([fileTypeChar isEqualToString:@"b"])
+    { type = BSPackageFileTypeBlock; }
+    else if ([fileTypeChar isEqualToString:@"c"])
+    { type = BSPackageFileTypeCharacter; }
+    else if ([fileTypeChar isEqualToString:@"l"])
+    { type = BSPackageFileTypeLink; }
+    else if ([fileTypeChar isEqualToString:@"p"])
+    { type = BSPackageFileTypePipe; }
+    else if ([fileTypeChar isEqualToString:@"s"])
+    { type = BSPackageFileTypeSocket; }
+    
+    return type;
+    
+}
+
+- (NSString*) description {
+    
+    NSString *orig = [super description];
+    NSMutableDictionary *details = [NSMutableDictionary new];
+    NSArray *props = [self properties];
+    [props enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        
+        NSString *cv = [self valueForKey:obj];
+        if (cv){
+            details[obj] = cv;
+        }
+        
+    }];
+    return [NSString stringWithFormat:@"%@ = %@", orig, details];
+    
+}
+
+@end

+ 44 - 878
bootstrapTool/main.m

@@ -13,28 +13,12 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <getopt.h>
-#import <objc/runtime.h>
-#import <sys/utsname.h>
-
 
+#import <sys/utsname.h>
 
-typedef NS_ENUM(NSInteger, BSPackageFileType)
-{
-    
-    BSPackageFileTypeFile,
-    BSPackageFileTypeDirectory,
-    BSPackageFileTypeBlock,
-    BSPackageFileTypeCharacter,
-    BSPackageFileTypeLink,
-    BSPackageFileTypePipe,
-    BSPackageFileTypeSocket,
-    BSPackageFileTypeUnknown
-    
-};
+#import "HelperClass.h"
 
 
-#define DLog(format, ...) CFShow((__bridge CFStringRef)[NSString stringWithFormat:format, ## __VA_ARGS__]);
-#define FM [NSFileManager defaultManager]
 /*
  
  fileType, @"fileType",octalPermissions, @"octalPermissions", octalUG, @"octalUG", size, @"size", date, @"date", time, @"time", linkDest, @"linkDest", fullPath, @"fullPath",  nil];
@@ -42,858 +26,6 @@ typedef NS_ENUM(NSInteger, BSPackageFileType)
  */
 
 
-@interface NSObject (Additions)
-
--(NSArray *)ivars;
--(NSArray *)properties;
-
-@end
-
-@implementation NSObject (Additions)
-
-- (NSArray *)properties
-{
-    u_int count;
-    objc_property_t* properties = class_copyPropertyList(self.class, &count);
-    NSMutableArray* propArray = [NSMutableArray arrayWithCapacity:count];
-    for (int i = 0; i < count ; i++)
-    {
-        const char* propertyName = property_getName(properties[i]);
-        NSString *propName = [NSString  stringWithCString:propertyName encoding:NSUTF8StringEncoding];
-        [propArray addObject:propName];
-    }
-    free(properties);
-    return propArray;
-}
-
--(NSArray *)ivars
-{
-    Class clazz = [self class];
-    u_int count;
-    Ivar* ivars = class_copyIvarList(clazz, &count);
-    NSMutableArray* ivarArray = [NSMutableArray arrayWithCapacity:count];
-    for (int i = 0; i < count ; i++)
-    {
-        const char* ivarName = ivar_getName(ivars[i]);
-        [ivarArray addObject:[NSString  stringWithCString:ivarName encoding:NSUTF8StringEncoding]];
-    }
-    free(ivars);
-    return ivarArray;
-}
-
-
-@end
-
-
-@interface DebPackageModel : NSObject
-
-@property (nonatomic, copy) NSString *name;
-@property (nonatomic, copy) NSString *package;
-@property (nonatomic, copy) NSString *source;
-@property (nonatomic, copy) NSString *version;
-@property (nonatomic, copy) NSString *priority;
-@property (nonatomic, copy) NSString *essential;
-@property (nonatomic, copy) NSArray *depends;
-@property (nonatomic, copy) NSString *maintainer;
-@property (nonatomic, copy) NSString *packageDescription; //cant be description, that is reservered
-@property (nonatomic, copy) NSString *homepage;
-@property (nonatomic, copy) NSString *author;
-@property (nonatomic, copy) NSString *icon;
-@property (nonatomic, copy) NSString *depiction;
-@property (nonatomic, copy) NSString *preDepends;
-@property (nonatomic, copy) NSString *breaks;
-@property (nonatomic, copy) NSString *status;
-@property (nonatomic, copy) NSString *tag;
-@property (nonatomic, copy) NSString *architecture;
-@property (nonatomic, copy) NSString *section;
-@property (nonatomic, copy) NSString *rawString;
-
-
-- (instancetype)initWithRawControlString:(NSString *)controlString;
-
-
-@end
-@implementation DebPackageModel
-
-- (NSString *)description {
-    
-    NSString *orig = [super description];
-    return [NSString stringWithFormat:@"%@ = %@ (%@)", orig, self.package, self.version];
-}
-
-- (NSString*) fullDescription {
-    
-    NSString *orig = [super description];
-    NSMutableDictionary *details = [NSMutableDictionary new];
-    NSArray *props = [self properties];
-    [props enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
-        
-        NSString *cv = [self valueForKey:obj];
-        if (cv){
-            details[obj] = cv;
-        }
-        
-    }];
-    return [NSString stringWithFormat:@"%@ = %@", orig, details];
-    
-}
-
-+ (NSDictionary *)dependencyDictionaryFromString:(NSString *)depend
-{
-    NSMutableCharacterSet *whitespaceAndPunctuationSet = [NSMutableCharacterSet characterSetWithCharactersInString:@"()"];
-    [whitespaceAndPunctuationSet formUnionWithCharacterSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
-    
-    NSScanner *stringScanner = [[NSScanner alloc] initWithString:depend];
-    stringScanner.charactersToBeSkipped = whitespaceAndPunctuationSet;
-    
-    NSString *name = nil;
-    NSInteger i = 0;
-    NSMutableDictionary *predicate = [NSMutableDictionary new];
-    while ([stringScanner scanUpToCharactersFromSet:whitespaceAndPunctuationSet intoString:&name]) {
-        // NSLog(@"%@ pass %li", name, (long)i);
-        switch (i) {
-            case 0 :
-                predicate[@"package"] = name;
-                break;
-            case 1:
-                predicate[@"predicate"] = name;
-                break;
-            case 2:
-                predicate[@"requirement"] = name;
-                break;
-            default:
-                break;
-        }
-        i++;
-    }
-    return predicate;
-}
-
-
-+ (NSArray *)dependencyArrayFromString:(NSString *)depends
-{
-    NSMutableArray *cleanArray = [[NSMutableArray alloc] init];
-    NSArray *dependsArray = [depends componentsSeparatedByString:@","];
-    for (id depend in dependsArray)
-    {
-        NSArray *spaceDelimitedArray = [depend componentsSeparatedByString:@" "];
-        NSString *isolatedDependency = [[spaceDelimitedArray objectAtIndex:0] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
-        if ([isolatedDependency length] == 0)
-            isolatedDependency = [[spaceDelimitedArray objectAtIndex:1] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
-        
-        NSDictionary *dependDict = [self dependencyDictionaryFromString:depend];
-        //DLog(@"depend dict: %@", dependDict);
-        [cleanArray addObject:dependDict];
-    }
-    
-    return cleanArray;
-}
-
-+ (NSDictionary *)JSONKeyPathsByPropertyKey {
-    return @{
-             @"name": @"Name",
-             @"package": @"Package",
-             @"source": @"Source",
-             @"version": @"Version",
-             @"priority": @"Priority",
-             @"essential": @"Essential",
-             @"depends": @"Depends",
-             @"maintainer": @"Maintainer",
-             @"packageDescription": @"Description",
-             @"homepage": @"Homepage",
-             @"icon": @"Icon",
-             @"author": @"Author",
-             @"preDepends": @"Pre-Depends",
-             @"breaks": @"Breaks",
-             @"depiction": @"Depiction",
-             @"tag": @"Tag",
-             @"architecture": @"Architecture",
-             @"section": @"Section",
-             @"osMax": @"osMax",
-             @"osMin": @"osMin",
-             @"banner": @"Banner",
-             @"topShelfImage": @"TopShelfImage"
-             };
-}
-
-- (instancetype)initWithRawControlString:(NSString *)controlString
-{
-    NSArray *packageArray = [controlString componentsSeparatedByString:@"\n"];
-    NSMutableDictionary *currentPackage = [[NSMutableDictionary alloc] init];
-    for (id currentLine in packageArray)
-    {
-        NSArray *itemArray = [currentLine componentsSeparatedByString:@": "];
-        if ([itemArray count] >= 2)
-        {
-            NSString *key = [itemArray objectAtIndex:0];
-            NSString *object = [itemArray objectAtIndex:1];
-            
-            if ([key isEqualToString:@"Depends"]) //process the array
-            {
-                NSArray *dependsObject = [DebPackageModel dependencyArrayFromString:object];
-                
-                [currentPackage setObject:dependsObject forKey:key];
-                
-            } else { //every other key, even if it has an array is treated as a string
-                
-                [currentPackage setObject:object forKey:key];
-            }
-        }
-    }
-    
-    if ([[currentPackage allKeys] count] > 4)
-    {
-        self = [super init];
-        self.rawString = controlString;
-        [self mapDictionaryToProperties:currentPackage];
-        return self;
-    }
-    return nil;
-    
-    
-}
-
-- (void)mapDictionaryToProperties:(NSDictionary *)theProps {
-    
-    NSArray *ourProps = [self properties];
-    NSArray *allKeys = [theProps allKeys];
-    NSDictionary *mappedKeys = [DebPackageModel JSONKeyPathsByPropertyKey];
-    [ourProps enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
-        
-        NSString *mappedProp = mappedKeys[obj];
-        
-        //DLog(@"allkeys: %@", allKeys);
-        
-        if ([allKeys containsObject:mappedProp]){
-            if ([self respondsToSelector:NSSelectorFromString(obj)]){ //redudant
-                
-                id value = theProps[mappedProp];
-                //DLog(@"setting value: %@ for key: %@ from mapped key: %@", value, obj, mappedProp);
-                [self setValue:value forKey:obj];
-                
-            }
-        } else {
-            
-            //DLog(@"%@ doesnt respond to %@", self, mappedProp);
-            
-        }
-        
-        
-    }];
-    
-}
-
-
-@end
-
-@interface NSString (Additions)
-
-- (void)writeToFileWithoutAttributes:(NSString *)theFile;
-
-
-@end
-
-@implementation NSString (Additions)
-
-- (void)writeToFileWithoutAttributes:(NSString *)theFile {
-    
-    if ([FM fileExistsAtPath:theFile]){
-        
-        DLog(@"overwriting file: %@", theFile);
-    }
-    FILE *fd = fopen([theFile UTF8String], "w+");
-    const char *text = self.UTF8String;
-    fwrite(text, strlen(text) + 1, 1, fd);
-    fclose(fd);
-    
-}
-
-@end
-
-
-
-
-
-@interface PackageFile: NSObject
-
-@property (nonatomic, strong) NSString *fileType;
-@property (nonatomic, strong) NSString *permissions;
-@property (nonatomic, strong) NSString *owner;
-@property (nonatomic, strong) NSString *size;
-@property (nonatomic, strong) NSString *date;
-@property (nonatomic, strong) NSString *time;
-@property (nonatomic, strong) NSString *linkDestination;
-@property (nonatomic, strong) NSString *path;
-@property (nonatomic, strong) NSString *basename;
-@property (readwrite, assign) BSPackageFileType type;
-
-- (void)_setFileTypeFromRaw:(NSString *)rawType;
-
-@end
-
-@implementation PackageFile
-
-- (void)_setFileTypeFromRaw:(NSString *)rawType {
-    
-    _fileType = [PackageFile readableFileTypeForRawMode:rawType];
-    _type = [PackageFile fileTypeForRawMode:rawType];
-    
-    
-}
-
-/*
- - denotes a regular file
- d denotes a directory
- b denotes a block special file
- c denotes a character special file
- l denotes a symbolic link
- p denotes a named pipe
- s denotes a domain socket
- */
-
-+ (NSString* )readableFileTypeForRawMode:(NSString *)fileTypeChar {
-    
-    NSString *fileType = nil;
-    
-    if ([fileTypeChar isEqualToString:@"-"])
-    { fileType = @"file"; }
-    else if ([fileTypeChar isEqualToString:@"d"])
-    { fileType = @"directory"; }
-    else if ([fileTypeChar isEqualToString:@"b"])
-    { fileType = @"block"; }
-    else if ([fileTypeChar isEqualToString:@"c"])
-    { fileType = @"character"; }
-    else if ([fileTypeChar isEqualToString:@"l"])
-    { fileType = @"link"; }
-    else if ([fileTypeChar isEqualToString:@"p"])
-    { fileType = @"pipe"; }
-    else if ([fileTypeChar isEqualToString:@"s"])
-    { fileType = @"socket"; }
-    
-    return fileType;
-    
-}
-
-+ (BSPackageFileType)fileTypeForRawMode:(NSString *)fileTypeChar {
-    
-    BSPackageFileType type = BSPackageFileTypeUnknown;
-    
-    if ([fileTypeChar isEqualToString:@"-"])
-    { type = BSPackageFileTypeFile; }
-    else if ([fileTypeChar isEqualToString:@"d"])
-    { type = BSPackageFileTypeDirectory; }
-    else if ([fileTypeChar isEqualToString:@"b"])
-    { type = BSPackageFileTypeBlock; }
-    else if ([fileTypeChar isEqualToString:@"c"])
-    { type = BSPackageFileTypeCharacter; }
-    else if ([fileTypeChar isEqualToString:@"l"])
-    { type = BSPackageFileTypeLink; }
-    else if ([fileTypeChar isEqualToString:@"p"])
-    { type = BSPackageFileTypePipe; }
-    else if ([fileTypeChar isEqualToString:@"s"])
-    { type = BSPackageFileTypeSocket; }
-    
-    return type;
-    
-}
-
-- (NSString*) description {
-    
-    NSString *orig = [super description];
-    NSMutableDictionary *details = [NSMutableDictionary new];
-    NSArray *props = [self properties];
-    [props enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
-        
-        NSString *cv = [self valueForKey:obj];
-        if (cv){
-            details[obj] = cv;
-        }
-        
-    }];
-    return [NSString stringWithFormat:@"%@ = %@", orig, details];
-    
-}
-
-@end
-
-@interface ErrorReturn: NSObject
-
-@property (nonatomic, strong) NSArray *overwriteFiles;
-@property (readwrite, assign) NSInteger returnStatus;
-
-
-@end
-
-@implementation ErrorReturn
-
-@end
-
-@interface Package: NSObject
-
-@property (nonatomic, strong) NSArray <PackageFile *> *files;
-@property (nonatomic, strong) NSArray  *controlFiles;
-@property (nonatomic, strong) NSString *packageName;
-@property (nonatomic, strong) NSString *version;
-
-- (ErrorReturn *)errorReturnForBootstrap:(NSString *)bootstrapPath;
-- (NSString *)listfile;
-@end
-
-
-@implementation Package
-
-- (NSString*) description {
-    
-    NSString *orig = [super description];
-    NSMutableDictionary *details = [NSMutableDictionary new];
-    NSArray *props = [self properties];
-    [props enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
-        
-        NSString *cv = [self valueForKey:obj];
-        if (cv){
-            details[obj] = cv;
-        }
-        
-    }];
-    return [NSString stringWithFormat:@"%@ = %@", orig, details];
-    
-}
-
-- (NSString *)listfile {
-    
-    __block NSMutableArray *outFiles = [NSMutableArray new];
-    [self.files enumerateObjectsUsingBlock:^(PackageFile * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
-        
-        if ([obj.fileType isEqualToString:@"link"]){ //does this need to handle things differently?
-            [outFiles addObject:obj.path];
-        } else {
-            [outFiles addObject:obj.path];
-        }
-    }];
-    return [outFiles componentsJoinedByString:@"\n"];
-    
-}
-
-- (ErrorReturn *)errorReturnForBootstrap:(NSString *)bootstrapPath
-{
-    NSArray *ignoreFiles = @[@".fauxsu", @".DS_Store"];
-    NSArray *forbiddenRoots = @[@"etc", @"var", @"tmp"];
-    NSFileManager *man = [NSFileManager defaultManager];
-    __block NSInteger returnValue = 0; //0 = good to go 1 = over write warning, 2 = no go
-    __block NSMutableArray *_overwriteArray = [NSMutableArray new];
-    [self.files enumerateObjectsUsingBlock:^(PackageFile * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
-        
-        if ([obj.fileType isEqualToString:@"file"]){
-            
-            NSString *fullPath = [bootstrapPath stringByAppendingPathComponent:obj.path];
-            if ([man fileExistsAtPath:fullPath] && ![ignoreFiles containsObject:obj.basename]){
-                
-                //DLog(@"[WARNING] overwriting a file that already exists and isn't DS_Store or .fauxsu: %@", fullPath);
-                [_overwriteArray addObject:obj.path];
-                //*stop = TRUE;//return FALSE;
-                returnValue = 1;
-            }
-            
-            NSArray *pathComponents = [obj.path pathComponents];
-            if ([pathComponents count] > 1)
-            {
-                NSString *rootPath = [pathComponents objectAtIndex:1];
-                if ([forbiddenRoots containsObject:rootPath])
-                {
-                    DLog(@"\n [ERROR] package file: '%@' would overwrite symbolic link at '%@'! Exiting!\n\n", obj.path, rootPath);
-                    *stop = TRUE;
-                    returnValue = 2;
-                }
-            }
-            
-            
-        }
-        
-        
-    }];
-    
-    ErrorReturn *er = [ErrorReturn new];
-    er.returnStatus = returnValue;
-    er.overwriteFiles = _overwriteArray;
-    
-    return er;
-}
-
-
-@end
-
-@interface HelperClass: NSObject
-
-+ (BOOL)shouldContinueWithError:(NSString *)errorMessage;
-+ (NSArray *)returnForProcess:(NSString *)call;
-+ (Package *)packageForDeb:(NSString *)debFile;
-+ (NSString *)octalFromSymbols:(NSString *)theSymbols;
-
-@end
-
-@implementation HelperClass
-
-+ (NSArray <DebPackageModel*>*)statusInstalledPackagesFromFile:(NSString *)statusFile
-{
-    
-    if (![FM fileExistsAtPath:statusFile]) {
-        return nil;
-    }
-    NSString *packageString = [NSString stringWithContentsOfFile:statusFile encoding:NSUTF8StringEncoding error:nil];
-    NSArray *lineArray = [packageString componentsSeparatedByString:@"\n\n"];
-    //DDLogInfo(@"lineArray: %@", lineArray);
-    NSMutableArray *mutableList = [[NSMutableArray alloc] init];
-    //NSMutableDictionary *mutableDict = [[NSMutableDictionary alloc] init];
-    for (id currentItem in lineArray)
-    {
-        
-        DebPackageModel *debModel = [[DebPackageModel alloc] initWithRawControlString:currentItem];
-        if (debModel != nil)
-            [mutableList addObject:debModel];
-    }
-    
-    NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES
-                                                                    selector:@selector(localizedCaseInsensitiveCompare:)];
-    NSSortDescriptor *packageDescriptor = [[NSSortDescriptor alloc] initWithKey:@"package" ascending:YES
-                                                                       selector:@selector(localizedCaseInsensitiveCompare:)];
-    NSArray *descriptors = [NSArray arrayWithObjects:nameDescriptor, packageDescriptor, nil];
-    NSArray *sortedArray = [mutableList sortedArrayUsingDescriptors:descriptors];
-    
-    
-    mutableList = nil;
-    
-    return sortedArray;
-}
-
-+ (BOOL)shouldContinueWithError:(NSString *)errorMessage {
-    
-    NSString *errorString = [NSString stringWithFormat:@"\n%@ Are you sure you want to continue? [y/n]?", errorMessage];
-    
-    char c;
-    printf("%s", [errorString UTF8String] );
-    c=getchar();
-    while(c!='y' && c!='n')
-    {
-        if (c!='\n'){
-            printf("[y/n]");
-        }
-        c=getchar();
-    }
-    
-    if (c == 'n')
-    {
-        DLog(@"\n smart move... exiting\n\n");
-        return FALSE;
-    } else if (c == 'y') {
-        DLog(@"\n its your funeral....\n\n");
-    }
-    
-    return TRUE;
-    
-}
-
-+ (NSArray *)returnForProcess:(NSString *)call
-{
-    if (call==nil)
-        return 0;
-    char line[200];
-    //DDLogInfo(@"running process: %@", call);
-    FILE* fp = popen([call UTF8String], "r");
-    NSMutableArray *lines = [[NSMutableArray alloc]init];
-    if (fp)
-    {
-        while (fgets(line, sizeof line, fp))
-        {
-            NSString *s = [NSString stringWithCString:line encoding:NSUTF8StringEncoding];
-            s = [s stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
-            [lines addObject:s];
-        }
-    }
-    pclose(fp);
-    return lines;
-}
-
-+ (PackageFile *)packageFileFromLine:(NSString *)inputLine {
-    //    "-rwxr-xr-x  0 root   wheel   69424 Oct 22 03:56 ./Library/MobileSubstrate/DynamicLibraries/beigelist7.dylib\n",
-    
-    //-rwxr-xr-x root/staff    10860 2011-02-02 03:55 ./Library/Frameworks/CydiaSubstrate.framework/Commands/cycc
-    
-    inputLine = [inputLine stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
-    inputLine = [inputLine stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\t"]];
-    NSMutableString *newString = [[NSMutableString alloc] initWithString:inputLine];
-    [newString replaceOccurrencesOfString:@"      " withString:@" " options:NSLiteralSearch range:NSMakeRange(0, [newString length])];
-    [newString replaceOccurrencesOfString:@"     " withString:@" " options:NSLiteralSearch range:NSMakeRange(0, [newString length])];
-    [newString replaceOccurrencesOfString:@"    " withString:@" " options:NSLiteralSearch range:NSMakeRange(0, [newString length])];
-    [newString replaceOccurrencesOfString:@"   " withString:@" " options:NSLiteralSearch range:NSMakeRange(0, [newString length])];
-    [newString replaceOccurrencesOfString:@"  " withString:@" " options:NSLiteralSearch range:NSMakeRange(0, [newString length])];
-    
-    NSArray *lineObjects = [newString componentsSeparatedByString:@" "];
-    
-    //NSLog(@"lineObjects: %@", lineObjects);
-    
-    
-    /*
-     
-     "drwxr-xr-x",
-     "root/wheel",
-     0,
-     "2018-06-27",
-     "01:21",
-     "./"
-     */
-    
-    
-    NSString *permissionsAndType = [lineObjects objectAtIndex:0];
-    NSString *userGroup = [lineObjects objectAtIndex:1];
-    NSString *size = [lineObjects objectAtIndex:2];
-    NSString *date = [lineObjects objectAtIndex:3];
-    NSString *time = [lineObjects objectAtIndex:4];
-    NSString *path = [lineObjects objectAtIndex:5];
-    
-    //@"drwxr-xr-x"
-    NSString *fileTypeChar = [permissionsAndType substringWithRange:NSMakeRange(0, 1)];
-    
-    NSString *octalPermissions = [self octalFromSymbols:permissionsAndType];
-    NSString *octalUG = [self octalFromGroupSymbols:userGroup];
-    NSString *fileName = [path lastPathComponent];
-    //NSString *fullPath = [NSString stringWithFormat:@"/%@", path];
-    NSString *fullPath = [path substringFromIndex:1];
-    
-    PackageFile *pf = [PackageFile new];
-    [pf _setFileTypeFromRaw:fileTypeChar];
-    
-    switch (pf.type) {
-        case BSPackageFileTypeLink:
-        {
-            
-            fullPath = [lineObjects objectAtIndex:7];
-            NSString *linkDest = [NSString stringWithFormat:@"/%@", path];
-            pf.permissions = octalPermissions;
-            pf.owner = octalUG;
-            pf.size = size;
-            pf.time = time;
-            pf.date = date;
-            pf.path = fullPath;
-            pf.basename = fileName;
-            pf.linkDestination = linkDest;
-            
-            return pf;
-        }
-            break;
-            
-        case BSPackageFileTypeDirectory: //return for now
-            
-            //DLog(@"we dont want directory entries do we %@", lineObjects);
-            pf.permissions = octalPermissions;
-            pf.owner = octalUG;
-            pf.size = size;
-            pf.time = time;
-            pf.date = date;
-            pf.path = fullPath;
-            pf.basename = fileName;
-            return pf;
-            break;
-            
-        default:
-            break;
-    }
-    
-    
-    pf.permissions = octalPermissions;
-    pf.owner = octalUG;
-    pf.size = size;
-    pf.time = time;
-    pf.date = date;
-    pf.path = fullPath;
-    pf.basename = fileName;
-    return pf;
-    // return [NSDictionary dictionaryWithObjectsAndKeys:fileType, @"fileType",octalPermissions, @"octalPermissions", octalUG, @"octalUG", size, @"size", date, @"date", time, @"time", fileName, @"fileName", fullPath, @"fullPath",  nil];
-    
-}
-
-
-+ (NSString *)octalFromGroupSymbols:(NSString *)theSymbols
-{
-    NSArray *groupArray = [theSymbols componentsSeparatedByString:@"/"];
-    NSString *user = [groupArray objectAtIndex:0];
-    NSString *group = [groupArray objectAtIndex:1];
-    
-    NSString *octalUser = nil;
-    NSString *octalGroup = nil;
-    //uid=0(root) gid=0(wheel) groups=0(wheel),1(daemon),2(kmem),3(sys),4(tty),5(operator),8(procview),9(procmod),20(staff),29(certusers),80(admin)
-    if ([user isEqualToString:@"root"])
-    {
-        octalUser = @"0";
-    } else if ([user isEqualToString:@"mobile"])
-    {
-        octalUser = @"501";
-    }
-    //obviously more cases!! FIXME:
-    
-    if ([group isEqualToString:@"staff"])
-    {
-        octalGroup = @"20";
-    } else if ([group isEqualToString:@"admin"])
-    {
-        octalGroup = @"80";
-    } else if ([group isEqualToString:@"wheel"])
-    {
-        octalGroup = @"0";
-    } else if ([group isEqualToString:@"daemon"])
-    {
-        octalGroup = @"1";
-    } else if ([group isEqualToString:@"kmem"])
-    {
-        octalGroup = @"2";
-    } else if ([group isEqualToString:@"sys"])
-    {
-        octalGroup = @"3";
-    } else if ([group isEqualToString:@"tty"])
-    {
-        octalGroup = @"4";
-    } else if ([group isEqualToString:@"operator"])
-    {
-        octalGroup = @"5";
-    } else if ([group isEqualToString:@"procview"])
-    {
-        octalGroup = @"8";
-    } else if ([group isEqualToString:@"procmod"])
-    {
-        octalGroup = @"9";
-    } else if ([group isEqualToString:@"certusers"])
-    {
-        octalGroup = @"29";
-    } else
-    {
-        octalGroup = @"501"; //default to mobile
-    }
-    //uid=0(root) gid=0(wheel) groups=0(wheel),1(daemon),2(kmem),3(sys),4(tty),5(operator),8(procview),9(procmod),20(staff),29(certusers),80(admin)
-    return [NSString stringWithFormat:@"%@:%@", octalUser, octalGroup];
-    
-}
-
-
-
-
-
-+ (Package *)packageForDeb:(NSString *)debFile {
-    
-    NSString *packageName = [[self returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -f %@ Package", debFile]] componentsJoinedByString:@"\n"];
-    NSString *packageVersion = [[self returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -f %@ Version", debFile]] componentsJoinedByString:@"\n"];
-    NSArray <PackageFile *> *fileList = [self returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -c %@", debFile]];
-    
-    __block NSMutableArray *finalArray = [NSMutableArray new];
-    
-    [fileList enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
-        
-        PackageFile *file = [self packageFileFromLine:obj];
-        if (file) {
-            //DLog(@"%@", file);
-            [finalArray addObject:file];
-        }
-        
-    }];
-    
-    Package *pkg = [Package new];
-    pkg.files = finalArray;
-    pkg.packageName = packageName;
-    pkg.version = packageVersion;
-    return pkg;
-    
-}
-
-+ (NSString *)octalFromSymbols:(NSString *)theSymbols
-{
-    //NSLog(@"%@ %s", self, _cmd);
-    NSString *U = [theSymbols substringWithRange:NSMakeRange(1, 3)];
-    NSString *G = [theSymbols substringWithRange:NSMakeRange(4, 3)];
-    NSString *O = [theSymbols substringWithRange:NSMakeRange(7, 3)];
-    //NSLog(@"fileTypeChar: %@", fileTypeChar);
-    //NSLog(@"U; %@", U);
-    //NSLog(@"G; %@", G);
-    //NSLog(@"O; %@", O);
-    
-    //USER
-    
-    int sIdBit = 0;
-    
-    int uOctal = 0;
-    
-    const char *uArray = [U cStringUsingEncoding:NSASCIIStringEncoding];
-    int stringLength = [U length];
-    
-    int x;
-    for( x=0; x<stringLength; x++ )
-    {
-        unsigned int aCharacter = uArray[x];
-        if (aCharacter == 'r')
-        {
-            uOctal += 4;
-        } else     if (aCharacter == 'w')
-        {
-            uOctal += 2;
-        } else     if (aCharacter == 'x')
-        {
-            uOctal += 1;
-        } else     if (aCharacter == 's')
-        {
-            sIdBit += 4;
-        }
-    }
-    
-    //GROUP
-    
-    int gOctal = 0;
-    const char *gArray = [G cStringUsingEncoding:NSASCIIStringEncoding];
-    stringLength = [G length];
-    
-    int y;
-    for( y=0; y<stringLength; y++ )
-    {
-        unsigned int aCharacter = gArray[y];
-        if (aCharacter == 'r')
-        {
-            gOctal += 4;
-        } else     if (aCharacter == 'w')
-        {
-            gOctal += 2;
-        } else     if (aCharacter == 'x')
-        {
-            gOctal += 1;
-        } else     if (aCharacter == 's')
-        {
-            gOctal += 2;
-        }
-    }
-    
-    //OTHERS
-    int z;
-    int oOctal = 0;
-    const char *oArray = [O cStringUsingEncoding:NSASCIIStringEncoding];
-    stringLength = [O length];
-    
-    
-    for( z=0; z<stringLength; z++ )
-    {
-        unsigned int aCharacter = oArray[z];
-        if (aCharacter == 'r')
-        {
-            oOctal += 4;
-        } else     if (aCharacter == 'w')
-        {
-            oOctal += 2;
-        } else     if (aCharacter == 'x')
-        {
-            oOctal += 1;
-        }
-    }
-    
-    
-    return [NSString stringWithFormat:@"%i%i%i%i", sIdBit, uOctal, gOctal, oOctal];
-    
-}
-
-@end
 
 #define OPTION_FLAGS "o:f:b:l:d:hc"
 
@@ -903,12 +35,13 @@ char *path;
 
 static struct option longopts[] = {
     { "octal",                     required_argument,      NULL,   'o' },
-    { "file",                      required_argument,      NULL,   'f' },
+    { "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",                 required_argument,      NULL,   'r' },
     { NULL,                        0,                      NULL,    0  }
 };
 
@@ -917,12 +50,12 @@ void cmd_help(){
     printf("Makes various modifications to a raw bootstrap folder\n\n");
     
     printf("  -h, --help\t\t\tprints usage information\n");
-    printf("  -f, --file\t\t\tthe deb package file you with to install\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 you want to delete\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");
 }
 
@@ -940,6 +73,7 @@ int main(int argc, const char * argv[]) {
         NSString *bootstrapPath = nil;
         NSString *bootstrapListPath = nil;
         NSString *deletePackage = nil;
+        NSString *repackage = nil;
         BOOL clean = FALSE;
         while ((flag = getopt_long(argc, argv, OPTION_FLAGS, longopts, NULL)) != -1) {
             switch(flag) {
@@ -967,6 +101,11 @@ int main(int argc, const char * argv[]) {
                     deletePackage = [NSString stringWithUTF8String:optarg];
                     break;
                     
+                case 'r':
+                    
+                    repackage = [NSString stringWithUTF8String:optarg];
+                    break;
+                    
                 case 'c':
                     
                     clean = TRUE;
@@ -977,6 +116,37 @@ int main(int argc, const char * argv[]) {
                     return -1;
                     
             }
+        }
+        
+        if (repackage) {
+            
+            NSString *pwd = [[HelperClass returnForProcess:@"/bin/pwd"] componentsJoinedByString:@"\n"];
+            DLog(@"\nProcessing file: %@\n", repackage);
+            Package *output = [HelperClass packageForDeb:repackage];
+            
+            DLog(@"\nFound package: '%@' at version: '%@'...\n", output.packageName, output.version );
+            
+            NSString *tmpPath = [pwd stringByAppendingPathComponent:output.packageName];
+            NSString *debian = [tmpPath stringByAppendingPathComponent:@"DEBIAN"];
+            [FM createDirectoryAtPath:tmpPath withIntermediateDirectories:TRUE attributes:nil error:nil];
+            DLog(@"\nExtracting package contents for processing...\n");
+            [HelperClass returnForProcess:[NSString stringWithFormat:@"/usr/local/bin/dpkg -x %@ %@", debFile, tmpPath]];
+            [FM 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 *controlPath = [debian stringByAppendingPathComponent:@"control"];
+            
+            NSMutableString *controlFile = [[NSMutableString alloc] initWithContentsOfFile:controlPath encoding:NSUTF8StringEncoding error:nil];
+            
+            [controlFile replaceOccurrencesOfString:@"iphoneos-arm" withString:@"appletvos-arm64" options:NSLiteralSearch range:NSMakeRange(0, [controlFile length])];
+            
+            [controlFile writeToFile:controlPath atomically:TRUE];
+            
+            
+            
+    
+            
         }
         
         //DLog(@"folder: %@ project: %@", folder, project);
@@ -1258,10 +428,6 @@ int main(int argc, const char * argv[]) {
             //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];