7 #include <sys/sysctl.h>
10 #include <Menes/ObjectHandle.h>
12 void Finish(const char *finish) {
16 const char *cydia(getenv("CYDIA"));
20 int fd([[[[NSString stringWithUTF8String:cydia] componentsSeparatedByString:@" "] objectAtIndex:0] intValue]);
22 FILE *fout(fdopen(fd, "w"));
23 fprintf(fout, "finish:%s\n", finish);
27 static bool setnsfpn(const char *path) {
28 return system([[NSString stringWithFormat:@"/usr/libexec/cydia/setnsfpn %s", path] UTF8String]) == 0;
31 static bool MoveStash() {
34 if (lstat("/var/stash", &stat) == -1)
35 return errno == ENOENT;
36 else if (S_ISLNK(stat.st_mode))
38 else if (!S_ISDIR(stat.st_mode))
41 if (lstat("/var/db/stash", &stat) == -1) {
45 } else if (S_ISLNK(stat.st_mode))
46 // XXX: this is fixable
48 else if (!S_ISDIR(stat.st_mode))
51 if (!setnsfpn("/var/db/stash"))
53 if (system("mv -t /var/stash /var/db/stash/*") != 0)
55 if (rmdir("/var/db/stash") == -1)
59 if (!setnsfpn("/var/stash"))
62 if (rename("/var/stash", "/var/db/stash") == -1)
64 if (symlink("/var/db/stash", "/var/stash") != -1)
66 if (rename("/var/db/stash", "/var/stash") != -1)
69 fprintf(stderr, "/var/stash misplaced -- DO NOT REBOOT\n");
73 static bool FixProtections() {
74 const char *path("/var/lib");
76 if (!setnsfpn(path)) {
77 fprintf(stderr, "failed to setnsfpn %s\n", path);
84 static void FixPermissions() {
85 DIR *stash(opendir("/var/stash"));
89 while (dirent *entry = readdir(stash)) {
90 const char *folder(entry->d_name);
91 if (strlen(folder) != 8)
93 if (strncmp(folder, "_.", 2) != 0)
97 sprintf(path, "/var/stash/%s", folder);
100 if (lstat(path, &stat) == -1)
102 if (!S_ISDIR(stat.st_mode))
111 #define APPLICATIONS "/Applications"
112 static bool FixApplications() {
114 ssize_t length(readlink(APPLICATIONS, target, sizeof(target)));
118 if (length >= sizeof(target)) // >= "just in case" (I'm nervous)
120 target[length] = '\0';
122 if (strlen(target) != 30)
124 if (memcmp(target, "/var/stash/Applications.", 24) != 0)
126 if (strchr(target + 24, '/') != NULL)
130 if (lstat(target, &stat) == -1)
132 if (!S_ISDIR(stat.st_mode))
135 char temp[] = "/var/stash/_.XXXXXX";
136 if (mkdtemp(temp) == NULL)
144 if (chmod(temp, 0755) == -1)
147 char destiny[strlen(temp) + 32];
148 sprintf(destiny, "%s%s", temp, APPLICATIONS);
150 if (unlink(APPLICATIONS) == -1)
153 if (rename(target, destiny) == -1) {
154 if (symlink(target, APPLICATIONS) == -1)
155 fprintf(stderr, "/Applications damaged -- DO NOT REBOOT\n");
159 if (symlink(destiny, APPLICATIONS) != -1)
162 fprintf(stderr, "/var/stash/Applications damaged -- DO NOT REBOOT\n");
166 // unneccessary, but feels better (I'm nervous)
167 symlink(destiny, target);
169 [@APPLICATIONS writeToFile:[NSString stringWithFormat:@"%s.lnk", temp] atomically:YES encoding:NSNonLossyASCIIStringEncoding error:NULL];
174 int main(int argc, const char *argv[]) {
175 if (argc < 2 || strcmp(argv[1], "configure") != 0)
178 NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
182 if (kCFCoreFoundationVersionNumber >= 1000) {
183 if (!FixProtections())
188 fprintf(stderr, "failed to move stash\n");
193 #define OldCache_ "/var/root/Library/Caches/com.saurik.Cydia"
194 if (access(OldCache_, F_OK) == 0)
195 system("rm -rf " OldCache_);
197 #define NewCache_ "/var/mobile/Library/Caches/com.saurik.Cydia"
198 system("cd /; su -c 'mkdir -p " NewCache_ "' mobile");
199 if (access(NewCache_ "/lists", F_OK) != 0 && errno == ENOENT)
200 system("cp -at " NewCache_ " /var/lib/apt/lists");
201 system("chown -R 501.501 " NewCache_);
203 #define OldLibrary_ "/var/lib/cydia"
205 #define NewLibrary_ "/var/mobile/Library/Cydia"
206 system("cd /; su -c 'mkdir -p " NewLibrary_ "' mobile");
208 #define Cytore_ "/metadata.cb0"
210 if (access(NewLibrary_ Cytore_, F_OK) != 0 && errno == ENOENT) {
211 if (access(NewCache_ Cytore_, F_OK) == 0)
212 system("mv -f " NewCache_ Cytore_ " " NewLibrary_);
213 else if (access(OldLibrary_ Cytore_, F_OK) == 0)
214 system("mv -f " OldLibrary_ Cytore_ " " NewLibrary_);
215 chown(NewLibrary_ Cytore_, 501, 501);
220 restart |= FixApplications();