/* src/vm/zip.c - ZIP file handling for bootstrap classloader
- Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
- C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
- E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Contact: cacao@cacaojvm.org
-
- Authors: Christian Thalinger
-
- Changes:
-
- $Id: zip.c 4357 2006-01-22 23:33:38Z twisti $
-
*/
#include "config.h"
#include <assert.h>
+#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <zlib.h>
#include "vm/types.h"
+#include "vm/descriptor.h" /* needed to prevent circular dependency */
+#include "toolbox/hashtable.h"
+
#include "mm/memory.h"
+
#include "vm/global.h"
-#include "vm/hashtable.h"
-#include "vm/suck.h"
+#include "vm/suck.hpp"
#include "vm/utf8.h"
+#include "vm/vm.hpp"
#include "vm/zip.h"
#define SIGNATURE_LENGTH 4
-
-/* Local file header ***********************************************************
-
- local file header signature 4 bytes (0x04034b50)
- version needed to extract 2 bytes
- general purpose bit flag 2 bytes
- compression method 2 bytes
- last mod file time 2 bytes
- last mod file date 2 bytes
- crc-32 4 bytes
- compressed size 4 bytes
- uncompressed size 4 bytes
- file name length 2 bytes
- extra field length 2 bytes
-
- file name (variable size)
- extra field (variable size)
-
-*******************************************************************************/
-
-#define LFH_HEADER_SIZE 30
-
-#define LFH_SIGNATURE 0x04034b50
-#define LFH_FILE_NAME_LENGTH 26
-#define LFH_EXTRA_FIELD_LENGTH 28
-
-typedef struct lfh lfh;
-
-struct lfh {
- u2 compressionmethod;
- u4 compressedsize;
- u4 uncompressedsize;
- u2 filenamelength;
- u2 extrafieldlength;
-};
-
-
/* Central directory structure *************************************************
[file header 1]
filename = (const char *) (p + CDSFH_FILENAME);
classext = filename + cdsfh.filenamelength - strlen(".class");
- if (strncmp(classext, ".class", strlen(".class")) == 0)
- u = utf_new(filename, cdsfh.filenamelength - strlen(".class"));
- else
- u = utf_new(filename, cdsfh.filenamelength);
+ /* skip directory entries */
+
+ if (filename[cdsfh.filenamelength - 1] != '/') {
+ if (strncmp(classext, ".class", strlen(".class")) == 0)
+ u = utf_new(filename, cdsfh.filenamelength - strlen(".class"));
+ else
+ u = utf_new(filename, cdsfh.filenamelength);
- /* insert class into hashtable */
+ /* insert class into hashtable */
- htzfe = NEW(hashtable_zipfile_entry);
+ htzfe = NEW(hashtable_zipfile_entry);
- htzfe->filename = u;
- htzfe->compressionmethod = cdsfh.compressionmethod;
- htzfe->compressedsize = cdsfh.compressedsize;
- htzfe->uncompressedsize = cdsfh.uncompressedsize;
- htzfe->data = filep + cdsfh.relativeoffset;
+ htzfe->filename = u;
+ htzfe->compressionmethod = cdsfh.compressionmethod;
+ htzfe->compressedsize = cdsfh.compressedsize;
+ htzfe->uncompressedsize = cdsfh.uncompressedsize;
+ htzfe->data = filep + cdsfh.relativeoffset;
- /* get hashtable slot */
+ /* get hashtable slot */
- key = utf_hashkey(u->text, u->blength);
- slot = key & (ht->size - 1);
+ key = utf_hashkey(u->text, u->blength);
+ slot = key & (ht->size - 1);
- /* insert into external chain */
+ /* insert into external chain */
- htzfe->hashlink = ht->ptr[slot];
+ htzfe->hashlink = ht->ptr[slot];
- /* insert hashtable zipfile entry */
+ /* insert hashtable zipfile entry */
- ht->ptr[slot] = htzfe;
- ht->entries++;
+ ht->ptr[slot] = htzfe;
+ ht->entries++;
+ }
/* move to next central directory structure file header */
/* zip_find ********************************************************************
- XXX
+ Search for the given filename in the classpath entries of a zip file.
+
+ NOTE: The '.class' extension is stripped when reading a zip file, so if
+ you want to find a .class file, you must search for its name _without_
+ the '.class' extension.
+ XXX I dont like that, it makes foo and foo.class ambiguous. -Edwin
+
+ IN:
+ lce..........the classpath entries for the zip file
+ u............the filename to look for
+
+ RETURN VALUE:
+ hashtable_zipfile_entry * of the entry if found, or
+ NULL if not found
*******************************************************************************/
/* try to find the class in the current archive */
- if ((htzfe = zip_find(lce, c->name)) == NULL)
+ htzfe = zip_find(lce, c->name);
+
+ if (htzfe == NULL)
return NULL;
/* read stuff from local file header */
/* initialize this inflate run */
if (inflateInit2(&zs, -MAX_WBITS) != Z_OK)
- assert(0);
+ vm_abort("zip_get: inflateInit2 failed: %s", strerror(errno));
/* decompress the file into buffer */
err = inflate(&zs, Z_SYNC_FLUSH);
if ((err != Z_STREAM_END) && (err != Z_OK))
- assert(0);
+ vm_abort("zip_get: inflate failed: %s", strerror(errno));
/* finish this inflate run */
if (inflateEnd(&zs) != Z_OK)
- assert(0);
+ vm_abort("zip_get: inflateEnd failed: %s", strerror(errno));
break;
case 0:
break;
default:
- assert(0);
+ vm_abort("zip_get: unknown compression method %d",
+ htzfe->compressionmethod);
}
/* allocate classbuffer */
cb = NEW(classbuffer);
- cb->class = c;
+ cb->clazz = c;
cb->size = htzfe->uncompressedsize;
cb->data = outdata;
cb->pos = outdata;
* c-basic-offset: 4
* tab-width: 4
* End:
+ * vim:noexpandtab:sw=4:ts=4:
*/