#include "Python.h"
#include "structmember.h"
#include "osdefs.h"
#include "marshal.h"
#include <time.h>


#define IS_SOURCE   0x0
#define IS_BYTECODE 0x1
#define IS_PACKAGE  0x2

struct st_zip_searchorder {
	char suffix[14];
	int type;
};

/* zip_searchorder defines how we search for a module in the Zip
   archive: we first search for a package __init__, then for
   non-package .pyc, .pyo and .py entries. The .pyc and .pyo entries
   are swapped by initzipimport() if we run in optimized mode. Also,
   '/' is replaced by SEP there. */
static struct st_zip_searchorder zip_searchorder[] = {
	{"/__init__.pyc", IS_PACKAGE | IS_BYTECODE},
	{"/__init__.pyo", IS_PACKAGE | IS_BYTECODE},
	{"/__init__.py", IS_PACKAGE | IS_SOURCE},
	{".pyc", IS_BYTECODE},
	{".pyo", IS_BYTECODE},
	{".py", IS_SOURCE},
	{"", 0}
};

/* zipimporter object definition and support */

typedef struct _zipimporter ZipImporter;

struct _zipimporter {
	PyObject_HEAD
	PyObject *archive;  /* pathname of the Zip archive */
	PyObject *prefix;   /* file prefix: "a/sub/directory/" */
	PyObject *files;    /* dict with file info {path: toc_entry} */
};

static PyObject *ZipImportError;
static PyObject *zip_directory_cache = NULL;

/* forward decls */
static PyObject *read_directory(char *archive);
static PyObject *get_data(char *archive, PyObject *toc_entry);
static PyObject *get_module_code(ZipImporter *self, char *fullname,
				 int *p_ispackage, char **p_modpath);


#define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)


/* zipimporter.__init__
   Split the "subdirectory" from the Zip archive path, lookup a matching
   entry in sys.path_importer_cache, fetch the file directory from there
   if found, or else read it from the archive. */
static int
zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
{
	char *path, *p, *prefix, buf[MAXPATHLEN+2];
	size_t len;

	if (!_PyArg_NoKeywords("zipimporter()", kwds))
		return -1;

	if (!PyArg_ParseTuple(args, "s:zipimporter",
			      &path))
		return -1;

	len = strlen(path);
	if (len == 0) {
		PyErr_SetString(ZipImportError, "archive path is empty");
		return -1;
	}
	if (len >= MAXPATHLEN) {
		PyErr_SetString(ZipImportError,
				"archive path too long");
		return -1;
	}
	strcpy(buf, path);

#ifdef ALTSEP
	for (p = buf; *p; p++) {
		if (*p == ALTSEP)
			*p = SEP;
	}
#endif

	path = NULL;
	prefix = NULL;
	for (;;) {
		struct stat statbuf;
		int rv;

		rv = stat(buf, &statbuf);
		if (rv == 0) {
			/* it exists */
			if (S_ISREG(statbuf.st_mode))
				/* it's a file */
				path = buf;
			break;
		}
		/* back up one path element */
		p = strrchr(buf, SEP);
		if (prefix != NULL)
			*prefix = SEP;
		if (p == NULL)
			break;
		*p = '\0';
		prefix = p;
	}
	if (path != NULL) {
		PyObject *files;
		files = PyDict_GetItemString(zip_directory_cache, path);
		if (files == NULL) {
			files = read_directory(buf);
			if (files == NULL)
				return -1;
			if (PyDict_SetItemString(zip_directory_cache, path,
						 files) != 0)
				return -1;
		}
		else
			Py_INCREF(files);
		self->files = files;
	}
	else {
		PyErr_SetString(ZipImportError, "not a Zip file");
		return -1;
	}

	if (prefix == NULL)
		prefix = "";
	else {
		prefix++;
		len = strlen(prefix);
		if (prefix[len-1] != SEP) {
			/* add trailing SEP */
			prefix[len] = SEP;
			prefix[len + 1] = '\0';
		}
	}

	self->archive = PyUnicode_FromString(buf);
	if (self->archive == NULL)
		return -1;

	self->prefix = PyUnicode_FromString(prefix);
	if (self->prefix == NULL)
		return -1;

	return 0;
}

/* GC support. */
static int
zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
{
	ZipImporter *self = (ZipImporter *)obj;
	Py_VISIT(self->files);
	return 0;
}

static void
zipimporter_dealloc(ZipImporter *self)
{
	PyObject_GC_UnTrack(self);
	Py_XDECREF(self->archive);
	Py_XDECREF(self->prefix);
	Py_XDECREF(self->files);
	Py_TYPE(self)->tp_free((PyObject *)self);
}

