blob: 180b56f8bc8e7fdfe225008addfe10fe03c1e983 [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;
Gregory P. Smith027ab392014-01-27 00:15:10 -0800137 if (Py_VerboseFlag && prefix && prefix[0] != '\0')
138 PySys_WriteStderr("# zipimport: prefix=%s constructing a "
139 "zipimporter for %s\n", prefix, path);
140 /* NOTE(gps): test_zipimport.py never exercises a case where
141 * prefix is non-empty. When would that ever be possible?
142 * Are we missing coverage or is prefix simply never needed?
143 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000144 files = PyDict_GetItemString(zip_directory_cache, path);
145 if (files == NULL) {
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800146 PyObject *zip_stat = NULL;
Gregory P. Smith027ab392014-01-27 00:15:10 -0800147 FILE *fp = fopen_rb_and_stat(path, &zip_stat);
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800148 if (fp == NULL) {
149 PyErr_Format(ZipImportError, "can't open Zip file: "
Gregory P. Smith027ab392014-01-27 00:15:10 -0800150 "'%.200s'", path);
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800151 Py_XDECREF(zip_stat);
Gregory P. Smith027ab392014-01-27 00:15:10 -0800152 goto error;
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800153 }
154
155 if (Py_VerboseFlag)
156 PySys_WriteStderr("# zipimport: %s not cached, "
157 "reading TOC.\n", path);
158
Gregory P. Smith027ab392014-01-27 00:15:10 -0800159 files = read_directory(fp, path);
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800160 fclose(fp);
161 if (files == NULL) {
162 Py_XDECREF(zip_stat);
Gregory P. Smith027ab392014-01-27 00:15:10 -0800163 goto error;
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800164 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000165 if (PyDict_SetItemString(zip_directory_cache, path,
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800166 files) != 0) {
167 Py_DECREF(files);
168 Py_XDECREF(zip_stat);
Gregory P. Smith027ab392014-01-27 00:15:10 -0800169 goto error;
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800170 }
171 if (zip_stat && PyDict_SetItemString(zip_stat_cache, path,
172 zip_stat) != 0) {
173 Py_DECREF(files);
174 Py_DECREF(zip_stat);
Gregory P. Smith027ab392014-01-27 00:15:10 -0800175 goto error;
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800176 }
177 Py_XDECREF(zip_stat);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000178 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000179 }
180 else {
181 PyErr_SetString(ZipImportError, "not a Zip file");
Gregory P. Smith027ab392014-01-27 00:15:10 -0800182 goto error;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000183 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000184
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000185 if (prefix == NULL)
186 prefix = "";
187 else {
188 prefix++;
189 len = strlen(prefix);
190 if (prefix[len-1] != SEP) {
191 /* add trailing SEP */
192 prefix[len] = SEP;
193 prefix[len + 1] = '\0';
194 }
195 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000196
Gregory P. Smith027ab392014-01-27 00:15:10 -0800197 self->archive = PyString_FromString(path);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000198 if (self->archive == NULL)
Gregory P. Smith027ab392014-01-27 00:15:10 -0800199 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000200
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000201 self->prefix = PyString_FromString(prefix);
202 if (self->prefix == NULL)
Gregory P. Smith027ab392014-01-27 00:15:10 -0800203 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000204
Gregory P. Smith027ab392014-01-27 00:15:10 -0800205 PyMem_Free(path_buf);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000206 return 0;
Gregory P. Smith027ab392014-01-27 00:15:10 -0800207error:
208 PyMem_Free(path_buf);
209 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +0000210}
211
212static void
213zipimporter_dealloc(ZipImporter *self)
214{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000215 Py_XDECREF(self->archive);
216 Py_XDECREF(self->prefix);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000217 Py_TYPE(self)->tp_free((PyObject *)self);
Just van Rossum52e14d62002-12-30 22:08:05 +0000218}
219
220static PyObject *
221zipimporter_repr(ZipImporter *self)
222{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000223 char buf[500];
224 char *archive = "???";
225 char *prefix = "";
Just van Rossum52e14d62002-12-30 22:08:05 +0000226
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000227 if (self->archive != NULL && PyString_Check(self->archive))
228 archive = PyString_AsString(self->archive);
229 if (self->prefix != NULL && PyString_Check(self->prefix))
230 prefix = PyString_AsString(self->prefix);
231 if (prefix != NULL && *prefix)
232 PyOS_snprintf(buf, sizeof(buf),
233 "<zipimporter object \"%.300s%c%.150s\">",
234 archive, SEP, prefix);
235 else
236 PyOS_snprintf(buf, sizeof(buf),
237 "<zipimporter object \"%.300s\">",
238 archive);
239 return PyString_FromString(buf);
Just van Rossum52e14d62002-12-30 22:08:05 +0000240}
241
242/* return fullname.split(".")[-1] */
243static char *
244get_subname(char *fullname)
245{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000246 char *subname = strrchr(fullname, '.');
247 if (subname == NULL)
248 subname = fullname;
249 else
250 subname++;
251 return subname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000252}
253
254/* Given a (sub)modulename, write the potential file path in the
255 archive (without extension) to the path buffer. Return the
256 length of the resulting string. */
257static int
258make_filename(char *prefix, char *name, char *path)
259{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000260 size_t len;
261 char *p;
Just van Rossum52e14d62002-12-30 22:08:05 +0000262
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000263 len = strlen(prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000264
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000265 /* self.prefix + name [+ SEP + "__init__"] + ".py[co]" */
266 if (len + strlen(name) + 13 >= MAXPATHLEN) {
267 PyErr_SetString(ZipImportError, "path too long");
268 return -1;
269 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000270
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000271 strcpy(path, prefix);
272 strcpy(path + len, name);
273 for (p = path + len; *p; p++) {
274 if (*p == '.')
275 *p = SEP;
276 }
277 len += strlen(name);
278 assert(len < INT_MAX);
279 return (int)len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000280}
281
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000282enum zi_module_info {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000283 MI_ERROR,
284 MI_NOT_FOUND,
285 MI_MODULE,
286 MI_PACKAGE
Just van Rossum52e14d62002-12-30 22:08:05 +0000287};
288
289/* Return some information about a module. */
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000290static enum zi_module_info
Just van Rossum52e14d62002-12-30 22:08:05 +0000291get_module_info(ZipImporter *self, char *fullname)
292{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000293 char *subname, path[MAXPATHLEN + 1];
294 int len;
295 struct st_zip_searchorder *zso;
Gregory P. Smith027ab392014-01-27 00:15:10 -0800296 PyObject *files;
Just van Rossum52e14d62002-12-30 22:08:05 +0000297
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000298 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +0000299
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000300 len = make_filename(PyString_AsString(self->prefix), subname, path);
301 if (len < 0)
302 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000303
Gregory P. Smith027ab392014-01-27 00:15:10 -0800304 files = PyDict_GetItem(zip_directory_cache, self->archive);
305 if (files == NULL) {
306 /* Some scoundrel has cleared zip_directory_cache out from
307 * beneath us. Try repopulating it once before giving up. */
308 char *unused_archive_name;
309 FILE *fp = safely_reopen_archive(self, &unused_archive_name);
310 if (fp == NULL)
311 return MI_ERROR;
312 fclose(fp);
313 files = PyDict_GetItem(zip_directory_cache, self->archive);
314 if (files == NULL)
315 return MI_ERROR;
316 }
317
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000318 for (zso = zip_searchorder; *zso->suffix; zso++) {
319 strcpy(path + len, zso->suffix);
Gregory P. Smith027ab392014-01-27 00:15:10 -0800320 if (PyDict_GetItemString(files, path) != NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000321 if (zso->type & IS_PACKAGE)
322 return MI_PACKAGE;
323 else
324 return MI_MODULE;
325 }
326 }
327 return MI_NOT_FOUND;
Just van Rossum52e14d62002-12-30 22:08:05 +0000328}
329
330/* Check whether we can satisfy the import of the module named by
331 'fullname'. Return self if we can, None if we can't. */
332static PyObject *
333zipimporter_find_module(PyObject *obj, PyObject *args)
334{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000335 ZipImporter *self = (ZipImporter *)obj;
336 PyObject *path = NULL;
337 char *fullname;
338 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000339
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000340 if (!PyArg_ParseTuple(args, "s|O:zipimporter.find_module",
341 &fullname, &path))
342 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000343
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000344 mi = get_module_info(self, fullname);
345 if (mi == MI_ERROR)
346 return NULL;
347 if (mi == MI_NOT_FOUND) {
348 Py_INCREF(Py_None);
349 return Py_None;
350 }
351 Py_INCREF(self);
352 return (PyObject *)self;
Just van Rossum52e14d62002-12-30 22:08:05 +0000353}
354
355/* Load and return the module named by 'fullname'. */
356static PyObject *
357zipimporter_load_module(PyObject *obj, PyObject *args)
358{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000359 ZipImporter *self = (ZipImporter *)obj;
360 PyObject *code, *mod, *dict;
361 char *fullname, *modpath;
362 int ispackage;
Just van Rossum52e14d62002-12-30 22:08:05 +0000363
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000364 if (!PyArg_ParseTuple(args, "s:zipimporter.load_module",
365 &fullname))
366 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000367
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000368 code = get_module_code(self, fullname, &ispackage, &modpath);
369 if (code == NULL)
370 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000371
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000372 mod = PyImport_AddModule(fullname);
373 if (mod == NULL) {
374 Py_DECREF(code);
375 return NULL;
376 }
377 dict = PyModule_GetDict(mod);
Just van Rossum52e14d62002-12-30 22:08:05 +0000378
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000379 /* mod.__loader__ = self */
380 if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
381 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000382
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000383 if (ispackage) {
384 /* add __path__ to the module *before* the code gets
385 executed */
386 PyObject *pkgpath, *fullpath;
387 char *prefix = PyString_AsString(self->prefix);
388 char *subname = get_subname(fullname);
389 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000390
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000391 fullpath = PyString_FromFormat("%s%c%s%s",
392 PyString_AsString(self->archive),
393 SEP,
394 *prefix ? prefix : "",
395 subname);
396 if (fullpath == NULL)
397 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000398
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000399 pkgpath = Py_BuildValue("[O]", fullpath);
400 Py_DECREF(fullpath);
401 if (pkgpath == NULL)
402 goto error;
403 err = PyDict_SetItemString(dict, "__path__", pkgpath);
404 Py_DECREF(pkgpath);
405 if (err != 0)
406 goto error;
407 }
408 mod = PyImport_ExecCodeModuleEx(fullname, code, modpath);
409 Py_DECREF(code);
410 if (Py_VerboseFlag)
411 PySys_WriteStderr("import %s # loaded from Zip %s\n",
412 fullname, modpath);
413 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +0000414error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000415 Py_DECREF(code);
416 Py_DECREF(mod);
417 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000418}
419
Nick Coghlana2053472008-12-14 10:54:50 +0000420/* Return a string matching __file__ for the named module */
421static PyObject *
422zipimporter_get_filename(PyObject *obj, PyObject *args)
423{
424 ZipImporter *self = (ZipImporter *)obj;
425 PyObject *code;
426 char *fullname, *modpath;
427 int ispackage;
428
Nick Coghlan0194f5b2009-02-08 03:17:00 +0000429 if (!PyArg_ParseTuple(args, "s:zipimporter.get_filename",
Nick Coghlana2053472008-12-14 10:54:50 +0000430 &fullname))
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000431 return NULL;
Nick Coghlana2053472008-12-14 10:54:50 +0000432
433 /* Deciding the filename requires working out where the code
434 would come from if the module was actually loaded */
435 code = get_module_code(self, fullname, &ispackage, &modpath);
436 if (code == NULL)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000437 return NULL;
Nick Coghlana2053472008-12-14 10:54:50 +0000438 Py_DECREF(code); /* Only need the path info */
439
440 return PyString_FromString(modpath);
441}
442
Just van Rossum52e14d62002-12-30 22:08:05 +0000443/* Return a bool signifying whether the module is a package or not. */
444static PyObject *
445zipimporter_is_package(PyObject *obj, PyObject *args)
446{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000447 ZipImporter *self = (ZipImporter *)obj;
448 char *fullname;
449 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000450
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000451 if (!PyArg_ParseTuple(args, "s:zipimporter.is_package",
452 &fullname))
453 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000454
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000455 mi = get_module_info(self, fullname);
456 if (mi == MI_ERROR)
457 return NULL;
458 if (mi == MI_NOT_FOUND) {
459 PyErr_Format(ZipImportError, "can't find module '%.200s'",
460 fullname);
461 return NULL;
462 }
463 return PyBool_FromLong(mi == MI_PACKAGE);
Just van Rossum52e14d62002-12-30 22:08:05 +0000464}
465
466static PyObject *
467zipimporter_get_data(PyObject *obj, PyObject *args)
468{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000469 ZipImporter *self = (ZipImporter *)obj;
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800470 char *path, *archive;
471 FILE *fp;
Just van Rossum52e14d62002-12-30 22:08:05 +0000472#ifdef ALTSEP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000473 char *p, buf[MAXPATHLEN + 1];
Just van Rossum52e14d62002-12-30 22:08:05 +0000474#endif
Gregory P. Smith027ab392014-01-27 00:15:10 -0800475 PyObject *toc_entry, *data, *files;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000476 Py_ssize_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000477
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000478 if (!PyArg_ParseTuple(args, "s:zipimporter.get_data", &path))
479 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000480
481#ifdef ALTSEP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000482 if (strlen(path) >= MAXPATHLEN) {
483 PyErr_SetString(ZipImportError, "path too long");
484 return NULL;
485 }
486 strcpy(buf, path);
487 for (p = buf; *p; p++) {
488 if (*p == ALTSEP)
489 *p = SEP;
490 }
491 path = buf;
Just van Rossum52e14d62002-12-30 22:08:05 +0000492#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000493 len = PyString_Size(self->archive);
494 if ((size_t)len < strlen(path) &&
495 strncmp(path, PyString_AsString(self->archive), len) == 0 &&
496 path[len] == SEP) {
497 path = path + len + 1;
498 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000499
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800500 fp = safely_reopen_archive(self, &archive);
501 if (fp == NULL)
502 return NULL;
503
Gregory P. Smith027ab392014-01-27 00:15:10 -0800504 files = PyDict_GetItem(zip_directory_cache, self->archive);
505 if (files == NULL) {
506 /* This should never happen as safely_reopen_archive() should
507 * have repopulated zip_directory_cache if needed. */
508 return NULL;
509 }
510 toc_entry = PyDict_GetItemString(files, path);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000511 if (toc_entry == NULL) {
512 PyErr_SetFromErrnoWithFilename(PyExc_IOError, path);
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800513 fclose(fp);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000514 return NULL;
515 }
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800516 data = get_data(fp, archive, toc_entry);
517 fclose(fp);
518 return data;
Just van Rossum52e14d62002-12-30 22:08:05 +0000519}
520
521static PyObject *
522zipimporter_get_code(PyObject *obj, PyObject *args)
523{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000524 ZipImporter *self = (ZipImporter *)obj;
525 char *fullname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000526
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000527 if (!PyArg_ParseTuple(args, "s:zipimporter.get_code", &fullname))
528 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000529
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000530 return get_module_code(self, fullname, NULL, NULL);
Just van Rossum52e14d62002-12-30 22:08:05 +0000531}
532
533static PyObject *
534zipimporter_get_source(PyObject *obj, PyObject *args)
535{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000536 ZipImporter *self = (ZipImporter *)obj;
Gregory P. Smith027ab392014-01-27 00:15:10 -0800537 PyObject *toc_entry, *files;
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800538 FILE *fp;
539 char *fullname, *subname, path[MAXPATHLEN+1], *archive;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000540 int len;
541 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000542
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000543 if (!PyArg_ParseTuple(args, "s:zipimporter.get_source", &fullname))
544 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000545
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000546 mi = get_module_info(self, fullname);
547 if (mi == MI_ERROR)
548 return NULL;
549 if (mi == MI_NOT_FOUND) {
550 PyErr_Format(ZipImportError, "can't find module '%.200s'",
551 fullname);
552 return NULL;
553 }
554 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +0000555
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000556 len = make_filename(PyString_AsString(self->prefix), subname, path);
557 if (len < 0)
558 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000559
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000560 if (mi == MI_PACKAGE) {
561 path[len] = SEP;
562 strcpy(path + len + 1, "__init__.py");
563 }
564 else
565 strcpy(path + len, ".py");
Just van Rossum52e14d62002-12-30 22:08:05 +0000566
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800567 fp = safely_reopen_archive(self, &archive);
568 if (fp == NULL)
569 return NULL;
570
Gregory P. Smith027ab392014-01-27 00:15:10 -0800571 files = PyDict_GetItem(zip_directory_cache, self->archive);
572 if (files == NULL) {
573 /* This should never happen as safely_reopen_archive() should
574 * have repopulated zip_directory_cache if needed. */
575 return NULL;
576 }
577 toc_entry = PyDict_GetItemString(files, path);
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800578 if (toc_entry != NULL) {
579 PyObject *data = get_data(fp, archive, toc_entry);
580 fclose(fp);
581 return data;
582 }
583 fclose(fp);
Just van Rossum52e14d62002-12-30 22:08:05 +0000584
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000585 /* we have the module, but no source */
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800586 Py_RETURN_NONE;
Just van Rossum52e14d62002-12-30 22:08:05 +0000587}
588
589PyDoc_STRVAR(doc_find_module,
590"find_module(fullname, path=None) -> self or None.\n\
591\n\
592Search for a module specified by 'fullname'. 'fullname' must be the\n\
593fully qualified (dotted) module name. It returns the zipimporter\n\
594instance itself if the module was found, or None if it wasn't.\n\
595The optional 'path' argument is ignored -- it's there for compatibility\n\
596with the importer protocol.");
597
598PyDoc_STRVAR(doc_load_module,
599"load_module(fullname) -> module.\n\
600\n\
601Load the module specified by 'fullname'. 'fullname' must be the\n\
602fully qualified (dotted) module name. It returns the imported\n\
603module, or raises ZipImportError if it wasn't found.");
604
605PyDoc_STRVAR(doc_get_data,
606"get_data(pathname) -> string with file data.\n\
607\n\
608Return the data associated with 'pathname'. Raise IOError if\n\
609the file wasn't found.");
610
611PyDoc_STRVAR(doc_is_package,
612"is_package(fullname) -> bool.\n\
613\n\
614Return True if the module specified by fullname is a package.\n\
Brian Curtin13b43e72010-07-21 01:35:46 +0000615Raise ZipImportError if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000616
617PyDoc_STRVAR(doc_get_code,
618"get_code(fullname) -> code object.\n\
619\n\
620Return the code object for the specified module. Raise ZipImportError\n\
Brian Curtin13b43e72010-07-21 01:35:46 +0000621if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000622
623PyDoc_STRVAR(doc_get_source,
624"get_source(fullname) -> source string.\n\
625\n\
626Return the source code for the specified module. Raise ZipImportError\n\
Brian Curtin13b43e72010-07-21 01:35:46 +0000627if the module couldn't be found, return None if the archive does\n\
Just van Rossum52e14d62002-12-30 22:08:05 +0000628contain the module, but has no source for it.");
629
Nick Coghlana2053472008-12-14 10:54:50 +0000630
631PyDoc_STRVAR(doc_get_filename,
Nick Coghlan0194f5b2009-02-08 03:17:00 +0000632"get_filename(fullname) -> filename string.\n\
Nick Coghlana2053472008-12-14 10:54:50 +0000633\n\
634Return the filename for the specified module.");
635
Just van Rossum52e14d62002-12-30 22:08:05 +0000636static PyMethodDef zipimporter_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000637 {"find_module", zipimporter_find_module, METH_VARARGS,
638 doc_find_module},
639 {"load_module", zipimporter_load_module, METH_VARARGS,
640 doc_load_module},
641 {"get_data", zipimporter_get_data, METH_VARARGS,
642 doc_get_data},
643 {"get_code", zipimporter_get_code, METH_VARARGS,
644 doc_get_code},
645 {"get_source", zipimporter_get_source, METH_VARARGS,
646 doc_get_source},
647 {"get_filename", zipimporter_get_filename, METH_VARARGS,
648 doc_get_filename},
649 {"is_package", zipimporter_is_package, METH_VARARGS,
650 doc_is_package},
651 {NULL, NULL} /* sentinel */
Just van Rossum52e14d62002-12-30 22:08:05 +0000652};
653
654static PyMemberDef zipimporter_members[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000655 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
656 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
657 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
658 {NULL}
Just van Rossum52e14d62002-12-30 22:08:05 +0000659};
660
661PyDoc_STRVAR(zipimporter_doc,
662"zipimporter(archivepath) -> zipimporter object\n\
663\n\
664Create a new zipimporter instance. 'archivepath' must be a path to\n\
Georg Brandl6a57c082008-05-11 15:05:13 +0000665a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
666'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
667valid directory inside the archive.\n\
668\n\
669'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
670archive.\n\
671\n\
672The 'archive' attribute of zipimporter objects contains the name of the\n\
673zipfile targeted.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000674
675#define DEFERRED_ADDRESS(ADDR) 0
676
677static PyTypeObject ZipImporter_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000678 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
679 "zipimport.zipimporter",
680 sizeof(ZipImporter),
681 0, /* tp_itemsize */
682 (destructor)zipimporter_dealloc, /* tp_dealloc */
683 0, /* tp_print */
684 0, /* tp_getattr */
685 0, /* tp_setattr */
686 0, /* tp_compare */
687 (reprfunc)zipimporter_repr, /* tp_repr */
688 0, /* tp_as_number */
689 0, /* tp_as_sequence */
690 0, /* tp_as_mapping */
691 0, /* tp_hash */
692 0, /* tp_call */
693 0, /* tp_str */
694 PyObject_GenericGetAttr, /* tp_getattro */
695 0, /* tp_setattro */
696 0, /* tp_as_buffer */
Gregory P. Smith027ab392014-01-27 00:15:10 -0800697 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000698 zipimporter_doc, /* tp_doc */
Gregory P. Smith027ab392014-01-27 00:15:10 -0800699 0, /* tp_traverse */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000700 0, /* tp_clear */
701 0, /* tp_richcompare */
702 0, /* tp_weaklistoffset */
703 0, /* tp_iter */
704 0, /* tp_iternext */
705 zipimporter_methods, /* tp_methods */
706 zipimporter_members, /* tp_members */
707 0, /* tp_getset */
708 0, /* tp_base */
709 0, /* tp_dict */
710 0, /* tp_descr_get */
711 0, /* tp_descr_set */
712 0, /* tp_dictoffset */
713 (initproc)zipimporter_init, /* tp_init */
714 PyType_GenericAlloc, /* tp_alloc */
715 PyType_GenericNew, /* tp_new */
Gregory P. Smith027ab392014-01-27 00:15:10 -0800716 0, /* tp_free */
Just van Rossum52e14d62002-12-30 22:08:05 +0000717};
718
719
720/* implementation */
721
Just van Rossum52e14d62002-12-30 22:08:05 +0000722/* Given a buffer, return the long that is represented by the first
723 4 bytes, encoded as little endian. This partially reimplements
724 marshal.c:r_long() */
725static long
726get_long(unsigned char *buf) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000727 long x;
728 x = buf[0];
729 x |= (long)buf[1] << 8;
730 x |= (long)buf[2] << 16;
731 x |= (long)buf[3] << 24;
Just van Rossum52e14d62002-12-30 22:08:05 +0000732#if SIZEOF_LONG > 4
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000733 /* Sign extension for 64-bit machines */
734 x |= -(x & 0x80000000L);
Just van Rossum52e14d62002-12-30 22:08:05 +0000735#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000736 return x;
Just van Rossum52e14d62002-12-30 22:08:05 +0000737}
738
739/*
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800740 fopen_rb_and_stat(path, &py_stat) -> FILE *
741
742 Opens path in "rb" mode and populates the Python py_stat stat_result
743 with information about the opened file. *py_stat may not be changed
744 if there is no fstat_function or if fstat_function fails.
745
746 Returns NULL and does nothing to *py_stat if the open failed.
747*/
748static FILE *
749fopen_rb_and_stat(char *path, PyObject **py_stat_p)
750{
751 FILE *fp;
752 assert(py_stat_p != NULL);
753 assert(*py_stat_p == NULL);
754
755 fp = fopen(path, "rb");
756 if (fp == NULL) {
757 return NULL;
758 }
759
760 if (fstat_function) {
761 PyObject *stat_result = PyObject_CallFunction(fstat_function,
762 "i", fileno(fp));
763 if (stat_result == NULL) {
764 PyErr_Clear(); /* We can function without it. */
765 } else {
766 *py_stat_p = stat_result;
767 }
768 }
769
770 return fp;
771}
772
773/* Return 1 if objects a and b fail a Py_EQ test for an attr. */
774static int
775compare_obj_attr_strings(PyObject *obj_a, PyObject *obj_b, char *attr_name)
776{
777 int problem = 0;
778 PyObject *attr_a = PyObject_GetAttrString(obj_a, attr_name);
779 PyObject *attr_b = PyObject_GetAttrString(obj_b, attr_name);
780 if (attr_a == NULL || attr_b == NULL)
781 problem = 1;
782 else
783 problem = (PyObject_RichCompareBool(attr_a, attr_b, Py_EQ) != 1);
784 Py_XDECREF(attr_a);
785 Py_XDECREF(attr_b);
786 return problem;
787}
788
789/*
790 * Returns an open FILE * on success and sets *archive_p to point to
791 * a read only C string representation of the archive name (as a
792 * convenience for use in error messages).
793 *
794 * Returns NULL on error with the Python error context set.
795 */
796static FILE *
797safely_reopen_archive(ZipImporter *self, char **archive_p)
798{
799 FILE *fp;
800 PyObject *stat_now = NULL;
801 char *archive;
802
803 assert(archive_p != NULL);
804 *archive_p = PyString_AsString(self->archive);
805 if (*archive_p == NULL)
806 return NULL;
807 archive = *archive_p;
808
809 fp = fopen_rb_and_stat(archive, &stat_now);
810 if (!fp) {
811 PyErr_Format(PyExc_IOError,
812 "zipimport: can not open file %s", archive);
813 Py_XDECREF(stat_now);
814 return NULL;
815 }
816
817 if (stat_now != NULL) {
818 int problem = 0;
819 PyObject *files;
820 PyObject *prev_stat = PyDict_GetItemString(zip_stat_cache, archive);
821 /* Test stat_now vs the old cached stat on some key attributes. */
822 if (prev_stat != NULL) {
823 problem = compare_obj_attr_strings(prev_stat, stat_now,
824 "st_ino");
825 problem |= compare_obj_attr_strings(prev_stat, stat_now,
826 "st_size");
827 problem |= compare_obj_attr_strings(prev_stat, stat_now,
828 "st_mtime");
829 } else {
830 if (Py_VerboseFlag)
831 PySys_WriteStderr("# zipimport: no stat data for %s!\n",
832 archive);
833 problem = 1;
834 }
835
836 if (problem) {
837 if (Py_VerboseFlag)
838 PySys_WriteStderr("# zipimport: %s modified since last"
839 " import, rereading TOC.\n", archive);
840 files = read_directory(fp, archive);
841 if (files == NULL) {
842 Py_DECREF(stat_now);
843 fclose(fp);
844 return NULL;
845 }
846 if (PyDict_SetItem(zip_directory_cache, self->archive,
847 files) != 0) {
848 Py_DECREF(files);
849 Py_DECREF(stat_now);
850 fclose(fp);
851 return NULL;
852 }
853 if (stat_now && PyDict_SetItem(zip_stat_cache, self->archive,
854 stat_now) != 0) {
855 Py_DECREF(files);
856 Py_DECREF(stat_now);
857 fclose(fp);
858 return NULL;
859 }
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800860 }
Benjamin Peterson7251fe12014-01-09 09:36:10 -0600861 Py_DECREF(stat_now);
Gregory P. Smith027ab392014-01-27 00:15:10 -0800862 } else {
863 if (Py_VerboseFlag)
864 PySys_WriteStderr("# zipimport: os.fstat failed on the "
865 "open %s file.\n", archive);
866 }
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800867
868 return fp;
869}
870
871/*
872 read_directory(fp, archive) -> files dict (new reference)
Just van Rossum52e14d62002-12-30 22:08:05 +0000873
874 Given a path to a Zip archive, build a dict, mapping file names
875 (local to the archive, using SEP as a separator) to toc entries.
876
877 A toc_entry is a tuple:
878
Fred Drakef5b7fd22005-11-11 19:34:56 +0000879 (__file__, # value to use for __file__, available for all files
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000880 compress, # compression kind; 0 for uncompressed
881 data_size, # size of compressed data on disk
882 file_size, # size of decompressed data
883 file_offset, # offset of file header from start of archive
884 time, # mod time of file (in dos format)
885 date, # mod data of file (in dos format)
886 crc, # crc checksum of the data
Just van Rossum52e14d62002-12-30 22:08:05 +0000887 )
888
889 Directories can be recognized by the trailing SEP in the name,
890 data_size and file_offset are 0.
891*/
892static PyObject *
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800893read_directory(FILE *fp, char *archive)
Just van Rossum52e14d62002-12-30 22:08:05 +0000894{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000895 PyObject *files = NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000896 long compress, crc, data_size, file_size, file_offset, date, time;
897 long header_offset, name_size, header_size, header_position;
898 long i, l, count;
899 size_t length;
900 char path[MAXPATHLEN + 5];
901 char name[MAXPATHLEN + 5];
902 char *p, endof_central_dir[22];
903 long arc_offset; /* offset from beginning of file to start of zip-archive */
Just van Rossum52e14d62002-12-30 22:08:05 +0000904
Gregory P. Smithb48c5d52014-01-06 09:46:46 -0800905 assert(fp != NULL);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000906 if (strlen(archive) > MAXPATHLEN) {
907 PyErr_SetString(PyExc_OverflowError,
908 "Zip path name is too long");
909 return NULL;
910 }
911 strcpy(path, archive);
Just van Rossum52e14d62002-12-30 22:08:05 +0000912
Jesus Ceae884be62012-10-03 02:13:05 +0200913 if (fseek(fp, -22, SEEK_END) == -1) {
Jesus Ceae884be62012-10-03 02:13:05 +0200914 PyErr_Format(ZipImportError, "can't read Zip file: %s", archive);
915 return NULL;
916 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000917 header_position = ftell(fp);
918 if (fread(endof_central_dir, 1, 22, fp) != 22) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000919 PyErr_Format(ZipImportError, "can't read Zip file: "
920 "'%.200s'", archive);
921 return NULL;
922 }
923 if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
924 /* Bad: End of Central Dir signature */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000925 PyErr_Format(ZipImportError, "not a Zip file: "
926 "'%.200s'", archive);
927 return NULL;
928 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000929
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000930 header_size = get_long((unsigned char *)endof_central_dir + 12);
931 header_offset = get_long((unsigned char *)endof_central_dir + 16);
932 arc_offset = header_position - header_offset - header_size;
933 header_offset += arc_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000934
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000935 files = PyDict_New();
936 if (files == NULL)
937 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000938
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000939 length = (long)strlen(path);
940 path[length] = SEP;
Just van Rossum52e14d62002-12-30 22:08:05 +0000941
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000942 /* Start of Central Directory */
943 count = 0;
944 for (;;) {
945 PyObject *t;
946 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000947
Jesus Ceae884be62012-10-03 02:13:05 +0200948 if (fseek(fp, header_offset, 0) == -1) /* Start of file header */
949 goto fseek_error;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000950 l = PyMarshal_ReadLongFromFile(fp);
951 if (l != 0x02014B50)
952 break; /* Bad: Central Dir File Header */
Jesus Ceae884be62012-10-03 02:13:05 +0200953 if (fseek(fp, header_offset + 10, 0) == -1)
954 goto fseek_error;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000955 compress = PyMarshal_ReadShortFromFile(fp);
956 time = PyMarshal_ReadShortFromFile(fp);
957 date = PyMarshal_ReadShortFromFile(fp);
958 crc = PyMarshal_ReadLongFromFile(fp);
959 data_size = PyMarshal_ReadLongFromFile(fp);
960 file_size = PyMarshal_ReadLongFromFile(fp);
961 name_size = PyMarshal_ReadShortFromFile(fp);
962 header_size = 46 + name_size +
963 PyMarshal_ReadShortFromFile(fp) +
964 PyMarshal_ReadShortFromFile(fp);
Jesus Ceae884be62012-10-03 02:13:05 +0200965 if (fseek(fp, header_offset + 42, 0) == -1)
966 goto fseek_error;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000967 file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
968 if (name_size > MAXPATHLEN)
969 name_size = MAXPATHLEN;
Just van Rossum52e14d62002-12-30 22:08:05 +0000970
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000971 p = name;
972 for (i = 0; i < name_size; i++) {
973 *p = (char)getc(fp);
974 if (*p == '/')
975 *p = SEP;
976 p++;
977 }
978 *p = 0; /* Add terminating null byte */
979 header_offset += header_size;
Just van Rossum52e14d62002-12-30 22:08:05 +0000980
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000981 strncpy(path + length + 1, name, MAXPATHLEN - length - 1);
Just van Rossum52e14d62002-12-30 22:08:05 +0000982
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000983 t = Py_BuildValue("siiiiiii", path, compress, data_size,
984 file_size, file_offset, time, date, crc);
985 if (t == NULL)
986 goto error;
987 err = PyDict_SetItemString(files, name, t);
988 Py_DECREF(t);
989 if (err != 0)
990 goto error;
991 count++;
992 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000993 if (Py_VerboseFlag)
994 PySys_WriteStderr("# zipimport: found %ld names in %s\n",
995 count, archive);
996 return files;
Jesus Ceae884be62012-10-03 02:13:05 +0200997fseek_error:
Jesus Ceae884be62012-10-03 02:13:05 +0200998 Py_XDECREF(files);
999 PyErr_Format(ZipImportError, "can't read Zip file: %s", archive);
1000 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001001error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001002 Py_XDECREF(files);
1003 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001004}
1005
1006/* Return the zlib.decompress function object, or NULL if zlib couldn't
1007 be imported. The function is cached when found, so subsequent calls
Victor Stinnerf58f1c32011-05-21 02:13:22 +02001008 don't import zlib again. */
Just van Rossum52e14d62002-12-30 22:08:05 +00001009static PyObject *
1010get_decompress_func(void)
1011{
Victor Stinnerf58f1c32011-05-21 02:13:22 +02001012 static int importing_zlib = 0;
1013 PyObject *zlib;
1014 PyObject *decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +00001015
Victor Stinnerf58f1c32011-05-21 02:13:22 +02001016 if (importing_zlib != 0)
1017 /* Someone has a zlib.py[co] in their Zip file;
1018 let's avoid a stack overflow. */
1019 return NULL;
1020 importing_zlib = 1;
1021 zlib = PyImport_ImportModuleNoBlock("zlib");
1022 importing_zlib = 0;
1023 if (zlib != NULL) {
1024 decompress = PyObject_GetAttrString(zlib,
1025 "decompress");
1026 Py_DECREF(zlib);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001027 }
Victor Stinnerf58f1c32011-05-21 02:13:22 +02001028 else {
1029 PyErr_Clear();
1030 decompress = NULL;
1031 }
1032 if (Py_VerboseFlag)
1033 PySys_WriteStderr("# zipimport: zlib %s\n",
1034 zlib != NULL ? "available": "UNAVAILABLE");
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001035 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +00001036}
1037
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001038/* Given a FILE* to a Zip file and a toc_entry, return the (uncompressed)
Just van Rossum52e14d62002-12-30 22:08:05 +00001039 data as a new reference. */
1040static PyObject *
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001041get_data(FILE *fp, char *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001042{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001043 PyObject *raw_data, *data = NULL, *decompress;
1044 char *buf;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001045 int err;
1046 Py_ssize_t bytes_read = 0;
1047 long l;
1048 char *datapath;
1049 long compress, data_size, file_size, file_offset;
1050 long time, date, crc;
Just van Rossum52e14d62002-12-30 22:08:05 +00001051
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001052 if (!PyArg_ParseTuple(toc_entry, "slllllll", &datapath, &compress,
1053 &data_size, &file_size, &file_offset, &time,
1054 &date, &crc)) {
1055 return NULL;
1056 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001057
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001058 /* Check to make sure the local file header is correct */
Jesus Ceae884be62012-10-03 02:13:05 +02001059 if (fseek(fp, file_offset, 0) == -1) {
Jesus Ceae884be62012-10-03 02:13:05 +02001060 PyErr_Format(ZipImportError, "can't read Zip file: %s", archive);
1061 return NULL;
1062 }
1063
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001064 l = PyMarshal_ReadLongFromFile(fp);
1065 if (l != 0x04034B50) {
1066 /* Bad: Local File Header */
1067 PyErr_Format(ZipImportError,
1068 "bad local file header in %s",
1069 archive);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001070 return NULL;
1071 }
Jesus Ceae884be62012-10-03 02:13:05 +02001072 if (fseek(fp, file_offset + 26, 0) == -1) {
Jesus Ceae884be62012-10-03 02:13:05 +02001073 PyErr_Format(ZipImportError, "can't read Zip file: %s", archive);
1074 return NULL;
1075 }
1076
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001077 l = 30 + PyMarshal_ReadShortFromFile(fp) +
1078 PyMarshal_ReadShortFromFile(fp); /* local header size */
1079 file_offset += l; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +00001080
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001081 raw_data = PyString_FromStringAndSize((char *)NULL, compress == 0 ?
1082 data_size : data_size + 1);
1083 if (raw_data == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001084 return NULL;
1085 }
1086 buf = PyString_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001087
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001088 err = fseek(fp, file_offset, 0);
Jesus Ceae884be62012-10-03 02:13:05 +02001089 if (err == 0) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001090 bytes_read = fread(buf, 1, data_size, fp);
Jesus Ceae884be62012-10-03 02:13:05 +02001091 } else {
Jesus Ceae884be62012-10-03 02:13:05 +02001092 PyErr_Format(ZipImportError, "can't read Zip file: %s", archive);
1093 return NULL;
1094 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001095 if (err || bytes_read != data_size) {
1096 PyErr_SetString(PyExc_IOError,
1097 "zipimport: can't read data");
1098 Py_DECREF(raw_data);
1099 return NULL;
1100 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001101
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001102 if (compress != 0) {
1103 buf[data_size] = 'Z'; /* saw this in zipfile.py */
1104 data_size++;
1105 }
1106 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +00001107
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001108 if (compress == 0) /* data is not compressed */
1109 return raw_data;
Just van Rossum52e14d62002-12-30 22:08:05 +00001110
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001111 /* Decompress with zlib */
1112 decompress = get_decompress_func();
1113 if (decompress == NULL) {
1114 PyErr_SetString(ZipImportError,
1115 "can't decompress data; "
1116 "zlib not available");
1117 goto error;
1118 }
1119 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Victor Stinnerf58f1c32011-05-21 02:13:22 +02001120 Py_DECREF(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +00001121error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001122 Py_DECREF(raw_data);
1123 return data;
Just van Rossum52e14d62002-12-30 22:08:05 +00001124}
1125
1126/* Lenient date/time comparison function. The precision of the mtime
1127 in the archive is lower than the mtime stored in a .pyc: we
1128 must allow a difference of at most one second. */
1129static int
1130eq_mtime(time_t t1, time_t t2)
1131{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001132 time_t d = t1 - t2;
1133 if (d < 0)
1134 d = -d;
1135 /* dostime only stores even seconds, so be lenient */
1136 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001137}
1138
1139/* Given the contents of a .py[co] file in a buffer, unmarshal the data
1140 and return the code object. Return None if it the magic word doesn't
1141 match (we do this instead of raising an exception as we fall back
1142 to .py if available and we don't want to mask other errors).
1143 Returns a new reference. */
1144static PyObject *
1145unmarshal_code(char *pathname, PyObject *data, time_t mtime)
1146{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001147 PyObject *code;
1148 char *buf = PyString_AsString(data);
1149 Py_ssize_t size = PyString_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001150
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001151 if (size <= 9) {
1152 PyErr_SetString(ZipImportError,
1153 "bad pyc data");
1154 return NULL;
1155 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001156
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001157 if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
1158 if (Py_VerboseFlag)
1159 PySys_WriteStderr("# %s has bad magic\n",
1160 pathname);
1161 Py_INCREF(Py_None);
1162 return Py_None; /* signal caller to try alternative */
1163 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001164
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001165 if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
1166 mtime)) {
1167 if (Py_VerboseFlag)
1168 PySys_WriteStderr("# %s has bad mtime\n",
1169 pathname);
1170 Py_INCREF(Py_None);
1171 return Py_None; /* signal caller to try alternative */
1172 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001173
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001174 code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
1175 if (code == NULL)
1176 return NULL;
1177 if (!PyCode_Check(code)) {
1178 Py_DECREF(code);
1179 PyErr_Format(PyExc_TypeError,
1180 "compiled module %.200s is not a code object",
1181 pathname);
1182 return NULL;
1183 }
1184 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001185}
1186
1187/* Replace any occurances of "\r\n?" in the input string with "\n".
1188 This converts DOS and Mac line endings to Unix line endings.
1189 Also append a trailing "\n" to be compatible with
1190 PyParser_SimpleParseFile(). Returns a new reference. */
1191static PyObject *
1192normalize_line_endings(PyObject *source)
1193{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001194 char *buf, *q, *p = PyString_AsString(source);
1195 PyObject *fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001196
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001197 if (!p)
1198 return NULL;
Neal Norwitzee7c8f92006-08-13 18:12:03 +00001199
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001200 /* one char extra for trailing \n and one for terminating \0 */
1201 buf = (char *)PyMem_Malloc(PyString_Size(source) + 2);
1202 if (buf == NULL) {
1203 PyErr_SetString(PyExc_MemoryError,
1204 "zipimport: no memory to allocate "
1205 "source buffer");
1206 return NULL;
1207 }
1208 /* replace "\r\n?" by "\n" */
1209 for (q = buf; *p != '\0'; p++) {
1210 if (*p == '\r') {
1211 *q++ = '\n';
1212 if (*(p + 1) == '\n')
1213 p++;
1214 }
1215 else
1216 *q++ = *p;
1217 }
1218 *q++ = '\n'; /* add trailing \n */
1219 *q = '\0';
1220 fixed_source = PyString_FromString(buf);
1221 PyMem_Free(buf);
1222 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001223}
1224
1225/* Given a string buffer containing Python source code, compile it
1226 return and return a code object as a new reference. */
1227static PyObject *
1228compile_source(char *pathname, PyObject *source)
1229{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001230 PyObject *code, *fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001231
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001232 fixed_source = normalize_line_endings(source);
1233 if (fixed_source == NULL)
1234 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001235
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001236 code = Py_CompileString(PyString_AsString(fixed_source), pathname,
1237 Py_file_input);
1238 Py_DECREF(fixed_source);
1239 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001240}
1241
1242/* Convert the date/time values found in the Zip archive to a value
1243 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001244static time_t
1245parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001246{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001247 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001248
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001249 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes62a8e952008-01-18 07:30:20 +00001250
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001251 stm.tm_sec = (dostime & 0x1f) * 2;
1252 stm.tm_min = (dostime >> 5) & 0x3f;
1253 stm.tm_hour = (dostime >> 11) & 0x1f;
1254 stm.tm_mday = dosdate & 0x1f;
1255 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1256 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1257 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001258
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001259 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001260}
1261
1262/* Given a path to a .pyc or .pyo file in the archive, return the
Ezio Melottic2077b02011-03-16 12:34:31 +02001263 modification time of the matching .py file, or 0 if no source
Just van Rossum52e14d62002-12-30 22:08:05 +00001264 is available. */
1265static time_t
1266get_mtime_of_source(ZipImporter *self, char *path)
1267{
Gregory P. Smith027ab392014-01-27 00:15:10 -08001268 PyObject *toc_entry, *files;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001269 time_t mtime = 0;
1270 Py_ssize_t lastchar = strlen(path) - 1;
1271 char savechar = path[lastchar];
1272 path[lastchar] = '\0'; /* strip 'c' or 'o' from *.py[co] */
Gregory P. Smith027ab392014-01-27 00:15:10 -08001273 files = PyDict_GetItem(zip_directory_cache, self->archive);
1274 if (files == NULL) {
1275 /* This should never happen as safely_reopen_archive() from
1276 * our only caller repopulated zip_directory_cache if needed. */
1277 return 0;
1278 }
1279 toc_entry = PyDict_GetItemString(files, path);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001280 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1281 PyTuple_Size(toc_entry) == 8) {
1282 /* fetch the time stamp of the .py file for comparison
1283 with an embedded pyc time stamp */
1284 int time, date;
1285 time = PyInt_AsLong(PyTuple_GetItem(toc_entry, 5));
1286 date = PyInt_AsLong(PyTuple_GetItem(toc_entry, 6));
1287 mtime = parse_dostime(time, date);
1288 }
1289 path[lastchar] = savechar;
1290 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001291}
1292
1293/* Return the code object for the module named by 'fullname' from the
1294 Zip archive as a new reference. */
1295static PyObject *
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001296get_code_from_data(char *archive, FILE *fp, int ispackage,
1297 int isbytecode, time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001298{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001299 PyObject *data, *code;
1300 char *modpath;
Just van Rossum52e14d62002-12-30 22:08:05 +00001301
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001302 data = get_data(fp, archive, toc_entry);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001303 if (data == NULL)
1304 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001305
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001306 modpath = PyString_AsString(PyTuple_GetItem(toc_entry, 0));
Just van Rossum52e14d62002-12-30 22:08:05 +00001307
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001308 if (isbytecode) {
1309 code = unmarshal_code(modpath, data, mtime);
1310 }
1311 else {
1312 code = compile_source(modpath, data);
1313 }
1314 Py_DECREF(data);
1315 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001316}
1317
Ezio Melotti24b07bc2011-03-15 18:55:01 +02001318/* Get the code object associated with the module specified by
Just van Rossum52e14d62002-12-30 22:08:05 +00001319 'fullname'. */
1320static PyObject *
1321get_module_code(ZipImporter *self, char *fullname,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001322 int *p_ispackage, char **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001323{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001324 PyObject *toc_entry;
1325 char *subname, path[MAXPATHLEN + 1];
1326 int len;
1327 struct st_zip_searchorder *zso;
Gregory P. Smith6de72602014-01-07 18:39:48 -08001328 FILE *fp;
1329 char *archive;
Just van Rossum52e14d62002-12-30 22:08:05 +00001330
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001331 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +00001332
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001333 len = make_filename(PyString_AsString(self->prefix), subname, path);
1334 if (len < 0)
1335 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001336
Gregory P. Smith6de72602014-01-07 18:39:48 -08001337 fp = safely_reopen_archive(self, &archive);
1338 if (fp == NULL)
1339 return NULL;
1340
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001341 for (zso = zip_searchorder; *zso->suffix; zso++) {
Gregory P. Smith027ab392014-01-27 00:15:10 -08001342 PyObject *code = NULL, *files;
Just van Rossum52e14d62002-12-30 22:08:05 +00001343
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001344 strcpy(path + len, zso->suffix);
1345 if (Py_VerboseFlag > 1)
1346 PySys_WriteStderr("# trying %s%c%s\n",
1347 PyString_AsString(self->archive),
1348 SEP, path);
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001349
Gregory P. Smith027ab392014-01-27 00:15:10 -08001350 files = PyDict_GetItem(zip_directory_cache, self->archive);
1351 if (files == NULL) {
1352 /* This should never happen as safely_reopen_archive() should
1353 * have repopulated zip_directory_cache if needed; and the GIL
1354 * is being held. */
1355 return NULL;
1356 }
1357 toc_entry = PyDict_GetItemString(files, path);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001358 if (toc_entry != NULL) {
1359 time_t mtime = 0;
1360 int ispackage = zso->type & IS_PACKAGE;
1361 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001362
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001363 if (isbytecode)
1364 mtime = get_mtime_of_source(self, path);
1365 if (p_ispackage != NULL)
1366 *p_ispackage = ispackage;
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001367 code = get_code_from_data(archive, fp, ispackage,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001368 isbytecode, mtime,
1369 toc_entry);
1370 if (code == Py_None) {
1371 /* bad magic number or non-matching mtime
1372 in byte code, try next */
1373 Py_DECREF(code);
1374 continue;
1375 }
1376 if (code != NULL && p_modpath != NULL)
1377 *p_modpath = PyString_AsString(
1378 PyTuple_GetItem(toc_entry, 0));
Gregory P. Smith6de72602014-01-07 18:39:48 -08001379 fclose(fp);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001380 return code;
1381 }
1382 }
1383 PyErr_Format(ZipImportError, "can't find module '%.200s'", fullname);
Gregory P. Smith6de72602014-01-07 18:39:48 -08001384 fclose(fp);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001385 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001386}
1387
1388
1389/* Module init */
1390
1391PyDoc_STRVAR(zipimport_doc,
1392"zipimport provides support for importing Python modules from Zip archives.\n\
1393\n\
1394This module exports three objects:\n\
1395- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001396- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001397 subclass of ImportError, so it can be caught as ImportError, too.\n\
1398- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1399 info dicts, as used in zipimporter._files.\n\
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001400- _zip_stat_cache: a dict, mapping archive paths to stat_result\n\
1401 info for the .zip the last time anything was imported from it.\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001402\n\
1403It is usually not needed to use the zipimport module explicitly; it is\n\
1404used by the builtin import mechanism for sys.path items that are paths\n\
1405to Zip archives.");
1406
1407PyMODINIT_FUNC
1408initzipimport(void)
1409{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001410 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001411
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001412 if (PyType_Ready(&ZipImporter_Type) < 0)
1413 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001414
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001415 /* Correct directory separator */
1416 zip_searchorder[0].suffix[0] = SEP;
1417 zip_searchorder[1].suffix[0] = SEP;
1418 zip_searchorder[2].suffix[0] = SEP;
1419 if (Py_OptimizeFlag) {
1420 /* Reverse *.pyc and *.pyo */
1421 struct st_zip_searchorder tmp;
1422 tmp = zip_searchorder[0];
1423 zip_searchorder[0] = zip_searchorder[1];
1424 zip_searchorder[1] = tmp;
1425 tmp = zip_searchorder[3];
1426 zip_searchorder[3] = zip_searchorder[4];
1427 zip_searchorder[4] = tmp;
1428 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001429
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001430 mod = Py_InitModule4("zipimport", NULL, zipimport_doc,
1431 NULL, PYTHON_API_VERSION);
1432 if (mod == NULL)
1433 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001434
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001435 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1436 PyExc_ImportError, NULL);
1437 if (ZipImportError == NULL)
1438 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001439
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001440 Py_INCREF(ZipImportError);
1441 if (PyModule_AddObject(mod, "ZipImportError",
1442 ZipImportError) < 0)
1443 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001444
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001445 Py_INCREF(&ZipImporter_Type);
1446 if (PyModule_AddObject(mod, "zipimporter",
1447 (PyObject *)&ZipImporter_Type) < 0)
1448 return;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001449
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001450 Py_XDECREF(zip_directory_cache); /* Avoid embedded interpreter leaks. */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001451 zip_directory_cache = PyDict_New();
1452 if (zip_directory_cache == NULL)
1453 return;
1454 Py_INCREF(zip_directory_cache);
1455 if (PyModule_AddObject(mod, "_zip_directory_cache",
1456 zip_directory_cache) < 0)
1457 return;
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001458
1459 Py_XDECREF(zip_stat_cache); /* Avoid embedded interpreter leaks. */
1460 zip_stat_cache = PyDict_New();
1461 if (zip_stat_cache == NULL)
1462 return;
1463 Py_INCREF(zip_stat_cache);
1464 if (PyModule_AddObject(mod, "_zip_stat_cache", zip_stat_cache) < 0)
1465 return;
1466
1467 {
1468 /* We cannot import "os" here as that is a .py/.pyc file that could
1469 * live within a zipped up standard library. Import the posix or nt
1470 * builtin that provides the fstat() function we want instead. */
1471 PyObject *os_like_module;
Gregory P. Smithad3e7252014-01-07 01:11:09 -08001472 Py_CLEAR(fstat_function); /* Avoid embedded interpreter leaks. */
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001473 os_like_module = PyImport_ImportModule("posix");
1474 if (os_like_module == NULL) {
Gregory P. Smithad3e7252014-01-07 01:11:09 -08001475 PyErr_Clear();
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001476 os_like_module = PyImport_ImportModule("nt");
1477 }
1478 if (os_like_module != NULL) {
1479 fstat_function = PyObject_GetAttrString(os_like_module, "fstat");
1480 Py_DECREF(os_like_module);
1481 }
1482 if (fstat_function == NULL) {
1483 PyErr_Clear(); /* non-fatal, we'll go on without it. */
Gregory P. Smithad3e7252014-01-07 01:11:09 -08001484 if (Py_VerboseFlag)
1485 PySys_WriteStderr("# zipimport unable to use os.fstat().\n");
Gregory P. Smithb48c5d52014-01-06 09:46:46 -08001486 }
1487 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001488}