]> git.saurik.com Git - uikittools.git/blob - sbreload.c
gcc -Wall -Werror
[uikittools.git] / sbreload.c
1 #include <launch.h>
2 #include <notify.h>
3
4 #include <stdio.h>
5
6 #include <CoreFoundation/CoreFoundation.h>
7
8 launch_data_t
9 CF2launch_data(CFTypeRef cfr);
10
11 void
12 myCFDictionaryApplyFunction(const void *key, const void *value, void *context)
13 {
14 launch_data_t ik, iw, where = context;
15
16 ik = CF2launch_data(key);
17 iw = CF2launch_data(value);
18
19 launch_data_dict_insert(where, iw, launch_data_get_string(ik));
20 launch_data_free(ik);
21 }
22
23 launch_data_t
24 CF2launch_data(CFTypeRef cfr)
25 {
26 launch_data_t r;
27 CFTypeID cft = CFGetTypeID(cfr);
28
29 if (cft == CFStringGetTypeID()) {
30 char buf[4096];
31 CFStringGetCString(cfr, buf, sizeof(buf), kCFStringEncodingUTF8);
32 r = launch_data_alloc(LAUNCH_DATA_STRING);
33 launch_data_set_string(r, buf);
34 } else if (cft == CFBooleanGetTypeID()) {
35 r = launch_data_alloc(LAUNCH_DATA_BOOL);
36 launch_data_set_bool(r, CFBooleanGetValue(cfr));
37 } else if (cft == CFArrayGetTypeID()) {
38 CFIndex i, ac = CFArrayGetCount(cfr);
39 r = launch_data_alloc(LAUNCH_DATA_ARRAY);
40 for (i = 0; i < ac; i++) {
41 CFTypeRef v = CFArrayGetValueAtIndex(cfr, i);
42 if (v) {
43 launch_data_t iv = CF2launch_data(v);
44 launch_data_array_set_index(r, iv, i);
45 }
46 }
47 } else if (cft == CFDictionaryGetTypeID()) {
48 r = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
49 CFDictionaryApplyFunction(cfr, myCFDictionaryApplyFunction, r);
50 } else if (cft == CFDataGetTypeID()) {
51 r = launch_data_alloc(LAUNCH_DATA_ARRAY);
52 launch_data_set_opaque(r, CFDataGetBytePtr(cfr), CFDataGetLength(cfr));
53 } else if (cft == CFNumberGetTypeID()) {
54 long long n;
55 double d;
56 CFNumberType cfnt = CFNumberGetType(cfr);
57 switch (cfnt) {
58 case kCFNumberSInt8Type:
59 case kCFNumberSInt16Type:
60 case kCFNumberSInt32Type:
61 case kCFNumberSInt64Type:
62 case kCFNumberCharType:
63 case kCFNumberShortType:
64 case kCFNumberIntType:
65 case kCFNumberLongType:
66 case kCFNumberLongLongType:
67 CFNumberGetValue(cfr, kCFNumberLongLongType, &n);
68 r = launch_data_alloc(LAUNCH_DATA_INTEGER);
69 launch_data_set_integer(r, n);
70 break;
71 case kCFNumberFloat32Type:
72 case kCFNumberFloat64Type:
73 case kCFNumberFloatType:
74 case kCFNumberDoubleType:
75 CFNumberGetValue(cfr, kCFNumberDoubleType, &d);
76 r = launch_data_alloc(LAUNCH_DATA_REAL);
77 launch_data_set_real(r, d);
78 break;
79 default:
80 r = NULL;
81 break;
82 }
83 } else {
84 r = NULL;
85 }
86 return r;
87 }
88
89 CFPropertyListRef
90 CreateMyPropertyListFromFile(const char *posixfile)
91 {
92 CFPropertyListRef propertyList;
93 CFStringRef errorString;
94 CFDataRef resourceData;
95 SInt32 errorCode;
96 CFURLRef fileURL;
97
98 fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)posixfile, strlen(posixfile), false);
99 if (!fileURL) {
100 fprintf(stderr, "%s: CFURLCreateFromFileSystemRepresentation(%s) failed\n", getprogname(), posixfile);
101 }
102 if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, fileURL, &resourceData, NULL, NULL, &errorCode)) {
103 fprintf(stderr, "%s: CFURLCreateDataAndPropertiesFromResource(%s) failed: %d\n", getprogname(), posixfile, (int)errorCode);
104 }
105 propertyList = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, resourceData, kCFPropertyListMutableContainers, &errorString);
106 if (!propertyList) {
107 fprintf(stderr, "%s: propertyList is NULL\n", getprogname());
108 }
109
110 return propertyList;
111 }
112
113 int main(int argc, const char *argv[]) {
114 if (argc > 1) {
115 fprintf(stderr, "usage: sbreload\n");
116 return 1;
117 }
118
119 notify_post("com.apple.mobile.springboard_teardown");
120
121 launch_data_t request = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
122
123 CFDictionaryRef plist = CreateMyPropertyListFromFile("/System/Library/LaunchDaemons/com.apple.SpringBoard.plist");
124 if (plist == NULL) {
125 fprintf(stderr, "CreateMyPropertyListFromFile() == NULL\n");
126 return 2;
127 }
128
129 launch_data_t job = CF2launch_data(plist);
130 if (job == NULL) {
131 fprintf(stderr, "CF2launch_data() == NULL\n");
132 return 3;
133 }
134
135 const char *label = launch_data_get_string(launch_data_dict_lookup(job, LAUNCH_JOBKEY_LABEL));
136 launch_data_dict_insert(request, job, LAUNCH_KEY_SUBMITJOB);
137
138 launch_data_t response;
139 launch_msg:
140 response = launch_msg(request);
141
142 if (response == NULL) {
143 fprintf(stderr, "launch_msg() == NULL\n");
144 return 4;
145 }
146
147 if (launch_data_get_type(response) != LAUNCH_DATA_ERRNO) {
148 fprintf(stderr, "launch_data_get_type() != ERRNO\n");
149 return 5;
150 }
151
152 int error = launch_data_get_errno(response);
153 launch_data_free(response);
154
155 const char *string = strerror(error);
156
157 if (error == EEXIST) {
158 fprintf(stderr, "%s: %s, retrying...\n", label, string);
159 sleep(1);
160 goto launch_msg;
161 } else if (error != 0) {
162 fprintf(stderr, "%s: %s\n", label, string);
163 return 6;
164 }
165
166 launch_data_free(request);
167
168 return 0;
169 }