zip.c
Go to the documentation of this file.
00001 /* zip.c -- IO on .zip files using zlib
00002    Version 1.1, February 14h, 2010
00003    part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
00004 
00005          Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
00006 
00007          Modifications for Zip64 support
00008          Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
00009 
00010          For more info read MiniZip_info.txt
00011 
00012          Changes
00013    Oct-2009 - Mathias Svensson - Remove old C style function prototypes
00014    Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
00015    Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
00016    Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
00017                                  It is used when recreting zip archive with RAW when deleting items from a zip.
00018                                  ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed.
00019    Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
00020    Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
00021 
00022 */
00023 
00024 
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028 #include <time.h>
00029 #include "zlib.h"
00030 #include "zip.h"
00031 
00032 #ifdef STDC
00033 #  include <stddef.h>
00034 #  include <string.h>
00035 #  include <stdlib.h>
00036 #endif
00037 #ifdef NO_ERRNO_H
00038     extern int errno;
00039 #else
00040 #   include <errno.h>
00041 #endif
00042 
00043 
00044 #ifndef local
00045 #  define local static
00046 #endif
00047 /* compile with -Dlocal if your debugger can't find static symbols */
00048 
00049 #ifndef VERSIONMADEBY
00050 # define VERSIONMADEBY   (0x0) /* platform depedent */
00051 #endif
00052 
00053 #ifndef Z_BUFSIZE
00054 #define Z_BUFSIZE (64*1024) //(16384)
00055 #endif
00056 
00057 #ifndef Z_MAXFILENAMEINZIP
00058 #define Z_MAXFILENAMEINZIP (256)
00059 #endif
00060 
00061 #ifndef ALLOC
00062 # define ALLOC(size) (malloc(size))
00063 #endif
00064 #ifndef TRYFREE
00065 # define TRYFREE(p) {if (p) free(p);}
00066 #endif
00067 
00068 /*
00069 #define SIZECENTRALDIRITEM (0x2e)
00070 #define SIZEZIPLOCALHEADER (0x1e)
00071 */
00072 
00073 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
00074 
00075 
00076 // NOT sure that this work on ALL platform
00077 #define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
00078 
00079 #ifndef SEEK_CUR
00080 #define SEEK_CUR    1
00081 #endif
00082 
00083 #ifndef SEEK_END
00084 #define SEEK_END    2
00085 #endif
00086 
00087 #ifndef SEEK_SET
00088 #define SEEK_SET    0
00089 #endif
00090 
00091 #ifndef DEF_MEM_LEVEL
00092 #if MAX_MEM_LEVEL >= 8
00093 #  define DEF_MEM_LEVEL 8
00094 #else
00095 #  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
00096 #endif
00097 #endif
00098 const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
00099 
00100 
00101 #define SIZEDATA_INDATABLOCK (4096-(4*4))
00102 
00103 #define LOCALHEADERMAGIC    (0x04034b50)
00104 #define CENTRALHEADERMAGIC  (0x02014b50)
00105 #define ENDHEADERMAGIC      (0x06054b50)
00106 #define ZIP64ENDHEADERMAGIC      (0x6064b50)
00107 #define ZIP64ENDLOCHEADERMAGIC   (0x7064b50)
00108 
00109 #define FLAG_LOCALHEADER_OFFSET (0x06)
00110 #define CRC_LOCALHEADER_OFFSET  (0x0e)
00111 
00112 #define SIZECENTRALHEADER (0x2e) /* 46 */
00113 
00114 typedef struct linkedlist_datablock_internal_s
00115 {
00116   struct linkedlist_datablock_internal_s* next_datablock;
00117   uLong  avail_in_this_block;
00118   uLong  filled_in_this_block;
00119   uLong  unused; /* for future use and alignement */
00120   unsigned char data[SIZEDATA_INDATABLOCK];
00121 } linkedlist_datablock_internal;
00122 
00123 typedef struct linkedlist_data_s
00124 {
00125     linkedlist_datablock_internal* first_block;
00126     linkedlist_datablock_internal* last_block;
00127 } linkedlist_data;
00128 
00129 
00130 typedef struct
00131 {
00132     z_stream stream;            /* zLib stream structure for inflate */
00133 #ifdef HAVE_BZIP2
00134     bz_stream bstream;          /* bzLib stream structure for bziped */
00135 #endif
00136 
00137     int  stream_initialised;    /* 1 is stream is initialised */
00138     uInt pos_in_buffered_data;  /* last written byte in buffered_data */
00139 
00140     ZPOS64_T pos_local_header;     /* offset of the local header of the file
00141                                      currenty writing */
00142     char* central_header;       /* central header data for the current file */
00143     uLong size_centralExtra;
00144     uLong size_centralheader;   /* size of the central header for cur file */
00145     uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
00146     uLong flag;                 /* flag of the file currently writing */
00147 
00148     int  method;                /* compression method of file currenty wr.*/
00149     int  raw;                   /* 1 for directly writing raw data */
00150     Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
00151     uLong dosDate;
00152     uLong crc32;
00153     int  encrypt;
00154     int  zip64;               /* Add ZIP64 extened information in the extra field */
00155     ZPOS64_T pos_zip64extrainfo;
00156     ZPOS64_T totalCompressedData;
00157     ZPOS64_T totalUncompressedData;
00158 #ifndef NOCRYPT
00159     unsigned long keys[3];     /* keys defining the pseudo-random sequence */
00160     const unsigned long* pcrc_32_tab;
00161     int crypt_header_size;
00162 #endif
00163 } curfile64_info;
00164 
00165 typedef struct
00166 {
00167     zlib_filefunc64_32_def z_filefunc;
00168     voidpf filestream;        /* io structore of the zipfile */
00169     linkedlist_data central_dir;/* datablock with central dir in construction*/
00170     int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/
00171     curfile64_info ci;            /* info on the file curretly writing */
00172 
00173     ZPOS64_T begin_pos;            /* position of the beginning of the zipfile */
00174     ZPOS64_T add_position_when_writting_offset;
00175     ZPOS64_T number_entry;
00176 
00177 #ifndef NO_ADDFILEINEXISTINGZIP
00178     char *globalcomment;
00179 #endif
00180 
00181 } zip64_internal;
00182 
00183 
00184 #ifndef NOCRYPT
00185 #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
00186 #include "crypt.h"
00187 #endif
00188 
00189 local linkedlist_datablock_internal* allocate_new_datablock()
00190 {
00191     linkedlist_datablock_internal* ldi;
00192     ldi = (linkedlist_datablock_internal*)
00193                  ALLOC(sizeof(linkedlist_datablock_internal));
00194     if (ldi!=NULL)
00195     {
00196         ldi->next_datablock = NULL ;
00197         ldi->filled_in_this_block = 0 ;
00198         ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
00199     }
00200     return ldi;
00201 }
00202 
00203 local void free_datablock(linkedlist_datablock_internal* ldi)
00204 {
00205     while (ldi!=NULL)
00206     {
00207         linkedlist_datablock_internal* ldinext = ldi->next_datablock;
00208         TRYFREE(ldi);
00209         ldi = ldinext;
00210     }
00211 }
00212 
00213 local void init_linkedlist(linkedlist_data* ll)
00214 {
00215     ll->first_block = ll->last_block = NULL;
00216 }
00217 
00218 local void free_linkedlist(linkedlist_data* ll)
00219 {
00220     free_datablock(ll->first_block);
00221     ll->first_block = ll->last_block = NULL;
00222 }
00223 
00224 
00225 local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
00226 {
00227     linkedlist_datablock_internal* ldi;
00228     const unsigned char* from_copy;
00229 
00230     if (ll==NULL)
00231         return ZIP_INTERNALERROR;
00232 
00233     if (ll->last_block == NULL)
00234     {
00235         ll->first_block = ll->last_block = allocate_new_datablock();
00236         if (ll->first_block == NULL)
00237             return ZIP_INTERNALERROR;
00238     }
00239 
00240     ldi = ll->last_block;
00241     from_copy = (unsigned char*)buf;
00242 
00243     while (len>0)
00244     {
00245         uInt copy_this;
00246         uInt i;
00247         unsigned char* to_copy;
00248 
00249         if (ldi->avail_in_this_block==0)
00250         {
00251             ldi->next_datablock = allocate_new_datablock();
00252             if (ldi->next_datablock == NULL)
00253                 return ZIP_INTERNALERROR;
00254             ldi = ldi->next_datablock ;
00255             ll->last_block = ldi;
00256         }
00257 
00258         if (ldi->avail_in_this_block < len)
00259             copy_this = (uInt)ldi->avail_in_this_block;
00260         else
00261             copy_this = (uInt)len;
00262 
00263         to_copy = &(ldi->data[ldi->filled_in_this_block]);
00264 
00265         for (i=0;i<copy_this;i++)
00266             *(to_copy+i)=*(from_copy+i);
00267 
00268         ldi->filled_in_this_block += copy_this;
00269         ldi->avail_in_this_block -= copy_this;
00270         from_copy += copy_this ;
00271         len -= copy_this;
00272     }
00273     return ZIP_OK;
00274 }
00275 
00276 
00277 
00278 /****************************************************************************/
00279 
00280 #ifndef NO_ADDFILEINEXISTINGZIP
00281 /* ===========================================================================
00282    Inputs a long in LSB order to the given file
00283    nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
00284 */
00285 
00286 local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
00287 local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
00288 {
00289     unsigned char buf[8];
00290     int n;
00291     for (n = 0; n < nbByte; n++)
00292     {
00293         buf[n] = (unsigned char)(x & 0xff);
00294         x >>= 8;
00295     }
00296     if (x != 0)
00297       {     /* data overflow - hack for ZIP64 (X Roche) */
00298       for (n = 0; n < nbByte; n++)
00299         {
00300           buf[n] = 0xff;
00301         }
00302       }
00303 
00304     if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
00305         return ZIP_ERRNO;
00306     else
00307         return ZIP_OK;
00308 }
00309 
00310 local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
00311 local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
00312 {
00313     unsigned char* buf=(unsigned char*)dest;
00314     int n;
00315     for (n = 0; n < nbByte; n++) {
00316         buf[n] = (unsigned char)(x & 0xff);
00317         x >>= 8;
00318     }
00319 
00320     if (x != 0)
00321     {     /* data overflow - hack for ZIP64 */
00322        for (n = 0; n < nbByte; n++)
00323        {
00324           buf[n] = 0xff;
00325        }
00326     }
00327 }
00328 
00329 /****************************************************************************/
00330 
00331 
00332 local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
00333 {
00334     uLong year = (uLong)ptm->tm_year;
00335     if (year>=1980)
00336         year-=1980;
00337     else if (year>=80)
00338         year-=80;
00339     return
00340       (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
00341         ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
00342 }
00343 
00344 
00345 /****************************************************************************/
00346 
00347 local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
00348 
00349 local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
00350 {
00351     unsigned char c;
00352     int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
00353     if (err==1)
00354     {
00355         *pi = (int)c;
00356         return ZIP_OK;
00357     }
00358     else
00359     {
00360         if (ZERROR64(*pzlib_filefunc_def,filestream))
00361             return ZIP_ERRNO;
00362         else
00363             return ZIP_EOF;
00364     }
00365 }
00366 
00367 
00368 /* ===========================================================================
00369    Reads a long in LSB order from the given gz_stream. Sets
00370 */
00371 local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
00372 
00373 local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
00374 {
00375     uLong x ;
00376     int i = 0;
00377     int err;
00378 
00379     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
00380     x = (uLong)i;
00381 
00382     if (err==ZIP_OK)
00383         err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
00384     x += ((uLong)i)<<8;
00385 
00386     if (err==ZIP_OK)
00387         *pX = x;
00388     else
00389         *pX = 0;
00390     return err;
00391 }
00392 
00393 local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
00394 
00395 local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
00396 {
00397     uLong x ;
00398     int i = 0;
00399     int err;
00400 
00401     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
00402     x = (uLong)i;
00403 
00404     if (err==ZIP_OK)
00405         err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
00406     x += ((uLong)i)<<8;
00407 
00408     if (err==ZIP_OK)
00409         err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
00410     x += ((uLong)i)<<16;
00411 
00412     if (err==ZIP_OK)
00413         err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
00414     x += ((uLong)i)<<24;
00415 
00416     if (err==ZIP_OK)
00417         *pX = x;
00418     else
00419         *pX = 0;
00420     return err;
00421 }
00422 
00423 local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));
00424 
00425 
00426 local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
00427 {
00428   ZPOS64_T x;
00429   int i = 0;
00430   int err;
00431 
00432   err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
00433   x = (ZPOS64_T)i;
00434 
00435   if (err==ZIP_OK)
00436     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
00437   x += ((ZPOS64_T)i)<<8;
00438 
00439   if (err==ZIP_OK)
00440     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
00441   x += ((ZPOS64_T)i)<<16;
00442 
00443   if (err==ZIP_OK)
00444     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
00445   x += ((ZPOS64_T)i)<<24;
00446 
00447   if (err==ZIP_OK)
00448     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
00449   x += ((ZPOS64_T)i)<<32;
00450 
00451   if (err==ZIP_OK)
00452     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
00453   x += ((ZPOS64_T)i)<<40;
00454 
00455   if (err==ZIP_OK)
00456     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
00457   x += ((ZPOS64_T)i)<<48;
00458 
00459   if (err==ZIP_OK)
00460     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
00461   x += ((ZPOS64_T)i)<<56;
00462 
00463   if (err==ZIP_OK)
00464     *pX = x;
00465   else
00466     *pX = 0;
00467 
00468   return err;
00469 }
00470 
00471 #ifndef BUFREADCOMMENT
00472 #define BUFREADCOMMENT (0x400)
00473 #endif
00474 /*
00475   Locate the Central directory of a zipfile (at the end, just before
00476     the global comment)
00477 */
00478 local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
00479 
00480 local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
00481 {
00482   unsigned char* buf;
00483   ZPOS64_T uSizeFile;
00484   ZPOS64_T uBackRead;
00485   ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
00486   ZPOS64_T uPosFound=0;
00487 
00488   if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
00489     return 0;
00490 
00491 
00492   uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
00493 
00494   if (uMaxBack>uSizeFile)
00495     uMaxBack = uSizeFile;
00496 
00497   buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
00498   if (buf==NULL)
00499     return 0;
00500 
00501   uBackRead = 4;
00502   while (uBackRead<uMaxBack)
00503   {
00504     uLong uReadSize;
00505     ZPOS64_T uReadPos ;
00506     int i;
00507     if (uBackRead+BUFREADCOMMENT>uMaxBack)
00508       uBackRead = uMaxBack;
00509     else
00510       uBackRead+=BUFREADCOMMENT;
00511     uReadPos = uSizeFile-uBackRead ;
00512 
00513     uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
00514       (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
00515     if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
00516       break;
00517 
00518     if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
00519       break;
00520 
00521     for (i=(int)uReadSize-3; (i--)>0;)
00522       if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
00523         ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
00524       {
00525         uPosFound = uReadPos+i;
00526         break;
00527       }
00528 
00529       if (uPosFound!=0)
00530         break;
00531   }
00532   TRYFREE(buf);
00533   return uPosFound;
00534 }
00535 
00536 /*
00537 Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
00538 the global comment)
00539 */
00540 local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
00541 
00542 local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
00543 {
00544   unsigned char* buf;
00545   ZPOS64_T uSizeFile;
00546   ZPOS64_T uBackRead;
00547   ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
00548   ZPOS64_T uPosFound=0;
00549   uLong uL;
00550   ZPOS64_T relativeOffset;
00551 
00552   if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
00553     return 0;
00554 
00555   uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
00556 
00557   if (uMaxBack>uSizeFile)
00558     uMaxBack = uSizeFile;
00559 
00560   buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
00561   if (buf==NULL)
00562     return 0;
00563 
00564   uBackRead = 4;
00565   while (uBackRead<uMaxBack)
00566   {
00567     uLong uReadSize;
00568     ZPOS64_T uReadPos;
00569     int i;
00570     if (uBackRead+BUFREADCOMMENT>uMaxBack)
00571       uBackRead = uMaxBack;
00572     else
00573       uBackRead+=BUFREADCOMMENT;
00574     uReadPos = uSizeFile-uBackRead ;
00575 
00576     uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
00577       (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
00578     if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
00579       break;
00580 
00581     if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
00582       break;
00583 
00584     for (i=(int)uReadSize-3; (i--)>0;)
00585     {
00586       // Signature "0x07064b50" Zip64 end of central directory locater
00587       if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
00588       {
00589         uPosFound = uReadPos+i;
00590         break;
00591       }
00592     }
00593 
00594       if (uPosFound!=0)
00595         break;
00596   }
00597 
00598   TRYFREE(buf);
00599   if (uPosFound == 0)
00600     return 0;
00601 
00602   /* Zip64 end of central directory locator */
00603   if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
00604     return 0;
00605 
00606   /* the signature, already checked */
00607   if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
00608     return 0;
00609 
00610   /* number of the disk with the start of the zip64 end of  central directory */
00611   if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
00612     return 0;
00613   if (uL != 0)
00614     return 0;
00615 
00616   /* relative offset of the zip64 end of central directory record */
00617   if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)
00618     return 0;
00619 
00620   /* total number of disks */
00621   if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
00622     return 0;
00623   if (uL != 1)
00624     return 0;
00625 
00626   /* Goto Zip64 end of central directory record */
00627   if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
00628     return 0;
00629 
00630   /* the signature */
00631   if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
00632     return 0;
00633 
00634   if (uL != 0x06064b50) // signature of 'Zip64 end of central directory'
00635     return 0;
00636 
00637   return relativeOffset;
00638 }
00639 
00640 int LoadCentralDirectoryRecord(zip64_internal* pziinit)
00641 {
00642   int err=ZIP_OK;
00643   ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
00644 
00645   ZPOS64_T size_central_dir;     /* size of the central directory  */
00646   ZPOS64_T offset_central_dir;   /* offset of start of central directory */
00647   ZPOS64_T central_pos;
00648   uLong uL;
00649 
00650   uLong number_disk;          /* number of the current dist, used for
00651                               spaning ZIP, unsupported, always 0*/
00652   uLong number_disk_with_CD;  /* number the the disk with central dir, used
00653                               for spaning ZIP, unsupported, always 0*/
00654   ZPOS64_T number_entry;
00655   ZPOS64_T number_entry_CD;      /* total number of entries in
00656                                 the central dir
00657                                 (same than number_entry on nospan) */
00658   uLong VersionMadeBy;
00659   uLong VersionNeeded;
00660   uLong size_comment;
00661 
00662   int hasZIP64Record = 0;
00663 
00664   // check first if we find a ZIP64 record
00665   central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
00666   if(central_pos > 0)
00667   {
00668     hasZIP64Record = 1;
00669   }
00670   else if(central_pos == 0)
00671   {
00672     central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
00673   }
00674 
00675 /* disable to allow appending to empty ZIP archive
00676         if (central_pos==0)
00677             err=ZIP_ERRNO;
00678 */
00679 
00680   if(hasZIP64Record)
00681   {
00682     ZPOS64_T sizeEndOfCentralDirectory;
00683     if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
00684       err=ZIP_ERRNO;
00685 
00686     /* the signature, already checked */
00687     if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
00688       err=ZIP_ERRNO;
00689 
00690     /* size of zip64 end of central directory record */
00691     if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
00692       err=ZIP_ERRNO;
00693 
00694     /* version made by */
00695     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
00696       err=ZIP_ERRNO;
00697 
00698     /* version needed to extract */
00699     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
00700       err=ZIP_ERRNO;
00701 
00702     /* number of this disk */
00703     if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
00704       err=ZIP_ERRNO;
00705 
00706     /* number of the disk with the start of the central directory */
00707     if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
00708       err=ZIP_ERRNO;
00709 
00710     /* total number of entries in the central directory on this disk */
00711     if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
00712       err=ZIP_ERRNO;
00713 
00714     /* total number of entries in the central directory */
00715     if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
00716       err=ZIP_ERRNO;
00717 
00718     if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
00719       err=ZIP_BADZIPFILE;
00720 
00721     /* size of the central directory */
00722     if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
00723       err=ZIP_ERRNO;
00724 
00725     /* offset of start of central directory with respect to the
00726     starting disk number */
00727     if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
00728       err=ZIP_ERRNO;
00729 
00730     // TODO..
00731     // read the comment from the standard central header.
00732     size_comment = 0;
00733   }
00734   else
00735   {
00736     // Read End of central Directory info
00737     if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
00738       err=ZIP_ERRNO;
00739 
00740     /* the signature, already checked */
00741     if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
00742       err=ZIP_ERRNO;
00743 
00744     /* number of this disk */
00745     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
00746       err=ZIP_ERRNO;
00747 
00748     /* number of the disk with the start of the central directory */
00749     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
00750       err=ZIP_ERRNO;
00751 
00752     /* total number of entries in the central dir on this disk */
00753     number_entry = 0;
00754     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
00755       err=ZIP_ERRNO;
00756     else
00757       number_entry = uL;
00758 
00759     /* total number of entries in the central dir */
00760     number_entry_CD = 0;
00761     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
00762       err=ZIP_ERRNO;
00763     else
00764       number_entry_CD = uL;
00765 
00766     if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
00767       err=ZIP_BADZIPFILE;
00768 
00769     /* size of the central directory */
00770     size_central_dir = 0;
00771     if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
00772       err=ZIP_ERRNO;
00773     else
00774       size_central_dir = uL;
00775 
00776     /* offset of start of central directory with respect to the starting disk number */
00777     offset_central_dir = 0;
00778     if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
00779       err=ZIP_ERRNO;
00780     else
00781       offset_central_dir = uL;
00782 
00783 
00784     /* zipfile global comment length */
00785     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
00786       err=ZIP_ERRNO;
00787   }
00788 
00789   if ((central_pos<offset_central_dir+size_central_dir) &&
00790     (err==ZIP_OK))
00791     err=ZIP_BADZIPFILE;
00792 
00793   if (err!=ZIP_OK)
00794   {
00795     ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);
00796     return ZIP_ERRNO;
00797   }
00798 
00799   if (size_comment>0)
00800   {
00801     pziinit->globalcomment = (char*)ALLOC(size_comment+1);
00802     if (pziinit->globalcomment)
00803     {
00804       size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
00805       pziinit->globalcomment[size_comment]=0;
00806     }
00807   }
00808 
00809   byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
00810   pziinit->add_position_when_writting_offset = byte_before_the_zipfile;
00811 
00812   {
00813     ZPOS64_T size_central_dir_to_read = size_central_dir;
00814     size_t buf_size = SIZEDATA_INDATABLOCK;
00815     void* buf_read = (void*)ALLOC(buf_size);
00816     if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
00817       err=ZIP_ERRNO;
00818 
00819     while ((size_central_dir_to_read>0) && (err==ZIP_OK))
00820     {
00821       ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
00822       if (read_this > size_central_dir_to_read)
00823         read_this = size_central_dir_to_read;
00824 
00825       if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)
00826         err=ZIP_ERRNO;
00827 
00828       if (err==ZIP_OK)
00829         err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);
00830 
00831       size_central_dir_to_read-=read_this;
00832     }
00833     TRYFREE(buf_read);
00834   }
00835   pziinit->begin_pos = byte_before_the_zipfile;
00836   pziinit->number_entry = number_entry_CD;
00837 
00838   if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)
00839     err=ZIP_ERRNO;
00840 
00841   return err;
00842 }
00843 
00844 
00845 #endif /* !NO_ADDFILEINEXISTINGZIP*/
00846 
00847 
00848 /************************************************************/
00849 extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
00850 {
00851     zip64_internal ziinit;
00852     zip64_internal* zi;
00853     int err=ZIP_OK;
00854 
00855     ziinit.z_filefunc.zseek32_file = NULL;
00856     ziinit.z_filefunc.ztell32_file = NULL;
00857     if (pzlib_filefunc64_32_def==NULL)
00858         fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
00859     else
00860         ziinit.z_filefunc = *pzlib_filefunc64_32_def;
00861 
00862     ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
00863                   pathname,
00864                   (append == APPEND_STATUS_CREATE) ?
00865                   (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
00866                     (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
00867 
00868     if (ziinit.filestream == NULL)
00869         return NULL;
00870 
00871     if (append == APPEND_STATUS_CREATEAFTER)
00872         ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
00873 
00874     ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
00875     ziinit.in_opened_file_inzip = 0;
00876     ziinit.ci.stream_initialised = 0;
00877     ziinit.number_entry = 0;
00878     ziinit.add_position_when_writting_offset = 0;
00879     init_linkedlist(&(ziinit.central_dir));
00880 
00881 
00882 
00883     zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
00884     if (zi==NULL)
00885     {
00886         ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
00887         return NULL;
00888     }
00889 
00890     /* now we add file in a zipfile */
00891 #    ifndef NO_ADDFILEINEXISTINGZIP
00892     ziinit.globalcomment = NULL;
00893     if (append == APPEND_STATUS_ADDINZIP)
00894     {
00895       // Read and Cache Central Directory Records
00896       err = LoadCentralDirectoryRecord(&ziinit);
00897     }
00898 
00899     if (globalcomment)
00900     {
00901       *globalcomment = ziinit.globalcomment;
00902     }
00903 #    endif /* !NO_ADDFILEINEXISTINGZIP*/
00904 
00905     if (err != ZIP_OK)
00906     {
00907 #    ifndef NO_ADDFILEINEXISTINGZIP
00908         TRYFREE(ziinit.globalcomment);
00909 #    endif /* !NO_ADDFILEINEXISTINGZIP*/
00910         TRYFREE(zi);
00911         return NULL;
00912     }
00913     else
00914     {
00915         *zi = ziinit;
00916         return (zipFile)zi;
00917     }
00918 }
00919 
00920 extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
00921 {
00922     if (pzlib_filefunc32_def != NULL)
00923     {
00924         zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
00925         fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
00926         return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
00927     }
00928     else
00929         return zipOpen3(pathname, append, globalcomment, NULL);
00930 }
00931 
00932 extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
00933 {
00934     if (pzlib_filefunc_def != NULL)
00935     {
00936         zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
00937         zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
00938         zlib_filefunc64_32_def_fill.ztell32_file = NULL;
00939         zlib_filefunc64_32_def_fill.zseek32_file = NULL;
00940         return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
00941     }
00942     else
00943         return zipOpen3(pathname, append, globalcomment, NULL);
00944 }
00945 
00946 
00947 
00948 extern zipFile ZEXPORT zipOpen (const char* pathname, int append)
00949 {
00950     return zipOpen3((const void*)pathname,append,NULL,NULL);
00951 }
00952 
00953 extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
00954 {
00955     return zipOpen3(pathname,append,NULL,NULL);
00956 }
00957 
00958 int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
00959 {
00960   /* write the local header */
00961   int err;
00962   uInt size_filename = (uInt)strlen(filename);
00963   uInt size_extrafield = size_extrafield_local;
00964 
00965   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
00966 
00967   if (err==ZIP_OK)
00968   {
00969     if(zi->ci.zip64)
00970       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */
00971     else
00972       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
00973   }
00974 
00975   if (err==ZIP_OK)
00976     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
00977 
00978   if (err==ZIP_OK)
00979     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
00980 
00981   if (err==ZIP_OK)
00982     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
00983 
00984   // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later
00985   if (err==ZIP_OK)
00986     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
00987   if (err==ZIP_OK)
00988   {
00989     if(zi->ci.zip64)
00990       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */
00991     else
00992       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
00993   }
00994   if (err==ZIP_OK)
00995   {
00996     if(zi->ci.zip64)
00997       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */
00998     else
00999       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
01000   }
01001 
01002   if (err==ZIP_OK)
01003     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
01004 
01005   if(zi->ci.zip64)
01006   {
01007     size_extrafield += 20;
01008   }
01009 
01010   if (err==ZIP_OK)
01011     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
01012 
01013   if ((err==ZIP_OK) && (size_filename > 0))
01014   {
01015     if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
01016       err = ZIP_ERRNO;
01017   }
01018 
01019   if ((err==ZIP_OK) && (size_extrafield_local > 0))
01020   {
01021     if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
01022       err = ZIP_ERRNO;
01023   }
01024 
01025 
01026   if ((err==ZIP_OK) && (zi->ci.zip64))
01027   {
01028       // write the Zip64 extended info
01029       short HeaderID = 1;
01030       short DataSize = 16;
01031       ZPOS64_T CompressedSize = 0;
01032       ZPOS64_T UncompressedSize = 0;
01033 
01034       // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
01035       zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
01036 
01037       err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2);
01038       err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2);
01039 
01040       err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
01041       err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
01042   }
01043 
01044   return err;
01045 }
01046 
01047 /*
01048  NOTE.
01049  When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
01050  before calling this function it can be done with zipRemoveExtraInfoBlock
01051 
01052  It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
01053  unnecessary allocations.
01054  */
01055 extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
01056                                          const void* extrafield_local, uInt size_extrafield_local,
01057                                          const void* extrafield_global, uInt size_extrafield_global,
01058                                          const char* comment, int method, int level, int raw,
01059                                          int windowBits,int memLevel, int strategy,
01060                                          const char* password, uLong crcForCrypting,
01061                                          uLong versionMadeBy, uLong flagBase, int zip64)
01062 {
01063     zip64_internal* zi;
01064     uInt size_filename;
01065     uInt size_comment;
01066     uInt i;
01067     int err = ZIP_OK;
01068 
01069 #    ifdef NOCRYPT
01070     if (password != NULL)
01071         return ZIP_PARAMERROR;
01072 #    endif
01073 
01074     if (file == NULL)
01075         return ZIP_PARAMERROR;
01076 
01077 #ifdef HAVE_BZIP2
01078     if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
01079       return ZIP_PARAMERROR;
01080 #else
01081     if ((method!=0) && (method!=Z_DEFLATED))
01082       return ZIP_PARAMERROR;
01083 #endif
01084 
01085     zi = (zip64_internal*)file;
01086 
01087     if (zi->in_opened_file_inzip == 1)
01088     {
01089         err = zipCloseFileInZip (file);
01090         if (err != ZIP_OK)
01091             return err;
01092     }
01093 
01094     if (filename==NULL)
01095         filename="-";
01096 
01097     if (comment==NULL)
01098         size_comment = 0;
01099     else
01100         size_comment = (uInt)strlen(comment);
01101 
01102     size_filename = (uInt)strlen(filename);
01103 
01104     if (zipfi == NULL)
01105         zi->ci.dosDate = 0;
01106     else
01107     {
01108         if (zipfi->dosDate != 0)
01109             zi->ci.dosDate = zipfi->dosDate;
01110         else
01111           zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
01112     }
01113 
01114     zi->ci.flag = flagBase;
01115     if ((level==8) || (level==9))
01116       zi->ci.flag |= 2;
01117     if ((level==2))
01118       zi->ci.flag |= 4;
01119     if ((level==1))
01120       zi->ci.flag |= 6;
01121     if (password != NULL)
01122       zi->ci.flag |= 1;
01123 
01124     zi->ci.crc32 = 0;
01125     zi->ci.method = method;
01126     zi->ci.encrypt = 0;
01127     zi->ci.stream_initialised = 0;
01128     zi->ci.pos_in_buffered_data = 0;
01129     zi->ci.raw = raw;
01130     zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
01131 
01132     zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
01133     zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
01134 
01135     zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
01136 
01137     zi->ci.size_centralExtra = size_extrafield_global;
01138     zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
01139     /* version info */
01140     zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
01141     zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
01142     zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
01143     zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
01144     zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
01145     zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
01146     zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
01147     zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
01148     zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
01149     zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
01150     zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
01151     zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
01152 
01153     if (zipfi==NULL)
01154         zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
01155     else
01156         zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
01157 
01158     if (zipfi==NULL)
01159         zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
01160     else
01161         zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
01162 
01163     if(zi->ci.pos_local_header >= 0xffffffff)
01164       zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
01165     else
01166       zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4);
01167 
01168     for (i=0;i<size_filename;i++)
01169         *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
01170 
01171     for (i=0;i<size_extrafield_global;i++)
01172         *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
01173               *(((const char*)extrafield_global)+i);
01174 
01175     for (i=0;i<size_comment;i++)
01176         *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
01177               size_extrafield_global+i) = *(comment+i);
01178     if (zi->ci.central_header == NULL)
01179         return ZIP_INTERNALERROR;
01180 
01181     zi->ci.zip64 = zip64;
01182     zi->ci.totalCompressedData = 0;
01183     zi->ci.totalUncompressedData = 0;
01184     zi->ci.pos_zip64extrainfo = 0;
01185 
01186     err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);
01187 
01188 #ifdef HAVE_BZIP2
01189     zi->ci.bstream.avail_in = (uInt)0;
01190     zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
01191     zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
01192     zi->ci.bstream.total_in_hi32 = 0;
01193     zi->ci.bstream.total_in_lo32 = 0;
01194     zi->ci.bstream.total_out_hi32 = 0;
01195     zi->ci.bstream.total_out_lo32 = 0;
01196 #endif
01197 
01198     zi->ci.stream.avail_in = (uInt)0;
01199     zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
01200     zi->ci.stream.next_out = zi->ci.buffered_data;
01201     zi->ci.stream.total_in = 0;
01202     zi->ci.stream.total_out = 0;
01203     zi->ci.stream.data_type = Z_BINARY;
01204 
01205 #ifdef HAVE_BZIP2
01206     if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
01207 #else
01208     if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
01209 #endif
01210     {
01211         if(zi->ci.method == Z_DEFLATED)
01212         {
01213           zi->ci.stream.zalloc = (alloc_func)0;
01214           zi->ci.stream.zfree = (free_func)0;
01215           zi->ci.stream.opaque = (voidpf)0;
01216 
01217           if (windowBits>0)
01218               windowBits = -windowBits;
01219 
01220           err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
01221 
01222           if (err==Z_OK)
01223               zi->ci.stream_initialised = Z_DEFLATED;
01224         }
01225         else if(zi->ci.method == Z_BZIP2ED)
01226         {
01227 #ifdef HAVE_BZIP2
01228             // Init BZip stuff here
01229           zi->ci.bstream.bzalloc = 0;
01230           zi->ci.bstream.bzfree = 0;
01231           zi->ci.bstream.opaque = (voidpf)0;
01232 
01233           err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
01234           if(err == BZ_OK)
01235             zi->ci.stream_initialised = Z_BZIP2ED;
01236 #endif
01237         }
01238 
01239     }
01240 
01241 #    ifndef NOCRYPT
01242     zi->ci.crypt_header_size = 0;
01243     if ((err==Z_OK) && (password != NULL))
01244     {
01245         unsigned char bufHead[RAND_HEAD_LEN];
01246         unsigned int sizeHead;
01247         zi->ci.encrypt = 1;
01248         zi->ci.pcrc_32_tab = get_crc_table();
01249         /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
01250 
01251         sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
01252         zi->ci.crypt_header_size = sizeHead;
01253 
01254         if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
01255                 err = ZIP_ERRNO;
01256     }
01257 #    endif
01258 
01259     if (err==Z_OK)
01260         zi->in_opened_file_inzip = 1;
01261     return err;
01262 }
01263 
01264 extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
01265                                          const void* extrafield_local, uInt size_extrafield_local,
01266                                          const void* extrafield_global, uInt size_extrafield_global,
01267                                          const char* comment, int method, int level, int raw,
01268                                          int windowBits,int memLevel, int strategy,
01269                                          const char* password, uLong crcForCrypting,
01270                                          uLong versionMadeBy, uLong flagBase)
01271 {
01272     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
01273                                  extrafield_local, size_extrafield_local,
01274                                  extrafield_global, size_extrafield_global,
01275                                  comment, method, level, raw,
01276                                  windowBits, memLevel, strategy,
01277                                  password, crcForCrypting, versionMadeBy, flagBase, 0);
01278 }
01279 
01280 extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
01281                                          const void* extrafield_local, uInt size_extrafield_local,
01282                                          const void* extrafield_global, uInt size_extrafield_global,
01283                                          const char* comment, int method, int level, int raw,
01284                                          int windowBits,int memLevel, int strategy,
01285                                          const char* password, uLong crcForCrypting)
01286 {
01287     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
01288                                  extrafield_local, size_extrafield_local,
01289                                  extrafield_global, size_extrafield_global,
01290                                  comment, method, level, raw,
01291                                  windowBits, memLevel, strategy,
01292                                  password, crcForCrypting, VERSIONMADEBY, 0, 0);
01293 }
01294 
01295 extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
01296                                          const void* extrafield_local, uInt size_extrafield_local,
01297                                          const void* extrafield_global, uInt size_extrafield_global,
01298                                          const char* comment, int method, int level, int raw,
01299                                          int windowBits,int memLevel, int strategy,
01300                                          const char* password, uLong crcForCrypting, int zip64)
01301 {
01302     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
01303                                  extrafield_local, size_extrafield_local,
01304                                  extrafield_global, size_extrafield_global,
01305                                  comment, method, level, raw,
01306                                  windowBits, memLevel, strategy,
01307                                  password, crcForCrypting, VERSIONMADEBY, 0, zip64);
01308 }
01309 
01310 extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
01311                                         const void* extrafield_local, uInt size_extrafield_local,
01312                                         const void* extrafield_global, uInt size_extrafield_global,
01313                                         const char* comment, int method, int level, int raw)
01314 {
01315     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
01316                                  extrafield_local, size_extrafield_local,
01317                                  extrafield_global, size_extrafield_global,
01318                                  comment, method, level, raw,
01319                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
01320                                  NULL, 0, VERSIONMADEBY, 0, 0);
01321 }
01322 
01323 extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
01324                                         const void* extrafield_local, uInt size_extrafield_local,
01325                                         const void* extrafield_global, uInt size_extrafield_global,
01326                                         const char* comment, int method, int level, int raw, int zip64)
01327 {
01328     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
01329                                  extrafield_local, size_extrafield_local,
01330                                  extrafield_global, size_extrafield_global,
01331                                  comment, method, level, raw,
01332                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
01333                                  NULL, 0, VERSIONMADEBY, 0, zip64);
01334 }
01335 
01336 extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
01337                                         const void* extrafield_local, uInt size_extrafield_local,
01338                                         const void*extrafield_global, uInt size_extrafield_global,
01339                                         const char* comment, int method, int level, int zip64)
01340 {
01341     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
01342                                  extrafield_local, size_extrafield_local,
01343                                  extrafield_global, size_extrafield_global,
01344                                  comment, method, level, 0,
01345                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
01346                                  NULL, 0, VERSIONMADEBY, 0, zip64);
01347 }
01348 
01349 extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
01350                                         const void* extrafield_local, uInt size_extrafield_local,
01351                                         const void*extrafield_global, uInt size_extrafield_global,
01352                                         const char* comment, int method, int level)
01353 {
01354     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
01355                                  extrafield_local, size_extrafield_local,
01356                                  extrafield_global, size_extrafield_global,
01357                                  comment, method, level, 0,
01358                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
01359                                  NULL, 0, VERSIONMADEBY, 0, 0);
01360 }
01361 
01362 local int zip64FlushWriteBuffer(zip64_internal* zi)
01363 {
01364     int err=ZIP_OK;
01365 
01366     if (zi->ci.encrypt != 0)
01367     {
01368 #ifndef NOCRYPT
01369         uInt i;
01370         int t;
01371         for (i=0;i<zi->ci.pos_in_buffered_data;i++)
01372             zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
01373 #endif
01374     }
01375 
01376     if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
01377       err = ZIP_ERRNO;
01378 
01379     zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
01380 
01381 #ifdef HAVE_BZIP2
01382     if(zi->ci.method == Z_BZIP2ED)
01383     {
01384       zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
01385       zi->ci.bstream.total_in_lo32 = 0;
01386       zi->ci.bstream.total_in_hi32 = 0;
01387     }
01388     else
01389 #endif
01390     {
01391       zi->ci.totalUncompressedData += zi->ci.stream.total_in;
01392       zi->ci.stream.total_in = 0;
01393     }
01394 
01395 
01396     zi->ci.pos_in_buffered_data = 0;
01397 
01398     return err;
01399 }
01400 
01401 extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
01402 {
01403     zip64_internal* zi;
01404     int err=ZIP_OK;
01405 
01406     if (file == NULL)
01407         return ZIP_PARAMERROR;
01408     zi = (zip64_internal*)file;
01409 
01410     if (zi->in_opened_file_inzip == 0)
01411         return ZIP_PARAMERROR;
01412 
01413     zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
01414 
01415 #ifdef HAVE_BZIP2
01416     if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
01417     {
01418       zi->ci.bstream.next_in = (void*)buf;
01419       zi->ci.bstream.avail_in = len;
01420       err = BZ_RUN_OK;
01421 
01422       while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
01423       {
01424         if (zi->ci.bstream.avail_out == 0)
01425         {
01426           if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
01427             err = ZIP_ERRNO;
01428           zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
01429           zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
01430         }
01431 
01432 
01433         if(err != BZ_RUN_OK)
01434           break;
01435 
01436         if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
01437         {
01438           uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
01439 //          uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
01440           err=BZ2_bzCompress(&zi->ci.bstream,  BZ_RUN);
01441 
01442           zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
01443         }
01444       }
01445 
01446       if(err == BZ_RUN_OK)
01447         err = ZIP_OK;
01448     }
01449     else
01450 #endif
01451     {
01452       zi->ci.stream.next_in = (Bytef*)buf;
01453       zi->ci.stream.avail_in = len;
01454 
01455       while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
01456       {
01457           if (zi->ci.stream.avail_out == 0)
01458           {
01459               if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
01460                   err = ZIP_ERRNO;
01461               zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
01462               zi->ci.stream.next_out = zi->ci.buffered_data;
01463           }
01464 
01465 
01466           if(err != ZIP_OK)
01467               break;
01468 
01469           if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
01470           {
01471               uLong uTotalOutBefore = zi->ci.stream.total_out;
01472               err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
01473               if(uTotalOutBefore > zi->ci.stream.total_out)
01474               {
01475                 int bBreak = 0;
01476                 bBreak++;
01477               }
01478 
01479               zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
01480           }
01481           else
01482           {
01483               uInt copy_this,i;
01484               if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
01485                   copy_this = zi->ci.stream.avail_in;
01486               else
01487                   copy_this = zi->ci.stream.avail_out;
01488 
01489               for (i = 0; i < copy_this; i++)
01490                   *(((char*)zi->ci.stream.next_out)+i) =
01491                       *(((const char*)zi->ci.stream.next_in)+i);
01492               {
01493                   zi->ci.stream.avail_in -= copy_this;
01494                   zi->ci.stream.avail_out-= copy_this;
01495                   zi->ci.stream.next_in+= copy_this;
01496                   zi->ci.stream.next_out+= copy_this;
01497                   zi->ci.stream.total_in+= copy_this;
01498                   zi->ci.stream.total_out+= copy_this;
01499                   zi->ci.pos_in_buffered_data += copy_this;
01500               }
01501           }
01502       }// while(...)
01503     }
01504 
01505     return err;
01506 }
01507 
01508 extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
01509 {
01510     return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
01511 }
01512 
01513 extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
01514 {
01515     zip64_internal* zi;
01516     ZPOS64_T compressed_size;
01517     uLong invalidValue = 0xffffffff;
01518     short datasize = 0;
01519     int err=ZIP_OK;
01520 
01521     if (file == NULL)
01522         return ZIP_PARAMERROR;
01523     zi = (zip64_internal*)file;
01524 
01525     if (zi->in_opened_file_inzip == 0)
01526         return ZIP_PARAMERROR;
01527     zi->ci.stream.avail_in = 0;
01528 
01529     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
01530                 {
01531                         while (err==ZIP_OK)
01532                         {
01533                                 uLong uTotalOutBefore;
01534                                 if (zi->ci.stream.avail_out == 0)
01535                                 {
01536                                         if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
01537                                                 err = ZIP_ERRNO;
01538                                         zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
01539                                         zi->ci.stream.next_out = zi->ci.buffered_data;
01540                                 }
01541                                 uTotalOutBefore = zi->ci.stream.total_out;
01542                                 err=deflate(&zi->ci.stream,  Z_FINISH);
01543                                 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
01544                         }
01545                 }
01546     else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
01547     {
01548 #ifdef HAVE_BZIP2
01549       err = BZ_FINISH_OK;
01550       while (err==BZ_FINISH_OK)
01551       {
01552         uLong uTotalOutBefore;
01553         if (zi->ci.bstream.avail_out == 0)
01554         {
01555           if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
01556             err = ZIP_ERRNO;
01557           zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
01558           zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
01559         }
01560         uTotalOutBefore = zi->ci.bstream.total_out_lo32;
01561         err=BZ2_bzCompress(&zi->ci.bstream,  BZ_FINISH);
01562         if(err == BZ_STREAM_END)
01563           err = Z_STREAM_END;
01564 
01565         zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
01566       }
01567 
01568       if(err == BZ_FINISH_OK)
01569         err = ZIP_OK;
01570 #endif
01571     }
01572 
01573     if (err==Z_STREAM_END)
01574         err=ZIP_OK; /* this is normal */
01575 
01576     if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
01577                 {
01578         if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
01579             err = ZIP_ERRNO;
01580                 }
01581 
01582     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
01583     {
01584         int tmp_err = deflateEnd(&zi->ci.stream);
01585         if (err == ZIP_OK)
01586             err = tmp_err;
01587         zi->ci.stream_initialised = 0;
01588     }
01589 #ifdef HAVE_BZIP2
01590     else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
01591     {
01592       int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
01593                         if (err==ZIP_OK)
01594                                 err = tmperr;
01595                         zi->ci.stream_initialised = 0;
01596     }
01597 #endif
01598 
01599     if (!zi->ci.raw)
01600     {
01601         crc32 = (uLong)zi->ci.crc32;
01602         uncompressed_size = zi->ci.totalUncompressedData;
01603     }
01604     compressed_size = zi->ci.totalCompressedData;
01605 
01606 #    ifndef NOCRYPT
01607     compressed_size += zi->ci.crypt_header_size;
01608 #    endif
01609 
01610     // update Current Item crc and sizes,
01611     if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
01612     {
01613       /*version Made by*/
01614       zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
01615       /*version needed*/
01616       zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);
01617 
01618     }
01619 
01620     zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
01621 
01622 
01623     if(compressed_size >= 0xffffffff)
01624       zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
01625     else
01626       zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
01627 
01629     if (zi->ci.stream.data_type == Z_ASCII)
01630         zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
01631 
01632     if(uncompressed_size >= 0xffffffff)
01633       zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
01634     else
01635       zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
01636 
01637     // Add ZIP64 extra info field for uncompressed size
01638     if(uncompressed_size >= 0xffffffff)
01639       datasize += 8;
01640 
01641     // Add ZIP64 extra info field for compressed size
01642     if(compressed_size >= 0xffffffff)
01643       datasize += 8;
01644 
01645     // Add ZIP64 extra info field for relative offset to local file header of current file
01646     if(zi->ci.pos_local_header >= 0xffffffff)
01647       datasize += 8;
01648 
01649     if(datasize > 0)
01650     {
01651       char* p = NULL;
01652 
01653       if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
01654       {
01655         // we can not write more data to the buffer that we have room for.
01656         return ZIP_BADZIPFILE;
01657       }
01658 
01659       p = zi->ci.central_header + zi->ci.size_centralheader;
01660 
01661       // Add Extra Information Header for 'ZIP64 information'
01662       zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
01663       p += 2;
01664       zip64local_putValue_inmemory(p, datasize, 2); // DataSize
01665       p += 2;
01666 
01667       if(uncompressed_size >= 0xffffffff)
01668       {
01669         zip64local_putValue_inmemory(p, uncompressed_size, 8);
01670         p += 8;
01671       }
01672 
01673       if(compressed_size >= 0xffffffff)
01674       {
01675         zip64local_putValue_inmemory(p, compressed_size, 8);
01676         p += 8;
01677       }
01678 
01679       if(zi->ci.pos_local_header >= 0xffffffff)
01680       {
01681         zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
01682         p += 8;
01683       }
01684 
01685       // Update how much extra free space we got in the memory buffer
01686       // and increase the centralheader size so the new ZIP64 fields are included
01687       // ( 4 below is the size of HeaderID and DataSize field )
01688       zi->ci.size_centralExtraFree -= datasize + 4;
01689       zi->ci.size_centralheader += datasize + 4;
01690 
01691       // Update the extra info size field
01692       zi->ci.size_centralExtra += datasize + 4;
01693       zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
01694     }
01695 
01696     if (err==ZIP_OK)
01697         err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
01698 
01699     free(zi->ci.central_header);
01700 
01701     if (err==ZIP_OK)
01702     {
01703         // Update the LocalFileHeader with the new values.
01704 
01705         ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
01706 
01707         if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
01708             err = ZIP_ERRNO;
01709 
01710         if (err==ZIP_OK)
01711             err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
01712 
01713         if(uncompressed_size >= 0xffffffff)
01714         {
01715           if(zi->ci.pos_zip64extrainfo > 0)
01716           {
01717             // Update the size in the ZIP64 extended field.
01718             if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
01719               err = ZIP_ERRNO;
01720 
01721             if (err==ZIP_OK) /* compressed size, unknown */
01722               err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
01723 
01724             if (err==ZIP_OK) /* uncompressed size, unknown */
01725               err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
01726           }
01727         }
01728         else
01729         {
01730           if (err==ZIP_OK) /* compressed size, unknown */
01731               err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
01732 
01733           if (err==ZIP_OK) /* uncompressed size, unknown */
01734               err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
01735         }
01736 
01737         if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
01738             err = ZIP_ERRNO;
01739     }
01740 
01741     zi->number_entry ++;
01742     zi->in_opened_file_inzip = 0;
01743 
01744     return err;
01745 }
01746 
01747 extern int ZEXPORT zipCloseFileInZip (zipFile file)
01748 {
01749     return zipCloseFileInZipRaw (file,0,0);
01750 }
01751 
01752 int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
01753 {
01754   int err = ZIP_OK;
01755   ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;
01756 
01757   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
01758 
01759   /*num disks*/
01760     if (err==ZIP_OK) /* number of the disk with the start of the central directory */
01761       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
01762 
01763   /*relative offset*/
01764     if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
01765       err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
01766 
01767   /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
01768     if (err==ZIP_OK) /* number of the disk with the start of the central directory */
01769       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
01770 
01771     return err;
01772 }
01773 
01774 int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
01775 {
01776   int err = ZIP_OK;
01777 
01778   uLong Zip64DataSize = 44;
01779 
01780   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
01781 
01782   if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
01783     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?
01784 
01785   if (err==ZIP_OK) /* version made by */
01786     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
01787 
01788   if (err==ZIP_OK) /* version needed */
01789     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
01790 
01791   if (err==ZIP_OK) /* number of this disk */
01792     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
01793 
01794   if (err==ZIP_OK) /* number of the disk with the start of the central directory */
01795     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
01796 
01797   if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
01798     err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
01799 
01800   if (err==ZIP_OK) /* total number of entries in the central dir */
01801     err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
01802 
01803   if (err==ZIP_OK) /* size of the central directory */
01804     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
01805 
01806   if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
01807   {
01808     ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
01809     err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
01810   }
01811   return err;
01812 }
01813 int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
01814 {
01815   int err = ZIP_OK;
01816 
01817   /*signature*/
01818   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
01819 
01820   if (err==ZIP_OK) /* number of this disk */
01821     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
01822 
01823   if (err==ZIP_OK) /* number of the disk with the start of the central directory */
01824     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
01825 
01826   if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
01827   {
01828     {
01829       if(zi->number_entry >= 0xFFFF)
01830         err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
01831       else
01832         err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
01833     }
01834   }
01835 
01836   if (err==ZIP_OK) /* total number of entries in the central dir */
01837   {
01838     if(zi->number_entry >= 0xFFFF)
01839       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
01840     else
01841       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
01842   }
01843 
01844   if (err==ZIP_OK) /* size of the central directory */
01845     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
01846 
01847   if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
01848   {
01849     ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
01850     if(pos >= 0xffffffff)
01851     {
01852       err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
01853     }
01854     else
01855                   err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
01856   }
01857 
01858    return err;
01859 }
01860 
01861 int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
01862 {
01863   int err = ZIP_OK;
01864   uInt size_global_comment = 0;
01865 
01866   if(global_comment != NULL)
01867     size_global_comment = (uInt)strlen(global_comment);
01868 
01869   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
01870 
01871   if (err == ZIP_OK && size_global_comment > 0)
01872   {
01873     if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
01874       err = ZIP_ERRNO;
01875   }
01876   return err;
01877 }
01878 
01879 extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
01880 {
01881     zip64_internal* zi;
01882     int err = 0;
01883     uLong size_centraldir = 0;
01884     ZPOS64_T centraldir_pos_inzip;
01885     ZPOS64_T pos;
01886 
01887     if (file == NULL)
01888         return ZIP_PARAMERROR;
01889 
01890     zi = (zip64_internal*)file;
01891 
01892     if (zi->in_opened_file_inzip == 1)
01893     {
01894         err = zipCloseFileInZip (file);
01895     }
01896 
01897 #ifndef NO_ADDFILEINEXISTINGZIP
01898     if (global_comment==NULL)
01899         global_comment = zi->globalcomment;
01900 #endif
01901 
01902     centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
01903 
01904     if (err==ZIP_OK)
01905     {
01906         linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
01907         while (ldi!=NULL)
01908         {
01909             if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
01910             {
01911                 if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
01912                     err = ZIP_ERRNO;
01913             }
01914 
01915             size_centraldir += ldi->filled_in_this_block;
01916             ldi = ldi->next_datablock;
01917         }
01918     }
01919     free_linkedlist(&(zi->central_dir));
01920 
01921     pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
01922     if(pos >= 0xffffffff)
01923     {
01924       ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
01925       Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
01926 
01927       Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
01928     }
01929 
01930     if (err==ZIP_OK)
01931       err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
01932 
01933     if(err == ZIP_OK)
01934       err = Write_GlobalComment(zi, global_comment);
01935 
01936     if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)
01937         if (err == ZIP_OK)
01938             err = ZIP_ERRNO;
01939 
01940 #ifndef NO_ADDFILEINEXISTINGZIP
01941     TRYFREE(zi->globalcomment);
01942 #endif
01943     TRYFREE(zi);
01944 
01945     return err;
01946 }
01947 
01948 extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
01949 {
01950   char* p = pData;
01951   int size = 0;
01952   char* pNewHeader;
01953   char* pTmp;
01954   short header;
01955   short dataSize;
01956 
01957   int retVal = ZIP_OK;
01958 
01959   if(pData == NULL || *dataLen < 4)
01960     return ZIP_PARAMERROR;
01961 
01962   pNewHeader = (char*)ALLOC(*dataLen);
01963   pTmp = pNewHeader;
01964 
01965   while(p < (pData + *dataLen))
01966   {
01967     header = *(short*)p;
01968     dataSize = *(((short*)p)+1);
01969 
01970     if( header == sHeader ) // Header found.
01971     {
01972       p += dataSize + 4; // skip it. do not copy to temp buffer
01973     }
01974     else
01975     {
01976       // Extra Info block should not be removed, So copy it to the temp buffer.
01977       memcpy(pTmp, p, dataSize + 4);
01978       p += dataSize + 4;
01979       size += dataSize + 4;
01980     }
01981 
01982   }
01983 
01984   if(size < *dataLen)
01985   {
01986     // clean old extra info block.
01987     memset(pData,0, *dataLen);
01988 
01989     // copy the new extra info block over the old
01990     if(size > 0)
01991       memcpy(pData, pNewHeader, size);
01992 
01993     // set the new extra info size
01994     *dataLen = size;
01995 
01996     retVal = ZIP_OK;
01997   }
01998   else
01999     retVal = ZIP_ERRNO;
02000 
02001   TRYFREE(pNewHeader);
02002 
02003   return retVal;
02004 }


re_object_recorder
Author(s): Andreas Koch
autogenerated on Sun Jan 5 2014 11:39:12