]> git.saurik.com Git - cydia.git/blame - postinst.mm
Restart SpringBoard in the case that we MoveStash.
[cydia.git] / postinst.mm
CommitLineData
86631cc4 1#include <dirent.h>
eaa9f122 2#include <strings.h>
86631cc4 3
eaa9f122
JF
4#include <Sources.h>
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
bcc58607
JF
31static bool MoveStash() {
32 struct stat stat;
33
34 if (lstat("/var/stash", &stat) == -1)
35 return errno == ENOENT;
36 else if (S_ISLNK(stat.st_mode))
37 return true;
38 else if (!S_ISDIR(stat.st_mode))
39 return false;
40
41 if (lstat("/var/db/stash", &stat) == -1) {
42 if (errno == ENOENT)
43 goto move;
44 else return false;
45 } else if (S_ISLNK(stat.st_mode))
46 // XXX: this is fixable
47 return false;
48 else if (!S_ISDIR(stat.st_mode))
49 return false;
50 else {
51 if (!setnsfpn("/var/db/stash"))
52 return false;
53 if (system("mv -t /var/stash /var/db/stash/*") != 0)
54 return false;
55 if (rmdir("/var/db/stash") == -1)
56 return false;
57 } move:
58
59 if (!setnsfpn("/var/stash"))
60 return false;
61
62 if (rename("/var/stash", "/var/db/stash") == -1)
63 return false;
64 if (symlink("/var/db/stash", "/var/stash") != -1)
65 return true;
66 if (rename("/var/db/stash", "/var/stash") != -1)
67 return false;
68
69 fprintf(stderr, "/var/stash misplaced -- DO NOT REBOOT\n");
70 return false;
71}
72
82e370b3 73static bool FixProtections() {
bcc58607 74 for (const char *path : (const char *[]) {"/var/lib", "/var/cache"}) {
82e370b3 75 mkdir(path, 0755);
e4d9a4f2 76 if (!setnsfpn(path)) {
82e370b3
JF
77 fprintf(stderr, "failed to setnsfpn %s\n", path);
78 return false;
79 }
80 }
bcc58607 81
82e370b3
JF
82 return true;
83}
84
b132a972
JF
85static void FixPermissions() {
86 DIR *stash(opendir("/var/stash"));
87 if (stash == NULL)
88 return;
89
90 while (dirent *entry = readdir(stash)) {
91 const char *folder(entry->d_name);
92 if (strlen(folder) != 8)
93 continue;
94 if (strncmp(folder, "_.", 2) != 0)
95 continue;
96
97 char path[1024];
98 sprintf(path, "/var/stash/%s", folder);
99
100 struct stat stat;
101 if (lstat(path, &stat) == -1)
102 continue;
103 if (!S_ISDIR(stat.st_mode))
104 continue;
105
106 chmod(path, 0755);
107 }
108
109 closedir(stash);
110}
111
86631cc4
JF
112#define APPLICATIONS "/Applications"
113static bool FixApplications() {
114 char target[1024];
115 ssize_t length(readlink(APPLICATIONS, target, sizeof(target)));
116 if (length == -1)
117 return false;
118
119 if (length >= sizeof(target)) // >= "just in case" (I'm nervous)
120 return false;
121 target[length] = '\0';
122
123 if (strlen(target) != 30)
124 return false;
125 if (memcmp(target, "/var/stash/Applications.", 24) != 0)
126 return false;
127 if (strchr(target + 24, '/') != NULL)
128 return false;
129
130 struct stat stat;
131 if (lstat(target, &stat) == -1)
132 return false;
133 if (!S_ISDIR(stat.st_mode))
134 return false;
135
136 char temp[] = "/var/stash/_.XXXXXX";
137 if (mkdtemp(temp) == NULL)
138 return false;
139
140 if (false) undo: {
141 unlink(temp);
142 return false;
143 }
144
145 if (chmod(temp, 0755) == -1)
146 goto undo;
147
148 char destiny[strlen(temp) + 32];
149 sprintf(destiny, "%s%s", temp, APPLICATIONS);
150
151 if (unlink(APPLICATIONS) == -1)
152 goto undo;
153
154 if (rename(target, destiny) == -1) {
155 if (symlink(target, APPLICATIONS) == -1)
156 fprintf(stderr, "/Applications damaged -- DO NOT REBOOT\n");
157 goto undo;
158 } else {
2e007a72
JF
159 bool success;
160 if (symlink(destiny, APPLICATIONS) != -1)
161 success = true;
162 else {
86631cc4 163 fprintf(stderr, "/var/stash/Applications damaged -- DO NOT REBOOT\n");
2e007a72
JF
164 success = false;
165 }
86631cc4
JF
166
167 // unneccessary, but feels better (I'm nervous)
168 symlink(destiny, target);
169
170 [@APPLICATIONS writeToFile:[NSString stringWithFormat:@"%s.lnk", temp] atomically:YES encoding:NSNonLossyASCIIStringEncoding error:NULL];
2e007a72 171 return success;
86631cc4
JF
172 }
173}
174
eaa9f122 175_H<NSMutableDictionary> Sources_;
eaa9f122
JF
176bool Changed_;
177
407564b5 178_H<NSString> System_;
eaa9f122
JF
179
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;
5530e234
JF
191 if (MoveStash())
192 restart = true;
193 else {
194 fprintf(stderr, "failed to move stash\n");
195 return 1;
196 }
197 }
82e370b3 198
407564b5
JF
199 size_t size;
200 sysctlbyname("kern.osversion", NULL, &size, NULL, 0);
201 char *osversion = new char[size];
202 if (sysctlbyname("kern.osversion", osversion, &size, NULL, 0) != -1)
203 System_ = [NSString stringWithUTF8String:osversion];
eaa9f122
JF
204
205 NSDictionary *metadata([[[NSMutableDictionary alloc] initWithContentsOfFile:@"/var/lib/cydia/metadata.plist"] autorelease]);
206 NSUInteger version(0);
207
208 if (metadata != nil) {
209 Sources_ = [metadata objectForKey:@"Sources"];
eaa9f122
JF
210
211 if (NSNumber *number = [metadata objectForKey:@"Version"])
212 version = [number unsignedIntValue];
213 }
214
eaa9f122
JF
215 if (Sources_ == nil)
216 Sources_ = [NSMutableDictionary dictionaryWithCapacity:8];
217
218 if (version == 0) {
219 CydiaAddSource(@"http://apt.thebigboss.org/repofiles/cydia/", @"stable", [NSMutableArray arrayWithObject:@"main"]);
220 CydiaAddSource(@"http://apt.modmyi.com/", @"stable", [NSMutableArray arrayWithObject:@"main"]);
221 CydiaAddSource(@"http://cydia.zodttd.com/repo/cydia/", @"stable", [NSMutableArray arrayWithObject:@"main"]);
222 CydiaAddSource(@"http://repo666.ultrasn0w.com/", @"./");
223 }
224
225 CydiaWriteSources();
226
00407aa9
JF
227 #define OldCache_ "/var/root/Library/Caches/com.saurik.Cydia"
228 if (access(OldCache_, F_OK) == 0)
229 system("rm -rf " OldCache_);
230
e3799a2e 231 #define NewCache_ "/var/mobile/Library/Caches/com.saurik.Cydia"
4cfa3e5b
JF
232 system("cd /; su -c 'mkdir -p " NewCache_ "' mobile");
233
e3799a2e 234 if (access(NewCache_ "/lists", F_OK) != 0 && errno == ENOENT) {
e3799a2e
JF
235 system("cp -at " NewCache_ " /var/lib/apt/lists");
236 system("chown -R 501.501 " NewCache_ "/lists");
237 }
238
a4a93d59
JF
239 #define OldLibrary_ "/var/lib/cydia"
240
241 #define NewLibrary_ "/var/mobile/Library/Cydia"
242 system("cd /; su -c 'mkdir -p " NewLibrary_ "' mobile");
243
244 #define Cytore_ "/metadata.cb0"
245
246 if (access(NewLibrary_ Cytore_, F_OK) != 0 && errno == ENOENT) {
247 if (access(NewCache_ Cytore_, F_OK) == 0)
248 system("mv -f " NewCache_ Cytore_ " " NewLibrary_);
249 else if (access(OldLibrary_ Cytore_, F_OK) == 0)
250 system("mv -f " OldLibrary_ Cytore_ " " NewLibrary_);
251 chown(NewLibrary_ Cytore_, 501, 501);
252 }
1a2f455b 253
b132a972
JF
254 FixPermissions();
255
5530e234
JF
256 restart |= FixApplications();
257
258 if (restart)
86631cc4
JF
259 Finish("restart");
260
eaa9f122
JF
261 [pool release];
262 return 0;
263}