Kevin Bradley 6 months ago
parent
commit
16a9a01156

+ 6 - 0
bootstrapTool.xcodeproj/project.pbxproj

@@ -16,6 +16,7 @@
 		325A24C020E83F97001D1BAD /* NSString+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 325A24B420E83EF8001D1BAD /* NSString+Additions.m */; };
 		325A24C120E83FCA001D1BAD /* InputPackageFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 325A24B820E83EF8001D1BAD /* InputPackageFile.m */; };
 		32B2C838236BC8270085F065 /* Universalize.m in Sources */ = {isa = PBXBuildFile; fileRef = 32B2C837236BC8270085F065 /* Universalize.m */; };
+		4C52701C2ACA7ECE0052FCAF /* strrep.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C52701B2ACA7ECE0052FCAF /* strrep.c */; };
 		4C56B59D29E670DD00D47844 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C56B59C29E670DD00D47844 /* main.m */; };
 		4C56B5A129E670F000D47844 /* Universalize.m in Sources */ = {isa = PBXBuildFile; fileRef = 32B2C837236BC8270085F065 /* Universalize.m */; };
 		4CADFF8C2AC0CD4C00218BB8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CADFF8B2AC0CD4C00218BB8 /* main.m */; };
@@ -82,6 +83,8 @@
 		325A24C220E84033001D1BAD /* Defines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Defines.h; path = Classes/Defines.h; sourceTree = "<group>"; };
 		32B2C837236BC8270085F065 /* Universalize.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Universalize.m; sourceTree = "<group>"; };
 		32B2C839236D1BD40085F065 /* Universalize.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Universalize.h; sourceTree = "<group>"; };
+		4C52701A2ACA7ECE0052FCAF /* strrep.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = strrep.h; sourceTree = "<group>"; };
+		4C52701B2ACA7ECE0052FCAF /* strrep.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strrep.c; sourceTree = "<group>"; };
 		4C56B59A29E670DD00D47844 /* universalize */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = universalize; sourceTree = BUILT_PRODUCTS_DIR; };
 		4C56B59C29E670DD00D47844 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
 		4CADFF892AC0CD4C00218BB8 /* chartest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = chartest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -165,6 +168,8 @@
 				325A24B620E83EF8001D1BAD /* InputPackage.m */,
 				325A24B720E83EF8001D1BAD /* InputPackageFile.h */,
 				325A24B820E83EF8001D1BAD /* InputPackageFile.m */,
+				4C52701A2ACA7ECE0052FCAF /* strrep.h */,
+				4C52701B2ACA7ECE0052FCAF /* strrep.c */,
 			);
 			path = Classes;
 			sourceTree = "<group>";
@@ -302,6 +307,7 @@
 				325A24B920E83F09001D1BAD /* HelperClass.m in Sources */,
 				325A24C120E83FCA001D1BAD /* InputPackageFile.m in Sources */,
 				325A24BF20E83F95001D1BAD /* NSObject+Additions.m in Sources */,
+				4C52701C2ACA7ECE0052FCAF /* strrep.c in Sources */,
 				3249302B20E4E29700E99767 /* main.m in Sources */,
 				325A24BE20E83F8C001D1BAD /* StatusPackageModel.m in Sources */,
 			);

+ 2 - 0
bootstrapTool/Classes/Defines.h

@@ -1,4 +1,5 @@
 
+#ifdef __OBJC__
 #import <Foundation/Foundation.h>
 #import "NSObject+Additions.h"
 #import "NSString+Additions.h"
@@ -24,3 +25,4 @@ typedef NS_ENUM(NSInteger, BSPackageFileType)
 
 #define DLog(format, ...) CFShow((__bridge CFStringRef)[NSString stringWithFormat:format, ## __VA_ARGS__]);
 #define FM [NSFileManager defaultManager]
+#endif

+ 1 - 1
bootstrapTool/Classes/HelperClass.h

