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