static PyObject *
zipimporter_repr(ZipImporter *self)
{
	char *archive = "???";
	char *prefix = "";

	if (self->archive != NULL && PyUnicode_Check(self->archive))
		archive = PyUnicode_AsString(self->archive);
	if (self->prefix != NULL && PyUnicode_Check(self->prefix))
		prefix = PyUnicode_AsString(self->prefix);
	if (prefix != NULL && *prefix)
		return PyUnicode_FromFormat("<zipimporter object \"%.300s%c%.150s\">",
		                            archive, SEP, prefix);
	else
		return PyUnicode_FromFormat("<zipimporter object \"%.300s\">",
		                            archive);
}

/* return fullname.split(".")[-1] */
static char *
get_subname(char *fullname)
{
	char *subname = strrchr(fullname, '.');
	if (subname == NULL)
		subname = fullname;
	else
		subname++;
	return subname;
}

/* Given a (sub)modulename, write the potential file path in the
   archive (without extension) to the path buffer. Return the
   length of the resulting string. */
static int
make_filename(char *prefix, char *name, char *path)
{
	size_t len;
	char *p;

	len = strlen(prefix);

	/* self.prefix + name [+ SEP + "__init__"] + ".py[co]" */
	if (len + strlen(name) + 13 >= MAXPATHLEN) {
		PyErr_SetString(ZipImportError, "path too long");
		return -1;
	}

	strcpy(path, prefix);
	strcpy(path + len, name);
	for (p = path + len; *p; p++) {
		if (*p == '.')
			*p = SEP;
	}
	len += strlen(name);
	assert(len < INT_MAX);
	return (int)len;
}

enum zi_module_info {
	MI_ERROR,
	MI_NOT_FOUND,
	MI_MODULE,
	MI_PACKAGE
};

/* Return some information about a module. */
static enum zi_module_info
get_module_info(ZipImporter *self, char *fullname)
{
	char *subname, path[MAXPATHLEN + 1];
	int len;
	struct st_zip_searchorder *zso;

	subname = get_subname(fullname);

	len = make_filename(PyUnicode_AsString(self->prefix), subname, path);
	if (len < 0)
		return MI_ERROR;

	for (zso = zip_searchorder; *zso->suffix; zso++) {
		strcpy(path + len, zso->suffix);
		if (PyDict_GetItemString(self->files, path) != NULL) {
			if (zso->type & IS_PACKAGE)
				return MI_PACKAGE;
			else
				return MI_MODULE;
		}
	}
	return MI_NOT_FOUND;
}

/* Check whether we can satisfy the import of the module named by
   'fullname'. Return self if we can, None if we can't. */
static PyObject *
zipimporter_find_module(PyObject *obj, PyObject *args)
{
	ZipImporter *self = (ZipImporter *)obj;
	PyObject *path = NULL;
	char *fullname;
	enum zi_module_info mi;

	if (!PyArg_ParseTuple(args, "s|O:zipimporter.find_module",
			      &fullname, &path))
		return NULL;

	mi = get_module_info(self, fullname);
	if (mi == MI_ERROR)
		return NULL;
	if (mi == MI_NOT_FOUND) {
		Py_INCREF(Py_None);
		return Py_None;
	}
	Py_INCREF(self);
	return (PyObject *)self;
}

/* Load and return the module named by 'fullname'. */
static PyObject *
zipimporter_load_module(PyObject *obj, PyObject *args)
{
	ZipImporter *self = (ZipImporter *)obj;
	PyObject *code, *mod, *dict;
	char *fullname, *modpath;
	int ispackage;

	if (!PyArg_ParseTuple(args, "s:zipimporter.load_module",
			      &fullname))
		return NULL;

	code = get_module_code(self, fullname, &ispackage, &modpath);
	if (code == NULL)
		return NULL;

	mod = PyImport_AddModule(fullname);
	if (mod == NULL) {
		Py_DECREF(code);
		return NULL;
	}
	dict = PyModule_GetDict(mod);

	/* mod.__loader__ = self */
	if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
		goto error;

	if (ispackage) {
		/* add __path__ to the module *before* the code gets
		   executed */
		PyObject *pkgpath, *fullpath;
		char *prefix = PyUnicode_AsString(self->prefix);
		char *subname = get_subname(fullname);
		int err;

		fullpath = PyUnicode_FromFormat("%s%c%s%s",
					PyUnicode_AsString(self->archive),
					SEP,
					*prefix ? prefix : "",
					subname);
		if (fullpath == NULL)
			goto error;

		pkgpath = Py_BuildValue("[O]", fullpath);
		Py_DECREF(fullpath);
		if (pkgpath == NULL)
			goto error;
		err = PyDict_SetItemString(dict, "__path__", pkgpath);
		Py_DECREF(pkgpath);
		if (err != 0)
			goto error;
	}
	mod = PyImport_ExecCodeModuleEx(fullname, code, modpath);
	Py_DECREF(code);
	if (Py_VerboseFlag)
		PySys_WriteStderr("import %s # loaded from Zip %s\n",
				  fullname, modpath);
	return mod;
error:
	Py_DECREF(code);
	Py_DECREF(mod);
	return NULL;
}

