/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
/*
*/
#include "zip_util.h"
#include "java.h"
/*
* Initialize zip file support. Return 0 if successful otherwise -1
* if could not be initialized.
*/
{
extern void out_of_memory(void);
if (inited)
return 0;
return 0;
}
/*
* Reads len bytes of data into buf. Returns 0 if all bytes could be read,
* otherwise returns -1.
*/
{
while (len > 0)
{
if (n <= 0)
return -1;
bp += n;
len -= n;
}
return 0;
}
/*
* Allocates a new zip file object for the specified file name.
* Returns the zip file object or NULL if not enough memory.
*/
{
if (zip == 0)
return 0;
{
return 0;
}
return zip;
}
/*
* Frees the specified zip file object.
*/
{
int i;
/* First free any cached jzentry */
zipFreeEntry(zip,0);
{
{
}
}
{
{
}
}
}
/*
* Searches for end of central directory (END) header. The contents of
* the END header will be read and placed in endbuf. Returns the file
* position of the END header, otherwise returns 0 if the END header
* was not found or -1 if an error occurred.
*/
{
/* Get the length of the zip file */
if (len == -1)
return -1;
/*
* Search backwards ENDHDR bytes at a time from end of file stopping
* when the END header has been found. We need to make sure that we
* handle the case where the signature may straddle a record boundary.
* Also, the END header must be located within the last 64k bytes of
* the file since that is the maximum comment length.
*/
{
unsigned char *bp;
/* Number of bytes to check in next block */
/* Shift previous block */
/* Update position and read next block */
return -1;
return -1;
/* Now scan the block for END header signature */
{
{
/* Check for possible END header */
{
/* Found END header */
return -1;
if (clen > 0)
{
return -1;
{
return -1;
}
}
return endpos;
}
}
}
}
return 0; /* END header not found */
}
/*
* Returns a hash code value for the specified string.
*/
static unsigned int
hash(const char *s)
{
int h = 0;
while (*s != '\0')
h = 31*h + *s++;
return h;
}
/*
* Returns true if the specified entry's name begins with the string
* "META-INF/" irrespect of case.
*/
static int
{
while (*s != '\0')
{
if (*s++ != (char)toupper(*t++))
return 0;
}
return 1;
}
static void
{
int i;
{
}
{
{
break;
}
}
/* If necessary, grow the metanames array */
{
}
}
static void
{
}
/*
* Reads zip file central directory. Returns the file position of first
* CEN header, otherwise returns 0 if central directory not found or -1
* if an error occurred. If zip->msg != NULL then the error was a zip
* format error and zip->msg has the error text.
*/
static
{
unsigned short *table;
/* Clear previous zip error */
/* Get position of END header */
if (endpos == 0)
return 0; /* END header not found */
if (endpos == -1)
return -1; /* system error */
/* Get position and length of central directory */
{
return -1;
}
/*
* Get position of first local file (LOC) header, taking into
* account that there maybe a stub prefixed to the zip file.
*/
{
return -1;
}
/* Get total number of central directory entries */
{
return -1;
}
if (total > ZIP_MAXENTRIES)
{
return -1;
}
/* Seek to first CEN header */
return -1;
/* Allocate temporary buffer for central directory bytes */
if (cenbuf == 0)
return -1;
/* Read central directory */
{
return -1;
}
/* Allocate array for item descriptors */
if (entries == 0)
{
return -1;
}
/* Allocate hash table */
if (table == 0)
{
return -1;
}
for (i = 0; i < tablelen; i++)
table[i] = ZIP_ENDCHAIN;
/* Now read the zip file entries */
{
/* Check CEN header looks OK */
{
break;
}
/* Verify CEN header signature */
{
break;
}
/* Check if entry is encrypted */
{
break;
}
{
break;
}
/* Get header field lengths */
{
break;
}
/* Set compressed size to zero if entry uncompressed */
/*
* Copy the name into a temporary location so we can null
* terminate it (sigh) as various functions expect this.
*/
{
/* grow temp buffer */
do
}
/*
* Record the LOC offset and the name hash in our hash cell.
*/
/*
* if the entry is metdata add it to our metadata names
*/
if (isMetaName(name))
/*
* If there is a comment add it to our comments array.
*/
if (clen > 0)
{
}
/*
* Finally we can add the entry to the hash table
*/
}
/* Free up temporary buffers */
/* Check for error */
{
/* Central directory was invalid, so free up entries and return */
return -1;
}
return cenpos;
}
/*
* Opens a zip file with the specified mode. Returns the jzfile object
* or NULL if an error occurred. If a zip error occurred then *msg will
* or NULL if an error occurred. If a zip error occurred then *zerror will be
* set to the error number. Otherwise, *zerror will be set to Z_OK.
*/
jzfile *
{
if (initializeZip())
return NULL;
/* Clear zip error message */
if (zerror != 0)
{
{
break;
}
}
if (zip == 0)
{
/* If not found then allocate a new zip object */
if (zip == 0)
return 0;
{
if (zerror != 0)
*zerror = Z_MEM_ERROR;
return 0;
}
if (len == -1)
{
if (zerror != 0)
*zerror = Z_STREAM_ERROR;
return 0;
}
{
if (zerror != 0)
*zerror = Z_STREAM_ERROR;
return 0;
}
{
/* An error occurred while trying to read the zip file */
if (zerror != 0)
*zerror = Z_STREAM_ERROR;
return 0;
}
}
return zip;
}
/*
* Opens a zip file for reading. Returns the jzfile object or NULL
* if an error occurred. If a zip error occurred then *zerror will be
* set to the error number. Otherwise, *zerror will be set to Z_OK.
*/
jzfile *
{
#ifdef WIN32
#else
#endif
}
/*
* Closes the specified zip file object.
*/
{
{
/* Still more references so just return */
return;
}
/* No other references so close the file and remove from list */
{
}
else
{
{
{
break;
}
}
}
return;
}
/*
* Read a LOC corresponding to a given hash cell and
* create a corrresponding jzentry entry descriptor
* The ZIP lock should be held here.
*/
static jzentry *
{
unsigned char *locbuf;
/* Seek to beginning of LOC header */
{
return NULL;
}
/* Try to read in the LOC header including the name and extra data */
{
return NULL;
}
/* Verify signature */
{
return NULL;
}
/* verify lengths */
/* If extra in CEN, use it instead of extra in LOC */
{
/* Seek to begin of CEN header extra field */
{
return NULL;
}
/* Try to read in the CEN Extra */
{
return NULL;
}
}
{
/* Store the extra data size in the first two bytes */
}
/*
* Process any comment (this should be very rare)
*/
{
}
/*
* We'd like to initialize the sizes from the LOC, but unfortunately
* some ZIPs, including the jar command, don't put them there.
* So we have to store them in the szcell.
*/
/* Fill in the rest of the entry fields from the LOC */
return ze;
}
/*
* Free the given jzentry.
* In fact we maintain a one-entry cache of the most recently used
* jzentry for each zip. This optimizes a common access pattern.
*/
void
{
{
/* Free the previously cached jzentry */
}
}
/*
* Returns the zip entry corresponding to the specified name, or
* NULL if not found.
*/
{
/* Check the cached entry first */
{
/* Cache hit! Remove and return the cached entry. */
return ze;
}
ze = 0;
/*
* Search down the target hash chain for a cell who's
* 32 bit hash matches the hashed name.
*/
while (idx != ZIP_ENDCHAIN)
{
{
/*
* OK, we've found a ZIP entry whose 32 bit hashcode
* matches the name we're looking for. Try to read its
* entry information from the LOC.
* If the LOC name matches the name we're looking,
* we're done.
* If the names don't (which should be very rare) we
* keep searching.
*/
break;
if (ze != 0)
ze = 0;
}
}
return ze;
}
/*
* Returns the n'th (starting at zero) zip file entry, or NULL if the
* specified index was out of range.
*/
jzentry *
{
return 0;
return result;
}
/*
* Reads bytes from the specified zip entry. Returns the
* number of bytes read, or -1 if an error occurred. If err->msg != 0
* then a zip error occurred and err->msg contains the error text.
*/
{
/* Clear previous zip error */
/* Check specified position */
{
return -1;
}
/* Check specified length */
if (len <= 0)
return 0;
/* Seek to beginning of entry data and read bytes */
if (n != -1)
return n;
}
/* The maximum size of a stack-allocated buffer.
*/
/*
* This function is used by the runtime system to load compressed entries
* so that it can be dynamically loaded by the runtime if the zip library
* is found.
*/
static jboolean
{
*msg = 0; /* Reset error message */
if (count == 0)
{
*msg = "inflateFully: entry not compressed";
return JNI_FALSE;
}
{
return JNI_FALSE;
}
while (count > 0)
{
if (n <= 0)
{
if (n == 0)
*msg = "inflateFully: Unexpected end of file";
inflateEnd(&strm);
return JNI_FALSE;
}
pos += n;
count -= n;
do
{
{
{
*msg = "inflateFully: Unexpected end of stream";
inflateEnd(&strm);
return JNI_FALSE;
}
}
{
inflateEnd(&strm);
return JNI_FALSE;
}
}
inflateEnd(&strm);
return JNI_TRUE;
}
jzentry *
{
if (entry)
{
}
return entry;
}
/*
* Reads a zip file entry into the specified byte array into the specified
* file.
*/
{
char *msg;
int fd;
#ifdef WIN32
#else
#endif
{
msg = "zipReadEntry: cannot open output file";
return JNI_FALSE;
}
{
/* Entry is stored */
while (count > 0)
{
jint n;
{
return JNI_FALSE;
}
pos += n;
count -= n;
}
}
else
{
/* Entry is compressed */
if (!ok)
{
return JNI_FALSE;
}
}
return JNI_TRUE;
}