#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);
	Py_TYPE(self)->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 = {
	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;
	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;

	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 = 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;
}
