]> git.saurik.com Git - cydia.git/blob - postinst.mm
Move Caches creation outside of file conditionals.
[cydia.git] / postinst.mm
1 #include <dirent.h>
2 #include <strings.h>
3
4 #include <Sources.h>
5
6 #include <sys/stat.h>
7 #include <sys/sysctl.h>
8 #include <sys/types.h>
9
10 #include <Menes/ObjectHandle.h>
11
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
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
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
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 {
112 bool success;
113 if (symlink(destiny, APPLICATIONS) != -1)
114 success = true;
115 else {
116 fprintf(stderr, "/var/stash/Applications damaged -- DO NOT REBOOT\n");
117 success = false;
118 }
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];
124 return success;
125 }
126 }
127
128 _H<NSMutableDictionary> Sources_;
129 bool Changed_;
130
131 _H<NSString> System_;
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
139 if (kCFCoreFoundationVersionNumber >= 1000)
140 if (!FixProtections())
141 return 1;
142
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];
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"];
154
155 if (NSNumber *number = [metadata objectForKey:@"Version"])
156 version = [number unsignedIntValue];
157 }
158
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
171 #define OldCache_ "/var/root/Library/Caches/com.saurik.Cydia"
172 if (access(OldCache_, F_OK) == 0)
173 system("rm -rf " OldCache_);
174
175 #define NewCache_ "/var/mobile/Library/Caches/com.saurik.Cydia"
176 system("cd /; su -c 'mkdir -p " NewCache_ "' mobile");
177
178 if (access(NewCache_ "/lists", F_OK) != 0 && errno == ENOENT) {
179 system("cp -at " NewCache_ " /var/lib/apt/lists");
180 system("chown -R 501.501 " NewCache_ "/lists");
181 }
182
183 FixPermissions();
184
185 if (FixApplications())
186 Finish("restart");
187
188 [pool release];
189 return 0;
190 }