1 | #ifndef URLADER |
1 | #ifndef URLADER |
2 | # define URLADER "urlader" |
2 | # define URLADER "urlader" |
3 | #endif |
3 | #endif |
4 | #define URLADER_VERSION "1.0" |
4 | #define URLADER_VERSION "1.0" // a decimal number, not a version string |
5 | |
5 | |
6 | #include <stdio.h> |
6 | #include <stdio.h> |
7 | #include <stdlib.h> |
7 | #include <stdlib.h> |
8 | #include <unistd.h> |
8 | #include <unistd.h> |
9 | #include <errno.h> |
9 | #include <errno.h> |
… | |
… | |
24 | #include <wininet.h> |
24 | #include <wininet.h> |
25 | |
25 | |
26 | static DWORD dword; |
26 | static DWORD dword; |
27 | |
27 | |
28 | #define u_handle HANDLE |
28 | #define u_handle HANDLE |
|
|
29 | #define u_valid(handle) (!!handle) |
|
|
30 | |
29 | #define u_setenv(name,value) SetEnvironmentVariable (name, value) |
31 | #define u_setenv(name,value) SetEnvironmentVariable (name, value) |
30 | #define u_mkdir(path) !CreateDirectory (path, NULL) |
32 | #define u_mkdir(path) !CreateDirectory (path, NULL) |
31 | #define u_chdir(path) !SetCurrentDirectory (path) |
33 | #define u_chdir(path) !SetCurrentDirectory (path) |
32 | #define u_rename(fr,to) !MoveFile (fr, to) |
34 | #define u_rename(fr,to) !MoveFile (fr, to) |
33 | #define u_open(path) CreateFile (path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL) |
35 | #define u_open(path) CreateFile (path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 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) |
36 | #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) |
37 | #define u_close(handle) CloseHandle (handle) |
36 | #define u_append(path,add) PathAppend (path, add) |
38 | #define u_append(path,add) PathAppend (path, add) |
37 | #define u_write(handle,data,len) (WriteFile (handle, data, len, &dword, 0) ? dword : -1) |
39 | #define u_write(handle,data,len) (WriteFile (handle, data, len, &dword, 0) ? dword : -1) |
38 | #define u_sync() // use transacted I/O? |
40 | |
|
|
41 | #define u_fsync(handle) FlushFileBuffers (handle) |
|
|
42 | #define u_sync() |
39 | |
43 | |
40 | #else |
44 | #else |
41 | |
45 | |
42 | #include <sys/mman.h> |
46 | #include <sys/mman.h> |
43 | #include <sys/types.h> |
47 | #include <sys/types.h> |
… | |
… | |
48 | #else |
52 | #else |
49 | #define MAX_PATH 4096 |
53 | #define MAX_PATH 4096 |
50 | #endif |
54 | #endif |
51 | |
55 | |
52 | #define u_handle int |
56 | #define u_handle int |
|
|
57 | #define u_valid(fd) ((fd) >= 0) |
|
|
58 | |
53 | #define u_setenv(name,value) setenv (name, value, 1) |
59 | #define u_setenv(name,value) setenv (name, value, 1) |
54 | #define u_mkdir(path) mkdir (path, 0777) |
60 | #define u_mkdir(path) mkdir (path, 0777) |
55 | #define u_chdir(path) chdir (path) |
61 | #define u_chdir(path) chdir (path) |
56 | #define u_rename(fr,to) rename (fr, to) |
62 | #define u_rename(fr,to) rename (fr, to) |
57 | #define u_open(path) open (path, O_RDONLY) + 1 |
63 | #define u_open(path) open (path, O_RDONLY) |
58 | #define u_creat(path,exec) open (path, O_WRONLY | O_CREAT | O_TRUNC, (exec) ? 0777 : 0666) + 1 |
64 | #define u_creat(path,exec) open (path, O_WRONLY | O_CREAT | O_TRUNC, (exec) ? 0777 : 0666) |
59 | #define u_close(handle) close (handle - 1) |
65 | #define u_close(handle) close (handle) |
60 | #define u_append(path,add) strcat (strcat (path, "/"), add) |
66 | #define u_append(path,add) strcat (strcat (path, "/"), add) |
61 | #define u_write(handle,data,len) write ((handle) - 1, data, len) |
67 | #define u_write(handle,data,len) write (handle, data, len) |
|
|
68 | |
|
|
69 | // on a mostly idle system, a sync at the end is certainly faster, hope for the best |
|
|
70 | #define u_fsync(handle) |
62 | #define u_sync() sync () |
71 | #define u_sync() sync () |
63 | |
72 | |
64 | #endif |
73 | #endif |
65 | |
74 | |
66 | #define u_16(ptr) (((ptr)[0] << 8) | (ptr)[1]) |
75 | #define u_16(ptr) (((ptr)[0] << 8) | (ptr)[1]) |
… | |
… | |
145 | |
154 | |
146 | enum |
155 | enum |
147 | { |
156 | { |
148 | T_NULL, // 5 |
157 | T_NULL, // 5 |
149 | T_META, // 1 : exe_id, exe_ver |
158 | T_META, // 1 : exe_id, exe_ver |
150 | T_ARG, // 2 : arg |
|
|
151 | T_ENV, // 3 : name, value |
159 | T_ENV, // 2 : name, value |
|
|
160 | T_ARG, // 3 : arg |
152 | T_DIR, // 4+: path |
161 | T_DIR, // 4+: path |
153 | T_FILE, // 4+: path, data |
162 | T_FILE, // 4+: path, data |
154 | T_NUM |
163 | T_NUM |
155 | }; |
164 | }; |
156 | |
165 | |
… | |
… | |
284 | |
293 | |
285 | if (u_chdir (exe_dir)) |
294 | if (u_chdir (exe_dir)) |
286 | fatal ("unable to change to application data directory"); |
295 | fatal ("unable to change to application data directory"); |
287 | |
296 | |
288 | u_handle h = u_open ("override"); |
297 | u_handle h = u_open ("override"); |
289 | if (h) |
298 | if (u_valid (h)) |
290 | { |
299 | { |
291 | u_handle oh = pack_handle; |
300 | u_handle oh = pack_handle; |
292 | |
301 | |
293 | pack_handle = h; |
302 | pack_handle = h; |
294 | if (!pack_map ()) |
303 | if (!pack_map ()) |
… | |
… | |
304 | fatal ("unable to locate override metadata"); |
313 | fatal ("unable to locate override metadata"); |
305 | |
314 | |
306 | strcpy (exe_ver, PACK_DATA); |
315 | strcpy (exe_ver, PACK_DATA); |
307 | pack_next (); |
316 | pack_next (); |
308 | |
317 | |
309 | while (pack_cur->type == T_ARG) |
318 | for (;;) |
310 | { |
319 | { |
|
|
320 | if (pack_cur->type == T_ENV) |
|
|
321 | u_setenv (PACK_NAME, PACK_DATA); |
|
|
322 | else if (pack_cur->type == T_ARG) |
311 | exe_argv [exe_argc++] = strdup (PACK_NAME); |
323 | exe_argv [exe_argc++] = strdup (PACK_NAME); |
|
|
324 | else |
|
|
325 | break; |
|
|
326 | |
312 | pack_next (); |
327 | pack_next (); |
313 | } |
328 | } |
314 | |
329 | |
315 | while (pack_cur->type == T_ENV) |
330 | done_env_arg: |
316 | { |
|
|
317 | u_setenv (PACK_NAME, PACK_DATA); |
|
|
318 | pack_next (); |
|
|
319 | } |
|
|
320 | |
|
|
321 | strcpy (execdir, exe_dir); |
331 | strcpy (execdir, exe_dir); |
322 | u_append (execdir, "i-"); |
332 | u_append (execdir, "i-"); |
323 | strcat (execdir, exe_ver); |
333 | strcat (execdir, exe_ver); |
324 | |
334 | |
325 | if (access (execdir, F_OK)) |
335 | if (access (execdir, F_OK)) |
… | |
… | |
351 | len = dlen; |
361 | len = dlen; |
352 | } |
362 | } |
353 | else |
363 | else |
354 | fatal ("unable to uncompress file data - pack corrupted?"); |
364 | fatal ("unable to uncompress file data - pack corrupted?"); |
355 | |
365 | |
356 | if (!h) |
366 | if (!u_valid (h)) |
357 | fatal ("unable to unpack file from packfile - disk full?"); |
367 | fatal ("unable to unpack file from packfile - disk full?"); |
358 | |
368 | |
359 | if (u_write (h, data, len) != len) |
369 | if (u_write (h, data, len) != len) |
360 | fatal ("unable to unpack file from packfile - disk full?"); |
370 | fatal ("unable to unpack file from packfile - disk full?"); |
361 | |
371 | |
|
|
372 | u_fsync (h); |
362 | u_close (h); |
373 | u_close (h); |
363 | } |
374 | } |
364 | break; |
375 | break; |
365 | |
376 | |
366 | case T_NULL: |
377 | case T_NULL: |
… | |
… | |
391 | u_setenv ("URLADER_EXECDIR", execdir); |
402 | u_setenv ("URLADER_EXECDIR", execdir); |
392 | u_setenv ("URLADER_EXE_ID" , exe_id); |
403 | u_setenv ("URLADER_EXE_ID" , exe_id); |
393 | u_setenv ("URLADER_EXE_DIR", exe_dir); |
404 | u_setenv ("URLADER_EXE_DIR", exe_dir); |
394 | u_setenv ("URLADER_EXE_VER", exe_ver); |
405 | u_setenv ("URLADER_EXE_VER", exe_ver); |
395 | |
406 | |
|
|
407 | #if 0 |
396 | // yes, this is overkill |
408 | // yes, this is overkill |
397 | u_setenv ("SHLIB_PATH" , execdir); // hpux |
409 | u_setenv ("SHLIB_PATH" , execdir); // hpux |
398 | u_setenv ("LIBPATH" , execdir); // aix |
410 | u_setenv ("LIBPATH" , execdir); // aix |
399 | u_setenv ("LD_LIBRARY_PATH" , execdir); // most elf systems |
411 | u_setenv ("LD_LIBRARY_PATH" , execdir); // most elf systems |
400 | u_setenv ("LD_LIBRARY_PATH_32", execdir); // solaris |
412 | u_setenv ("LD_LIBRARY_PATH_32", execdir); // solaris |
401 | u_setenv ("LD_LIBRARY_PATH_64", execdir); // solaris |
413 | u_setenv ("LD_LIBRARY_PATH_64", execdir); // solaris |
402 | u_setenv ("LD_LIBRARYN32_PATH", execdir); // irix |
414 | u_setenv ("LD_LIBRARYN32_PATH", execdir); // irix |
403 | u_setenv ("LD_LIBRARY64_PATH" , execdir); // irix |
415 | u_setenv ("LD_LIBRARY64_PATH" , execdir); // irix |
404 | u_setenv ("DYLD_LIBRARY_PATH" , execdir); // os sucks from apple |
416 | u_setenv ("DYLD_LIBRARY_PATH" , execdir); // os sucks from apple |
|
|
417 | #endif |
405 | } |
418 | } |
406 | |
419 | |
407 | static void |
420 | static void |
408 | execute (void) |
421 | execute (void) |
409 | { |
422 | { |
… | |
… | |
417 | WinMain (HINSTANCE hI, HINSTANCE hP, LPSTR argv, int command_show) |
430 | WinMain (HINSTANCE hI, HINSTANCE hP, LPSTR argv, int command_show) |
418 | { |
431 | { |
419 | if (!GetModuleFileName (hI, tmppath, sizeof (tmppath))) |
432 | if (!GetModuleFileName (hI, tmppath, sizeof (tmppath))) |
420 | fatal ("unable to find executable pack"); |
433 | fatal ("unable to find executable pack"); |
421 | |
434 | |
422 | if (!(pack_handle = u_open (tmppath))) |
435 | pack_handle = u_open (tmppath); |
|
|
436 | if (!u_valid (pack_handle)) |
423 | fatal ("unable to open executable pack"); |
437 | fatal ("unable to open executable pack"); |
424 | |
438 | |
425 | exe_info (); |
439 | exe_info (); |
426 | |
440 | |
427 | if (!GetCurrentDirectory (sizeof (currdir), currdir)) |
441 | if (!GetCurrentDirectory (sizeof (currdir), currdir)) |
… | |
… | |
444 | int |
458 | int |
445 | main (int argc, char *argv[]) |
459 | main (int argc, char *argv[]) |
446 | { |
460 | { |
447 | char *home = getenv ("HOME"); |
461 | char *home = getenv ("HOME"); |
448 | |
462 | |
449 | // we assume fd 0 and 2 are "normal" |
|
|
450 | |
|
|
451 | if (!(pack_handle = u_open (argv [0]))) |
463 | pack_handle = u_open (argv [0]); |
|
|
464 | if (!u_valid (pack_handle)) |
452 | fatal ("unable to open executable pack"); |
465 | fatal ("unable to open executable pack"); |
453 | |
466 | |
454 | exe_info (); |
467 | exe_info (); |
455 | |
468 | |
456 | if (!home) |
469 | if (!home) |
… | |
… | |
468 | |
481 | |
469 | u_mkdir (home); |
482 | u_mkdir (home); |
470 | sprintf (datadir, "%s/.%s", home, URLADER); |
483 | sprintf (datadir, "%s/.%s", home, URLADER); |
471 | u_mkdir (datadir); |
484 | u_mkdir (datadir); |
472 | |
485 | |
|
|
486 | #if 0 |
473 | if (gethostname (tmppath, sizeof (tmppath))) |
487 | if (gethostname (tmppath, sizeof (tmppath))) |
474 | strcpy (tmppath, "default"); |
488 | strcpy (tmppath, "default"); |
475 | |
489 | |
476 | u_append (datadir, tmppath); |
490 | u_append (datadir, tmppath); |
|
|
491 | #endif |
477 | |
492 | |
478 | load (); |
493 | load (); |
479 | execute (); |
494 | execute (); |
480 | |
495 | |
481 | return 0; |
496 | return 0; |