From 9a9dc451ef4b1b31bf2c67fd69604b4a0b91d834 Mon Sep 17 00:00:00 2001 From: wiidev Date: Sun, 4 Apr 2021 19:00:02 +0100 Subject: [PATCH] Fix zip file extraction --- Makefile | 11 +- portlibs/include/zconf.h | 201 +++- portlibs/include/zip/ioapi.h | 75 -- portlibs/include/zip/unzip.h | 354 ------ portlibs/include/zip/zip.h | 235 ---- portlibs/include/zlib.h | 343 ++++-- portlibs/lib/libz.a | Bin 106638 -> 106226 bytes portlibs/lib/libzip.a | Bin 31312 -> 0 bytes source/ZipFile.h | 3 +- source/homebrewboot/HomebrewBrowser.cpp | 2 +- source/utils/crypt.h | 132 +++ source/utils/ioapi.c | 129 +++ source/utils/ioapi.h | 70 ++ source/utils/minizip/miniunz.c | 139 +-- source/utils/minizip/miniunz.h | 8 +- source/utils/unzip.c | 1409 +++++++++++++++++++++++ source/utils/unzip.h | 320 +++++ 17 files changed, 2532 insertions(+), 899 deletions(-) delete mode 100644 portlibs/include/zip/ioapi.h delete mode 100644 portlibs/include/zip/unzip.h delete mode 100644 portlibs/include/zip/zip.h delete mode 100644 portlibs/lib/libzip.a create mode 100644 source/utils/crypt.h create mode 100644 source/utils/ioapi.c create mode 100644 source/utils/ioapi.h create mode 100644 source/utils/unzip.c create mode 100644 source/utils/unzip.h diff --git a/Makefile b/Makefile index 4e98dd15..e461e6c7 100644 --- a/Makefile +++ b/Makefile @@ -56,17 +56,10 @@ DATA := data \ data/binary INCLUDES := source -#--------------------------------------------------------------------------------- -# default IOS used when booting -#--------------------------------------------------------------------------------- -ifndef $(IOS) -IOS = 58 -endif - #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -CFLAGS = -g -ggdb -O3 -Wall -Wno-multichar -Wno-unused-parameter -Wextra $(MACHDEP) $(INCLUDE) -D_GNU_SOURCE -DBUILD_IOS=$(IOS) +CFLAGS = -g -ggdb -O3 -Wall -Wno-multichar -Wno-unused-parameter -Wextra $(MACHDEP) $(INCLUDE) -D_GNU_SOURCE CXXFLAGS = $(CFLAGS) LDFLAGS = -g -ggdb $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80B00000,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size @@ -79,7 +72,7 @@ endif # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- LIBS := -lwolfssl -lcustomfat -lcustomntfs -lcustomext2fs -lvorbisidec -logg \ - -lmad -lfreetype -lgd -ljpeg -lpng -lzip -lm -lz -lwiiuse -lwiidrc \ + -lmad -lfreetype -lgd -ljpeg -lpng -lm -lz -lwiiuse -lwiidrc \ -lbte -lasnd -logc -lruntimeiospatch #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing diff --git a/portlibs/include/zconf.h b/portlibs/include/zconf.h index b2343874..996fff29 100644 --- a/portlibs/include/zconf.h +++ b/portlibs/include/zconf.h @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2010 Jean-loup Gailly. + * Copyright (C) 1995-2013 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -15,11 +15,13 @@ * this permanently in zconf.h using "./configure --zprefix". */ #ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET /* all linked symbols */ # define _dist_code z__dist_code # define _length_code z__length_code # define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits # define _tr_flush_block z__tr_flush_block # define _tr_init z__tr_init # define _tr_stored_block z__tr_stored_block @@ -27,9 +29,11 @@ # define adler32 z_adler32 # define adler32_combine z_adler32_combine # define adler32_combine64 z_adler32_combine64 -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif # define crc32 z_crc32 # define crc32_combine z_crc32_combine # define crc32_combine64 z_crc32_combine64 @@ -40,44 +44,53 @@ # define deflateInit2_ z_deflateInit2_ # define deflateInit_ z_deflateInit_ # define deflateParams z_deflateParams +# define deflatePending z_deflatePending # define deflatePrime z_deflatePrime # define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep # define deflateSetDictionary z_deflateSetDictionary # define deflateSetHeader z_deflateSetHeader # define deflateTune z_deflateTune # define deflate_copyright z_deflate_copyright # define get_crc_table z_get_crc_table -# define gz_error z_gz_error -# define gz_intmax z_gz_intmax -# define gz_strwinerror z_gz_strwinerror -# define gzbuffer z_gzbuffer -# define gzclearerr z_gzclearerr -# define gzclose z_gzclose -# define gzclose_r z_gzclose_r -# define gzclose_w z_gzclose_w -# define gzdirect z_gzdirect -# define gzdopen z_gzdopen -# define gzeof z_gzeof -# define gzerror z_gzerror -# define gzflush z_gzflush -# define gzgetc z_gzgetc -# define gzgets z_gzgets -# define gzoffset z_gzoffset -# define gzoffset64 z_gzoffset64 -# define gzopen z_gzopen -# define gzopen64 z_gzopen64 -# define gzprintf z_gzprintf -# define gzputc z_gzputc -# define gzputs z_gzputs -# define gzread z_gzread -# define gzrewind z_gzrewind -# define gzseek z_gzseek -# define gzseek64 z_gzseek64 -# define gzsetparams z_gzsetparams -# define gztell z_gztell -# define gztell64 z_gztell64 -# define gzungetc z_gzungetc -# define gzwrite z_gzwrite +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzvprintf z_gzvprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# endif # define inflate z_inflate # define inflateBack z_inflateBack # define inflateBackEnd z_inflateBackEnd @@ -92,16 +105,22 @@ # define inflateReset z_inflateReset # define inflateReset2 z_inflateReset2 # define inflateSetDictionary z_inflateSetDictionary +# define inflateGetDictionary z_inflateGetDictionary # define inflateSync z_inflateSync # define inflateSyncPoint z_inflateSyncPoint # define inflateUndermine z_inflateUndermine +# define inflateResetKeep z_inflateResetKeep # define inflate_copyright z_inflate_copyright # define inflate_fast z_inflate_fast # define inflate_table z_inflate_table -# define uncompress z_uncompress +# ifndef Z_SOLO +# define uncompress z_uncompress +# endif # define zError z_zError -# define zcalloc z_zcalloc -# define zcfree z_zcfree +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif # define zlibCompileFlags z_zlibCompileFlags # define zlibVersion z_zlibVersion @@ -111,7 +130,9 @@ # define alloc_func z_alloc_func # define charf z_charf # define free_func z_free_func -# define gzFile z_gzFile +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif # define gz_header z_gz_header # define gz_headerp z_gz_headerp # define in_func z_in_func @@ -197,6 +218,12 @@ # endif #endif +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + /* Some Mac compilers merge all .h files incorrectly: */ #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) # define NO_DUMMY_DECL @@ -243,6 +270,14 @@ # endif #endif +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(args) () +# endif +#endif + /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have @@ -356,12 +391,47 @@ typedef uLong FAR uLongf; typedef Byte *voidp; #endif +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + #if 1 /* was set to #if 1 by ./configure */ # define Z_HAVE_UNISTD_H #endif +#if 1 /* was set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + #ifdef STDC -# include /* for off_t */ +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include /* for va_list */ +# endif +#endif + +#ifdef _WIN32 +# ifndef Z_SOLO +# include /* for wchar_t */ +# endif #endif /* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and @@ -370,21 +440,38 @@ typedef uLong FAR uLongf; * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as * equivalently requesting no 64-bit operations */ -#if -_LARGEFILE64_SOURCE - -1 == 1 +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 # undef _LARGEFILE64_SOURCE #endif -#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) -# include /* for SEEK_* and off_t */ -# ifdef VMS -# include /* for off_t */ -# endif -# ifndef z_off_t -# define z_off_t off_t +#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) +# define Z_HAVE_UNISTD_H +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif # endif #endif -#ifndef SEEK_SET +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) # define SEEK_SET 0 /* Seek from beginning of file. */ # define SEEK_CUR 1 /* Seek from current position. */ # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ @@ -394,18 +481,14 @@ typedef uLong FAR uLongf; # define z_off_t long #endif -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +#if !defined(_WIN32) && defined(Z_LARGE64) # define z_off64_t off64_t #else -# define z_off64_t z_off_t -#endif - -#if defined(__OS400__) -# define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf +# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif #endif /* MVS linker does not support external names larger than 8 bytes */ diff --git a/portlibs/include/zip/ioapi.h b/portlibs/include/zip/ioapi.h deleted file mode 100644 index 7d457baa..00000000 --- a/portlibs/include/zip/ioapi.h +++ /dev/null @@ -1,75 +0,0 @@ -/* ioapi.h -- IO base function header for compress/uncompress .zip - files using zlib + zip or unzip API - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant -*/ - -#ifndef _ZLIBIOAPI_H -#define _ZLIBIOAPI_H - - -#define ZLIB_FILEFUNC_SEEK_CUR (1) -#define ZLIB_FILEFUNC_SEEK_END (2) -#define ZLIB_FILEFUNC_SEEK_SET (0) - -#define ZLIB_FILEFUNC_MODE_READ (1) -#define ZLIB_FILEFUNC_MODE_WRITE (2) -#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) - -#define ZLIB_FILEFUNC_MODE_EXISTING (4) -#define ZLIB_FILEFUNC_MODE_CREATE (8) - - -#ifndef ZCALLBACK - -#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) -#define ZCALLBACK CALLBACK -#else -#define ZCALLBACK -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); -typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); -typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); -typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); -typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); -typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); -typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); - -typedef struct zlib_filefunc_def_s -{ - open_file_func zopen_file; - read_file_func zread_file; - write_file_func zwrite_file; - tell_file_func ztell_file; - seek_file_func zseek_file; - close_file_func zclose_file; - testerror_file_func zerror_file; - voidpf opaque; -} zlib_filefunc_def; - - - -void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); - -#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) -#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) -#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) -#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) -#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) -#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) - - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/portlibs/include/zip/unzip.h b/portlibs/include/zip/unzip.h deleted file mode 100644 index b247937c..00000000 --- a/portlibs/include/zip/unzip.h +++ /dev/null @@ -1,354 +0,0 @@ -/* unzip.h -- IO for uncompress .zip files using zlib - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g - WinZip, InfoZip tools and compatible. - - Multi volume ZipFile (span) are not supported. - Encryption compatible with pkzip 2.04g only supported - Old compressions used by old PKZip 1.x are not supported - - - I WAIT FEEDBACK at mail info@winimage.com - Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution - - Condition of use and distribution are the same than zlib : - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - -*/ - -/* for more info about .ZIP format, see - http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip - http://www.info-zip.org/pub/infozip/doc/ - PkWare has also a specification at : - ftp://ftp.pkware.com/probdesc.zip -*/ - -#ifndef _unz_H -#define _unz_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _ZLIB_H -#include "zlib.h" -#endif - -#ifndef _ZLIBIOAPI_H -#include "ioapi.h" -#endif - -#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) -/* like the STRICT of WIN32, we define a pointer that cannot be converted - from (void*) without cast */ -typedef struct TagunzFile__ { int unused; } unzFile__; -typedef unzFile__ *unzFile; -#else -typedef voidp unzFile; -#endif - - -#define UNZ_OK (0) -#define UNZ_END_OF_LIST_OF_FILE (-100) -#define UNZ_ERRNO (Z_ERRNO) -#define UNZ_EOF (0) -#define UNZ_PARAMERROR (-102) -#define UNZ_BADZIPFILE (-103) -#define UNZ_INTERNALERROR (-104) -#define UNZ_CRCERROR (-105) - -/* tm_unz contain date/time info */ -typedef struct tm_unz_s -{ - uInt tm_sec; /* seconds after the minute - [0,59] */ - uInt tm_min; /* minutes after the hour - [0,59] */ - uInt tm_hour; /* hours since midnight - [0,23] */ - uInt tm_mday; /* day of the month - [1,31] */ - uInt tm_mon; /* months since January - [0,11] */ - uInt tm_year; /* years - [1980..2044] */ -} tm_unz; - -/* unz_global_info structure contain global data about the ZIPfile - These data comes from the end of central dir */ -typedef struct unz_global_info_s -{ - uLong number_entry; /* total number of entries in - the central dir on this disk */ - uLong size_comment; /* size of the global comment of the zipfile */ -} unz_global_info; - - -/* unz_file_info contain information about a file in the zipfile */ -typedef struct unz_file_info_s -{ - uLong version; /* version made by 2 bytes */ - uLong version_needed; /* version needed to extract 2 bytes */ - uLong flag; /* general purpose bit flag 2 bytes */ - uLong compression_method; /* compression method 2 bytes */ - uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ - uLong crc; /* crc-32 4 bytes */ - uLong compressed_size; /* compressed size 4 bytes */ - uLong uncompressed_size; /* uncompressed size 4 bytes */ - uLong size_filename; /* filename length 2 bytes */ - uLong size_file_extra; /* extra field length 2 bytes */ - uLong size_file_comment; /* file comment length 2 bytes */ - - uLong disk_num_start; /* disk number start 2 bytes */ - uLong internal_fa; /* internal file attributes 2 bytes */ - uLong external_fa; /* external file attributes 4 bytes */ - - tm_unz tmu_date; -} unz_file_info; - -extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, - const char* fileName2, - int iCaseSensitivity)); -/* - Compare two filename (fileName1,fileName2). - If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) - If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi - or strcasecmp) - If iCaseSenisivity = 0, case sensitivity is defaut of your operating system - (like 1 on Unix, 2 on Windows) -*/ - - -extern unzFile ZEXPORT unzOpen OF((const char *path)); -/* - Open a Zip file. path contain the full pathname (by example, - on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer - "zlib/zlib113.zip". - If the zipfile cannot be opened (file don't exist or in not valid), the - return value is NULL. - Else, the return value is a unzFile Handle, usable with other function - of this unzip package. -*/ - -extern unzFile ZEXPORT unzOpen2 OF((const char *path, - zlib_filefunc_def* pzlib_filefunc_def)); -/* - Open a Zip file, like unzOpen, but provide a set of file low level API - for read/write the zip file (see ioapi.h) -*/ - -extern int ZEXPORT unzClose OF((unzFile file)); -/* - Close a ZipFile opened with unzipOpen. - If there is files inside the .Zip opened with unzOpenCurrentFile (see later), - these files MUST be closed with unzipCloseCurrentFile before call unzipClose. - return UNZ_OK if there is no problem. */ - -extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, - unz_global_info *pglobal_info)); -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. */ - - -extern int ZEXPORT unzGetGlobalComment OF((unzFile file, - char *szComment, - uLong uSizeBuf)); -/* - Get the global comment string of the ZipFile, in the szComment buffer. - uSizeBuf is the size of the szComment buffer. - return the number of byte copied or an error code <0 -*/ - - -/***************************************************************************/ -/* Unzip package allow you browse the directory of the zipfile */ - -extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); -/* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem -*/ - -extern int ZEXPORT unzGoToNextFile OF((unzFile file)); -/* - Set the current file of the zipfile to the next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. -*/ - -extern int ZEXPORT unzLocateFile OF((unzFile file, - const char *szFileName, - int iCaseSensitivity)); -/* - Try locate the file szFileName in the zipfile. - For the iCaseSensitivity signification, see unzStringFileNameCompare - - return value : - UNZ_OK if the file is found. It becomes the current file. - UNZ_END_OF_LIST_OF_FILE if the file is not found -*/ - - -/* ****************************************** */ -/* Ryan supplied functions */ -/* unz_file_info contain information about a file in the zipfile */ -typedef struct unz_file_pos_s -{ - uLong pos_in_zip_directory; /* offset in zip file directory */ - uLong num_of_file; /* # of file */ -} unz_file_pos; - -extern int ZEXPORT unzGetFilePos( - unzFile file, - unz_file_pos* file_pos); - -extern int ZEXPORT unzGoToFilePos( - unzFile file, - unz_file_pos* file_pos); - -/* ****************************************** */ - -extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, - unz_file_info *pfile_info, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); -/* - Get Info about the current file - if pfile_info!=NULL, the *pfile_info structure will contain somes info about - the current file - if szFileName!=NULL, the filemane string will be copied in szFileName - (fileNameBufferSize is the size of the buffer) - if extraField!=NULL, the extra field information will be copied in extraField - (extraFieldBufferSize is the size of the buffer). - This is the Central-header version of the extra field - if szComment!=NULL, the comment string of the file will be copied in szComment - (commentBufferSize is the size of the buffer) -*/ - -/***************************************************************************/ -/* for reading the content of the current zipfile, you can open it, read data - from it, and close it (you can close it before reading all the file) - */ - -extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); -/* - Open for reading data the current file in the zipfile. - If there is no error, the return value is UNZ_OK. -*/ - -extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, - const char* password)); -/* - Open for reading data the current file in the zipfile. - password is a crypting password - If there is no error, the return value is UNZ_OK. -*/ - -extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, - int* method, - int* level, - int raw)); -/* - Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) - if raw==1 - *method will receive method of compression, *level will receive level of - compression - note : you can set level parameter as NULL (if you did not want known level, - but you CANNOT set method parameter as NULL -*/ - -extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, - int* method, - int* level, - int raw, - const char* password)); -/* - Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) - if raw==1 - *method will receive method of compression, *level will receive level of - compression - note : you can set level parameter as NULL (if you did not want known level, - but you CANNOT set method parameter as NULL -*/ - - -extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); -/* - Close the file in zip opened with unzOpenCurrentFile - Return UNZ_CRCERROR if all the file was read but the CRC is not good -*/ - -extern int ZEXPORT unzReadCurrentFile OF((unzFile file, - voidp buf, - unsigned len)); -/* - Read bytes from the current file (opened by unzOpenCurrentFile) - buf contain buffer where data must be copied - len the size of buf. - - return the number of byte copied if somes bytes are copied - return 0 if the end of file was reached - return <0 with error code if there is an error - (UNZ_ERRNO for IO error, or zLib error for uncompress error) -*/ - -extern z_off_t ZEXPORT unztell OF((unzFile file)); -/* - Give the current position in uncompressed data -*/ - -extern int ZEXPORT unzeof OF((unzFile file)); -/* - return 1 if the end of file was reached, 0 elsewhere -*/ - -extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, - voidp buf, - unsigned len)); -/* - Read extra field from the current file (opened by unzOpenCurrentFile) - This is the local-header version of the extra field (sometimes, there is - more info in the local-header version than in the central-header) - - if buf==NULL, it return the size of the local extra field - - if buf!=NULL, len is the size of the buffer, the extra header is copied in - buf. - the return value is the number of bytes copied in buf, or (if <0) - the error code -*/ - -/***************************************************************************/ - -/* Get the current file offset */ -extern uLong ZEXPORT unzGetOffset (unzFile file); - -/* Set the current file offset */ -extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); - - - -#ifdef __cplusplus -} -#endif - -#endif /* _unz_H */ diff --git a/portlibs/include/zip/zip.h b/portlibs/include/zip/zip.h deleted file mode 100644 index acacce83..00000000 --- a/portlibs/include/zip/zip.h +++ /dev/null @@ -1,235 +0,0 @@ -/* zip.h -- IO for compress .zip files using zlib - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - This unzip package allow creates .ZIP file, compatible with PKZip 2.04g - WinZip, InfoZip tools and compatible. - Multi volume ZipFile (span) are not supported. - Encryption compatible with pkzip 2.04g only supported - Old compressions used by old PKZip 1.x are not supported - - For uncompress .zip file, look at unzip.h - - - I WAIT FEEDBACK at mail info@winimage.com - Visit also http://www.winimage.com/zLibDll/unzip.html for evolution - - Condition of use and distribution are the same than zlib : - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - -*/ - -/* for more info about .ZIP format, see - http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip - http://www.info-zip.org/pub/infozip/doc/ - PkWare has also a specification at : - ftp://ftp.pkware.com/probdesc.zip -*/ - -#ifndef _zip_H -#define _zip_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _ZLIB_H -#include "zlib.h" -#endif - -#ifndef _ZLIBIOAPI_H -#include "ioapi.h" -#endif - -#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) -/* like the STRICT of WIN32, we define a pointer that cannot be converted - from (void*) without cast */ -typedef struct TagzipFile__ { int unused; } zipFile__; -typedef zipFile__ *zipFile; -#else -typedef voidp zipFile; -#endif - -#define ZIP_OK (0) -#define ZIP_EOF (0) -#define ZIP_ERRNO (Z_ERRNO) -#define ZIP_PARAMERROR (-102) -#define ZIP_BADZIPFILE (-103) -#define ZIP_INTERNALERROR (-104) - -#ifndef DEF_MEM_LEVEL -# if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -# else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -# endif -#endif -/* default memLevel */ - -/* tm_zip contain date/time info */ -typedef struct tm_zip_s -{ - uInt tm_sec; /* seconds after the minute - [0,59] */ - uInt tm_min; /* minutes after the hour - [0,59] */ - uInt tm_hour; /* hours since midnight - [0,23] */ - uInt tm_mday; /* day of the month - [1,31] */ - uInt tm_mon; /* months since January - [0,11] */ - uInt tm_year; /* years - [1980..2044] */ -} tm_zip; - -typedef struct -{ - tm_zip tmz_date; /* date in understandable format */ - uLong dosDate; /* if dos_date == 0, tmu_date is used */ -/* uLong flag; */ /* general purpose bit flag 2 bytes */ - - uLong internal_fa; /* internal file attributes 2 bytes */ - uLong external_fa; /* external file attributes 4 bytes */ -} zip_fileinfo; - -typedef const char* zipcharpc; - - -#define APPEND_STATUS_CREATE (0) -#define APPEND_STATUS_CREATEAFTER (1) -#define APPEND_STATUS_ADDINZIP (2) - -extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); -/* - Create a zipfile. - pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on - an Unix computer "zlib/zlib113.zip". - if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip - will be created at the end of the file. - (useful if the file contain a self extractor code) - if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will - add files in existing zip (be sure you don't add file that doesn't exist) - If the zipfile cannot be opened, the return value is NULL. - Else, the return value is a zipFile Handle, usable with other function - of this zip package. -*/ - -/* Note : there is no delete function into a zipfile. - If you want delete file into a zipfile, you must open a zipfile, and create another - Of couse, you can use RAW reading and writing to copy the file you did not want delte -*/ - -extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, - int append, - zipcharpc* globalcomment, - zlib_filefunc_def* pzlib_filefunc_def)); - -extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level)); -/* - Open a file in the ZIP for writing. - filename : the filename in zip (if NULL, '-' without quote will be used - *zipfi contain supplemental information - if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local - contains the extrafield data the the local header - if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global - contains the extrafield data the the local header - if comment != NULL, comment contain the comment string - method contain the compression method (0 for store, Z_DEFLATED for deflate) - level contain the level of compression (can be Z_DEFAULT_COMPRESSION) -*/ - - -extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw)); - -/* - Same than zipOpenNewFileInZip, except if raw=1, we write raw file - */ - -extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCtypting)); - -/* - Same than zipOpenNewFileInZip2, except - windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 - password : crypting password (NULL for no crypting) - crcForCtypting : crc of file to compress (needed for crypting) - */ - - -extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, - const void* buf, - unsigned len)); -/* - Write data in the zipfile -*/ - -extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); -/* - Close the current file in the zipfile -*/ - -extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, - uLong uncompressed_size, - uLong crc32)); -/* - Close the current file in the zipfile, for fiel opened with - parameter raw=1 in zipOpenNewFileInZip2 - uncompressed_size and crc32 are value for the uncompressed size -*/ - -extern int ZEXPORT zipClose OF((zipFile file, - const char* global_comment)); -/* - Close the zipfile -*/ - -#ifdef __cplusplus -} -#endif - -#endif /* _zip_H */ diff --git a/portlibs/include/zlib.h b/portlibs/include/zlib.h index bfbba83e..3e0c7672 100644 --- a/portlibs/include/zlib.h +++ b/portlibs/include/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.5, April 19th, 2010 + version 1.2.8, April 28th, 2013 - Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,8 +24,8 @@ The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). + Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). */ #ifndef ZLIB_H @@ -37,11 +37,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.2.5" -#define ZLIB_VERNUM 0x1250 +#define ZLIB_VERSION "1.2.8" +#define ZLIB_VERNUM 0x1280 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 5 +#define ZLIB_VER_REVISION 8 #define ZLIB_VER_SUBREVISION 0 /* @@ -83,15 +83,15 @@ typedef void (*free_func) OF((voidpf opaque, voidpf address)); struct internal_state; typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ + z_const Bytef *next_in; /* next input byte */ uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ + uLong total_in; /* total number of input bytes read so far */ Bytef *next_out; /* next output byte should be put there */ uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ + uLong total_out; /* total number of bytes output so far */ - char *msg; /* last error message, NULL if no error */ + z_const char *msg; /* last error message, NULL if no error */ struct internal_state FAR *state; /* not visible by applications */ alloc_func zalloc; /* used to allocate the internal state */ @@ -327,8 +327,9 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); Z_FINISH can be used immediately after deflateInit if all the compression is to be done in a single step. In this case, avail_out must be at least the - value returned by deflateBound (see below). If deflate does not return - Z_STREAM_END, then it must be called again as described above. + value returned by deflateBound (see below). Then deflate is guaranteed to + return Z_STREAM_END. If not enough output space is provided, deflate will + not return Z_STREAM_END, and it must be called again as described above. deflate() sets strm->adler to the adler32 checksum of all input read so far (that is, total_in bytes). @@ -451,23 +452,29 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); error. However if all decompression is to be performed in a single step (a single call of inflate), the parameter flush should be set to Z_FINISH. In this case all pending input is processed and all pending output is flushed; - avail_out must be large enough to hold all the uncompressed data. (The size - of the uncompressed data may have been saved by the compressor for this - purpose.) The next operation on this stream must be inflateEnd to deallocate - the decompression state. The use of Z_FINISH is never required, but can be - used to inform inflate that a faster approach may be used for the single - inflate() call. + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. In this implementation, inflate() always flushes as much output as possible to the output buffer, and always uses the faster approach on the - first call. So the only effect of the flush parameter in this implementation - is on the return value of inflate(), as noted below, or when it returns early - because Z_BLOCK or Z_TREES is used. + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the adler32 checksum of the dictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the adler32 checksum of all output produced so far (that is, + strm->adler to the Adler-32 checksum of all output produced so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described below. At the end of the stream, inflate() checks that its computed adler32 checksum is equal to that saved by the compressor and returns Z_STREAM_END @@ -478,7 +485,9 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); initializing with inflateInit2(). Any information contained in the gzip header is not retained, so applications that need that information should instead use raw inflate, see inflateInit2() below, or inflateBack() and - perform their own processing of the gzip header and trailer. + perform their own processing of the gzip header and trailer. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + producted so far. The CRC-32 is checked against the gzip trailer. inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has @@ -580,10 +589,15 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, uInt dictLength)); /* Initializes the compression dictionary from the given byte sequence - without producing any compressed output. This function must be called - immediately after deflateInit, deflateInit2 or deflateReset, before any call - of deflate. The compressor and decompressor must use exactly the same - dictionary (see inflateSetDictionary). + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). The dictionary should consist of strings (byte sequences) that are likely to be encountered later in the data to be compressed, with the most commonly @@ -610,8 +624,8 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is inconsistent (for example if deflate has already been called for this stream - or if the compression method is bsort). deflateSetDictionary does not - perform any compression: this will be done by deflate(). + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, @@ -688,9 +702,29 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, deflation of sourceLen bytes. It must be called after deflateInit() or deflateInit2(), and after deflateSetHeader(), if used. This would be used to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. */ +ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, + unsigned *pending, + int *bits)); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are Z_NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, int bits, int value)); @@ -703,8 +737,9 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, than or equal to 16, and that many of the least significant bits of value will be inserted in the output. - deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. */ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, @@ -790,10 +825,11 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, if that call returned Z_NEED_DICT. The dictionary chosen by the compressor can be determined from the adler32 value returned by that call of inflate. The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called - immediately after inflateInit2() or inflateReset() and before any call of - inflate() to set the dictionary. The application must insure that the - dictionary that was used for compression is provided. + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is @@ -803,19 +839,38 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, inflate(). */ +ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, + Bytef *dictionary, + uInt *dictLength)); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similary, if dictLength is Z_NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); /* - Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all available input is skipped. No output is provided. - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been - found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the - success case, the application may save the current current value of total_in - which indicates where valid compressed data was found. In the error case, - the application may repeatedly call inflateSync, providing more input each - time, until success or end of the input data. + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current current value of + total_in which indicates where valid compressed data was found. In the + error case, the application may repeatedly call inflateSync, providing more + input each time, until success or end of the input data. */ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, @@ -962,12 +1017,13 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, See inflateBack() for the usage of these routines. inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the paramaters are invalid, Z_MEM_ERROR if the internal state could not be + the parameters are invalid, Z_MEM_ERROR if the internal state could not be allocated, or Z_VERSION_ERROR if the version of the library does not match the version of the header file. */ -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef unsigned (*in_func) OF((void FAR *, + z_const unsigned char FAR * FAR *)); typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, @@ -975,11 +1031,12 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, out_func out, void FAR *out_desc)); /* inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is more efficient than inflate() for - file i/o applications in that it avoids copying between the output and the - sliding window by simply making the window itself the output buffer. This - function trusts the application to not change the output buffer passed by - the output function, at least until inflateBack() returns. + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. inflateBackInit() must be called first to allocate the internal state and to initialize the state with the user-provided window buffer. @@ -1088,6 +1145,7 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); 27-31: 0 (reserved) */ +#ifndef Z_SOLO /* utility functions */ @@ -1149,10 +1207,11 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. */ - /* gzip file access functions */ /* @@ -1162,7 +1221,7 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, wrapper, documented in RFC 1952, wrapped around a deflate stream. */ -typedef voidp gzFile; /* opaque gzip file descriptor */ +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ /* ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); @@ -1172,13 +1231,28 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression as in "wb9F". (See the description of - deflateInit2 for more information about the strategy parameter.) Also "a" - can be used instead of "w" to request that the gzip stream that will be - written be appended to the file. "+" will result in an error, since reading - and writing to the same gzip file is not supported. + deflateInit2 for more information about the strategy parameter.) 'T' will + request transparent writing or appending with no compression and not using + the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. gzopen returns NULL if the file could not be opened, if there was insufficient memory to allocate the gzFile state, or if an invalid mode was @@ -1197,7 +1271,11 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, mode);. The duplicated descriptor should be saved to avoid a leak, since - gzdopen does not close fd if it fails. + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. gzdopen returns NULL if there was insufficient memory to allocate the gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not @@ -1235,14 +1313,26 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); /* Reads the given number of uncompressed bytes from the compressed file. If - the input file was not in gzip format, gzread copies the given number of - bytes into the buffer. + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. After reaching the end of a gzip stream in the input, gzread will continue - to read, looking for another gzip stream, or failing that, reading the rest - of the input file directly without decompression. The entire input file - will be read if gzread is called until it returns less than the requested - len. + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. gzread returns the number of uncompressed bytes actually read, less than len for end of file, or -1 for error. @@ -1256,7 +1346,7 @@ ZEXTERN int ZEXPORT gzwrite OF((gzFile file, error. */ -ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); /* Converts, formats, and writes the arguments to the compressed file under control of the format string, as in fprintf. gzprintf returns the number of @@ -1301,7 +1391,10 @@ ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); /* Reads one byte from the compressed file. gzgetc returns this byte or -1 - in case of end of file or error. + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. */ ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); @@ -1397,9 +1490,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file)); ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); /* Returns true (1) if file is being copied directly while reading, or false - (0) if file is a gzip stream being decompressed. This state can change from - false to true while reading the input file if the end of a gzip stream is - reached, but is followed by data that is not another gzip stream. + (0) if file is a gzip stream being decompressed. If the input file is empty, gzdirect() will return true, since the input does not contain a gzip stream. @@ -1408,6 +1499,13 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); cause buffers to be allocated to allow reading the file to determine if it is a gzip file. Therefore if gzbuffer() is used, it should be called before gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) */ ZEXTERN int ZEXPORT gzclose OF((gzFile file)); @@ -1419,7 +1517,8 @@ ZEXTERN int ZEXPORT gzclose OF((gzFile file)); must not be called more than once on the same allocation. gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a - file operation error, or Z_OK on success. + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. */ ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); @@ -1457,6 +1556,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); file that is being written concurrently. */ +#endif /* !Z_SOLO */ /* checksum functions */ @@ -1492,16 +1592,17 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. */ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); /* Update a running CRC-32 with the bytes buf[0..len-1] and return the updated CRC-32. If buf is Z_NULL, this function returns the required - initial value for the for the crc. Pre- and post-conditioning (one's - complement) is performed within this function so it shouldn't be done by the - application. + initial value for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. Usage example: @@ -1544,17 +1645,42 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, const char *version, int stream_size)); #define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) #define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) #define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, sizeof(z_stream)) + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) #define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) #define inflateBackInit(strm, windowBits, window) \ inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, sizeof(z_stream)) + ZLIB_VERSION, (int)sizeof(z_stream)) + +#ifndef Z_SOLO + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +# define z_gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#else +# define gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#endif /* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if @@ -1562,7 +1688,7 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, * functions are changed to 64 bits) -- in case these are set on systems * without large file support, _LFS64_LARGEFILE must also be true */ -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +#ifdef Z_LARGE64 ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); @@ -1571,14 +1697,23 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); #endif -#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# ifdef _LARGEFILE64_SOURCE +#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) +# ifdef Z_PREFIX_SET +# define z_gzopen z_gzopen64 +# define z_gzseek z_gzseek64 +# define z_gztell z_gztell64 +# define z_gzoffset z_gzoffset64 +# define z_adler32_combine z_adler32_combine64 +# define z_crc32_combine z_crc32_combine64 +# else +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# endif +# ifndef Z_LARGE64 ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); @@ -1595,6 +1730,13 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); #endif +#else /* Z_SOLO */ + + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); + +#endif /* !Z_SOLO */ + /* hack for buggy compilers */ #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) struct internal_state {int dummy;}; @@ -1603,8 +1745,21 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, /* undocumented functions */ ZEXTERN const char * ZEXPORT zError OF((int)); ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); +ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); +ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); +#if defined(_WIN32) && !defined(Z_SOLO) +ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, + const char *mode)); +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, + const char *format, + va_list va)); +# endif +#endif #ifdef __cplusplus } diff --git a/portlibs/lib/libz.a b/portlibs/lib/libz.a index cd3991d97e9395dc95f400b63c1240196c8ab572..28378965221c9c614e08e140d28da12678649765 100644 GIT binary patch delta 38343 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

    ;nrPAvjc{KGNq>z3+H1)-=;C zEzPLqu$Fs|x`nPKeJK1;r1cuThqi0Lu`o0vBwRx1HlCEq+^Jjo;Qssobq`SR1HoOy zww7CTL!~`bWDjh(n~zmP7NOK$D78;2^-6u#5~0-ns4YiLb)~+C8cwhuL{>G=!6_;q zHgmAo*1I03u~g7qh>EK}e#fK!yqA^i5Wd4!^$}cPL#GHPqB57g<`HR%Uc-4r;@D+} zENbG57M#hnLJVjDU1TyK1!Z|taOMhyi539vQ44?=?Id~}9JK(h z7w~gKhe&LgZrvzbKo@ZwE&Cvej_d+)KNZ?94-lSMDYf6Gb8pBMnC-#RF5il#Bej^f z05&YD7tKvtQJkwFv9|MC#O0D@g^0aKn?xspsk4UB?1jP0LNm`)AE=@*4zZ(8j)$`Y zd8m0mQjX~sj2@YS>1%LhNjX2#7E4wT5rJvz`47~4aZCl8jZ!ift-%@No6t{=K+4rH z6!$_Y7Vtf&+P3CLAe-lPgCq9oJRT|rHNwt=vIbI4Zw6S|(QnA8OZA^18SV9@F}M1{ zryfe9c7EzXSy}1}*b~(8fu+_UPdGtAG9e$f*C;^PY*1VBc<``Mppemdor-LNJ;7bN z;rV*CRNN{kX(sJj3FNKkSz><)s#EQ|z1#|>xqRh{)zux`=&QZSLx;UK({(XmloO0= z$Gr?F5i>^Y4Qdaa0NIdsu!^idm4Y!NdH_x~ol^;TR~vZm9)8UgN&4;yE*ywBH)RGI z!)grzHmueFP#V2v=4H>phv#_B14R@S4K&`%Q+QTj`@Jygxk#Bs{3CX$-6yUkiBh*j z-4i68JIpeqBbKRX+$3aRbGWv!0%6=cLUlTOPCYDC7|v@@BV>pU%dI}#i?%H^P3+Yo zgRw1%=FWlE20qtzVW$I;^cnd{2LgM%JYUTk?ti4>8Iq-bYPc^tU$WH(n(vWpu}=C| zK0~rZDr9MLGQIWb`|JWseSEx1?m2Au6#FAny-`sfsKK{4&(?#!qbHIZ_`H)}t%};{Qh$2AcwhMP@h;v3vJNbFK zmOhXgc)5{RX%Bs252UO7mf;=3bUR+I*UHlZWBhzd%#>qT$gK@@l;YmLw1Z;X1|Gq# zsWE8>QA|dlV;kP2en_Xg!W_ve$&L0N|@Y}F&Q~Q zWUNDmr!kE2u`%M549{dNp#fpzbkQ8fMju9=dfLNrY0eeED*mvvMSoZ6kKsKRSdiBL zEK0z&fsZe#8II6_H5Y`}T@dzP5WX+)b2^ChE)F7fVpo1KNK2L5DSm-<>nb8uhWFs$ z(O$S%-7<{r78r^$rA~%>Ez;ZN;hi#k^!)S+doOTXGylO9+G|mZ zr967BUFm5kAfRR?U6e@B9k;Am893C;uTEL9ZpF+QZ1q}k)C{j^{SS{-D;rh>W^Uvw zRay=;cDZvbCK_8JXaSM7M9?2cm5q%FygPg_LBV3Bad<&N-eLH1>Q#`i2h|C0U3ll-huLjXE1(=D)7_JO+%e*wqEi(ja6hK>R z3_{~k0RtY9AYrQi2v5X|qhX{Yj)#$sI2A^Uyu)HjKmmrB5>Pv%;DoG*H1>!zu81^l z^k;^=6RIK-)kY)&yC%rm(@7}7ExaF@F1bapEu4O2OSm#4p)13Aq1qy^AL-wgdHs<8 z$YbHmqejU@sNpCy97Fb_QX|q-N5H$n@*Xu9hDYBf@!enVAA$ zmyvl~ML2U}LO65c?r{7>QrH+YPt;-JmpUE+N9am&7c7b-D7in3C(W*xCE6cW3Wl{h z&Ba)T%#a3d7}}oZVZ-}>()f_ocpU;47PZkKlP@2~!+`@XnYMYOSQ7bTklBNu?zOSW zqEaav97Z-GqXc)gkdKYx^fmC^=z@)&_t>x}i<~*_`oR^dSamW&dc3&h=MG%O&; z7Dn(bv=1CqcmdO0q$XDnvzK8bC*o))t4H1VkswN^J`@BOXqe%}SQ|5dTRE{I3p-mq z>dq6_qT90)a&KCc2P3OqsvaT1`y`3TgZ=eXQ{4#(hcE_$`^5-XU&JG?Xc85M0TfsS z4-%bbK`l*mGJ;-+S)HF9R+~={FAoB_mrmD%G8*&bgbY*N6KV-lt&dJ6kw?#~ zz~h*CfLJ125{d~}C@{2%XWe)n1yp*8pJjpq8o$Ar7VN`JYz_?;#eB6Rh`D5Fx2Vc@ z`P(C_Na}#Z_WUS}$G|_#1*L~qAEN? zdT9FV0M{{vwHfmRoV>5cG`P-~0>feTy6Spoz2FlQQrn85Yj;sE+?G4AwPVI+e%Txw zp)u~uBJT>JrUpr<>D~9BpA&d$GryC+9!UHt&*#;FD}Tx}uva7vD(F8-^TQ)eb8uc_ z{W~5x%k6^Spw1hIIU{skeHeEO;fe>f@HOGg@Fru92_L$;{4JqWi&G1?q~x$)9qkDm-;i)7?Y>5hNU#Jt1;j*jhmZqON(z13Xrz3ys-_3V}QNsf7|Nm@XJjdCBj9{0s7%Rnknd zKOq+iatRyu1gpX&2i5+U=v2et2fFrBnqVi=2pff`6*CY0!Z)~e=@=Yl9;uL;1)7fu z$NFbbDY`IPq{l8Had9g-x32b!)}hZo)t(St@Bt?S%SA27MJ{G2$ZV&~Gy{pujOKKV zEQ3DpWiC=a5YyfY^VSOU1<#0>b^8(aBaDi5vt!l{xE}A4;Q647i}jUs_yDm4Z=(fd^|b|i#0D6oYmytVhTVP$ zBMn_4teZa~#2lqQMLYA2n+$=7Y^qM?h4PnqX|nI=$pX8K`0X~V}xpuVXN-e|7MazbQE#^ zz}KyO9!_!2Zi6pC=MT(GNh_}HeHItmg#{-r5vD^6AmtUZ%-Hg>SNA@Jc14(Va$O4n zmTU=aMhX2?DujroqOa#bc(e{E?Ph2%-q*>#42Lk&*+yD4gzz?Nx8TC$CYYtiaEIKB z%nt-ffrm8iQ0a0(y77{ZIHAT?kjRRl>{2;%AqwFl#yW?G6tfwau*TtqMEuaXjgU&q zdCE#wHC)X@fUAXp)US2ZEicrE3?&+p%9`eZ&A5@UXa~G1I78`;`(Td)V%^4BoP)Dg zm|vUIhD|UWr%*YwJUmHU$8I5|rUesM6YErW9Hk}nZT=9}N@Dx>$O2n1n$Vm3JQ%^- zgY_DgG>oR+8bVWFuIdU0#)(#>+l+s|C^(?&2XrOGbWxw$Aw_LRr*#t4)8Vfw(kpsT zdPVurxI%1Psxo0Dr+z50SdhTbAJ1%8s}UvNH-4zMm@sQ)wpAbKPl7w zM#q3jln%UrX%mWP+vNK{!S_^+^a(P2{_z*aKET|t4(X4{_n+!$hVgxUUYMptf#)CL z%hHz9d6~6$(m@z;aE8g-f3913*UE;#>~@|PuOEY9|8dt^d}SpiptbWPRi?UPZ4DEr z{|S30NR$&aI@2%=FTv3s%mzix?g32fp<4RG(^=X#Z+HvH@iPo#CMohFIr~!P1*p<~ zcVkM*fzZgnYk^x5K?l!<;g=<%B=GP}iHP7MVLS@(7;|9-6)^HDyCUL`3U881^f0AA z!fiAVMidp1Im#c-9Mx@1N#VTg410&7fz&u`6Wb^WbwP1{A_*n9C5%5V3FRltTE;yd z&JYK8l3*_~#6jx}4#k68#$-DIurZGw*&DvtV2)I9tXXFVPe>H>bP-EkA z4!B2TW_a{&y=BFk;jR3`w?Q~AKG}B8GQPHxVcOTza(@ipxbMpU)MD`Eg13M6xPogT z8-Kn%Iog_!`eVCz0$DM-aKYuEC&Po4bLk^KL}ZrKin;W-A=+-=SQT;2Sr$H=#t z@@YNWM(`TSQ214ie-H;X4{WsikFgqc;I!Kji!o?7tEQDOTr$mlgHd_jmvQGk(xGdt zXey@e@{4Ni%Waoo1HrV1U*cuj*AFjKzUb3#*uH#xJrW3ngiKC4TC`WUXW;DNKetaQ zvG`Mk{Z2#IQqh^J7^92oIp6|zHMW8qX|2g(q>V4=@uYHvR>SNUu}OKwl$ncD33N;3vP;sEKs zE$#03VKcp@i%wMDs#r61Lp`|@MRbePlva50am^PV#>HO%(|27Oy%dBUr-PJAT7|ZD z*QNXc;iXUiHO^38%8zUR*fmv|Y}H2nGQ``pQBN1~gIf91smU|!tY-CH4Y#fK-KYUCqjM01Ia9^FRG0SAQ$pK`UA)oL8b95d5BuZvgzEj0ZffAl$;oT`tpfA^u94 zhT!&yG*8PkM-XqcGr;sm2U@h9yHBRdn@^k<)AfD3f4xMZ3r0MxBk;L^Pg(K4v3vg! zJIu;wyACVzqdf)FFNOf8US`j>i;wo;k^KB6Dh?Aje}pXxaN*F{7Cm$UxovdM5Z{PV zTb8~T48zM*3=!!oC)hFs)!&U#fnDv)a;rPU#o5RF?HG{YDvg&xt^HWR}`JIx;O%=JE5W~TzNsW!_f6bqJ1 zMIqQKhQ`PVq0>exD!gMf08b^vV(^XO+Ql{)QGWGZe3~XqXxcEPB^yFnA^`^3#0jc} z_8;9>s=?D}gM*-l90QzaB|51c_;G``cVn5IE`TJad8;vvKvvMi;Yv9~Lrvr@^RA(@ z>7gKfGB2Sp=xnIgsm|44PlmY1#(awzoWNk3Sk<;%+xz19?2B^(mo$SLb@;jQt7u!0(yNuf zkT)%4G3dnjHP(DVN_>>y!EAo>O44&Bc_zNHNk*QQ7FyIP$ko@?IQ{slp z)Bf;c?yzmszJBqDsST5H?bSbA#*;MVrKwBCrfztfnVO1VfH$!bQ2V3J$;?vN5ITn) z2#&^g_j#Jn;d4ggU-A@!A32*?I(S=K$U;GAbWLMav!|&^-^kMh#2c`ih(24efp!!% zzEm=%A6t~Z!5!Chh0g?B;WI(&d&!}slxgt?SMa0S+Jox~$DT%~hYOPvGx5Z%e0)DR zKN4+cB-Yv4BJV&?Q7AM-{S4w05T8Kt2-~#eKXzQT%T4}q!Xp!)gZhBOuO|^ejMHG3XP+$?YwenhFROhOd!)zAEUr?Ft#3fqDZ!s zuc%+^KQs$>>nFZ)#S}BWx42PzQxSLyN*JZ9M>pUd0cYukQFU75EBW{$+@4pQu_Gw; zn8Vsgd0+hWE3 zg-*(Z(#%v+JxVXx5T{-8nw{_0Zg?$^$7%PyR-q;#5kvEuh^A#zf7VM)DM_9GmZx#& zuV7d{f1Qkut7mX2(wUogZWXErzPzE05A9iEY9rk$zdoYkCY zp|VEdX?9j)C)d;av=`|7Xwwvsz3|+g6 zxoYsBw&zHC{FuWs*bbqkYFEBKj#p|+UQbbLL5~Ye8cj^1dX@B?X;61SNq+aKr({Q5 zsT$~oCdL)eCN7|}i5+2>HaGtLd5`+L6M9Dh9O`?|S=9->Ztnz4&7IFty?sh0LCxMJ`p5uoG&}-Dc1pJDPv=pPV~@jLG}FBP8~!}1G(K~VO$-{7Aeiu=5sJDn^yO0jBe*W)d3@Zf7d`YjI9vW+XjSjG z!32zGX-Z+0*zHr{J*4gWbN0wn>Mx_7LQihK+;s*___Je0$&Q$M^-;1l*t#OPbEbXM zTr|W3xR&WXV*Y7+Q3%EwY3LXXh6Kl)nK&7{k#Vup7AAzuhc{(mUMmQJRLMqJ;AuLT zzfEY5w(_lv$zPNbpB+q?WazQUjml?)d3`2<)G{t%n@+@O?e(`Za2Nf*-kPaEw3Cm_ zkF6&jsN=P|BT3leV`XI1FPd-@+@)<^!TQgxe1pV-%A^ZU6p1_A#6gaZ#6z}_bD?$ z-=Z9U!&!#c>=y6K(=Fb4XB-yq$4-m46CY`NG9x%?8jJE}FThLI=lz)V(RVn!e=73$ zva=lCf0Q{(HkeP--~dWR%s8zD|GIEe0cuHPo4sRcAT@MKeUwFL$GrP^aT1u}FT+e5RwNXct zm6JQQX-6~AiS_{&X{qyINCH4lWFRdJ2fi zuv=hbi1t*l)rK$=p91OmGNEmnAkL(XdMA;8sf~PRLf)5d*`{_Q;RS8#Q@`G&k}*-> zDE(Kv*7&!?sV5JESj;-3YVpLZGim^bN-^t1Z#&$2zDm{RzL|YvOH890T4HsY*@(sM zuLMCK^VUvAvrNJ+z-W*2ICD5_@llpf=%XyAx%9yh-`M${McJXC+CsfI`imJ0J^5RZ zZ_^YUuECw*rR=iC1zPW$$>V%mT<%3}ryFm`G|z#>DfV5nMf=yAQ{y+=n6HMuIy6~J zduv8)4SDXqIjVKMGgbM#RqOfN{E^$j2H=a$+Nifz#JVAv6ZP?$=j}=0`}Vh!l@o*7 zZ{MDINj>;7Zei$?(~?h~Z}aJsW5iJ9OpP}6otaTJcWu&^zB38Nt?`|d=q~h?gDCpa z@m6q2IiE|P_kv3{G0LSe2pJGe<_jDqcG=>V*dCgbgLP5f6eVwQyBI6s8t%cZl`M8H zs2C41m+3n7&s~O|fyJrRjCB?GycC5-T~MgKB|U7|yzI1g)tgEALnzRYRn+446GB!f zj7Cy=YsXD}i~WBJVnodDdO+(vHZhwHK~eLyqtLNiQgBNo^v(fghdY`2PwF?*N_xJo z)s%NH#YY;ay_{E6akfYD{^Uhc zEG1&~QRKfI+O6-+Q>8}pif^YrehR|{(RD2hedZ8egY4HxI|>~Am{)y5{)KN$sE+hC zd~N~`(eo}0opguO{L>VMKi^98C?5<6{3K|CR~nfIx|}Y&SU@lSSr>+ncZV~4MIYmn z1bvblF6`7&?Y8$l=iTY4ZST*&xvqI=_-j+un8}DP8_N*nDkpZwqlwTbL&ci)!q7W6 zi(wkBxT6WRm_XA$@B0SaVw%}LS!`NI-YiUNaX;X92-VA^Vp68!%VCAzeiKg{N_+Q5esd9N1#QJRWTmG|Q% zR!Rp7hgy-&I|9}XAF^&mT-$B5)FM6=%1A6IFBPI2N&w7mw+1Jf_2-5kD~E8gQ;TIdr+y3QLW!i4xZNtOxwgDXb)l_9(tyYM~%s%Z_JZAk)_}XT@P4|_>I4tm8S+w_X zr&*y5?Qf2;ETV9%QQ!uAZPO_@I6;TJAD*_PDITP(9gF`EzYO!Set@MiT!%RECojam z>w@sTSVhTJKnU2Yxji#ySoDet$vu zW!#T^5OEtN!arl3q6`FN$uP9{l6t&%$S~&Om+V3%c;)O~8}}uw`d>ZDY(sGR!qCXbcPk15JPyPOA_%@UBEB!YmvbD_3nCCV?n7As;PK`#q2ss9G)ai-pb;@q ziogW0*I0#_ut!fsOGp#oSf(@tCtWGyfi$UH#uI!bT!D!ZcqZ-+7fkoe6LEYStjG;A z?>4A+iewA-B{)4HoIYK0g+mc465k`^=B+shpAsPZmgsJjaGLl4fS&vz36a1;9?!7evi2%jG8mx zrS#MfGQ1<0`a^MH9bK(Q9i!-42;L7EnJ5u;l*Wy9)L|Mo)=|gFs`WI~fs&!2^wg2E zS_y+l?X{unq8B38w-smT(f_LJ8xh za&e&C$U9rc+Yv9%PsLK+8G3xoX~1>~9|xS5KSeLtf`B+oTYWiY z?u<`EgXFeWtKaeX3d^k+1YWysHDeENV*DB0Q0vP+Yjtf1opj=ykowE2z~2>~7w0Uu z;@h7#hdGcM#dBtP2i&gikli=G)1fx|;Z_M{(tcx%AI*(}Z~=Dox_n6ETM5T;JF8lJ z2#j?Gyiq)3LUFH~sPK)x94DfM7Y)O3r8Mwt6rVooUU<{%Q#{^Z@;&O3w*y~9@o~H_ z5N+aFW3F-S2<^te6Jy1*r*eK4b$wv23Hv`AZV1K9MYPL-T06i5qJz{1a{-%g0qENV z`f%d08C`&S5|`>Do%6>ym*_Ity}zuoS7K4Xm*sZ)lJVi>d-$G*TNvLeDoMW?Md{@#oo62YrD#-tF*}mybs#Os+yl zRR2fx+zJGA!$2{f3Q4Q+H(hojs_0?!k8#^c$KCok$1j7R<^=YcW?ihaQ@S5tD zE~j>2)+}-1uep{6%u}LIFc>rag&O|Cx3Ta zJpW<5y3JV)we5$$wHNA%o5LR4$YQX@!_a(i!$vh!II32Cz(wH`MV~0`{;0(6$5teE z(F}WW2r3+P*7{f(8)f?^roZ=#eC?fwSc3l}O#6DVQ!fe|d`H~mS+vG9mrkueLwQ$~ z?176#>HJ7d?7{`ErwxhyA0>8AT7@I-vH0k~Ys>8PkqXM(ih?OK=AEti zo2i}gZk<4-&v)rU59W;ILx`mck@FZ%Vv~B`0Ig*1_ib81O(F9!Gro^&#+os3`ao2x z3Z#TwB6c9rE^2T zt9Z8^wYFmGv)NaE&aLG{{tza?F2;Ncd*Wn;(J{?6x$O|fT(_K zK6nXdWr;KFQ$esGHe>o8M-0U9GQ@y%^nS5=0CIQ%tPvT25F2CR)*A3-TyFJ#9An2W zqLGy!o96EQD6y*z1%e~};7$-V6-p^&UF)*b&4j+#B7EgrPwRzjo#mwA;7XL_3PjL` zd`(2SE`qPF7HmNTu>~f}?pt`h2hTG4fV$*L3~>c<1->=W}7uL~Qe! z-FiDU7kQ}d8`_N;_mS+0Q;$Uv*9LoixD=%GB|+Rs@5GPMz(1bpA&L!olpF|VIpPC* zC-StYRsekfrq@#ztWDS{`-M5+-8qS3I?1s{L!_oDiQR$8$-L;6Os{E1o@jq@*tPN! zn#Hv1Jx;8%MK*Y9e}rB%iI-vBUR|KKKcJbk08Jtr?JxcY42~|hQoc6Cld+&813k%* zVu)B+j|8uR!9v`HMYh zUqa1^fW;)=rx)zeke=!>Ou)xC*y(ILafw(=@+F(Do;+&}+@8Xxa97}=6prtxe1w8t zg4zaQm(xM{%dk?c+*-d>JP5k{Q;=vYA4Ks-k1z zZuO5d^3eXQDs>Pb(2J&n%s@_4sst_TfgZLo``8YJ7z6usz zT7Di2y@zMO*%&3HhH=j^VW(ls{r@mk`(m+p0W*o-Y`2fZNBE=&1qUHU!9m#Uun4h{ zx$-+?=*w2DBr~7+20O_RcPP3R#p{N@qjeD@%Z17*Q zf5D!%6}kcu)st3BErtU5%**W5^H4cdlTOnplVVhbsu8$4ofl80*R+BSQ*UmI8j;yH ze?)HElo2+k4IWjbaAB-Iq-3>^0H+@_|!KNbtnTi61TZZs&#VI1$(gGqC7Sq z$ff{UIgl;5aSu*QS@kOF7M);Nhi`zy(guPt6tMut*Nf3s&O@lzuak&Fx=Qx{c6K$P zO$1SR-nQn4AeuG?EEuwDq&J@!&QL**%$)7xR;$bJMZm#`(}6My_vV~^&s%p znE}STQi?tS^P%a9lSQlm2Zpha;sHyK7c_w(#X!JE8ouu~=9Y&PH46YD69D&PtvCBm z=6gKmJ6Z|eEXjG3x_Dohe-29Iz7B@`Kv0q+W^A3iKtk;qM9Shw79HjB&gfGql zo^9{*cu;lrU+P&6`Cz=cpKK<8v1PG^?Yd%HZFu7rV9)EVeimbnd+fMHBe~^Oj)-uo zp#<`wf1Q05a-(gk;ucmg_XAduEKW6e9k8w2BFbj@MQzQZv+dURunMU_e9#R3QH1p} zQZUCIs=Qw-H{|7RI$^BXwGZ92wz5;!}8Z*qgyDreXD6bA6GQx_;`+VM=l zY^)GiMQLSlDLKm)k1u%_a;X%&zSKR~a&@_oLBK@%8pp9Jk4g+JDrXv5{$$UmB~akrjnn%qXyGzSpRF|~*G+U4{7M~g|%Q50`@iZ(LT(izuNB$p1* zXR=$<(v)k53nY!cOXaDFa}BE4@T+qv_HRVD-;u`QDO8ejk=QPQ!a1Oe#Yw!?IbmvBI!;>C(Demo8p< zYdjXK((}*c-U^(L*xJ>#(Z&0^dU{-Z+m`OWf&^Q-Iyzm3&AnZlT)bP-2a!70hc|uY zi+x+VH+}gI^1Y|yp{^C1AL{Mc(xo7LwyW>6J)0lw=(%&#`pqU{#lu^+bZzPr?jUw^ z+vYpEw`|ps!uC0`U19;94vu@ek^#f2&Feb)xG@X%ZXYld_{4A+74f9$JVXeHgC~li`avlj3Rz@ zQH2jtM<(ub>(_7X(#RLP`tr!yb(?#)Z|VN>hCcO`?q0vj3?LErOWWSL$*<=Jx_c!~ zmnn$(LdUjiBdx4^y0!(3OQ(ulGF4PL zLHN^M#6 zpxVa!vny8I7OU#)`rVD)eXXr4Vq3a;x;nOY#g^Q%Fjil4Yt0g+YPN2FsITKe-hEsA z_XZ2~VS!XlXGdR$s(EnhR#hVrHP_hT8l-j@TCquXX+_rAB^4QJmsD)CU0RX(c1fEH zExAjY!l>75*(}ABI#^s&uWHsAgG9By*Dwc08Kcup0)KSoQ`_-7-|*4$I=mC#C!t1o z-i@ysp5lB2o@~v=Sz?rY{N95heGmS_11n=Z=^A)_0#|A5J zEfE$5oH@ZCD{qFO37+P0<(&qv(LJ3!C||HW$%<*P%=KSXubNq~B%G6zQeBqXxI~pEP(o z^bab3Va3}2-8TbzDpD*Z3-<(qtMx?_j>gsc;T-Tu)O72sni_Hv)=H?obm4skHA|@ zJfNa2bXtMw+aDE~5_o@9gf7b)iPq#-R9UFH}>%Z%_ zUxyaCxBUmp8tziwy)Abv+r2`C`)5CpOtFr&GWy#?$>EtQa!)2$qo0nCD{tfpRgwDs zB3bKJ$DdGk)0EJ&hDc;t+#Or_ChX35i;b+Wz-&#%quwQ3?WPnD-n{4$wIlODRz zGRR1+Q}tPq$y&c{-A@MM>vFj)GPB5HeO@K`4|%Lp+m({|;g2aL>1-O8&#bLap+|LU z`E1d#p3bXAI*|X!oaD$Lx{fYLQie+Ou1XzSl-xT{MbdwBS+9?g8L6heSX0-LM}6ZM zX^&CI=$1uBmh|vcqDK|^R-<2?=$BsiMl!wg?WC1MS}iB>WbSC2O4LZ&^w=+=#McM% z-a(cr!>g2`-jt!ql%W#+t5PY-@dV}DPdSdOIw`}*d{r^htYQUa=?KaaC*P(<>ThJg zlm-4Q{ODClnW`vLHD#)!O!bs0uFI6AJcs@+C{uQRP^K5s#kA&twy&5*-nK4M_ctVJ z?tdUNH~rgx9&Jfu9733$~3CnW7Nye{)W4g)Xh-;M^_~22fI?28>Jr%r`}vD^|;s6<36cJ`pcm` zgQ|DW8I{^SsCsrBSI;!>C~3;PL|cz5HMpEUp>jF;a+&VOPu&&G9HdW~{!Cw&J!rke zrQg1sl<~oY5}X z?Wxtfo7I}#9jbNre6@(H96LrYwTw(>eOeU9O` zyVp`vu5DIb>cb_;#2#;DEvp9Fw=SJIofx>RTGM@RBom{mEM4I}pNf_wZ<|o6Hluk; zYaf?ByiVpPev$gxR zjA;5>f0v98sxr=6T6J9<@O4IZ>F``#=0oX{my?5xC9$D97+X7JoMr}NjIHDj##xrJ ziVfI_JsQd~KCwr`*rUDJqkY(;QS8x}*drMW@Ym_Od;;6}pKp$GK2gV545vTy7kXYv zf9-95?xCNV`K3NRTCSRpU7eKlcjvBN6#jvyzU}kh^y8#Ee$&}k;muX}yt$QH_E+E5 zyaQkRRuS)*$n6nc(Ft98#4Zf{&5N2Jd*SJM5M2f?znHZ87+VmR_ClXFNh7>=UKD){ zZ(MlEBh{GDy7!qfP#2Q+^2use$iaEiM&{kG`)6p(U!}C8oDuakY-F4+%;mm0TY2BS zQ+e@oxr2<~W${_LgNtUUkF=@j%NAwSM~I&wZld{76=^#+eOYaUyy;)EhN%7q8{VPT zMDt@R-uyLH+B_Mw&%N$NUof4e)tE^qN13&g# zJ5+4&PUd^)gWalX_e!O9cdD?oyD8tf)cM9_|7>jdan7`STV2r~!?vGM(bQW@lh~d} z`juZM(?7qQOwHo_ZH#r#(7I%Q_m}M1R|S2lOwZ+{LBDd5&s=iO%p*~mN3dHJapn%{ zuw`($S{bLVhv%uf_(9dO8~Y!BN$qQhaSk@lGoe_9@g(5!d|RLDrf;^-N#48gCj;=u zQza!y>Z5|btn-xob-BL2V7n=sN_Ea*?(xFRS7({4&W&`a^UP5fn4d0E-b<8ml6mNb zOgCfdSryLwNJTP#t4arFsxs;=N}ZKwW~z$e4plz<1n=Xllg_A0Y;qO#QjJZnL%(|T zD5qYgWjdJ0(A}N4QvK-ALHi!?M&YZHxnKCC9w}?c<%Q=&<2ZI=g1Jz5f5^H{c!|pl zQf6m9)bp6|5g$iC=9I#DtdLeX{}s{#n>vNeLK|L~E|`OZbhOpreAVR7zv@lO@u;KU z>H@o7C~M7iXoYiyr1R7o@>!jl8H%Q{xy_^A(b|LBw!V;37h37>FVHS4Y2O!kj?mU^ zB45_f*i~t(7X+8JguFBK5rMInXLUcOuVm>f*vt#q%!~BzOZ2nJ_gW+)c>gA-&U5(@6FzG6+9_cRD z(Tri6CVik>G2a|+7|2~|{AuoL?e8*N7-5v2XYsN zX0qPOsJnsB0*8R70iOmg0iF(gGX3K}zk%@`m36y}11aO(xhwJX=%qyS{#=!gM|X*r zJ`Sw{J*$OR%IEfRYXYgHlUxtyFu*M z;9AuqcB?-UiVmh#Z#<%EuuXL-^@XTzBlSR3Y#Da0UhJ9JJjtWLuC=TBHuaMMcw|3u zjXm2t|7ud((c@kwH85xU$e@=@9c6FwgqPB5>@(g@>hdw{+^!MN+b}ZU>ltbGdPh3E zKFT>J-zlV?7G+hAd1p8?SHmMv%+6+oi`H zdh2nA?pbutqI;HdW+`Kqa%U+cV{b^to*o0N9nf{P$dUdp`8FTR=`k&O(g#+%bD(^` z`K<$t+nM<`7aaRuFLNXDb>PNsF@xLzb*OPI-^qZtv_NvkbmnrVc8A zZ5_M@yxQ>eHjdHX(u}vKD38?n=r5v@H$2fyPOV9OOtoTXblSnStV7Z&oVpTk9bB%; z`#+Xw?Y|2>M3;rXhz=uXm^8cLmp0lBKl+8yuRL+!YAU^7&mZ-&pBSW1$QWa-Uz(-g z$Xs>s(>?n?G8 z&bPuZOWU`me{!K!)?8p$X15kD{L<51#HuO1?vI=K>IY{@=oubgu=B$zw>d8T}D0b@{~N3gDB zJt?-of5jJ*{heQ8@4`CVU8^tjd9|(TrY~@YCueuUCvxqYopBy9=WV6N9#pW#DP!zM zvAIpzx9zxBbz-jum#bB@SxfrabFJ8}iu6~{C1kD7d{AF|K6t4Zg1T5m{%ac1)%34+ zbX9sUh>bISDj_tn-Sj81U!9HMGDnRZR0-i3*{@_BU!mv5>(mo@XgDW{p zo7pqC^4rF9Inmv(!*HoX^T!QyGyN?hd=9N(FH%Hv(v@6%XWBI~gLH`l;aIJIu2MO; zT&b=lg`uBPuEQ0m@=Gg8>JFlp*} zPv;%u9ZDQirP%+OyO-%P7RjzvYp^>pnG>+%GVg_{^9VMhH1ihyEXTS6yF0j6RWM&v zk9>*q&PMF(9JO=gMU@$OL$#x8=kVid!|;o$XZQ`(JA7I7?Vh8OyT8O)@*`>p{_^Gn zp?Y-QSNo{8b?uD_#%wuf-`JbRay1v8)yP~kaOrzd8QXgtK@LwTj~(>=Z3yZ89CFVp0q8Hb*Z$^ zuJ1A)h-ZwSr_M%=Z7h>^;f!Hua3N!weLQthA^lI*JhG0FcER54MCUMT=?bBfR*xyW z9%2nYoApzB;}dF5zjkDZ#a)i&GuezQ?D%RkA;%^Xv5Sr z|DIBM|AgpuQuLBKVm@k$&*n^VCU117Tx0atH8MwYrdXxd3)qw$*cAF^J^d`sT-wB% zA(6$lFi*5FN33FwXl0IQi&N0 z@>$N^-qhpf*rcqZ+K>@7`>rvO0sWFQUQ1uVY;=q-Y^!>`FF}~qEuBzgXu%>&QZxWf@-}4T~pVILW+957^rM@y} zJGP@r*VP=AVBYuFd&e%X!M;YCk6mu_^Sit%zhAw2nEvm{m>}Qtz##)q#3%fHYU=kE z=yNsJMeMKqI1Qth;Fgd1;eweTN@advA3%TB`&sG#g?62FiSA#fuj#e2IqyJ!WzNr{ zw40nM>hn8kJMx$?c~s~*XpnPM)-vopqO#^7&r11D$=p)PoLkO%qn+{GBzmHQo;#?w z8*Sd%w0vvy`!{lO^zpj%{?iFrN3i~A5&J^iDsy%(ZC@p8OK3gPw=?9IB`>{}Ll^p6 zl>SzZ-WBN0nJ)9uz#B=k9yuyylQqV^3f{8DU_1q5jk?hF!1;&h!un+w^X?dJqWYV> z=Yfaa^_ah3)V9p-A1lq;p`vFtXCuEaGFYQ`%QuJBJ`a0JQ;+9NJzjJEiB9^gfjyT# z_hj7Zb5POUws!-ttQDzmJx{;a^UuXKOKNT*ZA^bOk1ejLTO3{GD~eSN*R)z)s?wykDc_onWLI=oBF!8Z0hJKVxRhQw|~8noC>da7iw{B9!0W0TX6BaFtLB3`P#TC zL*OhqZaKpx1_*T@4*E|UicB`>~GUYOlAx62F3Qh29% zmKG^nL|$@za&Z0px_K1I&!x3Ec)O?+=KuFyNAl{5i=Z@@DZ^c|QPlAly1dk2ENATA0$H0QuALfsh_hCa5{Zhb= zy!VfT#)-4R%G*YSEAJ?H8;_LN)~(1J26yCr;1YNfj}2DdvqU(2Wzzq4S|;9>?@%5V z>MdpbvE`^RG|Bg6U{~G|ObAa9th{5y7+7exhz!wB${~G8Xd>@T-j2LzFL)h~4OZSS zh;aGFz^g11Z_D?Oz%Jjbpi&ka3}2|62#4>6)8MaJCf=6M_Ax`cWi>!0kCbBpkML2B zkl>EI8=u2&Tp-Q{D{l!A1{TsSDUwM)mGqzBvGVQ%cH~uzf(xGwR^I1{aOB;(6C8cC zJhAas-owDIyhGqo9vh5|kkr3{g>>sMf2_QPh9>2G9N3j7ePAkioXQl)lX6&jiwsTV zeHYl3cM`ml#|Eq43q-j3Jp(RnDfRa$Llb$lyDRTwbv{b0AFRB;26ghC3!iE+Jo2)9 zzXEpolHl^#VEO)m2v@&xa9iHRh6Y|D_n}3e^asM+3;eNjyF`c#=p_~YTZJSNzDxX( zHn+j#RU&dkp6E}QCw5Nyrwu}rM{ID3jfAfUv@wrs9zliI3?+*|FaG7U=04{A51n}a!{k?xY*+$fX4y^0DOKC{_!GwK@l!?EC{3*I}`+P=|4dL7dsFH za2dxz0Iv-Y0C3aC{aA1rS3v+@8Xy4R^+otC;1Ah2>BNLS|E0!1jUJ#r~Jk<5jy58-Q<<#d9I4Z7tsMk15{|kK1AL{7g z&_z64x~6npK>^u(>x|ynCmn5i3{#i(S$}V?>Fc(vTe?JbZ(85OQIKTu>p7|$0iW44 zmBaZ`_2sU8XHetSswAtUu@z_C|3Z}76E*o zC7&%z7*k~7F{fOV_f{L9%;zinHk+?{0kdX#(An0TSHaJEn0T)m(`9*9=jD67tWzux z`rKyV&^c}e7+BVwHok=Rvaq5)ZCPZ_4B(SWC2U^EUv6Rav~??UqU|S&ye#Zd4*?v@ z^LtGWoO0l!4m_Dp8zQZh6Kct~OK43VE}=eew`Cm9*FzW{TPNWQc{$VS9QZ3N6V2Li z+8$u^mN0EpsTD@%v{O!;SLPx8Gj0E zk8!W;z=EXtp0z8TnMla}ez~8Q{>IzM+HdfE_|q!V(9K=3{s*F@sqDYgzu%RbTX3)I zqVS2l^fx9x-@ot+(bOz_m5Ag1Ksf!=FGLeNa-)(j<)}3GW_*8vDZb@NJ?c9O{aR1C z;}({0@U%&ox|91Hl~TrclQYcS94kwI!$%IXPpwQ0au4ip zDd&7OWAsPLYkTDf%ecFCNq!4OzV*9w>1U(di-tZaVpPieIL*srZ~AyCU_hspIUO&$sQwm(;&IchTNqT{Xy^0mCEt zr%HnRb(chr>0AHL`;=1mr_J}#%G67Xv`-&ny_|kqp?xurQx<$NX_IPcM;RY{_vK!z zs-`}xr9X|lMO{;$jN@{?3yU90j5-edTdmKew1dbXo%NX<*Z!l@*5m(M?gdo`vZj!O zuBVKy)sC()bgh)WgOsGw6KK=-hn$dzW(mP5gST?%C!* z_aoQPIs)2gG0iD+=Kcrp6MY0fQT#)-pXlR%t?z%PN4YB_x?9~k-uXUgHM5@I$BtbX z=}1hbUgR#o@#ct>f8*YnV;b=GM#&ockm5;J$Hd_QstTH_}OsxWcUeHJ$#0H+32;qS;g_SY1%!X`^orq z$hUsdVX-7wx7Z~uUdnb(9*+K4+xNiFBQ-;0V&X@jZi-@pH&p3!~qnD!CgNBZi< z%m*$=dhz8HKTeS$=^KA~p-k#g--pRgNI#Z7u4+G~`*eHaF|}sVfe-wz^qcrrd_Q+Y zWNCj;k>$!kA6E|d%Z^gcRq2)F$32`?uPojnWf42coI57GzRxY~!#y)o&QjgCp1{A( zOPto_{_f3D>fw~tSIQu|>UKUhIV5t#?+4y`>A#jwc(lJ2J^@m9_$hFI$@p7s7k{fO zRf`_O-)dapZ{JdW>L0EaQIMB=t4fn82s%0ex5feEP8qvL;nJz4Gmosn^nY z%Kx1;sqa*m_%J5kY(93SU6<3ezuUhD=VJqzhtkh}J5_wtXBPT%`x47>)MK}H1lg2W3ib{c=~7TrhstL{$L z4(Tyc-Oo5`h_OyytLnJF+EncCAZbNLe^pB>dw@F0k2|kT@W)dT{5;Z(#aC{Ra(}KT z_4C`K{de(fJFP_remxq{GLfX*X%`?O2JgM-O8RJAo|fB1=7(HPDoM8JRci z7_80e`)cCPlEHUH${bdAC3OOi+doVkzU1^_@#i09OdQZ@OdFSopN=Uv zI=+?I#eONyp0ZE>rpmm;A^KuCdl0+3PJDGjdXCa`#=6jm_v7#_pg!>pXMH2-xesjU z{+zc@_ZjhH>GS(w;xND4$DLc==tsTD+)*ul{oJv&zAF*dePy(9^qtnYwaBH->WbT$ zIO}gO_dxsbGpMAW1$`lvWL`14Xc@9k~~%FONCmO&Kf96Q}9(JN@x8d6B-O?Iw9| zkbVRGr1TSPdy~jDX~v{KQ3j8GA7WhSbr!rA#g-6f?fJfb>(_Wjb;|mBPY3>tgDT$N z#_!BLp_=+{xjVV%IOXtEOMm$a`5m5Bsh{w>GR^p3{R)4W4*W_7@kP{ru=wxPU(;GNR%_oP*3VB4QWWh@MQ;W6z?uxBlf3iu-rtQgTcH)TQ|cwhTY`aCvE z%ILRM$z0P`P8@g2{q~z~`N$__;`AC=(h`?3akKJ#l;5|BdQEQngS5TaNxgZ<4qgzN(50%GfLMnR$ulNON;46KfTE^Bz?>@V92}hfmJK`ZwMcm9v_CvsDe} zLFdiy!Bh=A3*Y^!M%tD6zAsgt=S|K2{PUW3zwTpIvL3vRE4l%1)a89t^U`no=2^I&*VB&@^rNO>{KI%w(kJP& zi9^goJ#vmP$oP@@dk5o*aa7+w$nVQAPIoXy8B+hPW%n+O-O6~23|7#ee$F~>jVkT`$}kF-i2P~(g%LVcq%C0 zl?yICeFwg|h4fR2J)x8S?-Pag4K8QQ(?@LoVLcm>{#4wLSOcA~eX02mLZ!f7<6DWn z^sQlO?@z}V3*D^A*q`lq3!8z@66^6XvB&qlo|%h35`8;#F7U~km)L9lv5>LP`eFf( z4!y{p^{aX;#L_8#=K>opYYxe0*HO+PpfN|DZyZ!JZabqsDDmH#t7f%r|FdPnx2{}; z^nT6Q{*BPn>iFyTm%p+s-SC6t!6xw0BYK_{eU`_>5A43=x`yO1`3HK9EKiJzZUy?d zy1bazB@1t3hWX_TW0$=eIz=Qdy=~(8`y0Z`)-|A$q?O<8FlE^oLyy>xUT038d4B`C zHU3pHojmh=<0$j?f!qoCE^*%*Ut4C=$TtZ)pUHQLlsfae=6U^&WdlF_PEzRNBPQ}w zbC5-Tk9R0-Q-vS_a9Vv{QT zJ>+Ha#R)OiLjG9$rwZu@z}5J2jWsO1w36|MuN8g1$R0a$fwsr&4||u7Q(qJGqo2z9 zEQtVk*8GW$h@cs~=Aek!}3x&MmFLtHe=l#`b zc>R6Bu`BV+ag~xji|(zm7UJDDaN;{j-m6pNS9?>_mn1W1I2!ZRPUee9>J@w?7h-1; zzTcSapIEcWoG<0yK)KH{{;@~D8jiR7`|h4~FD5pu``JCxKUr5r?7nEQL;uE5HE9)R zpb_x;VNX>6mjcIuW58wjoBuuUDD@p7t`gXvN7++ggS9W8*kSX1;GD?Fke0Wc5mfS) zamx9onWv$Xu3YTDq?0pnXWdpU>o(SBWoEBdY0m2FN9Gs(9>sBfD`}A5w%VcIq)w|F z$-`fFg_<a~=c zucTq$xSBJB7fgD+4w7}Z$e{k}&F`_*?HB=1u>b zrT@JtmykXiKdOA6Y{r}DC1Xv>m`1N=epgM(Y|@uWU9h)s)&$e1$zDL_mx48c?8Bbq z_ljO(elv8&w#+~N{HN*suG{tLuUUHLt;FGi`Oi=P!n@G-TDqj2V$aow+~-6;%?D5F zl~;@RZT=i-%1|(e`8w43=Z#mZq%QUEZisE0(pFpz`}KHbGW$~E1vxA8`{~SLq-NS-ZpR9 zUd+JdtzuumAThLSd;wizu`eJrx$IToJ!azEauIdS{}ORry&&rgU%`J1k$)?4J$eyQ zR4DvsBZY~J=~JoerY{n2{Ma7cy0wP-@7Y?jwEkB9p+V9AH!vt=ac-ggS}tk&Ua`lJ zFn3}K@7WSBGzr`f)i5)n4*qQugYdF^|JpujD~xQbA68#+w_YJCisIqPIEt&k|>Yk>UL=5e61gT{VA%Pvl9v z2uHT z%+SC?oGcZ{OVA!tH#QgLDFdBp$0+Iqlw ze?}gi05%AZ1bLf01+6+yvT=Z$c|O4-`AR*_cG@RwO@v4Ev-*9O68spM4)jx8_yAMMY z2bgQ<5>vdTSgMS}4yAKkW43f4z{oQGF@4<+bt!gkzT{##|EzzBD9udU+xzv>{XSvm zA;yfov+q^qVO7mEVtINUxZZ&?4m|3>M;!QkJ}mf|Jte-@cG_w41d5g=D_0)JduZGUt@h=N>=4{DCuzTR=%0it4J~ZSN_~IPR z!(MN`&b^)awB9}ke$Ii>)5`Z=bKr9hJeh|>We!~Fz_gu}6QW!J-0r~Ca}dAFfhkK6 z@90xPS!~^g$=CWSg%3ILCmi@}9-bC<;7SKx>A;;1ywiaXcn5n!!zm~nDSaXGh-|dM=J956RC6H+gLgneImC58+{_* zGx6Y&Uzm7-FYucUrYtj~c|Wb0F@A!;#H*E#A5SG)2OHm>?_=sUXN=G;!FVZm;FI|} ad{5(uK4aTD)Z@Uz4tzKdmrx$RKl~qPB@-e5 diff --git a/source/ZipFile.h b/source/ZipFile.h index 980e0471..734a7617 100644 --- a/source/ZipFile.h +++ b/source/ZipFile.h @@ -28,9 +28,10 @@ #ifndef _ZIPFILE_H_ #define _ZIPFILE_H_ -#include #include +#include "utils/unzip.h" + typedef struct { u64 offset; // ZipFile offset diff --git a/source/homebrewboot/HomebrewBrowser.cpp b/source/homebrewboot/HomebrewBrowser.cpp index b33167e1..03c1bb13 100644 --- a/source/homebrewboot/HomebrewBrowser.cpp +++ b/source/homebrewboot/HomebrewBrowser.cpp @@ -420,7 +420,7 @@ int HomebrewBrowser::ReceiveFile() } extractZip(uf, 0, 1, 0, Settings.homebrewapps_path); - unzCloseCurrentFile(uf); + unzClose(uf); remove(zippath); diff --git a/source/utils/crypt.h b/source/utils/crypt.h new file mode 100644 index 00000000..89e599ec --- /dev/null +++ b/source/utils/crypt.h @@ -0,0 +1,132 @@ +/* crypt.h -- base code for crypt/uncrypt ZIPfile + + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This code is a modified version of crypting code in Infozip distribution + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + If you don't need crypting in your application, just define symbols + NOCRYPT and NOUNCRYPT. + + This code support the "Traditional PKWARE Encryption". + + The new AES encryption added on Zip format by Winzip (see the page + http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong + Encryption is not supported. +*/ + +#define CRC32(c, b) ((*(pcrc_32_tab + (((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) + +/*********************************************************************** + * Return the next byte in the pseudo-random sequence + */ +static int decrypt_byte(unsigned long *pkeys, const z_crc_t *pcrc_32_tab) +{ + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an + * unpredictable manner on 16-bit systems; not a problem + * with any known compiler so far, though */ + + temp = ((unsigned)(*(pkeys + 2)) & 0xffff) | 2; + return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); +} + +/*********************************************************************** + * Update the encryption keys with the next byte of plain text + */ +static int update_keys(unsigned long *pkeys, const z_crc_t *pcrc_32_tab, int c) +{ + (*(pkeys + 0)) = CRC32((*(pkeys + 0)), c); + (*(pkeys + 1)) += (*(pkeys + 0)) & 0xff; + (*(pkeys + 1)) = (*(pkeys + 1)) * 134775813L + 1; + { + register int keyshift = (int)((*(pkeys + 1)) >> 24); + (*(pkeys + 2)) = CRC32((*(pkeys + 2)), keyshift); + } + return c; +} + +/*********************************************************************** + * Initialize the encryption keys and the random header according to + * the given password. + */ +static void init_keys(const char *passwd, unsigned long *pkeys, const z_crc_t *pcrc_32_tab) +{ + *(pkeys + 0) = 305419896L; + *(pkeys + 1) = 591751049L; + *(pkeys + 2) = 878082192L; + while (*passwd != '\0') + { + update_keys(pkeys, pcrc_32_tab, (int)*passwd); + passwd++; + } +} + +#define zdecode(pkeys, pcrc_32_tab, c) \ + (update_keys(pkeys, pcrc_32_tab, c ^= decrypt_byte(pkeys, pcrc_32_tab))) + +#define zencode(pkeys, pcrc_32_tab, c, t) \ + (t = decrypt_byte(pkeys, pcrc_32_tab), update_keys(pkeys, pcrc_32_tab, c), t ^ (c)) + +#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED + +#define RAND_HEAD_LEN 12 +/* "last resort" source for second part of crypt seed pattern */ +#ifndef ZCR_SEED2 +#define ZCR_SEED2 3141592654UL /* use PI as default pattern */ +#endif + +static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting) + const char *passwd; /* password string */ +unsigned char *buf; /* where to write header */ +int bufSize; +unsigned long *pkeys; +const unsigned long *pcrc_32_tab; +unsigned long crcForCrypting; +{ + int n; /* index in random header */ + int t; /* temporary */ + int c; /* random byte */ + unsigned char header[RAND_HEAD_LEN - 2]; /* random header */ + static unsigned calls = 0; /* ensure different random header each time */ + + if (bufSize < RAND_HEAD_LEN) + return 0; + + /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the + * output of rand() to get less predictability, since rand() is + * often poorly implemented. + */ + if (++calls == 1) + { + srand((unsigned)(time(NULL) ^ ZCR_SEED2)); + } + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN - 2; n++) + { + c = (rand() >> 7) & 0xff; + header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); + } + /* Encrypt random header (last two bytes is high word of crc) */ + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN - 2; n++) + { + buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); + } + buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); + buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); + return n; +} + +#endif diff --git a/source/utils/ioapi.c b/source/utils/ioapi.c new file mode 100644 index 00000000..5428f9d5 --- /dev/null +++ b/source/utils/ioapi.c @@ -0,0 +1,129 @@ +/* ioapi.c -- IO base function header for compress/uncompress .zip + files using zlib + zip or unzip API + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant +*/ + +#include +#include +#include + +#include "zlib.h" +#include "ioapi.h" + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char *filename, int mode)); + +uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void *buf, uLong size)); + +uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void *buf, uLong size)); + +long ZCALLBACK ftell_file_func OF((voidpf opaque, voidpf stream)); + +long ZCALLBACK fseek_file_func OF((voidpf opaque, voidpf stream, uLong offset, int origin)); + +int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); + +int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); + +voidpf ZCALLBACK fopen_file_func(voidpf opaque, const char *filename, int mode) +{ + FILE *file = NULL; + const char *mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename != NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + +uLong ZCALLBACK fread_file_func(voidpf opaque, voidpf stream, void *buf, uLong size) +{ + uLong ret; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +uLong ZCALLBACK fwrite_file_func(voidpf opaque, voidpf stream, const void *buf, uLong size) +{ + uLong ret; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +long ZCALLBACK ftell_file_func(voidpf opaque, voidpf stream) +{ + long ret; + ret = ftell((FILE *)stream); + return ret; +} + +long ZCALLBACK fseek_file_func(voidpf opaque, voidpf stream, uLong offset, int origin) +{ + int fseek_origin = 0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR: + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END: + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET: + fseek_origin = SEEK_SET; + break; + default: + return -1; + } + ret = 0; + fseek((FILE *)stream, offset, fseek_origin); + return ret; +} + +int ZCALLBACK fclose_file_func(voidpf opaque, voidpf stream) +{ + int ret; + ret = fclose((FILE *)stream); + return ret; +} + +int ZCALLBACK ferror_file_func(voidpf opaque, voidpf stream) +{ + int ret; + ret = ferror((FILE *)stream); + return ret; +} + +void fill_fopen_filefunc(pzlib_filefunc_def) + zlib_filefunc_def *pzlib_filefunc_def; +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/source/utils/ioapi.h b/source/utils/ioapi.h new file mode 100644 index 00000000..8b9c6648 --- /dev/null +++ b/source/utils/ioapi.h @@ -0,0 +1,70 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + files using zlib + zip or unzip API + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant +*/ + +#ifndef _ZLIBIOAPI_H +#define _ZLIBIOAPI_H + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + +#ifndef ZCALLBACK + +#if (defined(WIN32) || defined(WINDOWS) || defined(_WINDOWS)) && defined(CALLBACK) && defined(USEWINDOWS_CALLBACK) +#define ZCALLBACK CALLBACK +#else +#define ZCALLBACK +#endif +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef voidpf(ZCALLBACK *open_file_func) OF((voidpf opaque, const char *filename, int mode)); + typedef uLong(ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void *buf, uLong size)); + typedef uLong(ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void *buf, uLong size)); + typedef long(ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); + typedef long(ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); + typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); + typedef int(ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); + + typedef struct zlib_filefunc_def_s + { + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; + } zlib_filefunc_def; + + void fill_fopen_filefunc OF((zlib_filefunc_def * pzlib_filefunc_def)); + +#define ZREAD(filefunc, filestream, buf, size) ((*((filefunc).zread_file))((filefunc).opaque, filestream, buf, size)) +#define ZWRITE(filefunc, filestream, buf, size) ((*((filefunc).zwrite_file))((filefunc).opaque, filestream, buf, size)) +#define ZTELL(filefunc, filestream) ((*((filefunc).ztell_file))((filefunc).opaque, filestream)) +#define ZSEEK(filefunc, filestream, pos, mode) ((*((filefunc).zseek_file))((filefunc).opaque, filestream, pos, mode)) +#define ZCLOSE(filefunc, filestream) ((*((filefunc).zclose_file))((filefunc).opaque, filestream)) +#define ZERROR(filefunc, filestream) ((*((filefunc).zerror_file))((filefunc).opaque, filestream)) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/utils/minizip/miniunz.c b/source/utils/minizip/miniunz.c index 65e8bcfd..5776747a 100644 --- a/source/utils/minizip/miniunz.c +++ b/source/utils/minizip/miniunz.c @@ -11,8 +11,8 @@ #include #include #include -# include -# include +#include +#include #include "miniunz.h" @@ -20,7 +20,7 @@ #define WRITEBUFFERSIZE (8192) #define MAXFILENAME (256) -static int mymkdir(const char* dirname) +static int mymkdir(const char *dirname) { int ret = 0; ret = mkdir(dirname, 0775); @@ -31,17 +31,17 @@ int makedir(char *newdir) { char *buffer; char *p; - int len = (int) strlen(newdir); + int len = (int)strlen(newdir); - if (len <= 0) return 0; + if (len <= 0) + return 0; - buffer = (char*) malloc(len + 1); + buffer = (char *)malloc(len + 1); strcpy(buffer, newdir); if (buffer[len - 1] == '/') - { buffer[len - 1] = '\0'; - } + if (mymkdir(buffer) == 0) { free(buffer); @@ -59,11 +59,12 @@ int makedir(char *newdir) *p = 0; if ((mymkdir(buffer) == -1) && (errno == ENOENT)) { - // printf("couldn't create directory %s\n",buffer); + //printf("couldn't create directory %s\n", buffer); free(buffer); return 0; } - if (hold == 0) break; + if (hold == 0) + break; *p++ = hold; } free(buffer); @@ -72,7 +73,7 @@ int makedir(char *newdir) static char *fullfilename(const char *basedir, char *filename) { - char *file = (char *) malloc(strlen(basedir) + strlen(filename) + 1); + char *file = (char *)malloc(strlen(basedir) + strlen(filename) + 1); if (basedir == NULL) { strcpy(file, filename); @@ -80,27 +81,22 @@ static char *fullfilename(const char *basedir, char *filename) else { if (basedir[strlen(basedir) - 1] == '/') - { sprintf(file, "%s%s", basedir, filename); - } else - { sprintf(file, "%s/%s", basedir, filename); - } } return file; } -static int do_extract_currentfile(unzFile uf, const int* popt_extract_without_path, int* popt_overwrite, - const char* password, const char *basedir) +static int do_extract_currentfile(unzFile uf, const int *popt_extract_without_path, int *popt_overwrite, const char *password, const char *basedir) { char filename_inzip[256]; - char* filename_withoutpath; - char* filename_withpath; - char* p; + char *filename_withoutpath; + char *filename_withpath; + char *p; int err = UNZ_OK; FILE *fout = NULL; - void* buf; + void *buf; uInt size_buf; unz_file_info file_info; @@ -108,15 +104,15 @@ static int do_extract_currentfile(unzFile uf, const int* popt_extract_without_pa if (err != UNZ_OK) { - // printf("error %d with zipfile in unzGetCurrentFileInfo\n",err); + //printf("error %d with zipfile in unzGetCurrentFileInfo\n", err); return err; } size_buf = WRITEBUFFERSIZE; - buf = (void*) malloc(size_buf); + buf = (void *)malloc(size_buf); if (buf == NULL) { - // printf("Error allocating memory\n"); + //printf("Error allocating memory\n"); return UNZ_INTERNALERROR; } @@ -124,7 +120,8 @@ static int do_extract_currentfile(unzFile uf, const int* popt_extract_without_pa filename_withpath = fullfilename(basedir, filename_inzip); while ((*p) != '\0') { - if (((*p) == '/') || ((*p) == '\\')) filename_withoutpath = p + 1; + if (((*p) == '/') || ((*p) == '\\')) + filename_withoutpath = p + 1; p++; } @@ -139,7 +136,7 @@ static int do_extract_currentfile(unzFile uf, const int* popt_extract_without_pa char *ptr = strstr(path, filename_withoutpath); *ptr = '\0'; - // printf("creating directory: %s\n",path); + //printf("creating directory: %s\n", path); mymkdir(path); free(path); @@ -147,46 +144,51 @@ static int do_extract_currentfile(unzFile uf, const int* popt_extract_without_pa } else { - char* write_filename; + char *write_filename; int skip = 0; if ((*popt_extract_without_path) == 0) write_filename = filename_withpath; - else write_filename = filename_withoutpath; + else + write_filename = filename_withoutpath; err = unzOpenCurrentFilePassword(uf, password); - if (err != UNZ_OK) + /*if (err != UNZ_OK) { - // printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err); - } + printf("error %d with zipfile in unzOpenCurrentFilePassword\n", err); + }*/ if (((*popt_overwrite) == 0) && (err == UNZ_OK)) { - char rep = 0; - FILE* ftestexist; + //char rep = 0; + char rep = 'A'; + FILE *ftestexist; ftestexist = fopen(write_filename, "rb"); if (ftestexist != NULL) { fclose(ftestexist); - do + /*do { char answer[128]; int ret; - // printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename); + printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ", write_filename); ret = scanf("%1s", answer); if (ret != 1) { exit(EXIT_FAILURE); } rep = answer[0]; - if ((rep >= 'a') && (rep <= 'z')) rep -= 0x20; - } while ((rep != 'Y') && (rep != 'N') && (rep != 'A')); + if ((rep >= 'a') && (rep <= 'z')) + rep -= 0x20; + } while ((rep != 'Y') && (rep != 'N') && (rep != 'A'));*/ } - if (rep == 'N') skip = 1; + if (rep == 'N') + skip = 1; - if (rep == 'A') *popt_overwrite = 1; + if (rep == 'A') + *popt_overwrite = 1; } if ((skip == 0) && (err == UNZ_OK)) @@ -194,8 +196,7 @@ static int do_extract_currentfile(unzFile uf, const int* popt_extract_without_pa fout = fopen(write_filename, "wb"); /* some zipfile don't contain directory alone before file */ - if ((fout == NULL) && ((*popt_extract_without_path) == 0) && (filename_withoutpath - != (char*) filename_inzip)) + if ((fout == NULL) && ((*popt_extract_without_path) == 0) && (filename_withoutpath != (char *)filename_inzip)) { char c = *(filename_withoutpath - 1); *(filename_withoutpath - 1) = '\0'; @@ -212,51 +213,53 @@ static int do_extract_currentfile(unzFile uf, const int* popt_extract_without_pa fout = fopen(write_filename, "wb"); } - if (fout == NULL) + /*if (fout == NULL) { - // printf("error opening %s\n",write_filename); - } + printf("error opening %s\n", write_filename); + }*/ } if (fout != NULL) { - // printf(" extracting: %s\n",write_filename); + //printf("extracting: %s\n", write_filename); do { err = unzReadCurrentFile(uf, buf, size_buf); if (err < 0) { - // printf("error %d with zipfile in unzReadCurrentFile\n",err); - break; - } - if (err > 0) if (fwrite(buf, err, 1, fout) != 1) - { - // printf("error in writing extracted file\n"); - err = UNZ_ERRNO; + //printf("error %d with zipfile in unzReadCurrentFile\n", err); break; } + if (err > 0) + if (fwrite(buf, err, 1, fout) != 1) + { + //printf("error in writing extracted file\n"); + err = UNZ_ERRNO; + break; + } } while (err > 0); - if (fout) fclose(fout); - + if (fout) + fclose(fout); } if (err == UNZ_OK) { err = unzCloseCurrentFile(uf); - if (err != UNZ_OK) + /*if (err != UNZ_OK) { - // printf("error %d with zipfile in unzCloseCurrentFile\n",err); - } + printf("error %d with zipfile in unzCloseCurrentFile\n", err); + }*/ } - else unzCloseCurrentFile(uf); /* don't lose the error */ + else + unzCloseCurrentFile(uf); /* don't lose the error */ } free(filename_withpath); free(buf); return err; } -int extractZip(unzFile uf, int opt_extract_without_path, int opt_overwrite, const char* password, const char *basedir) +int extractZip(unzFile uf, int opt_extract_without_path, int opt_overwrite, const char *password, const char *basedir) { uLong i; unz_global_info gi; @@ -264,18 +267,22 @@ int extractZip(unzFile uf, int opt_extract_without_path, int opt_overwrite, cons err = unzGetGlobalInfo(uf, &gi); if (err != UNZ_OK) - // printf("error %d with zipfile in unzGetGlobalInfo \n",err); + { + //printf("error %d with zipfile in unzGetGlobalInfo \n", err); + return -1; + } for (i = 0; i < gi.number_entry; i++) { - if (do_extract_currentfile(uf, &opt_extract_without_path, &opt_overwrite, password, basedir) != UNZ_OK) break; + if (do_extract_currentfile(uf, &opt_extract_without_path, &opt_overwrite, password, basedir) != UNZ_OK) + break; if ((i + 1) < gi.number_entry) { err = unzGoToNextFile(uf); if (err != UNZ_OK) { - // printf("error %d with zipfile in unzGoToNextFile\n",err); + //printf("error %d with zipfile in unzGoToNextFile\n", err); break; } } @@ -284,16 +291,16 @@ int extractZip(unzFile uf, int opt_extract_without_path, int opt_overwrite, cons return 0; } -int extractZipOnefile(unzFile uf, const char* filename, int opt_extract_without_path, int opt_overwrite, - const char* password) +int extractZipOnefile(unzFile uf, const char *filename, int opt_extract_without_path, int opt_overwrite, const char *password) { if (unzLocateFile(uf, filename, CASESENSITIVITY) != UNZ_OK) { - // printf("file %s not found in the zipfile\n",filename); + //printf("file %s not found in the zipfile\n", filename); return 2; } if (do_extract_currentfile(uf, &opt_extract_without_path, &opt_overwrite, password, NULL) == UNZ_OK) return 0; - else return 1; + else + return 1; } diff --git a/source/utils/minizip/miniunz.h b/source/utils/minizip/miniunz.h index 3120617a..b4d218e7 100644 --- a/source/utils/minizip/miniunz.h +++ b/source/utils/minizip/miniunz.h @@ -6,12 +6,10 @@ extern "C" { #endif -#include +#include "utils/unzip.h" - int extractZip(unzFile uf, int opt_extract_without_path, int opt_overwrite, const char* password, - const char *basedir); - int extractZipOnefile(unzFile uf, const char* filename, int opt_extract_without_path, int opt_overwrite, - const char* password); + int extractZip(unzFile uf, int opt_extract_without_path, int opt_overwrite, const char *password, const char *basedir); + int extractZipOnefile(unzFile uf, const char *filename, int opt_extract_without_path, int opt_overwrite, const char *password); int makedir(char *newdir); #ifdef __cplusplus diff --git a/source/utils/unzip.c b/source/utils/unzip.c new file mode 100644 index 00000000..285cc2e0 --- /dev/null +++ b/source/utils/unzip.c @@ -0,0 +1,1409 @@ +/* unzip.c -- IO for uncompress .zip files using zlib + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + Read unzip.h for more info + */ + +/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of + compatibility with older software. The following is from the original crypt.c. Code + woven in by Terry Thorsen 1/2003. + */ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html + */ +/* + crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + */ + +/* + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + */ + +#include +#include +#include +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC +#include +#include +#include +#endif +#ifdef NO_ERRNO_H +extern int errno; +#else +#include +#endif + +#ifndef local +#define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +#ifndef CASESENSITIVITYDEFAULT_NO +#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) +#define CASESENSITIVITYDEFAULT_NO +#endif +#endif + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +#define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +#define TRYFREE(p) \ + { \ + if (p) \ + free(p); \ + } +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + +const char unz_copyright[] = " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info_internal_s +{ + uLong offset_curfile; /* relative offset of local header 4 bytes */ +} unz_file_info_internal; + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + + uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + uLong offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ + uLong pos_local_extrafield; /* position in the local extra field in read*/ + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + uLong rest_read_compressed; /* number of byte to be decompressed */ + uLong rest_read_uncompressed; /*number of byte to be obtained after decomp*/ + zlib_filefunc_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + uLong byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx)*/ + int raw; +} file_in_zip_read_info_s; + +/* unz_s contain internal information about the zipfile */ +typedef struct +{ + zlib_filefunc_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + unz_global_info gi; /* public global information */ + uLong byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx)*/ + uLong num_file; /* number of the current file in the zipfile*/ + uLong pos_in_central_dir; /* pos of the current file in the central dir*/ + uLong current_file_ok; /* flag about the usability of the current file*/ + uLong central_pos; /* position of the beginning of the central dir*/ + + uLong size_central_dir; /* size of the central directory */ + uLong offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info cur_file_info; /* public info about the current file in zip*/ + unz_file_info_internal cur_file_info_internal; /* private info about it*/ + file_in_zip_read_info_s *pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ + int encrypted; +#ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const z_crc_t *pcrc_32_tab; +#endif +} unz_s; + +#ifndef NOUNCRYPT +#include "crypt.h" +#endif + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. + */ + +local int unzlocal_getByte OF((const zlib_filefunc_def *pzlib_filefunc_def, voidpf filestream, int *pi)); + +local int unzlocal_getByte(const zlib_filefunc_def *pzlib_filefunc_def, voidpf filestream, int *pi) +{ + unsigned char c; + int err = (int)ZREAD(*pzlib_filefunc_def, filestream, &c, 1); + if (err == 1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ZERROR(*pzlib_filefunc_def, filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets + */ +local int unzlocal_getShort OF((const zlib_filefunc_def *pzlib_filefunc_def, voidpf filestream, uLong *pX)); + +local int unzlocal_getShort(const zlib_filefunc_def *pzlib_filefunc_def, voidpf filestream, uLong *pX) +{ + uLong x; + int i = 0; + int err; + + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + x = (uLong)i; + + if (err == UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + x += ((uLong)i) << 8; + + if (err == UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unzlocal_getLong OF((const zlib_filefunc_def *pzlib_filefunc_def, voidpf filestream, uLong *pX)); + +local int unzlocal_getLong(const zlib_filefunc_def *pzlib_filefunc_def, voidpf filestream, uLong *pX) +{ + uLong x; + int i = 0; + int err; + + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + x = (uLong)i; + + if (err == UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + x += ((uLong)i) << 8; + + if (err == UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + x += ((uLong)i) << 16; + + if (err == UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + x += ((uLong)i) << 24; + + if (err == UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal(const char *fileName1, const char *fileName2) +{ + for (;;) + { + char c1 = *(fileName1++); + char c2 = *(fileName2++); + if ((c1 >= 'a') && (c1 <= 'z')) + c1 -= 0x20; + if ((c2 >= 'a') && (c2 <= 'z')) + c2 -= 0x20; + if (c1 == '\0') + return ((c2 == '\0') ? 0 : -1); + if (c2 == '\0') + return 1; + if (c1 < c2) + return -1; + if (c1 > c2) + return 1; + } +} + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + + */ +extern int ZEXPORT unzStringFileNameCompare(const char *fileName1, const char *fileName2, int iCaseSensitivity) +{ + if (iCaseSensitivity == 0) + iCaseSensitivity = CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity == 1) + return strcmp(fileName1, fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1, fileName2); +} +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) + */ +local uLong unzlocal_SearchCentralDir OF((const zlib_filefunc_def *pzlib_filefunc_def, voidpf filestream)); + +local uLong unzlocal_SearchCentralDir(const zlib_filefunc_def *pzlib_filefunc_def, voidpf filestream) +{ + unsigned char *buf; + uLong uSizeFile; + uLong uBackRead; + uLong uMaxBack = 0xffff; /* maximum size of global comment */ + uLong uPosFound = 0; + + if (ZSEEK(*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + uSizeFile = ZTELL(*pzlib_filefunc_def, filestream); + + if (uMaxBack > uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char *)ALLOC(BUFREADCOMMENT + 4); + if (buf == NULL) + return 0; + + uBackRead = 4; + while (uBackRead < uMaxBack) + { + uLong uReadSize, uReadPos; + int i; + if (uBackRead + BUFREADCOMMENT > uMaxBack) + uBackRead = uMaxBack; + else + uBackRead += BUFREADCOMMENT; + uReadPos = uSizeFile - uBackRead; + + uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos)) ? (BUFREADCOMMENT + 4) : (uSizeFile - uReadPos); + if (ZSEEK(*pzlib_filefunc_def, filestream, uReadPos, ZLIB_FILEFUNC_SEEK_SET) != 0) + break; + + if (ZREAD(*pzlib_filefunc_def, filestream, buf, uReadSize) != uReadSize) + break; + + for (i = (int)uReadSize - 3; (i--) > 0;) + if (((*(buf + i)) == 0x50) && ((*(buf + i + 1)) == 0x4b) && ((*(buf + i + 2)) == 0x05) && ((*(buf + i + 3)) == 0x06)) + { + uPosFound = uReadPos + i; + break; + } + + if (uPosFound != 0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer + "zlib/zlib114.zip". + If the zipfile cannot be opened (file doesn't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. + */ +extern unzFile ZEXPORT unzOpen2(const char *path, zlib_filefunc_def *pzlib_filefunc_def) +{ + unz_s us; + unz_s *s; + uLong central_pos, uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + uLong number_entry_CD; /* total number of entries in + the central dir (same than number_entry on nospan) */ + + int err = UNZ_OK; + + if (unz_copyright[0] != ' ') + return NULL; + + if (pzlib_filefunc_def == NULL) + fill_fopen_filefunc(&us.z_filefunc); + else + us.z_filefunc = *pzlib_filefunc_def; + + us.filestream = (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque, path, ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream == NULL) + return NULL; + + central_pos = unzlocal_SearchCentralDir(&us.z_filefunc, us.filestream); + if (central_pos == 0) + err = UNZ_ERRNO; + + if (ZSEEK(us.z_filefunc, us.filestream, + central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + err = UNZ_ERRNO; + + /* the signature, already checked */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + + /* number of this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &number_disk) != UNZ_OK) + err = UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &number_disk_with_CD) != UNZ_OK) + err = UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &us.gi.number_entry) != UNZ_OK) + err = UNZ_ERRNO; + + /* total number of entries in the central dir */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &number_entry_CD) != UNZ_OK) + err = UNZ_ERRNO; + + if ((number_entry_CD != us.gi.number_entry) || (number_disk_with_CD != 0) || (number_disk != 0)) + err = UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream, &us.size_central_dir) != UNZ_OK) + err = UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream, &us.offset_central_dir) != UNZ_OK) + err = UNZ_ERRNO; + + /* zipfile comment length */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &us.gi.size_comment) != UNZ_OK) + err = UNZ_ERRNO; + + if ((central_pos < us.offset_central_dir + us.size_central_dir) && (err == UNZ_OK)) + err = UNZ_BADZIPFILE; + + if (err != UNZ_OK) + { + ZCLOSE(us.z_filefunc, us.filestream); + return NULL; + } + + us.byte_before_the_zipfile = central_pos - (us.offset_central_dir + us.size_central_dir); + us.central_pos = central_pos; + us.pfile_in_zip_read = NULL; + us.encrypted = 0; + + s = (unz_s *)ALLOC(sizeof(unz_s)); + *s = us; + unzGoToFirstFile((unzFile)s); + return (unzFile)s; +} + +extern unzFile ZEXPORT unzOpen(const char *path) +{ + return unzOpen2(path, NULL); +} + +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzipOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzClose(unzFile file) +{ + unz_s *s; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *)file; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + ZCLOSE(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; +} + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info *pglobal_info) +{ + unz_s *s; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *)file; + *pglobal_info = s->gi; + return UNZ_OK; +} + +/* + Translate date/time from Dos format to tm_unz (readable more easilty) + */ +local void unzlocal_DosDateToTmuDate(uLong ulDosDate, tm_unz *ptm) +{ + uLong uDate; + uDate = (uLong)(ulDosDate >> 16); + ptm->tm_mday = (uInt)(uDate & 0x1f); + ptm->tm_mon = (uInt)((((uDate)&0x1E0) / 0x20) - 1); + ptm->tm_year = (uInt)(((uDate & 0x0FE00) / 0x0200) + 1980); + + ptm->tm_hour = (uInt)((ulDosDate & 0xF800) / 0x800); + ptm->tm_min = (uInt)((ulDosDate & 0x7E0) / 0x20); + ptm->tm_sec = (uInt)(2 * (ulDosDate & 0x1f)); +} + +/* + Get Info about the current file in the zipfile, with internal only info + */ +local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, unz_file_info *pfile_info, + unz_file_info_internal *pfile_info_internal, char *szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)); + +local int unzlocal_GetCurrentFileInfoInternal(unzFile file, unz_file_info *pfile_info, unz_file_info_internal *pfile_info_internal, + char *szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char *szComment, uLong commentBufferSize) +{ + unz_s *s; + unz_file_info file_info; + unz_file_info_internal file_info_internal; + int err = UNZ_OK; + uLong uMagic; + long lSeek = 0; + + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *)file; + if (ZSEEK(s->z_filefunc, s->filestream, + s->pos_in_central_dir + s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET) != 0) + err = UNZ_ERRNO; + + /* we check the magic */ + if (err == UNZ_OK) + { + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK) + err = UNZ_ERRNO; + else if (uMagic != 0x02014b50) + err = UNZ_BADZIPFILE; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.version) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.version_needed) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.flag) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.compression_method) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.dosDate) != UNZ_OK) + err = UNZ_ERRNO; + + unzlocal_DosDateToTmuDate(file_info.dosDate, &file_info.tmu_date); + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.crc) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.compressed_size) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.uncompressed_size) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.size_filename) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.size_file_extra) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.size_file_comment) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.disk_num_start) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.internal_fa) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.external_fa) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info_internal.offset_curfile) != UNZ_OK) + err = UNZ_ERRNO; + + lSeek += file_info.size_filename; + if ((err == UNZ_OK) && (szFileName != NULL)) + { + uLong uSizeRead; + if (file_info.size_filename < fileNameBufferSize) + { + *(szFileName + file_info.size_filename) = '\0'; + uSizeRead = file_info.size_filename; + } + else + uSizeRead = fileNameBufferSize; + + if ((file_info.size_filename > 0) && (fileNameBufferSize > 0)) + if (ZREAD(s->z_filefunc, s->filestream, szFileName, uSizeRead) != uSizeRead) + err = UNZ_ERRNO; + lSeek -= uSizeRead; + } + + if ((err == UNZ_OK) && (extraField != NULL)) + { + uLong uSizeRead; + if (file_info.size_file_extra < extraFieldBufferSize) + uSizeRead = file_info.size_file_extra; + else + uSizeRead = extraFieldBufferSize; + + if (lSeek != 0) + { + if (ZSEEK(s->z_filefunc, s->filestream, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0) + lSeek = 0; + else + err = UNZ_ERRNO; + } + + if ((file_info.size_file_extra > 0) && (extraFieldBufferSize > 0)) + if (ZREAD(s->z_filefunc, s->filestream, extraField, uSizeRead) != uSizeRead) + err = UNZ_ERRNO; + lSeek += file_info.size_file_extra - uSizeRead; + } + else + lSeek += file_info.size_file_extra; + + if ((err == UNZ_OK) && (szComment != NULL)) + { + uLong uSizeRead; + if (file_info.size_file_comment < commentBufferSize) + { + *(szComment + file_info.size_file_comment) = '\0'; + uSizeRead = file_info.size_file_comment; + } + else + uSizeRead = commentBufferSize; + + if (lSeek != 0) + { + if (ZSEEK(s->z_filefunc, s->filestream, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0) + lSeek = 0; + else + err = UNZ_ERRNO; + } + + if ((file_info.size_file_comment > 0) && (commentBufferSize > 0)) + if (ZREAD(s->z_filefunc, s->filestream, szComment, uSizeRead) != uSizeRead) + err = UNZ_ERRNO; + lSeek += file_info.size_file_comment - uSizeRead; + } + else + lSeek += file_info.size_file_comment; + + if ((err == UNZ_OK) && (pfile_info != NULL)) + *pfile_info = file_info; + + if ((err == UNZ_OK) && (pfile_info_internal != NULL)) + *pfile_info_internal = file_info_internal; + + return err; +} + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. + */ +extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, unz_file_info *pfile_info, char *szFileName, uLong fileNameBufferSize, void *extraField, + uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize) +{ + return unzlocal_GetCurrentFileInfoInternal(file, pfile_info, NULL, szFileName, fileNameBufferSize, extraField, + extraFieldBufferSize, szComment, commentBufferSize); +} + +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem + */ +extern int ZEXPORT unzGoToFirstFile(unzFile file) +{ + int err = UNZ_OK; + unz_s *s; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *)file; + s->pos_in_central_dir = s->offset_central_dir; + s->num_file = 0; + err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. + */ +extern int ZEXPORT unzGoToNextFile(unzFile file) +{ + unz_s *s; + int err; + + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file + 1 == s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment; + s->num_file++; + err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found + */ +extern int ZEXPORT unzLocateFile(unzFile file, const char *szFileName, int iCaseSensitivity) +{ + unz_s *s; + int err; + + /* We remember the 'current' position in the file so that we can jump + * back there if we fail. + */ + unz_file_info cur_file_infoSaved; + unz_file_info_internal cur_file_info_internalSaved; + uLong num_fileSaved; + uLong pos_in_central_dirSaved; + + if (file == NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName) >= UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s = (unz_s *)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + /* Save the current state */ + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + cur_file_infoSaved = s->cur_file_info; + cur_file_info_internalSaved = s->cur_file_info_internal; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP + 1]; + err = unzGetCurrentFileInfo(file, NULL, szCurrentFileName, sizeof(szCurrentFileName) - 1, NULL, 0, NULL, 0); + if (err == UNZ_OK) + { + if (unzStringFileNameCompare(szCurrentFileName, szFileName, iCaseSensitivity) == 0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + } + + /* We failed, so restore the state of the 'current file' to where we + * were. + */ + s->num_file = num_fileSaved; + s->pos_in_central_dir = pos_in_central_dirSaved; + s->cur_file_info = cur_file_infoSaved; + s->cur_file_info_internal = cur_file_info_internalSaved; + return err; +} + +/* + /////////////////////////////////////////// + // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) + // I need random access + // + // Further optimization could be realized by adding an ability + // to cache the directory in memory. The goal being a single + // comprehensive file read to put the file I need in a memory. + */ + +/* + typedef struct unz_file_pos_s + { + uLong pos_in_zip_directory; // offset in file + uLong num_of_file; // # of file + } unz_file_pos; + */ + +extern int ZEXPORT unzGetFilePos(unzFile file, unz_file_pos *file_pos) +{ + unz_s *s; + + if (file == NULL || file_pos == NULL) + return UNZ_PARAMERROR; + s = (unz_s *)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + file_pos->pos_in_zip_directory = s->pos_in_central_dir; + file_pos->num_of_file = s->num_file; + + return UNZ_OK; +} + +extern int ZEXPORT unzGoToFilePos(unzFile file, unz_file_pos *file_pos) +{ + unz_s *s; + int err; + + if (file == NULL || file_pos == NULL) + return UNZ_PARAMERROR; + s = (unz_s *)file; + + /* jump to the right spot */ + s->pos_in_central_dir = file_pos->pos_in_zip_directory; + s->num_file = file_pos->num_of_file; + + /* set the current file */ + err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0); + /* return results */ + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + // Unzip Helper Functions - should be here? + /////////////////////////////////////////// + */ + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) + */ +local int unzlocal_CheckCurrentFileCoherencyHeader(unz_s *s, uInt *piSizeVar, uLong *poffset_local_extrafield, uInt *psize_local_extrafield) +{ + uLong uMagic, uData, uFlags; + uLong size_filename; + uLong size_extra_field; + int err = UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK(s->z_filefunc, s->filestream, s->cur_file_info_internal.offset_curfile + s->byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) + return UNZ_ERRNO; + + if (err == UNZ_OK) + { + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK) + err = UNZ_ERRNO; + else if (uMagic != 0x04034b50) + err = UNZ_BADZIPFILE; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) + err = UNZ_ERRNO; + /* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; + */ + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uFlags) != UNZ_OK) + err = UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) + err = UNZ_ERRNO; + else if ((err == UNZ_OK) && (uData != s->cur_file_info.compression_method)) + err = UNZ_BADZIPFILE; + + if ((err == UNZ_OK) && (s->cur_file_info.compression_method != 0) && (s->cur_file_info.compression_method != Z_DEFLATED)) + err = UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) /* date/time */ + err = UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) /* crc */ + err = UNZ_ERRNO; + else if ((err == UNZ_OK) && (uData != s->cur_file_info.crc) && ((uFlags & 8) == 0)) + err = UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) /* size compr */ + err = UNZ_ERRNO; + else if ((err == UNZ_OK) && (uData != s->cur_file_info.compressed_size) && ((uFlags & 8) == 0)) + err = UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) /* size uncompr */ + err = UNZ_ERRNO; + else if ((err == UNZ_OK) && (uData != s->cur_file_info.uncompressed_size) && ((uFlags & 8) == 0)) + err = UNZ_BADZIPFILE; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &size_filename) != UNZ_OK) + err = UNZ_ERRNO; + else if ((err == UNZ_OK) && (size_filename != s->cur_file_info.size_filename)) + err = UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &size_extra_field) != UNZ_OK) + err = UNZ_ERRNO; + *poffset_local_extrafield = s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. + */ +extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int *method, int *level, int raw, const char *password) +{ + int err = UNZ_OK; + uInt iSizeVar; + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + uLong offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ +#ifndef NOUNCRYPT + char source[12]; +#else + if (password != NULL) + return UNZ_PARAMERROR; +#endif + + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unzlocal_CheckCurrentFileCoherencyHeader(s, &iSizeVar, &offset_local_extrafield, &size_local_extrafield) != UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip_read_info_s *)ALLOC(sizeof(file_in_zip_read_info_s)); + if (pfile_in_zip_read_info == NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer = (char *)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield = 0; + pfile_in_zip_read_info->raw = raw; + + if (pfile_in_zip_read_info->read_buffer == NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised = 0; + + if (method != NULL) + *method = (int)s->cur_file_info.compression_method; + + if (level != NULL) + { + *level = 6; + switch (s->cur_file_info.flag & 0x06) + { + case 6: + *level = 1; + break; + case 4: + *level = 2; + break; + case 2: + *level = 9; + break; + } + } + + if ((s->cur_file_info.compression_method != 0) && (s->cur_file_info.compression_method != Z_DEFLATED)) + err = UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait = s->cur_file_info.crc; + pfile_in_zip_read_info->crc32 = 0; + pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream = s->filestream; + pfile_in_zip_read_info->z_filefunc = s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile = s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method == Z_DEFLATED) && (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = (voidpf)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err = inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised = 1; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = s->cur_file_info.compressed_size; + pfile_in_zip_read_info->rest_read_uncompressed = s->cur_file_info.uncompressed_size; + + pfile_in_zip_read_info->pos_in_zipfile = s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + +#ifndef NOUNCRYPT + if (password != NULL) + { + int i; + s->pcrc_32_tab = get_crc_table(); + init_keys(password, s->keys, s->pcrc_32_tab); + if (ZSEEK(s->z_filefunc, s->filestream, + s->pfile_in_zip_read->pos_in_zipfile + + s->pfile_in_zip_read->byte_before_the_zipfile, + SEEK_SET) != 0) + return UNZ_INTERNALERROR; + if (ZREAD(s->z_filefunc, s->filestream, source, 12) < 12) + return UNZ_INTERNALERROR; + + for (i = 0; i < 12; i++) + zdecode(s->keys, s->pcrc_32_tab, source[i]); + + s->pfile_in_zip_read->pos_in_zipfile += 12; + s->encrypted = 1; + } +#endif + + return UNZ_OK; +} + +extern int ZEXPORT unzOpenCurrentFile(unzFile file) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); +} + +extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char *password) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); +} + +extern int ZEXPORT unzOpenCurrentFile2(unzFile file, int *method, int *level, int raw) +{ + return unzOpenCurrentFile3(file, method, level, raw, NULL); +} + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) + */ +extern int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, unsigned len) +{ + int err = UNZ_OK; + uInt iRead = 0; + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + return UNZ_PARAMERROR; + + if ((pfile_in_zip_read_info->read_buffer == NULL)) + return UNZ_END_OF_LIST_OF_FILE; + if (len == 0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef *)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if ((len > pfile_in_zip_read_info->rest_read_uncompressed) && (!(pfile_in_zip_read_info->raw))) + pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + if ((len > pfile_in_zip_read_info->rest_read_compressed + pfile_in_zip_read_info->stream.avail_in) && (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_compressed + pfile_in_zip_read_info->stream.avail_in; + + while (pfile_in_zip_read_info->stream.avail_out > 0) + { + if ((pfile_in_zip_read_info->stream.avail_in == 0) && (pfile_in_zip_read_info->rest_read_compressed > 0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressed < uReadThis) + uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (ZSEEK(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET) != 0) + return UNZ_ERRNO; + if (ZREAD(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer, + uReadThis) != uReadThis) + return UNZ_ERRNO; + +#ifndef NOUNCRYPT + if (s->encrypted) + { + uInt i; + for (i = 0; i < uReadThis; i++) + pfile_in_zip_read_info->read_buffer[i] = zdecode(s->keys, s->pcrc_32_tab, + pfile_in_zip_read_info->read_buffer[i]); + } +#endif + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed -= uReadThis; + + pfile_in_zip_read_info->stream.next_in = (Bytef *)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method == 0) || (pfile_in_zip_read_info->raw)) + { + uInt uDoCopy, i; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && (pfile_in_zip_read_info->rest_read_compressed == 0)) + return (iRead == 0) ? UNZ_EOF : iRead; + + if (pfile_in_zip_read_info->stream.avail_out < pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in; + + for (i = 0; i < uDoCopy; i++) + *(pfile_in_zip_read_info->stream.next_out + i) = *(pfile_in_zip_read_info->stream.next_in + i); + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed -= uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else + { + uLong uTotalOutBefore, uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + int flush = Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err = inflate(&pfile_in_zip_read_info->stream, flush); + + if ((err >= 0) && (pfile_in_zip_read_info->stream.msg != NULL)) + err = Z_DATA_ERROR; + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter - uTotalOutBefore; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, bufBefore, (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err == Z_STREAM_END) + return (iRead == 0) ? UNZ_EOF : iRead; + if (err != Z_OK) + break; + } + } + + if (err == Z_OK) + return iRead; + return err; +} + +/* + Give the current position in uncompressed data + */ +extern z_off_t ZEXPORT unztell(unzFile file) +{ + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + +/* + return 1 if the end of file was reached, 0 elsewhere + */ +extern int ZEXPORT unzeof(unzFile file) +{ + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code + */ +extern int ZEXPORT unzGetLocalExtrafield(unzFile file, voidp buf, unsigned len) +{ + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + uInt read_now; + uLong size_to_read; + + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - pfile_in_zip_read_info->pos_local_extrafield); + + if (buf == NULL) + return (int)size_to_read; + + if (len > size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len; + + if (read_now == 0) + return 0; + + if (ZSEEK(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield, + ZLIB_FILEFUNC_SEEK_SET) != 0) + return UNZ_ERRNO; + + if (ZREAD(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + buf, read_now) != read_now) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good + */ +extern int ZEXPORT unzCloseCurrentFile(unzFile file) +{ + int err = UNZ_OK; + + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + return UNZ_PARAMERROR; + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err = UNZ_CRCERROR; + } + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised) + inflateEnd(&pfile_in_zip_read_info->stream); + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read = NULL; + + return err; +} + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 + */ +extern int ZEXPORT unzGetGlobalComment(unzFile file, char *szComment, uLong uSizeBuf) +{ + unz_s *s; + uLong uReadThis; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *)file; + + uReadThis = uSizeBuf; + if (uReadThis > s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (ZSEEK(s->z_filefunc, s->filestream, s->central_pos + 22, ZLIB_FILEFUNC_SEEK_SET) != 0) + return UNZ_ERRNO; + + if (uReadThis > 0) + { + *szComment = '\0'; + if (ZREAD(s->z_filefunc, s->filestream, szComment, uReadThis) != uReadThis) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment + s->gi.size_comment) = '\0'; + return (int)uReadThis; +} + +/* Additions by RX '2004 */ +extern uLong ZEXPORT unzGetOffset(unzFile file) +{ + unz_s *s; + + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *)file; + if (!s->current_file_ok) + return 0; + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) + if (s->num_file == s->gi.number_entry) + return 0; + return s->pos_in_central_dir; +} + +extern int ZEXPORT unzSetOffset(unzFile file, uLong pos) +{ + unz_s *s; + int err; + + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz_s *)file; + + s->pos_in_central_dir = pos; + s->num_file = s->gi.number_entry; /* hack */ + err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0); + s->current_file_ok = (err == UNZ_OK); + return err; +} diff --git a/source/utils/unzip.h b/source/utils/unzip.h new file mode 100644 index 00000000..ec982ebb --- /dev/null +++ b/source/utils/unzip.h @@ -0,0 +1,320 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g + WinZip, InfoZip tools and compatible. + + Multi volume ZipFile (span) are not supported. + Encryption compatible with pkzip 2.04g only supported + Old compressions used by old PKZip 1.x are not supported + + + I WAIT FEEDBACK at mail info@winimage.com + Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + */ + +/* for more info about .ZIP format, see + http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip + http://www.info-zip.org/pub/infozip/doc/ + PkWare has also a specification at : + ftp://ftp.pkware.com/probdesc.zip + */ + +#ifndef _unz_H +#define _unz_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) + /* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ + typedef struct TagunzFile__ + { + int unused; + } unzFile__; + typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + + /* tm_unz contain date/time info */ + typedef struct tm_unz_s + { + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ + } tm_unz; + + /* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ + typedef struct unz_global_info_s + { + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ + } unz_global_info; + + /* unz_file_info contain information about a file in the zipfile */ + typedef struct unz_file_info_s + { + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; + } unz_file_info; + + extern int ZEXPORT unzStringFileNameCompare OF((const char *fileName1, const char *fileName2, int iCaseSensitivity)); + /* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + */ + + extern unzFile ZEXPORT unzOpen OF((const char *path)); + /* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. + */ + + extern unzFile ZEXPORT unzOpen2 OF((const char *path, zlib_filefunc_def *pzlib_filefunc_def)); + /* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see ioapi.h) + */ + + extern int ZEXPORT unzClose OF((unzFile file)); + /* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + + extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, unz_global_info *pglobal_info)); + /* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + extern int ZEXPORT unzGetGlobalComment OF((unzFile file, char *szComment, uLong uSizeBuf)); + /* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 + */ + + /***************************************************************************/ + /* Unzip package allow you browse the directory of the zipfile */ + + extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); + /* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem + */ + + extern int ZEXPORT unzGoToNextFile OF((unzFile file)); + /* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. + */ + + extern int ZEXPORT unzLocateFile OF((unzFile file, const char *szFileName, int iCaseSensitivity)); + /* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found + */ + + /* ****************************************** */ + /* Ryan supplied functions */ + /* unz_file_info contain information about a file in the zipfile */ + typedef struct unz_file_pos_s + { + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ + } unz_file_pos; + + extern int ZEXPORT unzGetFilePos(unzFile file, unz_file_pos *file_pos); + + extern int ZEXPORT unzGoToFilePos(unzFile file, unz_file_pos *file_pos); + + /* ****************************************** */ + + extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, unz_file_info *pfile_info, char *szFileName, + uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, + char *szComment, uLong commentBufferSize)); + /* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) + */ + + /***************************************************************************/ + /* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + + extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); + /* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. + */ + + extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, const char *password)); + /* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. + */ + + extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, int *method, int *level, int raw)); + /* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL + */ + + extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, int *method, int *level, int raw, const char *password)); + /* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL + */ + + extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); + /* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good + */ + + extern int ZEXPORT unzReadCurrentFile OF((unzFile file, voidp buf, unsigned len)); + /* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) + */ + + extern z_off_t ZEXPORT unztell OF((unzFile file)); + /* + Give the current position in uncompressed data + */ + + extern int ZEXPORT unzeof OF((unzFile file)); + /* + return 1 if the end of file was reached, 0 elsewhere + */ + + extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, voidp buf, unsigned len)); + /* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code + */ + + /***************************************************************************/ + + /* Get the current file offset */ + extern uLong ZEXPORT unzGetOffset(unzFile file); + + /* Set the current file offset */ + extern int ZEXPORT unzSetOffset(unzFile file, uLong pos); + +#ifdef __cplusplus +} +#endif + +#endif /* _unz_H */