@@ -16,7 +16,7 @@
 + (int)bumpPackageAtPath:(NSString *)debFile withPrefix:(NSString *)prefix sigChecks:(BOOL)skip excludeFile:(NSString *)excludeFile;
 + (int)repackagePackageAtPath:(NSString *)debFile withPrefix:(NSString *)prefix sigChecks:(BOOL)skip arch:(NSString *)arch excludeFile:(NSString *)excludeFile;
 + (int)cleanBootstrapAtPath:(NSString *)bootstrapPath;
-+ (int)deletePackage:(NSString *)deletePackage inBootstrap:(NSString *)bootstrapPath;
++ (int)deletePackage:(NSString *)deletePackage inBootstrap:(NSString *)bootstrapPath passive:(BOOL)isPassive;
 + (int)createNewBootstrap:(NSString *)bootstrapPath withPackages:(NSString *)packagesFolder;
 + (NSInteger)getNumberFromPrompt:(NSString *)prompt;
 @end

+ 16 - 13
bootstrapTool/Classes/HelperClass.m

@@ -1,6 +1,7 @@
 
 #import "HelperClass.h"
 #import "StatusPackageModel.h"
+#import "OCTotallyLazy.h"
 #if TARGET_OS_IOS || TARGET_OS_TV
 #import "NSTask.h"
 #endif
@@ -51,7 +52,7 @@
     return 0;
 }
 
-+ (int)deletePackage:(NSString *)deletePackage inBootstrap:(NSString *)bootstrapPath {
++ (int)deletePackage:(NSString *)deletePackage inBootstrap:(NSString *)bootstrapPath passive:(BOOL)isPassive {
     DLog(@"deleting package: %@ from bootstrap: %@", deletePackage, bootstrapPath);
     __block NSString *postRmFile = nil;
     NSString *statusFile = [bootstrapPath relativeStatusFilePath];
@@ -102,20 +103,21 @@
         [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);
-            }
-        }];
+        if (!isPassive){
+            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];
+            [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");
@@ -227,6 +229,7 @@
                 debModel.bootstrapPath = bootstrapPath;
             }
             [mutableList addObject:debModel];
+            
         }
     }
     NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES

+ 6 - 2
bootstrapTool/Classes/InputPackage.m

@@ -3,6 +3,7 @@
 #import "HelperClass.h"
 #import "Universalize.h"
 #import "InputPackageFile.h"
+#import "strrep.h"
 
 @implementation InputPackage
 //-rw-r--r--   1 root        wheel        4197184 May  9 19:53 nitotv_3.4.3-63_appletvos-arm64.deb
@@ -364,8 +365,8 @@
             NSString *statusFile = [bootstrapPath relativeStatusFilePath];
             
             [FM copyItemAtPath:statusFile toPath:[statusFile stringByAppendingPathExtension:@"bak"] error:nil];
-            NSString *statusCont = [[NSString stringWithContentsOfFile:statusFile encoding:NSASCIIStringEncoding error:nil] sanitizedControlString];
-            NSMutableString *statusContents = [statusCont mutableCopy];//[[NSMutableString alloc] initWithContentsOfFile:statusFile encoding:NSASCIIStringEncoding error:nil];
+            //NSString *statusCont = [[NSString stringWithContentsOfFile:statusFile encoding:NSASCIIStringEncoding error:nil] sanitizedControlString];
+            NSMutableString *statusContents = [[[[NSString alloc] initWithContentsOfFile:statusFile encoding:NSASCIIStringEncoding error:nil] sanitizedControlString] mutableCopy];
             //[statusContents sanitizedControlString];
             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");