/* Return a bool signifying whether the module is a package or not. */
static PyObject *
zipimporter_is_package(PyObject *obj, PyObject *args)
{
	ZipImporter *self = (ZipImporter *)obj;
	char *fullname;
	enum zi_module_info mi;

	if (!PyArg_ParseTuple(args, "s:zipimporter.is_package",
			      &fullname))
		return NULL;

	mi = get_module_info(self, fullname);
	if (mi == MI_ERROR)
		return NULL;
	if (mi == MI_NOT_FOUND) {
		PyErr_Format(ZipImportError, "can't find module '%.200s'",
			     fullname);
		return NULL;
	}
	return PyBool_FromLong(mi == MI_PACKAGE);
}

static PyObject *
zipimporter_get_data(PyObject *obj, PyObject *args)
{
	ZipImporter *self = (ZipImporter *)obj;
	char *path;
#ifdef ALTSEP
	char *p, buf[MAXPATHLEN + 1];
#endif
	PyObject *toc_entry;
	Py_ssize_t len;

	if (!PyArg_ParseTuple(args, "s:zipimporter.get_data", &path))
		return NULL;

#ifdef ALTSEP
	if (strlen(path) >= MAXPATHLEN) {
		PyErr_SetString(ZipImportError, "path too long");
		return NULL;
	}
	strcpy(buf, path);
	for (p = buf; *p; p++) {
		if (*p == ALTSEP)
			*p = SEP;
	}
	path = buf;
#endif
	len = PyUnicode_GET_SIZE(self->archive);
	if ((size_t)len < strlen(path) &&
	    strncmp(path, PyUnicode_AsString(self->archive), len) == 0 &&
	    path[len] == SEP) {
		path = path + len + 1;
	}

	toc_entry = PyDict_GetItemString(self->files, path);
	if (toc_entry == NULL) {
		PyErr_SetFromErrnoWithFilename(PyExc_IOError, path);
		return NULL;
	}
	return get_data(PyUnicode_AsString(self->archive), toc_entry);
}

static PyObject *
zipimporter_get_code(PyObject *obj, PyObject *args)
{
	ZipImporter *self = (ZipImporter *)obj;
	char *fullname;

	if (!PyArg_ParseTuple(args, "s:zipimporter.get_code", &fullname))
		return NULL;

	return get_module_code(self, fullname, NULL, NULL);
}

static PyObject *
zipimporter_get_source(PyObject *obj, PyObject *args)
{
	ZipImporter *self = (ZipImporter *)obj;
	PyObject *toc_entry;
	char *fullname, *subname, path[MAXPATHLEN+1];
	int len;
	enum zi_module_info mi;

	if (!PyArg_ParseTuple(args, "s:zipimporter.get_source", &fullname))
		return NULL;

	mi = get_module_info(self, fullname);
	if (mi == MI_ERROR)
		return NULL;
	if (mi == MI_NOT_FOUND) {
		PyErr_Format(ZipImportError, "can't find module '%.200s'",
			     fullname);
		return NULL;
	}
	subname = get_subname(fullname);

	len = make_filename(PyUnicode_AsString(self->prefix), subname, path);
	if (len < 0)
		return NULL;

	if (mi == MI_PACKAGE) {
		path[len] = SEP;
		strcpy(path + len + 1, "__init__.py");
	}
	else
		strcpy(path + len, ".py");

	toc_entry = PyDict_GetItemString(self->files, path);
	if (toc_entry != NULL) {
		PyObject *bytes = get_data(PyUnicode_AsString(self->archive), toc_entry);
		PyObject *res = PyUnicode_FromString(PyBytes_AsString(bytes));
		Py_XDECREF(bytes);
		return res;
	}

	/* we have the module, but no source */
	Py_INCREF(Py_None);
	return Py_None;
}

