|
1 /* |
|
2 * Bootloader for a packed executable. |
|
3 * Copyright (C) 2005, Giovanni Bajo |
|
4 * Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc. |
|
5 * |
|
6 * This program is free software; you can redistribute it and/or |
|
7 * modify it under the terms of the GNU General Public License |
|
8 * as published by the Free Software Foundation; either version 2 |
|
9 * of the License, or (at your option) any later version. |
|
10 * |
|
11 * In addition to the permissions in the GNU General Public License, the |
|
12 * authors give you unlimited permission to link or embed the compiled |
|
13 * version of this file into combinations with other programs, and to |
|
14 * distribute those combinations without any restriction coming from the |
|
15 * use of this file. (The General Public License restrictions do apply in |
|
16 * other respects; for example, they cover modification of the file, and |
|
17 * distribution when not linked into a combine executable.) |
|
18 * |
|
19 * This program is distributed in the hope that it will be useful, |
|
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
22 * GNU General Public License for more details. |
|
23 * |
|
24 * You should have received a copy of the GNU General Public License |
|
25 * along with this program; if not, write to the Free Software |
|
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|
27 */ |
|
28 #include "launch.h" |
|
29 |
|
30 #ifdef FREEZE_EXCEPTIONS |
|
31 extern unsigned char M_exceptions[]; |
|
32 static struct _frozen _PyImport_FrozenModules[] = { |
|
33 {"exceptions", M_exceptions, EXCEPTIONS_LEN}, |
|
34 {0, 0, 0} |
|
35 }; |
|
36 #endif |
|
37 int main(int argc, char* argv[]) |
|
38 { |
|
39 char thisfile[_MAX_PATH]; |
|
40 char homepath[_MAX_PATH]; |
|
41 char magic_envvar[_MAX_PATH + 12]; |
|
42 char ldlib_envvar[_MAX_PATH * 4 + 12]; |
|
43 char archivefile[_MAX_PATH + 5]; |
|
44 char *oldldlib; |
|
45 TOC *ptoc = NULL; |
|
46 int rc = 0; |
|
47 char *workpath = NULL; |
|
48 /* atexit(cleanUp); */ |
|
49 #ifdef FREEZE_EXCEPTIONS |
|
50 PyImport_FrozenModules = _PyImport_FrozenModules; |
|
51 #endif |
|
52 // fill in thisfile |
|
53 #ifdef __CYGWIN__ |
|
54 if (strncasecmp(&argv[0][strlen(argv[0])-4], ".exe", 4)) { |
|
55 strcpy(thisfile, argv[0]); |
|
56 strcat(thisfile, ".exe"); |
|
57 Py_SetProgramName(thisfile); |
|
58 } |
|
59 else |
|
60 #endif |
|
61 Py_SetProgramName(argv[0]); |
|
62 strcpy(thisfile, Py_GetProgramFullPath()); |
|
63 VS(thisfile); |
|
64 VS(" is thisfile\n"); |
|
65 |
|
66 workpath = getenv( "_MEIPASS2" ); |
|
67 VS(workpath); |
|
68 VS(" is _MEIPASS2 (workpath)\n"); |
|
69 |
|
70 // fill in here (directory of thisfile) |
|
71 strcpy(homepath, Py_GetPrefix()); |
|
72 strcat(homepath, "/"); |
|
73 VS(homepath); |
|
74 VS(" is homepath\n"); |
|
75 |
|
76 if (init(homepath, &thisfile[strlen(homepath)], workpath)) { |
|
77 /* no pkg there, so try the nonelf configuration */ |
|
78 strcpy(archivefile, thisfile); |
|
79 strcat(archivefile, ".pkg"); |
|
80 if (init(homepath, &archivefile[strlen(homepath)], workpath)) { |
|
81 FATALERROR("Cannot open self "); |
|
82 FATALERROR(thisfile); |
|
83 FATALERROR(" or archive "); |
|
84 FATALERROR(archivefile); |
|
85 FATALERROR("\n"); |
|
86 return -1; |
|
87 } |
|
88 } |
|
89 |
|
90 if (workpath) { |
|
91 // we're the "child" process |
|
92 VS("Already have a workpath - running!\n"); |
|
93 rc = doIt(argc, argv); |
|
94 if (strcmp(workpath, homepath)!=0) |
|
95 clear(workpath); |
|
96 } |
|
97 else { |
|
98 if (extractBinaries(&workpath)) { |
|
99 VS("Error extracting binaries\n"); |
|
100 return -1; |
|
101 } |
|
102 if (workpath == NULL) { |
|
103 /* now look for the "force LD_LIBRARY" flag */ |
|
104 ptoc = getFirstTocEntry(); |
|
105 while (ptoc) { |
|
106 if ((ptoc->typcd == 'o') && (ptoc->name[0] == 'f')) |
|
107 workpath = homepath; |
|
108 ptoc = getNextTocEntry(ptoc); |
|
109 } |
|
110 } |
|
111 if (workpath) { |
|
112 VS("Executing self as child with "); |
|
113 // run the "child" process, then clean up |
|
114 strcpy(magic_envvar, "_MEIPASS2="); |
|
115 strcat(magic_envvar, workpath); |
|
116 putenv(magic_envvar); |
|
117 // now LD_LIBRARY_PATH |
|
118 strcpy(ldlib_envvar, "LD_LIBRARY_PATH="); |
|
119 strcat(ldlib_envvar, workpath); |
|
120 ldlib_envvar[strlen(ldlib_envvar)-1] = '\0'; |
|
121 oldldlib = getenv("LD_LIBRARY_PATH"); |
|
122 if (oldldlib) { |
|
123 strcat(ldlib_envvar, ":"); |
|
124 strcat(ldlib_envvar, oldldlib); |
|
125 } |
|
126 putenv(ldlib_envvar); |
|
127 VS(ldlib_envvar); |
|
128 VS("\n"); |
|
129 rc = execvp(thisfile, argv); |
|
130 VS("Back to parent...\n"); |
|
131 } |
|
132 else |
|
133 // no "child" process necessary |
|
134 rc = doIt(argc, argv); |
|
135 } |
|
136 return rc; |
|
137 } |