summaryrefslogtreecommitdiff
path: root/data/uikittools/1_uicache.diff
diff options
context:
space:
mode:
Diffstat (limited to 'data/uikittools/1_uicache.diff')
-rw-r--r--data/uikittools/1_uicache.diff1170
1 files changed, 0 insertions, 1170 deletions
diff --git a/data/uikittools/1_uicache.diff b/data/uikittools/1_uicache.diff
deleted file mode 100644
index 8a01dd2e3..000000000
--- a/data/uikittools/1_uicache.diff
+++ /dev/null
@@ -1,1170 +0,0 @@
-diff -urN uikittools/sbreload.c uikittools+uicache/sbreload.c
---- uikittools/sbreload.c 2018-10-04 15:58:42.000000000 -1000
-+++ uikittools+uicache/sbreload.c 1969-12-31 14:00:00.000000000 -1000
-@@ -1,270 +0,0 @@
--/* UIKit Tools - command-line utilities for UIKit
-- * Copyright (C) 2008-2012 Jay Freeman (saurik)
--*/
--
--/* Modified BSD License {{{ */
--/*
-- * Redistribution and use in source and binary
-- * forms, with or without modification, are permitted
-- * provided that the following conditions are met:
-- *
-- * 1. Redistributions of source code must retain the
-- * above copyright notice, this list of conditions
-- * and the following disclaimer.
-- * 2. Redistributions in binary form must reproduce the
-- * above copyright notice, this list of conditions
-- * and the following disclaimer in the documentation
-- * and/or other materials provided with the
-- * distribution.
-- * 3. The name of the author may not be used to endorse
-- * or promote products derived from this software
-- * without specific prior written permission.
-- *
-- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
-- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
-- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
-- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--*/
--/* }}} */
--
--#include <launch.h>
--#include <notify.h>
--
--#include <stdio.h>
--#include <unistd.h>
--
--#include <CoreFoundation/CoreFoundation.h>
--
--/* Set platform binary flag */
--#define FLAG_PLATFORMIZE (1 << 1)
--#include <dlfcn.h>
--
--void platformizeme() {
-- void* handle = dlopen("/usr/lib/libjailbreak.dylib", RTLD_LAZY);
-- if (!handle) return;
--
-- // Reset errors
-- dlerror();
-- typedef void (*fix_entitle_prt_t)(pid_t pid, uint32_t what);
-- fix_entitle_prt_t ptr = (fix_entitle_prt_t)dlsym(handle, "jb_oneshot_entitle_now");
--
-- const char *dlsym_error = dlerror();
-- if (dlsym_error) {
-- return;
-- }
--
-- ptr(getpid(), FLAG_PLATFORMIZE);
--}
--
--launch_data_t
--CF2launch_data(CFTypeRef cfr);
--
--void
--myCFDictionaryApplyFunction(const void *key, const void *value, void *context)
--{
-- launch_data_t ik, iw, where = context;
--
-- ik = CF2launch_data(key);
-- iw = CF2launch_data(value);
--
-- launch_data_dict_insert(where, iw, launch_data_get_string(ik));
-- launch_data_free(ik);
--}
--
--launch_data_t
--CF2launch_data(CFTypeRef cfr)
--{
-- launch_data_t r;
-- CFTypeID cft = CFGetTypeID(cfr);
--
-- if (cft == CFStringGetTypeID()) {
-- char buf[4096];
-- CFStringGetCString(cfr, buf, sizeof(buf), kCFStringEncodingUTF8);
-- r = launch_data_alloc(LAUNCH_DATA_STRING);
-- launch_data_set_string(r, buf);
-- } else if (cft == CFBooleanGetTypeID()) {
-- r = launch_data_alloc(LAUNCH_DATA_BOOL);
-- launch_data_set_bool(r, CFBooleanGetValue(cfr));
-- } else if (cft == CFArrayGetTypeID()) {
-- CFIndex i, ac = CFArrayGetCount(cfr);
-- r = launch_data_alloc(LAUNCH_DATA_ARRAY);
-- for (i = 0; i < ac; i++) {
-- CFTypeRef v = CFArrayGetValueAtIndex(cfr, i);
-- if (v) {
-- launch_data_t iv = CF2launch_data(v);
-- launch_data_array_set_index(r, iv, i);
-- }
-- }
-- } else if (cft == CFDictionaryGetTypeID()) {
-- r = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
-- CFDictionaryApplyFunction(cfr, myCFDictionaryApplyFunction, r);
-- } else if (cft == CFDataGetTypeID()) {
-- r = launch_data_alloc(LAUNCH_DATA_ARRAY);
-- launch_data_set_opaque(r, CFDataGetBytePtr(cfr), CFDataGetLength(cfr));
-- } else if (cft == CFNumberGetTypeID()) {
-- long long n;
-- double d;
-- CFNumberType cfnt = CFNumberGetType(cfr);
-- switch (cfnt) {
-- case kCFNumberSInt8Type:
-- case kCFNumberSInt16Type:
-- case kCFNumberSInt32Type:
-- case kCFNumberSInt64Type:
-- case kCFNumberCharType:
-- case kCFNumberShortType:
-- case kCFNumberIntType:
-- case kCFNumberLongType:
-- case kCFNumberLongLongType:
-- CFNumberGetValue(cfr, kCFNumberLongLongType, &n);
-- r = launch_data_alloc(LAUNCH_DATA_INTEGER);
-- launch_data_set_integer(r, n);
-- break;
-- case kCFNumberFloat32Type:
-- case kCFNumberFloat64Type:
-- case kCFNumberFloatType:
-- case kCFNumberDoubleType:
-- CFNumberGetValue(cfr, kCFNumberDoubleType, &d);
-- r = launch_data_alloc(LAUNCH_DATA_REAL);
-- launch_data_set_real(r, d);
-- break;
-- default:
-- r = NULL;
-- break;
-- }
-- } else {
-- r = NULL;
-- }
-- return r;
--}
--
--CFPropertyListRef
--CreateMyPropertyListFromFile(const char *posixfile)
--{
-- CFPropertyListRef propertyList;
-- CFStringRef errorString;
-- CFDataRef resourceData;
-- SInt32 errorCode;
-- CFURLRef fileURL;
--
-- fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)posixfile, strlen(posixfile), false);
-- if (!fileURL) {
-- fprintf(stderr, "%s: CFURLCreateFromFileSystemRepresentation(%s) failed\n", getprogname(), posixfile);
-- }
-- if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, fileURL, &resourceData, NULL, NULL, &errorCode)) {
-- fprintf(stderr, "%s: CFURLCreateDataAndPropertiesFromResource(%s) failed: %d\n", getprogname(), posixfile, (int)errorCode);
-- }
-- propertyList = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, resourceData, kCFPropertyListMutableContainers, &errorString);
-- if (!propertyList) {
-- fprintf(stderr, "%s: propertyList is NULL\n", getprogname());
-- }
--
-- return propertyList;
--}
--
--#define _assert(test, format, args...) do { \
-- if (test) break; \
-- fprintf(stderr, format "\n", ##args); \
-- return 1; \
--} while (false)
--
--void stop() {
-- sleep(1);
--}
--
--#define SpringBoard_plist "/System/Library/LaunchDaemons/com.apple.SpringBoard.plist"
--
--int main(int argc, const char *argv[]) {
-- platformizeme();
-- _assert(argc == 1, "usage: sbreload");
--
-- CFDictionaryRef plist = CreateMyPropertyListFromFile(SpringBoard_plist);
-- _assert(plist != NULL, "CreateMyPropertyListFromFile() == NULL");
--
-- launch_data_t job = CF2launch_data(plist);
-- _assert(job != NULL, "CF2launch_data() == NULL");
--
-- launch_data_t data, request, response;
--
-- data = launch_data_dict_lookup(job, LAUNCH_JOBKEY_LABEL);
-- _assert(data != NULL, "launch_data_dict_lookup(LABEL) == NULL");
-- const char *label = launch_data_get_string(data);
--
-- request = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
-- launch_data_dict_insert(request, launch_data_new_string(label), LAUNCH_KEY_GETJOB);
--
-- response = launch_msg(request);
-- _assert(response != NULL, "launch_msg(GetJob) == NULL");
-- launch_data_free(request);
--
-- pid_t pid;
--
-- if (launch_data_get_type(response) == LAUNCH_DATA_ERRNO) {
-- int error = launch_data_get_errno(response);
-- _assert(error == ESRCH, "GetJob(%s): %s", label, strerror(error));
-- pid = -1;
-- } else if (launch_data_get_type(response) == LAUNCH_DATA_DICTIONARY) {
-- data = launch_data_dict_lookup(response, LAUNCH_JOBKEY_PID);
-- _assert(data != NULL, "launch_data_dict_lookup(PID) == NULL");
-- pid = launch_data_get_integer(data);
-- } else _assert(false, "launch_data_get_type() not in (DICTIONARY, ERRNO)");
--
-- launch_data_free(response);
--
-- // 600 is being used to approximate 4.x/5.x boundary
-- if (kCFCoreFoundationVersionNumber < 600) {
-- fprintf(stderr, "notify_post(com.apple.mobile.springboard_teardown)\n");
-- notify_post("com.apple.mobile.springboard_teardown");
-- } else {
-- // XXX: this code is preferable to launchctl unoad but it requires libvproc? :(
-- //vproc_err_t *error = _vproc_send_signal_by_label(label, VPROC_MAGIC_UNLOAD_SIGNAL);
-- //_assert(error == NULL, "_vproc_send_signal_by_label(UNLOAD) != NULL");
--
-- fprintf(stderr, "launchctl unload SpringBoard.plist\n");
-- system("launchctl unload " SpringBoard_plist);
-- }
--
-- if (pid != -1) {
-- fprintf(stderr, "waiting for kill(%u) != 0...\n", pid);
-- while (kill(pid, 0) == 0)
-- stop();
--
-- int error = errno;
-- _assert(error == ESRCH, "kill(%u): %s", pid, strerror(error));
-- }
--
-- request = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
-- launch_data_dict_insert(request, job, LAUNCH_KEY_SUBMITJOB);
--
-- for (;;) {
-- response = launch_msg(request);
-- _assert(response != NULL, "launch_msg(SubmitJob) == NULL");
--
-- _assert(launch_data_get_type(response) == LAUNCH_DATA_ERRNO, "launch_data_get_type() != ERRNO");
-- int error = launch_data_get_errno(response);
-- launch_data_free(response);
--
-- const char *string = strerror(error);
--
-- if (error == EEXIST) {
-- fprintf(stderr, "SubmitJob(%s): %s, retrying...\n", label, string);
-- stop();
-- } else {
-- _assert(error == 0, "SubmitJob(%s): %s", label, string);
-- break;
-- }
-- }
--
-- launch_data_free(request);
--
-- return 0;
--}
-diff -urN uikittools/sbreload.m uikittools+uicache/sbreload.m
---- uikittools/sbreload.m 1969-12-31 14:00:00.000000000 -1000
-+++ uikittools+uicache/sbreload.m 2019-06-07 22:37:29.000000000 -1000
-@@ -0,0 +1,336 @@
-+/* UIKit Tools - command-line utilities for UIKit
-+ * Copyright (C) 2008-2012 Jay Freeman (saurik)
-+*/
-+
-+/* Modified BSD License {{{ */
-+/*
-+ * Redistribution and use in source and binary
-+ * forms, with or without modification, are permitted
-+ * provided that the following conditions are met:
-+ *
-+ * 1. Redistributions of source code must retain the
-+ * above copyright notice, this list of conditions
-+ * and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the
-+ * above copyright notice, this list of conditions
-+ * and the following disclaimer in the documentation
-+ * and/or other materials provided with the
-+ * distribution.
-+ * 3. The name of the author may not be used to endorse
-+ * or promote products derived from this software
-+ * without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
-+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
-+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
-+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+*/
-+/* }}} */
-+
-+#include <launch.h>
-+#include <notify.h>
-+
-+#include <stdio.h>
-+#include <unistd.h>
-+
-+#include <Foundation/Foundation.h>
-+
-+/* Set platform binary flag */
-+#define FLAG_PLATFORMIZE (1 << 1)
-+#include <dlfcn.h>
-+#include <objc/runtime.h>
-+
-+@interface FBSSystemService
-++(id)sharedService;
-+-(void)sendActions:(NSSet*)actions withResult:(id)result;
-+@end
-+
-+typedef enum {
-+ None = 0,
-+ RestartRenderServer = (1 << 0), // also relaunch backboardd
-+ SnapshotTransition = (1 << 1),
-+ FadeToBlackTransition = (1 << 2),
-+} SBSRelaunchActionStyle;
-+
-+@interface SBSRelaunchAction
-++(id)actionWithReason:(id)reason options:(int64_t)options targetURL:(NSURL*)url;
-+@end
-+
-+void platformizeme() {
-+ void* handle = dlopen("/usr/lib/libjailbreak.dylib", RTLD_LAZY);
-+ if (!handle) return;
-+
-+ // Reset errors
-+ dlerror();
-+ typedef void (*fix_entitle_prt_t)(pid_t pid, uint32_t what);
-+ fix_entitle_prt_t ptr = (fix_entitle_prt_t)dlsym(handle, "jb_oneshot_entitle_now");
-+
-+ const char *dlsym_error = dlerror();
-+ if (dlsym_error) {
-+ return;
-+ }
-+
-+ ptr(getpid(), FLAG_PLATFORMIZE);
-+}
-+
-+launch_data_t
-+CF2launch_data(CFTypeRef cfr);
-+
-+void
-+myCFDictionaryApplyFunction(const void *key, const void *value, void *context)
-+{
-+ launch_data_t ik, iw, where = context;
-+
-+ ik = CF2launch_data(key);
-+ iw = CF2launch_data(value);
-+
-+ launch_data_dict_insert(where, iw, launch_data_get_string(ik));
-+ launch_data_free(ik);
-+}
-+
-+launch_data_t
-+CF2launch_data(CFTypeRef cfr)
-+{
-+ launch_data_t r;
-+ CFTypeID cft = CFGetTypeID(cfr);
-+
-+ if (cft == CFStringGetTypeID()) {
-+ char buf[4096];
-+ CFStringGetCString(cfr, buf, sizeof(buf), kCFStringEncodingUTF8);
-+ r = launch_data_alloc(LAUNCH_DATA_STRING);
-+ launch_data_set_string(r, buf);
-+ } else if (cft == CFBooleanGetTypeID()) {
-+ r = launch_data_alloc(LAUNCH_DATA_BOOL);
-+ launch_data_set_bool(r, CFBooleanGetValue(cfr));
-+ } else if (cft == CFArrayGetTypeID()) {
-+ CFIndex i, ac = CFArrayGetCount(cfr);
-+ r = launch_data_alloc(LAUNCH_DATA_ARRAY);
-+ for (i = 0; i < ac; i++) {
-+ CFTypeRef v = CFArrayGetValueAtIndex(cfr, i);
-+ if (v) {
-+ launch_data_t iv = CF2launch_data(v);
-+ launch_data_array_set_index(r, iv, i);
-+ }
-+ }
-+ } else if (cft == CFDictionaryGetTypeID()) {
-+ r = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
-+ CFDictionaryApplyFunction(cfr, myCFDictionaryApplyFunction, r);
-+ } else if (cft == CFDataGetTypeID()) {
-+ r = launch_data_alloc(LAUNCH_DATA_ARRAY);
-+ launch_data_set_opaque(r, CFDataGetBytePtr(cfr), CFDataGetLength(cfr));
-+ } else if (cft == CFNumberGetTypeID()) {
-+ long long n;
-+ double d;
-+ CFNumberType cfnt = CFNumberGetType(cfr);
-+ switch (cfnt) {
-+ case kCFNumberSInt8Type:
-+ case kCFNumberSInt16Type:
-+ case kCFNumberSInt32Type:
-+ case kCFNumberSInt64Type:
-+ case kCFNumberCharType:
-+ case kCFNumberShortType:
-+ case kCFNumberIntType:
-+ case kCFNumberLongType:
-+ case kCFNumberLongLongType:
-+ CFNumberGetValue(cfr, kCFNumberLongLongType, &n);
-+ r = launch_data_alloc(LAUNCH_DATA_INTEGER);
-+ launch_data_set_integer(r, n);
-+ break;
-+ case kCFNumberFloat32Type:
-+ case kCFNumberFloat64Type:
-+ case kCFNumberFloatType:
-+ case kCFNumberDoubleType:
-+ CFNumberGetValue(cfr, kCFNumberDoubleType, &d);
-+ r = launch_data_alloc(LAUNCH_DATA_REAL);
-+ launch_data_set_real(r, d);
-+ break;
-+ default:
-+ r = NULL;
-+ break;
-+ }
-+ } else {
-+ r = NULL;
-+ }
-+ return r;
-+}
-+
-+CFPropertyListRef
-+CreateMyPropertyListFromFile(const char *posixfile)
-+{
-+ CFPropertyListRef propertyList;
-+ CFStringRef errorString;
-+ CFDataRef resourceData;
-+ SInt32 errorCode;
-+ CFURLRef fileURL;
-+
-+ fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)posixfile, strlen(posixfile), false);
-+ if (!fileURL) {
-+ fprintf(stderr, "%s: CFURLCreateFromFileSystemRepresentation(%s) failed\n", getprogname(), posixfile);
-+ }
-+ if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, fileURL, &resourceData, NULL, NULL, &errorCode)) {
-+ fprintf(stderr, "%s: CFURLCreateDataAndPropertiesFromResource(%s) failed: %d\n", getprogname(), posixfile, (int)errorCode);
-+ }
-+ propertyList = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, resourceData, kCFPropertyListMutableContainers, &errorString);
-+ if (!propertyList) {
-+ fprintf(stderr, "%s: propertyList is NULL\n", getprogname());
-+ }
-+
-+ return propertyList;
-+}
-+
-+#define _assert(test, format, args...) do { \
-+ if (test) break; \
-+ fprintf(stderr, format "\n", ##args); \
-+ return 1; \
-+} while (false)
-+
-+void stop() {
-+ sleep(1);
-+}
-+
-+#define SpringBoard_plist "/System/Library/LaunchDaemons/com.apple.SpringBoard.plist"
-+
-+pid_t launch_get_job_pid(const char * job)
-+{
-+ launch_data_t resp;
-+ launch_data_t msg;
-+
-+ msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
-+ if (msg == NULL) {
-+ return -1;
-+ }
-+
-+ launch_data_dict_insert(msg, launch_data_new_string(job), LAUNCH_KEY_GETJOB);
-+
-+ resp = launch_msg(msg);
-+ launch_data_free(msg);
-+
-+ if (resp == NULL) {
-+ return -1;
-+ }
-+
-+ if (launch_data_get_type(resp) != LAUNCH_DATA_DICTIONARY) return -1;
-+
-+ launch_data_t pid_data = launch_data_dict_lookup(resp, "PID");
-+ if (launch_data_get_type(pid_data) != LAUNCH_DATA_INTEGER) return -1;
-+
-+ pid_t pid = (pid_t)launch_data_get_integer(pid_data);
-+ launch_data_free(resp);
-+ return pid;
-+}
-+
-+int main(int argc, const char *argv[]) {
-+ platformizeme();
-+ _assert(argc == 1, "usage: sbreload");
-+
-+ if (kCFCoreFoundationVersionNumber >= 1443.00) {
-+ dlopen("/System/Library/PrivateFrameworks/FrontBoardServices.framework/FrontBoardServices", RTLD_LAZY);
-+ dlopen("/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices", RTLD_LAZY);
-+ Class $SBSRelaunchAction = objc_getClass("SBSRelaunchAction");
-+ Class $FBSSystemService = objc_getClass("FBSSystemService");
-+ pid_t sb_pid = launch_get_job_pid("com.apple.SpringBoard");
-+ if ($SBSRelaunchAction && $FBSSystemService) {
-+ @autoreleasepool {
-+ id action = [$SBSRelaunchAction actionWithReason:@"respring" options:RestartRenderServer targetURL:nil];
-+ id sharedService = [$FBSSystemService sharedService];
-+ [sharedService sendActions:[NSSet setWithObject:action] withResult:nil];
-+ for (int i=0; i<100; i++) {
-+ if (kill(sb_pid, 0)) {
-+ return 0;
-+ }
-+ usleep(1000);
-+ }
-+ }
-+ }
-+ }
-+ CFDictionaryRef plist = CreateMyPropertyListFromFile(SpringBoard_plist);
-+ _assert(plist != NULL, "CreateMyPropertyListFromFile() == NULL");
-+
-+ launch_data_t job = CF2launch_data(plist);
-+ _assert(job != NULL, "CF2launch_data() == NULL");
-+
-+ launch_data_t data, request, response;
-+
-+ data = launch_data_dict_lookup(job, LAUNCH_JOBKEY_LABEL);
-+ _assert(data != NULL, "launch_data_dict_lookup(LABEL) == NULL");
-+ const char *label = launch_data_get_string(data);
-+
-+ request = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
-+ launch_data_dict_insert(request, launch_data_new_string(label), LAUNCH_KEY_GETJOB);
-+
-+ response = launch_msg(request);
-+ _assert(response != NULL, "launch_msg(GetJob) == NULL");
-+ launch_data_free(request);
-+
-+ pid_t pid;
-+
-+ if (launch_data_get_type(response) == LAUNCH_DATA_ERRNO) {
-+ int error = launch_data_get_errno(response);
-+ _assert(error == ESRCH, "GetJob(%s): %s", label, strerror(error));
-+ pid = -1;
-+ } else if (launch_data_get_type(response) == LAUNCH_DATA_DICTIONARY) {
-+ data = launch_data_dict_lookup(response, LAUNCH_JOBKEY_PID);
-+ _assert(data != NULL, "launch_data_dict_lookup(PID) == NULL");
-+ pid = launch_data_get_integer(data);
-+ } else _assert(false, "launch_data_get_type() not in (DICTIONARY, ERRNO)");
-+
-+ launch_data_free(response);
-+
-+ // 600 is being used to approximate 4.x/5.x boundary
-+ if (kCFCoreFoundationVersionNumber < 600) {
-+ fprintf(stderr, "notify_post(com.apple.mobile.springboard_teardown)\n");
-+ notify_post("com.apple.mobile.springboard_teardown");
-+ } else {
-+ // XXX: this code is preferable to launchctl unoad but it requires libvproc? :(
-+ //vproc_err_t *error = _vproc_send_signal_by_label(label, VPROC_MAGIC_UNLOAD_SIGNAL);
-+ //_assert(error == NULL, "_vproc_send_signal_by_label(UNLOAD) != NULL");
-+
-+ fprintf(stderr, "launchctl unload SpringBoard.plist\n");
-+ system("launchctl unload " SpringBoard_plist);
-+ }
-+
-+ if (pid != -1) {
-+ fprintf(stderr, "waiting for kill(%u) != 0...\n", pid);
-+ while (kill(pid, 0) == 0)
-+ stop();
-+
-+ int error = errno;
-+ _assert(error == ESRCH, "kill(%u): %s", pid, strerror(error));
-+ }
-+
-+ request = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
-+ launch_data_dict_insert(request, job, LAUNCH_KEY_SUBMITJOB);
-+
-+ for (;;) {
-+ response = launch_msg(request);
-+ _assert(response != NULL, "launch_msg(SubmitJob) == NULL");
-+
-+ _assert(launch_data_get_type(response) == LAUNCH_DATA_ERRNO, "launch_data_get_type() != ERRNO");
-+ int error = launch_data_get_errno(response);
-+ launch_data_free(response);
-+
-+ const char *string = strerror(error);
-+
-+ if (error == EEXIST) {
-+ fprintf(stderr, "SubmitJob(%s): %s, retrying...\n", label, string);
-+ stop();
-+ } else {
-+ _assert(error == 0, "SubmitJob(%s): %s", label, string);
-+ break;
-+ }
-+ }
-+
-+ launch_data_free(request);
-+
-+ return 0;
-+}
-diff -urN uikittools/sbreload.xml uikittools+uicache/sbreload.xml
---- uikittools/sbreload.xml 1969-12-31 14:00:00.000000000 -1000
-+++ uikittools+uicache/sbreload.xml 2019-06-07 22:37:29.000000000 -1000
-@@ -0,0 +1,13 @@
-+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-+<plist version="1.0">
-+<dict>
-+ <key>com.apple.frontboard.launchapplications</key>
-+ <true/>
-+ <key>com.apple.frontboard.shutdown</key>
-+ <true/>
-+ <key>platform-application</key>
-+ <true/>
-+ <key>com.apple.private.skip-library-validation</key>
-+ <true/>
-+</dict>
-+</plist>
-diff -urN uikittools/uicache.mm uikittools+uicache/uicache.mm
---- uikittools/uicache.mm 2018-10-04 15:58:19.000000000 -1000
-+++ uikittools+uicache/uicache.mm 2019-06-07 22:37:39.000000000 -1000
-@@ -1,7 +1,17 @@
- /* UIKit Tools - command-line utilities for UIKit
- * Copyright (C) 2008-2012 Jay Freeman (saurik)
-+ * Portions Copyright (C) 2019 Sam Bingner
- */
-
-+/* uicache.mm
-+ *
-+ * Licensed under GPL v2.0 license as available at:
-+ * https://www.gnu.org/licenses/gpl2.txt
-+ *
-+ * In adition, usage must meet the following
-+ * Modified BSD terms:
-+ */
-+
- /* Modified BSD License {{{ */
- /*
- * Redistribution and use in source and binary
-@@ -38,13 +48,16 @@
- /* }}} */
-
- #import <Foundation/Foundation.h>
--
--#include <notify.h>
--#include <sys/types.h>
--#include <sys/stat.h>
--#include <unistd.h>
--
--#include <objc/runtime.h>
-+#import <dlfcn.h>
-+#import <notify.h>
-+#import <sys/types.h>
-+#import <sys/stat.h>
-+#import <unistd.h>
-+#import <getopt.h>
-+#import <launch.h>
-+#import <objc/runtime.h>
-+#import <crt_externs.h>
-+#import <xpc/xpc.h>
-
- #include "csstore.hpp"
-
-@@ -81,6 +94,12 @@
-
- @end
-
-+@interface LSApplicationProxy : NSObject
-+- (NSString*) applicationIdentifier;
-+- (NSURL*) resourcesDirectoryURL;
-+- (NSDate*) registeredDate;
-+@end
-+
- @interface LSApplicationWorkspace : NSObject
- + (id) defaultWorkspace;
- - (BOOL) registerApplication:(id)application;
-@@ -89,16 +108,188 @@
- - (BOOL) registerApplicationDictionary:(id)application;
- - (BOOL) installApplication:(id)application withOptions:(id)options;
- - (BOOL) _LSPrivateRebuildApplicationDatabasesForSystemApps:(BOOL)system internal:(BOOL)internal user:(BOOL)user;
-+- (NSArray<LSApplicationProxy*>*) allApplications;
-+@end
-+
-+@interface MCMAppDataContainer
-++(id)containerWithIdentifier:(NSString*)identifier createIfNecessary:(bool)create existed:(bool*)existed error:(NSError*)error;
-+-(NSURL*)url;
-+@end
-+
-+@interface FBSSystemService
-++(id)sharedService;
-+-(void)sendActions:(NSSet*)actions withResult:(id)result;
- @end
-
--int main(int argc, const char *argv[]) {
-- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-+typedef enum {
-+ None = 0,
-+ RestartRenderServer = (1 << 0), // also relaunch backboardd
-+ SnapshotTransition = (1 << 1),
-+ FadeToBlackTransition = (1 << 2),
-+} SBSRelaunchActionStyle;
-+
-+@interface SBSRelaunchAction
-++(id)actionWithReason:(id)reason options:(int64_t)options targetURL:(NSURL*)url;
-+@end
-+
-+static int verbose=0;
-+static int standard_uicache(void);
-+static Class $MCMPluginKitPluginDataContainer;
-+static Class $MCMAppDataContainer;
-+static Class $LSApplicationWorkspace;
-+LSApplicationWorkspace *workspace=nil;
-+
-+NSString *getAppPath(NSString *path)
-+{
-+ path = [path stringByResolvingSymlinksInPath];
-+ if (![path hasPrefix:@"/Applications/"]) {
-+ fprintf(stderr, "Error: Path must be within /Applications/\n");
-+ return nil;
-+ }
-+ return [NSString pathWithComponents:[[path pathComponents] subarrayWithRange:NSMakeRange(0, 3)]];
-+}
-
-- Class $LSApplicationWorkspace(objc_getClass("LSApplicationWorkspace"));
-- LSApplicationWorkspace *workspace($LSApplicationWorkspace == nil ? nil : [$LSApplicationWorkspace defaultWorkspace]);
-+bool appIsRegistered(NSString *path)
-+{
-+ @autoreleasepool {
-+ path = getAppPath(path);
-+ if (!path) return false;
-+ for (LSApplicationProxy *app in [workspace allApplications]) {
-+ if ([path isEqualToString:[[app resourcesDirectoryURL] path]]) return true;
-+ }
-+ return false;
-+ }
-+}
-
-- if (kCFCoreFoundationVersionNumber > 1000) // this API is on iOS 7 but invaliding the icon cache is harder there
-- if ([workspace respondsToSelector:@selector(_LSPrivateRebuildApplicationDatabasesForSystemApps:internal:user:)]) {
-+bool unregisterPath(NSString *path)
-+{
-+ @autoreleasepool {
-+ if (verbose) fprintf(stderr, "Unregistering %s\n", path.lastPathComponent.UTF8String);
-+ path = getAppPath(path);
-+ if (!path) return false;
-+ if (appIsRegistered(path) && ![workspace unregisterApplication:[NSURL fileURLWithPath:path]]) {
-+ fprintf(stderr, "Error: unregisterApplication failed for %s\n", path.lastPathComponent.UTF8String);
-+ return false;
-+ }
-+ }
-+ return true;
-+}
-+
-+// Credit to coolstar for finding how to do this and not sharing with the community thereby forcing me to figure out how to do the same thing.
-+bool registerPath(NSString *path)
-+{
-+ if (!path) {
-+ if (verbose) fprintf(stderr, "registerPath called with no path\n");
-+ return false;
-+ }
-+ NSString *realPath = getAppPath(path);
-+ if (!realPath) {
-+ if (verbose) fprintf(stderr, "unable to determine path for %s\n", path.UTF8String);
-+ return false;
-+ }
-+ NSDictionary *infoDictionary = [NSDictionary dictionaryWithContentsOfFile:
-+ [realPath stringByAppendingPathComponent:@"Info.plist"]];
-+ NSString *bundleID = [infoDictionary objectForKey:@"CFBundleIdentifier"];
-+
-+ if (bundleID) {
-+ NSFileManager *fm = [NSFileManager defaultManager];
-+
-+ if ([infoDictionary objectForKey:@"CFBundleExecutable"]) {
-+ NSString *executable = [realPath stringByAppendingPathComponent:[infoDictionary objectForKey:@"CFBundleExecutable"]];
-+ if (![fm fileExistsAtPath:executable]) {
-+ fprintf(stderr, "Error: CFBundleExecutable defined but missing for %s - this is a fatal error. Aborting.\n", realPath.lastPathComponent.UTF8String);
-+ return false;
-+ }
-+ }
-+
-+ NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
-+ @"System", @"ApplicationType",
-+ @YES, @"BundleNameIsLocalized",
-+ bundleID, @"CFBundleIdentifier",
-+ @NO, @"CompatibilityState",
-+ @NO, @"IsDeletable",
-+ realPath, @"Path",
-+ [NSMutableDictionary dictionary], @"_LSBundlePlugins",
-+ nil];
-+
-+ id appContainer = [$MCMAppDataContainer containerWithIdentifier:bundleID
-+ createIfNecessary:YES existed:NULL error:nil];
-+
-+ NSString *appContainerPath = [[appContainer url] path];
-+ if (appContainerPath) {
-+ dict[@"Container"] = appContainerPath;
-+ }
-+ NSString *pluginsPath = [realPath stringByAppendingPathComponent:@"PlugIns"];
-+ for (NSString *plugin in [fm contentsOfDirectoryAtPath:pluginsPath error:nil]) {
-+ NSString *pluginPath = [pluginsPath stringByAppendingPathComponent:plugin];
-+ NSString *pluginInfoPlistPath = [pluginPath stringByAppendingPathComponent:@"Info.plist"];
-+ NSString *pluginBundleIdentifier = [[NSDictionary dictionaryWithContentsOfFile:pluginInfoPlistPath] objectForKey:@"CFBundleIdentifier"];
-+ if (pluginBundleIdentifier) {
-+ id pluginContainer = [$MCMPluginKitPluginDataContainer containerWithIdentifier:pluginBundleIdentifier
-+ createIfNecessary:YES existed:NULL error:nil];
-+ NSURL *pluginContainerURL = [pluginContainer url];
-+ NSString *pluginContainerPath = [pluginContainerURL path];
-+ dict[@"_LSBundlePlugins"][pluginBundleIdentifier] = @{
-+ @"ApplicationType": @"PluginKitPlugin",
-+ @"BundleNameIsLocalized": @YES,
-+ @"CFBundleIdentifier": pluginBundleIdentifier,
-+ @"CompatibilityState": @NO,
-+ @"Container": pluginContainerPath,
-+ @"Path": pluginPath,
-+ @"PluginOwnerBundleID": bundleID
-+ };
-+ }
-+ }
-+ if (![[$LSApplicationWorkspace defaultWorkspace] registerApplicationDictionary:dict]) {
-+ fprintf(stderr, "Error: registerApplicationDictionary failed for %s\n", path.lastPathComponent.UTF8String);
-+ return false;
-+ }
-+ } else {
-+ return unregisterPath(realPath);
-+ }
-+ return true;
-+}
-+
-+void usage(void)
-+{
-+ fprintf(stderr, "Usage: %s [-hrv] [[-p | -u] /Applications/App.app]]\n", getprogname());
-+ exit(EXIT_FAILURE);
-+}
-+
-+pid_t launch_get_job_pid(const char * job)
-+{
-+ launch_data_t resp;
-+ launch_data_t msg;
-+
-+ msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
-+ if (msg == NULL) {
-+ return -1;
-+ }
-+
-+ launch_data_dict_insert(msg, launch_data_new_string(job), LAUNCH_KEY_GETJOB);
-+
-+ resp = launch_msg(msg);
-+ launch_data_free(msg);
-+
-+ if (resp == NULL) {
-+ return -1;
-+ }
-+
-+ if (launch_data_get_type(resp) != LAUNCH_DATA_DICTIONARY) return -1;
-+
-+ launch_data_t pid_data = launch_data_dict_lookup(resp, "PID");
-+ if (launch_data_get_type(pid_data) != LAUNCH_DATA_INTEGER) return -1;
-+
-+ pid_t pid = (pid_t)launch_data_get_integer(pid_data);
-+ launch_data_free(resp);
-+ return pid;
-+}
-+
-+int standard_uicache(void)
-+{
-+ @autoreleasepool {
-+ if (kCFCoreFoundationVersionNumber > 1000 && // this API is on iOS 7 but invaliding the icon cache is harder there
-+ [workspace respondsToSelector:@selector(_LSPrivateRebuildApplicationDatabasesForSystemApps:internal:user:)]) {
- if (![workspace _LSPrivateRebuildApplicationDatabasesForSystemApps:YES internal:YES user:NO])
- fprintf(stderr, "failed to rebuild application databases");
- return 0;
-@@ -226,12 +417,247 @@
- system("killall -SIGCONT SpringBoard");
- }
-
-- if (respring)
-- system("launchctl stop com.apple.SpringBoard");
-- else
-- notify_post("com.apple.mobile.application_installed");
--
-- [pool release];
-+ notify_post("com.apple.mobile.application_installed");
-
- return 0;
-+ }
-+}
-+
-+pid_t pidOfCydia(void) {
-+ launch_data_t request = launch_data_new_string(LAUNCH_KEY_GETJOBS);
-+ launch_data_t response = launch_msg(request);
-+ launch_data_free(request);
-+ __block pid_t pid=-1;
-+
-+ if (response == NULL || launch_data_get_type(response) != LAUNCH_DATA_DICTIONARY) return -1;
-+
-+ xpc_dictionary_apply((xpc_object_t)response, ^bool(const char *key, xpc_object_t value) {
-+ if (xpc_get_type(value) == XPC_TYPE_DICTIONARY) {
-+ const char *program = xpc_dictionary_get_string(value, "Program");
-+ if (program && strcmp(program, "/Applications/Cydia.app/Cydia") == 0) {
-+ pid = (pid_t)xpc_dictionary_get_int64(value, "PID");
-+ if (verbose) fprintf(stderr, "Found Cydia running with PID: %d\n", pid);
-+ return false;
-+ }
-+ }
-+ return true;
-+ });
-+
-+ if (pid>0) {
-+ return pid;
-+ }
-+ return -1;
-+}
-+
-+int optimized_uicache(void) {
-+ __block int rv=0;
-+ NSMutableDictionary *registered = [NSMutableDictionary new];
-+ static void (^readHandler)(NSFileHandle*) = ^(NSFileHandle *fh) {
-+ NSData *output = [fh readDataToEndOfFile];
-+ if (output.length==0) return;
-+ const char *found_path = (const char *)[output bytes];
-+ NSArray *found = [@(found_path) pathComponents];
-+ if (found.count >= 3) {
-+ NSString *appPath = [@"/Applications" stringByAppendingPathComponent:found[2]];
-+ @synchronized (registered) {
-+ if (registered[appPath]) return;
-+ if (verbose) fprintf(stderr, "Updating %s\n", appPath.lastPathComponent.UTF8String);
-+ registered[appPath] = @YES;
-+ }
-+ pid_t cydia_pid;
-+ if ([found[2] isEqualToString:@"Cydia.app"] &&
-+ (cydia_pid = pidOfCydia()) > 0) {
-+ // We are in cydia and trying to refresh it - this will kill it. Let's schedule it for later.
-+ if (verbose) fprintf(stderr, "Waiting to refresh Cydia...\n");
-+ pid_t pid = fork();
-+ if (pid == 0) {
-+ setpgrp();
-+ signal(SIGHUP, SIG_IGN);
-+ signal(SIGPIPE, SIG_IGN);
-+ fclose(stdin);
-+ freopen("/dev/null", "a", stderr);
-+ freopen("/dev/null", "a", stdout);
-+ pid = fork();
-+ if (pid == 0) {
-+ while (kill(cydia_pid, 0)==0) {
-+ sleep(1);
-+ }
-+ const char *uicache = (*_NSGetArgv())[0];
-+ execl(uicache, uicache, "-vvvvvvv", NULL);
-+ fprintf(stderr, "Unable to exec\n");
-+ fflush(stderr);
-+ exit(-1);
-+ }
-+ exit(0);
-+ } else if (pid > 0) {
-+ int stat;
-+ waitpid(pid, &stat, 0);
-+ return;
-+ } else {
-+ fprintf(stderr, "Unable to fork\n");
-+ }
-+ }
-+ if (!registerPath(appPath)) rv++;
-+ }
-+ };
-+ NSFileManager *fm = [NSFileManager defaultManager];
-+ NSMutableDictionary *apps = [NSMutableDictionary new];
-+ NSMutableArray *cleanup = [NSMutableArray new];
-+ NSMutableArray *finds = [NSMutableArray new];
-+ if (verbose>1) fprintf(stderr, "Enumerating apps\n");
-+ for (LSApplicationProxy *app in [workspace allApplications]) {
-+ NSString *path = [[app resourcesDirectoryURL] path];
-+ if (![path hasPrefix:@"/Applications/"]) continue;
-+ if (verbose>1) fprintf(stderr, "Checking %s\n", path.lastPathComponent.UTF8String);
-+
-+ NSDate *lastRegistered = [app registeredDate];
-+
-+ if ([fm fileExistsAtPath:path]) {
-+ // Check for updated components
-+ NSTask *find = [NSTask new];
-+ [find setLaunchPath:@"/usr/bin/find"];
-+ [find setStandardOutput:[NSPipe pipe]];
-+ NSString *stampPath = [NSString stringWithFormat:@"/var/tmp/uicache.stamp.%@", app.applicationIdentifier];
-+ [fm createFileAtPath:stampPath contents:nil attributes:@{NSFileModificationDate: lastRegistered}];
-+ [cleanup addObject:stampPath];
-+ [find setArguments:@[ path, @"-newer", stampPath, @"-print0", @"-quit"]];
-+ [finds addObject:find];
-+ [find launch];
-+ apps[path.lastPathComponent] = app;
-+ } else {
-+ if (verbose) fprintf(stderr, "De-registering removed app: %s\n", path.lastPathComponent.UTF8String);
-+ @synchronized (registered) {
-+ if (registered[path]) continue;
-+ registered[path] = @YES;
-+ }
-+ if (!unregisterPath(path)) rv++;
-+ }
-+ }
-+
-+ for (NSString* existing in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"/Applications" error:nil]) {
-+ NSString *path = [@"/Applications" stringByAppendingPathComponent:existing];
-+ if (apps[existing] || registered[path] || ![existing hasSuffix:@".app"]) continue;
-+ if (verbose) fprintf(stderr, "Registering new app: %s\n", existing.UTF8String);
-+ @synchronized (registered) {
-+ registered[path] = @YES;
-+ }
-+ if (!registerPath(path)) rv++;
-+ }
-+ for (NSTask *find in finds) {
-+ if (verbose>2) fprintf(stderr, "waiting for find %s\n", [find.arguments componentsJoinedByString:@" "].UTF8String);
-+ readHandler([find.standardOutput fileHandleForReading]);
-+ [find waitUntilExit];
-+ }
-+ for (NSString *path in cleanup) {
-+ [fm removeItemAtPath:path error:nil];
-+ }
-+ return rv;
-+}
-+
-+int main(int argc, const char *argv[])
-+{
-+ if (getuid() == 0) {
-+ // Be mobile
-+ if (setuid(501)) {
-+ fprintf(stderr, "Error: unable to become mobile");
-+ return -1;
-+ }
-+ }
-+ dlopen("/System/Library/PrivateFrameworks/MobileContainerManager.framework/MobileContainerManager", RTLD_LAZY);
-+ dlopen("/System/Library/PrivateFrameworks/FrontBoardServices.framework/FrontBoardServices", RTLD_LAZY);
-+ dlopen("/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices", RTLD_LAZY);
-+ Class $SBSRelaunchAction = objc_getClass("SBSRelaunchAction");
-+ Class $FBSSystemService = objc_getClass("FBSSystemService");
-+ $MCMPluginKitPluginDataContainer = objc_getClass("MCMPluginKitPluginDataContainer");
-+ $MCMAppDataContainer = objc_getClass("MCMAppDataContainer");
-+ $LSApplicationWorkspace = objc_getClass("LSApplicationWorkspace");
-+ workspace = [$LSApplicationWorkspace defaultWorkspace];
-+
-+ static int rv=0;
-+ @autoreleasepool {
-+ bool respring=false, do_all=false;
-+ void (*jb_oneshot_entitle_now)(pid_t a, uint64_t b);
-+ void *libjb = dlopen("/usr/lib/libjailbreak.dylib", RTLD_LAZY);
-+
-+ if (libjb) {
-+ dlerror();
-+ jb_oneshot_entitle_now = (void (*)(pid_t, uint64_t))dlsym(libjb, "jb_oneshot_entitle_now");
-+ if (!dlerror()) jb_oneshot_entitle_now(getpid(), 2);
-+ }
-+
-+ NSMutableDictionary *paths = [NSMutableDictionary new];
-+ NSMutableDictionary *unregister_paths = [NSMutableDictionary new];
-+ static struct option long_options[] =
-+ {
-+ {"all", no_argument, 0, 'a'},
-+ {"help", no_argument, 0, 'h'},
-+ {"path", required_argument, 0, 'p'},
-+ {"unregister", required_argument, 0, 'u'},
-+ {"respring", no_argument, 0, 'r'},
-+ {"verbose", no_argument, 0, 'v'},
-+ {0, 0, 0, 0}
-+ };
-+ int option_index = 0;
-+ char ch;
-+ bool have_path = false;
-+ while ((ch = getopt_long(argc, (char *const *)argv, "ap:ru:vh?", long_options, &option_index)) != -1) {
-+ switch (ch)
-+ {
-+ case 'a':
-+ do_all = true;
-+ break;
-+ case 'h':
-+ usage();
-+ break;
-+ case 'p':
-+ paths[@(optarg)] = @YES;
-+ have_path = true;
-+ break;
-+ case 'r':
-+ respring = true;
-+ break;
-+ case 'u':
-+ unregister_paths[@(optarg)] = @YES;
-+ have_path = true;
-+ break;
-+ case 'v':
-+ verbose++;
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ if (do_all || !$MCMPluginKitPluginDataContainer || !$MCMAppDataContainer || !$LSApplicationWorkspace) {
-+ rv = standard_uicache();
-+ } else if (have_path) {
-+ for (NSString *path in [paths allKeys]) {
-+ if (verbose) fprintf(stderr, "Refreshing %s\n", path.UTF8String);
-+ if (!registerPath(path)) rv++;
-+ }
-+ for (NSString *path in [unregister_paths allKeys]) {
-+ if (!unregisterPath(path)) rv++;
-+ }
-+ } else {
-+ rv += optimized_uicache();
-+ }
-+ if ( respring )
-+ {
-+ pid_t sb_pid = launch_get_job_pid("com.apple.SpringBoard");
-+ if ($SBSRelaunchAction && $FBSSystemService) {
-+ id action = [$SBSRelaunchAction actionWithReason:@"respring" options:RestartRenderServer targetURL:nil];
-+ id sharedService = [$FBSSystemService sharedService];
-+ [sharedService sendActions:[NSSet setWithObject:action] withResult:nil];
-+ for (int i=0; i<100; i++) {
-+ if (kill(sb_pid, 0)) {
-+ break;
-+ }
-+ usleep(1000);
-+ }
-+ } else {
-+ system("launchctl stop com.apple.SpringBoard");
-+ system("launchctl stop com.apple.backboardd");
-+ }
-+ }
-+ } // @autoreleasepool
-+ return rv;
- }
-diff -urN uikittools/uicache.xml uikittools+uicache/uicache.xml
---- uikittools/uicache.xml 2018-10-04 15:58:37.000000000 -1000
-+++ uikittools+uicache/uicache.xml 2019-06-07 22:37:29.000000000 -1000
-@@ -4,23 +4,22 @@
- <key>com.apple.private.mobileinstall.allowedSPI</key>
- <array>
- <string>InstallForLaunchServices</string>
-+ <string>UninstallForLaunchServices</string>
- </array>
--
- <key>com.apple.lsapplicationworkspace.rebuildappdatabases</key>
- <true/>
--
- <key>com.apple.private.MobileContainerManager.allowed</key>
- <true/>
--
- <key>com.apple.private.kernel.override-cpumon</key>
- <true/>
--
- <key>com.apple.vpn.installer_events</key>
- <true/>
--
-+ <key>com.apple.frontboard.launchapplications</key>
-+ <true/>
-+ <key>com.apple.frontboard.shutdown</key>
-+ <true/>
- <key>platform-application</key>
- <true/>
--
- <key>com.apple.private.skip-library-validation</key>
- <true/>
- </dict>