diff --git a/Makefile b/Makefile index d3dda1e..a7dece8 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,11 @@ +ifeq ($(THEOS_PACKAGE_SCHEME),rootless) +export TARGET = iphone:clang:14.4:15.0 +export ARCHS = arm64 +TweakSettings_XCODEFLAGS = GCC_PREPROCESSOR_DEFINITIONS='THEOS_PACKAGE_INSTALL_PREFIX=\"$(THEOS_PACKAGE_INSTALL_PREFIX)\"' +else export TARGET = iphone:clang:14.4:10.0 export ARCHS = armv7 arm64 +endif DEBUG = 1 DEBUG_EXT = @@ -14,7 +20,7 @@ include $(THEOS)/makefiles/common.mk LAUNCH_URL = XCODEPROJ_NAME = TweakSettings -TweakSettings_XCODEFLAGS = PACKAGE_VERSION='@\"$(THEOS_PACKAGE_BASE_VERSION)\"' +TweakSettings_XCODEFLAGS += PACKAGE_VERSION='@\"$(THEOS_PACKAGE_BASE_VERSION)\"' TweakSettings_CODESIGN_FLAGS = -SResources/entitlements.plist include $(THEOS_MAKE_PATH)/xcodeproj.mk @@ -27,7 +33,8 @@ after-stage:: $(ECHO_NOTHING)rm -f $(THEOS_STAGING_DIR)/Applications/TweakSettings.app/Localizable.strings$(ECHO_END) $(ECHO_NOTHING)/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${THEOS_PACKAGE_BASE_VERSION}" "${THEOS_STAGING_DIR}/Applications/${XCODEPROJ_NAME}.app/Info.plist"$(ECHO_END) $(ECHO_NOTHING)/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${PACKAGE_VERSION}" "${THEOS_STAGING_DIR}/Applications/${XCODEPROJ_NAME}.app/Info.plist"$(ECHO_END) - @echo "Set bundle version to: ${PACKAGE_VERSION}" + $(ECHO_BEGIN)$(PRINT_FORMAT_MAGENTA) "Set bundle version to: ${PACKAGE_VERSION}"$(ECHO_END) + $(ECHO_BEGIN)$(PRINT_FORMAT_MAGENTA) "Built for $(or $(THEOS_PACKAGE_SCHEME),rootful)"$(ECHO_END) after-install:: - install.exec "killall -9 ${XCODEPROJ_NAME}; uicache -p /Applications/${XCODEPROJ_NAME}.app; uiopen tweaks:$(LAUNCH_URL)" \ No newline at end of file + install.exec "killall -9 ${XCODEPROJ_NAME}; uicache -p $(THEOS_PACKAGE_INSTALL_PREFIX)/Applications/${XCODEPROJ_NAME}.app; uiopen tweaks:$(LAUNCH_URL)" \ No newline at end of file diff --git a/Releases/com.creaturecoding.tweaksettings_1.0.7_iphoneos-arm.deb b/Releases/com.creaturecoding.tweaksettings_1.0.7_iphoneos-arm.deb new file mode 100644 index 0000000..02bfb0c Binary files /dev/null and b/Releases/com.creaturecoding.tweaksettings_1.0.7_iphoneos-arm.deb differ diff --git a/Releases/com.creaturecoding.tweaksettings_1.0.7_iphoneos-arm64.deb b/Releases/com.creaturecoding.tweaksettings_1.0.7_iphoneos-arm64.deb new file mode 100644 index 0000000..af01ff5 Binary files /dev/null and b/Releases/com.creaturecoding.tweaksettings_1.0.7_iphoneos-arm64.deb differ diff --git a/Resources/entitlements.plist b/Resources/entitlements.plist index 240d4e5..6d2068d 100644 --- a/Resources/entitlements.plist +++ b/Resources/entitlements.plist @@ -36,6 +36,28 @@ com.apple.private.security.storage.AppDataContainers + + com.apple.private.MobileContainerManager.allowed + + com.apple.private.MobileContainerManager.otherIdLookup + + com.apple.private.MobileContainerManager.otherIdentifierLookup + + com.apple.private.MobileContainerManager.userManagedAssets + + + com.apple.springboard.opensensitiveurl + + com.apple.springboard.presentPowerDownUI + + + com.apple.frontboard.delete-application-snapshots + + com.apple.frontboard.shutdown + + com.apple.frontboardservices.display-layout-monitor + + com.apple.security.iokit-user-client-class diff --git a/TweakSettings-App/NSTask.h b/TweakSettings-App/NSTask.h new file mode 100644 index 0000000..d4e4551 --- /dev/null +++ b/TweakSettings-App/NSTask.h @@ -0,0 +1,66 @@ +#import + +@class NSString, NSArray, NSDictionary; + +@interface NSTask : NSObject + +// Create an NSTask which can be run at a later time +// An NSTask can only be run once. Subsequent attempts to +// run an NSTask will raise. +// Upon task death a notification will be sent +// { Name = NSTaskDidTerminateNotification; object = task; } +// + +- (_Nullable instancetype)init; + +// set parameters +// these methods can only be done before a launch +// if not set, use current +// if not set, use current + +// set standard I/O channels; may be either an NSFileHandle or an NSPipe +- (void)setStandardInput:(id _Nullable)input; +- (void)setStandardOutput:(id _Nullable)output; +- (void)setStandardError:(id _Nullable)error; + +// get parameters +@property (NS_NONATOMIC_IOSONLY, copy) NSString *_Nullable launchPath; +@property (NS_NONATOMIC_IOSONLY, copy) NSArray *_Nullable arguments; +@property (NS_NONATOMIC_IOSONLY, copy) NSDictionary *_Nullable environment; +@property (NS_NONATOMIC_IOSONLY, copy) NSString *_Nullable currentDirectoryPath; +@property(NS_NONATOMIC_IOSONLY, copy) NSURL *_Nullable currentDirectoryURL; + +// get standard I/O channels; could be either an NSFileHandle or an NSPipe +- (id _Nullable)standardInput; +- (id _Nullable)standardOutput; +- (id _Nullable)standardError; + +// actions +- (void)launch; + +- (void)interrupt; // Not always possible. Sends SIGINT. +- (void)terminate; // Not always possible. Sends SIGTERM. + +@property (NS_NONATOMIC_IOSONLY, readonly) BOOL suspend; +@property (NS_NONATOMIC_IOSONLY, readonly) BOOL resume; + +// status +@property (NS_NONATOMIC_IOSONLY, readonly) int processIdentifier; +@property (NS_NONATOMIC_IOSONLY, getter = isRunning, readonly) BOOL running; + +@property (NS_NONATOMIC_IOSONLY, readonly) int terminationStatus; +@property (copy, nonnull) void (^terminationHandler)(NSTask *_Nonnull); + +@end + +@interface NSTask (NSTaskConveniences) + ++ (NSTask *_Nullable)launchedTaskWithLaunchPath:(NSString *_Nonnull)path arguments:(NSArray *_Nullable)arguments; +// convenience; create and launch + +- (void)waitUntilExit; +// poll the runLoop in defaultMode until task completes + +@end + +FOUNDATION_EXPORT NSString *_Nullable const NSTaskDidTerminateNotification; \ No newline at end of file diff --git a/TweakSettings-App/TS-Prefix.pch b/TweakSettings-App/TS-Prefix.pch index a4b7169..8ccd668 100644 --- a/TweakSettings-App/TS-Prefix.pch +++ b/TweakSettings-App/TS-Prefix.pch @@ -73,19 +73,4 @@ NS_INLINE __unused NSArray *ARRAY_WITH_PLIST(NSString *path) { return ARRAY_WITH_PLIST_OPTIONS(path, NSPropertyListImmutable); } -NS_INLINE __unused int STATUS_FOR_COMMAND(NSString *command) { - FILE *proc = popen(command.UTF8String, "r"); - - if (!proc) {return EXIT_FAILURE;} - - int size = 1024; - char data[size]; - - while (fgets(data, size, proc) != NULL) {} - - int status = pclose(proc); - - return status; -} - #endif /* TS_Prefix_pch */ diff --git a/TweakSettings-App/TSOptionsController.m b/TweakSettings-App/TSOptionsController.m index 59f17f4..309cb32 100644 --- a/TweakSettings-App/TSOptionsController.m +++ b/TweakSettings-App/TSOptionsController.m @@ -90,7 +90,7 @@ - (void)_openLink:(PSSpecifier *)specifier { - (NSArray *)_footerSpecifiers { PSSpecifier *developerGroupSpecifier = [PSSpecifier emptyGroupSpecifier]; - [developerGroupSpecifier setProperty:@"CreatureCoding © 2021" forKey:PSFooterTextGroupKey]; + [developerGroupSpecifier setProperty:@"CreatureCoding © 2023" forKey:PSFooterTextGroupKey]; [developerGroupSpecifier setProperty:@1 forKey:PSFooterAlignmentGroupKey]; PSSpecifier *changelogSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Changelog" target:self set:nil get:nil detail:TSChangelogController.class cell:PSLinkCell edit:nil]; diff --git a/TweakSettings-App/TSPackageUtility.m b/TweakSettings-App/TSPackageUtility.m index 8cde3d9..43bf040 100644 --- a/TweakSettings-App/TSPackageUtility.m +++ b/TweakSettings-App/TSPackageUtility.m @@ -11,6 +11,7 @@ #import "TSPackageUtility.h" #import "libprefs.h" +#import "rootless.h" #pragma mark - LIBPREFS Shim @@ -36,9 +37,9 @@ BOOL PREFERENCE_FILTER_PASSES_ENVIRONMENT_CHECKS(NSDictionary *filter) { if (isBundle) { NSFileManager *fileManger = NSFileManager.defaultManager; if (![fileManger fileExistsAtPath:bundlePath]) - bundlePath = [NSString stringWithFormat:@"/Library/PreferenceBundles/%@.bundle", bundleName]; + bundlePath = [NSString stringWithFormat:ROOT_PATH_NS(@"/Library/PreferenceBundles/%@.bundle"), bundleName]; if (![fileManger fileExistsAtPath:bundlePath]) - bundlePath = [NSString stringWithFormat:@"/System/Library/PreferenceBundles/%@.bundle", bundleName]; + bundlePath = [NSString stringWithFormat:ROOT_PATH_NS(@"/System/Library/PreferenceBundles/%@.bundle"), bundleName]; if (![fileManger fileExistsAtPath:bundlePath]) { return nil; } @@ -91,14 +92,14 @@ @implementation TSPackageUtility { + (NSArray *)loadTweakSpecifiersInController:(PSListController *)controller { NSMutableArray *preferenceSpecifiers = [NSMutableArray new]; - NSArray *preferenceBundlePaths = [NSFileManager.defaultManager subpathsOfDirectoryAtPath:@"/Library/PreferenceLoader/Preferences" error:nil]; + NSArray *preferenceBundlePaths = [NSFileManager.defaultManager subpathsOfDirectoryAtPath:ROOT_PATH_NS(@"/Library/PreferenceLoader/Preferences") error:nil]; NSMutableArray *searchableItems = [NSMutableArray new]; for (NSString *item in preferenceBundlePaths) { if (![item.pathExtension isEqualToString:@"plist"]) continue; - NSString *plistPath = [NSString stringWithFormat:@"/Library/PreferenceLoader/Preferences/%@", item]; + NSString *plistPath = [NSString stringWithFormat:ROOT_PATH_NS(@"/Library/PreferenceLoader/Preferences/%@"), item]; NSDictionary *plist = DICTIONARY_WITH_PLIST(plistPath); if (!plist[@"entry"]) continue; @@ -107,8 +108,8 @@ @implementation TSPackageUtility { NSString *bundlePath = [plistPath stringByDeletingLastPathComponent]; NSString *title = [item.lastPathComponent stringByDeletingPathExtension]; - BOOL customInstall = access("/var/lib/dpkg/info/com.artikus.preferenceloader.list", F_OK) == 0 - || access("/var/lib/dpkg/info/com.creaturecoding.preferred.list", F_OK) == 0; + BOOL customInstall = access(ROOT_PATH("/var/lib/dpkg/info/com.artikus.preferenceloader.list"), F_OK) == 0 + || access(ROOT_PATH("/var/lib/dpkg/info/com.creaturecoding.preferred.list"), F_OK) == 0; NSArray *itemSpecifiers = !customInstall ? SPECIFIERS_FROM_ENTRY(plist[@"entry"], bundlePath, title, controller) @@ -123,7 +124,7 @@ @implementation TSPackageUtility { [specifier setProperty:[UIImage imageNamed:@"tweak"] forKey:PSIconImageKey]; } - CSSearchableItemAttributeSet *attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:(NSString *) kUTTypeImage]; + CSSearchableItemAttributeSet *attributeSet = [[CSSearchableItemAttributeSet alloc] init]; attributeSet.title = specifier.name; attributeSet.contentDescription = [NSString stringWithFormat:@"Tweak Settings \u2192 %@", specifier.name]; attributeSet.thumbnailData = UIImagePNGRepresentation([specifier propertyForKey:PSIconImageKey]); diff --git a/TweakSettings-App/TSUtilityActionManager.h b/TweakSettings-App/TSUtilityActionManager.h index 54c4014..1653a38 100644 --- a/TweakSettings-App/TSUtilityActionManager.h +++ b/TweakSettings-App/TSUtilityActionManager.h @@ -12,6 +12,12 @@ @class UIAlertController; @class UIAlertAction; +struct TaskResult { + int status; + __strong NSString *output; + __strong NSString *error; +}; + extern NSString *const TSActionTypeRespring; extern NSString *const TSActionTypeSafemode; extern NSString *const TSActionTypeUICache; @@ -20,6 +26,7 @@ extern NSString *const TSActionTypeReboot; extern NSString *const TSActionTypeUserspaceReboot; extern NSString *const TSActionTypeTweakInject; +extern struct TaskResult ExecuteCommand(NSString *command); extern NSString *TitleForActionType(NSString *type); extern NSString *SubtitleForActionType(NSString *type); extern BOOL CanRunWithoutConfirmation(NSString *actionType); @@ -27,5 +34,6 @@ extern int HandleActionForType(NSString *actionType); extern UIAlertController *ActionAlertForType(NSString *actionType); extern UIAlertController *ActionListAlert(void); extern UIMenu *ActionListMenu(void) API_AVAILABLE(ios(13.0)); +extern NSString *CommandForActionType(NSString *actionType); #endif /* TSActionType_h */ diff --git a/TweakSettings-App/TSUtilityActionManager.m b/TweakSettings-App/TSUtilityActionManager.m index 7ba3c5d..b2cf39b 100644 --- a/TweakSettings-App/TSUtilityActionManager.m +++ b/TweakSettings-App/TSUtilityActionManager.m @@ -10,6 +10,8 @@ #import "TSUtilityActionManager.h" #import "Localizable.h" #import "TSAppDelegate.h" +#import "rootless.h" +#import "NSTask.h" NSString *const TSActionTypeRespring = @"respring"; NSString *const TSActionTypeSafemode = @"safemode"; @@ -19,6 +21,50 @@ NSString *const TSActionTypeUserspaceReboot = @"usreboot"; NSString *const TSActionTypeTweakInject = @"tweakinject"; +struct TaskResult ExecuteCommand(NSString *command) { + NSTask *task = [[NSTask alloc] init]; + [task setLaunchPath:ROOT_PATH_NS(@"/bin/sh")]; + [task setArguments:@[@"-c", command]]; + + NSPipe *outputPipe = [NSPipe pipe]; + [task setStandardOutput:outputPipe]; + + NSPipe *errorPipe = [NSPipe pipe]; + [task setStandardError:errorPipe]; + + [task launch]; + [task waitUntilExit]; + + NSData *errorData; + NSData *outputData; + NSString *output; + NSString *error; + + if (@available(iOS 13.0, *)) { + outputData = [[[task standardOutput] fileHandleForReading] readDataToEndOfFileAndReturnError:nil]; + errorData = [[[task standardError] fileHandleForReading] readDataToEndOfFileAndReturnError:nil]; + } else { + outputData = [[[task standardOutput] fileHandleForReading] readDataToEndOfFile]; + errorData = [[[task standardError] fileHandleForReading] readDataToEndOfFile]; + } + + if (outputData && outputData.length > 0) { + output = [[NSString alloc] initWithData:outputData encoding:NSASCIIStringEncoding]; + } + + if (errorData && errorData.length > 0) { + error = [[NSString alloc] initWithData:errorData encoding:NSASCIIStringEncoding]; + NSLog(@"TweakSettings: TASK INPUT: %@ ERROR: %@, STATUS: %d", task.arguments.lastObject, error, task.terminationStatus); + } + + struct TaskResult result; + result.status = task.terminationStatus; + result.output = output; + result.error = error; + + return result; +} + NSString *TitleForActionType(NSString *type) { if ([type isEqualToString:TSActionTypeRespring]) return NSLocalizedString(RESPRING_TITLE_KEY, nil); if ([type isEqualToString:TSActionTypeSafemode]) return NSLocalizedString(SAFEMODE_TITLE_KEY, nil); @@ -53,16 +99,7 @@ int HandleActionForType(NSString *actionType) { if (!actionType || !actionType.length) return EXIT_FAILURE; - int status = STATUS_FOR_COMMAND([NSString stringWithFormat:@"/usr/bin/tweaksettings-utility --%@", actionType]); - if (status == EXIT_SUCCESS && [actionType isEqualToString:TSActionTypeTweakInject]) { - if (access("/etc/rc.d/substrate", F_OK) == 0) { - if (STATUS_FOR_COMMAND(@"/usr/bin/tweaksettings-utility --substrated") == EXIT_SUCCESS) { - STATUS_FOR_COMMAND(@"/usr/bin/tweaksettings-utility --respring"); - } - } else { - STATUS_FOR_COMMAND(@"/usr/bin/tweaksettings-utility --respring"); - } - } + int status = ExecuteCommand(CommandForActionType(actionType)).status; return status; } @@ -83,7 +120,7 @@ int HandleActionForType(NSString *actionType) { UIAlertController *ActionListAlert(void) { - BOOL userspace_supported = access("/odyssey/jailbreakd.plist", F_OK) == 0 || access("/taurine/jailbreakd.plist", F_OK) == 0; + BOOL userspace_supported = access(ROOT_PATH("/odyssey/jailbreakd.plist"), F_OK) == 0 || access(ROOT_PATH("/taurine/jailbreakd.plist"), F_OK) == 0; UIAlertController *controller = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; [controller addAction:[UIAlertAction actionWithTitle:NSLocalizedString(RESPRING_TITLE_KEY, nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { @@ -117,7 +154,10 @@ int HandleActionForType(NSString *actionType) { UIMenu *ActionListMenu(void) API_AVAILABLE(ios(13.0)) { NSMutableArray *menuActions = [NSMutableArray new]; - BOOL userspace_supported = access("/odyssey/jailbreakd.plist", F_OK) == 0 || access("/taurine/jailbreakd.plist", F_OK) == 0; + BOOL userspace_supported = + access(ROOT_PATH("/odyssey/jailbreakd.plist"), F_OK) == 0 || + access(ROOT_PATH("/taurine/jailbreakd.plist"), F_OK) == 0 || + access(ROOT_PATH("/.installed_dopamine"), F_OK) == 0; [menuActions addObject:[UIAction actionWithTitle:NSLocalizedString(RESPRING_TITLE_KEY, nil) image:nil identifier:nil handler:^(__kindof UIAction *action) { [APP_DELEGATE handleActionForType:TSActionTypeRespring]; @@ -144,4 +184,8 @@ int HandleActionForType(NSString *actionType) { }]]; return [UIMenu menuWithTitle:@"" children:menuActions]; +} + +NSString *CommandForActionType(NSString *actionType) { + return [NSString stringWithFormat:ROOT_PATH_NS(@"/usr/bin/tweaksettings-utility --%@"), actionType]; } \ No newline at end of file diff --git a/TweakSettings-App/main.m b/TweakSettings-App/main.m index f6a8030..1459d79 100644 --- a/TweakSettings-App/main.m +++ b/TweakSettings-App/main.m @@ -10,6 +10,7 @@ #import #import "TSAppDelegate.h" +#import "rootless.h" int main(int argc, char *argv[]) { @@ -21,10 +22,10 @@ int main(int argc, char *argv[]) { // Setup code that might create autoreleased objects goes here. appDelegateClassName = NSStringFromClass([TSAppDelegate class]); - NSArray *librariesToLoad = ARRAY_WITH_PLIST(@"/Applications/TweakSettings.app/libraries.plist"); + NSArray *librariesToLoad = ARRAY_WITH_PLIST(ROOT_PATH_NS(@"/Applications/TweakSettings.app/libraries.plist")); for (NSString *path in librariesToLoad) { - dlopen(path.UTF8String, RTLD_NOW); + dlopen(ROOT_PATH_NS_VAR(path).UTF8String, RTLD_NOW); } } diff --git a/TweakSettings-App/rootless.h b/TweakSettings-App/rootless.h new file mode 100644 index 0000000..30733f2 --- /dev/null +++ b/TweakSettings-App/rootless.h @@ -0,0 +1,11 @@ +#ifdef THEOS_PACKAGE_INSTALL_PREFIX +#define ROOT_PATH(cPath) THEOS_PACKAGE_INSTALL_PREFIX cPath +#define ROOT_PATH_NS(path) @THEOS_PACKAGE_INSTALL_PREFIX path +#define ROOT_PATH_NS_VAR(path) [@THEOS_PACKAGE_INSTALL_PREFIX stringByAppendingPathComponent:path] +#define ROOT_PATH_VAR(cPath) ROOT_PATH_NS_VAR(@cPath).fileSystemRepresentation +#else +#define ROOT_PATH(cPath) cPath +#define ROOT_PATH_NS(path) path +#define ROOT_PATH_NS_VAR(path) path +#define ROOT_PATH_VAR(cPath) cPath +#endif diff --git a/TweakSettings-Utility/Makefile b/TweakSettings-Utility/Makefile index a1acc80..2f51e48 100644 --- a/TweakSettings-Utility/Makefile +++ b/TweakSettings-Utility/Makefile @@ -1,9 +1,12 @@ include $(THEOS)/makefiles/common.mk -PREFIX = $(THEOS)/toolchains/xcode11.xctoolchain/usr/bin/ TOOL_NAME = tweaksettings-utility tweaksettings-utility_FILES = main.c +tweaksettings-utility_CFLAGS = -fobjc-arc TARGET_CODESIGN_FLAGS = "-Sentitlements.plist" -include $(THEOS_MAKE_PATH)/tool.mk \ No newline at end of file +include $(THEOS_MAKE_PATH)/tool.mk + +before-package:: + chmod +s $(THEOS_STAGING_DIR)/usr/bin/tweaksettings-utility \ No newline at end of file diff --git a/TweakSettings-Utility/main.c b/TweakSettings-Utility/main.c index 6e8afdd..4cdd6d7 100644 --- a/TweakSettings-Utility/main.c +++ b/TweakSettings-Utility/main.c @@ -6,6 +6,9 @@ #include #include +#import "rootless.h" +#include + int proc_pidpath(pid_t pid, void *buffer, uint32_t buffersize); typedef enum { @@ -66,11 +69,30 @@ int status_for_cmd(const char *cmd) { return pclose(proc); } +int check_fork(pid_t pid) { + if (pid != 0) { + printf("tweaksettings-utility fork error (%s) (%d),\n", strerror(errno), errno); + } + + return pid; +} + +int wait_pid(pid_t pid) { + int wait; + int status; + if ((wait = waitpid (pid, &status, 0)) == -1) + printf("tweaksettings-utility wait error (%s) (%d),\n", strerror(errno), errno); + if (wait == pid) { + return 0; + } + return -1; +} + int main(int argc, char **argv, char **envp) { // check that TweakSettings.app exists struct stat correct; - if (lstat("/Applications/TweakSettings.app/TweakSettings", &correct) == -1){ + if (lstat(ROOT_PATH("/Applications/TweakSettings.app/TweakSettings"), &correct) == -1){ printf("tweaksettings-utility can only be used by TweakSettings.app,\n"); return EX_NOPERM; } @@ -82,7 +104,7 @@ int main(int argc, char **argv, char **envp) { char buffer[(1024)] = {0}; int pidpath = proc_pidpath(parent, buffer, sizeof(buffer)); if (pidpath > 0){ - if (strcmp(buffer, "/Applications/TweakSettings.app/TweakSettings") == 0){ + if (strcmp(buffer, ROOT_PATH("/Applications/TweakSettings.app/TweakSettings")) == 0){ tweaksettings = true; } } @@ -138,43 +160,72 @@ int main(int argc, char **argv, char **envp) { print_usage(); } break; case TSUtilityActionTypeRespring: { - execlp("/usr/bin/killall", "killall", "backboardd", NULL); + status = execl(ROOT_PATH("/usr/bin/killall"), "killall", "backboardd", NULL); } break; case TSUtilityActionTypeSafemode: { - execlp("/usr/bin/killall", "killall", "-SEGV", "SpringBoard", NULL); + status = execl(ROOT_PATH("/usr/bin/killall"), "killall", "-SEGV", "SpringBoard", NULL); } break; case TSUtilityActionTypeUICache: { - execlp("/usr/bin/uicache", "uicache", NULL); + status = execl(ROOT_PATH("/usr/bin/uicache"), "uicache", NULL); } break; case TSUtilityActionTypeReboot: { - execlp("/usr/sbin/reboot", "reboot", NULL); + status = execl(ROOT_PATH("/usr/sbin/reboot"), "reboot", NULL); } break; case TSUtilityActionTypeLDRestart: { - execlp("/usr/bin/ldrestart", "ldrestart", NULL); + status = execl(ROOT_PATH("/usr/bin/ldrestart"), "ldrestart", NULL); } break; case TSUtilityActionTypeUSReboot: { - status = status_for_cmd("/usr/bin/launchctl reboot userspace"); + status = execl(ROOT_PATH("/usr/bin/launchctl"), "launchctl", "reboot", "userspace", NULL); } break; case TSUtilityActionTypeTweakinject: { + if (access("/var/jb/.installed_dopamine", F_OK) == 0) { + pid_t cpid = fork(); + if (cpid == 0) { + status = access("/var/jb/basebin/.safe_mode", F_OK) == 0 + ? execl(ROOT_PATH("/bin/rm"), "rm", "-f", "/var/jb/basebin/.safe_mode", NULL) + : execl(ROOT_PATH("/bin/touch"), "touch", "/var/jb/basebin/.safe_mode", NULL); + } + + if (wait_pid(cpid) == 0) { + status = execl(ROOT_PATH("/usr/bin/launchctl"), "launchctl", "reboot", "userspace", NULL); + } + } else if (access(ROOT_PATH("/usr/lib/TweakInject.dylib"), F_OK) == 0) { + pid_t cpid = fork(); + + if (cpid == 0) { + status = access(ROOT_PATH("/.disable_tweakinject"), F_OK) == 0 + ? execl(ROOT_PATH("/bin/rm"), "rm", "-f", ROOT_PATH("/.disable_tweakinject"), NULL) + : execl(ROOT_PATH("/bin/touch"), "touch", ROOT_PATH("/.disable_tweakinject"), NULL); + } + + if (wait_pid(cpid) == 0) { + status = execl(ROOT_PATH("/usr/bin/killall"), "killall", "backboardd", NULL); + } + } else { + pid_t cpid = fork(); - if (access("/usr/lib/TweakInject.dylib", F_OK) == 0) { + if (cpid == 0) { + status = access(ROOT_PATH("/var/tmp/.substrated_disable_loader"), F_OK) == 0 + ? execl(ROOT_PATH("/bin/rm"), "rm", "-f", ROOT_PATH("/var/tmp/.substrated_disable_loader"), NULL) + : execl(ROOT_PATH("/bin/touch"), "touch", ROOT_PATH("/var/tmp/.substrated_disable_loader"), NULL); + } - if (access("/.disable_tweakinject", F_OK) == 0) { - execlp("/bin/rm", "rm", "-f", "/.disable_tweakinject", NULL); - } else { - execlp("/bin/touch", "touch", "/.disable_tweakinject", NULL); - } - } else { - if (access("/var/tmp/.substrated_disable_loader", F_OK) == 0) { - execlp("/bin/rm", "rm", "-f", "/var/tmp/.substrated_disable_loader", NULL); - } else { - execlp("/bin/touch", "touch", "/var/tmp/.substrated_disable_loader", NULL); - } + if (wait_pid(cpid) == 0) { + cpid = fork(); + + if (cpid == 0) { + status = execl(ROOT_PATH("/etc/rc.d/substrate"), "substrate", NULL); + } + + if (wait_pid(cpid) == 0) { + status = execl(ROOT_PATH("/usr/bin/killall"), "killall", "backboardd", NULL); + } + } } } break; case TSUtilityActionTypeSubstrated: { if (access("/etc/rc.d/substrate", F_OK) == 0) { - execlp("/etc/rc.d/substrate", "substrate", NULL); + execl("/etc/rc.d/substrate", "substrate", NULL); } } break; } diff --git a/TweakSettings.xcodeproj/project.pbxproj b/TweakSettings.xcodeproj/project.pbxproj index 03c0368..dced1ec 100644 --- a/TweakSettings.xcodeproj/project.pbxproj +++ b/TweakSettings.xcodeproj/project.pbxproj @@ -22,9 +22,9 @@ 9B241E2F90DD7CBD64A43B51 /* TSSearchableListController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B241E51979762427B0DEF19 /* TSSearchableListController.m */; }; 9B241FBC80A9F03FB421F1D3 /* TSOptionsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B241D3DD023C428A7AD45EF /* TSOptionsController.m */; }; 9B241FDA50F976918DC53162 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9B241DE01047656B78369A94 /* LaunchScreen.storyboard */; }; + B80B985A2A06E70E00C440EB /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B871CDB5265991710058F1C2 /* Localizable.strings */; }; B86FC5D626645DE60011E4AF /* Preferences.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B871CD462651D3680058F1C2 /* Preferences.framework */; }; B871CDA0265601110058F1C2 /* icon_large.png in Resources */ = {isa = PBXBuildFile; fileRef = B871CD9F265601110058F1C2 /* icon_large.png */; }; - B871CDBA26599BFD0058F1C2 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B871CDB5265991710058F1C2 /* Localizable.strings */; }; B8917F68267590B700A9DA57 /* CoreSpotlight.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B8917F67267590B700A9DA57 /* CoreSpotlight.framework */; }; B8917F6A2675944E00A9DA57 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B8917F692675944E00A9DA57 /* CoreServices.framework */; }; /* End PBXBuildFile section */ @@ -34,6 +34,7 @@ 9B241145674E6322664B2C03 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 9B2411C5CDD06E84A912DF3A /* libprefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libprefs.h; sourceTree = ""; }; 9B24127C70ECB51EAE77F9EE /* TSPackageUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSPackageUtility.h; sourceTree = ""; }; + 9B2412872ABBBB036129F433 /* build.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = build.sh; sourceTree = ""; }; 9B2413E3DE3004D22E25AAFB /* TSRootListController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSRootListController.m; sourceTree = ""; }; 9B2413E6B518A0A99C895507 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 9B24142E08BDFAEE4F8373EF /* TSChangelogController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSChangelogController.h; sourceTree = ""; }; @@ -44,9 +45,11 @@ 9B24169943CD9A7E1AA8E2FE /* TSAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TSAppDelegate.h; sourceTree = ""; }; 9B2416D9FECD758BFA318498 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.info; path = Info.plist; sourceTree = ""; }; 9B24181BB83D9773FE8446BB /* TSPrefsRootController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSPrefsRootController.h; sourceTree = ""; }; + 9B241824397C45F85F933DC1 /* rootless.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rootless.h; sourceTree = ""; }; 9B24192FDF28BB2496BBEA7B /* TSUserDefaults.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSUserDefaults.m; sourceTree = ""; }; 9B2419707513EEC97C39BA0C /* TSSplitViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSSplitViewController.m; sourceTree = ""; }; 9B2419CD47CC813402F66384 /* Localizable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Localizable.h; sourceTree = ""; }; + 9B241A100BBAE284CD214164 /* NSTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSTask.h; sourceTree = ""; }; 9B241B6A5EF71185ECED8986 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 9B241B6FA0ACC48629D31472 /* TSUtilityActionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSUtilityActionManager.h; sourceTree = ""; }; 9B241BDCA3396202FEB00F19 /* TSRootListController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSRootListController.h; sourceTree = ""; }; @@ -99,6 +102,7 @@ 9B241880696EB372AB810EDA /* Products */, 9B2416070FA2791AF62D5143 /* TweakSettings-App */, B86FC5D226645DC50011E4AF /* Frameworks */, + 9B2412872ABBBB036129F433 /* build.sh */, ); sourceTree = ""; }; @@ -136,6 +140,8 @@ 9B241649FFFF894DC1194290 /* TSUtilityActionManager.m */, 9B241C07A10B2F57EE3E6BDE /* TSChangelogController.m */, 9B24142E08BDFAEE4F8373EF /* TSChangelogController.h */, + 9B241824397C45F85F933DC1 /* rootless.h */, + 9B241A100BBAE284CD214164 /* NSTask.h */, ); path = "TweakSettings-App"; sourceTree = ""; @@ -259,7 +265,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - B871CDBA26599BFD0058F1C2 /* Localizable.strings in Resources */, + B80B985A2A06E70E00C440EB /* Localizable.strings in Resources */, B871CDA0265601110058F1C2 /* icon_large.png in Resources */, 9B2417125AF333AF7433AE3F /* Assets.xcassets in Resources */, 9B241FDA50F976918DC53162 /* LaunchScreen.storyboard in Resources */, diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..dc96f60 --- /dev/null +++ b/build.sh @@ -0,0 +1,15 @@ +#/bin/sh + +sudo xcode-select -switch /Applications/Xcode-11.7.0.app/Contents/Developer +xcode-select --print-path +# export PREFIX=$THEOS/toolchains/Xcode11.xctoolchain/usr/bin/ + +make clean +make package FINALPACKAGE=1 + +# export -n PREFIX +sudo xcode-select -switch /Applications/Xcode-12.5.0.app/Contents/Developer +xcode-select --print-path + +make clean +make package FINALPACKAGE=1 THEOS_PACKAGE_SCHEME=rootless \ No newline at end of file diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index cf9cc6f..d1478e3 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,7 +1,7 @@ Package: com.creaturecoding.tweaksettings Name: TweakSettings Depends: firmware (>= 10.0), preferenceloader | com.creaturecoding.preferred -Version: 1.0.6 +Version: 1.0.7 Priority: optional Architecture: iphoneos-arm Description: Dedicated settings app for tweaks diff --git a/layout/DEBIAN/postinst b/layout/DEBIAN/postinst index 87a669e..e5256fd 100755 --- a/layout/DEBIAN/postinst +++ b/layout/DEBIAN/postinst @@ -1,12 +1,35 @@ #!/bin/sh -chown root:wheel /usr/bin/tweaksettings-utility -chmod 0777 /usr/bin/tweaksettings-utility -chmod +s /usr/bin/tweaksettings-utility +UTILITY=/usr/bin/tweaksettings-utility +# if tweaksettings-utility doesnt exist, try the rootless path +if [ ! -f "$UTILITY" ]; then + UTILITY=/var/jb$UTILITY +fi -chown root:wheel /Applications/TweakSettings.app/TweakSettings -chmod 0755 /Applications/TweakSettings.app/TweakSettings +if [ -f "$UTILITY" ]; then + chown root:wheel $UTILITY + chmod 0777 $UTILITY + chmod +s $UTILITY + echo "set $UTILITY permissions" +fi -uicache -p /Applications/TweakSettings.app +APP=/Applications/TweakSettings.app/TweakSettings +# if TweakSettings.app doesnt exist, try the rootless path +if [ ! -f "$APP" ]; then + APP=/var/jb$APP +fi + +if [ -f "$APP" ]; then + chown root:wheel $APP + chmod 0755 $APP + echo "set $APP permissions" +fi + +APP_FOLDER=${APP%/*} + +if [ -f "$APP_FOLDER" ]; then + uicache -p APP_FOLDER + echo $APP_FOLDER +fi exit 0;