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