blob: 71e0d18611dadd3a6488142d24bd6bf730d23ab4 [file] [log] [blame]
Just van Rossum52e14d62002-12-30 22:08:05 +00001#include "Python.h"
2#include "structmember.h"
3#include "osdefs.h"
4#include "marshal.h"
Just van Rossum52e14d62002-12-30 22:08:05 +00005#include <time.h>
6
7
8#define IS_SOURCE 0x0
9#define IS_BYTECODE 0x1
10#define IS_PACKAGE 0x2
11
12struct st_zip_searchorder {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000013 char suffix[14];
14 int type;
Just van Rossum52e14d62002-12-30 22:08:05 +000015};
16
17/* zip_searchorder defines how we search for a module in the Zip
18 archive: we first search for a package __init__, then for
19 non-package .pyc, .pyo and .py entries. The .pyc and .pyo entries
20 are swapped by initzipimport() if we run in optimized mode. Also,
21 '/' is replaced by SEP there. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +000022static struct st_zip_searchorder zip_searchorder[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000023 {"/__init__.pyc", IS_PACKAGE | IS_BYTECODE},
24 {"/__init__.pyo", IS_PACKAGE | IS_BYTECODE},
25 {"/__init__.py", IS_PACKAGE | IS_SOURCE},
26 {".pyc", IS_BYTECODE},
27 {".pyo", IS_BYTECODE},
28 {".py", IS_SOURCE},
29 {"", 0}
Just van Rossum52e14d62002-12-30 22:08:05 +000030};
31
32/* zipimporter object definition and support */
33
34typedef struct _zipimporter ZipImporter;
35
36struct _zipimporter {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000037 PyObject_HEAD
38 PyObject *archive; /* pathname of the Zip archive */
39 PyObject *prefix; /* file prefix: "a/sub/directory/" */
40 PyObject *files; /* dict with file info {path: toc_entry} */
Just van Rossum52e14d62002-12-30 22:08:05 +000041};
42
Just van Rossum52e14d62002-12-30 22:08:05 +000043static PyObject *ZipImportError;
44static PyObject *zip_directory_cache = NULL;
Gregory P. Smithb48c5d52014-01-06 09:46:46 -080045static PyObject *zip_stat_cache = NULL;
46/* posix.fstat or nt.fstat function. Used due to posixmodule.c's
47 * superior fstat implementation over libc's on Windows. */
48static PyObject *fstat_function = NULL; /* posix.fstat() or nt.fstat() */
Just van Rossum52e14d62002-12-30 22:08:05 +000049
50/* forward decls */
Gregory P. Smithb48c5d52014-01-06 09:46:46 -080051static FILE *fopen_rb_and_stat(char *path, PyObject **py_stat_p);
52static FILE *safely_reopen_archive(ZipImporter *self, char **archive_p);
53static PyObject *read_directory(FILE *fp, char *archive);
54static PyObject *get_data(FILE *fp, char *archive, PyObject *toc_entry);
Just van Rossum52e14d62002-12-30 22:08:05 +000055static PyObject *get_module_code(ZipImporter *self, char *fullname,
Antoine Pitrouc83ea132010-05-09 14:46:46 +000056 int *p_ispackage, char **p_modpath);
Just van Rossum52e14d62002-12-30 22:08:05 +000057
58
59#define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
60
61
62/* zipimporter.__init__
63 Split the "subdirectory" from the Zip archive path, lookup a matching
64 entry in sys.path_importer_cache, fetch the file directory from there
65 if found, or else read it from the archive. */
66static int
67zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
68{
Gregory P. Smith027ab392014-01-27 00:15:10 -080069 char *path_arg, *path, *p, *prefix, *path_buf;
Antoine Pitrouc83ea132010-05-09 14:46:46 +000070 size_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +000071
Antoine Pitrouc83ea132010-05-09 14:46:46 +000072 if (!_PyArg_NoKeywords("zipimporter()", kwds))
73 return -1;
Georg Brandl02c42872005-08-26 06:42:30 +000074
Gregory P. Smith027ab392014-01-27 00:15:10 -080075 if (!PyArg_ParseTuple(args, "s:zipimporter", &path_arg))
Antoine Pitrouc83ea132010-05-09 14:46:46 +000076 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +000077
Gregory P. Smith027ab392014-01-27 00:15:10 -080078 len = strlen(path_arg);
Antoine Pitrouc83ea132010-05-09 14:46:46 +000079 if (len == 0) {
80 PyErr_SetString(ZipImportError, "archive path is empty");
81 return -1;
82 }
83 if (len >= MAXPATHLEN) {
Gregory P. Smith027ab392014-01-27 00:15:10 -080084 PyErr_SetString(ZipImportError, "archive path too long");
Antoine Pitrouc83ea132010-05-09 14:46:46 +000085 return -1;
86 }
Gregory P. Smith027ab392014-01-27 00:15:10 -080087 /* Room for the trailing \0 and room for an extra SEP if needed. */
88 path_buf = (char *)PyMem_Malloc(len + 2);
89 if (path_buf == NULL) {
90 PyErr_SetString(PyExc_MemoryError, "unable to malloc path buffer");
91 return -1;
92 }
93 strcpy(path_buf, path_arg);
Just van Rossum52e14d62002-12-30 22:08:05 +000094
95#ifdef ALTSEP
Gregory P. Smith027ab392014-01-27 00:15:10 -080096 for (p = path_buf; *p; p++) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000097 if (*p == ALTSEP)
98 *p = SEP;
99 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000100#endif
101
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000102 path = NULL;
103 prefix = NULL;
104 for (;;) {
Martin v. Löwisa94568a2003-05-10 07:36:56 +0000105#ifndef RISCOS
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000106 struct stat statbuf;
107 int rv;
Just van Rossum52e14d62002-12-30 22:08:05 +0000108
Gregory P. Smith027ab392014-01-27 00:15:10 -0800109 rv = stat(path_buf, &statbuf);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000110 if (rv == 0) {
111 /* it exists */
112 if (S_ISREG(statbuf.st_mode))
113 /* it's a file */
Gregory P. Smith027ab392014-01-27 00:15:10 -0800114 path = path_buf;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000115 break;
116 }
Martin v. Löwisa94568a2003-05-10 07:36:56 +0000117#else
Gregory P. Smith027ab392014-01-27 00:15:10 -0800118 if (object_exists(path_buf)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000119 /* it exists */
Gregory P. Smith027ab392014-01-27 00:15:10 -0800120 if (isfile(path_buf))
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000121 /* it's a file */
Gregory P. Smith027ab392014-01-27 00:15:10 -0800122 path = path_buf;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000123 break;
124 }
Martin v. Löwisa94568a2003-05-10 07:36:56 +0000125#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000126 /* back up one path element */
Gregory P. Smith027ab392014-01-27 00:15:10 -0800127 p = strrchr(path_buf, SEP);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000128 if (prefix != NULL)
129 *prefix = SEP;
130 if (p == NULL)
131 break;
132 *p = '\0';
133 prefix = p;
134 }
135 if (path != NULL) {
136 PyObject *files;
137 files = PyDict_GetItemString(zip_directory_cache, path);
138 if (files == NULL) {
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800139 PyObject *zip_stat = NULL;
Gregory P. Smith027ab392014-01-27 00:15:10 -0800140 FILE *fp = fopen_rb_and_stat(path, &zip_stat);
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800141 if (fp == NULL) {
142 PyErr_Format(ZipImportError, "can't open Zip file: "
Gregory P. Smith027ab392014-01-27 00:15:10 -0800143 "'%.200s'", path);
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800144 Py_XDECREF(zip_stat);
Gregory P. Smith027ab392014-01-27 00:15:10 -0800145 goto error;
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800146 }
147
148 if (Py_VerboseFlag)
149 PySys_WriteStderr("# zipimport: %s not cached, "
150 "reading TOC.\n", path);
151
Gregory P. Smith027ab392014-01-27 00:15:10 -0800152 files = read_directory(fp, path);
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800153 fclose(fp);
154 if (files == NULL) {
155 Py_XDECREF(zip_stat);
Gregory P. Smith027ab392014-01-27 00:15:10 -0800156 goto error;
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800157 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000158 if (PyDict_SetItemString(zip_directory_cache, path,
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800159 files) != 0) {
160 Py_DECREF(files);
161 Py_XDECREF(zip_stat);
Gregory P. Smith027ab392014-01-27 00:15:10 -0800162 goto error;
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800163 }
164 if (zip_stat && PyDict_SetItemString(zip_stat_cache, path,
165 zip_stat) != 0) {
166 Py_DECREF(files);
167 Py_DECREF(zip_stat);
Gregory P. Smith027ab392014-01-27 00:15:10 -0800168 goto error;
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800169 }
170 Py_XDECREF(zip_stat);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000171 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000172 }
173 else {
174 PyErr_SetString(ZipImportError, "not a Zip file");
Gregory P. Smith027ab392014-01-27 00:15:10 -0800175 goto error;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000176 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000177
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000178 if (prefix == NULL)
179 prefix = "";
180 else {
181 prefix++;
182 len = strlen(prefix);
183 if (prefix[len-1] != SEP) {
184 /* add trailing SEP */
185 prefix[len] = SEP;
186 prefix[len + 1] = '\0';
187 }
188 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000189
Gregory P. Smith027ab392014-01-27 00:15:10 -0800190 self->archive = PyString_FromString(path);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000191 if (self->archive == NULL)
Gregory P. Smith027ab392014-01-27 00:15:10 -0800192 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000193
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000194 self->prefix = PyString_FromString(prefix);
195 if (self->prefix == NULL)
Gregory P. Smith027ab392014-01-27 00:15:10 -0800196 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000197
Gregory P. Smith027ab392014-01-27 00:15:10 -0800198 PyMem_Free(path_buf);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000199 return 0;
Gregory P. Smith027ab392014-01-27 00:15:10 -0800200error:
201 PyMem_Free(path_buf);
202 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +0000203}
204
205static void
206zipimporter_dealloc(ZipImporter *self)
207{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000208 Py_XDECREF(self->archive);
209 Py_XDECREF(self->prefix);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000210 Py_TYPE(self)->tp_free((PyObject *)self);
Just van Rossum52e14d62002-12-30 22:08:05 +0000211}
212
213static PyObject *
214zipimporter_repr(ZipImporter *self)
215{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000216 char buf[500];
217 char *archive = "???";
218 char *prefix = "";
Just van Rossum52e14d62002-12-30 22:08:05 +0000219
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000220 if (self->archive != NULL && PyString_Check(self->archive))
221 archive = PyString_AsString(self->archive);
222 if (self->prefix != NULL && PyString_Check(self->prefix))
223 prefix = PyString_AsString(self->prefix);
224 if (prefix != NULL && *prefix)
225 PyOS_snprintf(buf, sizeof(buf),
226 "<zipimporter object \"%.300s%c%.150s\">",
227 archive, SEP, prefix);
228 else
229 PyOS_snprintf(buf, sizeof(buf),
230 "<zipimporter object \"%.300s\">",
231 archive);
232 return PyString_FromString(buf);
Just van Rossum52e14d62002-12-30 22:08:05 +0000233}
234
235/* return fullname.split(".")[-1] */
236static char *
237get_subname(char *fullname)
238{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000239 char *subname = strrchr(fullname, '.');
240 if (subname == NULL)
241 subname = fullname;
242 else
243 subname++;
244 return subname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000245}
246
247/* Given a (sub)modulename, write the potential file path in the
248 archive (without extension) to the path buffer. Return the
249 length of the resulting string. */
250static int
251make_filename(char *prefix, char *name, char *path)
252{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000253 size_t len;
254 char *p;
Just van Rossum52e14d62002-12-30 22:08:05 +0000255
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000256 len = strlen(prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000257
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000258 /* self.prefix + name [+ SEP + "__init__"] + ".py[co]" */
259 if (len + strlen(name) + 13 >= MAXPATHLEN) {
260 PyErr_SetString(ZipImportError, "path too long");
261 return -1;
262 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000263
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000264 strcpy(path, prefix);
265 strcpy(path + len, name);
266 for (p = path + len; *p; p++) {
267 if (*p == '.')
268 *p = SEP;
269 }
270 len += strlen(name);
271 assert(len < INT_MAX);
272 return (int)len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000273}
274
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000275enum zi_module_info {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000276 MI_ERROR,
277 MI_NOT_FOUND,
278 MI_MODULE,
279 MI_PACKAGE
Just van Rossum52e14d62002-12-30 22:08:05 +0000280};
281
282/* Return some information about a module. */
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000283static enum zi_module_info
Just van Rossum52e14d62002-12-30 22:08:05 +0000284get_module_info(ZipImporter *self, char *fullname)
285{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000286 char *subname, path[MAXPATHLEN + 1];
287 int len;
288 struct st_zip_searchorder *zso;
Gregory P. Smith027ab392014-01-27 00:15:10 -0800289 PyObject *files;
Just van Rossum52e14d62002-12-30 22:08:05 +0000290
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000291 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +0000292
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000293 len = make_filename(PyString_AsString(self->prefix), subname, path);
294 if (len < 0)
295 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000296
Gregory P. Smith027ab392014-01-27 00:15:10 -0800297 files = PyDict_GetItem(zip_directory_cache, self->archive);
298 if (files == NULL) {
299 /* Some scoundrel has cleared zip_directory_cache out from
300 * beneath us. Try repopulating it once before giving up. */
301 char *unused_archive_name;
302 FILE *fp = safely_reopen_archive(self, &unused_archive_name);
303 if (fp == NULL)
304 return MI_ERROR;
305 fclose(fp);
306 files = PyDict_GetItem(zip_directory_cache, self->archive);
307 if (files == NULL)
308 return MI_ERROR;
309 }
310
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000311 for (zso = zip_searchorder; *zso->suffix; zso++) {
312 strcpy(path + len, zso->suffix);
Gregory P. Smith027ab392014-01-27 00:15:10 -0800313 if (PyDict_GetItemString(files, path) != NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000314 if (zso->type & IS_PACKAGE)
315 return MI_PACKAGE;
316 else
317 return MI_MODULE;
318 }
319 }
320 return MI_NOT_FOUND;
Just van Rossum52e14d62002-12-30 22:08:05 +0000321}
322
323/* Check whether we can satisfy the import of the module named by
324 'fullname'. Return self if we can, None if we can't. */
325static PyObject *
326zipimporter_find_module(PyObject *obj, PyObject *args)
327{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000328 ZipImporter *self = (ZipImporter *)obj;
329 PyObject *path = NULL;
330 char *fullname;
331 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000332
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000333 if (!PyArg_ParseTuple(args, "s|O:zipimporter.find_module",
334 &fullname, &path))
335 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000336
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000337 mi = get_module_info(self, fullname);
338 if (mi == MI_ERROR)
339 return NULL;
340 if (mi == MI_NOT_FOUND) {
341 Py_INCREF(Py_None);
342 return Py_None;
343 }
344 Py_INCREF(self);
345 return (PyObject *)self;
Just van Rossum52e14d62002-12-30 22:08:05 +0000346}
347
348/* Load and return the module named by 'fullname'. */
349static PyObject *
350zipimporter_load_module(PyObject *obj, PyObject *args)
351{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000352 ZipImporter *self = (ZipImporter *)obj;
353 PyObject *code, *mod, *dict;
354 char *fullname, *modpath;
355 int ispackage;
Just van Rossum52e14d62002-12-30 22:08:05 +0000356
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000357 if (!PyArg_ParseTuple(args, "s:zipimporter.load_module",
358 &fullname))
359 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000360
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000361 code = get_module_code(self, fullname, &ispackage, &modpath);
362 if (code == NULL)
363 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000364
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000365 mod = PyImport_AddModule(fullname);
366 if (mod == NULL) {
367 Py_DECREF(code);
368 return NULL;
369 }
370 dict = PyModule_GetDict(mod);
Just van Rossum52e14d62002-12-30 22:08:05 +0000371
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000372 /* mod.__loader__ = self */
373 if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
374 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000375
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000376 if (ispackage) {
377 /* add __path__ to the module *before* the code gets
378 executed */
379 PyObject *pkgpath, *fullpath;
380 char *prefix = PyString_AsString(self->prefix);
381 char *subname = get_subname(fullname);
382 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000383
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000384 fullpath = PyString_FromFormat("%s%c%s%s",
385 PyString_AsString(self->archive),
386 SEP,
387 *prefix ? prefix : "",
388 subname);
389 if (fullpath == NULL)
390 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000391
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000392 pkgpath = Py_BuildValue("[O]", fullpath);
393 Py_DECREF(fullpath);
394 if (pkgpath == NULL)
395 goto error;
396 err = PyDict_SetItemString(dict, "__path__", pkgpath);
397 Py_DECREF(pkgpath);
398 if (err != 0)
399 goto error;
400 }
401 mod = PyImport_ExecCodeModuleEx(fullname, code, modpath);
402 Py_DECREF(code);
403 if (Py_VerboseFlag)
404 PySys_WriteStderr("import %s # loaded from Zip %s\n",
405 fullname, modpath);
406 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +0000407error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000408 Py_DECREF(code);
409 Py_DECREF(mod);
410 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000411}
412
Nick Coghlana2053472008-12-14 10:54:50 +0000413/* Return a string matching __file__ for the named module */
414static PyObject *
415zipimporter_get_filename(PyObject *obj, PyObject *args)
416{
417 ZipImporter *self = (ZipImporter *)obj;
418 PyObject *code;
419 char *fullname, *modpath;
420 int ispackage;
421
Nick Coghlan0194f5b2009-02-08 03:17:00 +0000422 if (!PyArg_ParseTuple(args, "s:zipimporter.get_filename",
Nick Coghlana2053472008-12-14 10:54:50 +0000423 &fullname))
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000424 return NULL;
Nick Coghlana2053472008-12-14 10:54:50 +0000425
426 /* Deciding the filename requires working out where the code
427 would come from if the module was actually loaded */
428 code = get_module_code(self, fullname, &ispackage, &modpath);
429 if (code == NULL)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000430 return NULL;
Nick Coghlana2053472008-12-14 10:54:50 +0000431 Py_DECREF(code); /* Only need the path info */
432
433 return PyString_FromString(modpath);
434}
435
Just van Rossum52e14d62002-12-30 22:08:05 +0000436/* Return a bool signifying whether the module is a package or not. */
437static PyObject *
438zipimporter_is_package(PyObject *obj, PyObject *args)
439{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000440 ZipImporter *self = (ZipImporter *)obj;
441 char *fullname;
442 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000443
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000444 if (!PyArg_ParseTuple(args, "s:zipimporter.is_package",
445 &fullname))
446 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000447
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000448 mi = get_module_info(self, fullname);
449 if (mi == MI_ERROR)
450 return NULL;
451 if (mi == MI_NOT_FOUND) {
452 PyErr_Format(ZipImportError, "can't find module '%.200s'",
453 fullname);
454 return NULL;
455 }
456 return PyBool_FromLong(mi == MI_PACKAGE);
Just van Rossum52e14d62002-12-30 22:08:05 +0000457}
458
459static PyObject *
460zipimporter_get_data(PyObject *obj, PyObject *args)
461{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000462 ZipImporter *self = (ZipImporter *)obj;
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800463 char *path, *archive;
464 FILE *fp;
Just van Rossum52e14d62002-12-30 22:08:05 +0000465#ifdef ALTSEP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000466 char *p, buf[MAXPATHLEN + 1];
Just van Rossum52e14d62002-12-30 22:08:05 +0000467#endif
Gregory P. Smith027ab392014-01-27 00:15:10 -0800468 PyObject *toc_entry, *data, *files;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000469 Py_ssize_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000470
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000471 if (!PyArg_ParseTuple(args, "s:zipimporter.get_data", &path))
472 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000473
474#ifdef ALTSEP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000475 if (strlen(path) >= MAXPATHLEN) {
476 PyErr_SetString(ZipImportError, "path too long");
477 return NULL;
478 }
479 strcpy(buf, path);
480 for (p = buf; *p; p++) {
481 if (*p == ALTSEP)
482 *p = SEP;
483 }
484 path = buf;
Just van Rossum52e14d62002-12-30 22:08:05 +0000485#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000486 len = PyString_Size(self->archive);
487 if ((size_t)len < strlen(path) &&
488 strncmp(path, PyString_AsString(self->archive), len) == 0 &&
489 path[len] == SEP) {
490 path = path + len + 1;
491 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000492
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800493 fp = safely_reopen_archive(self, &archive);
494 if (fp == NULL)
495 return NULL;
496
Gregory P. Smith027ab392014-01-27 00:15:10 -0800497 files = PyDict_GetItem(zip_directory_cache, self->archive);
498 if (files == NULL) {
499 /* This should never happen as safely_reopen_archive() should
500 * have repopulated zip_directory_cache if needed. */
501 return NULL;
502 }
503 toc_entry = PyDict_GetItemString(files, path);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000504 if (toc_entry == NULL) {
505 PyErr_SetFromErrnoWithFilename(PyExc_IOError, path);
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800506 fclose(fp);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000507 return NULL;
508 }
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800509 data = get_data(fp, archive, toc_entry);
510 fclose(fp);
511 return data;
Just van Rossum52e14d62002-12-30 22:08:05 +0000512}
513
514static PyObject *
515zipimporter_get_code(PyObject *obj, PyObject *args)
516{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000517 ZipImporter *self = (ZipImporter *)obj;
518 char *fullname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000519
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000520 if (!PyArg_ParseTuple(args, "s:zipimporter.get_code", &fullname))
521 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000522
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000523 return get_module_code(self, fullname, NULL, NULL);
Just van Rossum52e14d62002-12-30 22:08:05 +0000524}
525
526static PyObject *
527zipimporter_get_source(PyObject *obj, PyObject *args)
528{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000529 ZipImporter *self = (ZipImporter *)obj;
Gregory P. Smith027ab392014-01-27 00:15:10 -0800530 PyObject *toc_entry, *files;
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800531 FILE *fp;
532 char *fullname, *subname, path[MAXPATHLEN+1], *archive;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000533 int len;
534 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000535
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000536 if (!PyArg_ParseTuple(args, "s:zipimporter.get_source", &fullname))
537 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000538
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000539 mi = get_module_info(self, fullname);
540 if (mi == MI_ERROR)
541 return NULL;
542 if (mi == MI_NOT_FOUND) {
543 PyErr_Format(ZipImportError, "can't find module '%.200s'",
544 fullname);
545 return NULL;
546 }
547 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +0000548
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000549 len = make_filename(PyString_AsString(self->prefix), subname, path);
550 if (len < 0)
551 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000552
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000553 if (mi == MI_PACKAGE) {
554 path[len] = SEP;
555 strcpy(path + len + 1, "__init__.py");
556 }
557 else
558 strcpy(path + len, ".py");
Just van Rossum52e14d62002-12-30 22:08:05 +0000559
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800560 fp = safely_reopen_archive(self, &archive);
561 if (fp == NULL)
562 return NULL;
563
Gregory P. Smith027ab392014-01-27 00:15:10 -0800564 files = PyDict_GetItem(zip_directory_cache, self->archive);
565 if (files == NULL) {
566 /* This should never happen as safely_reopen_archive() should
567 * have repopulated zip_directory_cache if needed. */
568 return NULL;
569 }
570 toc_entry = PyDict_GetItemString(files, path);
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800571 if (toc_entry != NULL) {
572 PyObject *data = get_data(fp, archive, toc_entry);
573 fclose(fp);
574 return data;
575 }
576 fclose(fp);
Just van Rossum52e14d62002-12-30 22:08:05 +0000577
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000578 /* we have the module, but no source */
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800579 Py_RETURN_NONE;
Just van Rossum52e14d62002-12-30 22:08:05 +0000580}
581
582PyDoc_STRVAR(doc_find_module,
583"find_module(fullname, path=None) -> self or None.\n\
584\n\
585Search for a module specified by 'fullname'. 'fullname' must be the\n\
586fully qualified (dotted) module name. It returns the zipimporter\n\
587instance itself if the module was found, or None if it wasn't.\n\
588The optional 'path' argument is ignored -- it's there for compatibility\n\
589with the importer protocol.");
590
591PyDoc_STRVAR(doc_load_module,
592"load_module(fullname) -> module.\n\
593\n\
594Load the module specified by 'fullname'. 'fullname' must be the\n\
595fully qualified (dotted) module name. It returns the imported\n\
596module, or raises ZipImportError if it wasn't found.");
597
598PyDoc_STRVAR(doc_get_data,
599"get_data(pathname) -> string with file data.\n\
600\n\
601Return the data associated with 'pathname'. Raise IOError if\n\
602the file wasn't found.");
603
604PyDoc_STRVAR(doc_is_package,
605"is_package(fullname) -> bool.\n\
606\n\
607Return True if the module specified by fullname is a package.\n\
Brian Curtin13b43e72010-07-21 01:35:46 +0000608Raise ZipImportError if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000609
610PyDoc_STRVAR(doc_get_code,
611"get_code(fullname) -> code object.\n\
612\n\
613Return the code object for the specified module. Raise ZipImportError\n\
Brian Curtin13b43e72010-07-21 01:35:46 +0000614if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000615
616PyDoc_STRVAR(doc_get_source,
617"get_source(fullname) -> source string.\n\
618\n\
619Return the source code for the specified module. Raise ZipImportError\n\
Brian Curtin13b43e72010-07-21 01:35:46 +0000620if the module couldn't be found, return None if the archive does\n\
Just van Rossum52e14d62002-12-30 22:08:05 +0000621contain the module, but has no source for it.");
622
Nick Coghlana2053472008-12-14 10:54:50 +0000623
624PyDoc_STRVAR(doc_get_filename,
Nick Coghlan0194f5b2009-02-08 03:17:00 +0000625"get_filename(fullname) -> filename string.\n\
Nick Coghlana2053472008-12-14 10:54:50 +0000626\n\
627Return the filename for the specified module.");
628
Just van Rossum52e14d62002-12-30 22:08:05 +0000629static PyMethodDef zipimporter_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000630 {"find_module", zipimporter_find_module, METH_VARARGS,
631 doc_find_module},
632 {"load_module", zipimporter_load_module, METH_VARARGS,
633 doc_load_module},
634 {"get_data", zipimporter_get_data, METH_VARARGS,
635 doc_get_data},
636 {"get_code", zipimporter_get_code, METH_VARARGS,
637 doc_get_code},
638 {"get_source", zipimporter_get_source, METH_VARARGS,
639 doc_get_source},
640 {"get_filename", zipimporter_get_filename, METH_VARARGS,
641 doc_get_filename},
642 {"is_package", zipimporter_is_package, METH_VARARGS,
643 doc_is_package},
644 {NULL, NULL} /* sentinel */
Just van Rossum52e14d62002-12-30 22:08:05 +0000645};
646
647static PyMemberDef zipimporter_members[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000648 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
649 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
650 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
651 {NULL}
Just van Rossum52e14d62002-12-30 22:08:05 +0000652};
653
654PyDoc_STRVAR(zipimporter_doc,
655"zipimporter(archivepath) -> zipimporter object\n\
656\n\
657Create a new zipimporter instance. 'archivepath' must be a path to\n\
Georg Brandl6a57c082008-05-11 15:05:13 +0000658a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
659'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
660valid directory inside the archive.\n\
661\n\
662'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
663archive.\n\
664\n\
665The 'archive' attribute of zipimporter objects contains the name of the\n\
666zipfile targeted.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000667
668#define DEFERRED_ADDRESS(ADDR) 0
669
670static PyTypeObject ZipImporter_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000671 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
672 "zipimport.zipimporter",
673 sizeof(ZipImporter),
674 0, /* tp_itemsize */
675 (destructor)zipimporter_dealloc, /* tp_dealloc */
676 0, /* tp_print */
677 0, /* tp_getattr */
678 0, /* tp_setattr */
679 0, /* tp_compare */
680 (reprfunc)zipimporter_repr, /* tp_repr */
681 0, /* tp_as_number */
682 0, /* tp_as_sequence */
683 0, /* tp_as_mapping */
684 0, /* tp_hash */
685 0, /* tp_call */
686 0, /* tp_str */
687 PyObject_GenericGetAttr, /* tp_getattro */
688 0, /* tp_setattro */
689 0, /* tp_as_buffer */
Gregory P. Smith027ab392014-01-27 00:15:10 -0800690 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000691 zipimporter_doc, /* tp_doc */
Gregory P. Smith027ab392014-01-27 00:15:10 -0800692 0, /* tp_traverse */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000693 0, /* tp_clear */
694 0, /* tp_richcompare */
695 0, /* tp_weaklistoffset */
696 0, /* tp_iter */
697 0, /* tp_iternext */
698 zipimporter_methods, /* tp_methods */
699 zipimporter_members, /* tp_members */
700 0, /* tp_getset */
701 0, /* tp_base */
702 0, /* tp_dict */
703 0, /* tp_descr_get */
704 0, /* tp_descr_set */
705 0, /* tp_dictoffset */
706 (initproc)zipimporter_init, /* tp_init */
707 PyType_GenericAlloc, /* tp_alloc */
708 PyType_GenericNew, /* tp_new */
Gregory P. Smith027ab392014-01-27 00:15:10 -0800709 0, /* tp_free */
Just van Rossum52e14d62002-12-30 22:08:05 +0000710};
711
712
713/* implementation */
714
Just van Rossum52e14d62002-12-30 22:08:05 +0000715/* Given a buffer, return the long that is represented by the first
716 4 bytes, encoded as little endian. This partially reimplements
717 marshal.c:r_long() */
718static long
719get_long(unsigned char *buf) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000720 long x;
721 x = buf[0];
722 x |= (long)buf[1] << 8;
723 x |= (long)buf[2] << 16;
724 x |= (long)buf[3] << 24;
Just van Rossum52e14d62002-12-30 22:08:05 +0000725#if SIZEOF_LONG > 4
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000726 /* Sign extension for 64-bit machines */
727 x |= -(x & 0x80000000L);
Just van Rossum52e14d62002-12-30 22:08:05 +0000728#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000729 return x;
Just van Rossum52e14d62002-12-30 22:08:05 +0000730}
731
732/*
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800733 fopen_rb_and_stat(path, &py_stat) -> FILE *
734
735 Opens path in "rb" mode and populates the Python py_stat stat_result
736 with information about the opened file. *py_stat may not be changed
737 if there is no fstat_function or if fstat_function fails.
738
739 Returns NULL and does nothing to *py_stat if the open failed.
740*/
741static FILE *
742fopen_rb_and_stat(char *path, PyObject **py_stat_p)
743{
744 FILE *fp;
745 assert(py_stat_p != NULL);
746 assert(*py_stat_p == NULL);
747
748 fp = fopen(path, "rb");
749 if (fp == NULL) {
750 return NULL;
751 }
752
753 if (fstat_function) {
754 PyObject *stat_result = PyObject_CallFunction(fstat_function,
755 "i", fileno(fp));
756 if (stat_result == NULL) {
757 PyErr_Clear(); /* We can function without it. */
758 } else {
759 *py_stat_p = stat_result;
760 }
761 }
762
763 return fp;
764}
765
766/* Return 1 if objects a and b fail a Py_EQ test for an attr. */
767static int
768compare_obj_attr_strings(PyObject *obj_a, PyObject *obj_b, char *attr_name)
769{
770 int problem = 0;
771 PyObject *attr_a = PyObject_GetAttrString(obj_a, attr_name);
772 PyObject *attr_b = PyObject_GetAttrString(obj_b, attr_name);
773 if (attr_a == NULL || attr_b == NULL)
774 problem = 1;
775 else
776 problem = (PyObject_RichCompareBool(attr_a, attr_b, Py_EQ) != 1);
777 Py_XDECREF(attr_a);
778 Py_XDECREF(attr_b);
779 return problem;
780}
781
782/*
783 * Returns an open FILE * on success and sets *archive_p to point to
784 * a read only C string representation of the archive name (as a
785 * convenience for use in error messages).
786 *
787 * Returns NULL on error with the Python error context set.
788 */
789static FILE *
790safely_reopen_archive(ZipImporter *self, char **archive_p)
791{
792 FILE *fp;
793 PyObject *stat_now = NULL;
794 char *archive;
795
796 assert(archive_p != NULL);
797 *archive_p = PyString_AsString(self->archive);
798 if (*archive_p == NULL)
799 return NULL;
800 archive = *archive_p;
801
802 fp = fopen_rb_and_stat(archive, &stat_now);
803 if (!fp) {
804 PyErr_Format(PyExc_IOError,
805 "zipimport: can not open file %s", archive);
806 Py_XDECREF(stat_now);
807 return NULL;
808 }
809
810 if (stat_now != NULL) {
811 int problem = 0;
812 PyObject *files;
813 PyObject *prev_stat = PyDict_GetItemString(zip_stat_cache, archive);
814 /* Test stat_now vs the old cached stat on some key attributes. */
815 if (prev_stat != NULL) {
816 problem = compare_obj_attr_strings(prev_stat, stat_now,
817 "st_ino");
818 problem |= compare_obj_attr_strings(prev_stat, stat_now,
819 "st_size");
820 problem |= compare_obj_attr_strings(prev_stat, stat_now,
821 "st_mtime");
822 } else {
823 if (Py_VerboseFlag)
824 PySys_WriteStderr("# zipimport: no stat data for %s!\n",
825 archive);
826 problem = 1;
827 }
828
829 if (problem) {
830 if (Py_VerboseFlag)
831 PySys_WriteStderr("# zipimport: %s modified since last"
832 " import, rereading TOC.\n", archive);
833 files = read_directory(fp, archive);
834 if (files == NULL) {
835 Py_DECREF(stat_now);
836 fclose(fp);
837 return NULL;
838 }
839 if (PyDict_SetItem(zip_directory_cache, self->archive,
840 files) != 0) {
841 Py_DECREF(files);
842 Py_DECREF(stat_now);
843 fclose(fp);
844 return NULL;
845 }
846 if (stat_now && PyDict_SetItem(zip_stat_cache, self->archive,
847 stat_now) != 0) {
848 Py_DECREF(files);
849 Py_DECREF(stat_now);
850 fclose(fp);
851 return NULL;
852 }
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800853 }
Benjamin Peterson7251fe12014-01-09 09:36:10 -0600854 Py_DECREF(stat_now);
Gregory P. Smith027ab392014-01-27 00:15:10 -0800855 } else {
856 if (Py_VerboseFlag)
857 PySys_WriteStderr("# zipimport: os.fstat failed on the "
858 "open %s file.\n", archive);
859 }
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800860
861 return fp;
862}
863
864/*
865 read_directory(fp, archive) -> files dict (new reference)
Just van Rossum52e14d62002-12-30 22:08:05 +0000866
867 Given a path to a Zip archive, build a dict, mapping file names
868 (local to the archive, using SEP as a separator) to toc entries.
869
870 A toc_entry is a tuple:
871
Fred Drakef5b7fd22005-11-11 19:34:56 +0000872 (__file__, # value to use for __file__, available for all files
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000873 compress, # compression kind; 0 for uncompressed
874 data_size, # size of compressed data on disk
875 file_size, # size of decompressed data
876 file_offset, # offset of file header from start of archive
877 time, # mod time of file (in dos format)
878 date, # mod data of file (in dos format)
879 crc, # crc checksum of the data
Just van Rossum52e14d62002-12-30 22:08:05 +0000880 )
881
882 Directories can be recognized by the trailing SEP in the name,
883 data_size and file_offset are 0.
884*/
885static PyObject *
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800886read_directory(FILE *fp, char *archive)
Just van Rossum52e14d62002-12-30 22:08:05 +0000887{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000888 PyObject *files = NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000889 long compress, crc, data_size, file_size, file_offset, date, time;
890 long header_offset, name_size, header_size, header_position;
891 long i, l, count;
892 size_t length;
893 char path[MAXPATHLEN + 5];
894 char name[MAXPATHLEN + 5];
895 char *p, endof_central_dir[22];
896 long arc_offset; /* offset from beginning of file to start of zip-archive */
Just van Rossum52e14d62002-12-30 22:08:05 +0000897
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800898 assert(fp != NULL);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000899 if (strlen(archive) > MAXPATHLEN) {
900 PyErr_SetString(PyExc_OverflowError,
901 "Zip path name is too long");
902 return NULL;
903 }
904 strcpy(path, archive);
Just van Rossum52e14d62002-12-30 22:08:05 +0000905
Jesus Ceae884be62012-10-03 02:13:05 +0200906 if (fseek(fp, -22, SEEK_END) == -1) {
Jesus Ceae884be62012-10-03 02:13:05 +0200907 PyErr_Format(ZipImportError, "can't read Zip file: %s", archive);
908 return NULL;
909 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000910 header_position = ftell(fp);
911 if (fread(endof_central_dir, 1, 22, fp) != 22) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000912 PyErr_Format(ZipImportError, "can't read Zip file: "
913 "'%.200s'", archive);
914 return NULL;
915 }
916 if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
917 /* Bad: End of Central Dir signature */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000918 PyErr_Format(ZipImportError, "not a Zip file: "
919 "'%.200s'", archive);
920 return NULL;
921 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000922
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000923 header_size = get_long((unsigned char *)endof_central_dir + 12);
924 header_offset = get_long((unsigned char *)endof_central_dir + 16);
925 arc_offset = header_position - header_offset - header_size;
926 header_offset += arc_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000927
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000928 files = PyDict_New();
929 if (files == NULL)
930 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000931
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000932 length = (long)strlen(path);
933 path[length] = SEP;
Just van Rossum52e14d62002-12-30 22:08:05 +0000934
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000935 /* Start of Central Directory */
936 count = 0;
937 for (;;) {
938 PyObject *t;
939 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000940
Jesus Ceae884be62012-10-03 02:13:05 +0200941 if (fseek(fp, header_offset, 0) == -1) /* Start of file header */
942 goto fseek_error;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000943 l = PyMarshal_ReadLongFromFile(fp);
944 if (l != 0x02014B50)
945 break; /* Bad: Central Dir File Header */
Jesus Ceae884be62012-10-03 02:13:05 +0200946 if (fseek(fp, header_offset + 10, 0) == -1)
947 goto fseek_error;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000948 compress = PyMarshal_ReadShortFromFile(fp);
949 time = PyMarshal_ReadShortFromFile(fp);
950 date = PyMarshal_ReadShortFromFile(fp);
951 crc = PyMarshal_ReadLongFromFile(fp);
952 data_size = PyMarshal_ReadLongFromFile(fp);
953 file_size = PyMarshal_ReadLongFromFile(fp);
954 name_size = PyMarshal_ReadShortFromFile(fp);
955 header_size = 46 + name_size +
956 PyMarshal_ReadShortFromFile(fp) +
957 PyMarshal_ReadShortFromFile(fp);
Jesus Ceae884be62012-10-03 02:13:05 +0200958 if (fseek(fp, header_offset + 42, 0) == -1)
959 goto fseek_error;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000960 file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
961 if (name_size > MAXPATHLEN)
962 name_size = MAXPATHLEN;
Just van Rossum52e14d62002-12-30 22:08:05 +0000963
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000964 p = name;
965 for (i = 0; i < name_size; i++) {
966 *p = (char)getc(fp);
967 if (*p == '/')
968 *p = SEP;
969 p++;
970 }
971 *p = 0; /* Add terminating null byte */
972 header_offset += header_size;
Just van Rossum52e14d62002-12-30 22:08:05 +0000973
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000974 strncpy(path + length + 1, name, MAXPATHLEN - length - 1);
Just van Rossum52e14d62002-12-30 22:08:05 +0000975
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000976 t = Py_BuildValue("siiiiiii", path, compress, data_size,
977 file_size, file_offset, time, date, crc);
978 if (t == NULL)
979 goto error;
980 err = PyDict_SetItemString(files, name, t);
981 Py_DECREF(t);
982 if (err != 0)
983 goto error;
984 count++;
985 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000986 if (Py_VerboseFlag)
987 PySys_WriteStderr("# zipimport: found %ld names in %s\n",
988 count, archive);
989 return files;
Jesus Ceae884be62012-10-03 02:13:05 +0200990fseek_error:
Jesus Ceae884be62012-10-03 02:13:05 +0200991 Py_XDECREF(files);
992 PyErr_Format(ZipImportError, "can't read Zip file: %s", archive);
993 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000994error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000995 Py_XDECREF(files);
996 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000997}
998
999/* Return the zlib.decompress function object, or NULL if zlib couldn't
1000 be imported. The function is cached when found, so subsequent calls
Victor Stinnerf58f1c32011-05-21 02:13:22 +02001001 don't import zlib again. */
Just van Rossum52e14d62002-12-30 22:08:05 +00001002static PyObject *
1003get_decompress_func(void)
1004{
Victor Stinnerf58f1c32011-05-21 02:13:22 +02001005 static int importing_zlib = 0;
1006 PyObject *zlib;
1007 PyObject *decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +00001008
Victor Stinnerf58f1c32011-05-21 02:13:22 +02001009 if (importing_zlib != 0)
1010 /* Someone has a zlib.py[co] in their Zip file;
1011 let's avoid a stack overflow. */
1012 return NULL;
1013 importing_zlib = 1;
1014 zlib = PyImport_ImportModuleNoBlock("zlib");
1015 importing_zlib = 0;
1016 if (zlib != NULL) {
1017 decompress = PyObject_GetAttrString(zlib,
1018 "decompress");
1019 Py_DECREF(zlib);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001020 }
Victor Stinnerf58f1c32011-05-21 02:13:22 +02001021 else {
1022 PyErr_Clear();
1023 decompress = NULL;
1024 }
1025 if (Py_VerboseFlag)
1026 PySys_WriteStderr("# zipimport: zlib %s\n",
1027 zlib != NULL ? "available": "UNAVAILABLE");
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001028 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +00001029}
1030
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001031/* Given a FILE* to a Zip file and a toc_entry, return the (uncompressed)
Just van Rossum52e14d62002-12-30 22:08:05 +00001032 data as a new reference. */
1033static PyObject *
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001034get_data(FILE *fp, char *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001035{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001036 PyObject *raw_data, *data = NULL, *decompress;
1037 char *buf;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001038 int err;
1039 Py_ssize_t bytes_read = 0;
1040 long l;
1041 char *datapath;
1042 long compress, data_size, file_size, file_offset;
1043 long time, date, crc;
Just van Rossum52e14d62002-12-30 22:08:05 +00001044
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001045 if (!PyArg_ParseTuple(toc_entry, "slllllll", &datapath, &compress,
1046 &data_size, &file_size, &file_offset, &time,
1047 &date, &crc)) {
1048 return NULL;
1049 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001050
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001051 /* Check to make sure the local file header is correct */
Jesus Ceae884be62012-10-03 02:13:05 +02001052 if (fseek(fp, file_offset, 0) == -1) {
Jesus Ceae884be62012-10-03 02:13:05 +02001053 PyErr_Format(ZipImportError, "can't read Zip file: %s", archive);
1054 return NULL;
1055 }
1056
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001057 l = PyMarshal_ReadLongFromFile(fp);
1058 if (l != 0x04034B50) {
1059 /* Bad: Local File Header */
1060 PyErr_Format(ZipImportError,
1061 "bad local file header in %s",
1062 archive);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001063 return NULL;
1064 }
Jesus Ceae884be62012-10-03 02:13:05 +02001065 if (fseek(fp, file_offset + 26, 0) == -1) {
Jesus Ceae884be62012-10-03 02:13:05 +02001066 PyErr_Format(ZipImportError, "can't read Zip file: %s", archive);
1067 return NULL;
1068 }
1069
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001070 l = 30 + PyMarshal_ReadShortFromFile(fp) +
1071 PyMarshal_ReadShortFromFile(fp); /* local header size */
1072 file_offset += l; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +00001073
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001074 raw_data = PyString_FromStringAndSize((char *)NULL, compress == 0 ?
1075 data_size : data_size + 1);
1076 if (raw_data == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001077 return NULL;
1078 }
1079 buf = PyString_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001080
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001081 err = fseek(fp, file_offset, 0);
Jesus Ceae884be62012-10-03 02:13:05 +02001082 if (err == 0) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001083 bytes_read = fread(buf, 1, data_size, fp);
Jesus Ceae884be62012-10-03 02:13:05 +02001084 } else {
Jesus Ceae884be62012-10-03 02:13:05 +02001085 PyErr_Format(ZipImportError, "can't read Zip file: %s", archive);
1086 return NULL;
1087 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001088 if (err || bytes_read != data_size) {
1089 PyErr_SetString(PyExc_IOError,
1090 "zipimport: can't read data");
1091 Py_DECREF(raw_data);
1092 return NULL;
1093 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001094
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001095 if (compress != 0) {
1096 buf[data_size] = 'Z'; /* saw this in zipfile.py */
1097 data_size++;
1098 }
1099 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +00001100
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001101 if (compress == 0) /* data is not compressed */
1102 return raw_data;
Just van Rossum52e14d62002-12-30 22:08:05 +00001103
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001104 /* Decompress with zlib */
1105 decompress = get_decompress_func();
1106 if (decompress == NULL) {
1107 PyErr_SetString(ZipImportError,
1108 "can't decompress data; "
1109 "zlib not available");
1110 goto error;
1111 }
1112 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Victor Stinnerf58f1c32011-05-21 02:13:22 +02001113 Py_DECREF(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +00001114error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001115 Py_DECREF(raw_data);
1116 return data;
Just van Rossum52e14d62002-12-30 22:08:05 +00001117}
1118
1119/* Lenient date/time comparison function. The precision of the mtime
1120 in the archive is lower than the mtime stored in a .pyc: we
1121 must allow a difference of at most one second. */
1122static int
1123eq_mtime(time_t t1, time_t t2)
1124{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001125 time_t d = t1 - t2;
1126 if (d < 0)
1127 d = -d;
1128 /* dostime only stores even seconds, so be lenient */
1129 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001130}
1131
1132/* Given the contents of a .py[co] file in a buffer, unmarshal the data
1133 and return the code object. Return None if it the magic word doesn't
1134 match (we do this instead of raising an exception as we fall back
1135 to .py if available and we don't want to mask other errors).
1136 Returns a new reference. */
1137static PyObject *
1138unmarshal_code(char *pathname, PyObject *data, time_t mtime)
1139{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001140 PyObject *code;
1141 char *buf = PyString_AsString(data);
1142 Py_ssize_t size = PyString_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001143
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001144 if (size <= 9) {
1145 PyErr_SetString(ZipImportError,
1146 "bad pyc data");
1147 return NULL;
1148 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001149
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001150 if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
1151 if (Py_VerboseFlag)
1152 PySys_WriteStderr("# %s has bad magic\n",
1153 pathname);
1154 Py_INCREF(Py_None);
1155 return Py_None; /* signal caller to try alternative */
1156 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001157
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001158 if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
1159 mtime)) {
1160 if (Py_VerboseFlag)
1161 PySys_WriteStderr("# %s has bad mtime\n",
1162 pathname);
1163 Py_INCREF(Py_None);
1164 return Py_None; /* signal caller to try alternative */
1165 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001166
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001167 code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
1168 if (code == NULL)
1169 return NULL;
1170 if (!PyCode_Check(code)) {
1171 Py_DECREF(code);
1172 PyErr_Format(PyExc_TypeError,
1173 "compiled module %.200s is not a code object",
1174 pathname);
1175 return NULL;
1176 }
1177 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001178}
1179
1180/* Replace any occurances of "\r\n?" in the input string with "\n".
1181 This converts DOS and Mac line endings to Unix line endings.
1182 Also append a trailing "\n" to be compatible with
1183 PyParser_SimpleParseFile(). Returns a new reference. */
1184static PyObject *
1185normalize_line_endings(PyObject *source)
1186{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001187 char *buf, *q, *p = PyString_AsString(source);
1188 PyObject *fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001189
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001190 if (!p)
1191 return NULL;
Neal Norwitzee7c8f92006-08-13 18:12:03 +00001192
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001193 /* one char extra for trailing \n and one for terminating \0 */
1194 buf = (char *)PyMem_Malloc(PyString_Size(source) + 2);
1195 if (buf == NULL) {
1196 PyErr_SetString(PyExc_MemoryError,
1197 "zipimport: no memory to allocate "
1198 "source buffer");
1199 return NULL;
1200 }
1201 /* replace "\r\n?" by "\n" */
1202 for (q = buf; *p != '\0'; p++) {
1203 if (*p == '\r') {
1204 *q++ = '\n';
1205 if (*(p + 1) == '\n')
1206 p++;
1207 }
1208 else
1209 *q++ = *p;
1210 }
1211 *q++ = '\n'; /* add trailing \n */
1212 *q = '\0';
1213 fixed_source = PyString_FromString(buf);
1214 PyMem_Free(buf);
1215 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001216}
1217
1218/* Given a string buffer containing Python source code, compile it
1219 return and return a code object as a new reference. */
1220static PyObject *
1221compile_source(char *pathname, PyObject *source)
1222{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001223 PyObject *code, *fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001224
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001225 fixed_source = normalize_line_endings(source);
1226 if (fixed_source == NULL)
1227 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001228
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001229 code = Py_CompileString(PyString_AsString(fixed_source), pathname,
1230 Py_file_input);
1231 Py_DECREF(fixed_source);
1232 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001233}
1234
1235/* Convert the date/time values found in the Zip archive to a value
1236 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001237static time_t
1238parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001239{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001240 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001241
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001242 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes62a8e952008-01-18 07:30:20 +00001243
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001244 stm.tm_sec = (dostime & 0x1f) * 2;
1245 stm.tm_min = (dostime >> 5) & 0x3f;
1246 stm.tm_hour = (dostime >> 11) & 0x1f;
1247 stm.tm_mday = dosdate & 0x1f;
1248 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1249 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1250 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001251
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001252 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001253}
1254
1255/* Given a path to a .pyc or .pyo file in the archive, return the
Ezio Melottic2077b02011-03-16 12:34:31 +02001256 modification time of the matching .py file, or 0 if no source
Just van Rossum52e14d62002-12-30 22:08:05 +00001257 is available. */
1258static time_t
1259get_mtime_of_source(ZipImporter *self, char *path)
1260{
Gregory P. Smith027ab392014-01-27 00:15:10 -08001261 PyObject *toc_entry, *files;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001262 time_t mtime = 0;
1263 Py_ssize_t lastchar = strlen(path) - 1;
1264 char savechar = path[lastchar];
1265 path[lastchar] = '\0'; /* strip 'c' or 'o' from *.py[co] */
Gregory P. Smith027ab392014-01-27 00:15:10 -08001266 files = PyDict_GetItem(zip_directory_cache, self->archive);
1267 if (files == NULL) {
1268 /* This should never happen as safely_reopen_archive() from
1269 * our only caller repopulated zip_directory_cache if needed. */
1270 return 0;
1271 }
1272 toc_entry = PyDict_GetItemString(files, path);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001273 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1274 PyTuple_Size(toc_entry) == 8) {
1275 /* fetch the time stamp of the .py file for comparison
1276 with an embedded pyc time stamp */
1277 int time, date;
1278 time = PyInt_AsLong(PyTuple_GetItem(toc_entry, 5));
1279 date = PyInt_AsLong(PyTuple_GetItem(toc_entry, 6));
1280 mtime = parse_dostime(time, date);
1281 }
1282 path[lastchar] = savechar;
1283 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001284}
1285
1286/* Return the code object for the module named by 'fullname' from the
1287 Zip archive as a new reference. */
1288static PyObject *
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001289get_code_from_data(char *archive, FILE *fp, int ispackage,
1290 int isbytecode, time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001291{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001292 PyObject *data, *code;
1293 char *modpath;
Just van Rossum52e14d62002-12-30 22:08:05 +00001294
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001295 data = get_data(fp, archive, toc_entry);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001296 if (data == NULL)
1297 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001298
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001299 modpath = PyString_AsString(PyTuple_GetItem(toc_entry, 0));
Just van Rossum52e14d62002-12-30 22:08:05 +00001300
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001301 if (isbytecode) {
1302 code = unmarshal_code(modpath, data, mtime);
1303 }
1304 else {
1305 code = compile_source(modpath, data);
1306 }
1307 Py_DECREF(data);
1308 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001309}
1310
Ezio Melotti24b07bc2011-03-15 18:55:01 +02001311/* Get the code object associated with the module specified by
Just van Rossum52e14d62002-12-30 22:08:05 +00001312 'fullname'. */
1313static PyObject *
1314get_module_code(ZipImporter *self, char *fullname,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001315 int *p_ispackage, char **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001316{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001317 PyObject *toc_entry;
1318 char *subname, path[MAXPATHLEN + 1];
1319 int len;
1320 struct st_zip_searchorder *zso;
Gregory P. Smith6de72602014-01-07 18:39:48 -08001321 FILE *fp;
1322 char *archive;
Just van Rossum52e14d62002-12-30 22:08:05 +00001323
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001324 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +00001325
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001326 len = make_filename(PyString_AsString(self->prefix), subname, path);
1327 if (len < 0)
1328 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001329
Gregory P. Smith6de72602014-01-07 18:39:48 -08001330 fp = safely_reopen_archive(self, &archive);
1331 if (fp == NULL)
1332 return NULL;
1333
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001334 for (zso = zip_searchorder; *zso->suffix; zso++) {
Gregory P. Smith027ab392014-01-27 00:15:10 -08001335 PyObject *code = NULL, *files;
Just van Rossum52e14d62002-12-30 22:08:05 +00001336
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001337 strcpy(path + len, zso->suffix);
1338 if (Py_VerboseFlag > 1)
1339 PySys_WriteStderr("# trying %s%c%s\n",
1340 PyString_AsString(self->archive),
1341 SEP, path);
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001342
Gregory P. Smith027ab392014-01-27 00:15:10 -08001343 files = PyDict_GetItem(zip_directory_cache, self->archive);
1344 if (files == NULL) {
1345 /* This should never happen as safely_reopen_archive() should
1346 * have repopulated zip_directory_cache if needed; and the GIL
1347 * is being held. */
1348 return NULL;
1349 }
1350 toc_entry = PyDict_GetItemString(files, path);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001351 if (toc_entry != NULL) {
1352 time_t mtime = 0;
1353 int ispackage = zso->type & IS_PACKAGE;
1354 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001355
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001356 if (isbytecode)
1357 mtime = get_mtime_of_source(self, path);
1358 if (p_ispackage != NULL)
1359 *p_ispackage = ispackage;
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001360 code = get_code_from_data(archive, fp, ispackage,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001361 isbytecode, mtime,
1362 toc_entry);
1363 if (code == Py_None) {
1364 /* bad magic number or non-matching mtime
1365 in byte code, try next */
1366 Py_DECREF(code);
1367 continue;
1368 }
1369 if (code != NULL && p_modpath != NULL)
1370 *p_modpath = PyString_AsString(
1371 PyTuple_GetItem(toc_entry, 0));
Gregory P. Smith6de72602014-01-07 18:39:48 -08001372 fclose(fp);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001373 return code;
1374 }
1375 }
1376 PyErr_Format(ZipImportError, "can't find module '%.200s'", fullname);
Gregory P. Smith6de72602014-01-07 18:39:48 -08001377 fclose(fp);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001378 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001379}
1380
1381
1382/* Module init */
1383
1384PyDoc_STRVAR(zipimport_doc,
1385"zipimport provides support for importing Python modules from Zip archives.\n\
1386\n\
1387This module exports three objects:\n\
1388- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001389- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001390 subclass of ImportError, so it can be caught as ImportError, too.\n\
1391- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1392 info dicts, as used in zipimporter._files.\n\
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001393- _zip_stat_cache: a dict, mapping archive paths to stat_result\n\
1394 info for the .zip the last time anything was imported from it.\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001395\n\
1396It is usually not needed to use the zipimport module explicitly; it is\n\
1397used by the builtin import mechanism for sys.path items that are paths\n\
1398to Zip archives.");
1399
1400PyMODINIT_FUNC
1401initzipimport(void)
1402{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001403 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001404
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001405 if (PyType_Ready(&ZipImporter_Type) < 0)
1406 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001407
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001408 /* Correct directory separator */
1409 zip_searchorder[0].suffix[0] = SEP;
1410 zip_searchorder[1].suffix[0] = SEP;
1411 zip_searchorder[2].suffix[0] = SEP;
1412 if (Py_OptimizeFlag) {
1413 /* Reverse *.pyc and *.pyo */
1414 struct st_zip_searchorder tmp;
1415 tmp = zip_searchorder[0];
1416 zip_searchorder[0] = zip_searchorder[1];
1417 zip_searchorder[1] = tmp;
1418 tmp = zip_searchorder[3];
1419 zip_searchorder[3] = zip_searchorder[4];
1420 zip_searchorder[4] = tmp;
1421 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001422
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001423 mod = Py_InitModule4("zipimport", NULL, zipimport_doc,
1424 NULL, PYTHON_API_VERSION);
1425 if (mod == NULL)
1426 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001427
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001428 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1429 PyExc_ImportError, NULL);
1430 if (ZipImportError == NULL)
1431 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001432
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001433 Py_INCREF(ZipImportError);
1434 if (PyModule_AddObject(mod, "ZipImportError",
1435 ZipImportError) < 0)
1436 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001437
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001438 Py_INCREF(&ZipImporter_Type);
1439 if (PyModule_AddObject(mod, "zipimporter",
1440 (PyObject *)&ZipImporter_Type) < 0)
1441 return;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001442
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001443 Py_XDECREF(zip_directory_cache); /* Avoid embedded interpreter leaks. */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001444 zip_directory_cache = PyDict_New();
1445 if (zip_directory_cache == NULL)
1446 return;
1447 Py_INCREF(zip_directory_cache);
1448 if (PyModule_AddObject(mod, "_zip_directory_cache",
1449 zip_directory_cache) < 0)
1450 return;
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001451
1452 Py_XDECREF(zip_stat_cache); /* Avoid embedded interpreter leaks. */
1453 zip_stat_cache = PyDict_New();
1454 if (zip_stat_cache == NULL)
1455 return;
1456 Py_INCREF(zip_stat_cache);
1457 if (PyModule_AddObject(mod, "_zip_stat_cache", zip_stat_cache) < 0)
1458 return;
1459
1460 {
1461 /* We cannot import "os" here as that is a .py/.pyc file that could
1462 * live within a zipped up standard library. Import the posix or nt
1463 * builtin that provides the fstat() function we want instead. */
1464 PyObject *os_like_module;
Gregory P. Smithad3e7252014-01-07 01:11:09 -08001465 Py_CLEAR(fstat_function); /* Avoid embedded interpreter leaks. */
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001466 os_like_module = PyImport_ImportModule("posix");
1467 if (os_like_module == NULL) {
Gregory P. Smithad3e7252014-01-07 01:11:09 -08001468 PyErr_Clear();
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001469 os_like_module = PyImport_ImportModule("nt");
1470 }
1471 if (os_like_module != NULL) {
1472 fstat_function = PyObject_GetAttrString(os_like_module, "fstat");
1473 Py_DECREF(os_like_module);
1474 }
1475 if (fstat_function == NULL) {
1476 PyErr_Clear(); /* non-fatal, we'll go on without it. */
Gregory P. Smithad3e7252014-01-07 01:11:09 -08001477 if (Py_VerboseFlag)
1478 PySys_WriteStderr("# zipimport unable to use os.fstat().\n");
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001479 }
1480 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001481}