blob: b59fd50fc6ad6d5403f70dc8a5f288fcb6b3113a [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 Pitrouf95a1b32010-05-09 15:52:27 +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 Pitrouf95a1b32010-05-09 15:52:27 +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 Pitrouf95a1b32010-05-09 15:52:27 +000037 PyObject_HEAD
38 PyObject *archive; /* pathname of the Zip archive */
Victor Stinner72f767e2010-10-18 11:44:21 +000039 PyObject *prefix; /* file prefix: "a/sub/directory/",
40 encoded to the filesystem encoding */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000041 PyObject *files; /* dict with file info {path: toc_entry} */
Just van Rossum52e14d62002-12-30 22:08:05 +000042};
43
Just van Rossum52e14d62002-12-30 22:08:05 +000044static PyObject *ZipImportError;
Victor Stinnerc342fca2010-10-18 11:39:05 +000045/* read_directory() cache */
Just van Rossum52e14d62002-12-30 22:08:05 +000046static PyObject *zip_directory_cache = NULL;
47
48/* forward decls */
Victor Stinner2460a432010-08-16 17:54:28 +000049static PyObject *read_directory(PyObject *archive);
Victor Stinner60fe8d92010-08-16 23:48:11 +000050static PyObject *get_data(PyObject *archive, PyObject *toc_entry);
Just van Rossum52e14d62002-12-30 22:08:05 +000051static PyObject *get_module_code(ZipImporter *self, char *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +000052 int *p_ispackage, PyObject **p_modpath);
Just van Rossum52e14d62002-12-30 22:08:05 +000053
54
55#define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
56
57
58/* zipimporter.__init__
59 Split the "subdirectory" from the Zip archive path, lookup a matching
60 entry in sys.path_importer_cache, fetch the file directory from there
61 if found, or else read it from the archive. */
62static int
63zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
64{
Victor Stinner2460a432010-08-16 17:54:28 +000065 PyObject *pathobj, *files;
Victor Stinner2b8dab72010-08-14 14:54:10 +000066 Py_UNICODE *path, *p, *prefix, buf[MAXPATHLEN+2];
67 Py_ssize_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +000068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000069 if (!_PyArg_NoKeywords("zipimporter()", kwds))
70 return -1;
Georg Brandl02c42872005-08-26 06:42:30 +000071
Victor Stinner2b8dab72010-08-14 14:54:10 +000072 if (!PyArg_ParseTuple(args, "O&:zipimporter",
73 PyUnicode_FSDecoder, &pathobj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +000075
Victor Stinner2b8dab72010-08-14 14:54:10 +000076 /* copy path to buf */
77 len = PyUnicode_GET_SIZE(pathobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000078 if (len == 0) {
79 PyErr_SetString(ZipImportError, "archive path is empty");
Victor Stinner2b8dab72010-08-14 14:54:10 +000080 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000081 }
82 if (len >= MAXPATHLEN) {
83 PyErr_SetString(ZipImportError,
84 "archive path too long");
Victor Stinner2b8dab72010-08-14 14:54:10 +000085 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000086 }
Victor Stinner2b8dab72010-08-14 14:54:10 +000087 Py_UNICODE_strcpy(buf, PyUnicode_AS_UNICODE(pathobj));
Just van Rossum52e14d62002-12-30 22:08:05 +000088
89#ifdef ALTSEP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 for (p = buf; *p; p++) {
91 if (*p == ALTSEP)
92 *p = SEP;
93 }
Just van Rossum52e14d62002-12-30 22:08:05 +000094#endif
95
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000096 path = NULL;
97 prefix = NULL;
98 for (;;) {
99 struct stat statbuf;
100 int rv;
Just van Rossum52e14d62002-12-30 22:08:05 +0000101
Victor Stinner2b8dab72010-08-14 14:54:10 +0000102 if (pathobj == NULL) {
103 pathobj = PyUnicode_FromUnicode(buf, len);
104 if (pathobj == NULL)
105 goto error;
106 }
107 rv = _Py_stat(pathobj, &statbuf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000108 if (rv == 0) {
109 /* it exists */
110 if (S_ISREG(statbuf.st_mode))
111 /* it's a file */
112 path = buf;
113 break;
114 }
Victor Stinner2b8dab72010-08-14 14:54:10 +0000115 else if (PyErr_Occurred())
116 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000117 /* back up one path element */
Victor Stinner2b8dab72010-08-14 14:54:10 +0000118 p = Py_UNICODE_strrchr(buf, SEP);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000119 if (prefix != NULL)
120 *prefix = SEP;
121 if (p == NULL)
122 break;
123 *p = '\0';
Victor Stinner2b8dab72010-08-14 14:54:10 +0000124 len = p - buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 prefix = p;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000126 Py_CLEAR(pathobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000127 }
Victor Stinner2b8dab72010-08-14 14:54:10 +0000128 if (path == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 PyErr_SetString(ZipImportError, "not a Zip file");
Victor Stinner2b8dab72010-08-14 14:54:10 +0000130 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000131 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000132
Victor Stinner2b8dab72010-08-14 14:54:10 +0000133 files = PyDict_GetItem(zip_directory_cache, pathobj);
134 if (files == NULL) {
Victor Stinner2460a432010-08-16 17:54:28 +0000135 files = read_directory(pathobj);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000136 if (files == NULL)
137 goto error;
138 if (PyDict_SetItem(zip_directory_cache, pathobj, files) != 0)
139 goto error;
140 }
141 else
142 Py_INCREF(files);
143 self->files = files;
144
145 self->archive = pathobj;
146 pathobj = NULL;
147
148 if (prefix != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149 prefix++;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000150 len = Py_UNICODE_strlen(prefix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 if (prefix[len-1] != SEP) {
152 /* add trailing SEP */
153 prefix[len] = SEP;
154 prefix[len + 1] = '\0';
Victor Stinner2b8dab72010-08-14 14:54:10 +0000155 len++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000156 }
157 }
Victor Stinner2b8dab72010-08-14 14:54:10 +0000158 else
159 len = 0;
160 self->prefix = PyUnicode_FromUnicode(prefix, len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000161 if (self->prefix == NULL)
Victor Stinner2b8dab72010-08-14 14:54:10 +0000162 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 return 0;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000165
166error:
167 Py_XDECREF(pathobj);
168 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +0000169}
170
171/* GC support. */
172static int
173zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 ZipImporter *self = (ZipImporter *)obj;
176 Py_VISIT(self->files);
177 return 0;
Just van Rossum52e14d62002-12-30 22:08:05 +0000178}
179
180static void
181zipimporter_dealloc(ZipImporter *self)
182{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000183 PyObject_GC_UnTrack(self);
184 Py_XDECREF(self->archive);
185 Py_XDECREF(self->prefix);
186 Py_XDECREF(self->files);
187 Py_TYPE(self)->tp_free((PyObject *)self);
Just van Rossum52e14d62002-12-30 22:08:05 +0000188}
189
190static PyObject *
191zipimporter_repr(ZipImporter *self)
192{
Victor Stinner028dd972010-08-17 00:04:48 +0000193 if (self->archive == NULL)
194 return PyUnicode_FromString("<zipimporter object \"???\">");
195 else if (self->prefix != NULL && PyUnicode_GET_SIZE(self->prefix) != 0)
196 return PyUnicode_FromFormat("<zipimporter object \"%.300U%c%.150U\">",
197 self->archive, SEP, self->prefix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 else
Victor Stinner028dd972010-08-17 00:04:48 +0000199 return PyUnicode_FromFormat("<zipimporter object \"%.300U\">",
200 self->archive);
Just van Rossum52e14d62002-12-30 22:08:05 +0000201}
202
203/* return fullname.split(".")[-1] */
204static char *
205get_subname(char *fullname)
206{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 char *subname = strrchr(fullname, '.');
208 if (subname == NULL)
209 subname = fullname;
210 else
211 subname++;
212 return subname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000213}
214
215/* Given a (sub)modulename, write the potential file path in the
216 archive (without extension) to the path buffer. Return the
217 length of the resulting string. */
218static int
Victor Stinner269aeb72010-10-18 20:40:59 +0000219make_filename(PyObject *prefix_obj, char *name, char *path, size_t pathsize)
Just van Rossum52e14d62002-12-30 22:08:05 +0000220{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000221 size_t len;
222 char *p;
Victor Stinner72f767e2010-10-18 11:44:21 +0000223 PyObject *prefix;
Just van Rossum52e14d62002-12-30 22:08:05 +0000224
Victor Stinner72f767e2010-10-18 11:44:21 +0000225 prefix = PyUnicode_EncodeFSDefault(prefix_obj);
226 if (prefix == NULL)
227 return -1;
228 len = PyBytes_GET_SIZE(prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 /* self.prefix + name [+ SEP + "__init__"] + ".py[co]" */
Victor Stinner269aeb72010-10-18 20:40:59 +0000231 if (len + strlen(name) + 13 >= pathsize - 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000232 PyErr_SetString(ZipImportError, "path too long");
Victor Stinner72f767e2010-10-18 11:44:21 +0000233 Py_DECREF(prefix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 return -1;
235 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000236
Victor Stinner72f767e2010-10-18 11:44:21 +0000237 strcpy(path, PyBytes_AS_STRING(prefix));
238 Py_DECREF(prefix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 strcpy(path + len, name);
240 for (p = path + len; *p; p++) {
241 if (*p == '.')
242 *p = SEP;
243 }
244 len += strlen(name);
245 assert(len < INT_MAX);
246 return (int)len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000247}
248
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000249enum zi_module_info {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 MI_ERROR,
251 MI_NOT_FOUND,
252 MI_MODULE,
253 MI_PACKAGE
Just van Rossum52e14d62002-12-30 22:08:05 +0000254};
255
256/* Return some information about a module. */
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000257static enum zi_module_info
Victor Stinner04106562010-10-18 20:44:08 +0000258get_module_info(ZipImporter *self, PyObject *fullname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000259{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 char *subname, path[MAXPATHLEN + 1];
261 int len;
262 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +0000263
Victor Stinner04106562010-10-18 20:44:08 +0000264 subname = get_subname(PyBytes_AS_STRING(fullname));
Just van Rossum52e14d62002-12-30 22:08:05 +0000265
Victor Stinner269aeb72010-10-18 20:40:59 +0000266 len = make_filename(self->prefix, subname, path, sizeof(path));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 if (len < 0)
268 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 for (zso = zip_searchorder; *zso->suffix; zso++) {
271 strcpy(path + len, zso->suffix);
272 if (PyDict_GetItemString(self->files, path) != NULL) {
273 if (zso->type & IS_PACKAGE)
274 return MI_PACKAGE;
275 else
276 return MI_MODULE;
277 }
278 }
279 return MI_NOT_FOUND;
Just van Rossum52e14d62002-12-30 22:08:05 +0000280}
281
282/* Check whether we can satisfy the import of the module named by
283 'fullname'. Return self if we can, None if we can't. */
284static PyObject *
285zipimporter_find_module(PyObject *obj, PyObject *args)
286{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 ZipImporter *self = (ZipImporter *)obj;
288 PyObject *path = NULL;
Victor Stinner04106562010-10-18 20:44:08 +0000289 PyObject *fullname;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000291
Victor Stinner04106562010-10-18 20:44:08 +0000292 if (!PyArg_ParseTuple(args, "O&|O:zipimporter.find_module",
293 PyUnicode_FSConverter, &fullname, &path))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 mi = get_module_info(self, fullname);
Victor Stinner04106562010-10-18 20:44:08 +0000297 Py_DECREF(fullname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000298 if (mi == MI_ERROR)
299 return NULL;
300 if (mi == MI_NOT_FOUND) {
301 Py_INCREF(Py_None);
302 return Py_None;
303 }
304 Py_INCREF(self);
305 return (PyObject *)self;
Just van Rossum52e14d62002-12-30 22:08:05 +0000306}
307
308/* Load and return the module named by 'fullname'. */
309static PyObject *
310zipimporter_load_module(PyObject *obj, PyObject *args)
311{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 ZipImporter *self = (ZipImporter *)obj;
Victor Stinner26fabe12010-10-18 12:03:25 +0000313 PyObject *code = NULL, *mod, *dict;
Victor Stinner08654e12010-10-18 12:09:02 +0000314 char *fullname;
315 PyObject *modpath = NULL, *modpath_bytes;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000316 int ispackage;
Just van Rossum52e14d62002-12-30 22:08:05 +0000317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 if (!PyArg_ParseTuple(args, "s:zipimporter.load_module",
319 &fullname))
320 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 code = get_module_code(self, fullname, &ispackage, &modpath);
323 if (code == NULL)
Victor Stinner26fabe12010-10-18 12:03:25 +0000324 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 mod = PyImport_AddModule(fullname);
Victor Stinner26fabe12010-10-18 12:03:25 +0000327 if (mod == NULL)
328 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 dict = PyModule_GetDict(mod);
Just van Rossum52e14d62002-12-30 22:08:05 +0000330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 /* mod.__loader__ = self */
332 if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
333 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 if (ispackage) {
336 /* add __path__ to the module *before* the code gets
337 executed */
338 PyObject *pkgpath, *fullpath;
339 char *subname = get_subname(fullname);
340 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000341
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000342 fullpath = PyUnicode_FromFormat("%U%c%U%s",
343 self->archive, SEP,
344 self->prefix, subname);
345 if (fullpath == NULL)
346 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000348 pkgpath = Py_BuildValue("[O]", fullpath);
349 Py_DECREF(fullpath);
350 if (pkgpath == NULL)
351 goto error;
352 err = PyDict_SetItemString(dict, "__path__", pkgpath);
353 Py_DECREF(pkgpath);
354 if (err != 0)
355 goto error;
356 }
Victor Stinner08654e12010-10-18 12:09:02 +0000357 modpath_bytes = PyUnicode_EncodeFSDefault(modpath);
358 if (modpath_bytes == NULL)
359 goto error;
360 mod = PyImport_ExecCodeModuleEx(fullname, code,
361 PyBytes_AS_STRING(modpath_bytes));
362 Py_DECREF(modpath_bytes);
Victor Stinner26fabe12010-10-18 12:03:25 +0000363 Py_CLEAR(code);
364 if (mod == NULL)
365 goto error;
366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 if (Py_VerboseFlag)
Victor Stinner08654e12010-10-18 12:09:02 +0000368 PySys_FormatStderr("import %s # loaded from Zip %U\n",
369 fullname, modpath);
370 Py_DECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +0000372error:
Victor Stinner26fabe12010-10-18 12:03:25 +0000373 Py_XDECREF(code);
Victor Stinner08654e12010-10-18 12:09:02 +0000374 Py_XDECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000375 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000376}
377
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000378/* Return a string matching __file__ for the named module */
379static PyObject *
380zipimporter_get_filename(PyObject *obj, PyObject *args)
381{
382 ZipImporter *self = (ZipImporter *)obj;
383 PyObject *code;
Victor Stinner08654e12010-10-18 12:09:02 +0000384 char *fullname;
385 PyObject *modpath;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000386 int ispackage;
387
Nick Coghlan9a1d6e32009-02-08 03:37:27 +0000388 if (!PyArg_ParseTuple(args, "s:zipimporter.get_filename",
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000389 &fullname))
Victor Stinnerc342fca2010-10-18 11:39:05 +0000390 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000391
392 /* Deciding the filename requires working out where the code
393 would come from if the module was actually loaded */
394 code = get_module_code(self, fullname, &ispackage, &modpath);
395 if (code == NULL)
Victor Stinnerc342fca2010-10-18 11:39:05 +0000396 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000397 Py_DECREF(code); /* Only need the path info */
398
Victor Stinner08654e12010-10-18 12:09:02 +0000399 return modpath;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000400}
401
Victor Stinner8c8ed0a2010-10-18 21:21:02 +0000402static void
403cant_find_module(PyObject *bytes)
404{
405 PyObject *unicode = PyUnicode_DecodeFSDefaultAndSize(
406 PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
407 if (unicode != NULL) {
408 PyErr_Format(ZipImportError, "can't find module %U",
409 unicode);
410 Py_DECREF(unicode);
411 }
412 else
413 PyErr_Format(ZipImportError, "can't find module");
414}
415
Just van Rossum52e14d62002-12-30 22:08:05 +0000416/* Return a bool signifying whether the module is a package or not. */
417static PyObject *
418zipimporter_is_package(PyObject *obj, PyObject *args)
419{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 ZipImporter *self = (ZipImporter *)obj;
Victor Stinner04106562010-10-18 20:44:08 +0000421 PyObject *fullname;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000422 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000423
Victor Stinner04106562010-10-18 20:44:08 +0000424 if (!PyArg_ParseTuple(args, "O&:zipimporter.is_package",
425 PyUnicode_FSConverter, &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000428 mi = get_module_info(self, fullname);
429 if (mi == MI_ERROR)
Victor Stinner04106562010-10-18 20:44:08 +0000430 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000431 if (mi == MI_NOT_FOUND) {
Victor Stinner8c8ed0a2010-10-18 21:21:02 +0000432 cant_find_module(fullname);
Victor Stinner04106562010-10-18 20:44:08 +0000433 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000434 }
Victor Stinner04106562010-10-18 20:44:08 +0000435 Py_DECREF(fullname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000436 return PyBool_FromLong(mi == MI_PACKAGE);
Victor Stinner04106562010-10-18 20:44:08 +0000437
438error:
439 Py_DECREF(fullname);
440 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000441}
442
443static PyObject *
444zipimporter_get_data(PyObject *obj, PyObject *args)
445{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000446 ZipImporter *self = (ZipImporter *)obj;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000447 PyObject *pathobj, *key;
448 const Py_UNICODE *path;
Just van Rossum52e14d62002-12-30 22:08:05 +0000449#ifdef ALTSEP
Victor Stinner60fe8d92010-08-16 23:48:11 +0000450 Py_UNICODE *p, buf[MAXPATHLEN + 1];
Just van Rossum52e14d62002-12-30 22:08:05 +0000451#endif
Victor Stinner60fe8d92010-08-16 23:48:11 +0000452 Py_UNICODE *archive;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 PyObject *toc_entry;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000454 Py_ssize_t path_len, len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000455
Victor Stinner60fe8d92010-08-16 23:48:11 +0000456 if (!PyArg_ParseTuple(args, "U:zipimporter.get_data", &pathobj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000457 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000458
Victor Stinner60fe8d92010-08-16 23:48:11 +0000459 path_len = PyUnicode_GET_SIZE(pathobj);
460 path = PyUnicode_AS_UNICODE(pathobj);
Just van Rossum52e14d62002-12-30 22:08:05 +0000461#ifdef ALTSEP
Victor Stinner60fe8d92010-08-16 23:48:11 +0000462 if (path_len >= MAXPATHLEN) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 PyErr_SetString(ZipImportError, "path too long");
464 return NULL;
465 }
Victor Stinner60fe8d92010-08-16 23:48:11 +0000466 Py_UNICODE_strcpy(buf, path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 for (p = buf; *p; p++) {
468 if (*p == ALTSEP)
469 *p = SEP;
470 }
471 path = buf;
Just van Rossum52e14d62002-12-30 22:08:05 +0000472#endif
Victor Stinner60fe8d92010-08-16 23:48:11 +0000473 archive = PyUnicode_AS_UNICODE(self->archive);
474 len = PyUnicode_GET_SIZE(self->archive);
475 if ((size_t)len < Py_UNICODE_strlen(path) &&
476 Py_UNICODE_strncmp(path, archive, len) == 0 &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 path[len] == SEP) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000478 path += len + 1;
479 path_len -= len + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000481
Victor Stinner60fe8d92010-08-16 23:48:11 +0000482 key = PyUnicode_FromUnicode(path, path_len);
483 if (key == NULL)
484 return NULL;
485 toc_entry = PyDict_GetItem(self->files, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 if (toc_entry == NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000487 PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, key);
488 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 return NULL;
490 }
Victor Stinner60fe8d92010-08-16 23:48:11 +0000491 Py_DECREF(key);
492 return get_data(self->archive, toc_entry);
Just van Rossum52e14d62002-12-30 22:08:05 +0000493}
494
495static PyObject *
496zipimporter_get_code(PyObject *obj, PyObject *args)
497{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 ZipImporter *self = (ZipImporter *)obj;
499 char *fullname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000500
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 if (!PyArg_ParseTuple(args, "s:zipimporter.get_code", &fullname))
502 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 return get_module_code(self, fullname, NULL, NULL);
Just van Rossum52e14d62002-12-30 22:08:05 +0000505}
506
507static PyObject *
508zipimporter_get_source(PyObject *obj, PyObject *args)
509{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 ZipImporter *self = (ZipImporter *)obj;
511 PyObject *toc_entry;
Victor Stinner04106562010-10-18 20:44:08 +0000512 PyObject *fullname;
513 char *subname, path[MAXPATHLEN+1];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 int len;
515 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000516
Victor Stinner04106562010-10-18 20:44:08 +0000517 if (!PyArg_ParseTuple(args, "O&:zipimporter.get_source",
518 PyUnicode_FSConverter, &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 mi = get_module_info(self, fullname);
Victor Stinner04106562010-10-18 20:44:08 +0000522 if (mi == MI_ERROR) {
523 Py_DECREF(fullname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 return NULL;
525 }
Victor Stinner04106562010-10-18 20:44:08 +0000526 if (mi == MI_NOT_FOUND) {
Victor Stinner8c8ed0a2010-10-18 21:21:02 +0000527 cant_find_module(fullname);
Victor Stinner04106562010-10-18 20:44:08 +0000528 Py_DECREF(fullname);
529 return NULL;
530 }
531 subname = get_subname(PyBytes_AS_STRING(fullname));
Just van Rossum52e14d62002-12-30 22:08:05 +0000532
Victor Stinner269aeb72010-10-18 20:40:59 +0000533 len = make_filename(self->prefix, subname, path, sizeof(path));
Victor Stinner04106562010-10-18 20:44:08 +0000534 Py_DECREF(fullname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 if (len < 0)
536 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000537
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 if (mi == MI_PACKAGE) {
539 path[len] = SEP;
540 strcpy(path + len + 1, "__init__.py");
541 }
542 else
543 strcpy(path + len, ".py");
Just van Rossum52e14d62002-12-30 22:08:05 +0000544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 toc_entry = PyDict_GetItemString(self->files, path);
546 if (toc_entry != NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000547 PyObject *res, *bytes;
548 bytes = get_data(self->archive, toc_entry);
549 if (bytes == NULL)
550 return NULL;
551 res = PyUnicode_FromStringAndSize(PyBytes_AS_STRING(bytes),
552 PyBytes_GET_SIZE(bytes));
553 Py_DECREF(bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000554 return res;
555 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 /* we have the module, but no source */
558 Py_INCREF(Py_None);
559 return Py_None;
Just van Rossum52e14d62002-12-30 22:08:05 +0000560}
561
562PyDoc_STRVAR(doc_find_module,
563"find_module(fullname, path=None) -> self or None.\n\
564\n\
565Search for a module specified by 'fullname'. 'fullname' must be the\n\
566fully qualified (dotted) module name. It returns the zipimporter\n\
567instance itself if the module was found, or None if it wasn't.\n\
568The optional 'path' argument is ignored -- it's there for compatibility\n\
569with the importer protocol.");
570
571PyDoc_STRVAR(doc_load_module,
572"load_module(fullname) -> module.\n\
573\n\
574Load the module specified by 'fullname'. 'fullname' must be the\n\
575fully qualified (dotted) module name. It returns the imported\n\
576module, or raises ZipImportError if it wasn't found.");
577
578PyDoc_STRVAR(doc_get_data,
579"get_data(pathname) -> string with file data.\n\
580\n\
581Return the data associated with 'pathname'. Raise IOError if\n\
582the file wasn't found.");
583
584PyDoc_STRVAR(doc_is_package,
585"is_package(fullname) -> bool.\n\
586\n\
587Return True if the module specified by fullname is a package.\n\
Brian Curtin32839732010-07-21 01:44:19 +0000588Raise ZipImportError if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000589
590PyDoc_STRVAR(doc_get_code,
591"get_code(fullname) -> code object.\n\
592\n\
593Return the code object for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000594if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000595
596PyDoc_STRVAR(doc_get_source,
597"get_source(fullname) -> source string.\n\
598\n\
599Return the source code for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000600if the module couldn't be found, return None if the archive does\n\
Just van Rossum52e14d62002-12-30 22:08:05 +0000601contain the module, but has no source for it.");
602
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000603
604PyDoc_STRVAR(doc_get_filename,
Nick Coghlan9a1d6e32009-02-08 03:37:27 +0000605"get_filename(fullname) -> filename string.\n\
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000606\n\
607Return the filename for the specified module.");
608
Just van Rossum52e14d62002-12-30 22:08:05 +0000609static PyMethodDef zipimporter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 {"find_module", zipimporter_find_module, METH_VARARGS,
611 doc_find_module},
612 {"load_module", zipimporter_load_module, METH_VARARGS,
613 doc_load_module},
614 {"get_data", zipimporter_get_data, METH_VARARGS,
615 doc_get_data},
616 {"get_code", zipimporter_get_code, METH_VARARGS,
617 doc_get_code},
618 {"get_source", zipimporter_get_source, METH_VARARGS,
619 doc_get_source},
620 {"get_filename", zipimporter_get_filename, METH_VARARGS,
621 doc_get_filename},
622 {"is_package", zipimporter_is_package, METH_VARARGS,
623 doc_is_package},
624 {NULL, NULL} /* sentinel */
Just van Rossum52e14d62002-12-30 22:08:05 +0000625};
626
627static PyMemberDef zipimporter_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
629 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
630 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
631 {NULL}
Just van Rossum52e14d62002-12-30 22:08:05 +0000632};
633
634PyDoc_STRVAR(zipimporter_doc,
635"zipimporter(archivepath) -> zipimporter object\n\
636\n\
637Create a new zipimporter instance. 'archivepath' must be a path to\n\
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +0000638a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
639'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
640valid directory inside the archive.\n\
641\n\
642'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
643archive.\n\
644\n\
645The 'archive' attribute of zipimporter objects contains the name of the\n\
646zipfile targeted.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000647
648#define DEFERRED_ADDRESS(ADDR) 0
649
650static PyTypeObject ZipImporter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000651 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
652 "zipimport.zipimporter",
653 sizeof(ZipImporter),
654 0, /* tp_itemsize */
655 (destructor)zipimporter_dealloc, /* tp_dealloc */
656 0, /* tp_print */
657 0, /* tp_getattr */
658 0, /* tp_setattr */
659 0, /* tp_reserved */
660 (reprfunc)zipimporter_repr, /* tp_repr */
661 0, /* tp_as_number */
662 0, /* tp_as_sequence */
663 0, /* tp_as_mapping */
664 0, /* tp_hash */
665 0, /* tp_call */
666 0, /* tp_str */
667 PyObject_GenericGetAttr, /* tp_getattro */
668 0, /* tp_setattro */
669 0, /* tp_as_buffer */
670 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
671 Py_TPFLAGS_HAVE_GC, /* tp_flags */
672 zipimporter_doc, /* tp_doc */
673 zipimporter_traverse, /* tp_traverse */
674 0, /* tp_clear */
675 0, /* tp_richcompare */
676 0, /* tp_weaklistoffset */
677 0, /* tp_iter */
678 0, /* tp_iternext */
679 zipimporter_methods, /* tp_methods */
680 zipimporter_members, /* tp_members */
681 0, /* tp_getset */
682 0, /* tp_base */
683 0, /* tp_dict */
684 0, /* tp_descr_get */
685 0, /* tp_descr_set */
686 0, /* tp_dictoffset */
687 (initproc)zipimporter_init, /* tp_init */
688 PyType_GenericAlloc, /* tp_alloc */
689 PyType_GenericNew, /* tp_new */
690 PyObject_GC_Del, /* tp_free */
Just van Rossum52e14d62002-12-30 22:08:05 +0000691};
692
693
694/* implementation */
695
Just van Rossum52e14d62002-12-30 22:08:05 +0000696/* Given a buffer, return the long that is represented by the first
697 4 bytes, encoded as little endian. This partially reimplements
698 marshal.c:r_long() */
699static long
700get_long(unsigned char *buf) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000701 long x;
702 x = buf[0];
703 x |= (long)buf[1] << 8;
704 x |= (long)buf[2] << 16;
705 x |= (long)buf[3] << 24;
Just van Rossum52e14d62002-12-30 22:08:05 +0000706#if SIZEOF_LONG > 4
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 /* Sign extension for 64-bit machines */
708 x |= -(x & 0x80000000L);
Just van Rossum52e14d62002-12-30 22:08:05 +0000709#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000710 return x;
Just van Rossum52e14d62002-12-30 22:08:05 +0000711}
712
713/*
714 read_directory(archive) -> files dict (new reference)
715
716 Given a path to a Zip archive, build a dict, mapping file names
717 (local to the archive, using SEP as a separator) to toc entries.
718
719 A toc_entry is a tuple:
720
Victor Stinner08654e12010-10-18 12:09:02 +0000721 (__file__, # value to use for __file__, available for all files,
722 # encoded to the filesystem encoding
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 compress, # compression kind; 0 for uncompressed
724 data_size, # size of compressed data on disk
725 file_size, # size of decompressed data
726 file_offset, # offset of file header from start of archive
727 time, # mod time of file (in dos format)
728 date, # mod data of file (in dos format)
729 crc, # crc checksum of the data
Victor Stinnerc342fca2010-10-18 11:39:05 +0000730 )
Just van Rossum52e14d62002-12-30 22:08:05 +0000731
732 Directories can be recognized by the trailing SEP in the name,
733 data_size and file_offset are 0.
734*/
735static PyObject *
Victor Stinner2460a432010-08-16 17:54:28 +0000736read_directory(PyObject *archive_obj)
Just van Rossum52e14d62002-12-30 22:08:05 +0000737{
Victor Stinner2460a432010-08-16 17:54:28 +0000738 /* FIXME: work on Py_UNICODE* instead of char* */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739 PyObject *files = NULL;
740 FILE *fp;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000741 unsigned short flags;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742 long compress, crc, data_size, file_size, file_offset, date, time;
743 long header_offset, name_size, header_size, header_position;
744 long i, l, count;
745 size_t length;
Victor Stinner2460a432010-08-16 17:54:28 +0000746 Py_UNICODE path[MAXPATHLEN + 5];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 char name[MAXPATHLEN + 5];
Victor Stinner2460a432010-08-16 17:54:28 +0000748 PyObject *nameobj = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000749 char *p, endof_central_dir[22];
750 long arc_offset; /* offset from beginning of file to start of zip-archive */
Victor Stinner2460a432010-08-16 17:54:28 +0000751 PyObject *pathobj;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000752 const char *charset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000753
Victor Stinner2460a432010-08-16 17:54:28 +0000754 if (PyUnicode_GET_SIZE(archive_obj) > MAXPATHLEN) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000755 PyErr_SetString(PyExc_OverflowError,
756 "Zip path name is too long");
757 return NULL;
758 }
Victor Stinner2460a432010-08-16 17:54:28 +0000759 Py_UNICODE_strcpy(path, PyUnicode_AS_UNICODE(archive_obj));
Just van Rossum52e14d62002-12-30 22:08:05 +0000760
Victor Stinner2460a432010-08-16 17:54:28 +0000761 fp = _Py_fopen(archive_obj, "rb");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 if (fp == NULL) {
763 PyErr_Format(ZipImportError, "can't open Zip file: "
Victor Stinner2460a432010-08-16 17:54:28 +0000764 "'%.200U'", archive_obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765 return NULL;
766 }
767 fseek(fp, -22, SEEK_END);
768 header_position = ftell(fp);
769 if (fread(endof_central_dir, 1, 22, fp) != 22) {
770 fclose(fp);
771 PyErr_Format(ZipImportError, "can't read Zip file: "
Victor Stinner2460a432010-08-16 17:54:28 +0000772 "'%.200U'", archive_obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000773 return NULL;
774 }
775 if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
776 /* Bad: End of Central Dir signature */
777 fclose(fp);
778 PyErr_Format(ZipImportError, "not a Zip file: "
Victor Stinner2460a432010-08-16 17:54:28 +0000779 "'%.200U'", archive_obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000780 return NULL;
781 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000782
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000783 header_size = get_long((unsigned char *)endof_central_dir + 12);
784 header_offset = get_long((unsigned char *)endof_central_dir + 16);
785 arc_offset = header_position - header_offset - header_size;
786 header_offset += arc_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000788 files = PyDict_New();
789 if (files == NULL)
790 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000791
Victor Stinner2460a432010-08-16 17:54:28 +0000792 length = Py_UNICODE_strlen(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000793 path[length] = SEP;
Just van Rossum52e14d62002-12-30 22:08:05 +0000794
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000795 /* Start of Central Directory */
796 count = 0;
797 for (;;) {
798 PyObject *t;
799 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000800
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000801 fseek(fp, header_offset, 0); /* Start of file header */
802 l = PyMarshal_ReadLongFromFile(fp);
803 if (l != 0x02014B50)
804 break; /* Bad: Central Dir File Header */
Victor Stinnerd36c8212010-10-18 12:13:46 +0000805 fseek(fp, header_offset + 8, 0);
806 flags = (unsigned short)PyMarshal_ReadShortFromFile(fp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000807 compress = PyMarshal_ReadShortFromFile(fp);
808 time = PyMarshal_ReadShortFromFile(fp);
809 date = PyMarshal_ReadShortFromFile(fp);
810 crc = PyMarshal_ReadLongFromFile(fp);
811 data_size = PyMarshal_ReadLongFromFile(fp);
812 file_size = PyMarshal_ReadLongFromFile(fp);
813 name_size = PyMarshal_ReadShortFromFile(fp);
814 header_size = 46 + name_size +
815 PyMarshal_ReadShortFromFile(fp) +
816 PyMarshal_ReadShortFromFile(fp);
817 fseek(fp, header_offset + 42, 0);
818 file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
819 if (name_size > MAXPATHLEN)
820 name_size = MAXPATHLEN;
Just van Rossum52e14d62002-12-30 22:08:05 +0000821
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000822 p = name;
823 for (i = 0; i < name_size; i++) {
824 *p = (char)getc(fp);
825 if (*p == '/')
826 *p = SEP;
827 p++;
828 }
829 *p = 0; /* Add terminating null byte */
830 header_offset += header_size;
Just van Rossum52e14d62002-12-30 22:08:05 +0000831
Victor Stinnerd36c8212010-10-18 12:13:46 +0000832 if (flags & 0x0800)
833 charset = "utf-8";
834 else
835 charset = "cp437";
836 nameobj = PyUnicode_Decode(name, name_size, charset, NULL);
Victor Stinner2460a432010-08-16 17:54:28 +0000837 if (nameobj == NULL)
838 goto error;
839 Py_UNICODE_strncpy(path + length + 1, PyUnicode_AS_UNICODE(nameobj), MAXPATHLEN - length - 1);
Just van Rossum52e14d62002-12-30 22:08:05 +0000840
Victor Stinner2460a432010-08-16 17:54:28 +0000841 pathobj = PyUnicode_FromUnicode(path, Py_UNICODE_strlen(path));
842 if (pathobj == NULL)
843 goto error;
844 t = Py_BuildValue("Niiiiiii", pathobj, compress, data_size,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000845 file_size, file_offset, time, date, crc);
846 if (t == NULL)
847 goto error;
Victor Stinner2460a432010-08-16 17:54:28 +0000848 err = PyDict_SetItem(files, nameobj, t);
849 Py_CLEAR(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000850 Py_DECREF(t);
851 if (err != 0)
852 goto error;
853 count++;
854 }
855 fclose(fp);
856 if (Py_VerboseFlag)
Victor Stinner2460a432010-08-16 17:54:28 +0000857 PySys_FormatStderr("# zipimport: found %ld names in %U\n",
858 count, archive_obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000859 return files;
Just van Rossum52e14d62002-12-30 22:08:05 +0000860error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000861 fclose(fp);
862 Py_XDECREF(files);
Victor Stinner2460a432010-08-16 17:54:28 +0000863 Py_XDECREF(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000864 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000865}
866
867/* Return the zlib.decompress function object, or NULL if zlib couldn't
868 be imported. The function is cached when found, so subsequent calls
869 don't import zlib again. Returns a *borrowed* reference.
870 XXX This makes zlib.decompress immortal. */
871static PyObject *
872get_decompress_func(void)
873{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000874 static PyObject *decompress = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000876 if (decompress == NULL) {
877 PyObject *zlib;
878 static int importing_zlib = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +0000879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000880 if (importing_zlib != 0)
881 /* Someone has a zlib.py[co] in their Zip file;
882 let's avoid a stack overflow. */
883 return NULL;
884 importing_zlib = 1;
885 zlib = PyImport_ImportModuleNoBlock("zlib");
886 importing_zlib = 0;
887 if (zlib != NULL) {
888 decompress = PyObject_GetAttrString(zlib,
889 "decompress");
890 Py_DECREF(zlib);
891 }
892 else
893 PyErr_Clear();
894 if (Py_VerboseFlag)
895 PySys_WriteStderr("# zipimport: zlib %s\n",
896 zlib != NULL ? "available": "UNAVAILABLE");
897 }
898 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +0000899}
900
901/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
902 data as a new reference. */
903static PyObject *
Victor Stinner60fe8d92010-08-16 23:48:11 +0000904get_data(PyObject *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +0000905{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 PyObject *raw_data, *data = NULL, *decompress;
907 char *buf;
908 FILE *fp;
909 int err;
910 Py_ssize_t bytes_read = 0;
911 long l;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000912 PyObject *datapath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000913 long compress, data_size, file_size, file_offset, bytes_size;
914 long time, date, crc;
Just van Rossum52e14d62002-12-30 22:08:05 +0000915
Victor Stinner60fe8d92010-08-16 23:48:11 +0000916 if (!PyArg_ParseTuple(toc_entry, "Olllllll", &datapath, &compress,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000917 &data_size, &file_size, &file_offset, &time,
918 &date, &crc)) {
919 return NULL;
920 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000921
Victor Stinner60fe8d92010-08-16 23:48:11 +0000922 fp = _Py_fopen(archive, "rb");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000923 if (!fp) {
924 PyErr_Format(PyExc_IOError,
Victor Stinner60fe8d92010-08-16 23:48:11 +0000925 "zipimport: can not open file %U", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 return NULL;
927 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000928
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000929 /* Check to make sure the local file header is correct */
930 fseek(fp, file_offset, 0);
931 l = PyMarshal_ReadLongFromFile(fp);
932 if (l != 0x04034B50) {
933 /* Bad: Local File Header */
934 PyErr_Format(ZipImportError,
Victor Stinner60fe8d92010-08-16 23:48:11 +0000935 "bad local file header in %U",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000936 archive);
937 fclose(fp);
938 return NULL;
939 }
940 fseek(fp, file_offset + 26, 0);
941 l = 30 + PyMarshal_ReadShortFromFile(fp) +
942 PyMarshal_ReadShortFromFile(fp); /* local header size */
943 file_offset += l; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +0000944
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000945 bytes_size = compress == 0 ? data_size : data_size + 1;
946 if (bytes_size == 0)
947 bytes_size++;
948 raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
Just van Rossum52e14d62002-12-30 22:08:05 +0000949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000950 if (raw_data == NULL) {
951 fclose(fp);
952 return NULL;
953 }
954 buf = PyBytes_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +0000955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000956 err = fseek(fp, file_offset, 0);
957 if (err == 0)
958 bytes_read = fread(buf, 1, data_size, fp);
959 fclose(fp);
960 if (err || bytes_read != data_size) {
961 PyErr_SetString(PyExc_IOError,
962 "zipimport: can't read data");
963 Py_DECREF(raw_data);
964 return NULL;
965 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 if (compress != 0) {
968 buf[data_size] = 'Z'; /* saw this in zipfile.py */
969 data_size++;
970 }
971 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +0000972
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 if (compress == 0) { /* data is not compressed */
974 data = PyBytes_FromStringAndSize(buf, data_size);
975 Py_DECREF(raw_data);
976 return data;
977 }
978
979 /* Decompress with zlib */
980 decompress = get_decompress_func();
981 if (decompress == NULL) {
982 PyErr_SetString(ZipImportError,
983 "can't decompress data; "
984 "zlib not available");
985 goto error;
986 }
987 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Just van Rossum52e14d62002-12-30 22:08:05 +0000988error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 Py_DECREF(raw_data);
990 return data;
Just van Rossum52e14d62002-12-30 22:08:05 +0000991}
992
993/* Lenient date/time comparison function. The precision of the mtime
994 in the archive is lower than the mtime stored in a .pyc: we
995 must allow a difference of at most one second. */
996static int
997eq_mtime(time_t t1, time_t t2)
998{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 time_t d = t1 - t2;
1000 if (d < 0)
1001 d = -d;
1002 /* dostime only stores even seconds, so be lenient */
1003 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001004}
1005
1006/* Given the contents of a .py[co] file in a buffer, unmarshal the data
1007 and return the code object. Return None if it the magic word doesn't
1008 match (we do this instead of raising an exception as we fall back
1009 to .py if available and we don't want to mask other errors).
1010 Returns a new reference. */
1011static PyObject *
1012unmarshal_code(char *pathname, PyObject *data, time_t mtime)
1013{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 PyObject *code;
1015 char *buf = PyBytes_AsString(data);
1016 Py_ssize_t size = PyBytes_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001018 if (size <= 9) {
1019 PyErr_SetString(ZipImportError,
1020 "bad pyc data");
1021 return NULL;
1022 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001023
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024 if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
1025 if (Py_VerboseFlag)
1026 PySys_WriteStderr("# %s has bad magic\n",
1027 pathname);
1028 Py_INCREF(Py_None);
1029 return Py_None; /* signal caller to try alternative */
1030 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
1033 mtime)) {
1034 if (Py_VerboseFlag)
1035 PySys_WriteStderr("# %s has bad mtime\n",
1036 pathname);
1037 Py_INCREF(Py_None);
1038 return Py_None; /* signal caller to try alternative */
1039 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
1042 if (code == NULL)
1043 return NULL;
1044 if (!PyCode_Check(code)) {
1045 Py_DECREF(code);
1046 PyErr_Format(PyExc_TypeError,
1047 "compiled module %.200s is not a code object",
1048 pathname);
1049 return NULL;
1050 }
1051 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001052}
1053
1054/* Replace any occurances of "\r\n?" in the input string with "\n".
1055 This converts DOS and Mac line endings to Unix line endings.
1056 Also append a trailing "\n" to be compatible with
1057 PyParser_SimpleParseFile(). Returns a new reference. */
1058static PyObject *
1059normalize_line_endings(PyObject *source)
1060{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 char *buf, *q, *p = PyBytes_AsString(source);
1062 PyObject *fixed_source;
1063 int len = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +00001064
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 if (!p) {
1066 return PyBytes_FromStringAndSize("\n\0", 2);
1067 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 /* one char extra for trailing \n and one for terminating \0 */
1070 buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
1071 if (buf == NULL) {
1072 PyErr_SetString(PyExc_MemoryError,
1073 "zipimport: no memory to allocate "
1074 "source buffer");
1075 return NULL;
1076 }
1077 /* replace "\r\n?" by "\n" */
1078 for (q = buf; *p != '\0'; p++) {
1079 if (*p == '\r') {
1080 *q++ = '\n';
1081 if (*(p + 1) == '\n')
1082 p++;
1083 }
1084 else
1085 *q++ = *p;
1086 len++;
1087 }
1088 *q++ = '\n'; /* add trailing \n */
1089 *q = '\0';
1090 fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
1091 PyMem_Free(buf);
1092 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001093}
1094
1095/* Given a string buffer containing Python source code, compile it
1096 return and return a code object as a new reference. */
1097static PyObject *
1098compile_source(char *pathname, PyObject *source)
1099{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 PyObject *code, *fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 fixed_source = normalize_line_endings(source);
1103 if (fixed_source == NULL)
1104 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001106 code = Py_CompileString(PyBytes_AsString(fixed_source), pathname,
1107 Py_file_input);
1108 Py_DECREF(fixed_source);
1109 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001110}
1111
1112/* Convert the date/time values found in the Zip archive to a value
1113 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001114static time_t
1115parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001116{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001119 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes679db4a2008-01-18 09:56:22 +00001120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001121 stm.tm_sec = (dostime & 0x1f) * 2;
1122 stm.tm_min = (dostime >> 5) & 0x3f;
1123 stm.tm_hour = (dostime >> 11) & 0x1f;
1124 stm.tm_mday = dosdate & 0x1f;
1125 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1126 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1127 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001130}
1131
1132/* Given a path to a .pyc or .pyo file in the archive, return the
1133 modifictaion time of the matching .py file, or 0 if no source
1134 is available. */
1135static time_t
1136get_mtime_of_source(ZipImporter *self, char *path)
1137{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 PyObject *toc_entry;
1139 time_t mtime = 0;
1140 Py_ssize_t lastchar = strlen(path) - 1;
1141 char savechar = path[lastchar];
1142 path[lastchar] = '\0'; /* strip 'c' or 'o' from *.py[co] */
1143 toc_entry = PyDict_GetItemString(self->files, path);
1144 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1145 PyTuple_Size(toc_entry) == 8) {
1146 /* fetch the time stamp of the .py file for comparison
1147 with an embedded pyc time stamp */
1148 int time, date;
1149 time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
1150 date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
1151 mtime = parse_dostime(time, date);
1152 }
1153 path[lastchar] = savechar;
1154 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001155}
1156
1157/* Return the code object for the module named by 'fullname' from the
1158 Zip archive as a new reference. */
1159static PyObject *
1160get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001162{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001163 PyObject *data, *code;
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001164 PyObject *modpath;
Just van Rossum52e14d62002-12-30 22:08:05 +00001165
Victor Stinner60fe8d92010-08-16 23:48:11 +00001166 data = get_data(self->archive, toc_entry);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001167 if (data == NULL)
1168 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001169
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001170 modpath = PyUnicode_EncodeFSDefault(PyTuple_GetItem(toc_entry, 0));
Victor Stinner5a7913e2010-10-16 11:29:07 +00001171 if (modpath == NULL) {
1172 Py_DECREF(data);
1173 return NULL;
1174 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001175
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001176 if (isbytecode)
1177 code = unmarshal_code(PyBytes_AS_STRING(modpath), data, mtime);
1178 else
1179 code = compile_source(PyBytes_AS_STRING(modpath), data);
1180 Py_DECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001181 Py_DECREF(data);
1182 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001183}
1184
1185/* Get the code object assoiciated with the module specified by
1186 'fullname'. */
1187static PyObject *
1188get_module_code(ZipImporter *self, char *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +00001189 int *p_ispackage, PyObject **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001190{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001191 PyObject *toc_entry;
1192 char *subname, path[MAXPATHLEN + 1];
1193 int len;
1194 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +00001195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001196 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +00001197
Victor Stinner269aeb72010-10-18 20:40:59 +00001198 len = make_filename(self->prefix, subname, path, sizeof(path));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 if (len < 0)
1200 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001202 for (zso = zip_searchorder; *zso->suffix; zso++) {
1203 PyObject *code = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001205 strcpy(path + len, zso->suffix);
1206 if (Py_VerboseFlag > 1)
Victor Stinner353349c2010-10-18 11:40:40 +00001207 PySys_FormatStderr("# trying %U%c%s\n",
Victor Stinner72f767e2010-10-18 11:44:21 +00001208 self->archive, (int)SEP, path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 toc_entry = PyDict_GetItemString(self->files, path);
1210 if (toc_entry != NULL) {
1211 time_t mtime = 0;
1212 int ispackage = zso->type & IS_PACKAGE;
1213 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001215 if (isbytecode)
1216 mtime = get_mtime_of_source(self, path);
1217 if (p_ispackage != NULL)
1218 *p_ispackage = ispackage;
1219 code = get_code_from_data(self, ispackage,
1220 isbytecode, mtime,
1221 toc_entry);
1222 if (code == Py_None) {
1223 /* bad magic number or non-matching mtime
1224 in byte code, try next */
1225 Py_DECREF(code);
1226 continue;
1227 }
Victor Stinner08654e12010-10-18 12:09:02 +00001228 if (code != NULL && p_modpath != NULL) {
1229 *p_modpath = PyTuple_GetItem(toc_entry, 0);
1230 Py_INCREF(*p_modpath);
1231 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 return code;
1233 }
1234 }
1235 PyErr_Format(ZipImportError, "can't find module '%.200s'", fullname);
1236 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001237}
1238
1239
1240/* Module init */
1241
1242PyDoc_STRVAR(zipimport_doc,
1243"zipimport provides support for importing Python modules from Zip archives.\n\
1244\n\
1245This module exports three objects:\n\
1246- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001247- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001248 subclass of ImportError, so it can be caught as ImportError, too.\n\
1249- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1250 info dicts, as used in zipimporter._files.\n\
1251\n\
1252It is usually not needed to use the zipimport module explicitly; it is\n\
1253used by the builtin import mechanism for sys.path items that are paths\n\
1254to Zip archives.");
1255
Martin v. Löwis1a214512008-06-11 05:26:20 +00001256static struct PyModuleDef zipimportmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 PyModuleDef_HEAD_INIT,
1258 "zipimport",
1259 zipimport_doc,
1260 -1,
1261 NULL,
1262 NULL,
1263 NULL,
1264 NULL,
1265 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001266};
1267
Just van Rossum52e14d62002-12-30 22:08:05 +00001268PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001269PyInit_zipimport(void)
Just van Rossum52e14d62002-12-30 22:08:05 +00001270{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 if (PyType_Ready(&ZipImporter_Type) < 0)
1274 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001276 /* Correct directory separator */
1277 zip_searchorder[0].suffix[0] = SEP;
1278 zip_searchorder[1].suffix[0] = SEP;
1279 zip_searchorder[2].suffix[0] = SEP;
1280 if (Py_OptimizeFlag) {
1281 /* Reverse *.pyc and *.pyo */
1282 struct st_zip_searchorder tmp;
1283 tmp = zip_searchorder[0];
1284 zip_searchorder[0] = zip_searchorder[1];
1285 zip_searchorder[1] = tmp;
1286 tmp = zip_searchorder[3];
1287 zip_searchorder[3] = zip_searchorder[4];
1288 zip_searchorder[4] = tmp;
1289 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 mod = PyModule_Create(&zipimportmodule);
1292 if (mod == NULL)
1293 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1296 PyExc_ImportError, NULL);
1297 if (ZipImportError == NULL)
1298 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 Py_INCREF(ZipImportError);
1301 if (PyModule_AddObject(mod, "ZipImportError",
1302 ZipImportError) < 0)
1303 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 Py_INCREF(&ZipImporter_Type);
1306 if (PyModule_AddObject(mod, "zipimporter",
1307 (PyObject *)&ZipImporter_Type) < 0)
1308 return NULL;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 zip_directory_cache = PyDict_New();
1311 if (zip_directory_cache == NULL)
1312 return NULL;
1313 Py_INCREF(zip_directory_cache);
1314 if (PyModule_AddObject(mod, "_zip_directory_cache",
1315 zip_directory_cache) < 0)
1316 return NULL;
1317 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001318}