"Fossies" - the Fresh Open Source Software Archive

Member "muscle/zlib/zlib/contrib/minizip/zip.c" (21 Nov 2020, 65842 Bytes) of package /linux/privat/muscle7.62.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "zip.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 7.61_vs_7.62.

    1 /* zip.c -- IO on .zip files using zlib
    2    Version 1.1, February 14h, 2010
    3    part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
    4 
    5          Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
    6 
    7          Modifications for Zip64 support
    8          Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
    9 
   10          For more info read MiniZip_info.txt
   11 
   12          Changes
   13    Oct-2009 - Mathias Svensson - Remove old C style function prototypes
   14    Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
   15    Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
   16    Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
   17                                  It is used when recreting zip archive with RAW when deleting items from a zip.
   18                                  ZIP64 data is automatically added to items that needs it, and existing ZIP64 data need to be removed.
   19    Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
   20    Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
   21 
   22 */
   23 
   24 
   25 #include <stdio.h>
   26 #include <stdlib.h>
   27 #include <string.h>
   28 #include <time.h>
   29 #include "zlib.h"
   30 #include "zip.h"
   31 
   32 #ifdef STDC
   33 #  include <stddef.h>
   34 #  include <string.h>
   35 #  include <stdlib.h>
   36 #endif
   37 #ifdef NO_ERRNO_H
   38     extern int errno;
   39 #else
   40 #   include <errno.h>
   41 #endif
   42 
   43 
   44 #ifndef local
   45 #  define local static
   46 #endif
   47 /* compile with -Dlocal if your debugger can't find static symbols */
   48 
   49 #ifndef VERSIONMADEBY
   50 # define VERSIONMADEBY   (0x0) /* platform depedent */
   51 #endif
   52 
   53 #ifndef Z_BUFSIZE
   54 #define Z_BUFSIZE (64*1024) //(16384)
   55 #endif
   56 
   57 #ifndef Z_MAXFILENAMEINZIP
   58 #define Z_MAXFILENAMEINZIP (256)
   59 #endif
   60 
   61 #ifndef ALLOC
   62 # define ALLOC(size) (malloc(size))
   63 #endif
   64 #ifndef TRYFREE
   65 # define TRYFREE(p) {if (p) free(p);}
   66 #endif
   67 
   68 /*
   69 #define SIZECENTRALDIRITEM (0x2e)
   70 #define SIZEZIPLOCALHEADER (0x1e)
   71 */
   72 
   73 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
   74 
   75 
   76 // NOT sure that this work on ALL platform
   77 #define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
   78 
   79 #ifndef SEEK_CUR
   80 #define SEEK_CUR    1
   81 #endif
   82 
   83 #ifndef SEEK_END
   84 #define SEEK_END    2
   85 #endif
   86 
   87 #ifndef SEEK_SET
   88 #define SEEK_SET    0
   89 #endif
   90 
   91 #ifndef DEF_MEM_LEVEL
   92 #if MAX_MEM_LEVEL >= 8
   93 #  define DEF_MEM_LEVEL 8
   94 #else
   95 #  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
   96 #endif
   97 #endif
   98 const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
   99 
  100 
  101 #define SIZEDATA_INDATABLOCK (4096-(4*4))
  102 
  103 #define LOCALHEADERMAGIC    (0x04034b50)
  104 #define CENTRALHEADERMAGIC  (0x02014b50)
  105 #define ENDHEADERMAGIC      (0x06054b50)
  106 #define ZIP64ENDHEADERMAGIC      (0x6064b50)
  107 #define ZIP64ENDLOCHEADERMAGIC   (0x7064b50)
  108 
  109 #define FLAG_LOCALHEADER_OFFSET (0x06)
  110 #define CRC_LOCALHEADER_OFFSET  (0x0e)
  111 
  112 #define SIZECENTRALHEADER (0x2e) /* 46 */
  113 
  114 typedef struct linkedlist_datablock_internal_s
  115 {
  116   struct linkedlist_datablock_internal_s* next_datablock;
  117   uLong  avail_in_this_block;
  118   uLong  filled_in_this_block;
  119   uLong  unused; /* for future use and alignment */
  120   unsigned char data[SIZEDATA_INDATABLOCK];
  121 } linkedlist_datablock_internal;
  122 
  123 typedef struct linkedlist_data_s
  124 {
  125     linkedlist_datablock_internal* first_block;
  126     linkedlist_datablock_internal* last_block;
  127 } linkedlist_data;
  128 
  129 
  130 typedef struct
  131 {
  132     z_stream stream;            /* zLib stream structure for inflate */
  133 #ifdef HAVE_BZIP2
  134     bz_stream bstream;          /* bzLib stream structure for bziped */
  135 #endif
  136 
  137     int  stream_initialised;    /* 1 is stream is initialised */
  138     uInt pos_in_buffered_data;  /* last written byte in buffered_data */
  139 
  140     ZPOS64_T pos_local_header;     /* offset of the local header of the file
  141                                      currenty writing */
  142     char* central_header;       /* central header data for the current file */
  143     uLong size_centralExtra;
  144     uLong size_centralheader;   /* size of the central header for cur file */
  145     uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
  146     uLong flag;                 /* flag of the file currently writing */
  147 
  148     int  method;                /* compression method of file currenty wr.*/
  149     int  raw;                   /* 1 for directly writing raw data */
  150     Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
  151     uLong dosDate;
  152     uLong crc32;
  153     int  encrypt;
  154     int  zip64;               /* Add ZIP64 extened information in the extra field */
  155     ZPOS64_T pos_zip64extrainfo;
  156     ZPOS64_T totalCompressedData;
  157     ZPOS64_T totalUncompressedData;
  158 #ifndef NOCRYPT
  159     unsigned long keys[3];     /* keys defining the pseudo-random sequence */
  160     const z_crc_t* pcrc_32_tab;
  161     int crypt_header_size;
  162 #endif
  163 } curfile64_info;
  164 
  165 typedef struct
  166 {
  167     zlib_filefunc64_32_def z_filefunc;
  168     voidpf filestream;        /* io structore of the zipfile */
  169     linkedlist_data central_dir;/* datablock with central dir in construction*/
  170     int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/
  171     curfile64_info ci;            /* info on the file curretly writing */
  172 
  173     ZPOS64_T begin_pos;            /* position of the beginning of the zipfile */
  174     ZPOS64_T add_position_when_writing_offset;
  175     ZPOS64_T number_entry;
  176 
  177 #ifndef NO_ADDFILEINEXISTINGZIP
  178     char *globalcomment;
  179 #endif
  180 
  181 } zip64_internal;
  182 
  183 
  184 #ifndef NOCRYPT
  185 #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
  186 #include "crypt.h"
  187 #endif
  188 
  189 local linkedlist_datablock_internal* allocate_new_datablock()
  190 {
  191     linkedlist_datablock_internal* ldi;
  192     ldi = (linkedlist_datablock_internal*)
  193                  ALLOC(sizeof(linkedlist_datablock_internal));
  194     if (ldi!=NULL)
  195     {
  196         ldi->next_datablock = NULL ;
  197         ldi->filled_in_this_block = 0 ;
  198         ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
  199     }
  200     return ldi;
  201 }
  202 
  203 local void free_datablock(linkedlist_datablock_internal* ldi)
  204 {
  205     while (ldi!=NULL)
  206     {
  207         linkedlist_datablock_internal* ldinext = ldi->next_datablock;
  208         TRYFREE(ldi);
  209         ldi = ldinext;
  210     }
  211 }
  212 
  213 local void init_linkedlist(linkedlist_data* ll)
  214 {
  215     ll->first_block = ll->last_block = NULL;
  216 }
  217 
  218 local void free_linkedlist(linkedlist_data* ll)
  219 {
  220     free_datablock(ll->first_block);
  221     ll->first_block = ll->last_block = NULL;
  222 }
  223 
  224 
  225 local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
  226 {
  227     linkedlist_datablock_internal* ldi;
  228     const unsigned char* from_copy;
  229 
  230     if (ll==NULL)
  231         return ZIP_INTERNALERROR;
  232 
  233     if (ll->last_block == NULL)
  234     {
  235         ll->first_block = ll->last_block = allocate_new_datablock();
  236         if (ll->first_block == NULL)
  237             return ZIP_INTERNALERROR;
  238     }
  239 
  240     ldi = ll->last_block;
  241     from_copy = (unsigned char*)buf;
  242 
  243     while (len>0)
  244     {
  245         uInt copy_this;
  246         uInt i;
  247         unsigned char* to_copy;
  248 
  249         if (ldi->avail_in_this_block==0)
  250         {
  251             ldi->next_datablock = allocate_new_datablock();
  252             if (ldi->next_datablock == NULL)
  253                 return ZIP_INTERNALERROR;
  254             ldi = ldi->next_datablock ;
  255             ll->last_block = ldi;
  256         }
  257 
  258         if (ldi->avail_in_this_block < len)
  259             copy_this = (uInt)ldi->avail_in_this_block;
  260         else
  261             copy_this = (uInt)len;
  262 
  263         to_copy = &(ldi->data[ldi->filled_in_this_block]);
  264 
  265         for (i=0;i<copy_this;i++)
  266             *(to_copy+i)=*(from_copy+i);
  267 
  268         ldi->filled_in_this_block += copy_this;
  269         ldi->avail_in_this_block -= copy_this;
  270         from_copy += copy_this ;
  271         len -= copy_this;
  272     }
  273     return ZIP_OK;
  274 }
  275 
  276 
  277 
  278 /****************************************************************************/
  279 
  280 #ifndef NO_ADDFILEINEXISTINGZIP
  281 /* ===========================================================================
  282    Inputs a long in LSB order to the given file
  283    nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
  284 */
  285 
  286 local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
  287 local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
  288 {
  289     unsigned char buf[8];
  290     int n;
  291     for (n = 0; n < nbByte; n++)
  292     {
  293         buf[n] = (unsigned char)(x & 0xff);
  294         x >>= 8;
  295     }
  296     if (x != 0)
  297       {     /* data overflow - hack for ZIP64 (X Roche) */
  298       for (n = 0; n < nbByte; n++)
  299         {
  300           buf[n] = 0xff;
  301         }
  302       }
  303 
  304     if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
  305         return ZIP_ERRNO;
  306     else
  307         return ZIP_OK;
  308 }
  309 
  310 local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
  311 local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
  312 {
  313     unsigned char* buf=(unsigned char*)dest;
  314     int n;
  315     for (n = 0; n < nbByte; n++) {
  316         buf[n] = (unsigned char)(x & 0xff);
  317         x >>= 8;
  318     }
  319 
  320     if (x != 0)
  321     {     /* data overflow - hack for ZIP64 */
  322        for (n = 0; n < nbByte; n++)
  323        {
  324           buf[n] = 0xff;
  325        }
  326     }
  327 }
  328 
  329 /****************************************************************************/
  330 
  331 
  332 local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
  333 {
  334     uLong year = (uLong)ptm->tm_year;
  335     if (year>=1980)
  336         year-=1980;
  337     else if (year>=80)
  338         year-=80;
  339     return
  340       (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
  341         ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
  342 }
  343 
  344 
  345 /****************************************************************************/
  346 
  347 local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
  348 
  349 local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
  350 {
  351     unsigned char c;
  352     int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
  353     if (err==1)
  354     {
  355         *pi = (int)c;
  356         return ZIP_OK;
  357     }
  358     else
  359     {
  360         if (ZERROR64(*pzlib_filefunc_def,filestream))
  361             return ZIP_ERRNO;
  362         else
  363             return ZIP_EOF;
  364     }
  365 }
  366 
  367 
  368 /* ===========================================================================
  369    Reads a long in LSB order from the given gz_stream. Sets
  370 */
  371 local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
  372 
  373 local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
  374 {
  375     uLong x ;
  376     int i = 0;
  377     int err;
  378 
  379     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  380     x = (uLong)i;
  381 
  382     if (err==ZIP_OK)
  383         err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  384     x += ((uLong)i)<<8;
  385 
  386     if (err==ZIP_OK)
  387         *pX = x;
  388     else
  389         *pX = 0;
  390     return err;
  391 }
  392 
  393 local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
  394 
  395 local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
  396 {
  397     uLong x ;
  398     int i = 0;
  399     int err;
  400 
  401     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  402     x = (uLong)i;
  403 
  404     if (err==ZIP_OK)
  405         err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  406     x += ((uLong)i)<<8;
  407 
  408     if (err==ZIP_OK)
  409         err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  410     x += ((uLong)i)<<16;
  411 
  412     if (err==ZIP_OK)
  413         err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  414     x += ((uLong)i)<<24;
  415 
  416     if (err==ZIP_OK)
  417         *pX = x;
  418     else
  419         *pX = 0;
  420     return err;
  421 }
  422 
  423 local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));
  424 
  425 
  426 local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
  427 {
  428   ZPOS64_T x;
  429   int i = 0;
  430   int err;
  431 
  432   err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  433   x = (ZPOS64_T)i;
  434 
  435   if (err==ZIP_OK)
  436     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  437   x += ((ZPOS64_T)i)<<8;
  438 
  439   if (err==ZIP_OK)
  440     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  441   x += ((ZPOS64_T)i)<<16;
  442 
  443   if (err==ZIP_OK)
  444     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  445   x += ((ZPOS64_T)i)<<24;
  446 
  447   if (err==ZIP_OK)
  448     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  449   x += ((ZPOS64_T)i)<<32;
  450 
  451   if (err==ZIP_OK)
  452     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  453   x += ((ZPOS64_T)i)<<40;
  454 
  455   if (err==ZIP_OK)
  456     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  457   x += ((ZPOS64_T)i)<<48;
  458 
  459   if (err==ZIP_OK)
  460     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
  461   x += ((ZPOS64_T)i)<<56;
  462 
  463   if (err==ZIP_OK)
  464     *pX = x;
  465   else
  466     *pX = 0;
  467 
  468   return err;
  469 }
  470 
  471 #ifndef BUFREADCOMMENT
  472 #define BUFREADCOMMENT (0x400)
  473 #endif
  474 /*
  475   Locate the Central directory of a zipfile (at the end, just before
  476     the global comment)
  477 */
  478 local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
  479 
  480 local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
  481 {
  482   unsigned char* buf;
  483   ZPOS64_T uSizeFile;
  484   ZPOS64_T uBackRead;
  485   ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
  486   ZPOS64_T uPosFound=0;
  487 
  488   if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
  489     return 0;
  490 
  491 
  492   uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
  493 
  494   if (uMaxBack>uSizeFile)
  495     uMaxBack = uSizeFile;
  496 
  497   buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
  498   if (buf==NULL)
  499     return 0;
  500 
  501   uBackRead = 4;
  502   while (uBackRead<uMaxBack)
  503   {
  504     uLong uReadSize;
  505     ZPOS64_T uReadPos ;
  506     int i;
  507     if (uBackRead+BUFREADCOMMENT>uMaxBack)
  508       uBackRead = uMaxBack;
  509     else
  510       uBackRead+=BUFREADCOMMENT;
  511     uReadPos = uSizeFile-uBackRead ;
  512 
  513     uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
  514       (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
  515     if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
  516       break;
  517 
  518     if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
  519       break;
  520 
  521     for (i=(int)uReadSize-3; (i--)>0;)
  522       if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
  523         ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
  524       {
  525         uPosFound = uReadPos+i;
  526         break;
  527       }
  528 
  529       if (uPosFound!=0)
  530         break;
  531   }
  532   TRYFREE(buf);
  533   return uPosFound;
  534 }
  535 
  536 /*
  537 Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
  538 the global comment)
  539 */
  540 local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
  541 
  542 local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
  543 {
  544   unsigned char* buf;
  545   ZPOS64_T uSizeFile;
  546   ZPOS64_T uBackRead;
  547   ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
  548   ZPOS64_T uPosFound=0;
  549   uLong uL;
  550   ZPOS64_T relativeOffset;
  551 
  552   if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
  553     return 0;
  554 
  555   uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
  556 
  557   if (uMaxBack>uSizeFile)
  558     uMaxBack = uSizeFile;
  559 
  560   buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
  561   if (buf==NULL)
  562     return 0;
  563 
  564   uBackRead = 4;
  565   while (uBackRead<uMaxBack)
  566   {
  567     uLong uReadSize;
  568     ZPOS64_T uReadPos;
  569     int i;
  570     if (uBackRead+BUFREADCOMMENT>uMaxBack)
  571       uBackRead = uMaxBack;
  572     else
  573       uBackRead+=BUFREADCOMMENT;
  574     uReadPos = uSizeFile-uBackRead ;
  575 
  576     uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
  577       (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
  578     if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
  579       break;
  580 
  581     if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
  582       break;
  583 
  584     for (i=(int)uReadSize-3; (i--)>0;)
  585     {
  586       // Signature "0x07064b50" Zip64 end of central directory locater
  587       if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
  588       {
  589         uPosFound = uReadPos+i;
  590         break;
  591       }
  592     }
  593 
  594       if (uPosFound!=0)
  595         break;
  596   }
  597 
  598   TRYFREE(buf);
  599   if (uPosFound == 0)
  600     return 0;
  601 
  602   /* Zip64 end of central directory locator */
  603   if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
  604     return 0;
  605 
  606   /* the signature, already checked */
  607   if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
  608     return 0;
  609 
  610   /* number of the disk with the start of the zip64 end of  central directory */
  611   if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
  612     return 0;
  613   if (uL != 0)
  614     return 0;
  615 
  616   /* relative offset of the zip64 end of central directory record */
  617   if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)
  618     return 0;
  619 
  620   /* total number of disks */
  621   if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
  622     return 0;
  623   if (uL != 1)
  624     return 0;
  625 
  626   /* Goto Zip64 end of central directory record */
  627   if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
  628     return 0;
  629 
  630   /* the signature */
  631   if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
  632     return 0;
  633 
  634   if (uL != 0x06064b50) // signature of 'Zip64 end of central directory'
  635     return 0;
  636 
  637   return relativeOffset;
  638 }
  639 
  640 int LoadCentralDirectoryRecord(zip64_internal* pziinit)
  641 {
  642   int err=ZIP_OK;
  643   ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
  644 
  645   ZPOS64_T size_central_dir;     /* size of the central directory  */
  646   ZPOS64_T offset_central_dir;   /* offset of start of central directory */
  647   ZPOS64_T central_pos;
  648   uLong uL;
  649 
  650   uLong number_disk;          /* number of the current dist, used for
  651                               spaning ZIP, unsupported, always 0*/
  652   uLong number_disk_with_CD;  /* number the the disk with central dir, used
  653                               for spaning ZIP, unsupported, always 0*/
  654   ZPOS64_T number_entry;
  655   ZPOS64_T number_entry_CD;      /* total number of entries in
  656                                 the central dir
  657                                 (same than number_entry on nospan) */
  658   uLong VersionMadeBy;
  659   uLong VersionNeeded;
  660   uLong size_comment;
  661 
  662   int hasZIP64Record = 0;
  663 
  664   // check first if we find a ZIP64 record
  665   central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
  666   if(central_pos > 0)
  667   {
  668     hasZIP64Record = 1;
  669   }
  670   else if(central_pos == 0)
  671   {
  672     central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
  673   }
  674 
  675 /* disable to allow appending to empty ZIP archive
  676         if (central_pos==0)
  677             err=ZIP_ERRNO;
  678 */
  679 
  680   if(hasZIP64Record)
  681   {
  682     ZPOS64_T sizeEndOfCentralDirectory;
  683     if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
  684       err=ZIP_ERRNO;
  685 
  686     /* the signature, already checked */
  687     if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
  688       err=ZIP_ERRNO;
  689 
  690     /* size of zip64 end of central directory record */
  691     if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
  692       err=ZIP_ERRNO;
  693 
  694     /* version made by */
  695     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
  696       err=ZIP_ERRNO;
  697 
  698     /* version needed to extract */
  699     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
  700       err=ZIP_ERRNO;
  701 
  702     /* number of this disk */
  703     if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
  704       err=ZIP_ERRNO;
  705 
  706     /* number of the disk with the start of the central directory */
  707     if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
  708       err=ZIP_ERRNO;
  709 
  710     /* total number of entries in the central directory on this disk */
  711     if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
  712       err=ZIP_ERRNO;
  713 
  714     /* total number of entries in the central directory */
  715     if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
  716       err=ZIP_ERRNO;
  717 
  718     if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
  719       err=ZIP_BADZIPFILE;
  720 
  721     /* size of the central directory */
  722     if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
  723       err=ZIP_ERRNO;
  724 
  725     /* offset of start of central directory with respect to the
  726     starting disk number */
  727     if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
  728       err=ZIP_ERRNO;
  729 
  730     // TODO..
  731     // read the comment from the standard central header.
  732     size_comment = 0;
  733   }
  734   else
  735   {
  736     // Read End of central Directory info
  737     if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
  738       err=ZIP_ERRNO;
  739 
  740     /* the signature, already checked */
  741     if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
  742       err=ZIP_ERRNO;
  743 
  744     /* number of this disk */
  745     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
  746       err=ZIP_ERRNO;
  747 
  748     /* number of the disk with the start of the central directory */
  749     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
  750       err=ZIP_ERRNO;
  751 
  752     /* total number of entries in the central dir on this disk */
  753     number_entry = 0;
  754     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
  755       err=ZIP_ERRNO;
  756     else
  757       number_entry = uL;
  758 
  759     /* total number of entries in the central dir */
  760     number_entry_CD = 0;
  761     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
  762       err=ZIP_ERRNO;
  763     else
  764       number_entry_CD = uL;
  765 
  766     if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
  767       err=ZIP_BADZIPFILE;
  768 
  769     /* size of the central directory */
  770     size_central_dir = 0;
  771     if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
  772       err=ZIP_ERRNO;
  773     else
  774       size_central_dir = uL;
  775 
  776     /* offset of start of central directory with respect to the starting disk number */
  777     offset_central_dir = 0;
  778     if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
  779       err=ZIP_ERRNO;
  780     else
  781       offset_central_dir = uL;
  782 
  783 
  784     /* zipfile global comment length */
  785     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
  786       err=ZIP_ERRNO;
  787   }
  788 
  789   if ((central_pos<offset_central_dir+size_central_dir) &&
  790     (err==ZIP_OK))
  791     err=ZIP_BADZIPFILE;
  792 
  793   if (err!=ZIP_OK)
  794   {
  795     ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);
  796     return ZIP_ERRNO;
  797   }
  798 
  799   if (size_comment>0)
  800   {
  801     pziinit->globalcomment = (char*)ALLOC(size_comment+1);
  802     if (pziinit->globalcomment)
  803     {
  804       size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
  805       pziinit->globalcomment[size_comment]=0;
  806     }
  807   }
  808 
  809   byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
  810   pziinit->add_position_when_writing_offset = byte_before_the_zipfile;
  811 
  812   {
  813     ZPOS64_T size_central_dir_to_read = size_central_dir;
  814     size_t buf_size = SIZEDATA_INDATABLOCK;
  815     void* buf_read = (void*)ALLOC(buf_size);
  816     if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
  817       err=ZIP_ERRNO;
  818 
  819     while ((size_central_dir_to_read>0) && (err==ZIP_OK))
  820     {
  821       ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
  822       if (read_this > size_central_dir_to_read)
  823         read_this = size_central_dir_to_read;
  824 
  825       if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)
  826         err=ZIP_ERRNO;
  827 
  828       if (err==ZIP_OK)
  829         err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);
  830 
  831       size_central_dir_to_read-=read_this;
  832     }
  833     TRYFREE(buf_read);
  834   }
  835   pziinit->begin_pos = byte_before_the_zipfile;
  836   pziinit->number_entry = number_entry_CD;
  837 
  838   if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)
  839     err=ZIP_ERRNO;
  840 
  841   return err;
  842 }
  843 
  844 
  845 #endif /* !NO_ADDFILEINEXISTINGZIP*/
  846 
  847 
  848 /************************************************************/
  849 extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
  850 {
  851     zip64_internal ziinit;
  852     zip64_internal* zi;
  853     int err=ZIP_OK;
  854 
  855     ziinit.z_filefunc.zseek32_file = NULL;
  856     ziinit.z_filefunc.ztell32_file = NULL;
  857     if (pzlib_filefunc64_32_def==NULL)
  858         fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
  859     else
  860         ziinit.z_filefunc = *pzlib_filefunc64_32_def;
  861 
  862     ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
  863                   pathname,
  864                   (append == APPEND_STATUS_CREATE) ?
  865                   (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
  866                     (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
  867 
  868     if (ziinit.filestream == NULL)
  869         return NULL;
  870 
  871     if (append == APPEND_STATUS_CREATEAFTER)
  872         ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
  873 
  874     ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
  875     ziinit.in_opened_file_inzip = 0;
  876     ziinit.ci.stream_initialised = 0;
  877     ziinit.number_entry = 0;
  878     ziinit.add_position_when_writing_offset = 0;
  879     init_linkedlist(&(ziinit.central_dir));
  880 
  881 
  882 
  883     zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
  884     if (zi==NULL)
  885     {
  886         ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
  887         return NULL;
  888     }
  889 
  890     /* now we add file in a zipfile */
  891 #    ifndef NO_ADDFILEINEXISTINGZIP
  892     ziinit.globalcomment = NULL;
  893     if (append == APPEND_STATUS_ADDINZIP)
  894     {
  895       // Read and Cache Central Directory Records
  896       err = LoadCentralDirectoryRecord(&ziinit);
  897     }
  898 
  899     if (globalcomment)
  900     {
  901       *globalcomment = ziinit.globalcomment;
  902     }
  903 #    endif /* !NO_ADDFILEINEXISTINGZIP*/
  904 
  905     if (err != ZIP_OK)
  906     {
  907 #    ifndef NO_ADDFILEINEXISTINGZIP
  908         TRYFREE(ziinit.globalcomment);
  909 #    endif /* !NO_ADDFILEINEXISTINGZIP*/
  910         TRYFREE(zi);
  911         return NULL;
  912     }
  913     else
  914     {
  915         *zi = ziinit;
  916         return (zipFile)zi;
  917     }
  918 }
  919 
  920 extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
  921 {
  922     if (pzlib_filefunc32_def != NULL)
  923     {
  924         zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
  925         fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
  926         return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
  927     }
  928     else
  929         return zipOpen3(pathname, append, globalcomment, NULL);
  930 }
  931 
  932 extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
  933 {
  934     if (pzlib_filefunc_def != NULL)
  935     {
  936         zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
  937         zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
  938         zlib_filefunc64_32_def_fill.ztell32_file = NULL;
  939         zlib_filefunc64_32_def_fill.zseek32_file = NULL;
  940         return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
  941     }
  942     else
  943         return zipOpen3(pathname, append, globalcomment, NULL);
  944 }
  945 
  946 
  947 
  948 extern zipFile ZEXPORT zipOpen (const char* pathname, int append)
  949 {
  950     return zipOpen3((const void*)pathname,append,NULL,NULL);
  951 }
  952 
  953 extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
  954 {
  955     return zipOpen3(pathname,append,NULL,NULL);
  956 }
  957 
  958 int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
  959 {
  960   /* write the local header */
  961   int err;
  962   uInt size_filename = (uInt)strlen(filename);
  963   uInt size_extrafield = size_extrafield_local;
  964 
  965   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
  966 
  967   if (err==ZIP_OK)
  968   {
  969     if(zi->ci.zip64)
  970       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */
  971     else
  972       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
  973   }
  974 
  975   if (err==ZIP_OK)
  976     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
  977 
  978   if (err==ZIP_OK)
  979     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
  980 
  981   if (err==ZIP_OK)
  982     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
  983 
  984   // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later
  985   if (err==ZIP_OK)
  986     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
  987   if (err==ZIP_OK)
  988   {
  989     if(zi->ci.zip64)
  990       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */
  991     else
  992       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
  993   }
  994   if (err==ZIP_OK)
  995   {
  996     if(zi->ci.zip64)
  997       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */
  998     else
  999       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
 1000   }
 1001 
 1002   if (err==ZIP_OK)
 1003     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
 1004 
 1005   if(zi->ci.zip64)
 1006   {
 1007     size_extrafield += 20;
 1008   }
 1009 
 1010   if (err==ZIP_OK)
 1011     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
 1012 
 1013   if ((err==ZIP_OK) && (size_filename > 0))
 1014   {
 1015     if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
 1016       err = ZIP_ERRNO;
 1017   }
 1018 
 1019   if ((err==ZIP_OK) && (size_extrafield_local > 0))
 1020   {
 1021     if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
 1022       err = ZIP_ERRNO;
 1023   }
 1024 
 1025 
 1026   if ((err==ZIP_OK) && (zi->ci.zip64))
 1027   {
 1028       // write the Zip64 extended info
 1029       short HeaderID = 1;
 1030       short DataSize = 16;
 1031       ZPOS64_T CompressedSize = 0;
 1032       ZPOS64_T UncompressedSize = 0;
 1033 
 1034       // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
 1035       zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
 1036 
 1037       err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2);
 1038       err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2);
 1039 
 1040       err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
 1041       err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
 1042   }
 1043 
 1044   return err;
 1045 }
 1046 
 1047 /*
 1048  NOTE.
 1049  When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
 1050  before calling this function it can be done with zipRemoveExtraInfoBlock
 1051 
 1052  It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
 1053  unnecessary allocations.
 1054  */
 1055 extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
 1056                                          const void* extrafield_local, uInt size_extrafield_local,
 1057                                          const void* extrafield_global, uInt size_extrafield_global,
 1058                                          const char* comment, int method, int level, int raw,
 1059                                          int windowBits,int memLevel, int strategy,
 1060                                          const char* password, uLong crcForCrypting,
 1061                                          uLong versionMadeBy, uLong flagBase, int zip64)
 1062 {
 1063     zip64_internal* zi;
 1064     uInt size_filename;
 1065     uInt size_comment;
 1066     uInt i;
 1067     int err = ZIP_OK;
 1068 
 1069 #    ifdef NOCRYPT
 1070     (crcForCrypting);
 1071     if (password != NULL)
 1072         return ZIP_PARAMERROR;
 1073 #    endif
 1074 
 1075     if (file == NULL)
 1076         return ZIP_PARAMERROR;
 1077 
 1078 #ifdef HAVE_BZIP2
 1079     if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
 1080       return ZIP_PARAMERROR;
 1081 #else
 1082     if ((method!=0) && (method!=Z_DEFLATED))
 1083       return ZIP_PARAMERROR;
 1084 #endif
 1085 
 1086     zi = (zip64_internal*)file;
 1087 
 1088     if (zi->in_opened_file_inzip == 1)
 1089     {
 1090         err = zipCloseFileInZip (file);
 1091         if (err != ZIP_OK)
 1092             return err;
 1093     }
 1094 
 1095     if (filename==NULL)
 1096         filename="-";
 1097 
 1098     if (comment==NULL)
 1099         size_comment = 0;
 1100     else
 1101         size_comment = (uInt)strlen(comment);
 1102 
 1103     size_filename = (uInt)strlen(filename);
 1104 
 1105     if (zipfi == NULL)
 1106         zi->ci.dosDate = 0;
 1107     else
 1108     {
 1109         if (zipfi->dosDate != 0)
 1110             zi->ci.dosDate = zipfi->dosDate;
 1111         else
 1112           zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
 1113     }
 1114 
 1115     zi->ci.flag = flagBase;
 1116     if ((level==8) || (level==9))
 1117       zi->ci.flag |= 2;
 1118     if (level==2)
 1119       zi->ci.flag |= 4;
 1120     if (level==1)
 1121       zi->ci.flag |= 6;
 1122     if (password != NULL)
 1123       zi->ci.flag |= 1;
 1124 
 1125     zi->ci.crc32 = 0;
 1126     zi->ci.method = method;
 1127     zi->ci.encrypt = 0;
 1128     zi->ci.stream_initialised = 0;
 1129     zi->ci.pos_in_buffered_data = 0;
 1130     zi->ci.raw = raw;
 1131     zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
 1132 
 1133     zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
 1134     zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
 1135 
 1136     zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
 1137 
 1138     zi->ci.size_centralExtra = size_extrafield_global;
 1139     zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
 1140     /* version info */
 1141     zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
 1142     zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
 1143     zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
 1144     zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
 1145     zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
 1146     zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
 1147     zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
 1148     zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
 1149     zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
 1150     zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
 1151     zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
 1152     zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
 1153 
 1154     if (zipfi==NULL)
 1155         zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
 1156     else
 1157         zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
 1158 
 1159     if (zipfi==NULL)
 1160         zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
 1161     else
 1162         zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
 1163 
 1164     if(zi->ci.pos_local_header >= 0xffffffff)
 1165       zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
 1166     else
 1167       zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writing_offset,4);
 1168 
 1169     for (i=0;i<size_filename;i++)
 1170         *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
 1171 
 1172     for (i=0;i<size_extrafield_global;i++)
 1173         *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
 1174               *(((const char*)extrafield_global)+i);
 1175 
 1176     for (i=0;i<size_comment;i++)
 1177         *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
 1178               size_extrafield_global+i) = *(comment+i);
 1179     if (zi->ci.central_header == NULL)
 1180         return ZIP_INTERNALERROR;
 1181 
 1182     zi->ci.zip64 = zip64;
 1183     zi->ci.totalCompressedData = 0;
 1184     zi->ci.totalUncompressedData = 0;
 1185     zi->ci.pos_zip64extrainfo = 0;
 1186 
 1187     err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);
 1188 
 1189 #ifdef HAVE_BZIP2
 1190     zi->ci.bstream.avail_in = (uInt)0;
 1191     zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
 1192     zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
 1193     zi->ci.bstream.total_in_hi32 = 0;
 1194     zi->ci.bstream.total_in_lo32 = 0;
 1195     zi->ci.bstream.total_out_hi32 = 0;
 1196     zi->ci.bstream.total_out_lo32 = 0;
 1197 #endif
 1198 
 1199     zi->ci.stream.avail_in = (uInt)0;
 1200     zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
 1201     zi->ci.stream.next_out = zi->ci.buffered_data;
 1202     zi->ci.stream.total_in = 0;
 1203     zi->ci.stream.total_out = 0;
 1204     zi->ci.stream.data_type = Z_BINARY;
 1205 
 1206 #ifdef HAVE_BZIP2
 1207     if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
 1208 #else
 1209     if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
 1210 #endif
 1211     {
 1212         if(zi->ci.method == Z_DEFLATED)
 1213         {
 1214           zi->ci.stream.zalloc = (alloc_func)0;
 1215           zi->ci.stream.zfree = (free_func)0;
 1216           zi->ci.stream.opaque = (voidpf)0;
 1217 
 1218           if (windowBits>0)
 1219               windowBits = -windowBits;
 1220 
 1221           err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
 1222 
 1223           if (err==Z_OK)
 1224               zi->ci.stream_initialised = Z_DEFLATED;
 1225         }
 1226         else if(zi->ci.method == Z_BZIP2ED)
 1227         {
 1228 #ifdef HAVE_BZIP2
 1229             // Init BZip stuff here
 1230           zi->ci.bstream.bzalloc = 0;
 1231           zi->ci.bstream.bzfree = 0;
 1232           zi->ci.bstream.opaque = (voidpf)0;
 1233 
 1234           err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
 1235           if(err == BZ_OK)
 1236             zi->ci.stream_initialised = Z_BZIP2ED;
 1237 #endif
 1238         }
 1239 
 1240     }
 1241 
 1242 #    ifndef NOCRYPT
 1243     zi->ci.crypt_header_size = 0;
 1244     if ((err==Z_OK) && (password != NULL))
 1245     {
 1246         unsigned char bufHead[RAND_HEAD_LEN];
 1247         unsigned int sizeHead;
 1248         zi->ci.encrypt = 1;
 1249         zi->ci.pcrc_32_tab = get_crc_table();
 1250         /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
 1251 
 1252         sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
 1253         zi->ci.crypt_header_size = sizeHead;
 1254 
 1255         if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
 1256                 err = ZIP_ERRNO;
 1257     }
 1258 #    endif
 1259 
 1260     if (err==Z_OK)
 1261         zi->in_opened_file_inzip = 1;
 1262     return err;
 1263 }
 1264 
 1265 extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
 1266                                          const void* extrafield_local, uInt size_extrafield_local,
 1267                                          const void* extrafield_global, uInt size_extrafield_global,
 1268                                          const char* comment, int method, int level, int raw,
 1269                                          int windowBits,int memLevel, int strategy,
 1270                                          const char* password, uLong crcForCrypting,
 1271                                          uLong versionMadeBy, uLong flagBase)
 1272 {
 1273     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
 1274                                  extrafield_local, size_extrafield_local,
 1275                                  extrafield_global, size_extrafield_global,
 1276                                  comment, method, level, raw,
 1277                                  windowBits, memLevel, strategy,
 1278                                  password, crcForCrypting, versionMadeBy, flagBase, 0);
 1279 }
 1280 
 1281 extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
 1282                                          const void* extrafield_local, uInt size_extrafield_local,
 1283                                          const void* extrafield_global, uInt size_extrafield_global,
 1284                                          const char* comment, int method, int level, int raw,
 1285                                          int windowBits,int memLevel, int strategy,
 1286                                          const char* password, uLong crcForCrypting)
 1287 {
 1288     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
 1289                                  extrafield_local, size_extrafield_local,
 1290                                  extrafield_global, size_extrafield_global,
 1291                                  comment, method, level, raw,
 1292                                  windowBits, memLevel, strategy,
 1293                                  password, crcForCrypting, VERSIONMADEBY, 0, 0);
 1294 }
 1295 
 1296 extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
 1297                                          const void* extrafield_local, uInt size_extrafield_local,
 1298                                          const void* extrafield_global, uInt size_extrafield_global,
 1299                                          const char* comment, int method, int level, int raw,
 1300                                          int windowBits,int memLevel, int strategy,
 1301                                          const char* password, uLong crcForCrypting, int zip64)
 1302 {
 1303     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
 1304                                  extrafield_local, size_extrafield_local,
 1305                                  extrafield_global, size_extrafield_global,
 1306                                  comment, method, level, raw,
 1307                                  windowBits, memLevel, strategy,
 1308                                  password, crcForCrypting, VERSIONMADEBY, 0, zip64);
 1309 }
 1310 
 1311 extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
 1312                                         const void* extrafield_local, uInt size_extrafield_local,
 1313                                         const void* extrafield_global, uInt size_extrafield_global,
 1314                                         const char* comment, int method, int level, int raw)
 1315 {
 1316     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
 1317                                  extrafield_local, size_extrafield_local,
 1318                                  extrafield_global, size_extrafield_global,
 1319                                  comment, method, level, raw,
 1320                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
 1321                                  NULL, 0, VERSIONMADEBY, 0, 0);
 1322 }
 1323 
 1324 extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
 1325                                         const void* extrafield_local, uInt size_extrafield_local,
 1326                                         const void* extrafield_global, uInt size_extrafield_global,
 1327                                         const char* comment, int method, int level, int raw, int zip64)
 1328 {
 1329     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
 1330                                  extrafield_local, size_extrafield_local,
 1331                                  extrafield_global, size_extrafield_global,
 1332                                  comment, method, level, raw,
 1333                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
 1334                                  NULL, 0, VERSIONMADEBY, 0, zip64);
 1335 }
 1336 
 1337 extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
 1338                                         const void* extrafield_local, uInt size_extrafield_local,
 1339                                         const void*extrafield_global, uInt size_extrafield_global,
 1340                                         const char* comment, int method, int level, int zip64)
 1341 {
 1342     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
 1343                                  extrafield_local, size_extrafield_local,
 1344                                  extrafield_global, size_extrafield_global,
 1345                                  comment, method, level, 0,
 1346                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
 1347                                  NULL, 0, VERSIONMADEBY, 0, zip64);
 1348 }
 1349 
 1350 extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
 1351                                         const void* extrafield_local, uInt size_extrafield_local,
 1352                                         const void*extrafield_global, uInt size_extrafield_global,
 1353                                         const char* comment, int method, int level)
 1354 {
 1355     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
 1356                                  extrafield_local, size_extrafield_local,
 1357                                  extrafield_global, size_extrafield_global,
 1358                                  comment, method, level, 0,
 1359                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
 1360                                  NULL, 0, VERSIONMADEBY, 0, 0);
 1361 }
 1362 
 1363 local int zip64FlushWriteBuffer(zip64_internal* zi)
 1364 {
 1365     int err=ZIP_OK;
 1366 
 1367     if (zi->ci.encrypt != 0)
 1368     {
 1369 #ifndef NOCRYPT
 1370         uInt i;
 1371         int t;
 1372         for (i=0;i<zi->ci.pos_in_buffered_data;i++)
 1373             zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
 1374 #endif
 1375     }
 1376 
 1377     if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
 1378       err = ZIP_ERRNO;
 1379 
 1380     zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
 1381 
 1382 #ifdef HAVE_BZIP2
 1383     if(zi->ci.method == Z_BZIP2ED)
 1384     {
 1385       zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
 1386       zi->ci.bstream.total_in_lo32 = 0;
 1387       zi->ci.bstream.total_in_hi32 = 0;
 1388     }
 1389     else
 1390 #endif
 1391     {
 1392       zi->ci.totalUncompressedData += zi->ci.stream.total_in;
 1393       zi->ci.stream.total_in = 0;
 1394     }
 1395 
 1396 
 1397     zi->ci.pos_in_buffered_data = 0;
 1398 
 1399     return err;
 1400 }
 1401 
 1402 extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
 1403 {
 1404     zip64_internal* zi;
 1405     int err=ZIP_OK;
 1406 
 1407     if (file == NULL)
 1408         return ZIP_PARAMERROR;
 1409     zi = (zip64_internal*)file;
 1410 
 1411     if (zi->in_opened_file_inzip == 0)
 1412         return ZIP_PARAMERROR;
 1413 
 1414     zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
 1415 
 1416 #ifdef HAVE_BZIP2
 1417     if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
 1418     {
 1419       zi->ci.bstream.next_in = (void*)buf;
 1420       zi->ci.bstream.avail_in = len;
 1421       err = BZ_RUN_OK;
 1422 
 1423       while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
 1424       {
 1425         if (zi->ci.bstream.avail_out == 0)
 1426         {
 1427           if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
 1428             err = ZIP_ERRNO;
 1429           zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
 1430           zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
 1431         }
 1432 
 1433 
 1434         if(err != BZ_RUN_OK)
 1435           break;
 1436 
 1437         if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
 1438         {
 1439           uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
 1440 //          uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
 1441           err=BZ2_bzCompress(&zi->ci.bstream,  BZ_RUN);
 1442 
 1443           zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
 1444         }
 1445       }
 1446 
 1447       if(err == BZ_RUN_OK)
 1448         err = ZIP_OK;
 1449     }
 1450     else
 1451 #endif
 1452     {
 1453       zi->ci.stream.next_in = (Bytef*)buf;
 1454       zi->ci.stream.avail_in = len;
 1455 
 1456       while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
 1457       {
 1458           if (zi->ci.stream.avail_out == 0)
 1459           {
 1460               if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
 1461                   err = ZIP_ERRNO;
 1462               zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
 1463               zi->ci.stream.next_out = zi->ci.buffered_data;
 1464           }
 1465 
 1466 
 1467           if(err != ZIP_OK)
 1468               break;
 1469 
 1470           if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
 1471           {
 1472               uLong uTotalOutBefore = zi->ci.stream.total_out;
 1473               err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
 1474               if(uTotalOutBefore > zi->ci.stream.total_out)
 1475               {
 1476                 int bBreak = 0;
 1477                 bBreak++;
 1478               }
 1479 
 1480               zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
 1481           }
 1482           else
 1483           {
 1484               uInt copy_this,i;
 1485               if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
 1486                   copy_this = zi->ci.stream.avail_in;
 1487               else
 1488                   copy_this = zi->ci.stream.avail_out;
 1489 
 1490               for (i = 0; i < copy_this; i++)
 1491                   *(((char*)zi->ci.stream.next_out)+i) =
 1492                       *(((const char*)zi->ci.stream.next_in)+i);
 1493               {
 1494                   zi->ci.stream.avail_in -= copy_this;
 1495                   zi->ci.stream.avail_out-= copy_this;
 1496                   zi->ci.stream.next_in+= copy_this;
 1497                   zi->ci.stream.next_out+= copy_this;
 1498                   zi->ci.stream.total_in+= copy_this;
 1499                   zi->ci.stream.total_out+= copy_this;
 1500                   zi->ci.pos_in_buffered_data += copy_this;
 1501               }
 1502           }
 1503       }// while(...)
 1504     }
 1505 
 1506     return err;
 1507 }
 1508 
 1509 extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
 1510 {
 1511     return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
 1512 }
 1513 
 1514 extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
 1515 {
 1516     zip64_internal* zi;
 1517     ZPOS64_T compressed_size;
 1518     uLong invalidValue = 0xffffffff;
 1519     short datasize = 0;
 1520     int err=ZIP_OK;
 1521 
 1522     if (file == NULL)
 1523         return ZIP_PARAMERROR;
 1524     zi = (zip64_internal*)file;
 1525 
 1526     if (zi->in_opened_file_inzip == 0)
 1527         return ZIP_PARAMERROR;
 1528     zi->ci.stream.avail_in = 0;
 1529 
 1530     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
 1531                 {
 1532                         while (err==ZIP_OK)
 1533                         {
 1534                                 uLong uTotalOutBefore;
 1535                                 if (zi->ci.stream.avail_out == 0)
 1536                                 {
 1537                                         if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
 1538                                                 err = ZIP_ERRNO;
 1539                                         zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
 1540                                         zi->ci.stream.next_out = zi->ci.buffered_data;
 1541                                 }
 1542                                 uTotalOutBefore = zi->ci.stream.total_out;
 1543                                 err=deflate(&zi->ci.stream,  Z_FINISH);
 1544                                 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
 1545                         }
 1546                 }
 1547     else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
 1548     {
 1549 #ifdef HAVE_BZIP2
 1550       err = BZ_FINISH_OK;
 1551       while (err==BZ_FINISH_OK)
 1552       {
 1553         uLong uTotalOutBefore;
 1554         if (zi->ci.bstream.avail_out == 0)
 1555         {
 1556           if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
 1557             err = ZIP_ERRNO;
 1558           zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
 1559           zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
 1560         }
 1561         uTotalOutBefore = zi->ci.bstream.total_out_lo32;
 1562         err=BZ2_bzCompress(&zi->ci.bstream,  BZ_FINISH);
 1563         if(err == BZ_STREAM_END)
 1564           err = Z_STREAM_END;
 1565 
 1566         zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
 1567       }
 1568 
 1569       if(err == BZ_FINISH_OK)
 1570         err = ZIP_OK;
 1571 #endif
 1572     }
 1573 
 1574     if (err==Z_STREAM_END)
 1575         err=ZIP_OK; /* this is normal */
 1576 
 1577     if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
 1578                 {
 1579         if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
 1580             err = ZIP_ERRNO;
 1581                 }
 1582 
 1583     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
 1584     {
 1585         int tmp_err = deflateEnd(&zi->ci.stream);
 1586         if (err == ZIP_OK)
 1587             err = tmp_err;
 1588         zi->ci.stream_initialised = 0;
 1589     }
 1590 #ifdef HAVE_BZIP2
 1591     else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
 1592     {
 1593       int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
 1594                         if (err==ZIP_OK)
 1595                                 err = tmperr;
 1596                         zi->ci.stream_initialised = 0;
 1597     }
 1598 #endif
 1599 
 1600     if (!zi->ci.raw)
 1601     {
 1602         crc32 = (uLong)zi->ci.crc32;
 1603         uncompressed_size = zi->ci.totalUncompressedData;
 1604     }
 1605     compressed_size = zi->ci.totalCompressedData;
 1606 
 1607 #    ifndef NOCRYPT
 1608     compressed_size += zi->ci.crypt_header_size;
 1609 #    endif
 1610 
 1611     // update Current Item crc and sizes,
 1612     if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
 1613     {
 1614       /*version Made by*/
 1615       zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
 1616       /*version needed*/
 1617       zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);
 1618 
 1619     }
 1620 
 1621     zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
 1622 
 1623 
 1624     if(compressed_size >= 0xffffffff)
 1625       zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
 1626     else
 1627       zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
 1628 
 1629     /// set internal file attributes field
 1630     if (zi->ci.stream.data_type == Z_ASCII)
 1631         zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
 1632 
 1633     if(uncompressed_size >= 0xffffffff)
 1634       zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
 1635     else
 1636       zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
 1637 
 1638     // Add ZIP64 extra info field for uncompressed size
 1639     if(uncompressed_size >= 0xffffffff)
 1640       datasize += 8;
 1641 
 1642     // Add ZIP64 extra info field for compressed size
 1643     if(compressed_size >= 0xffffffff)
 1644       datasize += 8;
 1645 
 1646     // Add ZIP64 extra info field for relative offset to local file header of current file
 1647     if(zi->ci.pos_local_header >= 0xffffffff)
 1648       datasize += 8;
 1649 
 1650     if(datasize > 0)
 1651     {
 1652       char* p = NULL;
 1653 
 1654       if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
 1655       {
 1656         // we can not write more data to the buffer that we have room for.
 1657         return ZIP_BADZIPFILE;
 1658       }
 1659 
 1660       p = zi->ci.central_header + zi->ci.size_centralheader;
 1661 
 1662       // Add Extra Information Header for 'ZIP64 information'
 1663       zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
 1664       p += 2;
 1665       zip64local_putValue_inmemory(p, datasize, 2); // DataSize
 1666       p += 2;
 1667 
 1668       if(uncompressed_size >= 0xffffffff)
 1669       {
 1670         zip64local_putValue_inmemory(p, uncompressed_size, 8);
 1671         p += 8;
 1672       }
 1673 
 1674       if(compressed_size >= 0xffffffff)
 1675       {
 1676         zip64local_putValue_inmemory(p, compressed_size, 8);
 1677         p += 8;
 1678       }
 1679 
 1680       if(zi->ci.pos_local_header >= 0xffffffff)
 1681       {
 1682         zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
 1683         p += 8;
 1684       }
 1685 
 1686       // Update how much extra free space we got in the memory buffer
 1687       // and increase the centralheader size so the new ZIP64 fields are included
 1688       // ( 4 below is the size of HeaderID and DataSize field )
 1689       zi->ci.size_centralExtraFree -= datasize + 4;
 1690       zi->ci.size_centralheader += datasize + 4;
 1691 
 1692       // Update the extra info size field
 1693       zi->ci.size_centralExtra += datasize + 4;
 1694       zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
 1695     }
 1696 
 1697     if (err==ZIP_OK)
 1698         err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
 1699 
 1700     free(zi->ci.central_header);
 1701 
 1702     if (err==ZIP_OK)
 1703     {
 1704         // Update the LocalFileHeader with the new values.
 1705 
 1706         ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
 1707 
 1708         if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
 1709             err = ZIP_ERRNO;
 1710 
 1711         if (err==ZIP_OK)
 1712             err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
 1713 
 1714         if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff )
 1715         {
 1716           if(zi->ci.pos_zip64extrainfo > 0)
 1717           {
 1718             // Update the size in the ZIP64 extended field.
 1719             if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
 1720               err = ZIP_ERRNO;
 1721 
 1722             if (err==ZIP_OK) /* compressed size, unknown */
 1723               err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
 1724 
 1725             if (err==ZIP_OK) /* uncompressed size, unknown */
 1726               err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
 1727           }
 1728           else
 1729               err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal
 1730         }
 1731         else
 1732         {
 1733           if (err==ZIP_OK) /* compressed size, unknown */
 1734               err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
 1735 
 1736           if (err==ZIP_OK) /* uncompressed size, unknown */
 1737               err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
 1738         }
 1739 
 1740         if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
 1741             err = ZIP_ERRNO;
 1742     }
 1743 
 1744     zi->number_entry ++;
 1745     zi->in_opened_file_inzip = 0;
 1746 
 1747     return err;
 1748 }
 1749 
 1750 extern int ZEXPORT zipCloseFileInZip (zipFile file)
 1751 {
 1752     return zipCloseFileInZipRaw (file,0,0);
 1753 }
 1754 
 1755 int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
 1756 {
 1757   int err = ZIP_OK;
 1758   ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writing_offset;
 1759 
 1760   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
 1761 
 1762   /*num disks*/
 1763     if (err==ZIP_OK) /* number of the disk with the start of the central directory */
 1764       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
 1765 
 1766   /*relative offset*/
 1767     if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
 1768       err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
 1769 
 1770   /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
 1771     if (err==ZIP_OK) /* number of the disk with the start of the central directory */
 1772       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
 1773 
 1774     return err;
 1775 }
 1776 
 1777 int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
 1778 {
 1779   int err = ZIP_OK;
 1780 
 1781   uLong Zip64DataSize = 44;
 1782 
 1783   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
 1784 
 1785   if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
 1786     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?
 1787 
 1788   if (err==ZIP_OK) /* version made by */
 1789     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
 1790 
 1791   if (err==ZIP_OK) /* version needed */
 1792     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
 1793 
 1794   if (err==ZIP_OK) /* number of this disk */
 1795     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
 1796 
 1797   if (err==ZIP_OK) /* number of the disk with the start of the central directory */
 1798     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
 1799 
 1800   if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
 1801     err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
 1802 
 1803   if (err==ZIP_OK) /* total number of entries in the central dir */
 1804     err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
 1805 
 1806   if (err==ZIP_OK) /* size of the central directory */
 1807     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
 1808 
 1809   if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
 1810   {
 1811     ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset;
 1812     err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
 1813   }
 1814   return err;
 1815 }
 1816 int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
 1817 {
 1818   int err = ZIP_OK;
 1819 
 1820   /*signature*/
 1821   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
 1822 
 1823   if (err==ZIP_OK) /* number of this disk */
 1824     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
 1825 
 1826   if (err==ZIP_OK) /* number of the disk with the start of the central directory */
 1827     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
 1828 
 1829   if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
 1830   {
 1831     {
 1832       if(zi->number_entry >= 0xFFFF)
 1833         err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
 1834       else
 1835         err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
 1836     }
 1837   }
 1838 
 1839   if (err==ZIP_OK) /* total number of entries in the central dir */
 1840   {
 1841     if(zi->number_entry >= 0xFFFF)
 1842       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
 1843     else
 1844       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
 1845   }
 1846 
 1847   if (err==ZIP_OK) /* size of the central directory */
 1848     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
 1849 
 1850   if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
 1851   {
 1852     ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset;
 1853     if(pos >= 0xffffffff)
 1854     {
 1855       err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
 1856     }
 1857     else
 1858       err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writing_offset),4);
 1859   }
 1860 
 1861    return err;
 1862 }
 1863 
 1864 int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
 1865 {
 1866   int err = ZIP_OK;
 1867   uInt size_global_comment = 0;
 1868 
 1869   if(global_comment != NULL)
 1870     size_global_comment = (uInt)strlen(global_comment);
 1871 
 1872   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
 1873 
 1874   if (err == ZIP_OK && size_global_comment > 0)
 1875   {
 1876     if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
 1877       err = ZIP_ERRNO;
 1878   }
 1879   return err;
 1880 }
 1881 
 1882 extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
 1883 {
 1884     zip64_internal* zi;
 1885     int err = 0;
 1886     uLong size_centraldir = 0;
 1887     ZPOS64_T centraldir_pos_inzip;
 1888     ZPOS64_T pos;
 1889 
 1890     if (file == NULL)
 1891         return ZIP_PARAMERROR;
 1892 
 1893     zi = (zip64_internal*)file;
 1894 
 1895     if (zi->in_opened_file_inzip == 1)
 1896     {
 1897         err = zipCloseFileInZip (file);
 1898     }
 1899 
 1900 #ifndef NO_ADDFILEINEXISTINGZIP
 1901     if (global_comment==NULL)
 1902         global_comment = zi->globalcomment;
 1903 #endif
 1904 
 1905     centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
 1906 
 1907     if (err==ZIP_OK)
 1908     {
 1909         linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
 1910         while (ldi!=NULL)
 1911         {
 1912             if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
 1913             {
 1914                 if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
 1915                     err = ZIP_ERRNO;
 1916             }
 1917 
 1918             size_centraldir += ldi->filled_in_this_block;
 1919             ldi = ldi->next_datablock;
 1920         }
 1921     }
 1922     free_linkedlist(&(zi->central_dir));
 1923 
 1924     pos = centraldir_pos_inzip - zi->add_position_when_writing_offset;
 1925     if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)
 1926     {
 1927       ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
 1928       Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
 1929 
 1930       Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
 1931     }
 1932 
 1933     if (err==ZIP_OK)
 1934       err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
 1935 
 1936     if(err == ZIP_OK)
 1937       err = Write_GlobalComment(zi, global_comment);
 1938 
 1939     if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)
 1940         if (err == ZIP_OK)
 1941             err = ZIP_ERRNO;
 1942 
 1943 #ifndef NO_ADDFILEINEXISTINGZIP
 1944     TRYFREE(zi->globalcomment);
 1945 #endif
 1946     TRYFREE(zi);
 1947 
 1948     return err;
 1949 }
 1950 
 1951 extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
 1952 {
 1953   char* p = pData;
 1954   int size = 0;
 1955   char* pNewHeader;
 1956   char* pTmp;
 1957   short header;
 1958   short dataSize;
 1959 
 1960   int retVal = ZIP_OK;
 1961 
 1962   if(pData == NULL || *dataLen < 4)
 1963     return ZIP_PARAMERROR;
 1964 
 1965   pNewHeader = (char*)ALLOC(*dataLen);
 1966   pTmp = pNewHeader;
 1967 
 1968   while(p < (pData + *dataLen))
 1969   {
 1970     header = *(short*)p;
 1971     dataSize = *(((short*)p)+1);
 1972 
 1973     if( header == sHeader ) // Header found.
 1974     {
 1975       p += dataSize + 4; // skip it. do not copy to temp buffer
 1976     }
 1977     else
 1978     {
 1979       // Extra Info block should not be removed, So copy it to the temp buffer.
 1980       memcpy(pTmp, p, dataSize + 4);
 1981       p += dataSize + 4;
 1982       size += dataSize + 4;
 1983     }
 1984 
 1985   }
 1986 
 1987   if(size < *dataLen)
 1988   {
 1989     // clean old extra info block.
 1990     memset(pData,0, *dataLen);
 1991 
 1992     // copy the new extra info block over the old
 1993     if(size > 0)
 1994       memcpy(pData, pNewHeader, size);
 1995 
 1996     // set the new extra info size
 1997     *dataLen = size;
 1998 
 1999     retVal = ZIP_OK;
 2000   }
 2001   else
 2002     retVal = ZIP_ERRNO;
 2003 
 2004   TRYFREE(pNewHeader);
 2005 
 2006   return retVal;
 2007 }