X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/86631cc455af9d89ffac71610471829f72aa189f..367a112d938db5c80814b42c428b517e4a65efd9:/postinst.mm diff --git a/postinst.mm b/postinst.mm index a2969439..f826f4ff 100644 --- a/postinst.mm +++ b/postinst.mm @@ -1,3 +1,5 @@ +#include "CyteKit/UCPlatform.h" + #include #include @@ -24,6 +26,96 @@ void Finish(const char *finish) { fclose(fout); } +static bool setnsfpn(const char *path) { + return system([[NSString stringWithFormat:@"/usr/libexec/cydia/setnsfpn %s", path] UTF8String]) == 0; +} + +enum StashStatus { + StashDone, + StashFail, + StashGood, +}; + +static StashStatus MoveStash() { + struct stat stat; + + if (lstat("/var/stash", &stat) == -1) + return errno == ENOENT ? StashGood : StashFail; + else if (S_ISLNK(stat.st_mode)) + return StashGood; + else if (!S_ISDIR(stat.st_mode)) + return StashFail; + + if (lstat("/var/db/stash", &stat) == -1) { + if (errno == ENOENT) + goto move; + else return StashFail; + } else if (S_ISLNK(stat.st_mode)) + // XXX: this is fixable + return StashFail; + else if (!S_ISDIR(stat.st_mode)) + return StashFail; + else { + if (!setnsfpn("/var/db/stash")) + return StashFail; + if (system("mv -t /var/stash /var/db/stash/*") != 0) + return StashFail; + if (rmdir("/var/db/stash") == -1) + return StashFail; + } move: + + if (!setnsfpn("/var/stash")) + return StashFail; + + if (rename("/var/stash", "/var/db/stash") == -1) + return StashFail; + if (symlink("/var/db/stash", "/var/stash") != -1) + return StashDone; + if (rename("/var/db/stash", "/var/stash") != -1) + return StashFail; + + fprintf(stderr, "/var/stash misplaced -- DO NOT REBOOT\n"); + return StashFail; +} + +static bool FixProtections() { + const char *path("/var/lib"); + mkdir(path, 0755); + if (!setnsfpn(path)) { + fprintf(stderr, "failed to setnsfpn %s\n", path); + return false; + } + + return true; +} + +static void FixPermissions() { + DIR *stash(opendir("/var/stash")); + if (stash == NULL) + return; + + while (dirent *entry = readdir(stash)) { + const char *folder(entry->d_name); + if (strlen(folder) != 8) + continue; + if (strncmp(folder, "_.", 2) != 0) + continue; + + char path[1024]; + sprintf(path, "/var/stash/%s", folder); + + struct stat stat; + if (lstat(path, &stat) == -1) + continue; + if (!S_ISDIR(stat.st_mode)) + continue; + + chmod(path, 0755); + } + + closedir(stash); +} + #define APPLICATIONS "/Applications" static bool FixApplications() { char target[1024]; @@ -71,57 +163,84 @@ static bool FixApplications() { fprintf(stderr, "/Applications damaged -- DO NOT REBOOT\n"); goto undo; } else { - if (symlink(destiny, APPLICATIONS) == -1) + bool success; + if (symlink(destiny, APPLICATIONS) != -1) + success = true; + else { fprintf(stderr, "/var/stash/Applications damaged -- DO NOT REBOOT\n"); + success = false; + } // unneccessary, but feels better (I'm nervous) symlink(destiny, target); [@APPLICATIONS writeToFile:[NSString stringWithFormat:@"%s.lnk", temp] atomically:YES encoding:NSNonLossyASCIIStringEncoding error:NULL]; - return true; + return success; } } -_H Sources_; -bool Changed_; - -_H System_; - int main(int argc, const char *argv[]) { if (argc < 2 || strcmp(argv[1], "configure") != 0) return 0; NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]); - size_t size; - sysctlbyname("kern.osversion", NULL, &size, NULL, 0); - char *osversion = new char[size]; - if (sysctlbyname("kern.osversion", osversion, &size, NULL, 0) != -1) - System_ = [NSString stringWithUTF8String:osversion]; - - NSDictionary *metadata([[[NSMutableDictionary alloc] initWithContentsOfFile:@"/var/lib/cydia/metadata.plist"] autorelease]); - NSUInteger version(0); - - if (metadata != nil) { - Sources_ = [metadata objectForKey:@"Sources"]; - - if (NSNumber *number = [metadata objectForKey:@"Version"]) - version = [number unsignedIntValue]; + bool restart(false); + + if (kCFCoreFoundationVersionNumber >= 1000) { + if (!FixProtections()) + return 1; + switch (MoveStash()) { + case StashDone: + restart = true; + break; + case StashFail: + fprintf(stderr, "failed to move stash\n"); + return 1; + case StashGood: + break; + } } - if (Sources_ == nil) - Sources_ = [NSMutableDictionary dictionaryWithCapacity:8]; - - if (version == 0) { - CydiaAddSource(@"http://apt.thebigboss.org/repofiles/cydia/", @"stable", [NSMutableArray arrayWithObject:@"main"]); - CydiaAddSource(@"http://apt.modmyi.com/", @"stable", [NSMutableArray arrayWithObject:@"main"]); - CydiaAddSource(@"http://cydia.zodttd.com/repo/cydia/", @"stable", [NSMutableArray arrayWithObject:@"main"]); - CydiaAddSource(@"http://repo666.ultrasn0w.com/", @"./"); + #define OldCache_ "/var/root/Library/Caches/com.saurik.Cydia" + if (access(OldCache_, F_OK) == 0) + system("rm -rf " OldCache_); + + #define NewCache_ "/var/mobile/Library/Caches/com.saurik.Cydia" + system("cd /; su -c 'mkdir -p " NewCache_ "' mobile"); + if (access(NewCache_ "/lists", F_OK) != 0 && errno == ENOENT) + system("cp -at " NewCache_ " /var/lib/apt/lists"); + system("chown -R 501.501 " NewCache_); + + #define OldLibrary_ "/var/lib/cydia" + + #define NewLibrary_ "/var/mobile/Library/Cydia" + system("cd /; su -c 'mkdir -p " NewLibrary_ "' mobile"); + + #define Cytore_ "/metadata.cb0" + + #define CYDIA_LIST "/etc/apt/sources.list.d/cydia.list" + unlink(CYDIA_LIST); + [[NSString stringWithFormat:@ + "deb http://apt.saurik.com/ ios/%.2f main\n" + "deb http://apt.thebigboss.org/repofiles/cydia/ stable main\n" + "deb http://cydia.zodttd.com/repo/cydia/ stable main\n" + "deb http://apt.modmyi.com/ stable main\n" + , kCFCoreFoundationVersionNumber] writeToFile:@ CYDIA_LIST atomically:YES]; + + if (access(NewLibrary_ Cytore_, F_OK) != 0 && errno == ENOENT) { + if (access(NewCache_ Cytore_, F_OK) == 0) + system("mv -f " NewCache_ Cytore_ " " NewLibrary_); + else if (access(OldLibrary_ Cytore_, F_OK) == 0) + system("mv -f " OldLibrary_ Cytore_ " " NewLibrary_); + chown(NewLibrary_ Cytore_, 501, 501); } - CydiaWriteSources(); + FixPermissions(); + + restart |= FixApplications(); - if (FixApplications()) + if (restart) Finish("restart"); [pool release];