]>
Commit | Line | Data |
---|---|---|
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 |
12 | void 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 |
27 | static bool setnsfpn(const char *path) { |
28 | return system([[NSString stringWithFormat:@"/usr/libexec/cydia/setnsfpn %s", path] UTF8String]) == 0; | |
29 | } | |
30 | ||
bcc58607 JF |
31 | static 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 | 73 | static 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 |
85 | static 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" |
113 | static 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 |
176 | bool Changed_; |
177 | ||
407564b5 | 178 | _H<NSString> System_; |
eaa9f122 JF |
179 | |
180 | int 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 | } |