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 | ||
82e370b3 JF |
27 | static bool FixProtections() { |
28 | for (const char *path : (const char *[]) {"/var/lib", "/var/cache", "/var/stash"}) { | |
29 | mkdir(path, 0755); | |
30 | if (system([[NSString stringWithFormat:@"/usr/libexec/cydia/setnsfpn %s", path] UTF8String]) != 0) { | |
31 | fprintf(stderr, "failed to setnsfpn %s\n", path); | |
32 | return false; | |
33 | } | |
34 | } | |
35 | return true; | |
36 | } | |
37 | ||
b132a972 JF |
38 | static void FixPermissions() { |
39 | DIR *stash(opendir("/var/stash")); | |
40 | if (stash == NULL) | |
41 | return; | |
42 | ||
43 | while (dirent *entry = readdir(stash)) { | |
44 | const char *folder(entry->d_name); | |
45 | if (strlen(folder) != 8) | |
46 | continue; | |
47 | if (strncmp(folder, "_.", 2) != 0) | |
48 | continue; | |
49 | ||
50 | char path[1024]; | |
51 | sprintf(path, "/var/stash/%s", folder); | |
52 | ||
53 | struct stat stat; | |
54 | if (lstat(path, &stat) == -1) | |
55 | continue; | |
56 | if (!S_ISDIR(stat.st_mode)) | |
57 | continue; | |
58 | ||
59 | chmod(path, 0755); | |
60 | } | |
61 | ||
62 | closedir(stash); | |
63 | } | |
64 | ||
86631cc4 JF |
65 | #define APPLICATIONS "/Applications" |
66 | static bool FixApplications() { | |
67 | char target[1024]; | |
68 | ssize_t length(readlink(APPLICATIONS, target, sizeof(target))); | |
69 | if (length == -1) | |
70 | return false; | |
71 | ||
72 | if (length >= sizeof(target)) // >= "just in case" (I'm nervous) | |
73 | return false; | |
74 | target[length] = '\0'; | |
75 | ||
76 | if (strlen(target) != 30) | |
77 | return false; | |
78 | if (memcmp(target, "/var/stash/Applications.", 24) != 0) | |
79 | return false; | |
80 | if (strchr(target + 24, '/') != NULL) | |
81 | return false; | |
82 | ||
83 | struct stat stat; | |
84 | if (lstat(target, &stat) == -1) | |
85 | return false; | |
86 | if (!S_ISDIR(stat.st_mode)) | |
87 | return false; | |
88 | ||
89 | char temp[] = "/var/stash/_.XXXXXX"; | |
90 | if (mkdtemp(temp) == NULL) | |
91 | return false; | |
92 | ||
93 | if (false) undo: { | |
94 | unlink(temp); | |
95 | return false; | |
96 | } | |
97 | ||
98 | if (chmod(temp, 0755) == -1) | |
99 | goto undo; | |
100 | ||
101 | char destiny[strlen(temp) + 32]; | |
102 | sprintf(destiny, "%s%s", temp, APPLICATIONS); | |
103 | ||
104 | if (unlink(APPLICATIONS) == -1) | |
105 | goto undo; | |
106 | ||
107 | if (rename(target, destiny) == -1) { | |
108 | if (symlink(target, APPLICATIONS) == -1) | |
109 | fprintf(stderr, "/Applications damaged -- DO NOT REBOOT\n"); | |
110 | goto undo; | |
111 | } else { | |
2e007a72 JF |
112 | bool success; |
113 | if (symlink(destiny, APPLICATIONS) != -1) | |
114 | success = true; | |
115 | else { | |
86631cc4 | 116 | fprintf(stderr, "/var/stash/Applications damaged -- DO NOT REBOOT\n"); |
2e007a72 JF |
117 | success = false; |
118 | } | |
86631cc4 JF |
119 | |
120 | // unneccessary, but feels better (I'm nervous) | |
121 | symlink(destiny, target); | |
122 | ||
123 | [@APPLICATIONS writeToFile:[NSString stringWithFormat:@"%s.lnk", temp] atomically:YES encoding:NSNonLossyASCIIStringEncoding error:NULL]; | |
2e007a72 | 124 | return success; |
86631cc4 JF |
125 | } |
126 | } | |
127 | ||
eaa9f122 | 128 | _H<NSMutableDictionary> Sources_; |
eaa9f122 JF |
129 | bool Changed_; |
130 | ||
407564b5 | 131 | _H<NSString> System_; |
eaa9f122 JF |
132 | |
133 | int main(int argc, const char *argv[]) { | |
134 | if (argc < 2 || strcmp(argv[1], "configure") != 0) | |
135 | return 0; | |
136 | ||
137 | NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]); | |
138 | ||
82e370b3 JF |
139 | if (kCFCoreFoundationVersionNumber >= 1000) |
140 | if (!FixProtections()) | |
141 | return 1; | |
142 | ||
407564b5 JF |
143 | size_t size; |
144 | sysctlbyname("kern.osversion", NULL, &size, NULL, 0); | |
145 | char *osversion = new char[size]; | |
146 | if (sysctlbyname("kern.osversion", osversion, &size, NULL, 0) != -1) | |
147 | System_ = [NSString stringWithUTF8String:osversion]; | |
eaa9f122 JF |
148 | |
149 | NSDictionary *metadata([[[NSMutableDictionary alloc] initWithContentsOfFile:@"/var/lib/cydia/metadata.plist"] autorelease]); | |
150 | NSUInteger version(0); | |
151 | ||
152 | if (metadata != nil) { | |
153 | Sources_ = [metadata objectForKey:@"Sources"]; | |
eaa9f122 JF |
154 | |
155 | if (NSNumber *number = [metadata objectForKey:@"Version"]) | |
156 | version = [number unsignedIntValue]; | |
157 | } | |
158 | ||
eaa9f122 JF |
159 | if (Sources_ == nil) |
160 | Sources_ = [NSMutableDictionary dictionaryWithCapacity:8]; | |
161 | ||
162 | if (version == 0) { | |
163 | CydiaAddSource(@"http://apt.thebigboss.org/repofiles/cydia/", @"stable", [NSMutableArray arrayWithObject:@"main"]); | |
164 | CydiaAddSource(@"http://apt.modmyi.com/", @"stable", [NSMutableArray arrayWithObject:@"main"]); | |
165 | CydiaAddSource(@"http://cydia.zodttd.com/repo/cydia/", @"stable", [NSMutableArray arrayWithObject:@"main"]); | |
166 | CydiaAddSource(@"http://repo666.ultrasn0w.com/", @"./"); | |
167 | } | |
168 | ||
169 | CydiaWriteSources(); | |
170 | ||
b132a972 JF |
171 | FixPermissions(); |
172 | ||
86631cc4 JF |
173 | if (FixApplications()) |
174 | Finish("restart"); | |
175 | ||
eaa9f122 JF |
176 | [pool release]; |
177 | return 0; | |
178 | } |