PyDoc_STRVAR(doc_find_module,
"find_module(fullname, path=None) -> self or None.\n\
\n\
Search for a module specified by 'fullname'. 'fullname' must be the\n\
fully qualified (dotted) module name. It returns the zipimporter\n\
instance itself if the module was found, or None if it wasn't.\n\
The optional 'path' argument is ignored -- it's there for compatibility\n\
with the importer protocol.");

PyDoc_STRVAR(doc_load_module,
"load_module(fullname) -> module.\n\
\n\
Load the module specified by 'fullname'. 'fullname' must be the\n\
fully qualified (dotted) module name. It returns the imported\n\
module, or raises ZipImportError if it wasn't found.");

PyDoc_STRVAR(doc_get_data,
"get_data(pathname) -> string with file data.\n\
\n\
Return the data associated with 'pathname'. Raise IOError if\n\
the file wasn't found.");

PyDoc_STRVAR(doc_is_package,
"is_package(fullname) -> bool.\n\
\n\
Return True if the module specified by fullname is a package.\n\
Raise ZipImportError is the module couldn't be found.");

PyDoc_STRVAR(doc_get_code,
"get_code(fullname) -> code object.\n\
\n\
Return the code object for the specified module. Raise ZipImportError\n\
is the module couldn't be found.");

PyDoc_STRVAR(doc_get_source,
"get_source(fullname) -> source string.\n\
\n\
Return the source code for the specified module. Raise ZipImportError\n\
is the module couldn't be found, return None if the archive does\n\
contain the module, but has no source for it.");

static PyMethodDef zipimporter_methods[] = {
	{"find_module", zipimporter_find_module, METH_VARARGS,
	 doc_find_module},
	{"load_module", zipimporter_load_module, METH_VARARGS,
	 doc_load_module},
	{"get_data", zipimporter_get_data, METH_VARARGS,
	 doc_get_data},
	{"get_code", zipimporter_get_code, METH_VARARGS,
	 doc_get_code},
	{"get_source", zipimporter_get_source, METH_VARARGS,
	 doc_get_source},
	{"is_package", zipimporter_is_package, METH_VARARGS,
	 doc_is_package},
	{NULL,		NULL}	/* sentinel */
};

static PyMemberDef zipimporter_members[] = {
	{"archive",  T_OBJECT, offsetof(ZipImporter, archive),  READONLY},
	{"prefix",   T_OBJECT, offsetof(ZipImporter, prefix),   READONLY},
	{"_files",   T_OBJECT, offsetof(ZipImporter, files),    READONLY},
	{NULL}
};

PyDoc_STRVAR(zipimporter_doc,
"zipimporter(archivepath) -> zipimporter object\n\
\n\
Create a new zipimporter instance. 'archivepath' must be a path to\n\
a zipfile. ZipImportError is raised if 'archivepath' doesn't point to\n\
a valid Zip archive.");

#define DEFERRED_ADDRESS(ADDR) 0

static PyTypeObject ZipImporter_Type = {
	PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
	"zipimport.zipimporter",
	sizeof(ZipImporter),
	0,					/* tp_itemsize */
	(destructor)zipimporter_dealloc,	/* tp_dealloc */
	0,					/* tp_print */
	0,					/* tp_getattr */
	0,					/* tp_setattr */
	0,					/* tp_compare */
	(reprfunc)zipimporter_repr,		/* tp_repr */
	0,					/* tp_as_number */
	0,					/* tp_as_sequence */
	0,					/* tp_as_mapping */
	0,					/* tp_hash */
	0,					/* tp_call */
	0,					/* tp_str */
	PyObject_GenericGetAttr,		/* tp_getattro */
	0,					/* tp_setattro */
	0,					/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
		Py_TPFLAGS_HAVE_GC,		/* tp_flags */
	zipimporter_doc,			/* tp_doc */
	zipimporter_traverse,			/* tp_traverse */
	0,					/* tp_clear */
	0,					/* tp_richcompare */
	0,					/* tp_weaklistoffset */
	0,					/* tp_iter */
	0,					/* tp_iternext */
	zipimporter_methods,			/* tp_methods */
	zipimporter_members,			/* tp_members */
	0,					/* tp_getset */
	0,					/* tp_base */
	0,					/* tp_dict */
	0,					/* tp_descr_get */
	0,					/* tp_descr_set */
	0,					/* tp_dictoffset */
	(initproc)zipimporter_init,		/* tp_init */
	PyType_GenericAlloc,			/* tp_alloc */
	PyType_GenericNew,			/* tp_new */
	PyObject_GC_Del,			/* tp_free */
};


/* implementation */

