|
1 /* |
|
2 * Launch a python module from an archive. |
|
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 #ifndef LAUNCH_H |
|
29 #define LAUNCH_H |
|
30 #include <stdio.h> |
|
31 #include <string.h> |
|
32 #include <stdlib.h> |
|
33 #ifdef WIN32 |
|
34 #include <io.h> |
|
35 #else |
|
36 #include <unistd.h> |
|
37 #endif |
|
38 #include <fcntl.h> |
|
39 #ifdef WIN32 |
|
40 #include <winsock.h> /* for ntohl */ |
|
41 #else |
|
42 #include <netinet/in.h> |
|
43 #endif |
|
44 |
|
45 /* On Windows, we use dynamic loading so one binary |
|
46 can be used with (nearly) any Python version. |
|
47 This is the cruft necessary to do Windows dynamic loading |
|
48 */ |
|
49 |
|
50 #ifdef WIN32 |
|
51 /* |
|
52 * These macros used to define variables to hold dynamically accessed entry |
|
53 * points. These are declared 'extern' in this header, and defined fully later. |
|
54 */ |
|
55 #define EXTDECLPROC(result, name, args)\ |
|
56 typedef result (__cdecl *__PROC__##name) args;\ |
|
57 extern __PROC__##name name; |
|
58 |
|
59 #define EXTDECLVAR(vartyp, name)\ |
|
60 typedef vartyp __VAR__##name;\ |
|
61 extern __VAR__##name *name; |
|
62 |
|
63 /* |
|
64 * These types and macros are included from the Python header file object.h |
|
65 * They are needed to do very basic Python functionality. |
|
66 */ |
|
67 typedef _typeobject; |
|
68 typedef struct _object { |
|
69 int ob_refcnt; |
|
70 struct _typeobject *ob_type; |
|
71 } PyObject; |
|
72 typedef void (*destructor)(PyObject *); |
|
73 typedef struct _typeobject { |
|
74 int ob_refcnt; |
|
75 struct _typeobject *ob_type; |
|
76 int ob_size; |
|
77 char *tp_name; /* For printing */ |
|
78 int tp_basicsize, tp_itemsize; /* For allocation */ |
|
79 destructor tp_dealloc; |
|
80 /* ignore the rest.... */ |
|
81 } PyTypeObject; |
|
82 struct _ts; /* forward */ |
|
83 typedef struct _is { |
|
84 struct _is *next; |
|
85 struct _ts *tstate_head; |
|
86 PyObject *modules; |
|
87 PyObject *sysdict; |
|
88 PyObject *builtins; |
|
89 int checkinterval; |
|
90 } PyInterpreterState; |
|
91 typedef struct _ts { |
|
92 struct _ts *next; |
|
93 PyInterpreterState *interp; |
|
94 void *frame; /* struct _frame *frame; */ |
|
95 int recursion_depth; |
|
96 int ticker; |
|
97 int tracing; |
|
98 PyObject *sys_profilefunc; |
|
99 PyObject *sys_tracefunc; |
|
100 PyObject *curexc_type; |
|
101 PyObject *curexc_value; |
|
102 PyObject *curexc_traceback; |
|
103 PyObject *exc_type; |
|
104 PyObject *exc_value; |
|
105 PyObject *exc_traceback; |
|
106 PyObject *dict; |
|
107 /* XXX signal handlers should also be here */ |
|
108 } PyThreadState; |
|
109 |
|
110 |
|
111 /* These are the non reference debugging version of Py_INCREF and DECREF */ |
|
112 #define _Py_Dealloc(op) (*(op)->ob_type->tp_dealloc)((PyObject *)(op)) |
|
113 #define Py_INCREF(op) ((op)->ob_refcnt++) |
|
114 #define Py_DECREF(op) \ |
|
115 if (--(op)->ob_refcnt != 0) \ |
|
116 ; \ |
|
117 else \ |
|
118 _Py_Dealloc((PyObject *)(op)) |
|
119 #define Py_XINCREF(op) if ((op) == NULL) ; else Py_INCREF(op) |
|
120 #define Py_XDECREF(op) if ((op) == NULL) ; else Py_DECREF(op) |
|
121 |
|
122 /* The actual declarations of var & function entry points used. */ |
|
123 EXTDECLVAR(int, Py_NoSiteFlag); |
|
124 EXTDECLVAR(int, Py_OptimizeFlag); |
|
125 EXTDECLVAR(int, Py_VerboseFlag); |
|
126 EXTDECLPROC(int, Py_Initialize, (void)); |
|
127 EXTDECLPROC(int, Py_Finalize, (void)); |
|
128 EXTDECLPROC(PyObject *, Py_CompileString, (char *, char *, int)); |
|
129 EXTDECLPROC(PyObject *, PyImport_ExecCodeModule, (char *, PyObject *)); |
|
130 EXTDECLPROC(int, PyRun_SimpleString, (char *)); |
|
131 EXTDECLPROC(int, PySys_SetArgv, (int, char **)); |
|
132 EXTDECLPROC(void, Py_SetProgramName, (char *)); |
|
133 EXTDECLPROC(PyObject *, PyImport_ImportModule, (char *)); |
|
134 EXTDECLPROC(PyObject *, PyImport_AddModule, (char *)); |
|
135 EXTDECLPROC(int, PyObject_SetAttrString, (PyObject *, char *, PyObject *)); |
|
136 EXTDECLPROC(PyObject *, PyList_New, (int)); |
|
137 EXTDECLPROC(int, PyList_Append, (PyObject *, PyObject *)); |
|
138 EXTDECLPROC(PyObject *, Py_BuildValue, (char *, ...)); |
|
139 EXTDECLPROC(PyObject *, PyFile_FromString, (char *, char *)); |
|
140 EXTDECLPROC(PyObject *, PyString_FromStringAndSize, (const char *, int)); |
|
141 EXTDECLPROC(PyObject *, PyObject_CallFunction, (PyObject *, char *, ...)); |
|
142 EXTDECLPROC(PyObject *, PyModule_GetDict, (PyObject *)); |
|
143 EXTDECLPROC(PyObject *, PyDict_GetItemString, (PyObject *, char *)); |
|
144 EXTDECLPROC(void, PyErr_Clear, () ); |
|
145 EXTDECLPROC(PyObject *, PyErr_Occurred, () ); |
|
146 EXTDECLPROC(void, PyErr_Print, () ); |
|
147 EXTDECLPROC(PyObject *, PyObject_CallObject, (PyObject *, PyObject*) ); |
|
148 EXTDECLPROC(PyObject *, PyObject_CallMethod, (PyObject *, char *, char *, ...) ); |
|
149 EXTDECLPROC(void, PySys_AddWarnOption, (char *)); |
|
150 EXTDECLPROC(void, PyEval_InitThreads, () ); |
|
151 EXTDECLPROC(void, PyEval_AcquireThread, (PyThreadState *) ); |
|
152 EXTDECLPROC(void, PyEval_ReleaseThread, (PyThreadState *) ); |
|
153 EXTDECLPROC(void, PyEval_AcquireLock, (void) ); |
|
154 EXTDECLPROC(void, PyEval_ReleaseLock, (void) ); |
|
155 EXTDECLPROC(PyThreadState *, PyThreadState_Swap, (PyThreadState *) ); |
|
156 EXTDECLPROC(PyThreadState *, PyThreadState_New, (PyInterpreterState *) ); |
|
157 EXTDECLPROC(void, PyThreadState_Clear, (PyThreadState *) ); |
|
158 EXTDECLPROC(void, PyThreadState_Delete, (PyThreadState *) ); |
|
159 EXTDECLPROC(PyInterpreterState *, PyInterpreterState_New, () ); |
|
160 EXTDECLPROC(PyThreadState *, Py_NewInterpreter, () ); |
|
161 EXTDECLPROC(void, Py_EndInterpreter, (PyThreadState *) ); |
|
162 EXTDECLPROC(void, PyErr_Print, () ); |
|
163 EXTDECLPROC(long, PyInt_AsLong, (PyObject *) ); |
|
164 EXTDECLPROC(int, PySys_SetObject, (char *, PyObject *)); |
|
165 |
|
166 /* Macros to declare and get Python entry points in the C file. |
|
167 * Typedefs '__PROC__...' have been done above |
|
168 */ |
|
169 #define DECLPROC(name)\ |
|
170 __PROC__##name name = NULL; |
|
171 #define GETPROC(dll, name)\ |
|
172 name = (__PROC__##name)GetProcAddress (dll, #name);\ |
|
173 if (!name) {\ |
|
174 FATALERROR ("Cannot GetProcAddress for " #name);\ |
|
175 return -1;\ |
|
176 } |
|
177 #define DECLVAR(name)\ |
|
178 __VAR__##name *name = NULL; |
|
179 #define GETVAR(dll, name)\ |
|
180 name = (__VAR__##name *)GetProcAddress (dll, #name);\ |
|
181 if (!name) {\ |
|
182 FATALERROR ("Cannot GetProcAddress for " #name);\ |
|
183 return -1;\ |
|
184 } |
|
185 #else |
|
186 #include <Python.h> |
|
187 #endif /* WIN32 dynamic load cruft */ |
|
188 |
|
189 /* |
|
190 * #defines |
|
191 */ |
|
192 #define MAGIC "MEI\014\013\012\013\016" |
|
193 |
|
194 #if !defined WIN32 && !defined _CONSOLE |
|
195 #define _CONSOLE |
|
196 #endif |
|
197 |
|
198 #ifdef _CONSOLE |
|
199 # define FATALERROR(x) printf(x) |
|
200 # define OTHERERROR(x) printf(x) |
|
201 #else |
|
202 # define FATALERROR(x) MessageBox(NULL, x, "Fatal Error!", MB_OK | MB_ICONEXCLAMATION) |
|
203 # define OTHERERROR(x) MessageBox(NULL, x, "Error!", MB_OK | MB_ICONWARNING) |
|
204 #endif |
|
205 |
|
206 #ifdef LAUNCH_DEBUG |
|
207 # ifdef _CONSOLE |
|
208 # define VS(arg) printf(arg) |
|
209 # else |
|
210 # define VS(arg) MessageBox(NULL, arg, "Tracing", MB_OK) |
|
211 # endif |
|
212 #else |
|
213 # define VS(arg) |
|
214 #endif |
|
215 |
|
216 /* TOC entry for a CArchive */ |
|
217 typedef struct _toc { |
|
218 int structlen; /*len of this one - including full len of name */ |
|
219 int pos; /* pos rel to start of concatenation */ |
|
220 int len; /* len of the data (compressed) */ |
|
221 int ulen; /* len of data (uncompressed) */ |
|
222 char cflag; /* is it compressed (really a byte) */ |
|
223 char typcd; /* 'b' binary, 'z' zlib, 'm' module, 's' script (v3), |
|
224 'x' data, 'o' runtime option */ |
|
225 char name[1]; /* the name to save it as */ |
|
226 /* starting in v5, we stretch this out to a mult of 16 */ |
|
227 } TOC; |
|
228 |
|
229 /* The CArchive Cookie, from end of the archive. */ |
|
230 typedef struct _cookie { |
|
231 char magic[8]; /* 'MEI\014\013\012\013\016' */ |
|
232 int len; /* len of entire package */ |
|
233 int TOC; /* pos (rel to start) of TableOfContents */ |
|
234 int TOClen; /* length of TableOfContents */ |
|
235 int pyvers; /* new in v4 */ |
|
236 } COOKIE; |
|
237 |
|
238 /* _MAX_PATH for non-Windows */ |
|
239 #ifndef _MAX_PATH |
|
240 #define _MAX_PATH 256 |
|
241 #endif |
|
242 |
|
243 /** |
|
244 * Load Python using code stored in the following archive. |
|
245 * Intended for use by embedding applications. |
|
246 * |
|
247 * @param archivePath The path to the archive directory, with trailing |
|
248 * backslash. This directory will also contain the binary |
|
249 * dependencies of the application. There can be no |
|
250 * binaries inside the archive. |
|
251 * |
|
252 * @param archiveName The file name of the archive, without a path. |
|
253 * |
|
254 * @return 0 on success, non-zero otherwise. |
|
255 * |
|
256 */ |
|
257 int launchembedded(char const * archivePath, char const * archiveName); |
|
258 |
|
259 /***************************************************************** |
|
260 * The following 4 entries are for applications which may need to |
|
261 * use to 2 steps to execute |
|
262 *****************************************************************/ |
|
263 |
|
264 /** |
|
265 * Initialize the paths and open the archive |
|
266 * |
|
267 * @param archivePath The path (with trailing backslash) to the archive. |
|
268 * |
|
269 * @param archiveName The file name of the archive, without a path. |
|
270 * |
|
271 * @param workpath The path (with trailing backslash) to where |
|
272 * the binaries were extracted. If they have not |
|
273 * benn extracted yet, this is NULL. If they have, |
|
274 * this will either be archivePath, or a temp dir |
|
275 * where the user has write permissions. |
|
276 * |
|
277 * @return 0 on success, non-zero otherwise. |
|
278 */ |
|
279 int init(char const * archivePath, char const * archiveName, char const * workpath); |
|
280 |
|
281 /** |
|
282 * Extract binaries in the archive |
|
283 * |
|
284 * @param workpath (OUT) Where the binaries were extracted to. If |
|
285 * none extracted, is NULL. |
|
286 * |
|
287 * @return 0 on success, non-zero otherwise. |
|
288 */ |
|
289 int extractBinaries(char **workpath); |
|
290 |
|
291 /** |
|
292 * Load Python and execute all scripts in the archive |
|
293 * |
|
294 * @param argc Count of "commandline" args |
|
295 * |
|
296 * @param argv The "commandline". |
|
297 * |
|
298 * @return -1 for internal failures, or the rc of the last script. |
|
299 */ |
|
300 int doIt(int argc, char *argv[]); |
|
301 |
|
302 /* |
|
303 * Call a simple "int func(void)" entry point. Assumes such a function |
|
304 * exists in the main namespace. |
|
305 * Return non zero on failure, with -2 if the specific error is |
|
306 * that the function does not exist in the namespace. |
|
307 * |
|
308 * @param name Name of the function to execute. |
|
309 * @param presult Integer return value. |
|
310 */ |
|
311 int callSimpleEntryPoint(char *name, int *presult); |
|
312 |
|
313 /** |
|
314 * Clean up extracted binaries |
|
315 */ |
|
316 void cleanUp(void); |
|
317 |
|
318 /** |
|
319 * Helpers for embedders |
|
320 */ |
|
321 int getPyVersion(void); |
|
322 void finalizePython(void); |
|
323 |
|
324 /** |
|
325 * The gory detail level |
|
326 */ |
|
327 int setPaths(char const * archivePath, char const * archiveName); |
|
328 int openArchive(void); |
|
329 int attachPython(int *loadedNew); |
|
330 int loadPython(void); /* note - attachPython will call this if not already loaded */ |
|
331 void acquirePythonThread(void); |
|
332 void releasePythonThread(void); |
|
333 int startPython(int argc, char *argv[]); |
|
334 int importModules(void); |
|
335 int installZlibs(void); |
|
336 int runScripts(void); |
|
337 TOC *getFirstTocEntry(void); |
|
338 TOC *getNextTocEntry(TOC *entry); |
|
339 void clear(const char *dir); |
|
340 #endif |
|
341 |