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