… | |
… | |
9 | #include <errno.h> |
9 | #include <errno.h> |
10 | #include <string.h> |
10 | #include <string.h> |
11 | #include <time.h> |
11 | #include <time.h> |
12 | #include <fcntl.h> |
12 | #include <fcntl.h> |
13 | |
13 | |
14 | #include "lzf_d.c" |
14 | #include "liblzf/lzf_d.c" |
15 | |
15 | |
16 | #define TAIL_MAGIC "SCHMORPPACK0" |
16 | #define TAIL_MAGIC "SCHMORPPACK0" |
17 | |
17 | |
18 | #ifdef _WIN32 |
18 | #ifdef _WIN32 |
19 | |
19 | |
… | |
… | |
34 | #define u_creat(path,exec) CreateFile (path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL) |
34 | #define u_creat(path,exec) CreateFile (path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL) |
35 | #define u_close(handle) CloseHandle (handle) |
35 | #define u_close(handle) CloseHandle (handle) |
36 | #define u_append(path,add) PathAppend (path, add) |
36 | #define u_append(path,add) PathAppend (path, add) |
37 | #define u_write(handle,data,len) (WriteFile (handle, data, len, &dword, 0) ? dword : -1) |
37 | #define u_write(handle,data,len) (WriteFile (handle, data, len, &dword, 0) ? dword : -1) |
38 | |
38 | |
|
|
39 | #define u_fsync(handle) FlushFileBuffers (handle) |
|
|
40 | #define u_sync() |
|
|
41 | |
39 | #else |
42 | #else |
40 | |
43 | |
41 | #include <sys/mman.h> |
44 | #include <sys/mman.h> |
42 | #include <sys/types.h> |
45 | #include <sys/types.h> |
43 | #include <pwd.h> |
46 | #include <pwd.h> |
… | |
… | |
57 | #define u_creat(path,exec) open (path, O_WRONLY | O_CREAT | O_TRUNC, (exec) ? 0777 : 0666) + 1 |
60 | #define u_creat(path,exec) open (path, O_WRONLY | O_CREAT | O_TRUNC, (exec) ? 0777 : 0666) + 1 |
58 | #define u_close(handle) close (handle - 1) |
61 | #define u_close(handle) close (handle - 1) |
59 | #define u_append(path,add) strcat (strcat (path, "/"), add) |
62 | #define u_append(path,add) strcat (strcat (path, "/"), add) |
60 | #define u_write(handle,data,len) write ((handle) - 1, data, len) |
63 | #define u_write(handle,data,len) write ((handle) - 1, data, len) |
61 | |
64 | |
|
|
65 | // on a mostly idle system, a sync at the end is certainly faster, hope for the best |
|
|
66 | #define u_fsync(handle) |
|
|
67 | #define u_sync() sync () |
|
|
68 | |
62 | #endif |
69 | #endif |
63 | |
70 | |
64 | #define u_16(ptr) (((ptr)[0] << 8) | (ptr)[1]) |
71 | #define u_16(ptr) (((ptr)[0] << 8) | (ptr)[1]) |
65 | #define u_32(ptr) (((ptr)[0] << 24) | ((ptr)[1] << 16) | ((ptr)[2] << 8) | (ptr)[3]) |
72 | #define u_32(ptr) (((ptr)[0] << 24) | ((ptr)[1] << 16) | ((ptr)[2] << 8) | (ptr)[3]) |
66 | |
73 | |
… | |
… | |
105 | return; |
112 | return; |
106 | } |
113 | } |
107 | } |
114 | } |
108 | |
115 | |
109 | static void |
116 | static void |
110 | systemv (const char *const argv[]) |
117 | systemv (const char *const argv[], int dowait) |
111 | { |
118 | { |
112 | #ifdef _WIN32 |
119 | #ifdef _WIN32 |
113 | _spawnv (P_WAIT, argv [0], argv); |
120 | _spawnv (P_WAIT, argv [0], argv); |
114 | #else |
121 | #else |
115 | pid_t pid = fork (); |
122 | pid_t pid = dowait ? fork () : 0; |
116 | |
123 | |
117 | if (pid < 0) |
124 | if (pid < 0) |
118 | fatal ("fork failure"); |
125 | fatal ("fork failure"); |
119 | |
126 | |
120 | if (!pid) |
127 | if (!pid) |
… | |
… | |
136 | const char *argv[] = { getenv ("COMSPEC"), "/c", "rd", "/s", "/q", buf, 0 }; |
143 | const char *argv[] = { getenv ("COMSPEC"), "/c", "rd", "/s", "/q", buf, 0 }; |
137 | sprintf (buf, "\"%s\"", path); |
144 | sprintf (buf, "\"%s\"", path); |
138 | #else |
145 | #else |
139 | const char *argv[] = { "/bin/rm", "-rf", path, 0 }; |
146 | const char *argv[] = { "/bin/rm", "-rf", path, 0 }; |
140 | #endif |
147 | #endif |
141 | systemv (argv); |
148 | systemv (argv, 1); |
142 | } |
|
|
143 | |
|
|
144 | static void |
|
|
145 | execute (void) |
|
|
146 | { |
|
|
147 | exe_argv [exe_argc] = 0; |
|
|
148 | systemv (exe_argv); |
|
|
149 | } |
149 | } |
150 | |
150 | |
151 | enum |
151 | enum |
152 | { |
152 | { |
153 | T_NULL, // 5 |
153 | T_NULL, // 5 |
154 | T_META, // 1 : exe_id, exe_ver |
154 | T_META, // 1 : exe_id, exe_ver |
155 | T_ARG, // 2 : arg |
|
|
156 | T_ENV, // 3 : name, value |
155 | T_ENV, // 2 : name, value |
|
|
156 | T_ARG, // 3 : arg |
157 | T_DIR, // 4+: path |
157 | T_DIR, // 4+: path |
158 | T_FILE, // 4+: path, data |
158 | T_FILE, // 4+: path, data |
159 | T_NUM |
159 | T_NUM |
160 | }; |
160 | }; |
161 | |
161 | |
… | |
… | |
180 | char magic[12]; |
180 | char magic[12]; |
181 | }; |
181 | }; |
182 | |
182 | |
183 | static char *pack_base, *pack_end; |
183 | static char *pack_base, *pack_end; |
184 | static struct hdr *pack_cur; |
184 | static struct hdr *pack_cur; |
|
|
185 | static char *scratch; |
|
|
186 | static unsigned int scratch_len; |
185 | |
187 | |
186 | #define PACK_NAME ((char *)(pack_cur + 1)) |
188 | #define PACK_NAME ((char *)(pack_cur + 1)) |
187 | #define PACK_DATA (PACK_NAME + u_16 (pack_cur->namelen) + 1) |
189 | #define PACK_DATA (PACK_NAME + u_16 (pack_cur->namelen) + 1) |
188 | #define PACK_VALID pack_cur->type |
190 | #define PACK_VALID pack_cur->type |
189 | |
191 | |
… | |
… | |
199 | pack_unmap (void) |
201 | pack_unmap (void) |
200 | { |
202 | { |
201 | if (!pack_base) |
203 | if (!pack_base) |
202 | return; |
204 | return; |
203 | |
205 | |
|
|
206 | free (scratch); |
|
|
207 | |
204 | #ifdef _WIN32 |
208 | #ifdef _WIN32 |
205 | UnmapViewOfFile (pack_base); |
209 | UnmapViewOfFile (pack_base); |
206 | #else |
210 | #else |
207 | munmap (pack_base, pack_end - pack_base); |
211 | munmap (pack_base, pack_end - pack_base); |
208 | #endif |
212 | #endif |
… | |
… | |
253 | |
257 | |
254 | if (memcmp (tail->magic, TAIL_MAGIC, sizeof (TAIL_MAGIC) - 1)) |
258 | if (memcmp (tail->magic, TAIL_MAGIC, sizeof (TAIL_MAGIC) - 1)) |
255 | return 0; |
259 | return 0; |
256 | |
260 | |
257 | pack_cur = (struct hdr *)(pack_end - u_32 (tail->size)); |
261 | pack_cur = (struct hdr *)(pack_end - u_32 (tail->size)); |
|
|
262 | |
|
|
263 | free (scratch); |
|
|
264 | scratch = malloc (scratch_len = u_32 (tail->max_filesize)); |
258 | |
265 | |
259 | return 1; |
266 | return 1; |
260 | } |
267 | } |
261 | |
268 | |
262 | static void |
269 | static void |
… | |
… | |
302 | fatal ("unable to locate override metadata"); |
309 | fatal ("unable to locate override metadata"); |
303 | |
310 | |
304 | strcpy (exe_ver, PACK_DATA); |
311 | strcpy (exe_ver, PACK_DATA); |
305 | pack_next (); |
312 | pack_next (); |
306 | |
313 | |
|
|
314 | for (;;) |
|
|
315 | { |
|
|
316 | if (pack_cur->type == T_ENV) |
|
|
317 | u_setenv (PACK_NAME, PACK_DATA); |
307 | while (pack_cur->type == T_ARG) |
318 | else if (pack_cur->type == T_ARG) |
308 | { |
|
|
309 | exe_argv [exe_argc++] = strdup (PACK_NAME); |
319 | exe_argv [exe_argc++] = strdup (PACK_NAME); |
|
|
320 | else |
|
|
321 | break; |
|
|
322 | |
310 | pack_next (); |
323 | pack_next (); |
311 | } |
324 | } |
312 | |
325 | |
313 | while (pack_cur->type == T_ENV) |
326 | done_env_arg: |
314 | { |
|
|
315 | u_setenv (PACK_NAME, PACK_DATA); |
|
|
316 | pack_next (); |
|
|
317 | } |
|
|
318 | |
|
|
319 | strcpy (execdir, exe_dir); |
327 | strcpy (execdir, exe_dir); |
320 | u_append (execdir, "i-"); |
328 | u_append (execdir, "i-"); |
321 | strcat (execdir, exe_ver); |
329 | strcat (execdir, exe_ver); |
322 | |
330 | |
323 | if (access (execdir, F_OK)) |
331 | if (access (execdir, F_OK)) |
… | |
… | |
337 | break; |
345 | break; |
338 | |
346 | |
339 | case T_FILE: |
347 | case T_FILE: |
340 | { |
348 | { |
341 | u_handle h = u_creat (PACK_NAME, pack_cur->flags & F_EXEC); |
349 | u_handle h = u_creat (PACK_NAME, pack_cur->flags & F_EXEC); |
342 | unsigned int len = u_32 (pack_cur->datalen); |
350 | unsigned int dlen, len = u_32 (pack_cur->datalen); |
|
|
351 | char *data = PACK_DATA; |
|
|
352 | |
|
|
353 | if (pack_cur->flags & F_LZF) |
|
|
354 | if (dlen = lzf_decompress (data, len, scratch, scratch_len)) |
|
|
355 | { |
|
|
356 | data = scratch; |
|
|
357 | len = dlen; |
|
|
358 | } |
|
|
359 | else |
|
|
360 | fatal ("unable to uncompress file data - pack corrupted?"); |
343 | |
361 | |
344 | if (!h) |
362 | if (!h) |
345 | fatal ("unable to unpack file from packfile - disk full?"); |
363 | fatal ("unable to unpack file from packfile - disk full?"); |
346 | |
364 | |
347 | if (u_write (h, PACK_DATA, len) != len) |
365 | if (u_write (h, data, len) != len) |
348 | fatal ("unable to unpack file from packfile - disk full?"); |
366 | fatal ("unable to unpack file from packfile - disk full?"); |
349 | |
367 | |
|
|
368 | u_fsync (h); |
350 | u_close (h); |
369 | u_close (h); |
351 | } |
370 | } |
352 | break; |
371 | break; |
353 | |
372 | |
354 | case T_NULL: |
373 | case T_NULL: |
… | |
… | |
360 | |
379 | |
361 | done: |
380 | done: |
362 | if (u_chdir (datadir)) |
381 | if (u_chdir (datadir)) |
363 | fatal ("unable to change to data directory"); |
382 | fatal ("unable to change to data directory"); |
364 | |
383 | |
|
|
384 | u_sync (); |
|
|
385 | |
365 | if (u_rename (tmppath, execdir)) |
386 | if (u_rename (tmppath, execdir)) |
366 | deltree (tmppath); // if move fails, delete new, assume other process created it independently |
387 | deltree (tmppath); // if move fails, delete new, assume other process created it independently |
367 | |
|
|
368 | if (u_chdir (execdir)) |
|
|
369 | fatal ("unable to change to application instance directory"); |
|
|
370 | } |
388 | } |
371 | |
389 | |
372 | pack_unmap (); |
390 | pack_unmap (); |
373 | u_close (pack_handle); |
391 | u_close (pack_handle); |
|
|
392 | |
|
|
393 | if (u_chdir (execdir)) |
|
|
394 | fatal ("unable to change to application instance directory"); |
374 | |
395 | |
375 | u_setenv ("URLADER_VERSION", URLADER_VERSION); |
396 | u_setenv ("URLADER_VERSION", URLADER_VERSION); |
376 | u_setenv ("URLADER_DATADIR", datadir); |
397 | u_setenv ("URLADER_DATADIR", datadir); |
377 | u_setenv ("URLADER_EXECDIR", execdir); |
398 | u_setenv ("URLADER_EXECDIR", execdir); |
378 | u_setenv ("URLADER_EXE_ID" , exe_id); |
399 | u_setenv ("URLADER_EXE_ID" , exe_id); |
… | |
… | |
388 | u_setenv ("LD_LIBRARYN32_PATH", execdir); // irix |
409 | u_setenv ("LD_LIBRARYN32_PATH", execdir); // irix |
389 | u_setenv ("LD_LIBRARY64_PATH" , execdir); // irix |
410 | u_setenv ("LD_LIBRARY64_PATH" , execdir); // irix |
390 | u_setenv ("DYLD_LIBRARY_PATH" , execdir); // os sucks from apple |
411 | u_setenv ("DYLD_LIBRARY_PATH" , execdir); // os sucks from apple |
391 | } |
412 | } |
392 | |
413 | |
|
|
414 | static void |
|
|
415 | execute (void) |
|
|
416 | { |
|
|
417 | exe_argv [exe_argc] = 0; |
|
|
418 | systemv (exe_argv, 0); |
|
|
419 | } |
|
|
420 | |
393 | #ifdef _WIN32 |
421 | #ifdef _WIN32 |
394 | |
422 | |
395 | int APIENTRY |
423 | int APIENTRY |
396 | WinMain (HINSTANCE hI, HINSTANCE hP, LPSTR argv, int command_show) |
424 | WinMain (HINSTANCE hI, HINSTANCE hP, LPSTR argv, int command_show) |
397 | { |
425 | { |