]> git.saurik.com Git - cydia.git/blame - postinst.mm
Do not crash if Safari's Info.plist can't be read.
[cydia.git] / postinst.mm
CommitLineData
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
14void 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
29static bool setnsfpn(const char *path) {
30 return system([[NSString stringWithFormat:@"/usr/libexec/cydia/setnsfpn %s", path] UTF8String]) == 0;
31}
32
ec89f5e6
JF
33enum StashStatus {
34 StashDone,
35 StashFail,
36 StashGood,
37};
38
39static 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 81static 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
92static 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"
120static 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
182int 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}