/* Given a buffer, return the long that is represented by the first
   4 bytes, encoded as little endian. This partially reimplements
   marshal.c:r_long() */
static long
get_long(unsigned char *buf) {
	long x;
	x =  buf[0];
	x |= (long)buf[1] <<  8;
	x |= (long)buf[2] << 16;
	x |= (long)buf[3] << 24;
#if SIZEOF_LONG > 4
	/* Sign extension for 64-bit machines */
	x |= -(x & 0x80000000L);
#endif
	return x;
}

/*
   read_directory(archive) -> files dict (new reference)

   Given a path to a Zip archive, build a dict, mapping file names
   (local to the archive, using SEP as a separator) to toc entries.

   A toc_entry is a tuple:

       (__file__,      # value to use for __file__, available for all files
        compress,      # compression kind; 0 for uncompressed
        data_size,     # size of compressed data on disk
        file_size,     # size of decompressed data
        file_offset,   # offset of file header from start of archive
        time,          # mod time of file (in dos format)
        date,          # mod data of file (in dos format)
        crc,           # crc checksum of the data
       )

   Directories can be recognized by the trailing SEP in the name,
   data_size and file_offset are 0.
*/
static PyObject *
read_directory(char *archive)
{
	PyObject *files = NULL;
	FILE *fp;
	long compress, crc, data_size, file_size, file_offset, date, time;
	long header_offset, name_size, header_size, header_position;
	long i, l, count;
	size_t length;
	char path[MAXPATHLEN + 5];
	char name[MAXPATHLEN + 5];
	char *p, endof_central_dir[22];
	long arc_offset; /* offset from beginning of file to start of zip-archive */

	if (strlen(archive) > MAXPATHLEN) {
		PyErr_SetString(PyExc_OverflowError,
				"Zip path name is too long");
		return NULL;
	}
	strcpy(path, archive);

	fp = fopen(archive, "rb");
	if (fp == NULL) {
		PyErr_Format(ZipImportError, "can't open Zip file: "
			     "'%.200s'", archive);
		return NULL;
	}
	fseek(fp, -22, SEEK_END);
	header_position = ftell(fp);
	if (fread(endof_central_dir, 1, 22, fp) != 22) {
		fclose(fp);
		PyErr_Format(ZipImportError, "can't read Zip file: "
			     "'%.200s'", archive);
		return NULL;
	}
	if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
		/* Bad: End of Central Dir signature */
		fclose(fp);
		PyErr_Format(ZipImportError, "not a Zip file: "
			     "'%.200s'", archive);
		return NULL;
	}

	header_size = get_long((unsigned char *)endof_central_dir + 12);
	header_offset = get_long((unsigned char *)endof_central_dir + 16);
	arc_offset = header_position - header_offset - header_size;
	header_offset += arc_offset;

	files = PyDict_New();
	if (files == NULL)
		goto error;

	length = (long)strlen(path);
	path[length] = SEP;

	/* Start of Central Directory */
	count = 0;
	for (;;) {
		PyObject *t;
		int err;

		fseek(fp, header_offset, 0);  /* Start of file header */
		l = PyMarshal_ReadLongFromFile(fp);
		if (l != 0x02014B50)
			break;	/* Bad: Central Dir File Header */
		fseek(fp, header_offset + 10, 0);
		compress = PyMarshal_ReadShortFromFile(fp);
		time = PyMarshal_ReadShortFromFile(fp);
		date = PyMarshal_ReadShortFromFile(fp);
		crc = PyMarshal_ReadLongFromFile(fp);
		data_size = PyMarshal_ReadLongFromFile(fp);
		file_size = PyMarshal_ReadLongFromFile(fp);
		name_size = PyMarshal_ReadShortFromFile(fp);
		header_size = 46 + name_size +
		   PyMarshal_ReadShortFromFile(fp) +
		   PyMarshal_ReadShortFromFile(fp);
		fseek(fp, header_offset + 42, 0);
		file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
		if (name_size > MAXPATHLEN)
			name_size = MAXPATHLEN;

		p = name;
		for (i = 0; i < name_size; i++) {
			*p = (char)getc(fp);
			if (*p == '/')
				*p = SEP;
			p++;
		}
		*p = 0;	/* Add terminating null byte */
		header_offset += header_size;

		strncpy(path + length + 1, name, MAXPATHLEN - length - 1);

		t = Py_BuildValue("siiiiiii", path, compress, data_size,
				  file_size, file_offset, time, date, crc);
		if (t == NULL)
			goto error;
		err = PyDict_SetItemString(files, name, t);
		Py_DECREF(t);
		if (err != 0)
			goto error;
		count++;
	}
	fclose(fp);
	if (Py_VerboseFlag)
		PySys_WriteStderr("# zipimport: found %ld names in %s\n",
			count, archive);
	return files;
