diff options
author | Jay Freeman (saurik) <saurik@saurik.com> | 2014-05-27 04:56:52 -0700 |
---|---|---|
committer | Jay Freeman (saurik) <saurik@saurik.com> | 2014-05-27 04:56:52 -0700 |
commit | 86631cc455af9d89ffac71610471829f72aa189f (patch) | |
tree | 63912b81b08634481ea444ef3d8fdaa7f4df3ab8 /postinst.mm | |
parent | 1342f8086e51e53220ae49f41a879a3c274173a4 (diff) |
Finally commit the careful status bar upgrade fix.
Diffstat (limited to 'postinst.mm')
-rw-r--r-- | postinst.mm | 81 |
1 files changed, 80 insertions, 1 deletions
diff --git a/postinst.mm b/postinst.mm index c14f7fe..a296943 100644 --- a/postinst.mm +++ b/postinst.mm @@ -1,11 +1,87 @@ +#include <dirent.h> #include <strings.h> + #include <Sources.h> -#include <sys/types.h> +#include <sys/stat.h> #include <sys/sysctl.h> +#include <sys/types.h> #include <Menes/ObjectHandle.h> +void Finish(const char *finish) { + if (finish == NULL) + return; + + const char *cydia(getenv("CYDIA")); + if (cydia == NULL) + return; + + int fd([[[[NSString stringWithUTF8String:cydia] componentsSeparatedByString:@" "] objectAtIndex:0] intValue]); + + FILE *fout(fdopen(fd, "w")); + fprintf(fout, "finish:%s\n", finish); + fclose(fout); +} + +#define APPLICATIONS "/Applications" +static bool FixApplications() { + char target[1024]; + ssize_t length(readlink(APPLICATIONS, target, sizeof(target))); + if (length == -1) + return false; + + if (length >= sizeof(target)) // >= "just in case" (I'm nervous) + return false; + target[length] = '\0'; + + if (strlen(target) != 30) + return false; + if (memcmp(target, "/var/stash/Applications.", 24) != 0) + return false; + if (strchr(target + 24, '/') != NULL) + return false; + + struct stat stat; + if (lstat(target, &stat) == -1) + return false; + if (!S_ISDIR(stat.st_mode)) + return false; + + char temp[] = "/var/stash/_.XXXXXX"; + if (mkdtemp(temp) == NULL) + return false; + + if (false) undo: { + unlink(temp); + return false; + } + + if (chmod(temp, 0755) == -1) + goto undo; + + char destiny[strlen(temp) + 32]; + sprintf(destiny, "%s%s", temp, APPLICATIONS); + + if (unlink(APPLICATIONS) == -1) + goto undo; + + if (rename(target, destiny) == -1) { + if (symlink(target, APPLICATIONS) == -1) + fprintf(stderr, "/Applications damaged -- DO NOT REBOOT\n"); + goto undo; + } else { + if (symlink(destiny, APPLICATIONS) == -1) + fprintf(stderr, "/var/stash/Applications damaged -- DO NOT REBOOT\n"); + + // 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; + } +} + _H<NSMutableDictionary> Sources_; bool Changed_; @@ -45,6 +121,9 @@ int main(int argc, const char *argv[]) { CydiaWriteSources(); + if (FixApplications()) + Finish("restart"); + [pool release]; return 0; } |