summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Freeman (saurik) <saurik@saurik.com>2010-12-03 10:49:28 +0000
committerJay Freeman (saurik) <saurik@saurik.com>2010-12-03 10:49:28 +0000
commit2618b3e95d753aea41a970219bee94cf006ec1f9 (patch)
tree986f4cc525197f4ef972e457e3494b65a4e2615d
parent57ebf0d9e1617e5f5ec75fdde1d161a40569999b (diff)
Add the new sbreload command.v1.0.3366
-rw-r--r--.gitignore1
-rw-r--r--makefile6
-rw-r--r--sbreload.c169
3 files changed, 175 insertions, 1 deletions
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 <launch.h>
+#include <notify.h>
+
+#include <stdio.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+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;
+}