error:
	fclose(fp);
	Py_XDECREF(files);
	return NULL;
}

/* Return the zlib.decompress function object, or NULL if zlib couldn't
   be imported. The function is cached when found, so subsequent calls
   don't import zlib again. Returns a *borrowed* reference.
   XXX This makes zlib.decompress immortal. */
static PyObject *
get_decompress_func(void)
{
	static PyObject *decompress = NULL;

	if (decompress == NULL) {
		PyObject *zlib;
		static int importing_zlib = 0;

		if (importing_zlib != 0)
			/* Someone has a zlib.py[co] in their Zip file;
			   let's avoid a stack overflow. */
			return NULL;
		importing_zlib = 1;
		zlib = PyImport_ImportModuleNoBlock("zlib");
		importing_zlib = 0;
		if (zlib != NULL) {
			decompress = PyObject_GetAttrString(zlib,
							    "decompress");
			Py_DECREF(zlib);
		}
		else
			PyErr_Clear();
		if (Py_VerboseFlag)
			PySys_WriteStderr("# zipimport: zlib %s\n",
				zlib != NULL ? "available": "UNAVAILABLE");
	}
	return decompress;
}

/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
   data as a new reference. */
static PyObject *
get_data(char *archive, PyObject *toc_entry)
{
	PyObject *raw_data, *data = NULL, *decompress;
	char *buf;
	FILE *fp;
	int err;
	Py_ssize_t bytes_read = 0;
	long l;
	char *datapath;
	long compress, data_size, file_size, file_offset, bytes_size;
	long time, date, crc;

	if (!PyArg_ParseTuple(toc_entry, "slllllll", &datapath, &compress,
			      &data_size, &file_size, &file_offset, &time,
			      &date, &crc)) {
		return NULL;
	}

	fp = fopen(archive, "rb");
	if (!fp) {
		PyErr_Format(PyExc_IOError,
		   "zipimport: can not open file %s", archive);
		return NULL;
	}

	/* Check to make sure the local file header is correct */
	fseek(fp, file_offset, 0);
	l = PyMarshal_ReadLongFromFile(fp);
	if (l != 0x04034B50) {
		/* Bad: Local File Header */
		PyErr_Format(ZipImportError,
			     "bad local file header in %s",
			     archive);
		fclose(fp);
		return NULL;
	}
	fseek(fp, file_offset + 26, 0);
	l = 30 + PyMarshal_ReadShortFromFile(fp) +
	    PyMarshal_ReadShortFromFile(fp);	/* local header size */
	file_offset += l;	/* Start of file data */

	bytes_size = compress == 0 ? data_size : data_size + 1;
	if (bytes_size == 0)
		bytes_size++;
	raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
					     
	if (raw_data == NULL) {
		fclose(fp);
		return NULL;
	}
	buf = PyBytes_AsString(raw_data);

	err = fseek(fp, file_offset, 0);
	if (err == 0)
		bytes_read = fread(buf, 1, data_size, fp);
	fclose(fp);
	if (err || bytes_read != data_size) {
		PyErr_SetString(PyExc_IOError,
				"zipimport: can't read data");
		Py_DECREF(raw_data);
		return NULL;
	}

	if (compress != 0) {
		buf[data_size] = 'Z';  /* saw this in zipfile.py */
		data_size++;
	}
	buf[data_size] = '\0';

	if (compress == 0) {  /* data is not compressed */
		data = PyBytes_FromStringAndSize(buf, data_size);
		Py_DECREF(raw_data);
		return data;
	}

	/* Decompress with zlib */
	decompress = get_decompress_func();
	if (decompress == NULL) {
		PyErr_SetString(ZipImportError,
				"can't decompress data; "
				"zlib not available");
		goto error;
	}
	data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
error:
	Py_DECREF(raw_data);
	return data;
}

/* Lenient date/time comparison function. The precision of the mtime
   in the archive is lower than the mtime stored in a .pyc: we
   must allow a difference of at most one second. */
static int
eq_mtime(time_t t1, time_t t2)
{
	time_t d = t1 - t2;
	if (d < 0)
		d = -d;
	/* dostime only stores even seconds, so be lenient */
	return d <= 1;
}

/* Given the contents of a .py[co] file in a buffer, unmarshal the data
   and return the code object. Return None if it the magic word doesn't
   match (we do this instead of raising an exception as we fall back
   to .py if available and we don't want to mask other errors).
   Returns a new reference. */
