xref: /netbsd-src/external/gpl3/binutils.old/dist/zlib/contrib/minizip/zip.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
175fd0b74Schristos /* zip.c -- IO on .zip files using zlib
275fd0b74Schristos    Version 1.1, February 14h, 2010
375fd0b74Schristos    part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
475fd0b74Schristos 
575fd0b74Schristos          Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
675fd0b74Schristos 
775fd0b74Schristos          Modifications for Zip64 support
875fd0b74Schristos          Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
975fd0b74Schristos 
1075fd0b74Schristos          For more info read MiniZip_info.txt
1175fd0b74Schristos 
1275fd0b74Schristos          Changes
1375fd0b74Schristos    Oct-2009 - Mathias Svensson - Remove old C style function prototypes
1475fd0b74Schristos    Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
1575fd0b74Schristos    Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
1675fd0b74Schristos    Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
1775fd0b74Schristos                                  It is used when recreting zip archive with RAW when deleting items from a zip.
18ede78133Schristos                                  ZIP64 data is automatically added to items that needs it, and existing ZIP64 data need to be removed.
1975fd0b74Schristos    Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
2075fd0b74Schristos    Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
2175fd0b74Schristos 
2275fd0b74Schristos */
2375fd0b74Schristos 
2475fd0b74Schristos 
2575fd0b74Schristos #include <stdio.h>
2675fd0b74Schristos #include <stdlib.h>
2775fd0b74Schristos #include <string.h>
2875fd0b74Schristos #include <time.h>
2975fd0b74Schristos #include "zlib.h"
3075fd0b74Schristos #include "zip.h"
3175fd0b74Schristos 
3275fd0b74Schristos #ifdef STDC
3375fd0b74Schristos #  include <stddef.h>
3475fd0b74Schristos #  include <string.h>
3575fd0b74Schristos #  include <stdlib.h>
3675fd0b74Schristos #endif
3775fd0b74Schristos #ifdef NO_ERRNO_H
3875fd0b74Schristos     extern int errno;
3975fd0b74Schristos #else
4075fd0b74Schristos #   include <errno.h>
4175fd0b74Schristos #endif
4275fd0b74Schristos 
4375fd0b74Schristos 
4475fd0b74Schristos #ifndef local
4575fd0b74Schristos #  define local static
4675fd0b74Schristos #endif
4775fd0b74Schristos /* compile with -Dlocal if your debugger can't find static symbols */
4875fd0b74Schristos 
4975fd0b74Schristos #ifndef VERSIONMADEBY
5075fd0b74Schristos # define VERSIONMADEBY   (0x0) /* platform depedent */
5175fd0b74Schristos #endif
5275fd0b74Schristos 
5375fd0b74Schristos #ifndef Z_BUFSIZE
5475fd0b74Schristos #define Z_BUFSIZE (64*1024) //(16384)
5575fd0b74Schristos #endif
5675fd0b74Schristos 
5775fd0b74Schristos #ifndef Z_MAXFILENAMEINZIP
5875fd0b74Schristos #define Z_MAXFILENAMEINZIP (256)
5975fd0b74Schristos #endif
6075fd0b74Schristos 
6175fd0b74Schristos #ifndef ALLOC
6275fd0b74Schristos # define ALLOC(size) (malloc(size))
6375fd0b74Schristos #endif
6475fd0b74Schristos #ifndef TRYFREE
6575fd0b74Schristos # define TRYFREE(p) {if (p) free(p);}
6675fd0b74Schristos #endif
6775fd0b74Schristos 
6875fd0b74Schristos /*
6975fd0b74Schristos #define SIZECENTRALDIRITEM (0x2e)
7075fd0b74Schristos #define SIZEZIPLOCALHEADER (0x1e)
7175fd0b74Schristos */
7275fd0b74Schristos 
7375fd0b74Schristos /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
7475fd0b74Schristos 
7575fd0b74Schristos 
7675fd0b74Schristos // NOT sure that this work on ALL platform
7775fd0b74Schristos #define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
7875fd0b74Schristos 
7975fd0b74Schristos #ifndef SEEK_CUR
8075fd0b74Schristos #define SEEK_CUR    1
8175fd0b74Schristos #endif
8275fd0b74Schristos 
8375fd0b74Schristos #ifndef SEEK_END
8475fd0b74Schristos #define SEEK_END    2
8575fd0b74Schristos #endif
8675fd0b74Schristos 
8775fd0b74Schristos #ifndef SEEK_SET
8875fd0b74Schristos #define SEEK_SET    0
8975fd0b74Schristos #endif
9075fd0b74Schristos 
9175fd0b74Schristos #ifndef DEF_MEM_LEVEL
9275fd0b74Schristos #if MAX_MEM_LEVEL >= 8
9375fd0b74Schristos #  define DEF_MEM_LEVEL 8
9475fd0b74Schristos #else
9575fd0b74Schristos #  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
9675fd0b74Schristos #endif
9775fd0b74Schristos #endif
9875fd0b74Schristos const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
9975fd0b74Schristos 
10075fd0b74Schristos 
10175fd0b74Schristos #define SIZEDATA_INDATABLOCK (4096-(4*4))
10275fd0b74Schristos 
10375fd0b74Schristos #define LOCALHEADERMAGIC    (0x04034b50)
10475fd0b74Schristos #define CENTRALHEADERMAGIC  (0x02014b50)
10575fd0b74Schristos #define ENDHEADERMAGIC      (0x06054b50)
10675fd0b74Schristos #define ZIP64ENDHEADERMAGIC      (0x6064b50)
10775fd0b74Schristos #define ZIP64ENDLOCHEADERMAGIC   (0x7064b50)
10875fd0b74Schristos 
10975fd0b74Schristos #define FLAG_LOCALHEADER_OFFSET (0x06)
11075fd0b74Schristos #define CRC_LOCALHEADER_OFFSET  (0x0e)
11175fd0b74Schristos 
11275fd0b74Schristos #define SIZECENTRALHEADER (0x2e) /* 46 */
11375fd0b74Schristos 
11475fd0b74Schristos typedef struct linkedlist_datablock_internal_s
11575fd0b74Schristos {
11675fd0b74Schristos   struct linkedlist_datablock_internal_s* next_datablock;
11775fd0b74Schristos   uLong  avail_in_this_block;
11875fd0b74Schristos   uLong  filled_in_this_block;
119ede78133Schristos   uLong  unused; /* for future use and alignment */
12075fd0b74Schristos   unsigned char data[SIZEDATA_INDATABLOCK];
12175fd0b74Schristos } linkedlist_datablock_internal;
12275fd0b74Schristos 
12375fd0b74Schristos typedef struct linkedlist_data_s
12475fd0b74Schristos {
12575fd0b74Schristos     linkedlist_datablock_internal* first_block;
12675fd0b74Schristos     linkedlist_datablock_internal* last_block;
12775fd0b74Schristos } linkedlist_data;
12875fd0b74Schristos 
12975fd0b74Schristos 
13075fd0b74Schristos typedef struct
13175fd0b74Schristos {
13275fd0b74Schristos     z_stream stream;            /* zLib stream structure for inflate */
13375fd0b74Schristos #ifdef HAVE_BZIP2
13475fd0b74Schristos     bz_stream bstream;          /* bzLib stream structure for bziped */
13575fd0b74Schristos #endif
13675fd0b74Schristos 
13775fd0b74Schristos     int  stream_initialised;    /* 1 is stream is initialised */
13875fd0b74Schristos     uInt pos_in_buffered_data;  /* last written byte in buffered_data */
13975fd0b74Schristos 
14075fd0b74Schristos     ZPOS64_T pos_local_header;     /* offset of the local header of the file
14175fd0b74Schristos                                      currenty writing */
14275fd0b74Schristos     char* central_header;       /* central header data for the current file */
14375fd0b74Schristos     uLong size_centralExtra;
14475fd0b74Schristos     uLong size_centralheader;   /* size of the central header for cur file */
14575fd0b74Schristos     uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
14675fd0b74Schristos     uLong flag;                 /* flag of the file currently writing */
14775fd0b74Schristos 
14875fd0b74Schristos     int  method;                /* compression method of file currenty wr.*/
14975fd0b74Schristos     int  raw;                   /* 1 for directly writing raw data */
15075fd0b74Schristos     Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
15175fd0b74Schristos     uLong dosDate;
15275fd0b74Schristos     uLong crc32;
15375fd0b74Schristos     int  encrypt;
15475fd0b74Schristos     int  zip64;               /* Add ZIP64 extened information in the extra field */
15575fd0b74Schristos     ZPOS64_T pos_zip64extrainfo;
15675fd0b74Schristos     ZPOS64_T totalCompressedData;
15775fd0b74Schristos     ZPOS64_T totalUncompressedData;
15875fd0b74Schristos #ifndef NOCRYPT
15975fd0b74Schristos     unsigned long keys[3];     /* keys defining the pseudo-random sequence */
16075fd0b74Schristos     const z_crc_t* pcrc_32_tab;
161*e992f068Schristos     unsigned crypt_header_size;
16275fd0b74Schristos #endif
16375fd0b74Schristos } curfile64_info;
16475fd0b74Schristos 
16575fd0b74Schristos typedef struct
16675fd0b74Schristos {
16775fd0b74Schristos     zlib_filefunc64_32_def z_filefunc;
16875fd0b74Schristos     voidpf filestream;        /* io structore of the zipfile */
16975fd0b74Schristos     linkedlist_data central_dir;/* datablock with central dir in construction*/
17075fd0b74Schristos     int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/
17175fd0b74Schristos     curfile64_info ci;            /* info on the file curretly writing */
17275fd0b74Schristos 
17375fd0b74Schristos     ZPOS64_T begin_pos;            /* position of the beginning of the zipfile */
174ede78133Schristos     ZPOS64_T add_position_when_writing_offset;
17575fd0b74Schristos     ZPOS64_T number_entry;
17675fd0b74Schristos 
17775fd0b74Schristos #ifndef NO_ADDFILEINEXISTINGZIP
17875fd0b74Schristos     char *globalcomment;
17975fd0b74Schristos #endif
18075fd0b74Schristos 
18175fd0b74Schristos } zip64_internal;
18275fd0b74Schristos 
18375fd0b74Schristos 
18475fd0b74Schristos #ifndef NOCRYPT
18575fd0b74Schristos #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
18675fd0b74Schristos #include "crypt.h"
18775fd0b74Schristos #endif
18875fd0b74Schristos 
allocate_new_datablock()18975fd0b74Schristos local linkedlist_datablock_internal* allocate_new_datablock()
19075fd0b74Schristos {
19175fd0b74Schristos     linkedlist_datablock_internal* ldi;
19275fd0b74Schristos     ldi = (linkedlist_datablock_internal*)
19375fd0b74Schristos                  ALLOC(sizeof(linkedlist_datablock_internal));
19475fd0b74Schristos     if (ldi!=NULL)
19575fd0b74Schristos     {
19675fd0b74Schristos         ldi->next_datablock = NULL ;
19775fd0b74Schristos         ldi->filled_in_this_block = 0 ;
19875fd0b74Schristos         ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
19975fd0b74Schristos     }
20075fd0b74Schristos     return ldi;
20175fd0b74Schristos }
20275fd0b74Schristos 
free_datablock(linkedlist_datablock_internal * ldi)20375fd0b74Schristos local void free_datablock(linkedlist_datablock_internal* ldi)
20475fd0b74Schristos {
20575fd0b74Schristos     while (ldi!=NULL)
20675fd0b74Schristos     {
20775fd0b74Schristos         linkedlist_datablock_internal* ldinext = ldi->next_datablock;
20875fd0b74Schristos         TRYFREE(ldi);
20975fd0b74Schristos         ldi = ldinext;
21075fd0b74Schristos     }
21175fd0b74Schristos }
21275fd0b74Schristos 
init_linkedlist(linkedlist_data * ll)21375fd0b74Schristos local void init_linkedlist(linkedlist_data* ll)
21475fd0b74Schristos {
21575fd0b74Schristos     ll->first_block = ll->last_block = NULL;
21675fd0b74Schristos }
21775fd0b74Schristos 
free_linkedlist(linkedlist_data * ll)21875fd0b74Schristos local void free_linkedlist(linkedlist_data* ll)
21975fd0b74Schristos {
22075fd0b74Schristos     free_datablock(ll->first_block);
22175fd0b74Schristos     ll->first_block = ll->last_block = NULL;
22275fd0b74Schristos }
22375fd0b74Schristos 
22475fd0b74Schristos 
add_data_in_datablock(linkedlist_data * ll,const void * buf,uLong len)22575fd0b74Schristos local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
22675fd0b74Schristos {
22775fd0b74Schristos     linkedlist_datablock_internal* ldi;
22875fd0b74Schristos     const unsigned char* from_copy;
22975fd0b74Schristos 
23075fd0b74Schristos     if (ll==NULL)
23175fd0b74Schristos         return ZIP_INTERNALERROR;
23275fd0b74Schristos 
23375fd0b74Schristos     if (ll->last_block == NULL)
23475fd0b74Schristos     {
23575fd0b74Schristos         ll->first_block = ll->last_block = allocate_new_datablock();
23675fd0b74Schristos         if (ll->first_block == NULL)
23775fd0b74Schristos             return ZIP_INTERNALERROR;
23875fd0b74Schristos     }
23975fd0b74Schristos 
24075fd0b74Schristos     ldi = ll->last_block;
24175fd0b74Schristos     from_copy = (unsigned char*)buf;
24275fd0b74Schristos 
24375fd0b74Schristos     while (len>0)
24475fd0b74Schristos     {
24575fd0b74Schristos         uInt copy_this;
24675fd0b74Schristos         uInt i;
24775fd0b74Schristos         unsigned char* to_copy;
24875fd0b74Schristos 
24975fd0b74Schristos         if (ldi->avail_in_this_block==0)
25075fd0b74Schristos         {
25175fd0b74Schristos             ldi->next_datablock = allocate_new_datablock();
25275fd0b74Schristos             if (ldi->next_datablock == NULL)
25375fd0b74Schristos                 return ZIP_INTERNALERROR;
25475fd0b74Schristos             ldi = ldi->next_datablock ;
25575fd0b74Schristos             ll->last_block = ldi;
25675fd0b74Schristos         }
25775fd0b74Schristos 
25875fd0b74Schristos         if (ldi->avail_in_this_block < len)
25975fd0b74Schristos             copy_this = (uInt)ldi->avail_in_this_block;
26075fd0b74Schristos         else
26175fd0b74Schristos             copy_this = (uInt)len;
26275fd0b74Schristos 
26375fd0b74Schristos         to_copy = &(ldi->data[ldi->filled_in_this_block]);
26475fd0b74Schristos 
26575fd0b74Schristos         for (i=0;i<copy_this;i++)
26675fd0b74Schristos             *(to_copy+i)=*(from_copy+i);
26775fd0b74Schristos 
26875fd0b74Schristos         ldi->filled_in_this_block += copy_this;
26975fd0b74Schristos         ldi->avail_in_this_block -= copy_this;
27075fd0b74Schristos         from_copy += copy_this ;
27175fd0b74Schristos         len -= copy_this;
27275fd0b74Schristos     }
27375fd0b74Schristos     return ZIP_OK;
27475fd0b74Schristos }
27575fd0b74Schristos 
27675fd0b74Schristos 
27775fd0b74Schristos 
27875fd0b74Schristos /****************************************************************************/
27975fd0b74Schristos 
28075fd0b74Schristos #ifndef NO_ADDFILEINEXISTINGZIP
28175fd0b74Schristos /* ===========================================================================
28275fd0b74Schristos    Inputs a long in LSB order to the given file
28375fd0b74Schristos    nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
28475fd0b74Schristos */
28575fd0b74Schristos 
28675fd0b74Schristos local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
zip64local_putValue(const zlib_filefunc64_32_def * pzlib_filefunc_def,voidpf filestream,ZPOS64_T x,int nbByte)28775fd0b74Schristos local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
28875fd0b74Schristos {
28975fd0b74Schristos     unsigned char buf[8];
29075fd0b74Schristos     int n;
29175fd0b74Schristos     for (n = 0; n < nbByte; n++)
29275fd0b74Schristos     {
29375fd0b74Schristos         buf[n] = (unsigned char)(x & 0xff);
29475fd0b74Schristos         x >>= 8;
29575fd0b74Schristos     }
29675fd0b74Schristos     if (x != 0)
29775fd0b74Schristos       {     /* data overflow - hack for ZIP64 (X Roche) */
29875fd0b74Schristos       for (n = 0; n < nbByte; n++)
29975fd0b74Schristos         {
30075fd0b74Schristos           buf[n] = 0xff;
30175fd0b74Schristos         }
30275fd0b74Schristos       }
30375fd0b74Schristos 
304*e992f068Schristos     if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,(uLong)nbByte)!=(uLong)nbByte)
30575fd0b74Schristos         return ZIP_ERRNO;
30675fd0b74Schristos     else
30775fd0b74Schristos         return ZIP_OK;
30875fd0b74Schristos }
30975fd0b74Schristos 
31075fd0b74Schristos local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
zip64local_putValue_inmemory(void * dest,ZPOS64_T x,int nbByte)31175fd0b74Schristos local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
31275fd0b74Schristos {
31375fd0b74Schristos     unsigned char* buf=(unsigned char*)dest;
31475fd0b74Schristos     int n;
31575fd0b74Schristos     for (n = 0; n < nbByte; n++) {
31675fd0b74Schristos         buf[n] = (unsigned char)(x & 0xff);
31775fd0b74Schristos         x >>= 8;
31875fd0b74Schristos     }
31975fd0b74Schristos 
32075fd0b74Schristos     if (x != 0)
32175fd0b74Schristos     {     /* data overflow - hack for ZIP64 */
32275fd0b74Schristos        for (n = 0; n < nbByte; n++)
32375fd0b74Schristos        {
32475fd0b74Schristos           buf[n] = 0xff;
32575fd0b74Schristos        }
32675fd0b74Schristos     }
32775fd0b74Schristos }
32875fd0b74Schristos 
32975fd0b74Schristos /****************************************************************************/
33075fd0b74Schristos 
33175fd0b74Schristos 
zip64local_TmzDateToDosDate(const tm_zip * ptm)33275fd0b74Schristos local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
33375fd0b74Schristos {
33475fd0b74Schristos     uLong year = (uLong)ptm->tm_year;
33575fd0b74Schristos     if (year>=1980)
33675fd0b74Schristos         year-=1980;
33775fd0b74Schristos     else if (year>=80)
33875fd0b74Schristos         year-=80;
33975fd0b74Schristos     return
340*e992f068Schristos       (uLong) (((uLong)(ptm->tm_mday) + (32 * (uLong)(ptm->tm_mon+1)) + (512 * year)) << 16) |
341*e992f068Schristos         (((uLong)ptm->tm_sec/2) + (32 * (uLong)ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
34275fd0b74Schristos }
34375fd0b74Schristos 
34475fd0b74Schristos 
34575fd0b74Schristos /****************************************************************************/
34675fd0b74Schristos 
34775fd0b74Schristos local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
34875fd0b74Schristos 
zip64local_getByte(const zlib_filefunc64_32_def * pzlib_filefunc_def,voidpf filestream,int * pi)34975fd0b74Schristos local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
35075fd0b74Schristos {
35175fd0b74Schristos     unsigned char c;
35275fd0b74Schristos     int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
35375fd0b74Schristos     if (err==1)
35475fd0b74Schristos     {
35575fd0b74Schristos         *pi = (int)c;
35675fd0b74Schristos         return ZIP_OK;
35775fd0b74Schristos     }
35875fd0b74Schristos     else
35975fd0b74Schristos     {
36075fd0b74Schristos         if (ZERROR64(*pzlib_filefunc_def,filestream))
36175fd0b74Schristos             return ZIP_ERRNO;
36275fd0b74Schristos         else
36375fd0b74Schristos             return ZIP_EOF;
36475fd0b74Schristos     }
36575fd0b74Schristos }
36675fd0b74Schristos 
36775fd0b74Schristos 
36875fd0b74Schristos /* ===========================================================================
36975fd0b74Schristos    Reads a long in LSB order from the given gz_stream. Sets
37075fd0b74Schristos */
37175fd0b74Schristos local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
37275fd0b74Schristos 
zip64local_getShort(const zlib_filefunc64_32_def * pzlib_filefunc_def,voidpf filestream,uLong * pX)37375fd0b74Schristos local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
37475fd0b74Schristos {
37575fd0b74Schristos     uLong x ;
37675fd0b74Schristos     int i = 0;
37775fd0b74Schristos     int err;
37875fd0b74Schristos 
37975fd0b74Schristos     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
38075fd0b74Schristos     x = (uLong)i;
38175fd0b74Schristos 
38275fd0b74Schristos     if (err==ZIP_OK)
38375fd0b74Schristos         err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
38475fd0b74Schristos     x += ((uLong)i)<<8;
38575fd0b74Schristos 
38675fd0b74Schristos     if (err==ZIP_OK)
38775fd0b74Schristos         *pX = x;
38875fd0b74Schristos     else
38975fd0b74Schristos         *pX = 0;
39075fd0b74Schristos     return err;
39175fd0b74Schristos }
39275fd0b74Schristos 
39375fd0b74Schristos local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
39475fd0b74Schristos 
zip64local_getLong(const zlib_filefunc64_32_def * pzlib_filefunc_def,voidpf filestream,uLong * pX)39575fd0b74Schristos local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
39675fd0b74Schristos {
39775fd0b74Schristos     uLong x ;
39875fd0b74Schristos     int i = 0;
39975fd0b74Schristos     int err;
40075fd0b74Schristos 
40175fd0b74Schristos     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
40275fd0b74Schristos     x = (uLong)i;
40375fd0b74Schristos 
40475fd0b74Schristos     if (err==ZIP_OK)
40575fd0b74Schristos         err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
40675fd0b74Schristos     x += ((uLong)i)<<8;
40775fd0b74Schristos 
40875fd0b74Schristos     if (err==ZIP_OK)
40975fd0b74Schristos         err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
41075fd0b74Schristos     x += ((uLong)i)<<16;
41175fd0b74Schristos 
41275fd0b74Schristos     if (err==ZIP_OK)
41375fd0b74Schristos         err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
41475fd0b74Schristos     x += ((uLong)i)<<24;
41575fd0b74Schristos 
41675fd0b74Schristos     if (err==ZIP_OK)
41775fd0b74Schristos         *pX = x;
41875fd0b74Schristos     else
41975fd0b74Schristos         *pX = 0;
42075fd0b74Schristos     return err;
42175fd0b74Schristos }
42275fd0b74Schristos 
42375fd0b74Schristos local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));
42475fd0b74Schristos 
42575fd0b74Schristos 
zip64local_getLong64(const zlib_filefunc64_32_def * pzlib_filefunc_def,voidpf filestream,ZPOS64_T * pX)42675fd0b74Schristos local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
42775fd0b74Schristos {
42875fd0b74Schristos   ZPOS64_T x;
42975fd0b74Schristos   int i = 0;
43075fd0b74Schristos   int err;
43175fd0b74Schristos 
43275fd0b74Schristos   err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
43375fd0b74Schristos   x = (ZPOS64_T)i;
43475fd0b74Schristos 
43575fd0b74Schristos   if (err==ZIP_OK)
43675fd0b74Schristos     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
43775fd0b74Schristos   x += ((ZPOS64_T)i)<<8;
43875fd0b74Schristos 
43975fd0b74Schristos   if (err==ZIP_OK)
44075fd0b74Schristos     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
44175fd0b74Schristos   x += ((ZPOS64_T)i)<<16;
44275fd0b74Schristos 
44375fd0b74Schristos   if (err==ZIP_OK)
44475fd0b74Schristos     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
44575fd0b74Schristos   x += ((ZPOS64_T)i)<<24;
44675fd0b74Schristos 
44775fd0b74Schristos   if (err==ZIP_OK)
44875fd0b74Schristos     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
44975fd0b74Schristos   x += ((ZPOS64_T)i)<<32;
45075fd0b74Schristos 
45175fd0b74Schristos   if (err==ZIP_OK)
45275fd0b74Schristos     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
45375fd0b74Schristos   x += ((ZPOS64_T)i)<<40;
45475fd0b74Schristos 
45575fd0b74Schristos   if (err==ZIP_OK)
45675fd0b74Schristos     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
45775fd0b74Schristos   x += ((ZPOS64_T)i)<<48;
45875fd0b74Schristos 
45975fd0b74Schristos   if (err==ZIP_OK)
46075fd0b74Schristos     err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
46175fd0b74Schristos   x += ((ZPOS64_T)i)<<56;
46275fd0b74Schristos 
46375fd0b74Schristos   if (err==ZIP_OK)
46475fd0b74Schristos     *pX = x;
46575fd0b74Schristos   else
46675fd0b74Schristos     *pX = 0;
46775fd0b74Schristos 
46875fd0b74Schristos   return err;
46975fd0b74Schristos }
47075fd0b74Schristos 
47175fd0b74Schristos #ifndef BUFREADCOMMENT
47275fd0b74Schristos #define BUFREADCOMMENT (0x400)
47375fd0b74Schristos #endif
47475fd0b74Schristos /*
47575fd0b74Schristos   Locate the Central directory of a zipfile (at the end, just before
47675fd0b74Schristos     the global comment)
47775fd0b74Schristos */
47875fd0b74Schristos local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
47975fd0b74Schristos 
zip64local_SearchCentralDir(const zlib_filefunc64_32_def * pzlib_filefunc_def,voidpf filestream)48075fd0b74Schristos local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
48175fd0b74Schristos {
48275fd0b74Schristos   unsigned char* buf;
48375fd0b74Schristos   ZPOS64_T uSizeFile;
48475fd0b74Schristos   ZPOS64_T uBackRead;
48575fd0b74Schristos   ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
48675fd0b74Schristos   ZPOS64_T uPosFound=0;
48775fd0b74Schristos 
48875fd0b74Schristos   if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
48975fd0b74Schristos     return 0;
49075fd0b74Schristos 
49175fd0b74Schristos 
49275fd0b74Schristos   uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
49375fd0b74Schristos 
49475fd0b74Schristos   if (uMaxBack>uSizeFile)
49575fd0b74Schristos     uMaxBack = uSizeFile;
49675fd0b74Schristos 
49775fd0b74Schristos   buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
49875fd0b74Schristos   if (buf==NULL)
49975fd0b74Schristos     return 0;
50075fd0b74Schristos 
50175fd0b74Schristos   uBackRead = 4;
50275fd0b74Schristos   while (uBackRead<uMaxBack)
50375fd0b74Schristos   {
50475fd0b74Schristos     uLong uReadSize;
50575fd0b74Schristos     ZPOS64_T uReadPos ;
50675fd0b74Schristos     int i;
50775fd0b74Schristos     if (uBackRead+BUFREADCOMMENT>uMaxBack)
50875fd0b74Schristos       uBackRead = uMaxBack;
50975fd0b74Schristos     else
51075fd0b74Schristos       uBackRead+=BUFREADCOMMENT;
51175fd0b74Schristos     uReadPos = uSizeFile-uBackRead ;
51275fd0b74Schristos 
51375fd0b74Schristos     uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
51475fd0b74Schristos       (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
51575fd0b74Schristos     if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
51675fd0b74Schristos       break;
51775fd0b74Schristos 
51875fd0b74Schristos     if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
51975fd0b74Schristos       break;
52075fd0b74Schristos 
52175fd0b74Schristos     for (i=(int)uReadSize-3; (i--)>0;)
52275fd0b74Schristos       if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
52375fd0b74Schristos         ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
52475fd0b74Schristos       {
525*e992f068Schristos         uPosFound = uReadPos+(unsigned)i;
52675fd0b74Schristos         break;
52775fd0b74Schristos       }
52875fd0b74Schristos 
52975fd0b74Schristos     if (uPosFound!=0)
53075fd0b74Schristos       break;
53175fd0b74Schristos   }
53275fd0b74Schristos   TRYFREE(buf);
53375fd0b74Schristos   return uPosFound;
53475fd0b74Schristos }
53575fd0b74Schristos 
53675fd0b74Schristos /*
53775fd0b74Schristos Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
53875fd0b74Schristos the global comment)
53975fd0b74Schristos */
54075fd0b74Schristos local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
54175fd0b74Schristos 
zip64local_SearchCentralDir64(const zlib_filefunc64_32_def * pzlib_filefunc_def,voidpf filestream)54275fd0b74Schristos local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
54375fd0b74Schristos {
54475fd0b74Schristos   unsigned char* buf;
54575fd0b74Schristos   ZPOS64_T uSizeFile;
54675fd0b74Schristos   ZPOS64_T uBackRead;
54775fd0b74Schristos   ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
54875fd0b74Schristos   ZPOS64_T uPosFound=0;
54975fd0b74Schristos   uLong uL;
55075fd0b74Schristos   ZPOS64_T relativeOffset;
55175fd0b74Schristos 
55275fd0b74Schristos   if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
55375fd0b74Schristos     return 0;
55475fd0b74Schristos 
55575fd0b74Schristos   uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
55675fd0b74Schristos 
55775fd0b74Schristos   if (uMaxBack>uSizeFile)
55875fd0b74Schristos     uMaxBack = uSizeFile;
55975fd0b74Schristos 
56075fd0b74Schristos   buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
56175fd0b74Schristos   if (buf==NULL)
56275fd0b74Schristos     return 0;
56375fd0b74Schristos 
56475fd0b74Schristos   uBackRead = 4;
56575fd0b74Schristos   while (uBackRead<uMaxBack)
56675fd0b74Schristos   {
56775fd0b74Schristos     uLong uReadSize;
56875fd0b74Schristos     ZPOS64_T uReadPos;
56975fd0b74Schristos     int i;
57075fd0b74Schristos     if (uBackRead+BUFREADCOMMENT>uMaxBack)
57175fd0b74Schristos       uBackRead = uMaxBack;
57275fd0b74Schristos     else
57375fd0b74Schristos       uBackRead+=BUFREADCOMMENT;
57475fd0b74Schristos     uReadPos = uSizeFile-uBackRead ;
57575fd0b74Schristos 
57675fd0b74Schristos     uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
57775fd0b74Schristos       (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
57875fd0b74Schristos     if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
57975fd0b74Schristos       break;
58075fd0b74Schristos 
58175fd0b74Schristos     if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
58275fd0b74Schristos       break;
58375fd0b74Schristos 
58475fd0b74Schristos     for (i=(int)uReadSize-3; (i--)>0;)
58575fd0b74Schristos     {
58675fd0b74Schristos       // Signature "0x07064b50" Zip64 end of central directory locater
58775fd0b74Schristos       if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
58875fd0b74Schristos       {
589*e992f068Schristos         uPosFound = uReadPos+(unsigned)i;
59075fd0b74Schristos         break;
59175fd0b74Schristos       }
59275fd0b74Schristos     }
59375fd0b74Schristos 
59475fd0b74Schristos       if (uPosFound!=0)
59575fd0b74Schristos         break;
59675fd0b74Schristos   }
59775fd0b74Schristos 
59875fd0b74Schristos   TRYFREE(buf);
59975fd0b74Schristos   if (uPosFound == 0)
60075fd0b74Schristos     return 0;
60175fd0b74Schristos 
60275fd0b74Schristos   /* Zip64 end of central directory locator */
60375fd0b74Schristos   if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
60475fd0b74Schristos     return 0;
60575fd0b74Schristos 
60675fd0b74Schristos   /* the signature, already checked */
60775fd0b74Schristos   if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
60875fd0b74Schristos     return 0;
60975fd0b74Schristos 
61075fd0b74Schristos   /* number of the disk with the start of the zip64 end of  central directory */
61175fd0b74Schristos   if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
61275fd0b74Schristos     return 0;
61375fd0b74Schristos   if (uL != 0)
61475fd0b74Schristos     return 0;
61575fd0b74Schristos 
61675fd0b74Schristos   /* relative offset of the zip64 end of central directory record */
61775fd0b74Schristos   if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)
61875fd0b74Schristos     return 0;
61975fd0b74Schristos 
62075fd0b74Schristos   /* total number of disks */
62175fd0b74Schristos   if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
62275fd0b74Schristos     return 0;
62375fd0b74Schristos   if (uL != 1)
62475fd0b74Schristos     return 0;
62575fd0b74Schristos 
62675fd0b74Schristos   /* Goto Zip64 end of central directory record */
62775fd0b74Schristos   if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
62875fd0b74Schristos     return 0;
62975fd0b74Schristos 
63075fd0b74Schristos   /* the signature */
63175fd0b74Schristos   if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
63275fd0b74Schristos     return 0;
63375fd0b74Schristos 
63475fd0b74Schristos   if (uL != 0x06064b50) // signature of 'Zip64 end of central directory'
63575fd0b74Schristos     return 0;
63675fd0b74Schristos 
63775fd0b74Schristos   return relativeOffset;
63875fd0b74Schristos }
63975fd0b74Schristos 
LoadCentralDirectoryRecord(zip64_internal * pziinit)640*e992f068Schristos local int LoadCentralDirectoryRecord(zip64_internal* pziinit)
64175fd0b74Schristos {
64275fd0b74Schristos   int err=ZIP_OK;
64375fd0b74Schristos   ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
64475fd0b74Schristos 
64575fd0b74Schristos   ZPOS64_T size_central_dir;     /* size of the central directory  */
64675fd0b74Schristos   ZPOS64_T offset_central_dir;   /* offset of start of central directory */
64775fd0b74Schristos   ZPOS64_T central_pos;
64875fd0b74Schristos   uLong uL;
64975fd0b74Schristos 
65075fd0b74Schristos   uLong number_disk;          /* number of the current dist, used for
65175fd0b74Schristos                               spaning ZIP, unsupported, always 0*/
65275fd0b74Schristos   uLong number_disk_with_CD;  /* number the the disk with central dir, used
65375fd0b74Schristos                               for spaning ZIP, unsupported, always 0*/
65475fd0b74Schristos   ZPOS64_T number_entry;
65575fd0b74Schristos   ZPOS64_T number_entry_CD;      /* total number of entries in
65675fd0b74Schristos                                 the central dir
65775fd0b74Schristos                                 (same than number_entry on nospan) */
65875fd0b74Schristos   uLong VersionMadeBy;
65975fd0b74Schristos   uLong VersionNeeded;
66075fd0b74Schristos   uLong size_comment;
66175fd0b74Schristos 
66275fd0b74Schristos   int hasZIP64Record = 0;
66375fd0b74Schristos 
66475fd0b74Schristos   // check first if we find a ZIP64 record
66575fd0b74Schristos   central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
66675fd0b74Schristos   if(central_pos > 0)
66775fd0b74Schristos   {
66875fd0b74Schristos     hasZIP64Record = 1;
66975fd0b74Schristos   }
67075fd0b74Schristos   else if(central_pos == 0)
67175fd0b74Schristos   {
67275fd0b74Schristos     central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
67375fd0b74Schristos   }
67475fd0b74Schristos 
67575fd0b74Schristos /* disable to allow appending to empty ZIP archive
67675fd0b74Schristos         if (central_pos==0)
67775fd0b74Schristos             err=ZIP_ERRNO;
67875fd0b74Schristos */
67975fd0b74Schristos 
68075fd0b74Schristos   if(hasZIP64Record)
68175fd0b74Schristos   {
68275fd0b74Schristos     ZPOS64_T sizeEndOfCentralDirectory;
68375fd0b74Schristos     if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
68475fd0b74Schristos       err=ZIP_ERRNO;
68575fd0b74Schristos 
68675fd0b74Schristos     /* the signature, already checked */
68775fd0b74Schristos     if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
68875fd0b74Schristos       err=ZIP_ERRNO;
68975fd0b74Schristos 
69075fd0b74Schristos     /* size of zip64 end of central directory record */
69175fd0b74Schristos     if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
69275fd0b74Schristos       err=ZIP_ERRNO;
69375fd0b74Schristos 
69475fd0b74Schristos     /* version made by */
69575fd0b74Schristos     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
69675fd0b74Schristos       err=ZIP_ERRNO;
69775fd0b74Schristos 
69875fd0b74Schristos     /* version needed to extract */
69975fd0b74Schristos     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
70075fd0b74Schristos       err=ZIP_ERRNO;
70175fd0b74Schristos 
70275fd0b74Schristos     /* number of this disk */
70375fd0b74Schristos     if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
70475fd0b74Schristos       err=ZIP_ERRNO;
70575fd0b74Schristos 
70675fd0b74Schristos     /* number of the disk with the start of the central directory */
70775fd0b74Schristos     if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
70875fd0b74Schristos       err=ZIP_ERRNO;
70975fd0b74Schristos 
71075fd0b74Schristos     /* total number of entries in the central directory on this disk */
71175fd0b74Schristos     if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
71275fd0b74Schristos       err=ZIP_ERRNO;
71375fd0b74Schristos 
71475fd0b74Schristos     /* total number of entries in the central directory */
71575fd0b74Schristos     if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
71675fd0b74Schristos       err=ZIP_ERRNO;
71775fd0b74Schristos 
71875fd0b74Schristos     if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
71975fd0b74Schristos       err=ZIP_BADZIPFILE;
72075fd0b74Schristos 
72175fd0b74Schristos     /* size of the central directory */
72275fd0b74Schristos     if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
72375fd0b74Schristos       err=ZIP_ERRNO;
72475fd0b74Schristos 
72575fd0b74Schristos     /* offset of start of central directory with respect to the
72675fd0b74Schristos     starting disk number */
72775fd0b74Schristos     if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
72875fd0b74Schristos       err=ZIP_ERRNO;
72975fd0b74Schristos 
73075fd0b74Schristos     // TODO..
73175fd0b74Schristos     // read the comment from the standard central header.
73275fd0b74Schristos     size_comment = 0;
73375fd0b74Schristos   }
73475fd0b74Schristos   else
73575fd0b74Schristos   {
73675fd0b74Schristos     // Read End of central Directory info
73775fd0b74Schristos     if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
73875fd0b74Schristos       err=ZIP_ERRNO;
73975fd0b74Schristos 
74075fd0b74Schristos     /* the signature, already checked */
74175fd0b74Schristos     if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
74275fd0b74Schristos       err=ZIP_ERRNO;
74375fd0b74Schristos 
74475fd0b74Schristos     /* number of this disk */
74575fd0b74Schristos     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
74675fd0b74Schristos       err=ZIP_ERRNO;
74775fd0b74Schristos 
74875fd0b74Schristos     /* number of the disk with the start of the central directory */
74975fd0b74Schristos     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
75075fd0b74Schristos       err=ZIP_ERRNO;
75175fd0b74Schristos 
75275fd0b74Schristos     /* total number of entries in the central dir on this disk */
75375fd0b74Schristos     number_entry = 0;
75475fd0b74Schristos     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
75575fd0b74Schristos       err=ZIP_ERRNO;
75675fd0b74Schristos     else
75775fd0b74Schristos       number_entry = uL;
75875fd0b74Schristos 
75975fd0b74Schristos     /* total number of entries in the central dir */
76075fd0b74Schristos     number_entry_CD = 0;
76175fd0b74Schristos     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
76275fd0b74Schristos       err=ZIP_ERRNO;
76375fd0b74Schristos     else
76475fd0b74Schristos       number_entry_CD = uL;
76575fd0b74Schristos 
76675fd0b74Schristos     if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
76775fd0b74Schristos       err=ZIP_BADZIPFILE;
76875fd0b74Schristos 
76975fd0b74Schristos     /* size of the central directory */
77075fd0b74Schristos     size_central_dir = 0;
77175fd0b74Schristos     if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
77275fd0b74Schristos       err=ZIP_ERRNO;
77375fd0b74Schristos     else
77475fd0b74Schristos       size_central_dir = uL;
77575fd0b74Schristos 
77675fd0b74Schristos     /* offset of start of central directory with respect to the starting disk number */
77775fd0b74Schristos     offset_central_dir = 0;
77875fd0b74Schristos     if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
77975fd0b74Schristos       err=ZIP_ERRNO;
78075fd0b74Schristos     else
78175fd0b74Schristos       offset_central_dir = uL;
78275fd0b74Schristos 
78375fd0b74Schristos 
78475fd0b74Schristos     /* zipfile global comment length */
78575fd0b74Schristos     if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
78675fd0b74Schristos       err=ZIP_ERRNO;
78775fd0b74Schristos   }
78875fd0b74Schristos 
78975fd0b74Schristos   if ((central_pos<offset_central_dir+size_central_dir) &&
79075fd0b74Schristos     (err==ZIP_OK))
79175fd0b74Schristos     err=ZIP_BADZIPFILE;
79275fd0b74Schristos 
79375fd0b74Schristos   if (err!=ZIP_OK)
79475fd0b74Schristos   {
79575fd0b74Schristos     ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);
79675fd0b74Schristos     return ZIP_ERRNO;
79775fd0b74Schristos   }
79875fd0b74Schristos 
79975fd0b74Schristos   if (size_comment>0)
80075fd0b74Schristos   {
80175fd0b74Schristos     pziinit->globalcomment = (char*)ALLOC(size_comment+1);
80275fd0b74Schristos     if (pziinit->globalcomment)
80375fd0b74Schristos     {
80475fd0b74Schristos       size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
80575fd0b74Schristos       pziinit->globalcomment[size_comment]=0;
80675fd0b74Schristos     }
80775fd0b74Schristos   }
80875fd0b74Schristos 
80975fd0b74Schristos   byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
810ede78133Schristos   pziinit->add_position_when_writing_offset = byte_before_the_zipfile;
81175fd0b74Schristos 
81275fd0b74Schristos   {
81375fd0b74Schristos     ZPOS64_T size_central_dir_to_read = size_central_dir;
81475fd0b74Schristos     size_t buf_size = SIZEDATA_INDATABLOCK;
81575fd0b74Schristos     void* buf_read = (void*)ALLOC(buf_size);
81675fd0b74Schristos     if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
81775fd0b74Schristos       err=ZIP_ERRNO;
81875fd0b74Schristos 
81975fd0b74Schristos     while ((size_central_dir_to_read>0) && (err==ZIP_OK))
82075fd0b74Schristos     {
82175fd0b74Schristos       ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
82275fd0b74Schristos       if (read_this > size_central_dir_to_read)
82375fd0b74Schristos         read_this = size_central_dir_to_read;
82475fd0b74Schristos 
82575fd0b74Schristos       if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)
82675fd0b74Schristos         err=ZIP_ERRNO;
82775fd0b74Schristos 
82875fd0b74Schristos       if (err==ZIP_OK)
82975fd0b74Schristos         err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);
83075fd0b74Schristos 
83175fd0b74Schristos       size_central_dir_to_read-=read_this;
83275fd0b74Schristos     }
83375fd0b74Schristos     TRYFREE(buf_read);
83475fd0b74Schristos   }
83575fd0b74Schristos   pziinit->begin_pos = byte_before_the_zipfile;
83675fd0b74Schristos   pziinit->number_entry = number_entry_CD;
83775fd0b74Schristos 
83875fd0b74Schristos   if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)
83975fd0b74Schristos     err=ZIP_ERRNO;
84075fd0b74Schristos 
84175fd0b74Schristos   return err;
84275fd0b74Schristos }
84375fd0b74Schristos 
84475fd0b74Schristos 
84575fd0b74Schristos #endif /* !NO_ADDFILEINEXISTINGZIP*/
84675fd0b74Schristos 
84775fd0b74Schristos 
84875fd0b74Schristos /************************************************************/
zipOpen3(const void * pathname,int append,zipcharpc * globalcomment,zlib_filefunc64_32_def * pzlib_filefunc64_32_def)84975fd0b74Schristos extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
85075fd0b74Schristos {
85175fd0b74Schristos     zip64_internal ziinit;
85275fd0b74Schristos     zip64_internal* zi;
85375fd0b74Schristos     int err=ZIP_OK;
85475fd0b74Schristos 
85575fd0b74Schristos     ziinit.z_filefunc.zseek32_file = NULL;
85675fd0b74Schristos     ziinit.z_filefunc.ztell32_file = NULL;
85775fd0b74Schristos     if (pzlib_filefunc64_32_def==NULL)
85875fd0b74Schristos         fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
85975fd0b74Schristos     else
86075fd0b74Schristos         ziinit.z_filefunc = *pzlib_filefunc64_32_def;
86175fd0b74Schristos 
86275fd0b74Schristos     ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
86375fd0b74Schristos                   pathname,
86475fd0b74Schristos                   (append == APPEND_STATUS_CREATE) ?
86575fd0b74Schristos                   (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
86675fd0b74Schristos                     (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
86775fd0b74Schristos 
86875fd0b74Schristos     if (ziinit.filestream == NULL)
86975fd0b74Schristos         return NULL;
87075fd0b74Schristos 
87175fd0b74Schristos     if (append == APPEND_STATUS_CREATEAFTER)
87275fd0b74Schristos         ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
87375fd0b74Schristos 
87475fd0b74Schristos     ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
87575fd0b74Schristos     ziinit.in_opened_file_inzip = 0;
87675fd0b74Schristos     ziinit.ci.stream_initialised = 0;
87775fd0b74Schristos     ziinit.number_entry = 0;
878ede78133Schristos     ziinit.add_position_when_writing_offset = 0;
87975fd0b74Schristos     init_linkedlist(&(ziinit.central_dir));
88075fd0b74Schristos 
88175fd0b74Schristos 
88275fd0b74Schristos 
88375fd0b74Schristos     zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
88475fd0b74Schristos     if (zi==NULL)
88575fd0b74Schristos     {
88675fd0b74Schristos         ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
88775fd0b74Schristos         return NULL;
88875fd0b74Schristos     }
88975fd0b74Schristos 
89075fd0b74Schristos     /* now we add file in a zipfile */
89175fd0b74Schristos #    ifndef NO_ADDFILEINEXISTINGZIP
89275fd0b74Schristos     ziinit.globalcomment = NULL;
89375fd0b74Schristos     if (append == APPEND_STATUS_ADDINZIP)
89475fd0b74Schristos     {
89575fd0b74Schristos       // Read and Cache Central Directory Records
89675fd0b74Schristos       err = LoadCentralDirectoryRecord(&ziinit);
89775fd0b74Schristos     }
89875fd0b74Schristos 
89975fd0b74Schristos     if (globalcomment)
90075fd0b74Schristos     {
90175fd0b74Schristos       *globalcomment = ziinit.globalcomment;
90275fd0b74Schristos     }
90375fd0b74Schristos #    endif /* !NO_ADDFILEINEXISTINGZIP*/
90475fd0b74Schristos 
90575fd0b74Schristos     if (err != ZIP_OK)
90675fd0b74Schristos     {
90775fd0b74Schristos #    ifndef NO_ADDFILEINEXISTINGZIP
90875fd0b74Schristos         TRYFREE(ziinit.globalcomment);
90975fd0b74Schristos #    endif /* !NO_ADDFILEINEXISTINGZIP*/
91075fd0b74Schristos         TRYFREE(zi);
91175fd0b74Schristos         return NULL;
91275fd0b74Schristos     }
91375fd0b74Schristos     else
91475fd0b74Schristos     {
91575fd0b74Schristos         *zi = ziinit;
91675fd0b74Schristos         return (zipFile)zi;
91775fd0b74Schristos     }
91875fd0b74Schristos }
91975fd0b74Schristos 
zipOpen2(const char * pathname,int append,zipcharpc * globalcomment,zlib_filefunc_def * pzlib_filefunc32_def)92075fd0b74Schristos extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
92175fd0b74Schristos {
92275fd0b74Schristos     if (pzlib_filefunc32_def != NULL)
92375fd0b74Schristos     {
92475fd0b74Schristos         zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
92575fd0b74Schristos         fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
92675fd0b74Schristos         return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
92775fd0b74Schristos     }
92875fd0b74Schristos     else
92975fd0b74Schristos         return zipOpen3(pathname, append, globalcomment, NULL);
93075fd0b74Schristos }
93175fd0b74Schristos 
zipOpen2_64(const void * pathname,int append,zipcharpc * globalcomment,zlib_filefunc64_def * pzlib_filefunc_def)93275fd0b74Schristos extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
93375fd0b74Schristos {
93475fd0b74Schristos     if (pzlib_filefunc_def != NULL)
93575fd0b74Schristos     {
93675fd0b74Schristos         zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
93775fd0b74Schristos         zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
93875fd0b74Schristos         zlib_filefunc64_32_def_fill.ztell32_file = NULL;
93975fd0b74Schristos         zlib_filefunc64_32_def_fill.zseek32_file = NULL;
94075fd0b74Schristos         return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
94175fd0b74Schristos     }
94275fd0b74Schristos     else
94375fd0b74Schristos         return zipOpen3(pathname, append, globalcomment, NULL);
94475fd0b74Schristos }
94575fd0b74Schristos 
94675fd0b74Schristos 
94775fd0b74Schristos 
zipOpen(const char * pathname,int append)94875fd0b74Schristos extern zipFile ZEXPORT zipOpen (const char* pathname, int append)
94975fd0b74Schristos {
95075fd0b74Schristos     return zipOpen3((const void*)pathname,append,NULL,NULL);
95175fd0b74Schristos }
95275fd0b74Schristos 
zipOpen64(const void * pathname,int append)95375fd0b74Schristos extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
95475fd0b74Schristos {
95575fd0b74Schristos     return zipOpen3(pathname,append,NULL,NULL);
95675fd0b74Schristos }
95775fd0b74Schristos 
Write_LocalFileHeader(zip64_internal * zi,const char * filename,uInt size_extrafield_local,const void * extrafield_local)958*e992f068Schristos local int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
95975fd0b74Schristos {
96075fd0b74Schristos   /* write the local header */
96175fd0b74Schristos   int err;
96275fd0b74Schristos   uInt size_filename = (uInt)strlen(filename);
96375fd0b74Schristos   uInt size_extrafield = size_extrafield_local;
96475fd0b74Schristos 
96575fd0b74Schristos   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
96675fd0b74Schristos 
96775fd0b74Schristos   if (err==ZIP_OK)
96875fd0b74Schristos   {
96975fd0b74Schristos     if(zi->ci.zip64)
97075fd0b74Schristos       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */
97175fd0b74Schristos     else
97275fd0b74Schristos       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
97375fd0b74Schristos   }
97475fd0b74Schristos 
97575fd0b74Schristos   if (err==ZIP_OK)
97675fd0b74Schristos     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
97775fd0b74Schristos 
97875fd0b74Schristos   if (err==ZIP_OK)
97975fd0b74Schristos     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
98075fd0b74Schristos 
98175fd0b74Schristos   if (err==ZIP_OK)
98275fd0b74Schristos     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
98375fd0b74Schristos 
98475fd0b74Schristos   // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later
98575fd0b74Schristos   if (err==ZIP_OK)
98675fd0b74Schristos     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
98775fd0b74Schristos   if (err==ZIP_OK)
98875fd0b74Schristos   {
98975fd0b74Schristos     if(zi->ci.zip64)
99075fd0b74Schristos       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */
99175fd0b74Schristos     else
99275fd0b74Schristos       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
99375fd0b74Schristos   }
99475fd0b74Schristos   if (err==ZIP_OK)
99575fd0b74Schristos   {
99675fd0b74Schristos     if(zi->ci.zip64)
99775fd0b74Schristos       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */
99875fd0b74Schristos     else
99975fd0b74Schristos       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
100075fd0b74Schristos   }
100175fd0b74Schristos 
100275fd0b74Schristos   if (err==ZIP_OK)
100375fd0b74Schristos     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
100475fd0b74Schristos 
100575fd0b74Schristos   if(zi->ci.zip64)
100675fd0b74Schristos   {
100775fd0b74Schristos     size_extrafield += 20;
100875fd0b74Schristos   }
100975fd0b74Schristos 
101075fd0b74Schristos   if (err==ZIP_OK)
101175fd0b74Schristos     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
101275fd0b74Schristos 
101375fd0b74Schristos   if ((err==ZIP_OK) && (size_filename > 0))
101475fd0b74Schristos   {
101575fd0b74Schristos     if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
101675fd0b74Schristos       err = ZIP_ERRNO;
101775fd0b74Schristos   }
101875fd0b74Schristos 
101975fd0b74Schristos   if ((err==ZIP_OK) && (size_extrafield_local > 0))
102075fd0b74Schristos   {
102175fd0b74Schristos     if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
102275fd0b74Schristos       err = ZIP_ERRNO;
102375fd0b74Schristos   }
102475fd0b74Schristos 
102575fd0b74Schristos 
102675fd0b74Schristos   if ((err==ZIP_OK) && (zi->ci.zip64))
102775fd0b74Schristos   {
102875fd0b74Schristos       // write the Zip64 extended info
102975fd0b74Schristos       short HeaderID = 1;
103075fd0b74Schristos       short DataSize = 16;
103175fd0b74Schristos       ZPOS64_T CompressedSize = 0;
103275fd0b74Schristos       ZPOS64_T UncompressedSize = 0;
103375fd0b74Schristos 
103475fd0b74Schristos       // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
103575fd0b74Schristos       zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
103675fd0b74Schristos 
1037*e992f068Schristos       err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)HeaderID,2);
1038*e992f068Schristos       err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)DataSize,2);
103975fd0b74Schristos 
104075fd0b74Schristos       err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
104175fd0b74Schristos       err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
104275fd0b74Schristos   }
104375fd0b74Schristos 
104475fd0b74Schristos   return err;
104575fd0b74Schristos }
104675fd0b74Schristos 
104775fd0b74Schristos /*
104875fd0b74Schristos  NOTE.
104975fd0b74Schristos  When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
105075fd0b74Schristos  before calling this function it can be done with zipRemoveExtraInfoBlock
105175fd0b74Schristos 
105275fd0b74Schristos  It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
105375fd0b74Schristos  unnecessary allocations.
105475fd0b74Schristos  */
zipOpenNewFileInZip4_64(zipFile file,const char * filename,const zip_fileinfo * zipfi,const void * extrafield_local,uInt size_extrafield_local,const void * extrafield_global,uInt size_extrafield_global,const char * comment,int method,int level,int raw,int windowBits,int memLevel,int strategy,const char * password,uLong crcForCrypting,uLong versionMadeBy,uLong flagBase,int zip64)105575fd0b74Schristos extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
105675fd0b74Schristos                                          const void* extrafield_local, uInt size_extrafield_local,
105775fd0b74Schristos                                          const void* extrafield_global, uInt size_extrafield_global,
105875fd0b74Schristos                                          const char* comment, int method, int level, int raw,
105975fd0b74Schristos                                          int windowBits,int memLevel, int strategy,
106075fd0b74Schristos                                          const char* password, uLong crcForCrypting,
106175fd0b74Schristos                                          uLong versionMadeBy, uLong flagBase, int zip64)
106275fd0b74Schristos {
106375fd0b74Schristos     zip64_internal* zi;
106475fd0b74Schristos     uInt size_filename;
106575fd0b74Schristos     uInt size_comment;
106675fd0b74Schristos     uInt i;
106775fd0b74Schristos     int err = ZIP_OK;
106875fd0b74Schristos 
106975fd0b74Schristos #    ifdef NOCRYPT
107075fd0b74Schristos     (crcForCrypting);
107175fd0b74Schristos     if (password != NULL)
107275fd0b74Schristos         return ZIP_PARAMERROR;
107375fd0b74Schristos #    endif
107475fd0b74Schristos 
107575fd0b74Schristos     if (file == NULL)
107675fd0b74Schristos         return ZIP_PARAMERROR;
107775fd0b74Schristos 
107875fd0b74Schristos #ifdef HAVE_BZIP2
107975fd0b74Schristos     if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
108075fd0b74Schristos       return ZIP_PARAMERROR;
108175fd0b74Schristos #else
108275fd0b74Schristos     if ((method!=0) && (method!=Z_DEFLATED))
108375fd0b74Schristos       return ZIP_PARAMERROR;
108475fd0b74Schristos #endif
108575fd0b74Schristos 
108675fd0b74Schristos     zi = (zip64_internal*)file;
108775fd0b74Schristos 
108875fd0b74Schristos     if (zi->in_opened_file_inzip == 1)
108975fd0b74Schristos     {
109075fd0b74Schristos         err = zipCloseFileInZip (file);
109175fd0b74Schristos         if (err != ZIP_OK)
109275fd0b74Schristos             return err;
109375fd0b74Schristos     }
109475fd0b74Schristos 
109575fd0b74Schristos     if (filename==NULL)
109675fd0b74Schristos         filename="-";
109775fd0b74Schristos 
109875fd0b74Schristos     if (comment==NULL)
109975fd0b74Schristos         size_comment = 0;
110075fd0b74Schristos     else
110175fd0b74Schristos         size_comment = (uInt)strlen(comment);
110275fd0b74Schristos 
110375fd0b74Schristos     size_filename = (uInt)strlen(filename);
110475fd0b74Schristos 
110575fd0b74Schristos     if (zipfi == NULL)
110675fd0b74Schristos         zi->ci.dosDate = 0;
110775fd0b74Schristos     else
110875fd0b74Schristos     {
110975fd0b74Schristos         if (zipfi->dosDate != 0)
111075fd0b74Schristos             zi->ci.dosDate = zipfi->dosDate;
111175fd0b74Schristos         else
111275fd0b74Schristos           zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
111375fd0b74Schristos     }
111475fd0b74Schristos 
111575fd0b74Schristos     zi->ci.flag = flagBase;
111675fd0b74Schristos     if ((level==8) || (level==9))
111775fd0b74Schristos       zi->ci.flag |= 2;
111875fd0b74Schristos     if (level==2)
111975fd0b74Schristos       zi->ci.flag |= 4;
112075fd0b74Schristos     if (level==1)
112175fd0b74Schristos       zi->ci.flag |= 6;
112275fd0b74Schristos     if (password != NULL)
112375fd0b74Schristos       zi->ci.flag |= 1;
112475fd0b74Schristos 
112575fd0b74Schristos     zi->ci.crc32 = 0;
112675fd0b74Schristos     zi->ci.method = method;
112775fd0b74Schristos     zi->ci.encrypt = 0;
112875fd0b74Schristos     zi->ci.stream_initialised = 0;
112975fd0b74Schristos     zi->ci.pos_in_buffered_data = 0;
113075fd0b74Schristos     zi->ci.raw = raw;
113175fd0b74Schristos     zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
113275fd0b74Schristos 
113375fd0b74Schristos     zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
113475fd0b74Schristos     zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
113575fd0b74Schristos 
113675fd0b74Schristos     zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
113775fd0b74Schristos 
113875fd0b74Schristos     zi->ci.size_centralExtra = size_extrafield_global;
113975fd0b74Schristos     zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
114075fd0b74Schristos     /* version info */
114175fd0b74Schristos     zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
114275fd0b74Schristos     zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
114375fd0b74Schristos     zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
114475fd0b74Schristos     zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
114575fd0b74Schristos     zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
114675fd0b74Schristos     zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
114775fd0b74Schristos     zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
114875fd0b74Schristos     zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
114975fd0b74Schristos     zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
115075fd0b74Schristos     zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
115175fd0b74Schristos     zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
115275fd0b74Schristos     zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
115375fd0b74Schristos 
115475fd0b74Schristos     if (zipfi==NULL)
115575fd0b74Schristos         zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
115675fd0b74Schristos     else
115775fd0b74Schristos         zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
115875fd0b74Schristos 
115975fd0b74Schristos     if (zipfi==NULL)
116075fd0b74Schristos         zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
116175fd0b74Schristos     else
116275fd0b74Schristos         zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
116375fd0b74Schristos 
116475fd0b74Schristos     if(zi->ci.pos_local_header >= 0xffffffff)
116575fd0b74Schristos       zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
116675fd0b74Schristos     else
1167ede78133Schristos       zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writing_offset,4);
116875fd0b74Schristos 
116975fd0b74Schristos     for (i=0;i<size_filename;i++)
117075fd0b74Schristos         *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
117175fd0b74Schristos 
117275fd0b74Schristos     for (i=0;i<size_extrafield_global;i++)
117375fd0b74Schristos         *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
117475fd0b74Schristos               *(((const char*)extrafield_global)+i);
117575fd0b74Schristos 
117675fd0b74Schristos     for (i=0;i<size_comment;i++)
117775fd0b74Schristos         *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
117875fd0b74Schristos               size_extrafield_global+i) = *(comment+i);
117975fd0b74Schristos     if (zi->ci.central_header == NULL)
118075fd0b74Schristos         return ZIP_INTERNALERROR;
118175fd0b74Schristos 
118275fd0b74Schristos     zi->ci.zip64 = zip64;
118375fd0b74Schristos     zi->ci.totalCompressedData = 0;
118475fd0b74Schristos     zi->ci.totalUncompressedData = 0;
118575fd0b74Schristos     zi->ci.pos_zip64extrainfo = 0;
118675fd0b74Schristos 
118775fd0b74Schristos     err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);
118875fd0b74Schristos 
118975fd0b74Schristos #ifdef HAVE_BZIP2
119075fd0b74Schristos     zi->ci.bstream.avail_in = (uInt)0;
119175fd0b74Schristos     zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
119275fd0b74Schristos     zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
119375fd0b74Schristos     zi->ci.bstream.total_in_hi32 = 0;
119475fd0b74Schristos     zi->ci.bstream.total_in_lo32 = 0;
119575fd0b74Schristos     zi->ci.bstream.total_out_hi32 = 0;
119675fd0b74Schristos     zi->ci.bstream.total_out_lo32 = 0;
119775fd0b74Schristos #endif
119875fd0b74Schristos 
119975fd0b74Schristos     zi->ci.stream.avail_in = (uInt)0;
120075fd0b74Schristos     zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
120175fd0b74Schristos     zi->ci.stream.next_out = zi->ci.buffered_data;
120275fd0b74Schristos     zi->ci.stream.total_in = 0;
120375fd0b74Schristos     zi->ci.stream.total_out = 0;
120475fd0b74Schristos     zi->ci.stream.data_type = Z_BINARY;
120575fd0b74Schristos 
120675fd0b74Schristos #ifdef HAVE_BZIP2
120775fd0b74Schristos     if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
120875fd0b74Schristos #else
120975fd0b74Schristos     if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
121075fd0b74Schristos #endif
121175fd0b74Schristos     {
121275fd0b74Schristos         if(zi->ci.method == Z_DEFLATED)
121375fd0b74Schristos         {
121475fd0b74Schristos           zi->ci.stream.zalloc = (alloc_func)0;
121575fd0b74Schristos           zi->ci.stream.zfree = (free_func)0;
121675fd0b74Schristos           zi->ci.stream.opaque = (voidpf)0;
121775fd0b74Schristos 
121875fd0b74Schristos           if (windowBits>0)
121975fd0b74Schristos               windowBits = -windowBits;
122075fd0b74Schristos 
122175fd0b74Schristos           err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
122275fd0b74Schristos 
122375fd0b74Schristos           if (err==Z_OK)
122475fd0b74Schristos               zi->ci.stream_initialised = Z_DEFLATED;
122575fd0b74Schristos         }
122675fd0b74Schristos         else if(zi->ci.method == Z_BZIP2ED)
122775fd0b74Schristos         {
122875fd0b74Schristos #ifdef HAVE_BZIP2
122975fd0b74Schristos             // Init BZip stuff here
123075fd0b74Schristos           zi->ci.bstream.bzalloc = 0;
123175fd0b74Schristos           zi->ci.bstream.bzfree = 0;
123275fd0b74Schristos           zi->ci.bstream.opaque = (voidpf)0;
123375fd0b74Schristos 
123475fd0b74Schristos           err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
123575fd0b74Schristos           if(err == BZ_OK)
123675fd0b74Schristos             zi->ci.stream_initialised = Z_BZIP2ED;
123775fd0b74Schristos #endif
123875fd0b74Schristos         }
123975fd0b74Schristos 
124075fd0b74Schristos     }
124175fd0b74Schristos 
124275fd0b74Schristos #    ifndef NOCRYPT
124375fd0b74Schristos     zi->ci.crypt_header_size = 0;
124475fd0b74Schristos     if ((err==Z_OK) && (password != NULL))
124575fd0b74Schristos     {
124675fd0b74Schristos         unsigned char bufHead[RAND_HEAD_LEN];
124775fd0b74Schristos         unsigned int sizeHead;
124875fd0b74Schristos         zi->ci.encrypt = 1;
124975fd0b74Schristos         zi->ci.pcrc_32_tab = get_crc_table();
125075fd0b74Schristos         /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
125175fd0b74Schristos 
125275fd0b74Schristos         sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
125375fd0b74Schristos         zi->ci.crypt_header_size = sizeHead;
125475fd0b74Schristos 
125575fd0b74Schristos         if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
125675fd0b74Schristos                 err = ZIP_ERRNO;
125775fd0b74Schristos     }
125875fd0b74Schristos #    endif
125975fd0b74Schristos 
126075fd0b74Schristos     if (err==Z_OK)
126175fd0b74Schristos         zi->in_opened_file_inzip = 1;
126275fd0b74Schristos     return err;
126375fd0b74Schristos }
126475fd0b74Schristos 
zipOpenNewFileInZip4(zipFile file,const char * filename,const zip_fileinfo * zipfi,const void * extrafield_local,uInt size_extrafield_local,const void * extrafield_global,uInt size_extrafield_global,const char * comment,int method,int level,int raw,int windowBits,int memLevel,int strategy,const char * password,uLong crcForCrypting,uLong versionMadeBy,uLong flagBase)126575fd0b74Schristos extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
126675fd0b74Schristos                                          const void* extrafield_local, uInt size_extrafield_local,
126775fd0b74Schristos                                          const void* extrafield_global, uInt size_extrafield_global,
126875fd0b74Schristos                                          const char* comment, int method, int level, int raw,
126975fd0b74Schristos                                          int windowBits,int memLevel, int strategy,
127075fd0b74Schristos                                          const char* password, uLong crcForCrypting,
127175fd0b74Schristos                                          uLong versionMadeBy, uLong flagBase)
127275fd0b74Schristos {
127375fd0b74Schristos     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
127475fd0b74Schristos                                  extrafield_local, size_extrafield_local,
127575fd0b74Schristos                                  extrafield_global, size_extrafield_global,
127675fd0b74Schristos                                  comment, method, level, raw,
127775fd0b74Schristos                                  windowBits, memLevel, strategy,
127875fd0b74Schristos                                  password, crcForCrypting, versionMadeBy, flagBase, 0);
127975fd0b74Schristos }
128075fd0b74Schristos 
zipOpenNewFileInZip3(zipFile file,const char * filename,const zip_fileinfo * zipfi,const void * extrafield_local,uInt size_extrafield_local,const void * extrafield_global,uInt size_extrafield_global,const char * comment,int method,int level,int raw,int windowBits,int memLevel,int strategy,const char * password,uLong crcForCrypting)128175fd0b74Schristos extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
128275fd0b74Schristos                                          const void* extrafield_local, uInt size_extrafield_local,
128375fd0b74Schristos                                          const void* extrafield_global, uInt size_extrafield_global,
128475fd0b74Schristos                                          const char* comment, int method, int level, int raw,
128575fd0b74Schristos                                          int windowBits,int memLevel, int strategy,
128675fd0b74Schristos                                          const char* password, uLong crcForCrypting)
128775fd0b74Schristos {
128875fd0b74Schristos     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
128975fd0b74Schristos                                  extrafield_local, size_extrafield_local,
129075fd0b74Schristos                                  extrafield_global, size_extrafield_global,
129175fd0b74Schristos                                  comment, method, level, raw,
129275fd0b74Schristos                                  windowBits, memLevel, strategy,
129375fd0b74Schristos                                  password, crcForCrypting, VERSIONMADEBY, 0, 0);
129475fd0b74Schristos }
129575fd0b74Schristos 
zipOpenNewFileInZip3_64(zipFile file,const char * filename,const zip_fileinfo * zipfi,const void * extrafield_local,uInt size_extrafield_local,const void * extrafield_global,uInt size_extrafield_global,const char * comment,int method,int level,int raw,int windowBits,int memLevel,int strategy,const char * password,uLong crcForCrypting,int zip64)129675fd0b74Schristos extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
129775fd0b74Schristos                                          const void* extrafield_local, uInt size_extrafield_local,
129875fd0b74Schristos                                          const void* extrafield_global, uInt size_extrafield_global,
129975fd0b74Schristos                                          const char* comment, int method, int level, int raw,
130075fd0b74Schristos                                          int windowBits,int memLevel, int strategy,
130175fd0b74Schristos                                          const char* password, uLong crcForCrypting, int zip64)
130275fd0b74Schristos {
130375fd0b74Schristos     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
130475fd0b74Schristos                                  extrafield_local, size_extrafield_local,
130575fd0b74Schristos                                  extrafield_global, size_extrafield_global,
130675fd0b74Schristos                                  comment, method, level, raw,
130775fd0b74Schristos                                  windowBits, memLevel, strategy,
130875fd0b74Schristos                                  password, crcForCrypting, VERSIONMADEBY, 0, zip64);
130975fd0b74Schristos }
131075fd0b74Schristos 
zipOpenNewFileInZip2(zipFile file,const char * filename,const zip_fileinfo * zipfi,const void * extrafield_local,uInt size_extrafield_local,const void * extrafield_global,uInt size_extrafield_global,const char * comment,int method,int level,int raw)131175fd0b74Schristos extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
131275fd0b74Schristos                                         const void* extrafield_local, uInt size_extrafield_local,
131375fd0b74Schristos                                         const void* extrafield_global, uInt size_extrafield_global,
131475fd0b74Schristos                                         const char* comment, int method, int level, int raw)
131575fd0b74Schristos {
131675fd0b74Schristos     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
131775fd0b74Schristos                                  extrafield_local, size_extrafield_local,
131875fd0b74Schristos                                  extrafield_global, size_extrafield_global,
131975fd0b74Schristos                                  comment, method, level, raw,
132075fd0b74Schristos                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
132175fd0b74Schristos                                  NULL, 0, VERSIONMADEBY, 0, 0);
132275fd0b74Schristos }
132375fd0b74Schristos 
zipOpenNewFileInZip2_64(zipFile file,const char * filename,const zip_fileinfo * zipfi,const void * extrafield_local,uInt size_extrafield_local,const void * extrafield_global,uInt size_extrafield_global,const char * comment,int method,int level,int raw,int zip64)132475fd0b74Schristos extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
132575fd0b74Schristos                                         const void* extrafield_local, uInt size_extrafield_local,
132675fd0b74Schristos                                         const void* extrafield_global, uInt size_extrafield_global,
132775fd0b74Schristos                                         const char* comment, int method, int level, int raw, int zip64)
132875fd0b74Schristos {
132975fd0b74Schristos     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
133075fd0b74Schristos                                  extrafield_local, size_extrafield_local,
133175fd0b74Schristos                                  extrafield_global, size_extrafield_global,
133275fd0b74Schristos                                  comment, method, level, raw,
133375fd0b74Schristos                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
133475fd0b74Schristos                                  NULL, 0, VERSIONMADEBY, 0, zip64);
133575fd0b74Schristos }
133675fd0b74Schristos 
zipOpenNewFileInZip64(zipFile file,const char * filename,const zip_fileinfo * zipfi,const void * extrafield_local,uInt size_extrafield_local,const void * extrafield_global,uInt size_extrafield_global,const char * comment,int method,int level,int zip64)133775fd0b74Schristos extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
133875fd0b74Schristos                                         const void* extrafield_local, uInt size_extrafield_local,
133975fd0b74Schristos                                         const void*extrafield_global, uInt size_extrafield_global,
134075fd0b74Schristos                                         const char* comment, int method, int level, int zip64)
134175fd0b74Schristos {
134275fd0b74Schristos     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
134375fd0b74Schristos                                  extrafield_local, size_extrafield_local,
134475fd0b74Schristos                                  extrafield_global, size_extrafield_global,
134575fd0b74Schristos                                  comment, method, level, 0,
134675fd0b74Schristos                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
134775fd0b74Schristos                                  NULL, 0, VERSIONMADEBY, 0, zip64);
134875fd0b74Schristos }
134975fd0b74Schristos 
zipOpenNewFileInZip(zipFile file,const char * filename,const zip_fileinfo * zipfi,const void * extrafield_local,uInt size_extrafield_local,const void * extrafield_global,uInt size_extrafield_global,const char * comment,int method,int level)135075fd0b74Schristos extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
135175fd0b74Schristos                                         const void* extrafield_local, uInt size_extrafield_local,
135275fd0b74Schristos                                         const void*extrafield_global, uInt size_extrafield_global,
135375fd0b74Schristos                                         const char* comment, int method, int level)
135475fd0b74Schristos {
135575fd0b74Schristos     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
135675fd0b74Schristos                                  extrafield_local, size_extrafield_local,
135775fd0b74Schristos                                  extrafield_global, size_extrafield_global,
135875fd0b74Schristos                                  comment, method, level, 0,
135975fd0b74Schristos                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
136075fd0b74Schristos                                  NULL, 0, VERSIONMADEBY, 0, 0);
136175fd0b74Schristos }
136275fd0b74Schristos 
zip64FlushWriteBuffer(zip64_internal * zi)136375fd0b74Schristos local int zip64FlushWriteBuffer(zip64_internal* zi)
136475fd0b74Schristos {
136575fd0b74Schristos     int err=ZIP_OK;
136675fd0b74Schristos 
136775fd0b74Schristos     if (zi->ci.encrypt != 0)
136875fd0b74Schristos     {
136975fd0b74Schristos #ifndef NOCRYPT
137075fd0b74Schristos         uInt i;
137175fd0b74Schristos         int t;
137275fd0b74Schristos         for (i=0;i<zi->ci.pos_in_buffered_data;i++)
137375fd0b74Schristos             zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
137475fd0b74Schristos #endif
137575fd0b74Schristos     }
137675fd0b74Schristos 
137775fd0b74Schristos     if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
137875fd0b74Schristos       err = ZIP_ERRNO;
137975fd0b74Schristos 
138075fd0b74Schristos     zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
138175fd0b74Schristos 
138275fd0b74Schristos #ifdef HAVE_BZIP2
138375fd0b74Schristos     if(zi->ci.method == Z_BZIP2ED)
138475fd0b74Schristos     {
138575fd0b74Schristos       zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
138675fd0b74Schristos       zi->ci.bstream.total_in_lo32 = 0;
138775fd0b74Schristos       zi->ci.bstream.total_in_hi32 = 0;
138875fd0b74Schristos     }
138975fd0b74Schristos     else
139075fd0b74Schristos #endif
139175fd0b74Schristos     {
139275fd0b74Schristos       zi->ci.totalUncompressedData += zi->ci.stream.total_in;
139375fd0b74Schristos       zi->ci.stream.total_in = 0;
139475fd0b74Schristos     }
139575fd0b74Schristos 
139675fd0b74Schristos 
139775fd0b74Schristos     zi->ci.pos_in_buffered_data = 0;
139875fd0b74Schristos 
139975fd0b74Schristos     return err;
140075fd0b74Schristos }
140175fd0b74Schristos 
zipWriteInFileInZip(zipFile file,const void * buf,unsigned int len)140275fd0b74Schristos extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
140375fd0b74Schristos {
140475fd0b74Schristos     zip64_internal* zi;
140575fd0b74Schristos     int err=ZIP_OK;
140675fd0b74Schristos 
140775fd0b74Schristos     if (file == NULL)
140875fd0b74Schristos         return ZIP_PARAMERROR;
140975fd0b74Schristos     zi = (zip64_internal*)file;
141075fd0b74Schristos 
141175fd0b74Schristos     if (zi->in_opened_file_inzip == 0)
141275fd0b74Schristos         return ZIP_PARAMERROR;
141375fd0b74Schristos 
141475fd0b74Schristos     zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
141575fd0b74Schristos 
141675fd0b74Schristos #ifdef HAVE_BZIP2
141775fd0b74Schristos     if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
141875fd0b74Schristos     {
141975fd0b74Schristos       zi->ci.bstream.next_in = (void*)buf;
142075fd0b74Schristos       zi->ci.bstream.avail_in = len;
142175fd0b74Schristos       err = BZ_RUN_OK;
142275fd0b74Schristos 
142375fd0b74Schristos       while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
142475fd0b74Schristos       {
142575fd0b74Schristos         if (zi->ci.bstream.avail_out == 0)
142675fd0b74Schristos         {
142775fd0b74Schristos           if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
142875fd0b74Schristos             err = ZIP_ERRNO;
142975fd0b74Schristos           zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
143075fd0b74Schristos           zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
143175fd0b74Schristos         }
143275fd0b74Schristos 
143375fd0b74Schristos 
143475fd0b74Schristos         if(err != BZ_RUN_OK)
143575fd0b74Schristos           break;
143675fd0b74Schristos 
143775fd0b74Schristos         if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
143875fd0b74Schristos         {
143975fd0b74Schristos           uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
144075fd0b74Schristos //          uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
144175fd0b74Schristos           err=BZ2_bzCompress(&zi->ci.bstream,  BZ_RUN);
144275fd0b74Schristos 
144375fd0b74Schristos           zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
144475fd0b74Schristos         }
144575fd0b74Schristos       }
144675fd0b74Schristos 
144775fd0b74Schristos       if(err == BZ_RUN_OK)
144875fd0b74Schristos         err = ZIP_OK;
144975fd0b74Schristos     }
145075fd0b74Schristos     else
145175fd0b74Schristos #endif
145275fd0b74Schristos     {
145375fd0b74Schristos       zi->ci.stream.next_in = (Bytef*)buf;
145475fd0b74Schristos       zi->ci.stream.avail_in = len;
145575fd0b74Schristos 
145675fd0b74Schristos       while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
145775fd0b74Schristos       {
145875fd0b74Schristos           if (zi->ci.stream.avail_out == 0)
145975fd0b74Schristos           {
146075fd0b74Schristos               if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
146175fd0b74Schristos                   err = ZIP_ERRNO;
146275fd0b74Schristos               zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
146375fd0b74Schristos               zi->ci.stream.next_out = zi->ci.buffered_data;
146475fd0b74Schristos           }
146575fd0b74Schristos 
146675fd0b74Schristos 
146775fd0b74Schristos           if(err != ZIP_OK)
146875fd0b74Schristos               break;
146975fd0b74Schristos 
147075fd0b74Schristos           if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
147175fd0b74Schristos           {
147275fd0b74Schristos               uLong uTotalOutBefore = zi->ci.stream.total_out;
147375fd0b74Schristos               err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
147475fd0b74Schristos               if(uTotalOutBefore > zi->ci.stream.total_out)
147575fd0b74Schristos               {
147675fd0b74Schristos                 int bBreak = 0;
147775fd0b74Schristos                 bBreak++;
147875fd0b74Schristos               }
147975fd0b74Schristos 
148075fd0b74Schristos               zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
148175fd0b74Schristos           }
148275fd0b74Schristos           else
148375fd0b74Schristos           {
148475fd0b74Schristos               uInt copy_this,i;
148575fd0b74Schristos               if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
148675fd0b74Schristos                   copy_this = zi->ci.stream.avail_in;
148775fd0b74Schristos               else
148875fd0b74Schristos                   copy_this = zi->ci.stream.avail_out;
148975fd0b74Schristos 
149075fd0b74Schristos               for (i = 0; i < copy_this; i++)
149175fd0b74Schristos                   *(((char*)zi->ci.stream.next_out)+i) =
149275fd0b74Schristos                       *(((const char*)zi->ci.stream.next_in)+i);
149375fd0b74Schristos               {
149475fd0b74Schristos                   zi->ci.stream.avail_in -= copy_this;
149575fd0b74Schristos                   zi->ci.stream.avail_out-= copy_this;
149675fd0b74Schristos                   zi->ci.stream.next_in+= copy_this;
149775fd0b74Schristos                   zi->ci.stream.next_out+= copy_this;
149875fd0b74Schristos                   zi->ci.stream.total_in+= copy_this;
149975fd0b74Schristos                   zi->ci.stream.total_out+= copy_this;
150075fd0b74Schristos                   zi->ci.pos_in_buffered_data += copy_this;
150175fd0b74Schristos               }
150275fd0b74Schristos           }
150375fd0b74Schristos       }// while(...)
150475fd0b74Schristos     }
150575fd0b74Schristos 
150675fd0b74Schristos     return err;
150775fd0b74Schristos }
150875fd0b74Schristos 
zipCloseFileInZipRaw(zipFile file,uLong uncompressed_size,uLong crc32)150975fd0b74Schristos extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
151075fd0b74Schristos {
151175fd0b74Schristos     return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
151275fd0b74Schristos }
151375fd0b74Schristos 
zipCloseFileInZipRaw64(zipFile file,ZPOS64_T uncompressed_size,uLong crc32)151475fd0b74Schristos extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
151575fd0b74Schristos {
151675fd0b74Schristos     zip64_internal* zi;
151775fd0b74Schristos     ZPOS64_T compressed_size;
151875fd0b74Schristos     uLong invalidValue = 0xffffffff;
1519*e992f068Schristos     unsigned datasize = 0;
152075fd0b74Schristos     int err=ZIP_OK;
152175fd0b74Schristos 
152275fd0b74Schristos     if (file == NULL)
152375fd0b74Schristos         return ZIP_PARAMERROR;
152475fd0b74Schristos     zi = (zip64_internal*)file;
152575fd0b74Schristos 
152675fd0b74Schristos     if (zi->in_opened_file_inzip == 0)
152775fd0b74Schristos         return ZIP_PARAMERROR;
152875fd0b74Schristos     zi->ci.stream.avail_in = 0;
152975fd0b74Schristos 
153075fd0b74Schristos     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
153175fd0b74Schristos                 {
153275fd0b74Schristos                         while (err==ZIP_OK)
153375fd0b74Schristos                         {
153475fd0b74Schristos                                 uLong uTotalOutBefore;
153575fd0b74Schristos                                 if (zi->ci.stream.avail_out == 0)
153675fd0b74Schristos                                 {
153775fd0b74Schristos                                         if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
153875fd0b74Schristos                                                 err = ZIP_ERRNO;
153975fd0b74Schristos                                         zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
154075fd0b74Schristos                                         zi->ci.stream.next_out = zi->ci.buffered_data;
154175fd0b74Schristos                                 }
154275fd0b74Schristos                                 uTotalOutBefore = zi->ci.stream.total_out;
154375fd0b74Schristos                                 err=deflate(&zi->ci.stream,  Z_FINISH);
154475fd0b74Schristos                                 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
154575fd0b74Schristos                         }
154675fd0b74Schristos                 }
154775fd0b74Schristos     else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
154875fd0b74Schristos     {
154975fd0b74Schristos #ifdef HAVE_BZIP2
155075fd0b74Schristos       err = BZ_FINISH_OK;
155175fd0b74Schristos       while (err==BZ_FINISH_OK)
155275fd0b74Schristos       {
155375fd0b74Schristos         uLong uTotalOutBefore;
155475fd0b74Schristos         if (zi->ci.bstream.avail_out == 0)
155575fd0b74Schristos         {
155675fd0b74Schristos           if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
155775fd0b74Schristos             err = ZIP_ERRNO;
155875fd0b74Schristos           zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
155975fd0b74Schristos           zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
156075fd0b74Schristos         }
156175fd0b74Schristos         uTotalOutBefore = zi->ci.bstream.total_out_lo32;
156275fd0b74Schristos         err=BZ2_bzCompress(&zi->ci.bstream,  BZ_FINISH);
156375fd0b74Schristos         if(err == BZ_STREAM_END)
156475fd0b74Schristos           err = Z_STREAM_END;
156575fd0b74Schristos 
156675fd0b74Schristos         zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
156775fd0b74Schristos       }
156875fd0b74Schristos 
156975fd0b74Schristos       if(err == BZ_FINISH_OK)
157075fd0b74Schristos         err = ZIP_OK;
157175fd0b74Schristos #endif
157275fd0b74Schristos     }
157375fd0b74Schristos 
157475fd0b74Schristos     if (err==Z_STREAM_END)
157575fd0b74Schristos         err=ZIP_OK; /* this is normal */
157675fd0b74Schristos 
157775fd0b74Schristos     if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
157875fd0b74Schristos                 {
157975fd0b74Schristos         if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
158075fd0b74Schristos             err = ZIP_ERRNO;
158175fd0b74Schristos                 }
158275fd0b74Schristos 
158375fd0b74Schristos     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
158475fd0b74Schristos     {
158575fd0b74Schristos         int tmp_err = deflateEnd(&zi->ci.stream);
158675fd0b74Schristos         if (err == ZIP_OK)
158775fd0b74Schristos             err = tmp_err;
158875fd0b74Schristos         zi->ci.stream_initialised = 0;
158975fd0b74Schristos     }
159075fd0b74Schristos #ifdef HAVE_BZIP2
159175fd0b74Schristos     else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
159275fd0b74Schristos     {
159375fd0b74Schristos       int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
159475fd0b74Schristos                         if (err==ZIP_OK)
159575fd0b74Schristos                                 err = tmperr;
159675fd0b74Schristos                         zi->ci.stream_initialised = 0;
159775fd0b74Schristos     }
159875fd0b74Schristos #endif
159975fd0b74Schristos 
160075fd0b74Schristos     if (!zi->ci.raw)
160175fd0b74Schristos     {
160275fd0b74Schristos         crc32 = (uLong)zi->ci.crc32;
160375fd0b74Schristos         uncompressed_size = zi->ci.totalUncompressedData;
160475fd0b74Schristos     }
160575fd0b74Schristos     compressed_size = zi->ci.totalCompressedData;
160675fd0b74Schristos 
160775fd0b74Schristos #    ifndef NOCRYPT
160875fd0b74Schristos     compressed_size += zi->ci.crypt_header_size;
160975fd0b74Schristos #    endif
161075fd0b74Schristos 
161175fd0b74Schristos     // update Current Item crc and sizes,
161275fd0b74Schristos     if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
161375fd0b74Schristos     {
161475fd0b74Schristos       /*version Made by*/
161575fd0b74Schristos       zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
161675fd0b74Schristos       /*version needed*/
161775fd0b74Schristos       zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);
161875fd0b74Schristos 
161975fd0b74Schristos     }
162075fd0b74Schristos 
162175fd0b74Schristos     zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
162275fd0b74Schristos 
162375fd0b74Schristos 
162475fd0b74Schristos     if(compressed_size >= 0xffffffff)
162575fd0b74Schristos       zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
162675fd0b74Schristos     else
162775fd0b74Schristos       zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
162875fd0b74Schristos 
162975fd0b74Schristos     /// set internal file attributes field
163075fd0b74Schristos     if (zi->ci.stream.data_type == Z_ASCII)
163175fd0b74Schristos         zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
163275fd0b74Schristos 
163375fd0b74Schristos     if(uncompressed_size >= 0xffffffff)
163475fd0b74Schristos       zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
163575fd0b74Schristos     else
163675fd0b74Schristos       zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
163775fd0b74Schristos 
163875fd0b74Schristos     // Add ZIP64 extra info field for uncompressed size
163975fd0b74Schristos     if(uncompressed_size >= 0xffffffff)
164075fd0b74Schristos       datasize += 8;
164175fd0b74Schristos 
164275fd0b74Schristos     // Add ZIP64 extra info field for compressed size
164375fd0b74Schristos     if(compressed_size >= 0xffffffff)
164475fd0b74Schristos       datasize += 8;
164575fd0b74Schristos 
164675fd0b74Schristos     // Add ZIP64 extra info field for relative offset to local file header of current file
164775fd0b74Schristos     if(zi->ci.pos_local_header >= 0xffffffff)
164875fd0b74Schristos       datasize += 8;
164975fd0b74Schristos 
165075fd0b74Schristos     if(datasize > 0)
165175fd0b74Schristos     {
165275fd0b74Schristos       char* p = NULL;
165375fd0b74Schristos 
165475fd0b74Schristos       if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
165575fd0b74Schristos       {
165675fd0b74Schristos         // we can not write more data to the buffer that we have room for.
165775fd0b74Schristos         return ZIP_BADZIPFILE;
165875fd0b74Schristos       }
165975fd0b74Schristos 
166075fd0b74Schristos       p = zi->ci.central_header + zi->ci.size_centralheader;
166175fd0b74Schristos 
166275fd0b74Schristos       // Add Extra Information Header for 'ZIP64 information'
166375fd0b74Schristos       zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
166475fd0b74Schristos       p += 2;
166575fd0b74Schristos       zip64local_putValue_inmemory(p, datasize, 2); // DataSize
166675fd0b74Schristos       p += 2;
166775fd0b74Schristos 
166875fd0b74Schristos       if(uncompressed_size >= 0xffffffff)
166975fd0b74Schristos       {
167075fd0b74Schristos         zip64local_putValue_inmemory(p, uncompressed_size, 8);
167175fd0b74Schristos         p += 8;
167275fd0b74Schristos       }
167375fd0b74Schristos 
167475fd0b74Schristos       if(compressed_size >= 0xffffffff)
167575fd0b74Schristos       {
167675fd0b74Schristos         zip64local_putValue_inmemory(p, compressed_size, 8);
167775fd0b74Schristos         p += 8;
167875fd0b74Schristos       }
167975fd0b74Schristos 
168075fd0b74Schristos       if(zi->ci.pos_local_header >= 0xffffffff)
168175fd0b74Schristos       {
168275fd0b74Schristos         zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
168375fd0b74Schristos         p += 8;
168475fd0b74Schristos       }
168575fd0b74Schristos 
168675fd0b74Schristos       // Update how much extra free space we got in the memory buffer
168775fd0b74Schristos       // and increase the centralheader size so the new ZIP64 fields are included
168875fd0b74Schristos       // ( 4 below is the size of HeaderID and DataSize field )
168975fd0b74Schristos       zi->ci.size_centralExtraFree -= datasize + 4;
169075fd0b74Schristos       zi->ci.size_centralheader += datasize + 4;
169175fd0b74Schristos 
169275fd0b74Schristos       // Update the extra info size field
169375fd0b74Schristos       zi->ci.size_centralExtra += datasize + 4;
169475fd0b74Schristos       zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
169575fd0b74Schristos     }
169675fd0b74Schristos 
169775fd0b74Schristos     if (err==ZIP_OK)
169875fd0b74Schristos         err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
169975fd0b74Schristos 
170075fd0b74Schristos     free(zi->ci.central_header);
170175fd0b74Schristos 
170275fd0b74Schristos     if (err==ZIP_OK)
170375fd0b74Schristos     {
170475fd0b74Schristos         // Update the LocalFileHeader with the new values.
170575fd0b74Schristos 
170675fd0b74Schristos         ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
170775fd0b74Schristos 
170875fd0b74Schristos         if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
170975fd0b74Schristos             err = ZIP_ERRNO;
171075fd0b74Schristos 
171175fd0b74Schristos         if (err==ZIP_OK)
171275fd0b74Schristos             err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
171375fd0b74Schristos 
171475fd0b74Schristos         if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff )
171575fd0b74Schristos         {
171675fd0b74Schristos           if(zi->ci.pos_zip64extrainfo > 0)
171775fd0b74Schristos           {
171875fd0b74Schristos             // Update the size in the ZIP64 extended field.
171975fd0b74Schristos             if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
172075fd0b74Schristos               err = ZIP_ERRNO;
172175fd0b74Schristos 
172275fd0b74Schristos             if (err==ZIP_OK) /* compressed size, unknown */
172375fd0b74Schristos               err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
172475fd0b74Schristos 
172575fd0b74Schristos             if (err==ZIP_OK) /* uncompressed size, unknown */
172675fd0b74Schristos               err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
172775fd0b74Schristos           }
172875fd0b74Schristos           else
172975fd0b74Schristos               err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal
173075fd0b74Schristos         }
173175fd0b74Schristos         else
173275fd0b74Schristos         {
173375fd0b74Schristos           if (err==ZIP_OK) /* compressed size, unknown */
173475fd0b74Schristos               err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
173575fd0b74Schristos 
173675fd0b74Schristos           if (err==ZIP_OK) /* uncompressed size, unknown */
173775fd0b74Schristos               err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
173875fd0b74Schristos         }
173975fd0b74Schristos 
174075fd0b74Schristos         if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
174175fd0b74Schristos             err = ZIP_ERRNO;
174275fd0b74Schristos     }
174375fd0b74Schristos 
174475fd0b74Schristos     zi->number_entry ++;
174575fd0b74Schristos     zi->in_opened_file_inzip = 0;
174675fd0b74Schristos 
174775fd0b74Schristos     return err;
174875fd0b74Schristos }
174975fd0b74Schristos 
zipCloseFileInZip(zipFile file)175075fd0b74Schristos extern int ZEXPORT zipCloseFileInZip (zipFile file)
175175fd0b74Schristos {
175275fd0b74Schristos     return zipCloseFileInZipRaw (file,0,0);
175375fd0b74Schristos }
175475fd0b74Schristos 
Write_Zip64EndOfCentralDirectoryLocator(zip64_internal * zi,ZPOS64_T zip64eocd_pos_inzip)1755*e992f068Schristos local int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
175675fd0b74Schristos {
175775fd0b74Schristos   int err = ZIP_OK;
1758ede78133Schristos   ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writing_offset;
175975fd0b74Schristos 
176075fd0b74Schristos   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
176175fd0b74Schristos 
176275fd0b74Schristos   /*num disks*/
176375fd0b74Schristos     if (err==ZIP_OK) /* number of the disk with the start of the central directory */
176475fd0b74Schristos       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
176575fd0b74Schristos 
176675fd0b74Schristos   /*relative offset*/
176775fd0b74Schristos     if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
176875fd0b74Schristos       err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
176975fd0b74Schristos 
177075fd0b74Schristos   /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
177175fd0b74Schristos     if (err==ZIP_OK) /* number of the disk with the start of the central directory */
177275fd0b74Schristos       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
177375fd0b74Schristos 
177475fd0b74Schristos     return err;
177575fd0b74Schristos }
177675fd0b74Schristos 
Write_Zip64EndOfCentralDirectoryRecord(zip64_internal * zi,uLong size_centraldir,ZPOS64_T centraldir_pos_inzip)1777*e992f068Schristos local int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
177875fd0b74Schristos {
177975fd0b74Schristos   int err = ZIP_OK;
178075fd0b74Schristos 
178175fd0b74Schristos   uLong Zip64DataSize = 44;
178275fd0b74Schristos 
178375fd0b74Schristos   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
178475fd0b74Schristos 
178575fd0b74Schristos   if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
178675fd0b74Schristos     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?
178775fd0b74Schristos 
178875fd0b74Schristos   if (err==ZIP_OK) /* version made by */
178975fd0b74Schristos     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
179075fd0b74Schristos 
179175fd0b74Schristos   if (err==ZIP_OK) /* version needed */
179275fd0b74Schristos     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
179375fd0b74Schristos 
179475fd0b74Schristos   if (err==ZIP_OK) /* number of this disk */
179575fd0b74Schristos     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
179675fd0b74Schristos 
179775fd0b74Schristos   if (err==ZIP_OK) /* number of the disk with the start of the central directory */
179875fd0b74Schristos     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
179975fd0b74Schristos 
180075fd0b74Schristos   if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
180175fd0b74Schristos     err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
180275fd0b74Schristos 
180375fd0b74Schristos   if (err==ZIP_OK) /* total number of entries in the central dir */
180475fd0b74Schristos     err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
180575fd0b74Schristos 
180675fd0b74Schristos   if (err==ZIP_OK) /* size of the central directory */
180775fd0b74Schristos     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
180875fd0b74Schristos 
180975fd0b74Schristos   if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
181075fd0b74Schristos   {
1811ede78133Schristos     ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset;
181275fd0b74Schristos     err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
181375fd0b74Schristos   }
181475fd0b74Schristos   return err;
181575fd0b74Schristos }
Write_EndOfCentralDirectoryRecord(zip64_internal * zi,uLong size_centraldir,ZPOS64_T centraldir_pos_inzip)1816*e992f068Schristos local int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
181775fd0b74Schristos {
181875fd0b74Schristos   int err = ZIP_OK;
181975fd0b74Schristos 
182075fd0b74Schristos   /*signature*/
182175fd0b74Schristos   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
182275fd0b74Schristos 
182375fd0b74Schristos   if (err==ZIP_OK) /* number of this disk */
182475fd0b74Schristos     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
182575fd0b74Schristos 
182675fd0b74Schristos   if (err==ZIP_OK) /* number of the disk with the start of the central directory */
182775fd0b74Schristos     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
182875fd0b74Schristos 
182975fd0b74Schristos   if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
183075fd0b74Schristos   {
183175fd0b74Schristos     {
183275fd0b74Schristos       if(zi->number_entry >= 0xFFFF)
183375fd0b74Schristos         err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
183475fd0b74Schristos       else
183575fd0b74Schristos         err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
183675fd0b74Schristos     }
183775fd0b74Schristos   }
183875fd0b74Schristos 
183975fd0b74Schristos   if (err==ZIP_OK) /* total number of entries in the central dir */
184075fd0b74Schristos   {
184175fd0b74Schristos     if(zi->number_entry >= 0xFFFF)
184275fd0b74Schristos       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
184375fd0b74Schristos     else
184475fd0b74Schristos       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
184575fd0b74Schristos   }
184675fd0b74Schristos 
184775fd0b74Schristos   if (err==ZIP_OK) /* size of the central directory */
184875fd0b74Schristos     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
184975fd0b74Schristos 
185075fd0b74Schristos   if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
185175fd0b74Schristos   {
1852ede78133Schristos     ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset;
185375fd0b74Schristos     if(pos >= 0xffffffff)
185475fd0b74Schristos     {
185575fd0b74Schristos       err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
185675fd0b74Schristos     }
185775fd0b74Schristos     else
1858ede78133Schristos       err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writing_offset),4);
185975fd0b74Schristos   }
186075fd0b74Schristos 
186175fd0b74Schristos    return err;
186275fd0b74Schristos }
186375fd0b74Schristos 
Write_GlobalComment(zip64_internal * zi,const char * global_comment)1864*e992f068Schristos local int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
186575fd0b74Schristos {
186675fd0b74Schristos   int err = ZIP_OK;
186775fd0b74Schristos   uInt size_global_comment = 0;
186875fd0b74Schristos 
186975fd0b74Schristos   if(global_comment != NULL)
187075fd0b74Schristos     size_global_comment = (uInt)strlen(global_comment);
187175fd0b74Schristos 
187275fd0b74Schristos   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
187375fd0b74Schristos 
187475fd0b74Schristos   if (err == ZIP_OK && size_global_comment > 0)
187575fd0b74Schristos   {
187675fd0b74Schristos     if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
187775fd0b74Schristos       err = ZIP_ERRNO;
187875fd0b74Schristos   }
187975fd0b74Schristos   return err;
188075fd0b74Schristos }
188175fd0b74Schristos 
zipClose(zipFile file,const char * global_comment)188275fd0b74Schristos extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
188375fd0b74Schristos {
188475fd0b74Schristos     zip64_internal* zi;
188575fd0b74Schristos     int err = 0;
188675fd0b74Schristos     uLong size_centraldir = 0;
188775fd0b74Schristos     ZPOS64_T centraldir_pos_inzip;
188875fd0b74Schristos     ZPOS64_T pos;
188975fd0b74Schristos 
189075fd0b74Schristos     if (file == NULL)
189175fd0b74Schristos         return ZIP_PARAMERROR;
189275fd0b74Schristos 
189375fd0b74Schristos     zi = (zip64_internal*)file;
189475fd0b74Schristos 
189575fd0b74Schristos     if (zi->in_opened_file_inzip == 1)
189675fd0b74Schristos     {
189775fd0b74Schristos         err = zipCloseFileInZip (file);
189875fd0b74Schristos     }
189975fd0b74Schristos 
190075fd0b74Schristos #ifndef NO_ADDFILEINEXISTINGZIP
190175fd0b74Schristos     if (global_comment==NULL)
190275fd0b74Schristos         global_comment = zi->globalcomment;
190375fd0b74Schristos #endif
190475fd0b74Schristos 
190575fd0b74Schristos     centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
190675fd0b74Schristos 
190775fd0b74Schristos     if (err==ZIP_OK)
190875fd0b74Schristos     {
190975fd0b74Schristos         linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
191075fd0b74Schristos         while (ldi!=NULL)
191175fd0b74Schristos         {
191275fd0b74Schristos             if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
191375fd0b74Schristos             {
191475fd0b74Schristos                 if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
191575fd0b74Schristos                     err = ZIP_ERRNO;
191675fd0b74Schristos             }
191775fd0b74Schristos 
191875fd0b74Schristos             size_centraldir += ldi->filled_in_this_block;
191975fd0b74Schristos             ldi = ldi->next_datablock;
192075fd0b74Schristos         }
192175fd0b74Schristos     }
192275fd0b74Schristos     free_linkedlist(&(zi->central_dir));
192375fd0b74Schristos 
1924ede78133Schristos     pos = centraldir_pos_inzip - zi->add_position_when_writing_offset;
192575fd0b74Schristos     if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)
192675fd0b74Schristos     {
192775fd0b74Schristos       ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
192875fd0b74Schristos       Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
192975fd0b74Schristos 
193075fd0b74Schristos       Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
193175fd0b74Schristos     }
193275fd0b74Schristos 
193375fd0b74Schristos     if (err==ZIP_OK)
193475fd0b74Schristos       err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
193575fd0b74Schristos 
193675fd0b74Schristos     if(err == ZIP_OK)
193775fd0b74Schristos       err = Write_GlobalComment(zi, global_comment);
193875fd0b74Schristos 
193975fd0b74Schristos     if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)
194075fd0b74Schristos         if (err == ZIP_OK)
194175fd0b74Schristos             err = ZIP_ERRNO;
194275fd0b74Schristos 
194375fd0b74Schristos #ifndef NO_ADDFILEINEXISTINGZIP
194475fd0b74Schristos     TRYFREE(zi->globalcomment);
194575fd0b74Schristos #endif
194675fd0b74Schristos     TRYFREE(zi);
194775fd0b74Schristos 
194875fd0b74Schristos     return err;
194975fd0b74Schristos }
195075fd0b74Schristos 
zipRemoveExtraInfoBlock(char * pData,int * dataLen,short sHeader)195175fd0b74Schristos extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
195275fd0b74Schristos {
195375fd0b74Schristos   char* p = pData;
195475fd0b74Schristos   int size = 0;
195575fd0b74Schristos   char* pNewHeader;
195675fd0b74Schristos   char* pTmp;
195775fd0b74Schristos   short header;
195875fd0b74Schristos   short dataSize;
195975fd0b74Schristos 
196075fd0b74Schristos   int retVal = ZIP_OK;
196175fd0b74Schristos 
196275fd0b74Schristos   if(pData == NULL || *dataLen < 4)
196375fd0b74Schristos     return ZIP_PARAMERROR;
196475fd0b74Schristos 
1965*e992f068Schristos   pNewHeader = (char*)ALLOC((unsigned)*dataLen);
196675fd0b74Schristos   pTmp = pNewHeader;
196775fd0b74Schristos 
196875fd0b74Schristos   while(p < (pData + *dataLen))
196975fd0b74Schristos   {
197075fd0b74Schristos     header = *(short*)p;
197175fd0b74Schristos     dataSize = *(((short*)p)+1);
197275fd0b74Schristos 
197375fd0b74Schristos     if( header == sHeader ) // Header found.
197475fd0b74Schristos     {
197575fd0b74Schristos       p += dataSize + 4; // skip it. do not copy to temp buffer
197675fd0b74Schristos     }
197775fd0b74Schristos     else
197875fd0b74Schristos     {
197975fd0b74Schristos       // Extra Info block should not be removed, So copy it to the temp buffer.
198075fd0b74Schristos       memcpy(pTmp, p, dataSize + 4);
198175fd0b74Schristos       p += dataSize + 4;
198275fd0b74Schristos       size += dataSize + 4;
198375fd0b74Schristos     }
198475fd0b74Schristos 
198575fd0b74Schristos   }
198675fd0b74Schristos 
198775fd0b74Schristos   if(size < *dataLen)
198875fd0b74Schristos   {
198975fd0b74Schristos     // clean old extra info block.
199075fd0b74Schristos     memset(pData,0, *dataLen);
199175fd0b74Schristos 
199275fd0b74Schristos     // copy the new extra info block over the old
199375fd0b74Schristos     if(size > 0)
199475fd0b74Schristos       memcpy(pData, pNewHeader, size);
199575fd0b74Schristos 
199675fd0b74Schristos     // set the new extra info size
199775fd0b74Schristos     *dataLen = size;
199875fd0b74Schristos 
199975fd0b74Schristos     retVal = ZIP_OK;
200075fd0b74Schristos   }
200175fd0b74Schristos   else
200275fd0b74Schristos     retVal = ZIP_ERRNO;
200375fd0b74Schristos 
200475fd0b74Schristos   TRYFREE(pNewHeader);
200575fd0b74Schristos 
200675fd0b74Schristos   return retVal;
200775fd0b74Schristos }
2008