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