static PyObject *
unmarshal_code(char *pathname, PyObject *data, time_t mtime)
{
	PyObject *code;
	char *buf = PyBytes_AsString(data);
	Py_ssize_t size = PyBytes_Size(data);

	if (size <= 9) {
		PyErr_SetString(ZipImportError,
				"bad pyc data");
		return NULL;
	}

	if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
		if (Py_VerboseFlag)
			PySys_WriteStderr("# %s has bad magic\n",
					  pathname);
		Py_INCREF(Py_None);
		return Py_None;  /* signal caller to try alternative */
	}

	if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
				    mtime)) {
		if (Py_VerboseFlag)
			PySys_WriteStderr("# %s has bad mtime\n",
					  pathname);
		Py_INCREF(Py_None);
		return Py_None;  /* signal caller to try alternative */
	}

	code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
	if (code == NULL)
		return NULL;
	if (!PyCode_Check(code)) {
		Py_DECREF(code);
		PyErr_Format(PyExc_TypeError,
		     "compiled module %.200s is not a code object",
		     pathname);
		return NULL;
	}
	return code;
}

/* Replace any occurances of "\r\n?" in the input string with "\n".
   This converts DOS and Mac line endings to Unix line endings.
   Also append a trailing "\n" to be compatible with
   PyParser_SimpleParseFile(). Returns a new reference. */
static PyObject *
normalize_line_endings(PyObject *source)
{
	char *buf, *q, *p = PyBytes_AsString(source);
	PyObject *fixed_source;
	int len = 0;

	if (!p) {
		return PyBytes_FromStringAndSize("\n\0", 2);
	}

	/* one char extra for trailing \n and one for terminating \0 */
	buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
	if (buf == NULL) {
		PyErr_SetString(PyExc_MemoryError,
				"zipimport: no memory to allocate "
				"source buffer");
		return NULL;
	}
	/* replace "\r\n?" by "\n" */
	for (q = buf; *p != '\0'; p++) {
		if (*p == '\r') {
			*q++ = '\n';
			if (*(p + 1) == '\n')
				p++;
		}
		else
			*q++ = *p;
		len++;
	}
	*q++ = '\n';  /* add trailing \n */
	*q = '\0';
	fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
	PyMem_Free(buf);
	return fixed_source;
}

/* Given a string buffer containing Python source code, compile it
   return and return a code object as a new reference. */
static PyObject *
compile_source(char *pathname, PyObject *source)
{
	PyObject *code, *fixed_source;

	fixed_source = normalize_line_endings(source);
	if (fixed_source == NULL)
		return NULL;

	code = Py_CompileString(PyBytes_AsString(fixed_source), pathname,
				Py_file_input);
	Py_DECREF(fixed_source);
	return code;
}

/* Convert the date/time values found in the Zip archive to a value
   that's compatible with the time stamp stored in .pyc files. */
static time_t
parse_dostime(int dostime, int dosdate)
{
	struct tm stm;

	memset((void *) &stm, '\0', sizeof(stm));

	stm.tm_sec   =  (dostime        & 0x1f) * 2;
	stm.tm_min   =  (dostime >> 5)  & 0x3f;
	stm.tm_hour  =  (dostime >> 11) & 0x1f;
	stm.tm_mday  =   dosdate        & 0x1f;
	stm.tm_mon   = ((dosdate >> 5)  & 0x0f) - 1;
	stm.tm_year  = ((dosdate >> 9)  & 0x7f) + 80;
	stm.tm_isdst =   -1; /* wday/yday is ignored */

	return mktime(&stm);
}

/* Given a path to a .pyc or .pyo file in the archive, return the
   modifictaion time of the matching .py file, or 0 if no source
   is available. */
static time_t
get_mtime_of_source(ZipImporter *self, char *path)
{
	PyObject *toc_entry;
	time_t mtime = 0;
	Py_ssize_t lastchar = strlen(path) - 1;
	char savechar = path[lastchar];
	path[lastchar] = '\0';  /* strip 'c' or 'o' from *.py[co] */
	toc_entry = PyDict_GetItemString(self->files, path);
	if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
	    PyTuple_Size(toc_entry) == 8) {
		/* fetch the time stamp of the .py file for comparison
		   with an embedded pyc time stamp */
		int time, date;
		time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
		date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
		mtime = parse_dostime(time, date);
	}
	path[lastchar] = savechar;
	return mtime;
}

/* Return the code object for the module named by 'fullname' from the
   Zip archive as a new reference. */
