From 2618b3e95d753aea41a970219bee94cf006ec1f9 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Fri, 3 Dec 2010 10:49:28 +0000 Subject: Add the new sbreload command. --- .gitignore | 1 + makefile | 6 ++- sbreload.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 sbreload.c diff --git a/.gitignore b/.gitignore index bef8e3b..0d6822e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ _ debs gssc sbdidlaunch +sbreload uicache uiduid uiopen diff --git a/makefile b/makefile index 08d8b37..54fe85b 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,4 @@ -uikittools = uiduid uishoot uicache uiopen gssc sbdidlaunch +uikittools = uiduid uishoot uicache uiopen gssc sbdidlaunch sbreload all: $(uikittools) @@ -11,6 +11,10 @@ clean: $${PKG_TARG}-g++ -o $@ $< -framework CoreFoundation -framework Foundation -framework UIKit -framework GraphicsServices -F"$${PKG_ROOT}"/System/Library/PrivateFrameworks -lobjc -framework SpringBoardServices ldid -S $@ +%: %.c + $${PKG_TARG}-gcc -o $@ $< -framework CoreFoundation + ldid -S $@ + package: all rm -rf _ mkdir -p _/usr/bin diff --git a/sbreload.c b/sbreload.c new file mode 100644 index 0000000..6aa5862 --- /dev/null +++ b/sbreload.c @@ -0,0 +1,169 @@ +#include +#include + +#include + +#include + +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; +} + +int main(int argc, const char *argv[]) { + if (argc > 1) { + fprintf(stderr, "usage: sbreload\n"); + return 1; + } + + notify_post("com.apple.mobile.springboard_teardown"); + + launch_data_t request = launch_data_alloc(LAUNCH_DATA_DICTIONARY); + + CFDictionaryRef plist = CreateMyPropertyListFromFile("/System/Library/LaunchDaemons/com.apple.SpringBoard.plist"); + if (plist == NULL) { + fprintf(stderr, "CreateMyPropertyListFromFile() == NULL\n"); + return 2; + } + + launch_data_t job = CF2launch_data(plist); + if (job == NULL) { + fprintf(stderr, "CF2launch_data() == NULL\n"); + return 3; + } + + const char *label = launch_data_get_string(launch_data_dict_lookup(job, LAUNCH_JOBKEY_LABEL)); + launch_data_dict_insert(request, job, LAUNCH_KEY_SUBMITJOB); + + launch_data_t response; + launch_msg: + response = launch_msg(request); + + if (response == NULL) { + fprintf(stderr, "launch_msg() == NULL\n"); + return 4; + } + + if (launch_data_get_type(response) != LAUNCH_DATA_ERRNO) { + fprintf(stderr, "launch_data_get_type() != ERRNO\n"); + return 5; + } + + int error = launch_data_get_errno(response); + launch_data_free(response); + + const char *string = strerror(error); + + if (error == EEXIST) { + fprintf(stderr, "%s: %s, retrying...\n", label, string); + sleep(1); + goto launch_msg; + } else if (error != 0) { + fprintf(stderr, "%s: %s\n", label, string); + return 6; + } + + launch_data_free(request); + + return 0; +} -- cgit v1.2.3