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