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