]>
Commit | Line | Data |
---|---|---|
63755c48 JF |
1 | #include "CyteKit/UCPlatform.h" |
2 | ||
86631cc4 | 3 | #include <dirent.h> |
eaa9f122 | 4 | #include <strings.h> |
86631cc4 | 5 | |
eaa9f122 JF |
6 | #include <Sources.h> |
7 | ||
86631cc4 | 8 | #include <sys/stat.h> |
407564b5 | 9 | #include <sys/sysctl.h> |
86631cc4 | 10 | #include <sys/types.h> |
407564b5 | 11 | |
608321d0 | 12 | #include <Menes/ObjectHandle.h> |
eaa9f122 | 13 | |
86631cc4 JF |
14 | void Finish(const char *finish) { |
15 | if (finish == NULL) | |
16 | return; | |
17 | ||
18 | const char *cydia(getenv("CYDIA")); | |
19 | if (cydia == NULL) | |
20 | return; | |
21 | ||
22 | int fd([[[[NSString stringWithUTF8String:cydia] componentsSeparatedByString:@" "] objectAtIndex:0] intValue]); | |
23 | ||
24 | FILE *fout(fdopen(fd, "w")); | |
25 | fprintf(fout, "finish:%s\n", finish); | |
26 | fclose(fout); | |
27 | } | |
28 | ||
e4d9a4f2 JF |
29 | static bool setnsfpn(const char *path) { |
30 | return system([[NSString stringWithFormat:@"/usr/libexec/cydia/setnsfpn %s", path] UTF8String]) == 0; | |
31 | } | |
32 | ||
ec89f5e6 JF |
33 | enum StashStatus { |
34 | StashDone, | |
35 | StashFail, | |
36 | StashGood, | |
37 | }; | |
38 | ||
39 | static StashStatus MoveStash() { | |
bcc58607 JF |
40 | struct stat stat; |
41 | ||
42 | if (lstat("/var/stash", &stat) == -1) | |
ec89f5e6 | 43 | return errno == ENOENT ? StashGood : StashFail; |
bcc58607 | 44 | else if (S_ISLNK(stat.st_mode)) |
ec89f5e6 | 45 | return StashGood; |
bcc58607 | 46 | else if (!S_ISDIR(stat.st_mode)) |
ec89f5e6 | 47 | return StashFail; |
bcc58607 JF |
48 | |
49 | if (lstat("/var/db/stash", &stat) == -1) { | |
50 | if (errno == ENOENT) | |
51 | goto move; | |
ec89f5e6 | 52 | else return StashFail; |
bcc58607 JF |
53 | } else if (S_ISLNK(stat.st_mode)) |
54 | // XXX: this is fixable | |
ec89f5e6 | 55 | return StashFail; |
bcc58607 | 56 | else if (!S_ISDIR(stat.st_mode)) |
ec89f5e6 | 57 | return StashFail; |
bcc58607 JF |
58 | else { |
59 | if (!setnsfpn("/var/db/stash")) | |
ec89f5e6 | 60 | return StashFail; |
bcc58607 | 61 | if (system("mv -t /var/stash /var/db/stash/*") != 0) |
ec89f5e6 | 62 | return StashFail; |
bcc58607 | 63 | if (rmdir("/var/db/stash") == -1) |
ec89f5e6 | 64 | return StashFail; |
bcc58607 JF |
65 | } move: |
66 | ||
67 | if (!setnsfpn("/var/stash")) | |
ec89f5e6 | 68 | return StashFail; |
bcc58607 JF |
69 | |
70 | if (rename("/var/stash", "/var/db/stash") == -1) | |
ec89f5e6 | 71 | return StashFail; |
bcc58607 | 72 | if (symlink("/var/db/stash", "/var/stash") != -1) |
ec89f5e6 | 73 | return StashDone; |
bcc58607 | 74 | if (rename("/var/db/stash", "/var/stash") != -1) |
ec89f5e6 | 75 | return StashFail; |
bcc58607 JF |
76 | |
77 | fprintf(stderr, "/var/stash misplaced -- DO NOT REBOOT\n"); | |
ec89f5e6 | 78 | return StashFail; |
bcc58607 JF |
79 | } |
80 | ||
82e370b3 | 81 | static bool FixProtections() { |
3a686b9f JF |
82 | const char *path("/var/lib"); |
83 | mkdir(path, 0755); | |
84 | if (!setnsfpn(path)) { | |
85 | fprintf(stderr, "failed to setnsfpn %s\n", path); | |
86 | return false; | |
82e370b3 | 87 | } |
bcc58607 | 88 | |
82e370b3 JF |
89 | return true; |
90 | } | |
91 | ||
b132a972 JF |
92 | static void FixPermissions() { |
93 | DIR *stash(opendir("/var/stash")); | |
94 | if (stash == NULL) | |
95 | return; | |
96 | ||
97 | while (dirent *entry = readdir(stash)) { | |
98 | const char *folder(entry->d_name); | |
99 | if (strlen(folder) != 8) | |
100 | continue; | |
101 | if (strncmp(folder, "_.", 2) != 0) | |
102 | continue; | |
103 | ||
104 | char path[1024]; | |
105 | sprintf(path, "/var/stash/%s", folder); | |
106 | ||
107 | struct stat stat; | |
108 | if (lstat(path, &stat) == -1) | |
109 | continue; | |
110 | if (!S_ISDIR(stat.st_mode)) | |
111 | continue; | |
112 | ||
113 | chmod(path, 0755); | |
114 | } | |
115 | ||
116 | closedir(stash); | |
117 | } | |
118 | ||
86631cc4 JF |
119 | #define APPLICATIONS "/Applications" |
120 | static bool FixApplications() { | |
121 | char target[1024]; | |
122 | ssize_t length(readlink(APPLICATIONS, target, sizeof(target))); | |
123 | if (length == -1) | |
124 | return false; | |
125 | ||
126 | if (length >= sizeof(target)) // >= "just in case" (I'm nervous) | |
127 | return false; | |
128 | target[length] = '\0'; | |
129 | ||
130 | if (strlen(target) != 30) | |
131 | return false; | |
132 | if (memcmp(target, "/var/stash/Applications.", 24) != 0) | |
133 | return false; | |
134 | if (strchr(target + 24, '/') != NULL) | |
135 | return false; | |
136 | ||
137 | struct stat stat; | |
138 | if (lstat(target, &stat) == -1) | |
139 | return false; | |
140 | if (!S_ISDIR(stat.st_mode)) | |
141 | return false; | |
142 | ||
143 | char temp[] = "/var/stash/_.XXXXXX"; | |
144 | if (mkdtemp(temp) == NULL) | |
145 | return false; | |
146 | ||
147 | if (false) undo: { | |
148 | unlink(temp); | |
149 | return false; | |
150 | } | |
151 | ||
152 | if (chmod(temp, 0755) == -1) | |
153 | goto undo; | |
154 | ||
155 | char destiny[strlen(temp) + 32]; | |
156 | sprintf(destiny, "%s%s", temp, APPLICATIONS); | |
157 | ||
158 | if (unlink(APPLICATIONS) == -1) | |
159 | goto undo; | |
160 | ||
161 | if (rename(target, destiny) == -1) { | |
162 | if (symlink(target, APPLICATIONS) == -1) | |
163 | fprintf(stderr, "/Applications damaged -- DO NOT REBOOT\n"); | |
164 | goto undo; | |
165 | } else { | |
2e007a72 JF |
166 | bool success; |
167 | if (symlink(destiny, APPLICATIONS) != -1) | |
168 | success = true; | |
169 | else { | |
86631cc4 | 170 | fprintf(stderr, "/var/stash/Applications damaged -- DO NOT REBOOT\n"); |
2e007a72 JF |
171 | success = false; |
172 | } | |
86631cc4 JF |
173 | |
174 | // unneccessary, but feels better (I'm nervous) | |
175 | symlink(destiny, target); | |
176 | ||
177 | [@APPLICATIONS writeToFile:[NSString stringWithFormat:@"%s.lnk", temp] atomically:YES encoding:NSNonLossyASCIIStringEncoding error:NULL]; | |
2e007a72 | 178 | return success; |
86631cc4 JF |
179 | } |
180 | } | |
181 | ||
eaa9f122 JF |
182 | int main(int argc, const char *argv[]) { |
183 | if (argc < 2 || strcmp(argv[1], "configure") != 0) | |
184 | return 0; | |
185 | ||
186 | NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]); | |
187 | ||
5530e234 JF |
188 | bool restart(false); |
189 | ||
190 | if (kCFCoreFoundationVersionNumber >= 1000) { | |
82e370b3 JF |
191 | if (!FixProtections()) |
192 | return 1; | |
ec89f5e6 JF |
193 | switch (MoveStash()) { |
194 | case StashDone: | |
195 | restart = true; | |
196 | break; | |
197 | case StashFail: | |
198 | fprintf(stderr, "failed to move stash\n"); | |
199 | return 1; | |
200 | case StashGood: | |
201 | break; | |
5530e234 JF |
202 | } |
203 | } | |
82e370b3 | 204 | |
00407aa9 JF |
205 | #define OldCache_ "/var/root/Library/Caches/com.saurik.Cydia" |
206 | if (access(OldCache_, F_OK) == 0) | |
207 | system("rm -rf " OldCache_); | |
208 | ||
e3799a2e | 209 | #define NewCache_ "/var/mobile/Library/Caches/com.saurik.Cydia" |
4cfa3e5b | 210 | system("cd /; su -c 'mkdir -p " NewCache_ "' mobile"); |
0c0a966b | 211 | if (access(NewCache_ "/lists", F_OK) != 0 && errno == ENOENT) |
e3799a2e | 212 | system("cp -at " NewCache_ " /var/lib/apt/lists"); |
0c0a966b | 213 | system("chown -R 501.501 " NewCache_); |
e3799a2e | 214 | |
a4a93d59 JF |
215 | #define OldLibrary_ "/var/lib/cydia" |
216 | ||
217 | #define NewLibrary_ "/var/mobile/Library/Cydia" | |
218 | system("cd /; su -c 'mkdir -p " NewLibrary_ "' mobile"); | |
219 | ||
220 | #define Cytore_ "/metadata.cb0" | |
221 | ||
57cc2170 JF |
222 | #define CYDIA_LIST "/etc/apt/sources.list.d/cydia.list" |
223 | unlink(CYDIA_LIST); | |
224 | [[NSString stringWithFormat:@ | |
225 | "deb http://apt.saurik.com/ ios/%.2f main\n" | |
226 | "deb http://apt.thebigboss.org/repofiles/cydia/ stable main\n" | |
227 | "deb http://cydia.zodttd.com/repo/cydia/ stable main\n" | |
228 | "deb http://apt.modmyi.com/ stable main\n" | |
229 | , kCFCoreFoundationVersionNumber] writeToFile:@ CYDIA_LIST atomically:YES]; | |
230 | ||
a4a93d59 JF |
231 | if (access(NewLibrary_ Cytore_, F_OK) != 0 && errno == ENOENT) { |
232 | if (access(NewCache_ Cytore_, F_OK) == 0) | |
233 | system("mv -f " NewCache_ Cytore_ " " NewLibrary_); | |
234 | else if (access(OldLibrary_ Cytore_, F_OK) == 0) | |
235 | system("mv -f " OldLibrary_ Cytore_ " " NewLibrary_); | |
236 | chown(NewLibrary_ Cytore_, 501, 501); | |
237 | } | |
1a2f455b | 238 | |
b132a972 JF |
239 | FixPermissions(); |
240 | ||
5530e234 JF |
241 | restart |= FixApplications(); |
242 | ||
243 | if (restart) | |
86631cc4 JF |
244 | Finish("restart"); |
245 | ||
eaa9f122 JF |
246 | [pool release]; |
247 | return 0; | |
248 | } |