static PyObject *
get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
		   time_t mtime, PyObject *toc_entry)
{
	PyObject *data, *code;
	char *modpath;
	char *archive = PyUnicode_AsString(self->archive);

	if (archive == NULL)
		return NULL;

	data = get_data(archive, toc_entry);
	if (data == NULL)
		return NULL;

	modpath = PyUnicode_AsString(PyTuple_GetItem(toc_entry, 0));

	if (isbytecode) {
		code = unmarshal_code(modpath, data, mtime);
	}
	else {
		code = compile_source(modpath, data);
	}
	Py_DECREF(data);
	return code;
}

/* Get the code object assoiciated with the module specified by
   'fullname'. */
static PyObject *
get_module_code(ZipImporter *self, char *fullname,
		int *p_ispackage, char **p_modpath)
{
	PyObject *toc_entry;
	char *subname, path[MAXPATHLEN + 1];
	int len;
	struct st_zip_searchorder *zso;

	subname = get_subname(fullname);

	len = make_filename(PyUnicode_AsString(self->prefix), subname, path);
	if (len < 0)
		return NULL;

	for (zso = zip_searchorder; *zso->suffix; zso++) {
		PyObject *code = NULL;

		strcpy(path + len, zso->suffix);
		if (Py_VerboseFlag > 1)
			PySys_WriteStderr("# trying %s%c%s\n",
					  PyUnicode_AsString(self->archive),
					  SEP, path);
		toc_entry = PyDict_GetItemString(self->files, path);
		if (toc_entry != NULL) {
			time_t mtime = 0;
			int ispackage = zso->type & IS_PACKAGE;
			int isbytecode = zso->type & IS_BYTECODE;

			if (isbytecode)
				mtime = get_mtime_of_source(self, path);
			if (p_ispackage != NULL)
				*p_ispackage = ispackage;
			code = get_code_from_data(self, ispackage,
						  isbytecode, mtime,
						  toc_entry);
			if (code == Py_None) {
				/* bad magic number or non-matching mtime
				   in byte code, try next */
				Py_DECREF(code);
				continue;
			}
			if (code != NULL && p_modpath != NULL)
				*p_modpath = PyUnicode_AsString(
					PyTuple_GetItem(toc_entry, 0));
			return code;
		}
	}
	PyErr_Format(ZipImportError, "can't find module '%.200s'", fullname);
	return NULL;
}


/* Module init */

PyDoc_STRVAR(zipimport_doc,
"zipimport provides support for importing Python modules from Zip archives.\n\
\n\
This module exports three objects:\n\
- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
- ZipImportError: exception raised by zipimporter objects. It's a\n\
  subclass of ImportError, so it can be caught as ImportError, too.\n\
- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
  info dicts, as used in zipimporter._files.\n\
\n\
It is usually not needed to use the zipimport module explicitly; it is\n\
used by the builtin import mechanism for sys.path items that are paths\n\
to Zip archives.");

PyMODINIT_FUNC
initzipimport(void)
{
	PyObject *mod;

	if (PyType_Ready(&ZipImporter_Type) < 0)
		return;

	/* Correct directory separator */
	zip_searchorder[0].suffix[0] = SEP;
	zip_searchorder[1].suffix[0] = SEP;
	zip_searchorder[2].suffix[0] = SEP;
	if (Py_OptimizeFlag) {
		/* Reverse *.pyc and *.pyo */
		struct st_zip_searchorder tmp;
		tmp = zip_searchorder[0];
		zip_searchorder[0] = zip_searchorder[1];
		zip_searchorder[1] = tmp;
		tmp = zip_searchorder[3];
		zip_searchorder[3] = zip_searchorder[4];
		zip_searchorder[4] = tmp;
	}

	mod = Py_InitModule4("zipimport", NULL, zipimport_doc,
			     NULL, PYTHON_API_VERSION);
	if (mod == NULL)
		return;

	ZipImportError = PyErr_NewException("zipimport.ZipImportError",
					    PyExc_ImportError, NULL);
	if (ZipImportError == NULL)
		return;

	Py_INCREF(ZipImportError);
	if (PyModule_AddObject(mod, "ZipImportError",
			       ZipImportError) < 0)
		return;

	Py_INCREF(&ZipImporter_Type);
	if (PyModule_AddObject(mod, "zipimporter",
			       (PyObject *)&ZipImporter_Type) < 0)
		return;

	zip_directory_cache = PyDict_New();
	if (zip_directory_cache == NULL)
		return;
	Py_INCREF(zip_directory_cache);
	if (PyModule_AddObject(mod, "_zip_directory_cache",
			       zip_directory_cache) < 0)
		return;
}