@@ -376,12 +377,15 @@
             } else {
                 DLog(@"Updating status file for new package...\n\n");
                 
+                //add_status_file_entry([statusFile UTF8String], [controlFile UTF8String]);
+                
                 //DLog(@"down here??: -%@-\n", controlFile);
                 [statusContents appendFormat:@"%@\n", controlFile];
                 
                 //DLog(@"\nnew status file: %@\n", statusContents);
                 //[statusContents writeToFileWithoutAttributes:statusFile];
                 [statusContents writeToFile:statusFile atomically:TRUE encoding:NSASCIIStringEncoding error:nil];
+                
             }
         }
     }];

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

@@ -30,12 +30,6 @@
     DLog(@"lastTwo: %@", lastTwo);
     NSArray *filtered = [lastTwo filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self == ''"]];
     DLog(@"filtered: %@", filtered);
-    if (filtered.count == 2){
-        DLog(@"double empty, only need one!");
-        NSMutableArray *_newLines = [lines mutableCopy];
-        //[_newLines removeLastObject];
-        finalString = [_newLines componentsJoinedByString:@"\n"];
-    }
     if (filtered.count <= 1) {
         DLog(@"insufficient empty lines!");
         NSMutableArray *_newLines = [lines mutableCopy];

+ 85 - 0
bootstrapTool/Classes/strrep.c

@@ -0,0 +1,85 @@
+/*
+ * strrep.c
+ *
+ *  Created on: 12 ene. 2020
+ *      Author: ipserc
+ */
+
+#include "strrep.h"
+
+int add_status_file_entry(const char *statusFilePath, const char *entry) {
+    FILE *statusFile = fopen(statusFilePath, "a");
+
+    if (statusFile == NULL) {
+        return -1;
+    }
+    fputs(entry, statusFile);
+    fclose(statusFile);
+    return 0;
+}
+
+/** appendstr (Append String). Appends the string 'append' to the string 'string'.
+ * @param string The string in which append the new text.
+ * @param append The new string to append.
+ * @return returns a new string with the appended text.
+ */
+char * appendstr(char * string, const char * append) {
+    char * newString = malloc(strlen(string) + strlen(append) + 1);
+
+    sprintf(newString, "%s%s", string, append);
+    free(string);
+    return newString;
+}
+
+/**
+ * strtokk (String Tokenizer). Breaks string 'string' into a series of tokens using 'strf' as a WHOLE DELIMITER string.
+ * It works in the same way as strtok, so the 'string' passed as parameter is split in the different parts, breaking the 'string'.
+ * @param string The contents of this string are modified and broken into smaller strings (tokens).
+ * @param strf This is the C string containing the DELIMITER.
+ * @return Returns a pointer to the first token found in the string. A null pointer is returned if there are no tokens left to retrieve.
+ */
+char * strtokk(char * string, const char * strf) {
+    static char * ptr;
+    static char * ptr2;
+
+    if (!*strf) return string;
+    if (string) ptr = string;
+    else {
+        if (!ptr2) return ptr2;
+        ptr = ptr2 + strlen(strf);
+    }
+
+    if (ptr) {
+        ptr2 = strstr(ptr, strf);
+        if (ptr2) memset(ptr2, 0, strlen(strf));
+    }
+    return ptr;
+}
+
+/**
+ * strrep (String Replace). Replaces 'strf' with 'strr' in 'cadena' and returns the new string.
+ * You need to free the returned string in your code after using strrep.
+ * @param cadena The string with the text.
+ * @param strf The text to find.
+ * @param strr The replacement text.
+ * @return The text updated wit the replacement.
+ */
+char * strrep(const char * cadena, const char * strf, const char * strr) {
+    char * string;
+    char * ptr;
+    char * strrep;
+
+    string = (char *)malloc(strlen(cadena) + 1);
+    sprintf(string, "%s", cadena);
+    if (!*strf) return string;
+    ptr = strtokk(string, strf);
+    strrep = malloc(strlen(ptr) + 1);
+    memset(strrep, 0, strlen(ptr) + 1);
+    while (ptr) {
+        strrep = appendstr(strrep, ptr);
+        ptr = strtokk(NULL, strf);
+        if (ptr) strrep = appendstr(strrep, strr);
+    }
+    free(string);
+    return strrep;
+}

+ 22 - 0
bootstrapTool/Classes/strrep.h

@@ -0,0 +1,22 @@
+/*
+ * strrep.h
+ *
+ *  Created on: 12 ene. 2020
+ *      Author: ipserc
+ */
+
+#ifndef SOURCE_STRREP_H_
+#define SOURCE_STRREP_H_
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int add_status_file_entry(const char *statusFilePath, const char *entry);
+char * appendstr(char * string, const char * append);
+char * strtokk(char * string, const char * strf);
+
+char * strrep(const char * string, const char * strf, const char * strr);
+
+
+#endif /* SOURCE_STRREP_H_ */

+ 1 - 1
bootstrapTool/Makefile

@@ -7,7 +7,7 @@ include $(THEOS)/makefiles/common.mk
 
 TOOL_NAME = bootstrapTool
 
-bootstrapTool_FILES = $(wildcard *.m) $(wildcard Classes/*.m)
+bootstrapTool_FILES = $(wildcard *.m) $(wildcard Classes/*.m) $(wildcard Classes/*.c)
 bootstrapTool_CFLAGS = -fobjc-arc -IClasses -include Classes/Defines.h -I../include/OCTotallyLazy -I../include
 bootstrapTool_INSTALL_PATH = /fs/jb/usr/local/bin
 bootstrapTool_LDFLAGS = -framework Foundation -lOCTotallyStatic -L../ios 

+ 9 - 2
bootstrapTool/main.m

@@ -16,7 +16,7 @@
 #import <sys/utsname.h>
 #import "HelperClass.h"
 
-#define OPTION_FLAGS "o:i:ld:hcrbp:su:yn:a:Ce:fL:U"
+#define OPTION_FLAGS "o:i:ld:hcrbp:su:yn:a:Ce:fL:UP"
 
 char *progname;
 char *path;
@@ -41,6 +41,7 @@ static struct option longopts[] = {
     { "force",                     no_argument,            NULL,   'f' },
     { "contents",                  required_argument,      NULL,   'L' },
     { "unpack",                    no_argument,            NULL,   'U' },
+    { "passive",                   no_argument,            NULL,   'P' },
     { NULL,                        0,                      NULL,    0  }
 };
 
@@ -65,6 +66,7 @@ void cmd_help(void){
     printf("  -f, --force\t\t\tforce an install operation, ignoring 'forbidden' roots\n");
     printf("  -L, --contents\t\tlist the contents of an installed package, required a bootstrap path\n");
     printf("  -U, --unpack\t\t\tmark the package as unpacked rather than installed in the status file\n");
+    printf("  -P, --passive\t\t\twhen removing a package, only remove its contents but not its status entry.\n");
     printf("\n");
 }
 
@@ -94,6 +96,7 @@ int main(int argc, char **argv) {
         BOOL create = FALSE;
         BOOL force = FALSE;
         BOOL unpack = FALSE;
+        BOOL passive = FALSE;
         NSString *targetPkg = nil; //for --contents/L flag
         /*
         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/";
@@ -183,6 +186,10 @@ int main(int argc, char **argv) {
                 case 'e':
                     excludeFile = [NSString stringWithUTF8String:optarg];
                     break;
+                
+                case 'P':
+                    passive = TRUE;
+                    break;
                     
                 default:
                     cmd_help();
@@ -244,7 +251,7 @@ int main(int argc, char **argv) {
             return 1;
         }
         if (deletePackage && bootstrapPath) {
-            return [HelperClass deletePackage:deletePackage inBootstrap:bootstrapPath];
+            return [HelperClass deletePackage:deletePackage inBootstrap:bootstrapPath passive:passive];
         } else if (deletePackage) {
             DLog(@"\nYou need to choose a bootstrap path to delete from!\n\n");
             return 1;