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