From 13a294f044ef0a89b2dcbfbb5d4d4c792673348e Mon Sep 17 00:00:00 2001 From: Mark Adler Date: Fri, 9 Sep 2011 23:21:57 -0700 Subject: zlib 1.2.0.1 --- contrib/minizip/zip.c | 662 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 556 insertions(+), 106 deletions(-) (limited to 'contrib/minizip/zip.c') diff --git a/contrib/minizip/zip.c b/contrib/minizip/zip.c index 0cae64a..29c17d8 100644 --- a/contrib/minizip/zip.c +++ b/contrib/minizip/zip.c @@ -1,5 +1,5 @@ -/* zip.c -- IO on .zip files using zlib - Version 0.15 beta, Mar 19th, 1998, +/* zip.c -- IO on .zip files using zlib + Version 0.21, March 10th, 2003 Read zip.h for more info */ @@ -8,6 +8,7 @@ #include #include #include +#include #include "zlib.h" #include "zip.h" @@ -66,8 +67,15 @@ #define SEEK_SET 0 #endif +#ifndef DEF_MEM_LEVEL +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +#endif const char zip_copyright[] = - " zip 0.15 Copyright 1998 Gilles Vollant "; + " zip 0.21 Copyright 1998-2003 Gilles Vollant - http://www.winimage.com/zLibDll"; #define SIZEDATA_INDATABLOCK (4096-(4*4)) @@ -99,33 +107,49 @@ typedef struct linkedlist_data_s typedef struct { - z_stream stream; /* zLib stream structure for inflate */ + z_stream stream; /* zLib stream structure for inflate */ int stream_initialised; /* 1 is stream is initialised */ uInt pos_in_buffered_data; /* last written byte in buffered_data */ - uLong pos_local_header; /* offset of the local header of the file + uLong pos_local_header; /* offset of the local header of the file currenty writing */ char* central_header; /* central header data for the current file */ uLong size_centralheader; /* size of the central header for cur file */ uLong flag; /* flag of the file currently writing */ int method; /* compression method of file currenty wr.*/ + int raw; /* 1 for directly writing raw data */ Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ uLong dosDate; uLong crc32; + int encrypt; +#ifndef NOCRPYT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; + int crypt_header_size; +#endif } curfile_info; typedef struct { - FILE * filezip; + zlib_filefunc_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ linkedlist_data central_dir;/* datablock with central dir in construction*/ int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ curfile_info ci; /* info on the file curretly writing */ uLong begin_pos; /* position of the beginning of the zipfile */ + uLong add_position_when_writting_offset; uLong number_entry; } zip_internal; + + +#ifndef NOCRPYT +#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED +#include "crypt.h" +#endif + local linkedlist_datablock_internal* allocate_new_datablock() { linkedlist_datablock_internal* ldi; @@ -166,7 +190,7 @@ local void free_linkedlist(ll) local int add_data_in_datablock(ll,buf,len) - linkedlist_data* ll; + linkedlist_data* ll; const void* buf; uLong len; { @@ -220,32 +244,20 @@ local int add_data_in_datablock(ll,buf,len) } -local int write_datablock(fout,ll) - FILE * fout; - linkedlist_data* ll; -{ - linkedlist_datablock_internal* ldi; - ldi = ll->first_block; - while (ldi!=NULL) - { - if (ldi->filled_in_this_block > 0) - if (fwrite(ldi->data,(uInt)ldi->filled_in_this_block,1,fout)!=1) - return ZIP_ERRNO; - ldi = ldi->next_datablock; - } - return ZIP_OK; -} /****************************************************************************/ +#ifndef NO_ADDFILEINEXISTINGZIP /* =========================================================================== - Outputs a long in LSB order to the given file + Inputs a long in LSB order to the given file nbByte == 1, 2 or 4 (byte, short or long) */ -local int ziplocal_putValue OF((FILE *file, uLong x, int nbByte)); -local int ziplocal_putValue (file, x, nbByte) - FILE *file; +local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, uLong x, int nbByte)); +local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; uLong x; int nbByte; { @@ -255,7 +267,7 @@ local int ziplocal_putValue (file, x, nbByte) buf[n] = (unsigned char)(x & 0xff); x >>= 8; } - if (fwrite(buf,nbByte,1,file)!=1) + if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) return ZIP_ERRNO; else return ZIP_OK; @@ -278,7 +290,7 @@ local void ziplocal_putValue_inmemory (dest, x, nbByte) local uLong ziplocal_TmzDateToDosDate(ptm,dosDate) - tm_zip* ptm; + const tm_zip* ptm; uLong dosDate; { uLong year = (uLong)ptm->tm_year; @@ -294,38 +306,348 @@ local uLong ziplocal_TmzDateToDosDate(ptm,dosDate) /****************************************************************************/ -extern zipFile ZEXPORT zipOpen (pathname, append) +local int ziplocal_getByte OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + int *pi)); + +local int ziplocal_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 ZIP_OK; + } + else + { + if (ZERROR(*pzlib_filefunc_def,filestream)) + return ZIP_ERRNO; + else + return ZIP_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int ziplocal_getShort OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==ZIP_OK) + err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int ziplocal_getLong OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==ZIP_OK) + err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==ZIP_OK) + err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<16; + + if (err==ZIP_OK) + err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local uLong ziplocal_SearchCentralDir OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream)); + +local uLong ziplocal_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; +} +#endif /* !NO_ADDFILEINEXISTINGZIP*/ + +/************************************************************/ +extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def) const char *pathname; int append; + zipcharpc* globalcomment; + zlib_filefunc_def* pzlib_filefunc_def; { zip_internal ziinit; zip_internal* zi; + int err=ZIP_OK; + - ziinit.filezip = fopen(pathname,(append == 0) ? "wb" : "ab"); - if (ziinit.filezip == NULL) + if (pzlib_filefunc_def==NULL) + fill_fopen_filefunc(&ziinit.z_filefunc); + else + ziinit.z_filefunc = *pzlib_filefunc_def; + + ziinit.filestream = (*(ziinit.z_filefunc.zopen_file)) + (ziinit.z_filefunc.opaque, + pathname, + (append == APPEND_STATUS_CREATE) ? + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); + + if (ziinit.filestream == NULL) return NULL; - ziinit.begin_pos = ftell(ziinit.filezip); + ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream); ziinit.in_opened_file_inzip = 0; ziinit.ci.stream_initialised = 0; ziinit.number_entry = 0; + ziinit.add_position_when_writting_offset = 0; init_linkedlist(&(ziinit.central_dir)); zi = (zip_internal*)ALLOC(sizeof(zip_internal)); if (zi==NULL) { - fclose(ziinit.filezip); + ZCLOSE(ziinit.z_filefunc,ziinit.filestream); return NULL; } - *zi = ziinit; - return (zipFile)zi; + /* now we add file in a zipfile */ + #ifndef NO_ADDFILEINEXISTINGZIP + if (append == APPEND_STATUS_ADDINZIP) + { + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + + uLong size_central_dir; /* size of the central directory */ + uLong offset_central_dir; /* offset of start of central directory */ + 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; + uLong number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + uLong size_comment; + + central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream); + if (central_pos==0) + err=ZIP_ERRNO; + + if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=ZIP_ERRNO; + + /* the signature, already checked */ + if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of this disk */ + if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of the disk with the start of the central directory */ + if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central dir */ + if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + if ((number_entry_CD!=number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=ZIP_BADZIPFILE; + + /* size of the central directory */ + if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK) + err=ZIP_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK) + err=ZIP_ERRNO; + + /* zipfile comment length */ + if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK) + err=ZIP_ERRNO; + + if ((central_pos0) && (err==ZIP_OK)) + { + uLong read_this = SIZEDATA_INDATABLOCK; + if (read_this > size_central_dir_to_read) + read_this = size_central_dir_to_read; + if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this) + err=ZIP_ERRNO; + + if (err==ZIP_OK) + err = add_data_in_datablock(&ziinit.central_dir,buf_read, + (uLong)read_this); + size_central_dir_to_read-=read_this; + } + TRYFREE(buf_read); + } + ziinit.begin_pos = byte_before_the_zipfile; + ziinit.number_entry = number_entry_CD; + + if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, + offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=ZIP_ERRNO; + } + #endif /* !NO_ADDFILEINEXISTINGZIP*/ + + if (err != ZIP_OK) + { + TRYFREE(zi); + return NULL; + } + else + { + *zi = ziinit; + return (zipFile)zi; + } } -extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level) +extern zipFile ZEXPORT zipOpen (pathname, append) + const char *pathname; + int append; +{ + return zipOpen2(pathname,append,NULL,NULL); +} + +extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting) zipFile file; const char* filename; const zip_fileinfo* zipfi; @@ -336,6 +658,12 @@ extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, const char* comment; int method; int level; + int raw; + int windowBits; + int memLevel; + int strategy; + const char* password; + uLong crcForCrypting; { zip_internal* zi; uInt size_filename; @@ -343,6 +671,11 @@ extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, uInt i; int err = ZIP_OK; + #ifdef NOCRPYT + if (password != NULL) + return ZIP_PARAMERROR; + #endif + if (file == NULL) return ZIP_PARAMERROR; if ((method!=0) && (method!=Z_DEFLATED)) @@ -384,13 +717,17 @@ extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, zi->ci.flag |= 4; if ((level==1)) zi->ci.flag |= 6; + if (password != NULL) + zi->ci.flag |= 1; zi->ci.crc32 = 0; zi->ci.method = method; + zi->ci.encrypt = 0; zi->ci.stream_initialised = 0; zi->ci.pos_in_buffered_data = 0; - zi->ci.pos_local_header = ftell(zi->filezip); - zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + + zi->ci.raw = raw; + zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ; + zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader); @@ -410,16 +747,16 @@ extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ if (zipfi==NULL) - ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); + ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); else - ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); + ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); if (zipfi==NULL) - ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); + ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); else ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); - ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header,4); + ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4); for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); @@ -430,44 +767,44 @@ extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ - size_extrafield_global+i) = *(filename+i); + size_extrafield_global+i) = *(comment+i); if (zi->ci.central_header == NULL) return ZIP_INTERNALERROR; /* write the local header */ - err = ziplocal_putValue(zi->filezip,(uLong)LOCALHEADERMAGIC,4); + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4); if (err==ZIP_OK) - err = ziplocal_putValue(zi->filezip,(uLong)20,2);/* version needed to extract */ + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ if (err==ZIP_OK) - err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.flag,2); + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); if (err==ZIP_OK) - err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.method,2); + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); if (err==ZIP_OK) - err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.dosDate,4); + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); if (err==ZIP_OK) - err = ziplocal_putValue(zi->filezip,(uLong)0,4); /* crc 32, unknown */ + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ if (err==ZIP_OK) - err = ziplocal_putValue(zi->filezip,(uLong)0,4); /* compressed size, unknown */ + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ if (err==ZIP_OK) - err = ziplocal_putValue(zi->filezip,(uLong)0,4); /* uncompressed size, unknown */ + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ if (err==ZIP_OK) - err = ziplocal_putValue(zi->filezip,(uLong)size_filename,2); + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); if (err==ZIP_OK) - err = ziplocal_putValue(zi->filezip,(uLong)size_extrafield_local,2); + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2); if ((err==ZIP_OK) && (size_filename>0)) - if (fwrite(filename,(uInt)size_filename,1,zi->filezip)!=1) + if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) err = ZIP_ERRNO; if ((err==ZIP_OK) && (size_extrafield_local>0)) - if (fwrite(extrafield_local,(uInt)size_extrafield_local,1,zi->filezip) - !=1) + if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local) + !=size_extrafield_local) err = ZIP_ERRNO; zi->ci.stream.avail_in = (uInt)0; @@ -476,17 +813,38 @@ extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, zi->ci.stream.total_in = 0; zi->ci.stream.total_out = 0; - if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED)) + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) { zi->ci.stream.zalloc = (alloc_func)0; zi->ci.stream.zfree = (free_func)0; zi->ci.stream.opaque = (voidpf)0; + if (windowBits>0) + windowBits = -windowBits; + err = deflateInit2(&zi->ci.stream, level, - Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0); + Z_DEFLATED, windowBits, memLevel, strategy); if (err==Z_OK) zi->ci.stream_initialised = 1; + + #ifndef NOCRPYT + zi->ci.crypt_header_size = 0; + if ((err==Z_OK) && (password != NULL)) + { + unsigned char bufHead[RAND_HEAD_LEN]; + unsigned int sizeHead; + zi->ci.encrypt = 1; + zi->ci.pcrc_32_tab = get_crc_table(); + /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ + + sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); + zi->ci.crypt_header_size = sizeHead; + + if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) + err = ZIP_ERRNO; + } + #endif } @@ -495,9 +853,74 @@ extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, return err; } +extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw) + zipFile file; + const char* filename; + const zip_fileinfo* zipfi; + const void* extrafield_local; + uInt size_extrafield_local; + const void* extrafield_global; + uInt size_extrafield_global; + const char* comment; + int method; + int level; + int raw; +{ + return zipOpenNewFileInZip3 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level) + zipFile file; + const char* filename; + const zip_fileinfo* zipfi; + const void* extrafield_local; + uInt size_extrafield_local; + const void* extrafield_global; + uInt size_extrafield_global; + const char* comment; + int method; + int level; +{ + return zipOpenNewFileInZip2 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0); +} + +local int zipFlushWriteBuffer(zi) + zip_internal* zi; +{ + int err=ZIP_OK; + + if (zi->ci.encrypt != 0) + { + uInt i; + int t; + for (i=0;ici.pos_in_buffered_data;i++) + zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, + zi->ci.buffered_data[i],t); + } + if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) + !=zi->ci.pos_in_buffered_data) + err = ZIP_ERRNO; + zi->ci.pos_in_buffered_data = 0; + return err; +} + extern int ZEXPORT zipWriteInFileInZip (file, buf, len) zipFile file; - const voidp buf; + const void* buf; unsigned len; { zip_internal* zi; @@ -510,7 +933,7 @@ extern int ZEXPORT zipWriteInFileInZip (file, buf, len) if (zi->in_opened_file_inzip == 0) return ZIP_PARAMERROR; - zi->ci.stream.next_in = buf; + zi->ci.stream.next_in = (void*)buf; zi->ci.stream.avail_in = len; zi->ci.crc32 = crc32(zi->ci.crc32,buf,len); @@ -518,15 +941,17 @@ extern int ZEXPORT zipWriteInFileInZip (file, buf, len) { if (zi->ci.stream.avail_out == 0) { - if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip) - !=1) + if (zipFlushWriteBuffer(zi) == ZIP_ERRNO) err = ZIP_ERRNO; - zi->ci.pos_in_buffered_data = 0; zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; zi->ci.stream.next_out = zi->ci.buffered_data; } - if (zi->ci.method == Z_DEFLATED) + + if(err != ZIP_OK) + break; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) { uLong uTotalOutBefore = zi->ci.stream.total_out; err=deflate(&zi->ci.stream, Z_NO_FLUSH); @@ -555,33 +980,34 @@ extern int ZEXPORT zipWriteInFileInZip (file, buf, len) } } - return 0; + return err; } -extern int ZEXPORT zipCloseFileInZip (file) +extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32) zipFile file; + uLong uncompressed_size; + uLong crc32; { zip_internal* zi; + uLong compressed_size; int err=ZIP_OK; if (file == NULL) return ZIP_PARAMERROR; zi = (zip_internal*)file; - if (zi->in_opened_file_inzip == 0) + if (zi->in_opened_file_inzip == 0) return ZIP_PARAMERROR; zi->ci.stream.avail_in = 0; - - if (zi->ci.method == Z_DEFLATED) + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) while (err==ZIP_OK) { uLong uTotalOutBefore; if (zi->ci.stream.avail_out == 0) { - if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip) - !=1) + if (zipFlushWriteBuffer(zi) == ZIP_ERRNO) err = ZIP_ERRNO; - zi->ci.pos_in_buffered_data = 0; zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; zi->ci.stream.next_out = zi->ci.buffered_data; } @@ -594,21 +1020,32 @@ extern int ZEXPORT zipCloseFileInZip (file) err=ZIP_OK; /* this is normal */ if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) - if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip) - !=1) + if (zipFlushWriteBuffer(zi)==ZIP_ERRNO) err = ZIP_ERRNO; - if ((zi->ci.method == Z_DEFLATED) && (err==ZIP_OK)) + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) { err=deflateEnd(&zi->ci.stream); zi->ci.stream_initialised = 0; } - ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)zi->ci.crc32,4); /*crc*/ + if (!zi->ci.raw) + { + crc32 = (uLong)zi->ci.crc32; + uncompressed_size = (uLong)zi->ci.stream.total_in; + } + compressed_size = (uLong)zi->ci.stream.total_out; + #ifndef NOCRPYT + compressed_size += zi->ci.crypt_header_size; + #endif + + ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ ziplocal_putValue_inmemory(zi->ci.central_header+20, - (uLong)zi->ci.stream.total_out,4); /*compr size*/ + compressed_size,4); /*compr size*/ + if (zi->ci.stream.data_type == Z_ASCII) + ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); ziplocal_putValue_inmemory(zi->ci.central_header+24, - (uLong)zi->ci.stream.total_in,4); /*uncompr size*/ + uncompressed_size,4); /*uncompr size*/ if (err==ZIP_OK) err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header, @@ -617,23 +1054,23 @@ extern int ZEXPORT zipCloseFileInZip (file) if (err==ZIP_OK) { - long cur_pos_inzip = ftell(zi->filezip); - if (fseek(zi->filezip, - zi->ci.pos_local_header + 14,SEEK_SET)!=0) - err = ZIP_ERRNO; + long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream); + if (ZSEEK(zi->z_filefunc,zi->filestream, + zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; if (err==ZIP_OK) - err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.crc32,4); /* crc 32, unknown */ + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ if (err==ZIP_OK) /* compressed size, unknown */ - err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.stream.total_out,4); + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); if (err==ZIP_OK) /* uncompressed size, unknown */ - err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.stream.total_in,4); + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); - if (fseek(zi->filezip, - cur_pos_inzip,SEEK_SET)!=0) - err = ZIP_ERRNO; + if (ZSEEK(zi->z_filefunc,zi->filestream, + cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; } zi->number_entry ++; @@ -642,6 +1079,12 @@ extern int ZEXPORT zipCloseFileInZip (file) return err; } +extern int ZEXPORT zipCloseFileInZip (file) + zipFile file; +{ + return zipCloseFileInZipRaw (file,0,0); +} + extern int ZEXPORT zipClose (file, global_comment) zipFile file; const char* global_comment; @@ -666,15 +1109,16 @@ extern int ZEXPORT zipClose (file, global_comment) size_global_comment = strlen(global_comment); - centraldir_pos_inzip = ftell(zi->filezip); + centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream); if (err==ZIP_OK) { linkedlist_datablock_internal* ldi = zi->central_dir.first_block ; while (ldi!=NULL) { if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) - if (fwrite(ldi->data,(uInt)ldi->filled_in_this_block, - 1,zi->filezip) !=1 ) + if (ZWRITE(zi->z_filefunc,zi->filestream, + ldi->data,ldi->filled_in_this_block) + !=ldi->filled_in_this_block ) err = ZIP_ERRNO; size_centraldir += ldi->filled_in_this_block; @@ -684,34 +1128,40 @@ extern int ZEXPORT zipClose (file, global_comment) free_datablock(zi->central_dir.first_block); if (err==ZIP_OK) /* Magic End */ - err = ziplocal_putValue(zi->filezip,(uLong)ENDHEADERMAGIC,4); + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); if (err==ZIP_OK) /* number of this disk */ - err = ziplocal_putValue(zi->filezip,(uLong)0,2); + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); if (err==ZIP_OK) /* number of the disk with the start of the central directory */ - err = ziplocal_putValue(zi->filezip,(uLong)0,2); + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ - err = ziplocal_putValue(zi->filezip,(uLong)zi->number_entry,2); + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); if (err==ZIP_OK) /* total number of entries in the central dir */ - err = ziplocal_putValue(zi->filezip,(uLong)zi->number_entry,2); + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); if (err==ZIP_OK) /* size of the central directory */ - err = ziplocal_putValue(zi->filezip,(uLong)size_centraldir,4); + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); - if (err==ZIP_OK) /* offset of start of central directory with respect to the - starting disk number */ - err = ziplocal_putValue(zi->filezip,(uLong)centraldir_pos_inzip ,4); + if (err==ZIP_OK) /* offset of start of central directory with respect to the + starting disk number */ + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream, + (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); if (err==ZIP_OK) /* zipfile comment length */ - err = ziplocal_putValue(zi->filezip,(uLong)size_global_comment,2); + err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); if ((err==ZIP_OK) && (size_global_comment>0)) - if (fwrite(global_comment,(uInt)size_global_comment,1,zi->filezip) !=1 ) + if (ZWRITE(zi->z_filefunc,zi->filestream, + global_comment,size_global_comment) != size_global_comment) err = ZIP_ERRNO; - fclose(zi->filezip); + + if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0) + if (err == ZIP_OK) + err = ZIP_ERRNO; + TRYFREE(zi); return err; -- cgit v1.2.3-55-g6feb