1 /*
   2  * Copyright 1995-2009 Sun Microsystems, Inc.  All Rights Reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Sun designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Sun in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 
  26 /*
  27  * Prototypes for zip file support
  28  */
  29 
  30 #ifndef _ZIP_H_
  31 #define _ZIP_H_
  32 
  33 /*
  34  * Header signatures
  35  */
  36 #define LOCSIG 0x04034b50L          /* "PK\003\004" */
  37 #define EXTSIG 0x08074b50L          /* "PK\007\008" */
  38 #define CENSIG 0x02014b50L          /* "PK\001\002" */
  39 #define ENDSIG 0x06054b50L          /* "PK\005\006" */
  40 
  41 /*
  42  * Header sizes including signatures
  43  */
  44 #ifdef USE_MMAP
  45 #define SIGSIZ  4
  46 #endif
  47 #define LOCHDR 30
  48 #define EXTHDR 16
  49 #define CENHDR 46
  50 #define ENDHDR 22
  51 
  52 /*
  53  * Header field access macros
  54  */
  55 #define CH(b, n) (((unsigned char *)(b))[n])
  56 #define SH(b, n) (CH(b, n) | (CH(b, n+1) << 8))
  57 #define LG(b, n) (SH(b, n) | (SH(b, n+2) << 16))
  58 #define GETSIG(b) LG(b, 0)
  59 
  60 /*
  61  * Macros for getting local file (LOC) header fields
  62  */
  63 #define LOCVER(b) SH(b, 4)          /* version needed to extract */
  64 #define LOCFLG(b) SH(b, 6)          /* general purpose bit flags */
  65 #define LOCHOW(b) SH(b, 8)          /* compression method */
  66 #define LOCTIM(b) LG(b, 10)         /* modification time */
  67 #define LOCCRC(b) LG(b, 14)         /* crc of uncompressed data */
  68 #define LOCSIZ(b) LG(b, 18)         /* compressed data size */
  69 #define LOCLEN(b) LG(b, 22)         /* uncompressed data size */
  70 #define LOCNAM(b) SH(b, 26)         /* filename length */
  71 #define LOCEXT(b) SH(b, 28)         /* extra field length */
  72 
  73 /*
  74  * Macros for getting extra local (EXT) header fields
  75  */
  76 #define EXTCRC(b) LG(b, 4)          /* crc of uncompressed data */
  77 #define EXTSIZ(b) LG(b, 8)          /* compressed size */
  78 #define EXTLEN(b) LG(b, 12)         /* uncompressed size */
  79 
  80 /*
  81  * Macros for getting central directory header (CEN) fields
  82  */
  83 #define CENVEM(b) SH(b, 4)          /* version made by */
  84 #define CENVER(b) SH(b, 6)          /* version needed to extract */
  85 #define CENFLG(b) SH(b, 8)          /* general purpose bit flags */
  86 #define CENHOW(b) SH(b, 10)         /* compression method */
  87 #define CENTIM(b) LG(b, 12)         /* modification time */
  88 #define CENCRC(b) LG(b, 16)         /* crc of uncompressed data */
  89 #define CENSIZ(b) LG(b, 20)         /* compressed size */
  90 #define CENLEN(b) LG(b, 24)         /* uncompressed size */
  91 #define CENNAM(b) SH(b, 28)         /* length of filename */
  92 #define CENEXT(b) SH(b, 30)         /* length of extra field */
  93 #define CENCOM(b) SH(b, 32)         /* file comment length */
  94 #define CENDSK(b) SH(b, 34)         /* disk number start */
  95 #define CENATT(b) SH(b, 36)         /* internal file attributes */
  96 #define CENATX(b) LG(b, 38)         /* external file attributes */
  97 #define CENOFF(b) LG(b, 42)         /* offset of local header */
  98 
  99 /*
 100  * Macros for getting end of central directory header (END) fields
 101  */
 102 #define ENDSUB(b) SH(b, 8)          /* number of entries on this disk */
 103 #define ENDTOT(b) SH(b, 10)         /* total number of entries */
 104 #define ENDSIZ(b) LG(b, 12)         /* central directory size */
 105 #define ENDOFF(b) LG(b, 16)         /* central directory offset */
 106 #define ENDCOM(b) SH(b, 20)         /* size of zip file comment */
 107 
 108 /*
 109  * Supported compression methods
 110  */
 111 #define STORED      0
 112 #define DEFLATED    8
 113 
 114 /*
 115  * Support for reading ZIP/JAR files. Some things worth noting:
 116  *
 117  * - Zip file entries larger than 2**32 bytes are not supported.
 118  * - jzentry time and crc fields are signed even though they really
 119  *   represent unsigned quantities.
 120  * - If csize is zero then the entry is uncompressed.
 121  * - If extra != 0 then the first two bytes are the length of the extra
 122  *   data in intel byte order.
 123  * - If pos <= 0 then it is the position of entry LOC header.
 124  *   If pos > 0 then it is the position of entry data.
 125  *   pos should not be accessed directly, but only by ZIP_GetEntryDataOffset.
 126  */
 127 
 128 typedef struct jzentry {  /* Zip file entry */
 129     char *name;           /* entry name */
 130     jlong time;           /* modification time */
 131     jlong size;           /* size of uncompressed data */
 132     jlong csize;          /* size of compressed data (zero if uncompressed) */
 133     jint crc;             /* crc of uncompressed data */
 134     char *comment;        /* optional zip file comment */
 135     jbyte *extra;         /* optional extra data */
 136     jlong pos;            /* position of LOC header or entry data */
 137 } jzentry;
 138 
 139 /*
 140  * In-memory hash table cell.
 141  * In a typical system we have a *lot* of these, as we have one for
 142  * every entry in every active JAR.
 143  * Note that in order to save space we don't keep the name in memory,
 144  * but merely remember a 32 bit hash.
 145  */
 146 typedef struct jzcell {
 147     unsigned int hash;    /* 32 bit hashcode on name */
 148     unsigned int cenpos;  /* Offset of central directory file header */
 149     unsigned int next;    /* hash chain: index into jzfile->entries */
 150 } jzcell;
 151 
 152 typedef struct cencache {
 153     char *data;           /* A cached page of CEN headers */
 154     jlong pos;            /* file offset of data */
 155 } cencache;
 156 
 157 /*
 158  * Use ZFILE to represent access to a file in a platform-indepenent
 159  * fashion.
 160  */
 161 #ifdef WIN32
 162 #define ZFILE jlong
 163 #else
 164 #define ZFILE int
 165 #endif
 166 
 167 /*
 168  * Descriptor for a ZIP file.
 169  */
 170 typedef struct jzfile {   /* Zip file */
 171     char *name;           /* zip file name */
 172     jint refs;            /* number of active references */
 173     jlong len;            /* length (in bytes) of zip file */
 174 #ifdef USE_MMAP
 175     unsigned char *maddr; /* beginning address of the CEN & ENDHDR */
 176     jlong mlen;           /* length (in bytes) mmaped */
 177     jlong offset;         /* offset of the mmapped region from the
 178                              start of the file. */
 179 #else
 180     cencache cencache;    /* CEN header cache */
 181 #endif
 182     ZFILE zfd;            /* open file descriptor */
 183     void *lock;           /* read lock */
 184     char *comment;        /* zip file comment */
 185     char *msg;            /* zip error message */
 186     jzcell *entries;      /* array of hash cells */
 187     jint total;           /* total number of entries */
 188     jint *table;          /* Hash chain heads: indexes into entries */
 189     jint tablelen;        /* number of hash heads */
 190     struct jzfile *next;  /* next zip file in search list */
 191     jzentry *cache;       /* we cache the most recently freed jzentry */
 192     /* Information on metadata names in META-INF directory */
 193     char **metanames;     /* array of meta names (may have null names) */
 194     jint metacurrent;     /* the next empty slot in metanames array */
 195     jint metacount;       /* number of slots in metanames array */
 196     jlong lastModified;   /* last modified time */
 197     jlong locpos;         /* position of first LOC header (usually 0) */
 198 } jzfile;
 199 
 200 /*
 201  * Index representing end of hash chain
 202  */
 203 #define ZIP_ENDCHAIN ((jint)-1)
 204 
 205 jzentry * JNICALL
 206 ZIP_FindEntry(jzfile *zip, char *name, jint *sizeP, jint *nameLenP);
 207 
 208 jboolean JNICALL
 209 ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entrynm);
 210 
 211 jzentry * JNICALL
 212 ZIP_GetNextEntry(jzfile *zip, jint n);
 213 
 214 jzfile * JNICALL
 215 ZIP_Open(const char *name, char **pmsg);
 216 
 217 jzfile *
 218 ZIP_Open_Generic(const char *name, char **pmsg, int mode, jlong lastModified);
 219 
 220 jzfile *
 221 ZIP_Get_From_Cache(const char *name, char **pmsg, jlong lastModified);
 222 
 223 jzfile *
 224 ZIP_Put_In_Cache(const char *name, ZFILE zfd, char **pmsg, jlong lastModified);
 225 
 226 void JNICALL
 227 ZIP_Close(jzfile *zip);
 228 
 229 jzentry * ZIP_GetEntry(jzfile *zip, char *name, jint ulen);
 230 void ZIP_Lock(jzfile *zip);
 231 void ZIP_Unlock(jzfile *zip);
 232 jint ZIP_Read(jzfile *zip, jzentry *entry, jlong pos, void *buf, jint len);
 233 void ZIP_FreeEntry(jzfile *zip, jzentry *ze);
 234 jlong ZIP_GetEntryDataOffset(jzfile *zip, jzentry *entry);
 235 
 236 #endif /* !_ZIP_H_ */