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