Mercurial > hg > sv-dependency-builds
comparison src/zlib-1.2.7/contrib/minizip/unzip.c @ 4:e13257ea84a4
Add bzip2, zlib, liblo, portaudio sources
author | Chris Cannam |
---|---|
date | Wed, 20 Mar 2013 13:59:52 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:6c505a35919a | 4:e13257ea84a4 |
---|---|
1 /* unzip.c -- IO for uncompress .zip files using zlib | |
2 Version 1.1, February 14h, 2010 | |
3 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) | |
4 | |
5 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) | |
6 | |
7 Modifications of Unzip for Zip64 | |
8 Copyright (C) 2007-2008 Even Rouault | |
9 | |
10 Modifications for Zip64 support on both zip and unzip | |
11 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) | |
12 | |
13 For more info read MiniZip_info.txt | |
14 | |
15 | |
16 ------------------------------------------------------------------------------------ | |
17 Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of | |
18 compatibility with older software. The following is from the original crypt.c. | |
19 Code woven in by Terry Thorsen 1/2003. | |
20 | |
21 Copyright (c) 1990-2000 Info-ZIP. All rights reserved. | |
22 | |
23 See the accompanying file LICENSE, version 2000-Apr-09 or later | |
24 (the contents of which are also included in zip.h) for terms of use. | |
25 If, for some reason, all these files are missing, the Info-ZIP license | |
26 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html | |
27 | |
28 crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] | |
29 | |
30 The encryption/decryption parts of this source code (as opposed to the | |
31 non-echoing password parts) were originally written in Europe. The | |
32 whole source package can be freely distributed, including from the USA. | |
33 (Prior to January 2000, re-export from the US was a violation of US law.) | |
34 | |
35 This encryption code is a direct transcription of the algorithm from | |
36 Roger Schlafly, described by Phil Katz in the file appnote.txt. This | |
37 file (appnote.txt) is distributed with the PKZIP program (even in the | |
38 version without encryption capabilities). | |
39 | |
40 ------------------------------------------------------------------------------------ | |
41 | |
42 Changes in unzip.c | |
43 | |
44 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos | |
45 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz* | |
46 2007-2008 - Even Rouault - Remove old C style function prototypes | |
47 2007-2008 - Even Rouault - Add unzip support for ZIP64 | |
48 | |
49 Copyright (C) 2007-2008 Even Rouault | |
50 | |
51 | |
52 Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). | |
53 Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G | |
54 should only read the compressed/uncompressed size from the Zip64 format if | |
55 the size from normal header was 0xFFFFFFFF | |
56 Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant | |
57 Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required) | |
58 Patch created by Daniel Borca | |
59 | |
60 Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer | |
61 | |
62 Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson | |
63 | |
64 */ | |
65 | |
66 | |
67 #include <stdio.h> | |
68 #include <stdlib.h> | |
69 #include <string.h> | |
70 | |
71 #ifndef NOUNCRYPT | |
72 #define NOUNCRYPT | |
73 #endif | |
74 | |
75 #include "zlib.h" | |
76 #include "unzip.h" | |
77 | |
78 #ifdef STDC | |
79 # include <stddef.h> | |
80 # include <string.h> | |
81 # include <stdlib.h> | |
82 #endif | |
83 #ifdef NO_ERRNO_H | |
84 extern int errno; | |
85 #else | |
86 # include <errno.h> | |
87 #endif | |
88 | |
89 | |
90 #ifndef local | |
91 # define local static | |
92 #endif | |
93 /* compile with -Dlocal if your debugger can't find static symbols */ | |
94 | |
95 | |
96 #ifndef CASESENSITIVITYDEFAULT_NO | |
97 # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) | |
98 # define CASESENSITIVITYDEFAULT_NO | |
99 # endif | |
100 #endif | |
101 | |
102 | |
103 #ifndef UNZ_BUFSIZE | |
104 #define UNZ_BUFSIZE (16384) | |
105 #endif | |
106 | |
107 #ifndef UNZ_MAXFILENAMEINZIP | |
108 #define UNZ_MAXFILENAMEINZIP (256) | |
109 #endif | |
110 | |
111 #ifndef ALLOC | |
112 # define ALLOC(size) (malloc(size)) | |
113 #endif | |
114 #ifndef TRYFREE | |
115 # define TRYFREE(p) {if (p) free(p);} | |
116 #endif | |
117 | |
118 #define SIZECENTRALDIRITEM (0x2e) | |
119 #define SIZEZIPLOCALHEADER (0x1e) | |
120 | |
121 | |
122 const char unz_copyright[] = | |
123 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; | |
124 | |
125 /* unz_file_info_interntal contain internal info about a file in zipfile*/ | |
126 typedef struct unz_file_info64_internal_s | |
127 { | |
128 ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ | |
129 } unz_file_info64_internal; | |
130 | |
131 | |
132 /* file_in_zip_read_info_s contain internal information about a file in zipfile, | |
133 when reading and decompress it */ | |
134 typedef struct | |
135 { | |
136 char *read_buffer; /* internal buffer for compressed data */ | |
137 z_stream stream; /* zLib stream structure for inflate */ | |
138 | |
139 #ifdef HAVE_BZIP2 | |
140 bz_stream bstream; /* bzLib stream structure for bziped */ | |
141 #endif | |
142 | |
143 ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ | |
144 uLong stream_initialised; /* flag set if stream structure is initialised*/ | |
145 | |
146 ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ | |
147 uInt size_local_extrafield;/* size of the local extra field */ | |
148 ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ | |
149 ZPOS64_T total_out_64; | |
150 | |
151 uLong crc32; /* crc32 of all data uncompressed */ | |
152 uLong crc32_wait; /* crc32 we must obtain after decompress all */ | |
153 ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ | |
154 ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ | |
155 zlib_filefunc64_32_def z_filefunc; | |
156 voidpf filestream; /* io structore of the zipfile */ | |
157 uLong compression_method; /* compression method (0==store) */ | |
158 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ | |
159 int raw; | |
160 } file_in_zip64_read_info_s; | |
161 | |
162 | |
163 /* unz64_s contain internal information about the zipfile | |
164 */ | |
165 typedef struct | |
166 { | |
167 zlib_filefunc64_32_def z_filefunc; | |
168 int is64bitOpenFunction; | |
169 voidpf filestream; /* io structore of the zipfile */ | |
170 unz_global_info64 gi; /* public global information */ | |
171 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ | |
172 ZPOS64_T num_file; /* number of the current file in the zipfile*/ | |
173 ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ | |
174 ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ | |
175 ZPOS64_T central_pos; /* position of the beginning of the central dir*/ | |
176 | |
177 ZPOS64_T size_central_dir; /* size of the central directory */ | |
178 ZPOS64_T offset_central_dir; /* offset of start of central directory with | |
179 respect to the starting disk number */ | |
180 | |
181 unz_file_info64 cur_file_info; /* public info about the current file in zip*/ | |
182 unz_file_info64_internal cur_file_info_internal; /* private info about it*/ | |
183 file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current | |
184 file if we are decompressing it */ | |
185 int encrypted; | |
186 | |
187 int isZip64; | |
188 | |
189 # ifndef NOUNCRYPT | |
190 unsigned long keys[3]; /* keys defining the pseudo-random sequence */ | |
191 const unsigned long* pcrc_32_tab; | |
192 # endif | |
193 } unz64_s; | |
194 | |
195 | |
196 #ifndef NOUNCRYPT | |
197 #include "crypt.h" | |
198 #endif | |
199 | |
200 /* =========================================================================== | |
201 Read a byte from a gz_stream; update next_in and avail_in. Return EOF | |
202 for end of file. | |
203 IN assertion: the stream s has been sucessfully opened for reading. | |
204 */ | |
205 | |
206 | |
207 local int unz64local_getByte OF(( | |
208 const zlib_filefunc64_32_def* pzlib_filefunc_def, | |
209 voidpf filestream, | |
210 int *pi)); | |
211 | |
212 local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) | |
213 { | |
214 unsigned char c; | |
215 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); | |
216 if (err==1) | |
217 { | |
218 *pi = (int)c; | |
219 return UNZ_OK; | |
220 } | |
221 else | |
222 { | |
223 if (ZERROR64(*pzlib_filefunc_def,filestream)) | |
224 return UNZ_ERRNO; | |
225 else | |
226 return UNZ_EOF; | |
227 } | |
228 } | |
229 | |
230 | |
231 /* =========================================================================== | |
232 Reads a long in LSB order from the given gz_stream. Sets | |
233 */ | |
234 local int unz64local_getShort OF(( | |
235 const zlib_filefunc64_32_def* pzlib_filefunc_def, | |
236 voidpf filestream, | |
237 uLong *pX)); | |
238 | |
239 local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, | |
240 voidpf filestream, | |
241 uLong *pX) | |
242 { | |
243 uLong x ; | |
244 int i = 0; | |
245 int err; | |
246 | |
247 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | |
248 x = (uLong)i; | |
249 | |
250 if (err==UNZ_OK) | |
251 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | |
252 x |= ((uLong)i)<<8; | |
253 | |
254 if (err==UNZ_OK) | |
255 *pX = x; | |
256 else | |
257 *pX = 0; | |
258 return err; | |
259 } | |
260 | |
261 local int unz64local_getLong OF(( | |
262 const zlib_filefunc64_32_def* pzlib_filefunc_def, | |
263 voidpf filestream, | |
264 uLong *pX)); | |
265 | |
266 local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, | |
267 voidpf filestream, | |
268 uLong *pX) | |
269 { | |
270 uLong x ; | |
271 int i = 0; | |
272 int err; | |
273 | |
274 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | |
275 x = (uLong)i; | |
276 | |
277 if (err==UNZ_OK) | |
278 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | |
279 x |= ((uLong)i)<<8; | |
280 | |
281 if (err==UNZ_OK) | |
282 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | |
283 x |= ((uLong)i)<<16; | |
284 | |
285 if (err==UNZ_OK) | |
286 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | |
287 x += ((uLong)i)<<24; | |
288 | |
289 if (err==UNZ_OK) | |
290 *pX = x; | |
291 else | |
292 *pX = 0; | |
293 return err; | |
294 } | |
295 | |
296 local int unz64local_getLong64 OF(( | |
297 const zlib_filefunc64_32_def* pzlib_filefunc_def, | |
298 voidpf filestream, | |
299 ZPOS64_T *pX)); | |
300 | |
301 | |
302 local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, | |
303 voidpf filestream, | |
304 ZPOS64_T *pX) | |
305 { | |
306 ZPOS64_T x ; | |
307 int i = 0; | |
308 int err; | |
309 | |
310 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | |
311 x = (ZPOS64_T)i; | |
312 | |
313 if (err==UNZ_OK) | |
314 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | |
315 x |= ((ZPOS64_T)i)<<8; | |
316 | |
317 if (err==UNZ_OK) | |
318 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | |
319 x |= ((ZPOS64_T)i)<<16; | |
320 | |
321 if (err==UNZ_OK) | |
322 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | |
323 x |= ((ZPOS64_T)i)<<24; | |
324 | |
325 if (err==UNZ_OK) | |
326 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | |
327 x |= ((ZPOS64_T)i)<<32; | |
328 | |
329 if (err==UNZ_OK) | |
330 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | |
331 x |= ((ZPOS64_T)i)<<40; | |
332 | |
333 if (err==UNZ_OK) | |
334 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | |
335 x |= ((ZPOS64_T)i)<<48; | |
336 | |
337 if (err==UNZ_OK) | |
338 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | |
339 x |= ((ZPOS64_T)i)<<56; | |
340 | |
341 if (err==UNZ_OK) | |
342 *pX = x; | |
343 else | |
344 *pX = 0; | |
345 return err; | |
346 } | |
347 | |
348 /* My own strcmpi / strcasecmp */ | |
349 local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) | |
350 { | |
351 for (;;) | |
352 { | |
353 char c1=*(fileName1++); | |
354 char c2=*(fileName2++); | |
355 if ((c1>='a') && (c1<='z')) | |
356 c1 -= 0x20; | |
357 if ((c2>='a') && (c2<='z')) | |
358 c2 -= 0x20; | |
359 if (c1=='\0') | |
360 return ((c2=='\0') ? 0 : -1); | |
361 if (c2=='\0') | |
362 return 1; | |
363 if (c1<c2) | |
364 return -1; | |
365 if (c1>c2) | |
366 return 1; | |
367 } | |
368 } | |
369 | |
370 | |
371 #ifdef CASESENSITIVITYDEFAULT_NO | |
372 #define CASESENSITIVITYDEFAULTVALUE 2 | |
373 #else | |
374 #define CASESENSITIVITYDEFAULTVALUE 1 | |
375 #endif | |
376 | |
377 #ifndef STRCMPCASENOSENTIVEFUNCTION | |
378 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal | |
379 #endif | |
380 | |
381 /* | |
382 Compare two filename (fileName1,fileName2). | |
383 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) | |
384 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi | |
385 or strcasecmp) | |
386 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system | |
387 (like 1 on Unix, 2 on Windows) | |
388 | |
389 */ | |
390 extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, | |
391 const char* fileName2, | |
392 int iCaseSensitivity) | |
393 | |
394 { | |
395 if (iCaseSensitivity==0) | |
396 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; | |
397 | |
398 if (iCaseSensitivity==1) | |
399 return strcmp(fileName1,fileName2); | |
400 | |
401 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); | |
402 } | |
403 | |
404 #ifndef BUFREADCOMMENT | |
405 #define BUFREADCOMMENT (0x400) | |
406 #endif | |
407 | |
408 /* | |
409 Locate the Central directory of a zipfile (at the end, just before | |
410 the global comment) | |
411 */ | |
412 local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); | |
413 local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) | |
414 { | |
415 unsigned char* buf; | |
416 ZPOS64_T uSizeFile; | |
417 ZPOS64_T uBackRead; | |
418 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ | |
419 ZPOS64_T uPosFound=0; | |
420 | |
421 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) | |
422 return 0; | |
423 | |
424 | |
425 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); | |
426 | |
427 if (uMaxBack>uSizeFile) | |
428 uMaxBack = uSizeFile; | |
429 | |
430 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); | |
431 if (buf==NULL) | |
432 return 0; | |
433 | |
434 uBackRead = 4; | |
435 while (uBackRead<uMaxBack) | |
436 { | |
437 uLong uReadSize; | |
438 ZPOS64_T uReadPos ; | |
439 int i; | |
440 if (uBackRead+BUFREADCOMMENT>uMaxBack) | |
441 uBackRead = uMaxBack; | |
442 else | |
443 uBackRead+=BUFREADCOMMENT; | |
444 uReadPos = uSizeFile-uBackRead ; | |
445 | |
446 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? | |
447 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); | |
448 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) | |
449 break; | |
450 | |
451 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) | |
452 break; | |
453 | |
454 for (i=(int)uReadSize-3; (i--)>0;) | |
455 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && | |
456 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) | |
457 { | |
458 uPosFound = uReadPos+i; | |
459 break; | |
460 } | |
461 | |
462 if (uPosFound!=0) | |
463 break; | |
464 } | |
465 TRYFREE(buf); | |
466 return uPosFound; | |
467 } | |
468 | |
469 | |
470 /* | |
471 Locate the Central directory 64 of a zipfile (at the end, just before | |
472 the global comment) | |
473 */ | |
474 local ZPOS64_T unz64local_SearchCentralDir64 OF(( | |
475 const zlib_filefunc64_32_def* pzlib_filefunc_def, | |
476 voidpf filestream)); | |
477 | |
478 local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, | |
479 voidpf filestream) | |
480 { | |
481 unsigned char* buf; | |
482 ZPOS64_T uSizeFile; | |
483 ZPOS64_T uBackRead; | |
484 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ | |
485 ZPOS64_T uPosFound=0; | |
486 uLong uL; | |
487 ZPOS64_T relativeOffset; | |
488 | |
489 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) | |
490 return 0; | |
491 | |
492 | |
493 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); | |
494 | |
495 if (uMaxBack>uSizeFile) | |
496 uMaxBack = uSizeFile; | |
497 | |
498 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); | |
499 if (buf==NULL) | |
500 return 0; | |
501 | |
502 uBackRead = 4; | |
503 while (uBackRead<uMaxBack) | |
504 { | |
505 uLong uReadSize; | |
506 ZPOS64_T uReadPos; | |
507 int i; | |
508 if (uBackRead+BUFREADCOMMENT>uMaxBack) | |
509 uBackRead = uMaxBack; | |
510 else | |
511 uBackRead+=BUFREADCOMMENT; | |
512 uReadPos = uSizeFile-uBackRead ; | |
513 | |
514 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? | |
515 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); | |
516 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) | |
517 break; | |
518 | |
519 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) | |
520 break; | |
521 | |
522 for (i=(int)uReadSize-3; (i--)>0;) | |
523 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && | |
524 ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) | |
525 { | |
526 uPosFound = uReadPos+i; | |
527 break; | |
528 } | |
529 | |
530 if (uPosFound!=0) | |
531 break; | |
532 } | |
533 TRYFREE(buf); | |
534 if (uPosFound == 0) | |
535 return 0; | |
536 | |
537 /* Zip64 end of central directory locator */ | |
538 if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) | |
539 return 0; | |
540 | |
541 /* the signature, already checked */ | |
542 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) | |
543 return 0; | |
544 | |
545 /* number of the disk with the start of the zip64 end of central directory */ | |
546 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) | |
547 return 0; | |
548 if (uL != 0) | |
549 return 0; | |
550 | |
551 /* relative offset of the zip64 end of central directory record */ | |
552 if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) | |
553 return 0; | |
554 | |
555 /* total number of disks */ | |
556 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) | |
557 return 0; | |
558 if (uL != 1) | |
559 return 0; | |
560 | |
561 /* Goto end of central directory record */ | |
562 if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) | |
563 return 0; | |
564 | |
565 /* the signature */ | |
566 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) | |
567 return 0; | |
568 | |
569 if (uL != 0x06064b50) | |
570 return 0; | |
571 | |
572 return relativeOffset; | |
573 } | |
574 | |
575 /* | |
576 Open a Zip file. path contain the full pathname (by example, | |
577 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer | |
578 "zlib/zlib114.zip". | |
579 If the zipfile cannot be opened (file doesn't exist or in not valid), the | |
580 return value is NULL. | |
581 Else, the return value is a unzFile Handle, usable with other function | |
582 of this unzip package. | |
583 */ | |
584 local unzFile unzOpenInternal (const void *path, | |
585 zlib_filefunc64_32_def* pzlib_filefunc64_32_def, | |
586 int is64bitOpenFunction) | |
587 { | |
588 unz64_s us; | |
589 unz64_s *s; | |
590 ZPOS64_T central_pos; | |
591 uLong uL; | |
592 | |
593 uLong number_disk; /* number of the current dist, used for | |
594 spaning ZIP, unsupported, always 0*/ | |
595 uLong number_disk_with_CD; /* number the the disk with central dir, used | |
596 for spaning ZIP, unsupported, always 0*/ | |
597 ZPOS64_T number_entry_CD; /* total number of entries in | |
598 the central dir | |
599 (same than number_entry on nospan) */ | |
600 | |
601 int err=UNZ_OK; | |
602 | |
603 if (unz_copyright[0]!=' ') | |
604 return NULL; | |
605 | |
606 us.z_filefunc.zseek32_file = NULL; | |
607 us.z_filefunc.ztell32_file = NULL; | |
608 if (pzlib_filefunc64_32_def==NULL) | |
609 fill_fopen64_filefunc(&us.z_filefunc.zfile_func64); | |
610 else | |
611 us.z_filefunc = *pzlib_filefunc64_32_def; | |
612 us.is64bitOpenFunction = is64bitOpenFunction; | |
613 | |
614 | |
615 | |
616 us.filestream = ZOPEN64(us.z_filefunc, | |
617 path, | |
618 ZLIB_FILEFUNC_MODE_READ | | |
619 ZLIB_FILEFUNC_MODE_EXISTING); | |
620 if (us.filestream==NULL) | |
621 return NULL; | |
622 | |
623 central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); | |
624 if (central_pos) | |
625 { | |
626 uLong uS; | |
627 ZPOS64_T uL64; | |
628 | |
629 us.isZip64 = 1; | |
630 | |
631 if (ZSEEK64(us.z_filefunc, us.filestream, | |
632 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) | |
633 err=UNZ_ERRNO; | |
634 | |
635 /* the signature, already checked */ | |
636 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) | |
637 err=UNZ_ERRNO; | |
638 | |
639 /* size of zip64 end of central directory record */ | |
640 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) | |
641 err=UNZ_ERRNO; | |
642 | |
643 /* version made by */ | |
644 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) | |
645 err=UNZ_ERRNO; | |
646 | |
647 /* version needed to extract */ | |
648 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) | |
649 err=UNZ_ERRNO; | |
650 | |
651 /* number of this disk */ | |
652 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) | |
653 err=UNZ_ERRNO; | |
654 | |
655 /* number of the disk with the start of the central directory */ | |
656 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) | |
657 err=UNZ_ERRNO; | |
658 | |
659 /* total number of entries in the central directory on this disk */ | |
660 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) | |
661 err=UNZ_ERRNO; | |
662 | |
663 /* total number of entries in the central directory */ | |
664 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) | |
665 err=UNZ_ERRNO; | |
666 | |
667 if ((number_entry_CD!=us.gi.number_entry) || | |
668 (number_disk_with_CD!=0) || | |
669 (number_disk!=0)) | |
670 err=UNZ_BADZIPFILE; | |
671 | |
672 /* size of the central directory */ | |
673 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) | |
674 err=UNZ_ERRNO; | |
675 | |
676 /* offset of start of central directory with respect to the | |
677 starting disk number */ | |
678 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) | |
679 err=UNZ_ERRNO; | |
680 | |
681 us.gi.size_comment = 0; | |
682 } | |
683 else | |
684 { | |
685 central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); | |
686 if (central_pos==0) | |
687 err=UNZ_ERRNO; | |
688 | |
689 us.isZip64 = 0; | |
690 | |
691 if (ZSEEK64(us.z_filefunc, us.filestream, | |
692 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) | |
693 err=UNZ_ERRNO; | |
694 | |
695 /* the signature, already checked */ | |
696 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) | |
697 err=UNZ_ERRNO; | |
698 | |
699 /* number of this disk */ | |
700 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) | |
701 err=UNZ_ERRNO; | |
702 | |
703 /* number of the disk with the start of the central directory */ | |
704 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) | |
705 err=UNZ_ERRNO; | |
706 | |
707 /* total number of entries in the central dir on this disk */ | |
708 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) | |
709 err=UNZ_ERRNO; | |
710 us.gi.number_entry = uL; | |
711 | |
712 /* total number of entries in the central dir */ | |
713 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) | |
714 err=UNZ_ERRNO; | |
715 number_entry_CD = uL; | |
716 | |
717 if ((number_entry_CD!=us.gi.number_entry) || | |
718 (number_disk_with_CD!=0) || | |
719 (number_disk!=0)) | |
720 err=UNZ_BADZIPFILE; | |
721 | |
722 /* size of the central directory */ | |
723 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) | |
724 err=UNZ_ERRNO; | |
725 us.size_central_dir = uL; | |
726 | |
727 /* offset of start of central directory with respect to the | |
728 starting disk number */ | |
729 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) | |
730 err=UNZ_ERRNO; | |
731 us.offset_central_dir = uL; | |
732 | |
733 /* zipfile comment length */ | |
734 if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) | |
735 err=UNZ_ERRNO; | |
736 } | |
737 | |
738 if ((central_pos<us.offset_central_dir+us.size_central_dir) && | |
739 (err==UNZ_OK)) | |
740 err=UNZ_BADZIPFILE; | |
741 | |
742 if (err!=UNZ_OK) | |
743 { | |
744 ZCLOSE64(us.z_filefunc, us.filestream); | |
745 return NULL; | |
746 } | |
747 | |
748 us.byte_before_the_zipfile = central_pos - | |
749 (us.offset_central_dir+us.size_central_dir); | |
750 us.central_pos = central_pos; | |
751 us.pfile_in_zip_read = NULL; | |
752 us.encrypted = 0; | |
753 | |
754 | |
755 s=(unz64_s*)ALLOC(sizeof(unz64_s)); | |
756 if( s != NULL) | |
757 { | |
758 *s=us; | |
759 unzGoToFirstFile((unzFile)s); | |
760 } | |
761 return (unzFile)s; | |
762 } | |
763 | |
764 | |
765 extern unzFile ZEXPORT unzOpen2 (const char *path, | |
766 zlib_filefunc_def* pzlib_filefunc32_def) | |
767 { | |
768 if (pzlib_filefunc32_def != NULL) | |
769 { | |
770 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; | |
771 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); | |
772 return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0); | |
773 } | |
774 else | |
775 return unzOpenInternal(path, NULL, 0); | |
776 } | |
777 | |
778 extern unzFile ZEXPORT unzOpen2_64 (const void *path, | |
779 zlib_filefunc64_def* pzlib_filefunc_def) | |
780 { | |
781 if (pzlib_filefunc_def != NULL) | |
782 { | |
783 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; | |
784 zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; | |
785 zlib_filefunc64_32_def_fill.ztell32_file = NULL; | |
786 zlib_filefunc64_32_def_fill.zseek32_file = NULL; | |
787 return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1); | |
788 } | |
789 else | |
790 return unzOpenInternal(path, NULL, 1); | |
791 } | |
792 | |
793 extern unzFile ZEXPORT unzOpen (const char *path) | |
794 { | |
795 return unzOpenInternal(path, NULL, 0); | |
796 } | |
797 | |
798 extern unzFile ZEXPORT unzOpen64 (const void *path) | |
799 { | |
800 return unzOpenInternal(path, NULL, 1); | |
801 } | |
802 | |
803 /* | |
804 Close a ZipFile opened with unzipOpen. | |
805 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later), | |
806 these files MUST be closed with unzipCloseCurrentFile before call unzipClose. | |
807 return UNZ_OK if there is no problem. */ | |
808 extern int ZEXPORT unzClose (unzFile file) | |
809 { | |
810 unz64_s* s; | |
811 if (file==NULL) | |
812 return UNZ_PARAMERROR; | |
813 s=(unz64_s*)file; | |
814 | |
815 if (s->pfile_in_zip_read!=NULL) | |
816 unzCloseCurrentFile(file); | |
817 | |
818 ZCLOSE64(s->z_filefunc, s->filestream); | |
819 TRYFREE(s); | |
820 return UNZ_OK; | |
821 } | |
822 | |
823 | |
824 /* | |
825 Write info about the ZipFile in the *pglobal_info structure. | |
826 No preparation of the structure is needed | |
827 return UNZ_OK if there is no problem. */ | |
828 extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) | |
829 { | |
830 unz64_s* s; | |
831 if (file==NULL) | |
832 return UNZ_PARAMERROR; | |
833 s=(unz64_s*)file; | |
834 *pglobal_info=s->gi; | |
835 return UNZ_OK; | |
836 } | |
837 | |
838 extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) | |
839 { | |
840 unz64_s* s; | |
841 if (file==NULL) | |
842 return UNZ_PARAMERROR; | |
843 s=(unz64_s*)file; | |
844 /* to do : check if number_entry is not truncated */ | |
845 pglobal_info32->number_entry = (uLong)s->gi.number_entry; | |
846 pglobal_info32->size_comment = s->gi.size_comment; | |
847 return UNZ_OK; | |
848 } | |
849 /* | |
850 Translate date/time from Dos format to tm_unz (readable more easilty) | |
851 */ | |
852 local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) | |
853 { | |
854 ZPOS64_T uDate; | |
855 uDate = (ZPOS64_T)(ulDosDate>>16); | |
856 ptm->tm_mday = (uInt)(uDate&0x1f) ; | |
857 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; | |
858 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; | |
859 | |
860 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); | |
861 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; | |
862 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; | |
863 } | |
864 | |
865 /* | |
866 Get Info about the current file in the zipfile, with internal only info | |
867 */ | |
868 local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, | |
869 unz_file_info64 *pfile_info, | |
870 unz_file_info64_internal | |
871 *pfile_info_internal, | |
872 char *szFileName, | |
873 uLong fileNameBufferSize, | |
874 void *extraField, | |
875 uLong extraFieldBufferSize, | |
876 char *szComment, | |
877 uLong commentBufferSize)); | |
878 | |
879 local int unz64local_GetCurrentFileInfoInternal (unzFile file, | |
880 unz_file_info64 *pfile_info, | |
881 unz_file_info64_internal | |
882 *pfile_info_internal, | |
883 char *szFileName, | |
884 uLong fileNameBufferSize, | |
885 void *extraField, | |
886 uLong extraFieldBufferSize, | |
887 char *szComment, | |
888 uLong commentBufferSize) | |
889 { | |
890 unz64_s* s; | |
891 unz_file_info64 file_info; | |
892 unz_file_info64_internal file_info_internal; | |
893 int err=UNZ_OK; | |
894 uLong uMagic; | |
895 long lSeek=0; | |
896 uLong uL; | |
897 | |
898 if (file==NULL) | |
899 return UNZ_PARAMERROR; | |
900 s=(unz64_s*)file; | |
901 if (ZSEEK64(s->z_filefunc, s->filestream, | |
902 s->pos_in_central_dir+s->byte_before_the_zipfile, | |
903 ZLIB_FILEFUNC_SEEK_SET)!=0) | |
904 err=UNZ_ERRNO; | |
905 | |
906 | |
907 /* we check the magic */ | |
908 if (err==UNZ_OK) | |
909 { | |
910 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) | |
911 err=UNZ_ERRNO; | |
912 else if (uMagic!=0x02014b50) | |
913 err=UNZ_BADZIPFILE; | |
914 } | |
915 | |
916 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) | |
917 err=UNZ_ERRNO; | |
918 | |
919 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) | |
920 err=UNZ_ERRNO; | |
921 | |
922 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) | |
923 err=UNZ_ERRNO; | |
924 | |
925 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) | |
926 err=UNZ_ERRNO; | |
927 | |
928 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) | |
929 err=UNZ_ERRNO; | |
930 | |
931 unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); | |
932 | |
933 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) | |
934 err=UNZ_ERRNO; | |
935 | |
936 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) | |
937 err=UNZ_ERRNO; | |
938 file_info.compressed_size = uL; | |
939 | |
940 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) | |
941 err=UNZ_ERRNO; | |
942 file_info.uncompressed_size = uL; | |
943 | |
944 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) | |
945 err=UNZ_ERRNO; | |
946 | |
947 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) | |
948 err=UNZ_ERRNO; | |
949 | |
950 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) | |
951 err=UNZ_ERRNO; | |
952 | |
953 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) | |
954 err=UNZ_ERRNO; | |
955 | |
956 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) | |
957 err=UNZ_ERRNO; | |
958 | |
959 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) | |
960 err=UNZ_ERRNO; | |
961 | |
962 // relative offset of local header | |
963 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) | |
964 err=UNZ_ERRNO; | |
965 file_info_internal.offset_curfile = uL; | |
966 | |
967 lSeek+=file_info.size_filename; | |
968 if ((err==UNZ_OK) && (szFileName!=NULL)) | |
969 { | |
970 uLong uSizeRead ; | |
971 if (file_info.size_filename<fileNameBufferSize) | |
972 { | |
973 *(szFileName+file_info.size_filename)='\0'; | |
974 uSizeRead = file_info.size_filename; | |
975 } | |
976 else | |
977 uSizeRead = fileNameBufferSize; | |
978 | |
979 if ((file_info.size_filename>0) && (fileNameBufferSize>0)) | |
980 if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) | |
981 err=UNZ_ERRNO; | |
982 lSeek -= uSizeRead; | |
983 } | |
984 | |
985 // Read extrafield | |
986 if ((err==UNZ_OK) && (extraField!=NULL)) | |
987 { | |
988 ZPOS64_T uSizeRead ; | |
989 if (file_info.size_file_extra<extraFieldBufferSize) | |
990 uSizeRead = file_info.size_file_extra; | |
991 else | |
992 uSizeRead = extraFieldBufferSize; | |
993 | |
994 if (lSeek!=0) | |
995 { | |
996 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) | |
997 lSeek=0; | |
998 else | |
999 err=UNZ_ERRNO; | |
1000 } | |
1001 | |
1002 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) | |
1003 if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) | |
1004 err=UNZ_ERRNO; | |
1005 | |
1006 lSeek += file_info.size_file_extra - (uLong)uSizeRead; | |
1007 } | |
1008 else | |
1009 lSeek += file_info.size_file_extra; | |
1010 | |
1011 | |
1012 if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) | |
1013 { | |
1014 uLong acc = 0; | |
1015 | |
1016 // since lSeek now points to after the extra field we need to move back | |
1017 lSeek -= file_info.size_file_extra; | |
1018 | |
1019 if (lSeek!=0) | |
1020 { | |
1021 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) | |
1022 lSeek=0; | |
1023 else | |
1024 err=UNZ_ERRNO; | |
1025 } | |
1026 | |
1027 while(acc < file_info.size_file_extra) | |
1028 { | |
1029 uLong headerId; | |
1030 uLong dataSize; | |
1031 | |
1032 if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) | |
1033 err=UNZ_ERRNO; | |
1034 | |
1035 if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) | |
1036 err=UNZ_ERRNO; | |
1037 | |
1038 /* ZIP64 extra fields */ | |
1039 if (headerId == 0x0001) | |
1040 { | |
1041 uLong uL; | |
1042 | |
1043 if(file_info.uncompressed_size == MAXU32) | |
1044 { | |
1045 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) | |
1046 err=UNZ_ERRNO; | |
1047 } | |
1048 | |
1049 if(file_info.compressed_size == MAXU32) | |
1050 { | |
1051 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) | |
1052 err=UNZ_ERRNO; | |
1053 } | |
1054 | |
1055 if(file_info_internal.offset_curfile == MAXU32) | |
1056 { | |
1057 /* Relative Header offset */ | |
1058 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) | |
1059 err=UNZ_ERRNO; | |
1060 } | |
1061 | |
1062 if(file_info.disk_num_start == MAXU32) | |
1063 { | |
1064 /* Disk Start Number */ | |
1065 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) | |
1066 err=UNZ_ERRNO; | |
1067 } | |
1068 | |
1069 } | |
1070 else | |
1071 { | |
1072 if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) | |
1073 err=UNZ_ERRNO; | |
1074 } | |
1075 | |
1076 acc += 2 + 2 + dataSize; | |
1077 } | |
1078 } | |
1079 | |
1080 if ((err==UNZ_OK) && (szComment!=NULL)) | |
1081 { | |
1082 uLong uSizeRead ; | |
1083 if (file_info.size_file_comment<commentBufferSize) | |
1084 { | |
1085 *(szComment+file_info.size_file_comment)='\0'; | |
1086 uSizeRead = file_info.size_file_comment; | |
1087 } | |
1088 else | |
1089 uSizeRead = commentBufferSize; | |
1090 | |
1091 if (lSeek!=0) | |
1092 { | |
1093 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) | |
1094 lSeek=0; | |
1095 else | |
1096 err=UNZ_ERRNO; | |
1097 } | |
1098 | |
1099 if ((file_info.size_file_comment>0) && (commentBufferSize>0)) | |
1100 if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) | |
1101 err=UNZ_ERRNO; | |
1102 lSeek+=file_info.size_file_comment - uSizeRead; | |
1103 } | |
1104 else | |
1105 lSeek+=file_info.size_file_comment; | |
1106 | |
1107 | |
1108 if ((err==UNZ_OK) && (pfile_info!=NULL)) | |
1109 *pfile_info=file_info; | |
1110 | |
1111 if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) | |
1112 *pfile_info_internal=file_info_internal; | |
1113 | |
1114 return err; | |
1115 } | |
1116 | |
1117 | |
1118 | |
1119 /* | |
1120 Write info about the ZipFile in the *pglobal_info structure. | |
1121 No preparation of the structure is needed | |
1122 return UNZ_OK if there is no problem. | |
1123 */ | |
1124 extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, | |
1125 unz_file_info64 * pfile_info, | |
1126 char * szFileName, uLong fileNameBufferSize, | |
1127 void *extraField, uLong extraFieldBufferSize, | |
1128 char* szComment, uLong commentBufferSize) | |
1129 { | |
1130 return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, | |
1131 szFileName,fileNameBufferSize, | |
1132 extraField,extraFieldBufferSize, | |
1133 szComment,commentBufferSize); | |
1134 } | |
1135 | |
1136 extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, | |
1137 unz_file_info * pfile_info, | |
1138 char * szFileName, uLong fileNameBufferSize, | |
1139 void *extraField, uLong extraFieldBufferSize, | |
1140 char* szComment, uLong commentBufferSize) | |
1141 { | |
1142 int err; | |
1143 unz_file_info64 file_info64; | |
1144 err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, | |
1145 szFileName,fileNameBufferSize, | |
1146 extraField,extraFieldBufferSize, | |
1147 szComment,commentBufferSize); | |
1148 if ((err==UNZ_OK) && (pfile_info != NULL)) | |
1149 { | |
1150 pfile_info->version = file_info64.version; | |
1151 pfile_info->version_needed = file_info64.version_needed; | |
1152 pfile_info->flag = file_info64.flag; | |
1153 pfile_info->compression_method = file_info64.compression_method; | |
1154 pfile_info->dosDate = file_info64.dosDate; | |
1155 pfile_info->crc = file_info64.crc; | |
1156 | |
1157 pfile_info->size_filename = file_info64.size_filename; | |
1158 pfile_info->size_file_extra = file_info64.size_file_extra; | |
1159 pfile_info->size_file_comment = file_info64.size_file_comment; | |
1160 | |
1161 pfile_info->disk_num_start = file_info64.disk_num_start; | |
1162 pfile_info->internal_fa = file_info64.internal_fa; | |
1163 pfile_info->external_fa = file_info64.external_fa; | |
1164 | |
1165 pfile_info->tmu_date = file_info64.tmu_date, | |
1166 | |
1167 | |
1168 pfile_info->compressed_size = (uLong)file_info64.compressed_size; | |
1169 pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; | |
1170 | |
1171 } | |
1172 return err; | |
1173 } | |
1174 /* | |
1175 Set the current file of the zipfile to the first file. | |
1176 return UNZ_OK if there is no problem | |
1177 */ | |
1178 extern int ZEXPORT unzGoToFirstFile (unzFile file) | |
1179 { | |
1180 int err=UNZ_OK; | |
1181 unz64_s* s; | |
1182 if (file==NULL) | |
1183 return UNZ_PARAMERROR; | |
1184 s=(unz64_s*)file; | |
1185 s->pos_in_central_dir=s->offset_central_dir; | |
1186 s->num_file=0; | |
1187 err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, | |
1188 &s->cur_file_info_internal, | |
1189 NULL,0,NULL,0,NULL,0); | |
1190 s->current_file_ok = (err == UNZ_OK); | |
1191 return err; | |
1192 } | |
1193 | |
1194 /* | |
1195 Set the current file of the zipfile to the next file. | |
1196 return UNZ_OK if there is no problem | |
1197 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. | |
1198 */ | |
1199 extern int ZEXPORT unzGoToNextFile (unzFile file) | |
1200 { | |
1201 unz64_s* s; | |
1202 int err; | |
1203 | |
1204 if (file==NULL) | |
1205 return UNZ_PARAMERROR; | |
1206 s=(unz64_s*)file; | |
1207 if (!s->current_file_ok) | |
1208 return UNZ_END_OF_LIST_OF_FILE; | |
1209 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ | |
1210 if (s->num_file+1==s->gi.number_entry) | |
1211 return UNZ_END_OF_LIST_OF_FILE; | |
1212 | |
1213 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + | |
1214 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; | |
1215 s->num_file++; | |
1216 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, | |
1217 &s->cur_file_info_internal, | |
1218 NULL,0,NULL,0,NULL,0); | |
1219 s->current_file_ok = (err == UNZ_OK); | |
1220 return err; | |
1221 } | |
1222 | |
1223 | |
1224 /* | |
1225 Try locate the file szFileName in the zipfile. | |
1226 For the iCaseSensitivity signification, see unzipStringFileNameCompare | |
1227 | |
1228 return value : | |
1229 UNZ_OK if the file is found. It becomes the current file. | |
1230 UNZ_END_OF_LIST_OF_FILE if the file is not found | |
1231 */ | |
1232 extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) | |
1233 { | |
1234 unz64_s* s; | |
1235 int err; | |
1236 | |
1237 /* We remember the 'current' position in the file so that we can jump | |
1238 * back there if we fail. | |
1239 */ | |
1240 unz_file_info64 cur_file_infoSaved; | |
1241 unz_file_info64_internal cur_file_info_internalSaved; | |
1242 ZPOS64_T num_fileSaved; | |
1243 ZPOS64_T pos_in_central_dirSaved; | |
1244 | |
1245 | |
1246 if (file==NULL) | |
1247 return UNZ_PARAMERROR; | |
1248 | |
1249 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) | |
1250 return UNZ_PARAMERROR; | |
1251 | |
1252 s=(unz64_s*)file; | |
1253 if (!s->current_file_ok) | |
1254 return UNZ_END_OF_LIST_OF_FILE; | |
1255 | |
1256 /* Save the current state */ | |
1257 num_fileSaved = s->num_file; | |
1258 pos_in_central_dirSaved = s->pos_in_central_dir; | |
1259 cur_file_infoSaved = s->cur_file_info; | |
1260 cur_file_info_internalSaved = s->cur_file_info_internal; | |
1261 | |
1262 err = unzGoToFirstFile(file); | |
1263 | |
1264 while (err == UNZ_OK) | |
1265 { | |
1266 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; | |
1267 err = unzGetCurrentFileInfo64(file,NULL, | |
1268 szCurrentFileName,sizeof(szCurrentFileName)-1, | |
1269 NULL,0,NULL,0); | |
1270 if (err == UNZ_OK) | |
1271 { | |
1272 if (unzStringFileNameCompare(szCurrentFileName, | |
1273 szFileName,iCaseSensitivity)==0) | |
1274 return UNZ_OK; | |
1275 err = unzGoToNextFile(file); | |
1276 } | |
1277 } | |
1278 | |
1279 /* We failed, so restore the state of the 'current file' to where we | |
1280 * were. | |
1281 */ | |
1282 s->num_file = num_fileSaved ; | |
1283 s->pos_in_central_dir = pos_in_central_dirSaved ; | |
1284 s->cur_file_info = cur_file_infoSaved; | |
1285 s->cur_file_info_internal = cur_file_info_internalSaved; | |
1286 return err; | |
1287 } | |
1288 | |
1289 | |
1290 /* | |
1291 /////////////////////////////////////////// | |
1292 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) | |
1293 // I need random access | |
1294 // | |
1295 // Further optimization could be realized by adding an ability | |
1296 // to cache the directory in memory. The goal being a single | |
1297 // comprehensive file read to put the file I need in a memory. | |
1298 */ | |
1299 | |
1300 /* | |
1301 typedef struct unz_file_pos_s | |
1302 { | |
1303 ZPOS64_T pos_in_zip_directory; // offset in file | |
1304 ZPOS64_T num_of_file; // # of file | |
1305 } unz_file_pos; | |
1306 */ | |
1307 | |
1308 extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) | |
1309 { | |
1310 unz64_s* s; | |
1311 | |
1312 if (file==NULL || file_pos==NULL) | |
1313 return UNZ_PARAMERROR; | |
1314 s=(unz64_s*)file; | |
1315 if (!s->current_file_ok) | |
1316 return UNZ_END_OF_LIST_OF_FILE; | |
1317 | |
1318 file_pos->pos_in_zip_directory = s->pos_in_central_dir; | |
1319 file_pos->num_of_file = s->num_file; | |
1320 | |
1321 return UNZ_OK; | |
1322 } | |
1323 | |
1324 extern int ZEXPORT unzGetFilePos( | |
1325 unzFile file, | |
1326 unz_file_pos* file_pos) | |
1327 { | |
1328 unz64_file_pos file_pos64; | |
1329 int err = unzGetFilePos64(file,&file_pos64); | |
1330 if (err==UNZ_OK) | |
1331 { | |
1332 file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; | |
1333 file_pos->num_of_file = (uLong)file_pos64.num_of_file; | |
1334 } | |
1335 return err; | |
1336 } | |
1337 | |
1338 extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) | |
1339 { | |
1340 unz64_s* s; | |
1341 int err; | |
1342 | |
1343 if (file==NULL || file_pos==NULL) | |
1344 return UNZ_PARAMERROR; | |
1345 s=(unz64_s*)file; | |
1346 | |
1347 /* jump to the right spot */ | |
1348 s->pos_in_central_dir = file_pos->pos_in_zip_directory; | |
1349 s->num_file = file_pos->num_of_file; | |
1350 | |
1351 /* set the current file */ | |
1352 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, | |
1353 &s->cur_file_info_internal, | |
1354 NULL,0,NULL,0,NULL,0); | |
1355 /* return results */ | |
1356 s->current_file_ok = (err == UNZ_OK); | |
1357 return err; | |
1358 } | |
1359 | |
1360 extern int ZEXPORT unzGoToFilePos( | |
1361 unzFile file, | |
1362 unz_file_pos* file_pos) | |
1363 { | |
1364 unz64_file_pos file_pos64; | |
1365 if (file_pos == NULL) | |
1366 return UNZ_PARAMERROR; | |
1367 | |
1368 file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; | |
1369 file_pos64.num_of_file = file_pos->num_of_file; | |
1370 return unzGoToFilePos64(file,&file_pos64); | |
1371 } | |
1372 | |
1373 /* | |
1374 // Unzip Helper Functions - should be here? | |
1375 /////////////////////////////////////////// | |
1376 */ | |
1377 | |
1378 /* | |
1379 Read the local header of the current zipfile | |
1380 Check the coherency of the local header and info in the end of central | |
1381 directory about this file | |
1382 store in *piSizeVar the size of extra info in local header | |
1383 (filename and size of extra field data) | |
1384 */ | |
1385 local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, | |
1386 ZPOS64_T * poffset_local_extrafield, | |
1387 uInt * psize_local_extrafield) | |
1388 { | |
1389 uLong uMagic,uData,uFlags; | |
1390 uLong size_filename; | |
1391 uLong size_extra_field; | |
1392 int err=UNZ_OK; | |
1393 | |
1394 *piSizeVar = 0; | |
1395 *poffset_local_extrafield = 0; | |
1396 *psize_local_extrafield = 0; | |
1397 | |
1398 if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + | |
1399 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) | |
1400 return UNZ_ERRNO; | |
1401 | |
1402 | |
1403 if (err==UNZ_OK) | |
1404 { | |
1405 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) | |
1406 err=UNZ_ERRNO; | |
1407 else if (uMagic!=0x04034b50) | |
1408 err=UNZ_BADZIPFILE; | |
1409 } | |
1410 | |
1411 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) | |
1412 err=UNZ_ERRNO; | |
1413 /* | |
1414 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) | |
1415 err=UNZ_BADZIPFILE; | |
1416 */ | |
1417 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) | |
1418 err=UNZ_ERRNO; | |
1419 | |
1420 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) | |
1421 err=UNZ_ERRNO; | |
1422 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) | |
1423 err=UNZ_BADZIPFILE; | |
1424 | |
1425 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && | |
1426 /* #ifdef HAVE_BZIP2 */ | |
1427 (s->cur_file_info.compression_method!=Z_BZIP2ED) && | |
1428 /* #endif */ | |
1429 (s->cur_file_info.compression_method!=Z_DEFLATED)) | |
1430 err=UNZ_BADZIPFILE; | |
1431 | |
1432 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ | |
1433 err=UNZ_ERRNO; | |
1434 | |
1435 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ | |
1436 err=UNZ_ERRNO; | |
1437 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) | |
1438 err=UNZ_BADZIPFILE; | |
1439 | |
1440 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ | |
1441 err=UNZ_ERRNO; | |
1442 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) | |
1443 err=UNZ_BADZIPFILE; | |
1444 | |
1445 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ | |
1446 err=UNZ_ERRNO; | |
1447 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) | |
1448 err=UNZ_BADZIPFILE; | |
1449 | |
1450 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) | |
1451 err=UNZ_ERRNO; | |
1452 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) | |
1453 err=UNZ_BADZIPFILE; | |
1454 | |
1455 *piSizeVar += (uInt)size_filename; | |
1456 | |
1457 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) | |
1458 err=UNZ_ERRNO; | |
1459 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + | |
1460 SIZEZIPLOCALHEADER + size_filename; | |
1461 *psize_local_extrafield = (uInt)size_extra_field; | |
1462 | |
1463 *piSizeVar += (uInt)size_extra_field; | |
1464 | |
1465 return err; | |
1466 } | |
1467 | |
1468 /* | |
1469 Open for reading data the current file in the zipfile. | |
1470 If there is no error and the file is opened, the return value is UNZ_OK. | |
1471 */ | |
1472 extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, | |
1473 int* level, int raw, const char* password) | |
1474 { | |
1475 int err=UNZ_OK; | |
1476 uInt iSizeVar; | |
1477 unz64_s* s; | |
1478 file_in_zip64_read_info_s* pfile_in_zip_read_info; | |
1479 ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ | |
1480 uInt size_local_extrafield; /* size of the local extra field */ | |
1481 # ifndef NOUNCRYPT | |
1482 char source[12]; | |
1483 # else | |
1484 if (password != NULL) | |
1485 return UNZ_PARAMERROR; | |
1486 # endif | |
1487 | |
1488 if (file==NULL) | |
1489 return UNZ_PARAMERROR; | |
1490 s=(unz64_s*)file; | |
1491 if (!s->current_file_ok) | |
1492 return UNZ_PARAMERROR; | |
1493 | |
1494 if (s->pfile_in_zip_read != NULL) | |
1495 unzCloseCurrentFile(file); | |
1496 | |
1497 if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) | |
1498 return UNZ_BADZIPFILE; | |
1499 | |
1500 pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); | |
1501 if (pfile_in_zip_read_info==NULL) | |
1502 return UNZ_INTERNALERROR; | |
1503 | |
1504 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); | |
1505 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; | |
1506 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; | |
1507 pfile_in_zip_read_info->pos_local_extrafield=0; | |
1508 pfile_in_zip_read_info->raw=raw; | |
1509 | |
1510 if (pfile_in_zip_read_info->read_buffer==NULL) | |
1511 { | |
1512 TRYFREE(pfile_in_zip_read_info); | |
1513 return UNZ_INTERNALERROR; | |
1514 } | |
1515 | |
1516 pfile_in_zip_read_info->stream_initialised=0; | |
1517 | |
1518 if (method!=NULL) | |
1519 *method = (int)s->cur_file_info.compression_method; | |
1520 | |
1521 if (level!=NULL) | |
1522 { | |
1523 *level = 6; | |
1524 switch (s->cur_file_info.flag & 0x06) | |
1525 { | |
1526 case 6 : *level = 1; break; | |
1527 case 4 : *level = 2; break; | |
1528 case 2 : *level = 9; break; | |
1529 } | |
1530 } | |
1531 | |
1532 if ((s->cur_file_info.compression_method!=0) && | |
1533 /* #ifdef HAVE_BZIP2 */ | |
1534 (s->cur_file_info.compression_method!=Z_BZIP2ED) && | |
1535 /* #endif */ | |
1536 (s->cur_file_info.compression_method!=Z_DEFLATED)) | |
1537 | |
1538 err=UNZ_BADZIPFILE; | |
1539 | |
1540 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; | |
1541 pfile_in_zip_read_info->crc32=0; | |
1542 pfile_in_zip_read_info->total_out_64=0; | |
1543 pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; | |
1544 pfile_in_zip_read_info->filestream=s->filestream; | |
1545 pfile_in_zip_read_info->z_filefunc=s->z_filefunc; | |
1546 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; | |
1547 | |
1548 pfile_in_zip_read_info->stream.total_out = 0; | |
1549 | |
1550 if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) | |
1551 { | |
1552 #ifdef HAVE_BZIP2 | |
1553 pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; | |
1554 pfile_in_zip_read_info->bstream.bzfree = (free_func)0; | |
1555 pfile_in_zip_read_info->bstream.opaque = (voidpf)0; | |
1556 pfile_in_zip_read_info->bstream.state = (voidpf)0; | |
1557 | |
1558 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; | |
1559 pfile_in_zip_read_info->stream.zfree = (free_func)0; | |
1560 pfile_in_zip_read_info->stream.opaque = (voidpf)0; | |
1561 pfile_in_zip_read_info->stream.next_in = (voidpf)0; | |
1562 pfile_in_zip_read_info->stream.avail_in = 0; | |
1563 | |
1564 err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); | |
1565 if (err == Z_OK) | |
1566 pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; | |
1567 else | |
1568 { | |
1569 TRYFREE(pfile_in_zip_read_info); | |
1570 return err; | |
1571 } | |
1572 #else | |
1573 pfile_in_zip_read_info->raw=1; | |
1574 #endif | |
1575 } | |
1576 else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) | |
1577 { | |
1578 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; | |
1579 pfile_in_zip_read_info->stream.zfree = (free_func)0; | |
1580 pfile_in_zip_read_info->stream.opaque = (voidpf)0; | |
1581 pfile_in_zip_read_info->stream.next_in = 0; | |
1582 pfile_in_zip_read_info->stream.avail_in = 0; | |
1583 | |
1584 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); | |
1585 if (err == Z_OK) | |
1586 pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; | |
1587 else | |
1588 { | |
1589 TRYFREE(pfile_in_zip_read_info); | |
1590 return err; | |
1591 } | |
1592 /* windowBits is passed < 0 to tell that there is no zlib header. | |
1593 * Note that in this case inflate *requires* an extra "dummy" byte | |
1594 * after the compressed stream in order to complete decompression and | |
1595 * return Z_STREAM_END. | |
1596 * In unzip, i don't wait absolutely Z_STREAM_END because I known the | |
1597 * size of both compressed and uncompressed data | |
1598 */ | |
1599 } | |
1600 pfile_in_zip_read_info->rest_read_compressed = | |
1601 s->cur_file_info.compressed_size ; | |
1602 pfile_in_zip_read_info->rest_read_uncompressed = | |
1603 s->cur_file_info.uncompressed_size ; | |
1604 | |
1605 | |
1606 pfile_in_zip_read_info->pos_in_zipfile = | |
1607 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + | |
1608 iSizeVar; | |
1609 | |
1610 pfile_in_zip_read_info->stream.avail_in = (uInt)0; | |
1611 | |
1612 s->pfile_in_zip_read = pfile_in_zip_read_info; | |
1613 s->encrypted = 0; | |
1614 | |
1615 # ifndef NOUNCRYPT | |
1616 if (password != NULL) | |
1617 { | |
1618 int i; | |
1619 s->pcrc_32_tab = get_crc_table(); | |
1620 init_keys(password,s->keys,s->pcrc_32_tab); | |
1621 if (ZSEEK64(s->z_filefunc, s->filestream, | |
1622 s->pfile_in_zip_read->pos_in_zipfile + | |
1623 s->pfile_in_zip_read->byte_before_the_zipfile, | |
1624 SEEK_SET)!=0) | |
1625 return UNZ_INTERNALERROR; | |
1626 if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) | |
1627 return UNZ_INTERNALERROR; | |
1628 | |
1629 for (i = 0; i<12; i++) | |
1630 zdecode(s->keys,s->pcrc_32_tab,source[i]); | |
1631 | |
1632 s->pfile_in_zip_read->pos_in_zipfile+=12; | |
1633 s->encrypted=1; | |
1634 } | |
1635 # endif | |
1636 | |
1637 | |
1638 return UNZ_OK; | |
1639 } | |
1640 | |
1641 extern int ZEXPORT unzOpenCurrentFile (unzFile file) | |
1642 { | |
1643 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); | |
1644 } | |
1645 | |
1646 extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) | |
1647 { | |
1648 return unzOpenCurrentFile3(file, NULL, NULL, 0, password); | |
1649 } | |
1650 | |
1651 extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) | |
1652 { | |
1653 return unzOpenCurrentFile3(file, method, level, raw, NULL); | |
1654 } | |
1655 | |
1656 /** Addition for GDAL : START */ | |
1657 | |
1658 extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) | |
1659 { | |
1660 unz64_s* s; | |
1661 file_in_zip64_read_info_s* pfile_in_zip_read_info; | |
1662 s=(unz64_s*)file; | |
1663 if (file==NULL) | |
1664 return 0; //UNZ_PARAMERROR; | |
1665 pfile_in_zip_read_info=s->pfile_in_zip_read; | |
1666 if (pfile_in_zip_read_info==NULL) | |
1667 return 0; //UNZ_PARAMERROR; | |
1668 return pfile_in_zip_read_info->pos_in_zipfile + | |
1669 pfile_in_zip_read_info->byte_before_the_zipfile; | |
1670 } | |
1671 | |
1672 /** Addition for GDAL : END */ | |
1673 | |
1674 /* | |
1675 Read bytes from the current file. | |
1676 buf contain buffer where data must be copied | |
1677 len the size of buf. | |
1678 | |
1679 return the number of byte copied if somes bytes are copied | |
1680 return 0 if the end of file was reached | |
1681 return <0 with error code if there is an error | |
1682 (UNZ_ERRNO for IO error, or zLib error for uncompress error) | |
1683 */ | |
1684 extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) | |
1685 { | |
1686 int err=UNZ_OK; | |
1687 uInt iRead = 0; | |
1688 unz64_s* s; | |
1689 file_in_zip64_read_info_s* pfile_in_zip_read_info; | |
1690 if (file==NULL) | |
1691 return UNZ_PARAMERROR; | |
1692 s=(unz64_s*)file; | |
1693 pfile_in_zip_read_info=s->pfile_in_zip_read; | |
1694 | |
1695 if (pfile_in_zip_read_info==NULL) | |
1696 return UNZ_PARAMERROR; | |
1697 | |
1698 | |
1699 if (pfile_in_zip_read_info->read_buffer == NULL) | |
1700 return UNZ_END_OF_LIST_OF_FILE; | |
1701 if (len==0) | |
1702 return 0; | |
1703 | |
1704 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; | |
1705 | |
1706 pfile_in_zip_read_info->stream.avail_out = (uInt)len; | |
1707 | |
1708 if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && | |
1709 (!(pfile_in_zip_read_info->raw))) | |
1710 pfile_in_zip_read_info->stream.avail_out = | |
1711 (uInt)pfile_in_zip_read_info->rest_read_uncompressed; | |
1712 | |
1713 if ((len>pfile_in_zip_read_info->rest_read_compressed+ | |
1714 pfile_in_zip_read_info->stream.avail_in) && | |
1715 (pfile_in_zip_read_info->raw)) | |
1716 pfile_in_zip_read_info->stream.avail_out = | |
1717 (uInt)pfile_in_zip_read_info->rest_read_compressed+ | |
1718 pfile_in_zip_read_info->stream.avail_in; | |
1719 | |
1720 while (pfile_in_zip_read_info->stream.avail_out>0) | |
1721 { | |
1722 if ((pfile_in_zip_read_info->stream.avail_in==0) && | |
1723 (pfile_in_zip_read_info->rest_read_compressed>0)) | |
1724 { | |
1725 uInt uReadThis = UNZ_BUFSIZE; | |
1726 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis) | |
1727 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed; | |
1728 if (uReadThis == 0) | |
1729 return UNZ_EOF; | |
1730 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, | |
1731 pfile_in_zip_read_info->filestream, | |
1732 pfile_in_zip_read_info->pos_in_zipfile + | |
1733 pfile_in_zip_read_info->byte_before_the_zipfile, | |
1734 ZLIB_FILEFUNC_SEEK_SET)!=0) | |
1735 return UNZ_ERRNO; | |
1736 if (ZREAD64(pfile_in_zip_read_info->z_filefunc, | |
1737 pfile_in_zip_read_info->filestream, | |
1738 pfile_in_zip_read_info->read_buffer, | |
1739 uReadThis)!=uReadThis) | |
1740 return UNZ_ERRNO; | |
1741 | |
1742 | |
1743 # ifndef NOUNCRYPT | |
1744 if(s->encrypted) | |
1745 { | |
1746 uInt i; | |
1747 for(i=0;i<uReadThis;i++) | |
1748 pfile_in_zip_read_info->read_buffer[i] = | |
1749 zdecode(s->keys,s->pcrc_32_tab, | |
1750 pfile_in_zip_read_info->read_buffer[i]); | |
1751 } | |
1752 # endif | |
1753 | |
1754 | |
1755 pfile_in_zip_read_info->pos_in_zipfile += uReadThis; | |
1756 | |
1757 pfile_in_zip_read_info->rest_read_compressed-=uReadThis; | |
1758 | |
1759 pfile_in_zip_read_info->stream.next_in = | |
1760 (Bytef*)pfile_in_zip_read_info->read_buffer; | |
1761 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; | |
1762 } | |
1763 | |
1764 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) | |
1765 { | |
1766 uInt uDoCopy,i ; | |
1767 | |
1768 if ((pfile_in_zip_read_info->stream.avail_in == 0) && | |
1769 (pfile_in_zip_read_info->rest_read_compressed == 0)) | |
1770 return (iRead==0) ? UNZ_EOF : iRead; | |
1771 | |
1772 if (pfile_in_zip_read_info->stream.avail_out < | |
1773 pfile_in_zip_read_info->stream.avail_in) | |
1774 uDoCopy = pfile_in_zip_read_info->stream.avail_out ; | |
1775 else | |
1776 uDoCopy = pfile_in_zip_read_info->stream.avail_in ; | |
1777 | |
1778 for (i=0;i<uDoCopy;i++) | |
1779 *(pfile_in_zip_read_info->stream.next_out+i) = | |
1780 *(pfile_in_zip_read_info->stream.next_in+i); | |
1781 | |
1782 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; | |
1783 | |
1784 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, | |
1785 pfile_in_zip_read_info->stream.next_out, | |
1786 uDoCopy); | |
1787 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; | |
1788 pfile_in_zip_read_info->stream.avail_in -= uDoCopy; | |
1789 pfile_in_zip_read_info->stream.avail_out -= uDoCopy; | |
1790 pfile_in_zip_read_info->stream.next_out += uDoCopy; | |
1791 pfile_in_zip_read_info->stream.next_in += uDoCopy; | |
1792 pfile_in_zip_read_info->stream.total_out += uDoCopy; | |
1793 iRead += uDoCopy; | |
1794 } | |
1795 else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) | |
1796 { | |
1797 #ifdef HAVE_BZIP2 | |
1798 uLong uTotalOutBefore,uTotalOutAfter; | |
1799 const Bytef *bufBefore; | |
1800 uLong uOutThis; | |
1801 | |
1802 pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; | |
1803 pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; | |
1804 pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; | |
1805 pfile_in_zip_read_info->bstream.total_in_hi32 = 0; | |
1806 pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; | |
1807 pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; | |
1808 pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; | |
1809 pfile_in_zip_read_info->bstream.total_out_hi32 = 0; | |
1810 | |
1811 uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; | |
1812 bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; | |
1813 | |
1814 err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); | |
1815 | |
1816 uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; | |
1817 uOutThis = uTotalOutAfter-uTotalOutBefore; | |
1818 | |
1819 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; | |
1820 | |
1821 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); | |
1822 pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; | |
1823 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); | |
1824 | |
1825 pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; | |
1826 pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; | |
1827 pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; | |
1828 pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; | |
1829 pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; | |
1830 pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; | |
1831 | |
1832 if (err==BZ_STREAM_END) | |
1833 return (iRead==0) ? UNZ_EOF : iRead; | |
1834 if (err!=BZ_OK) | |
1835 break; | |
1836 #endif | |
1837 } // end Z_BZIP2ED | |
1838 else | |
1839 { | |
1840 ZPOS64_T uTotalOutBefore,uTotalOutAfter; | |
1841 const Bytef *bufBefore; | |
1842 ZPOS64_T uOutThis; | |
1843 int flush=Z_SYNC_FLUSH; | |
1844 | |
1845 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; | |
1846 bufBefore = pfile_in_zip_read_info->stream.next_out; | |
1847 | |
1848 /* | |
1849 if ((pfile_in_zip_read_info->rest_read_uncompressed == | |
1850 pfile_in_zip_read_info->stream.avail_out) && | |
1851 (pfile_in_zip_read_info->rest_read_compressed == 0)) | |
1852 flush = Z_FINISH; | |
1853 */ | |
1854 err=inflate(&pfile_in_zip_read_info->stream,flush); | |
1855 | |
1856 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) | |
1857 err = Z_DATA_ERROR; | |
1858 | |
1859 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; | |
1860 uOutThis = uTotalOutAfter-uTotalOutBefore; | |
1861 | |
1862 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; | |
1863 | |
1864 pfile_in_zip_read_info->crc32 = | |
1865 crc32(pfile_in_zip_read_info->crc32,bufBefore, | |
1866 (uInt)(uOutThis)); | |
1867 | |
1868 pfile_in_zip_read_info->rest_read_uncompressed -= | |
1869 uOutThis; | |
1870 | |
1871 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); | |
1872 | |
1873 if (err==Z_STREAM_END) | |
1874 return (iRead==0) ? UNZ_EOF : iRead; | |
1875 if (err!=Z_OK) | |
1876 break; | |
1877 } | |
1878 } | |
1879 | |
1880 if (err==Z_OK) | |
1881 return iRead; | |
1882 return err; | |
1883 } | |
1884 | |
1885 | |
1886 /* | |
1887 Give the current position in uncompressed data | |
1888 */ | |
1889 extern z_off_t ZEXPORT unztell (unzFile file) | |
1890 { | |
1891 unz64_s* s; | |
1892 file_in_zip64_read_info_s* pfile_in_zip_read_info; | |
1893 if (file==NULL) | |
1894 return UNZ_PARAMERROR; | |
1895 s=(unz64_s*)file; | |
1896 pfile_in_zip_read_info=s->pfile_in_zip_read; | |
1897 | |
1898 if (pfile_in_zip_read_info==NULL) | |
1899 return UNZ_PARAMERROR; | |
1900 | |
1901 return (z_off_t)pfile_in_zip_read_info->stream.total_out; | |
1902 } | |
1903 | |
1904 extern ZPOS64_T ZEXPORT unztell64 (unzFile file) | |
1905 { | |
1906 | |
1907 unz64_s* s; | |
1908 file_in_zip64_read_info_s* pfile_in_zip_read_info; | |
1909 if (file==NULL) | |
1910 return (ZPOS64_T)-1; | |
1911 s=(unz64_s*)file; | |
1912 pfile_in_zip_read_info=s->pfile_in_zip_read; | |
1913 | |
1914 if (pfile_in_zip_read_info==NULL) | |
1915 return (ZPOS64_T)-1; | |
1916 | |
1917 return pfile_in_zip_read_info->total_out_64; | |
1918 } | |
1919 | |
1920 | |
1921 /* | |
1922 return 1 if the end of file was reached, 0 elsewhere | |
1923 */ | |
1924 extern int ZEXPORT unzeof (unzFile file) | |
1925 { | |
1926 unz64_s* s; | |
1927 file_in_zip64_read_info_s* pfile_in_zip_read_info; | |
1928 if (file==NULL) | |
1929 return UNZ_PARAMERROR; | |
1930 s=(unz64_s*)file; | |
1931 pfile_in_zip_read_info=s->pfile_in_zip_read; | |
1932 | |
1933 if (pfile_in_zip_read_info==NULL) | |
1934 return UNZ_PARAMERROR; | |
1935 | |
1936 if (pfile_in_zip_read_info->rest_read_uncompressed == 0) | |
1937 return 1; | |
1938 else | |
1939 return 0; | |
1940 } | |
1941 | |
1942 | |
1943 | |
1944 /* | |
1945 Read extra field from the current file (opened by unzOpenCurrentFile) | |
1946 This is the local-header version of the extra field (sometimes, there is | |
1947 more info in the local-header version than in the central-header) | |
1948 | |
1949 if buf==NULL, it return the size of the local extra field that can be read | |
1950 | |
1951 if buf!=NULL, len is the size of the buffer, the extra header is copied in | |
1952 buf. | |
1953 the return value is the number of bytes copied in buf, or (if <0) | |
1954 the error code | |
1955 */ | |
1956 extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) | |
1957 { | |
1958 unz64_s* s; | |
1959 file_in_zip64_read_info_s* pfile_in_zip_read_info; | |
1960 uInt read_now; | |
1961 ZPOS64_T size_to_read; | |
1962 | |
1963 if (file==NULL) | |
1964 return UNZ_PARAMERROR; | |
1965 s=(unz64_s*)file; | |
1966 pfile_in_zip_read_info=s->pfile_in_zip_read; | |
1967 | |
1968 if (pfile_in_zip_read_info==NULL) | |
1969 return UNZ_PARAMERROR; | |
1970 | |
1971 size_to_read = (pfile_in_zip_read_info->size_local_extrafield - | |
1972 pfile_in_zip_read_info->pos_local_extrafield); | |
1973 | |
1974 if (buf==NULL) | |
1975 return (int)size_to_read; | |
1976 | |
1977 if (len>size_to_read) | |
1978 read_now = (uInt)size_to_read; | |
1979 else | |
1980 read_now = (uInt)len ; | |
1981 | |
1982 if (read_now==0) | |
1983 return 0; | |
1984 | |
1985 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, | |
1986 pfile_in_zip_read_info->filestream, | |
1987 pfile_in_zip_read_info->offset_local_extrafield + | |
1988 pfile_in_zip_read_info->pos_local_extrafield, | |
1989 ZLIB_FILEFUNC_SEEK_SET)!=0) | |
1990 return UNZ_ERRNO; | |
1991 | |
1992 if (ZREAD64(pfile_in_zip_read_info->z_filefunc, | |
1993 pfile_in_zip_read_info->filestream, | |
1994 buf,read_now)!=read_now) | |
1995 return UNZ_ERRNO; | |
1996 | |
1997 return (int)read_now; | |
1998 } | |
1999 | |
2000 /* | |
2001 Close the file in zip opened with unzipOpenCurrentFile | |
2002 Return UNZ_CRCERROR if all the file was read but the CRC is not good | |
2003 */ | |
2004 extern int ZEXPORT unzCloseCurrentFile (unzFile file) | |
2005 { | |
2006 int err=UNZ_OK; | |
2007 | |
2008 unz64_s* s; | |
2009 file_in_zip64_read_info_s* pfile_in_zip_read_info; | |
2010 if (file==NULL) | |
2011 return UNZ_PARAMERROR; | |
2012 s=(unz64_s*)file; | |
2013 pfile_in_zip_read_info=s->pfile_in_zip_read; | |
2014 | |
2015 if (pfile_in_zip_read_info==NULL) | |
2016 return UNZ_PARAMERROR; | |
2017 | |
2018 | |
2019 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && | |
2020 (!pfile_in_zip_read_info->raw)) | |
2021 { | |
2022 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) | |
2023 err=UNZ_CRCERROR; | |
2024 } | |
2025 | |
2026 | |
2027 TRYFREE(pfile_in_zip_read_info->read_buffer); | |
2028 pfile_in_zip_read_info->read_buffer = NULL; | |
2029 if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) | |
2030 inflateEnd(&pfile_in_zip_read_info->stream); | |
2031 #ifdef HAVE_BZIP2 | |
2032 else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) | |
2033 BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); | |
2034 #endif | |
2035 | |
2036 | |
2037 pfile_in_zip_read_info->stream_initialised = 0; | |
2038 TRYFREE(pfile_in_zip_read_info); | |
2039 | |
2040 s->pfile_in_zip_read=NULL; | |
2041 | |
2042 return err; | |
2043 } | |
2044 | |
2045 | |
2046 /* | |
2047 Get the global comment string of the ZipFile, in the szComment buffer. | |
2048 uSizeBuf is the size of the szComment buffer. | |
2049 return the number of byte copied or an error code <0 | |
2050 */ | |
2051 extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) | |
2052 { | |
2053 unz64_s* s; | |
2054 uLong uReadThis ; | |
2055 if (file==NULL) | |
2056 return (int)UNZ_PARAMERROR; | |
2057 s=(unz64_s*)file; | |
2058 | |
2059 uReadThis = uSizeBuf; | |
2060 if (uReadThis>s->gi.size_comment) | |
2061 uReadThis = s->gi.size_comment; | |
2062 | |
2063 if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) | |
2064 return UNZ_ERRNO; | |
2065 | |
2066 if (uReadThis>0) | |
2067 { | |
2068 *szComment='\0'; | |
2069 if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) | |
2070 return UNZ_ERRNO; | |
2071 } | |
2072 | |
2073 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) | |
2074 *(szComment+s->gi.size_comment)='\0'; | |
2075 return (int)uReadThis; | |
2076 } | |
2077 | |
2078 /* Additions by RX '2004 */ | |
2079 extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) | |
2080 { | |
2081 unz64_s* s; | |
2082 | |
2083 if (file==NULL) | |
2084 return 0; //UNZ_PARAMERROR; | |
2085 s=(unz64_s*)file; | |
2086 if (!s->current_file_ok) | |
2087 return 0; | |
2088 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) | |
2089 if (s->num_file==s->gi.number_entry) | |
2090 return 0; | |
2091 return s->pos_in_central_dir; | |
2092 } | |
2093 | |
2094 extern uLong ZEXPORT unzGetOffset (unzFile file) | |
2095 { | |
2096 ZPOS64_T offset64; | |
2097 | |
2098 if (file==NULL) | |
2099 return 0; //UNZ_PARAMERROR; | |
2100 offset64 = unzGetOffset64(file); | |
2101 return (uLong)offset64; | |
2102 } | |
2103 | |
2104 extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) | |
2105 { | |
2106 unz64_s* s; | |
2107 int err; | |
2108 | |
2109 if (file==NULL) | |
2110 return UNZ_PARAMERROR; | |
2111 s=(unz64_s*)file; | |
2112 | |
2113 s->pos_in_central_dir = pos; | |
2114 s->num_file = s->gi.number_entry; /* hack */ | |
2115 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, | |
2116 &s->cur_file_info_internal, | |
2117 NULL,0,NULL,0,NULL,0); | |
2118 s->current_file_ok = (err == UNZ_OK); | |
2119 return err; | |
2120 } | |
2121 | |
2122 extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) | |
2123 { | |
2124 return unzSetOffset64(file,pos); | |
2125 } |