#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 (;;) {
#ifndef RISCOS
		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;
		}
#else
		if (object_exists(buf)) {
			/* it exists */
			if (isfile(buf))
				/* it's a file */
				path = buf;
			break;
		}
#endif
		/* 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 = PyString_FromString(buf);
	if (self->archive == NULL)
		return -1;

	self->prefix = PyString_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);
	self->ob_type->tp_free((PyObject *)self);
}

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

	if (self->archive != NULL && PyString_Check(self->archive))
		archive = PyString_AsString(self->archive);
	if (self->prefix != NULL && PyString_Check(self->prefix))
		prefix = PyString_AsString(self->prefix);
	if (prefix != NULL && *prefix)
		PyOS_snprintf(buf, sizeof(buf),
			      "<zipimporter object \"%.300s%c%.150s\">",
			      archive, SEP, prefix);
	else
		PyOS_snprintf(buf, sizeof(buf),
			      "<zipimporter object \"%.300s\">",
			      archive);
	return PyString_FromString(buf);
}

/* 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(PyString_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 = PyString_AsString(self->prefix);
		char *subname = get_subname(fullname);
		int err;

		fullpath = PyString_FromFormat("%s%c%s%s",
					PyString_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 = PyString_Size(self->archive);
	if ((size_t)len < strlen(path) &&
	    strncmp(path, PyString_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(PyString_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(PyString_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)
		return get_data(PyString_AsString(self->archive), toc_entry);

	/* 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 = {
	PyObject_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_ImportModule("zlib");	/* import 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;
	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 */

	raw_data = PyString_FromStringAndSize((char *)NULL, compress == 0 ?
					      data_size : data_size + 1);
	if (raw_data == NULL) {
		fclose(fp);
		return NULL;
	}
	buf = PyString_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 */
		return raw_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 = PyString_AsString(data);
	Py_ssize_t size = PyString_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 = PyString_AsString(source);
	PyObject *fixed_source;

	if (!p)
		return NULL;

	/* one char extra for trailing \n and one for terminating \0 */
	buf = (char *)PyMem_Malloc(PyString_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;
	}
	*q++ = '\n';  /* add trailing \n */
	*q = '\0';
	fixed_source = PyString_FromString(buf);
	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(PyString_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;

	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 = PyInt_AsLong(PyTuple_GetItem(toc_entry, 5));
		date = PyInt_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 = PyString_AsString(self->archive);

	if (archive == NULL)
		return NULL;

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

	modpath = PyString_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(PyString_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",
					  PyString_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 = PyString_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;
}
