From 64c63da758619d3a1896c4dcaafd4bf689ab830f Mon Sep 17 00:00:00 2001 From: Nils Durner Date: Sun, 16 Nov 2008 22:00:21 +0000 Subject: move unzip code to libextractor_common --- src/common/ChangeLogUnzip | 93 +++ src/common/Makefile.am | 4 +- src/common/unzip.c | 1324 +++++++++++++++++++++++++++++++++++++ src/common/unzip.h | 126 ++++ src/plugins/oo/ChangeLogUnzip | 93 --- src/plugins/oo/Makefile.am | 1 + src/plugins/oo/ooextractor.c | 1437 +---------------------------------------- 7 files changed, 1582 insertions(+), 1496 deletions(-) create mode 100644 src/common/ChangeLogUnzip create mode 100644 src/common/unzip.c create mode 100644 src/common/unzip.h delete mode 100644 src/plugins/oo/ChangeLogUnzip (limited to 'src') diff --git a/src/common/ChangeLogUnzip b/src/common/ChangeLogUnzip new file mode 100644 index 0000000..06c70d9 --- /dev/null +++ b/src/common/ChangeLogUnzip @@ -0,0 +1,93 @@ +The files crypt.h, ioapi.c, ioapi.h, miniunz, unzip.c and unzip.h are +from contrib/ in zlib (copyright below). The code was adapted for +libextractor and extended to support OpenOffice meta-data extraction +by Christian Grothoff. + + Copyright (C) 1998-2003 Gilles Vollant + + This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g + WinZip, InfoZip tools and compatible. + Encryption and multi volume ZipFile (span) are not 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. + + +Original ChangeLog (from before LE integration): + + +Change in 1.00: (10 sept 03) +- rename to 1.00 +- cosmetic code change + +Change in 0.22: (19 May 03) +- crypting support (unless you define NOCRYPT) +- append file in existing zipfile + +Change in 0.21: (10 Mar 03) +- bug fixes + +Change in 0.17: (27 Jan 02) +- bug fixes + +Change in 0.16: (19 Jan 02) +- Support of ioapi for virtualize zip file access + +Change in 0.15: (19 Mar 98) +- fix memory leak in minizip.c + +Change in 0.14: (10 Mar 98) +- fix bugs in minizip.c sample for zipping big file +- fix problem in month in date handling +- fix bug in unzlocal_GetCurrentFileInfoInternal in unzip.c for + comment handling + +Change in 0.13: (6 Mar 98) +- fix bugs in zip.c +- add real minizip sample + +Change in 0.12: (4 Mar 98) +- add zip.c and zip.h for creates .zip file +- fix change_file_date in miniunz.c for Unix (Jean-loup Gailly) +- fix miniunz.c for file without specific record for directory + +Change in 0.11: (3 Mar 98) +- fix bug in unzGetCurrentFileInfo for get extra field and comment +- enhance miniunz sample, remove the bad unztst.c sample + +Change in 0.10: (2 Mar 98) +- fix bug in unzReadCurrentFile +- rename unzip* to unz* function and structure +- remove Windows-like hungary notation variable name +- modify some structure in unzip.h +- add somes comment in source +- remove unzipGetcCurrentFile function +- replace ZUNZEXPORT by ZEXPORT +- add unzGetLocalExtrafield for get the local extrafield info +- add a new sample, miniunz.c + +Change in 0.4: (25 Feb 98) +- suppress the type unzipFileInZip. + Only on file in the zipfile can be open at the same time +- fix somes typo in code +- added tm_unz structure in unzip_file_info (date/time in readable format) diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 4ffd5bd..6d2ff77 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -19,9 +19,11 @@ libextractor_common_la_LDFLAGS = \ $(exportflag) $(winexportflag) -version-info @LIB_VERSION_CURRENT@:@LIB_VERSION_REVISION@:@LIB_VERSION_AGE@ $(LIBICONV) libextractor_common_la_LIBADD = \ - $(LIBLTDL) $(dlflag) + $(LIBLTDL) $(dlflag) -lz libextractor_common_la_SOURCES = \ + unzip.c \ + unzip.h \ pack.c \ pack.h \ convert.c \ diff --git a/src/common/unzip.c b/src/common/unzip.c new file mode 100644 index 0000000..60c97b1 --- /dev/null +++ b/src/common/unzip.c @@ -0,0 +1,1324 @@ +/* + This file is part of libextractor. + (C) 2004, 2008 Vidyut Samanta and Christian Grothoff + + libextractor is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + libextractor is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libextractor; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "platform.h" +#include +#include "extractor.h" +#include "unzip.h" + +#define CASESENSITIVITY (0) +#define MAXFILENAME (256) + +/* *********************** IOAPI ***************** */ + +#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) + + +#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)) + + +/* ******************* former crypt.h ********************* */ + +/* 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; + +/* + 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 +*/ + +#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.00 Copyright 1998-2003 Gilles Vollant - http://www.winimage.com/zLibDll"; + +/* EXTRACTOR_unzip_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*/ + EXTRACTOR_unzip_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 +{ + EXTRACTOR_unzip_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 */ + + EXTRACTOR_unzip_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; +} unz_s; + + + +/* =========================================================================== + 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. +*/ + + +static int unzlocal_getByte OF(( + const EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + int *pi)); + +static int unzlocal_getByte(pzlib_filefunc_def,filestream,pi) + const EXTRACTOR_unzip_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 EXTRACTOR_UNZIP_OK; + } + else + { + if (ZERROR(*pzlib_filefunc_def,filestream)) + return EXTRACTOR_UNZIP_ERRNO; + else + return EXTRACTOR_UNZIP_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +static int unzlocal_getShort OF(( + const EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +static int unzlocal_getShort (pzlib_filefunc_def,filestream,pX) + const EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==EXTRACTOR_UNZIP_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==EXTRACTOR_UNZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +static int unzlocal_getLong OF(( + const EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +static int unzlocal_getLong (pzlib_filefunc_def,filestream,pX) + const EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==EXTRACTOR_UNZIP_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==EXTRACTOR_UNZIP_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<16; + + if (err==EXTRACTOR_UNZIP_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==EXTRACTOR_UNZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + + +/* My own strcmpi / strcasecmp */ +static int strcmpcasenosensitive_internal (fileName1,fileName2) + 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 (c1c2) + 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) + +*/ +int EXTRACTOR_common_unzip_string_file_name_compare (fileName1,fileName2,iCaseSensitivity) + 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) +*/ +static uLong unzlocal_SearchCentralDir OF(( + const EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def, + voidpf filestream)); + +static uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream) + const EXTRACTOR_unzip_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 (uBackReaduMaxBack) + 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; +} + +/* + Translate date/time from Dos format to EXTRACTOR_unzip_tm_unz (readable more easilty) +*/ +static void unzlocal_DosDateToTmuDate (ulDosDate, ptm) + uLong ulDosDate; + EXTRACTOR_unzip_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)) ; +} + + + +static int unzlocal_GetCurrentFileInfoInternal (file, + pfile_info, + pfile_info_internal, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + EXTRACTOR_unzip_file file; + EXTRACTOR_unzip_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; + EXTRACTOR_unzip_file_info file_info; + unz_file_info_internal file_info_internal; + int err=EXTRACTOR_UNZIP_OK; + uLong uMagic; + long lSeek=0; + + if (file==NULL) + return EXTRACTOR_UNZIP_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=EXTRACTOR_UNZIP_ERRNO; + + + /* we check the magic */ + if (err==EXTRACTOR_UNZIP_OK) { + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + else if (uMagic!=0x02014b50) + err=EXTRACTOR_UNZIP_BADZIPFILE; + } + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + lSeek+=file_info.size_filename; + if ((err==EXTRACTOR_UNZIP_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) + err=EXTRACTOR_UNZIP_ERRNO; + lSeek -= uSizeRead; + } + + + if ((err==EXTRACTOR_UNZIP_OK) && (extraField!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=EXTRACTOR_UNZIP_ERRNO; + } + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead) + err=EXTRACTOR_UNZIP_ERRNO; + lSeek += file_info.size_file_extra - uSizeRead; + } + else + lSeek+=file_info.size_file_extra; + + + if ((err==EXTRACTOR_UNZIP_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=EXTRACTOR_UNZIP_ERRNO; + } + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) + err=EXTRACTOR_UNZIP_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + if ((err==EXTRACTOR_UNZIP_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==EXTRACTOR_UNZIP_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +int EXTRACTOR_common_unzip_go_to_first_file (file) + EXTRACTOR_unzip_file file; +{ + int err=EXTRACTOR_UNZIP_OK; + unz_s* s; + if (file==NULL) + return EXTRACTOR_UNZIP_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 == EXTRACTOR_UNZIP_OK); + return err; +} + + +/* + 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 EXTRACTOR_unzip_file Handle, usable with other function + of this unzip package. +*/ +EXTRACTOR_unzip_file EXTRACTOR_common_unzip_open2 (path, pzlib_filefunc_def) + const char *path; + EXTRACTOR_unzip_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=EXTRACTOR_UNZIP_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + 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=EXTRACTOR_UNZIP_ERRNO; + + if (ZSEEK(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=EXTRACTOR_UNZIP_ERRNO; + + /* the signature, already checked */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + /* number of this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + /* total number of entries in the central dir */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=EXTRACTOR_UNZIP_BADZIPFILE; + + /* size of the central directory */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_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)!=EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + /* zipfile comment length */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + if ((central_pospfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return EXTRACTOR_UNZIP_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=EXTRACTOR_UNZIP_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; +} + +/* + 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 EXTRACTOR_UNZIP_OK if there is no problem. */ +int EXTRACTOR_common_unzip_close (file) + EXTRACTOR_unzip_file file; +{ + unz_s* s; + if (file==NULL) + return EXTRACTOR_UNZIP_PARAMERROR; + s=(unz_s*)file; + + if (s->pfile_in_zip_read!=NULL) + EXTRACTOR_common_unzip_close_current_file(file); + + ZCLOSE(s->z_filefunc, s->filestream); + TRYFREE(s); + return EXTRACTOR_UNZIP_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return EXTRACTOR_UNZIP_OK if there is no problem. +*/ +int EXTRACTOR_common_unzip_get_current_file_info (file, + pfile_info, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + EXTRACTOR_unzip_file file; + EXTRACTOR_unzip_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 next file. + return EXTRACTOR_UNZIP_OK if there is no problem + return EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +int EXTRACTOR_common_unzip_go_to_next_file (file) + EXTRACTOR_unzip_file file; +{ + unz_s* s; + int err; + + if (file==NULL) + return EXTRACTOR_UNZIP_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE; + if (s->num_file+1==s->gi.number_entry) + return EXTRACTOR_UNZIP_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 == EXTRACTOR_UNZIP_OK); + return err; +} + + + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare + + return value : + EXTRACTOR_UNZIP_OK if the file is found. It becomes the current file. + EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE if the file is not found +*/ +int EXTRACTOR_common_unzip_local_file (file, szFileName, iCaseSensitivity) + EXTRACTOR_unzip_file 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. + */ + EXTRACTOR_unzip_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 EXTRACTOR_UNZIP_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return EXTRACTOR_UNZIP_PARAMERROR; + + s=(unz_s*)file; + if (!s->current_file_ok) + return EXTRACTOR_UNZIP_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 = EXTRACTOR_common_unzip_go_to_first_file(file); + + while (err == EXTRACTOR_UNZIP_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + err = EXTRACTOR_common_unzip_get_current_file_info(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (err == EXTRACTOR_UNZIP_OK) + { + if (EXTRACTOR_common_unzip_string_file_name_compare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return EXTRACTOR_UNZIP_OK; + err = EXTRACTOR_common_unzip_go_to_next_file(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; +} + + +/* + 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 + (EXTRACTOR_UNZIP_ERRNO for IO error, or zLib error for uncompress error) +*/ +int EXTRACTOR_common_unzip_read_current_file (file, buf, len) + EXTRACTOR_unzip_file file; + voidp buf; + unsigned len; +{ + int err=EXTRACTOR_UNZIP_OK; + uInt iRead = 0; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return EXTRACTOR_UNZIP_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return EXTRACTOR_UNZIP_PARAMERROR; + + + if ((pfile_in_zip_read_info->read_buffer == NULL)) + return EXTRACTOR_UNZIP_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->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + 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_compressedrest_read_compressed; + if (uReadThis == 0) + return EXTRACTOR_UNZIP_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 EXTRACTOR_UNZIP_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 EXTRACTOR_UNZIP_ERRNO; + + + 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) ? EXTRACTOR_UNZIP_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;istream.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); + + 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) ? EXTRACTOR_UNZIP_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + +/* + 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) +*/ +static int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, + poffset_local_extrafield, + psize_local_extrafield) + 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=EXTRACTOR_UNZIP_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 EXTRACTOR_UNZIP_ERRNO; + + + if (err==EXTRACTOR_UNZIP_OK) { + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + else if (uMagic!=0x04034b50) + err=EXTRACTOR_UNZIP_BADZIPFILE; + } + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; +/* + else if ((err==EXTRACTOR_UNZIP_OK) && (uData!=s->cur_file_info.wVersion)) + err=EXTRACTOR_UNZIP_BADZIPFILE; +*/ + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + else if ((err==EXTRACTOR_UNZIP_OK) && (uData!=s->cur_file_info.compression_method)) + err=EXTRACTOR_UNZIP_BADZIPFILE; + + if ((err==EXTRACTOR_UNZIP_OK) && (s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=EXTRACTOR_UNZIP_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != EXTRACTOR_UNZIP_OK) /* date/time */ + err=EXTRACTOR_UNZIP_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != EXTRACTOR_UNZIP_OK) /* crc */ + err=EXTRACTOR_UNZIP_ERRNO; + else if ((err==EXTRACTOR_UNZIP_OK) && (uData!=s->cur_file_info.crc) && + ((uFlags & 8)==0)) + err=EXTRACTOR_UNZIP_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != EXTRACTOR_UNZIP_OK) /* size compr */ + err=EXTRACTOR_UNZIP_ERRNO; + else if ((err==EXTRACTOR_UNZIP_OK) && (uData!=s->cur_file_info.compressed_size) && + ((uFlags & 8)==0)) + err=EXTRACTOR_UNZIP_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != EXTRACTOR_UNZIP_OK) /* size uncompr */ + err=EXTRACTOR_UNZIP_ERRNO; + else if ((err==EXTRACTOR_UNZIP_OK) && (uData!=s->cur_file_info.uncompressed_size) && + ((uFlags & 8)==0)) + err=EXTRACTOR_UNZIP_BADZIPFILE; + + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_ERRNO; + else if ((err==EXTRACTOR_UNZIP_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=EXTRACTOR_UNZIP_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != EXTRACTOR_UNZIP_OK) + err=EXTRACTOR_UNZIP_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 EXTRACTOR_UNZIP_OK. +*/ +int EXTRACTOR_common_unzip_open_current_file3 (file, method, level, raw) + EXTRACTOR_unzip_file file; + int* method; + int* level; + int raw; +{ + int err=EXTRACTOR_UNZIP_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 */ + + if (file==NULL) + return EXTRACTOR_UNZIP_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return EXTRACTOR_UNZIP_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + EXTRACTOR_common_unzip_close_current_file(file); + if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, + &offset_local_extrafield,&size_local_extrafield)!=EXTRACTOR_UNZIP_OK) + return EXTRACTOR_UNZIP_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 EXTRACTOR_UNZIP_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 EXTRACTOR_UNZIP_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=EXTRACTOR_UNZIP_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 + 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; + + return EXTRACTOR_UNZIP_OK; +} + +typedef struct Ecls { + char * data; + size_t size; + size_t pos; +} Ecls; + +voidpf EXTRACTOR_common_unzip_zlib_open_file_func (voidpf opaque, + const char* filename, + int mode) { + if (0 == strcmp(filename, + "ERROR")) + return opaque; + else + return NULL; +} + +uLong EXTRACTOR_common_unzip_zlib_read_file_func(voidpf opaque, + voidpf stream, + void* buf, + uLong size) { + Ecls * e = opaque; + uLong ret; + + ret = e->size - e->pos; + if (ret > size) + ret = size; + memcpy(buf, + &e->data[e->pos], + ret); + e->pos += ret; + return ret; +} + +long EXTRACTOR_common_unzip_zlib_tell_file_func(voidpf opaque, + voidpf stream) { + Ecls * e = opaque; + return e->pos; +} + +long EXTRACTOR_common_unzip_zlib_seek_file_func(voidpf opaque, + voidpf stream, + uLong offset, + int origin) { + Ecls * e = opaque; + + switch (origin) { + case ZLIB_FILEFUNC_SEEK_SET: + if ( (offset > e->size) || + (offset < 0) ) + return -1; + e->pos = offset; + break; + case ZLIB_FILEFUNC_SEEK_END: + if ( (offset > e->size) || + (offset < 0) ) + return -1; + e->pos = e->size - offset; + break; + case ZLIB_FILEFUNC_SEEK_CUR: + if ( (offset < - e->pos) || + (offset > e->size - e->pos) ) + return -1; + e->pos += offset; + break; + default: + return -1; + } + return 0; +} + +int EXTRACTOR_common_unzip_zlib_close_file_func(voidpf opaque, + voidpf stream) { + return 0; +} + +int EXTRACTOR_common_unzip_zlib_testerror_file_func(voidpf opaque, + voidpf stream) { + return 0; +} diff --git a/src/common/unzip.h b/src/common/unzip.h new file mode 100644 index 0000000..f0c2c4e --- /dev/null +++ b/src/common/unzip.h @@ -0,0 +1,126 @@ +/* + This file is part of libextractor. + (C) 2008 Christian Grothoff (and other contributing authors) + + libextractor is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + libextractor is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libextractor; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef UNZIP_H_ +#define UNZIP_H_ + +#include + +#define EXTRACTOR_UNZIP_OK (0) +#define EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE (-100) +#define EXTRACTOR_UNZIP_ERRNO (Z_ERRNO) +#define EXTRACTOR_UNZIP_EOF (0) +#define EXTRACTOR_UNZIP_PARAMERROR (-102) +#define EXTRACTOR_UNZIP_BADZIPFILE (-103) +#define EXTRACTOR_UNZIP_INTERNALERROR (-104) +#define EXTRACTOR_UNZIP_CRCERROR (-105) + +typedef voidp EXTRACTOR_unzip_file; + +typedef struct EXTRACTOR_unzip_filefunc_def_s +{ + voidpf ( *zopen_file) (voidpf opaque, const char* filename, int mode); + uLong ( *zread_file) (voidpf opaque, voidpf stream, void* buf, uLong size); + uLong ( *zwrite_file) (voidpf opaque, voidpf stream, const void* buf, uLong size); + long ( *ztell_file) (voidpf opaque, voidpf stream); + long ( *zseek_file) (voidpf opaque, voidpf stream, uLong offset, int origin); + int ( *zclose_file) (voidpf opaque, voidpf stream); + int ( *zerror_file) (voidpf opaque, voidpf stream); + voidpf opaque; +} EXTRACTOR_unzip_filefunc_def; + +/* tm_unz contain date/time info */ +typedef struct EXTRACTOR_unzip_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] */ +} EXTRACTOR_unzip_tm_unz; + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct EXTRACTOR_unzip_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 */ + + EXTRACTOR_unzip_tm_unz tmu_date; +} EXTRACTOR_unzip_file_info; + +int EXTRACTOR_common_unzip_string_file_name_compare(const char* fileName1, + const char* fileName2, int iCaseSensitivity); + +int EXTRACTOR_common_unzip_go_to_first_file(EXTRACTOR_unzip_file file); + +EXTRACTOR_unzip_file EXTRACTOR_common_unzip_open2(const char *path, + EXTRACTOR_unzip_filefunc_def* pzlib_filefunc_def); + +int EXTRACTOR_common_unzip_close_current_file(EXTRACTOR_unzip_file file); + +int EXTRACTOR_common_unzip_close(EXTRACTOR_unzip_file file); + +int EXTRACTOR_common_unzip_get_current_file_info(EXTRACTOR_unzip_file file, + EXTRACTOR_unzip_file_info *pfile_info, char *szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, char *szComment, + uLong commentBufferSize); + +int EXTRACTOR_common_unzip_go_to_next_file(EXTRACTOR_unzip_file file); + +int EXTRACTOR_common_unzip_local_file(EXTRACTOR_unzip_file file, const char *szFileName, + int iCaseSensitivity); + +int EXTRACTOR_common_unzip_read_current_file(EXTRACTOR_unzip_file file, voidp buf, + unsigned len); + +int EXTRACTOR_common_unzip_open_current_file3(EXTRACTOR_unzip_file file, int* method, + int* level, int raw); + +voidpf EXTRACTOR_common_unzip_zlib_open_file_func(voidpf opaque, + const char* filename, int mode); + +uLong EXTRACTOR_common_unzip_zlib_read_file_func(voidpf opaque, voidpf stream, + void* buf, uLong size); + +long EXTRACTOR_common_unzip_zlib_tell_file_func(voidpf opaque, voidpf stream); + +long EXTRACTOR_common_unzip_zlib_seek_file_func(voidpf opaque, voidpf stream, + uLong offset, int origin); + +int EXTRACTOR_common_unzip_zlib_close_file_func(voidpf opaque, voidpf stream); + +int EXTRACTOR_common_unzip_zlib_testerror_file_func(voidpf opaque, + voidpf stream); + +#endif /* UNZIP_H_ */ diff --git a/src/plugins/oo/ChangeLogUnzip b/src/plugins/oo/ChangeLogUnzip deleted file mode 100644 index 06c70d9..0000000 --- a/src/plugins/oo/ChangeLogUnzip +++ /dev/null @@ -1,93 +0,0 @@ -The files crypt.h, ioapi.c, ioapi.h, miniunz, unzip.c and unzip.h are -from contrib/ in zlib (copyright below). The code was adapted for -libextractor and extended to support OpenOffice meta-data extraction -by Christian Grothoff. - - Copyright (C) 1998-2003 Gilles Vollant - - This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g - WinZip, InfoZip tools and compatible. - Encryption and multi volume ZipFile (span) are not 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. - - -Original ChangeLog (from before LE integration): - - -Change in 1.00: (10 sept 03) -- rename to 1.00 -- cosmetic code change - -Change in 0.22: (19 May 03) -- crypting support (unless you define NOCRYPT) -- append file in existing zipfile - -Change in 0.21: (10 Mar 03) -- bug fixes - -Change in 0.17: (27 Jan 02) -- bug fixes - -Change in 0.16: (19 Jan 02) -- Support of ioapi for virtualize zip file access - -Change in 0.15: (19 Mar 98) -- fix memory leak in minizip.c - -Change in 0.14: (10 Mar 98) -- fix bugs in minizip.c sample for zipping big file -- fix problem in month in date handling -- fix bug in unzlocal_GetCurrentFileInfoInternal in unzip.c for - comment handling - -Change in 0.13: (6 Mar 98) -- fix bugs in zip.c -- add real minizip sample - -Change in 0.12: (4 Mar 98) -- add zip.c and zip.h for creates .zip file -- fix change_file_date in miniunz.c for Unix (Jean-loup Gailly) -- fix miniunz.c for file without specific record for directory - -Change in 0.11: (3 Mar 98) -- fix bug in unzGetCurrentFileInfo for get extra field and comment -- enhance miniunz sample, remove the bad unztst.c sample - -Change in 0.10: (2 Mar 98) -- fix bug in unzReadCurrentFile -- rename unzip* to unz* function and structure -- remove Windows-like hungary notation variable name -- modify some structure in unzip.h -- add somes comment in source -- remove unzipGetcCurrentFile function -- replace ZUNZEXPORT by ZEXPORT -- add unzGetLocalExtrafield for get the local extrafield info -- add a new sample, miniunz.c - -Change in 0.4: (25 Feb 98) -- suppress the type unzipFileInZip. - Only on file in the zipfile can be open at the same time -- fix somes typo in code -- added tm_unz structure in unzip_file_info (date/time in readable format) diff --git a/src/plugins/oo/Makefile.am b/src/plugins/oo/Makefile.am index 0a328f0..4f79fbf 100644 --- a/src/plugins/oo/Makefile.am +++ b/src/plugins/oo/Makefile.am @@ -13,4 +13,5 @@ libextractor_oo_la_LDFLAGS = \ libextractor_oo_la_LIBADD = \ $(top_builddir)/src/main/libextractor.la \ + $(top_builddir)/src/common/libextractor_common.la \ -lz diff --git a/src/plugins/oo/ooextractor.c b/src/plugins/oo/ooextractor.c index e12c8ab..40558c1 100644 --- a/src/plugins/oo/ooextractor.c +++ b/src/plugins/oo/ooextractor.c @@ -22,1304 +22,11 @@ #include #include "extractor.h" #include "zlib.h" +#include "unzip.h" #define CASESENSITIVITY (0) #define MAXFILENAME (256) -/* *********************** IOAPI ***************** */ - -#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) - - -typedef voidpf ( *open_file_func) (voidpf opaque, const char* filename, int mode); -typedef uLong ( *read_file_func) (voidpf opaque, voidpf stream, void* buf, uLong size); -typedef uLong ( *write_file_func) (voidpf opaque, voidpf stream, const void* buf, uLong size); -typedef long ( *tell_file_func) (voidpf opaque, voidpf stream); -typedef long ( *seek_file_func) (voidpf opaque, voidpf stream, uLong offset, int origin); -typedef int ( *close_file_func) (voidpf opaque, voidpf stream); -typedef int ( *testerror_file_func) (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; - -#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)) - - -/* ******************* former crypt.h ********************* */ - -#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; - - -/* - 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 -*/ - -#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.00 Copyright 1998-2003 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; -} unz_s; - - - -/* =========================================================================== - 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. -*/ - - -static int unzlocal_getByte OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, - int *pi)); - -static int unzlocal_getByte(pzlib_filefunc_def,filestream,pi) - 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 -*/ -static int unzlocal_getShort OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX)); - -static int unzlocal_getShort (pzlib_filefunc_def,filestream,pX) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; - uLong *pX; -{ - uLong x ; - int i; - 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; -} - -static int unzlocal_getLong OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX)); - -static int unzlocal_getLong (pzlib_filefunc_def,filestream,pX) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; - uLong *pX; -{ - uLong x ; - int i; - 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 */ -static int strcmpcasenosensitive_internal (fileName1,fileName2) - 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 (c1c2) - 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) - -*/ -static int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) - 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) -*/ -static uLong unzlocal_SearchCentralDir OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream)); - -static uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream) - 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 (uBackReaduMaxBack) - 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; -} - -/* - Translate date/time from Dos format to tm_unz (readable more easilty) -*/ -static void unzlocal_DosDateToTmuDate (ulDosDate, ptm) - 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)) ; -} - - - -static int unzlocal_GetCurrentFileInfoInternal (file, - pfile_info, - pfile_info_internal, - szFileName, fileNameBufferSize, - extraField, extraFieldBufferSize, - szComment, commentBufferSize) - 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_filename0) && (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_extraz_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_commentz_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; -} - -/* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem -*/ -static int ZEXPORT unzGoToFirstFile (file) - 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; -} - - -/* - 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. -*/ -static unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def) - 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; - - 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_pospfile_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; -} - -/* - 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. */ -static int ZEXPORT unzClose (file) - 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. -*/ -static int ZEXPORT unzGetCurrentFileInfo (file, - pfile_info, - szFileName, fileNameBufferSize, - extraField, extraFieldBufferSize, - szComment, commentBufferSize) - 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 next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. -*/ -static int ZEXPORT unzGoToNextFile (file) - 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->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 -*/ -static int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity) - 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; -} - - -/* - 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) -*/ -static int ZEXPORT unzReadCurrentFile (file, buf, len) - 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->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_uncompressed; - - 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_compressedrest_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; - - - 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;istream.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); - - 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; -} - -/* - 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) -*/ -static int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, - poffset_local_extrafield, - psize_local_extrafield) - 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. -*/ -static int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw) - unzFile file; - int* method; - int* level; - int raw; -{ - 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 */ - - 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 - 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; - - return UNZ_OK; -} - - -/* *************************** main extractor code *********************** */ - /** * Name of the file with the meta-data in OO documents. @@ -1369,16 +76,16 @@ static Matches tmap[] = { * returns either zero when mimetype info is missing * or an already malloc'ed string containing the mimetype info. */ -static char *libextractor_oo_getmimetype(unzFile uf) { +static char *libextractor_oo_getmimetype(EXTRACTOR_unzip_file uf) { char filename_inzip[MAXFILENAME]; - unz_file_info file_info; + EXTRACTOR_unzip_file_info file_info; char * buf = NULL; size_t buf_size = 0; - if (UNZ_OK == unzLocateFile(uf, + if (EXTRACTOR_UNZIP_OK == EXTRACTOR_common_unzip_local_file(uf, "mimetype", CASESENSITIVITY)) { - if ( (UNZ_OK == unzGetCurrentFileInfo(uf, + if ( (EXTRACTOR_UNZIP_OK == EXTRACTOR_common_unzip_get_current_file_info(uf, &file_info, filename_inzip, sizeof(filename_inzip), @@ -1386,14 +93,14 @@ static char *libextractor_oo_getmimetype(unzFile uf) { 0, NULL, 0) && - (UNZ_OK == unzOpenCurrentFile3(uf,NULL, NULL, 0)) ) ) { + (EXTRACTOR_UNZIP_OK == EXTRACTOR_common_unzip_open_current_file3(uf,NULL, NULL, 0)) ) ) { buf_size = file_info.uncompressed_size; if (buf_size > 1024) { /* way too large! */ } else if (NULL == (buf = malloc(1 + buf_size))) { /* memory exhausted! */ - } else if (buf_size != (size_t) unzReadCurrentFile(uf,buf,buf_size)) { + } else if (buf_size != (size_t) EXTRACTOR_common_unzip_read_current_file(uf,buf,buf_size)) { free(buf); buf = NULL; } else { @@ -1408,7 +115,7 @@ static char *libextractor_oo_getmimetype(unzFile uf) { } } } - unzCloseCurrentFile(uf); + EXTRACTOR_common_unzip_close_current_file(uf); } return buf; } @@ -1420,80 +127,6 @@ typedef struct Ecls { size_t pos; } Ecls; -static voidpf Eopen_file_func (voidpf opaque, - const char* filename, - int mode) { - if (0 == strcmp(filename, - "ERROR")) - return opaque; - else - return NULL; -} - -static uLong Eread_file_func(voidpf opaque, - voidpf stream, - void* buf, - uLong size) { - Ecls * e = opaque; - uLong ret; - - ret = e->size - e->pos; - if (ret > size) - ret = size; - memcpy(buf, - &e->data[e->pos], - ret); - e->pos += ret; - return ret; -} - -static long Etell_file_func(voidpf opaque, - voidpf stream) { - Ecls * e = opaque; - return e->pos; -} - -static long Eseek_file_func(voidpf opaque, - voidpf stream, - uLong offset, - int origin) { - Ecls * e = opaque; - - switch (origin) { - case ZLIB_FILEFUNC_SEEK_SET: - if ( (offset > e->size) || - (offset < 0) ) - return -1; - e->pos = offset; - break; - case ZLIB_FILEFUNC_SEEK_END: - if ( (offset > e->size) || - (offset < 0) ) - return -1; - e->pos = e->size - offset; - break; - case ZLIB_FILEFUNC_SEEK_CUR: - if ( (offset < - e->pos) || - (offset > e->size - e->pos) ) - return -1; - e->pos += offset; - break; - default: - return -1; - } - return 0; -} - -static int Eclose_file_func(voidpf opaque, - voidpf stream) { - return 0; -} - -static int Etesterror_file_func(voidpf opaque, - voidpf stream) { - return 0; -} - struct EXTRACTOR_Keywords * libextractor_oo_extract(const char * filename, @@ -1501,13 +134,13 @@ libextractor_oo_extract(const char * filename, size_t size, struct EXTRACTOR_Keywords * prev) { char filename_inzip[MAXFILENAME]; - unzFile uf; - unz_file_info file_info; + EXTRACTOR_unzip_file uf; + EXTRACTOR_unzip_file_info file_info; char * buf; char * pbuf; size_t buf_size; int i; - zlib_filefunc_def io; + EXTRACTOR_unzip_filefunc_def io; Ecls cls; char * mimetype; @@ -1519,16 +152,16 @@ libextractor_oo_extract(const char * filename, cls.data = data; cls.size = size; cls.pos = 0; - io.zopen_file = &Eopen_file_func; - io.zread_file = &Eread_file_func; + io.zopen_file = &EXTRACTOR_common_unzip_zlib_open_file_func; + io.zread_file = &EXTRACTOR_common_unzip_zlib_read_file_func; io.zwrite_file = NULL; - io.ztell_file = &Etell_file_func; - io.zseek_file = &Eseek_file_func; - io.zclose_file = &Eclose_file_func; - io.zerror_file = &Etesterror_file_func; + io.ztell_file = &EXTRACTOR_common_unzip_zlib_tell_file_func; + io.zseek_file = &EXTRACTOR_common_unzip_zlib_seek_file_func; + io.zclose_file = &EXTRACTOR_common_unzip_zlib_close_file_func; + io.zerror_file = &EXTRACTOR_common_unzip_zlib_testerror_file_func; io.opaque = &cls; - uf = unzOpen2("ERROR", &io); + uf = EXTRACTOR_common_unzip_open2("ERROR", &io); if (uf == NULL) return prev; mimetype = libextractor_oo_getmimetype(uf); @@ -1539,47 +172,47 @@ libextractor_oo_extract(const char * filename, EXTRACTOR_MIMETYPE)); - if (unzLocateFile(uf, + if (EXTRACTOR_common_unzip_local_file(uf, METAFILE, - CASESENSITIVITY) != UNZ_OK) { - unzClose(uf); + CASESENSITIVITY) != EXTRACTOR_UNZIP_OK) { + EXTRACTOR_common_unzip_close(uf); return prev; /* not found */ } - if (UNZ_OK != unzGetCurrentFileInfo(uf, + if (EXTRACTOR_UNZIP_OK != EXTRACTOR_common_unzip_get_current_file_info(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL,0,NULL,0)) { - unzClose(uf); + EXTRACTOR_common_unzip_close(uf); return prev; /* problems... */ } - if (UNZ_OK != unzOpenCurrentFile3(uf, NULL, NULL, 0)) { - unzClose(uf); + if (EXTRACTOR_UNZIP_OK != EXTRACTOR_common_unzip_open_current_file3(uf, NULL, NULL, 0)) { + EXTRACTOR_common_unzip_close(uf); return prev; /* problems... */ } buf_size = file_info.uncompressed_size; if (buf_size > 128 * 1024) { - unzCloseCurrentFile(uf); - unzClose(uf); + EXTRACTOR_common_unzip_close_current_file(uf); + EXTRACTOR_common_unzip_close(uf); return prev; /* hardly meta-data! */ } buf = malloc(buf_size+1); if (buf == NULL) { - unzCloseCurrentFile(uf); - unzClose(uf); + EXTRACTOR_common_unzip_close_current_file(uf); + EXTRACTOR_common_unzip_close(uf); return prev; /* out of memory */ } - if (buf_size != unzReadCurrentFile(uf,buf,buf_size)) { + if (buf_size != EXTRACTOR_common_unzip_read_current_file(uf,buf,buf_size)) { free(buf); - unzCloseCurrentFile(uf); - unzClose(uf); + EXTRACTOR_common_unzip_close_current_file(uf); + EXTRACTOR_common_unzip_close(uf); return prev; } - unzCloseCurrentFile(uf); + EXTRACTOR_common_unzip_close_current_file(uf); /* we don't do "proper" parsing of the meta-data but rather use some heuristics to get values out that we understand */ buf[buf_size] = '\0'; @@ -1609,7 +242,7 @@ libextractor_oo_extract(const char * filename, strcat(needle, "=\""); spos = strstr(pbuf, needle); if (spos == NULL) - break; + break; spos += strlen(needle); epos = spos; while ( (epos[0] != '\0') && @@ -1648,7 +281,7 @@ libextractor_oo_extract(const char * filename, } } free(buf); - unzClose(uf); + EXTRACTOR_common_unzip_close(uf); return prev; } -- cgit v1.2.3