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