unzip.c revision 1.1 1 1.1 christos /* $NetBSD: unzip.c,v 1.1 2006/01/14 20:10:59 christos Exp $ */
2 1.1 christos
3 1.1 christos /* unzip.c -- IO for uncompress .zip files using zlib
4 1.1 christos Version 1.01e, February 12th, 2005
5 1.1 christos
6 1.1 christos Copyright (C) 1998-2005 Gilles Vollant
7 1.1 christos
8 1.1 christos Read unzip.h for more info
9 1.1 christos */
10 1.1 christos
11 1.1 christos /* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
12 1.1 christos compatibility with older software. The following is from the original crypt.c. Code
13 1.1 christos woven in by Terry Thorsen 1/2003.
14 1.1 christos */
15 1.1 christos /*
16 1.1 christos Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
17 1.1 christos
18 1.1 christos See the accompanying file LICENSE, version 2000-Apr-09 or later
19 1.1 christos (the contents of which are also included in zip.h) for terms of use.
20 1.1 christos If, for some reason, all these files are missing, the Info-ZIP license
21 1.1 christos also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
22 1.1 christos */
23 1.1 christos /*
24 1.1 christos crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
25 1.1 christos
26 1.1 christos The encryption/decryption parts of this source code (as opposed to the
27 1.1 christos non-echoing password parts) were originally written in Europe. The
28 1.1 christos whole source package can be freely distributed, including from the USA.
29 1.1 christos (Prior to January 2000, re-export from the US was a violation of US law.)
30 1.1 christos */
31 1.1 christos
32 1.1 christos /*
33 1.1 christos This encryption code is a direct transcription of the algorithm from
34 1.1 christos Roger Schlafly, described by Phil Katz in the file appnote.txt. This
35 1.1 christos file (appnote.txt) is distributed with the PKZIP program (even in the
36 1.1 christos version without encryption capabilities).
37 1.1 christos */
38 1.1 christos
39 1.1 christos
40 1.1 christos #include <stdio.h>
41 1.1 christos #include <stdlib.h>
42 1.1 christos #include <string.h>
43 1.1 christos #include "zlib.h"
44 1.1 christos #include "unzip.h"
45 1.1 christos
46 1.1 christos #ifdef STDC
47 1.1 christos # include <stddef.h>
48 1.1 christos # include <string.h>
49 1.1 christos # include <stdlib.h>
50 1.1 christos #endif
51 1.1 christos #ifdef NO_ERRNO_H
52 1.1 christos extern int errno;
53 1.1 christos #else
54 1.1 christos # include <errno.h>
55 1.1 christos #endif
56 1.1 christos
57 1.1 christos
58 1.1 christos #ifndef local
59 1.1 christos # define local static
60 1.1 christos #endif
61 1.1 christos /* compile with -Dlocal if your debugger can't find static symbols */
62 1.1 christos
63 1.1 christos
64 1.1 christos #ifndef CASESENSITIVITYDEFAULT_NO
65 1.1 christos # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
66 1.1 christos # define CASESENSITIVITYDEFAULT_NO
67 1.1 christos # endif
68 1.1 christos #endif
69 1.1 christos
70 1.1 christos
71 1.1 christos #ifndef UNZ_BUFSIZE
72 1.1 christos #define UNZ_BUFSIZE (16384)
73 1.1 christos #endif
74 1.1 christos
75 1.1 christos #ifndef UNZ_MAXFILENAMEINZIP
76 1.1 christos #define UNZ_MAXFILENAMEINZIP (256)
77 1.1 christos #endif
78 1.1 christos
79 1.1 christos #ifndef ALLOC
80 1.1 christos # define ALLOC(size) (malloc(size))
81 1.1 christos #endif
82 1.1 christos #ifndef TRYFREE
83 1.1 christos # define TRYFREE(p) {if (p) free(p);}
84 1.1 christos #endif
85 1.1 christos
86 1.1 christos #define SIZECENTRALDIRITEM (0x2e)
87 1.1 christos #define SIZEZIPLOCALHEADER (0x1e)
88 1.1 christos
89 1.1 christos
90 1.1 christos
91 1.1 christos
92 1.1 christos const char unz_copyright[] =
93 1.1 christos " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
94 1.1 christos
95 1.1 christos /* unz_file_info_interntal contain internal info about a file in zipfile*/
96 1.1 christos typedef struct unz_file_info_internal_s
97 1.1 christos {
98 1.1 christos uLong offset_curfile;/* relative offset of local header 4 bytes */
99 1.1 christos } unz_file_info_internal;
100 1.1 christos
101 1.1 christos
102 1.1 christos /* file_in_zip_read_info_s contain internal information about a file in zipfile,
103 1.1 christos when reading and decompress it */
104 1.1 christos typedef struct
105 1.1 christos {
106 1.1 christos char *read_buffer; /* internal buffer for compressed data */
107 1.1 christos z_stream stream; /* zLib stream structure for inflate */
108 1.1 christos
109 1.1 christos uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
110 1.1 christos uLong stream_initialised; /* flag set if stream structure is initialised*/
111 1.1 christos
112 1.1 christos uLong offset_local_extrafield;/* offset of the local extra field */
113 1.1 christos uInt size_local_extrafield;/* size of the local extra field */
114 1.1 christos uLong pos_local_extrafield; /* position in the local extra field in read*/
115 1.1 christos
116 1.1 christos uLong crc32; /* crc32 of all data uncompressed */
117 1.1 christos uLong crc32_wait; /* crc32 we must obtain after decompress all */
118 1.1 christos uLong rest_read_compressed; /* number of byte to be decompressed */
119 1.1 christos uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
120 1.1 christos zlib_filefunc_def z_filefunc;
121 1.1 christos voidpf filestream; /* io structore of the zipfile */
122 1.1 christos uLong compression_method; /* compression method (0==store) */
123 1.1 christos uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
124 1.1 christos int raw;
125 1.1 christos } file_in_zip_read_info_s;
126 1.1 christos
127 1.1 christos
128 1.1 christos /* unz_s contain internal information about the zipfile
129 1.1 christos */
130 1.1 christos typedef struct
131 1.1 christos {
132 1.1 christos zlib_filefunc_def z_filefunc;
133 1.1 christos voidpf filestream; /* io structore of the zipfile */
134 1.1 christos unz_global_info gi; /* public global information */
135 1.1 christos uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
136 1.1 christos uLong num_file; /* number of the current file in the zipfile*/
137 1.1 christos uLong pos_in_central_dir; /* pos of the current file in the central dir*/
138 1.1 christos uLong current_file_ok; /* flag about the usability of the current file*/
139 1.1 christos uLong central_pos; /* position of the beginning of the central dir*/
140 1.1 christos
141 1.1 christos uLong size_central_dir; /* size of the central directory */
142 1.1 christos uLong offset_central_dir; /* offset of start of central directory with
143 1.1 christos respect to the starting disk number */
144 1.1 christos
145 1.1 christos unz_file_info cur_file_info; /* public info about the current file in zip*/
146 1.1 christos unz_file_info_internal cur_file_info_internal; /* private info about it*/
147 1.1 christos file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
148 1.1 christos file if we are decompressing it */
149 1.1 christos int encrypted;
150 1.1 christos # ifndef NOUNCRYPT
151 1.1 christos unsigned long keys[3]; /* keys defining the pseudo-random sequence */
152 1.1 christos const unsigned long* pcrc_32_tab;
153 1.1 christos # endif
154 1.1 christos } unz_s;
155 1.1 christos
156 1.1 christos
157 1.1 christos #ifndef NOUNCRYPT
158 1.1 christos #include "crypt.h"
159 1.1 christos #endif
160 1.1 christos
161 1.1 christos /* ===========================================================================
162 1.1 christos Read a byte from a gz_stream; update next_in and avail_in. Return EOF
163 1.1 christos for end of file.
164 1.1 christos IN assertion: the stream s has been sucessfully opened for reading.
165 1.1 christos */
166 1.1 christos
167 1.1 christos
168 1.1 christos local int unzlocal_getByte OF((
169 1.1 christos const zlib_filefunc_def* pzlib_filefunc_def,
170 1.1 christos voidpf filestream,
171 1.1 christos int *pi));
172 1.1 christos
173 1.1 christos local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
174 1.1 christos const zlib_filefunc_def* pzlib_filefunc_def;
175 1.1 christos voidpf filestream;
176 1.1 christos int *pi;
177 1.1 christos {
178 1.1 christos unsigned char c;
179 1.1 christos int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
180 1.1 christos if (err==1)
181 1.1 christos {
182 1.1 christos *pi = (int)c;
183 1.1 christos return UNZ_OK;
184 1.1 christos }
185 1.1 christos else
186 1.1 christos {
187 1.1 christos if (ZERROR(*pzlib_filefunc_def,filestream))
188 1.1 christos return UNZ_ERRNO;
189 1.1 christos else
190 1.1 christos return UNZ_EOF;
191 1.1 christos }
192 1.1 christos }
193 1.1 christos
194 1.1 christos
195 1.1 christos /* ===========================================================================
196 1.1 christos Reads a long in LSB order from the given gz_stream. Sets
197 1.1 christos */
198 1.1 christos local int unzlocal_getShort OF((
199 1.1 christos const zlib_filefunc_def* pzlib_filefunc_def,
200 1.1 christos voidpf filestream,
201 1.1 christos uLong *pX));
202 1.1 christos
203 1.1 christos local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
204 1.1 christos const zlib_filefunc_def* pzlib_filefunc_def;
205 1.1 christos voidpf filestream;
206 1.1 christos uLong *pX;
207 1.1 christos {
208 1.1 christos uLong x ;
209 1.1 christos int i;
210 1.1 christos int err;
211 1.1 christos
212 1.1 christos err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
213 1.1 christos x = (uLong)i;
214 1.1 christos
215 1.1 christos if (err==UNZ_OK)
216 1.1 christos err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
217 1.1 christos x += ((uLong)i)<<8;
218 1.1 christos
219 1.1 christos if (err==UNZ_OK)
220 1.1 christos *pX = x;
221 1.1 christos else
222 1.1 christos *pX = 0;
223 1.1 christos return err;
224 1.1 christos }
225 1.1 christos
226 1.1 christos local int unzlocal_getLong OF((
227 1.1 christos const zlib_filefunc_def* pzlib_filefunc_def,
228 1.1 christos voidpf filestream,
229 1.1 christos uLong *pX));
230 1.1 christos
231 1.1 christos local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
232 1.1 christos const zlib_filefunc_def* pzlib_filefunc_def;
233 1.1 christos voidpf filestream;
234 1.1 christos uLong *pX;
235 1.1 christos {
236 1.1 christos uLong x ;
237 1.1 christos int i;
238 1.1 christos int err;
239 1.1 christos
240 1.1 christos err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
241 1.1 christos x = (uLong)i;
242 1.1 christos
243 1.1 christos if (err==UNZ_OK)
244 1.1 christos err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
245 1.1 christos x += ((uLong)i)<<8;
246 1.1 christos
247 1.1 christos if (err==UNZ_OK)
248 1.1 christos err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
249 1.1 christos x += ((uLong)i)<<16;
250 1.1 christos
251 1.1 christos if (err==UNZ_OK)
252 1.1 christos err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
253 1.1 christos x += ((uLong)i)<<24;
254 1.1 christos
255 1.1 christos if (err==UNZ_OK)
256 1.1 christos *pX = x;
257 1.1 christos else
258 1.1 christos *pX = 0;
259 1.1 christos return err;
260 1.1 christos }
261 1.1 christos
262 1.1 christos
263 1.1 christos /* My own strcmpi / strcasecmp */
264 1.1 christos local int strcmpcasenosensitive_internal (fileName1,fileName2)
265 1.1 christos const char* fileName1;
266 1.1 christos const char* fileName2;
267 1.1 christos {
268 1.1 christos for (;;)
269 1.1 christos {
270 1.1 christos char c1=*(fileName1++);
271 1.1 christos char c2=*(fileName2++);
272 1.1 christos if ((c1>='a') && (c1<='z'))
273 1.1 christos c1 -= 0x20;
274 1.1 christos if ((c2>='a') && (c2<='z'))
275 1.1 christos c2 -= 0x20;
276 1.1 christos if (c1=='\0')
277 1.1 christos return ((c2=='\0') ? 0 : -1);
278 1.1 christos if (c2=='\0')
279 1.1 christos return 1;
280 1.1 christos if (c1<c2)
281 1.1 christos return -1;
282 1.1 christos if (c1>c2)
283 1.1 christos return 1;
284 1.1 christos }
285 1.1 christos }
286 1.1 christos
287 1.1 christos
288 1.1 christos #ifdef CASESENSITIVITYDEFAULT_NO
289 1.1 christos #define CASESENSITIVITYDEFAULTVALUE 2
290 1.1 christos #else
291 1.1 christos #define CASESENSITIVITYDEFAULTVALUE 1
292 1.1 christos #endif
293 1.1 christos
294 1.1 christos #ifndef STRCMPCASENOSENTIVEFUNCTION
295 1.1 christos #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
296 1.1 christos #endif
297 1.1 christos
298 1.1 christos /*
299 1.1 christos Compare two filename (fileName1,fileName2).
300 1.1 christos If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
301 1.1 christos If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
302 1.1 christos or strcasecmp)
303 1.1 christos If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
304 1.1 christos (like 1 on Unix, 2 on Windows)
305 1.1 christos
306 1.1 christos */
307 1.1 christos extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
308 1.1 christos const char* fileName1;
309 1.1 christos const char* fileName2;
310 1.1 christos int iCaseSensitivity;
311 1.1 christos {
312 1.1 christos if (iCaseSensitivity==0)
313 1.1 christos iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
314 1.1 christos
315 1.1 christos if (iCaseSensitivity==1)
316 1.1 christos return strcmp(fileName1,fileName2);
317 1.1 christos
318 1.1 christos return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
319 1.1 christos }
320 1.1 christos
321 1.1 christos #ifndef BUFREADCOMMENT
322 1.1 christos #define BUFREADCOMMENT (0x400)
323 1.1 christos #endif
324 1.1 christos
325 1.1 christos /*
326 1.1 christos Locate the Central directory of a zipfile (at the end, just before
327 1.1 christos the global comment)
328 1.1 christos */
329 1.1 christos local uLong unzlocal_SearchCentralDir OF((
330 1.1 christos const zlib_filefunc_def* pzlib_filefunc_def,
331 1.1 christos voidpf filestream));
332 1.1 christos
333 1.1 christos local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
334 1.1 christos const zlib_filefunc_def* pzlib_filefunc_def;
335 1.1 christos voidpf filestream;
336 1.1 christos {
337 1.1 christos unsigned char* buf;
338 1.1 christos uLong uSizeFile;
339 1.1 christos uLong uBackRead;
340 1.1 christos uLong uMaxBack=0xffff; /* maximum size of global comment */
341 1.1 christos uLong uPosFound=0;
342 1.1 christos
343 1.1 christos if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
344 1.1 christos return 0;
345 1.1 christos
346 1.1 christos
347 1.1 christos uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
348 1.1 christos
349 1.1 christos if (uMaxBack>uSizeFile)
350 1.1 christos uMaxBack = uSizeFile;
351 1.1 christos
352 1.1 christos buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
353 1.1 christos if (buf==NULL)
354 1.1 christos return 0;
355 1.1 christos
356 1.1 christos uBackRead = 4;
357 1.1 christos while (uBackRead<uMaxBack)
358 1.1 christos {
359 1.1 christos uLong uReadSize,uReadPos ;
360 1.1 christos int i;
361 1.1 christos if (uBackRead+BUFREADCOMMENT>uMaxBack)
362 1.1 christos uBackRead = uMaxBack;
363 1.1 christos else
364 1.1 christos uBackRead+=BUFREADCOMMENT;
365 1.1 christos uReadPos = uSizeFile-uBackRead ;
366 1.1 christos
367 1.1 christos uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
368 1.1 christos (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
369 1.1 christos if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
370 1.1 christos break;
371 1.1 christos
372 1.1 christos if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
373 1.1 christos break;
374 1.1 christos
375 1.1 christos for (i=(int)uReadSize-3; (i--)>0;)
376 1.1 christos if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
377 1.1 christos ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
378 1.1 christos {
379 1.1 christos uPosFound = uReadPos+i;
380 1.1 christos break;
381 1.1 christos }
382 1.1 christos
383 1.1 christos if (uPosFound!=0)
384 1.1 christos break;
385 1.1 christos }
386 1.1 christos TRYFREE(buf);
387 1.1 christos return uPosFound;
388 1.1 christos }
389 1.1 christos
390 1.1 christos /*
391 1.1 christos Open a Zip file. path contain the full pathname (by example,
392 1.1 christos on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
393 1.1 christos "zlib/zlib114.zip".
394 1.1 christos If the zipfile cannot be opened (file doesn't exist or in not valid), the
395 1.1 christos return value is NULL.
396 1.1 christos Else, the return value is a unzFile Handle, usable with other function
397 1.1 christos of this unzip package.
398 1.1 christos */
399 1.1 christos extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
400 1.1 christos const char *path;
401 1.1 christos zlib_filefunc_def* pzlib_filefunc_def;
402 1.1 christos {
403 1.1 christos unz_s us;
404 1.1 christos unz_s *s;
405 1.1 christos uLong central_pos,uL;
406 1.1 christos
407 1.1 christos uLong number_disk; /* number of the current dist, used for
408 1.1 christos spaning ZIP, unsupported, always 0*/
409 1.1 christos uLong number_disk_with_CD; /* number the the disk with central dir, used
410 1.1 christos for spaning ZIP, unsupported, always 0*/
411 1.1 christos uLong number_entry_CD; /* total number of entries in
412 1.1 christos the central dir
413 1.1 christos (same than number_entry on nospan) */
414 1.1 christos
415 1.1 christos int err=UNZ_OK;
416 1.1 christos
417 1.1 christos if (unz_copyright[0]!=' ')
418 1.1 christos return NULL;
419 1.1 christos
420 1.1 christos if (pzlib_filefunc_def==NULL)
421 1.1 christos fill_fopen_filefunc(&us.z_filefunc);
422 1.1 christos else
423 1.1 christos us.z_filefunc = *pzlib_filefunc_def;
424 1.1 christos
425 1.1 christos us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
426 1.1 christos path,
427 1.1 christos ZLIB_FILEFUNC_MODE_READ |
428 1.1 christos ZLIB_FILEFUNC_MODE_EXISTING);
429 1.1 christos if (us.filestream==NULL)
430 1.1 christos return NULL;
431 1.1 christos
432 1.1 christos central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
433 1.1 christos if (central_pos==0)
434 1.1 christos err=UNZ_ERRNO;
435 1.1 christos
436 1.1 christos if (ZSEEK(us.z_filefunc, us.filestream,
437 1.1 christos central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
438 1.1 christos err=UNZ_ERRNO;
439 1.1 christos
440 1.1 christos /* the signature, already checked */
441 1.1 christos if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
442 1.1 christos err=UNZ_ERRNO;
443 1.1 christos
444 1.1 christos /* number of this disk */
445 1.1 christos if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
446 1.1 christos err=UNZ_ERRNO;
447 1.1 christos
448 1.1 christos /* number of the disk with the start of the central directory */
449 1.1 christos if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
450 1.1 christos err=UNZ_ERRNO;
451 1.1 christos
452 1.1 christos /* total number of entries in the central dir on this disk */
453 1.1 christos if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
454 1.1 christos err=UNZ_ERRNO;
455 1.1 christos
456 1.1 christos /* total number of entries in the central dir */
457 1.1 christos if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
458 1.1 christos err=UNZ_ERRNO;
459 1.1 christos
460 1.1 christos if ((number_entry_CD!=us.gi.number_entry) ||
461 1.1 christos (number_disk_with_CD!=0) ||
462 1.1 christos (number_disk!=0))
463 1.1 christos err=UNZ_BADZIPFILE;
464 1.1 christos
465 1.1 christos /* size of the central directory */
466 1.1 christos if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
467 1.1 christos err=UNZ_ERRNO;
468 1.1 christos
469 1.1 christos /* offset of start of central directory with respect to the
470 1.1 christos starting disk number */
471 1.1 christos if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
472 1.1 christos err=UNZ_ERRNO;
473 1.1 christos
474 1.1 christos /* zipfile comment length */
475 1.1 christos if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
476 1.1 christos err=UNZ_ERRNO;
477 1.1 christos
478 1.1 christos if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
479 1.1 christos (err==UNZ_OK))
480 1.1 christos err=UNZ_BADZIPFILE;
481 1.1 christos
482 1.1 christos if (err!=UNZ_OK)
483 1.1 christos {
484 1.1 christos ZCLOSE(us.z_filefunc, us.filestream);
485 1.1 christos return NULL;
486 1.1 christos }
487 1.1 christos
488 1.1 christos us.byte_before_the_zipfile = central_pos -
489 1.1 christos (us.offset_central_dir+us.size_central_dir);
490 1.1 christos us.central_pos = central_pos;
491 1.1 christos us.pfile_in_zip_read = NULL;
492 1.1 christos us.encrypted = 0;
493 1.1 christos
494 1.1 christos
495 1.1 christos s=(unz_s*)ALLOC(sizeof(unz_s));
496 1.1 christos *s=us;
497 1.1 christos unzGoToFirstFile((unzFile)s);
498 1.1 christos return (unzFile)s;
499 1.1 christos }
500 1.1 christos
501 1.1 christos
502 1.1 christos extern unzFile ZEXPORT unzOpen (path)
503 1.1 christos const char *path;
504 1.1 christos {
505 1.1 christos return unzOpen2(path, NULL);
506 1.1 christos }
507 1.1 christos
508 1.1 christos /*
509 1.1 christos Close a ZipFile opened with unzipOpen.
510 1.1 christos If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
511 1.1 christos these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
512 1.1 christos return UNZ_OK if there is no problem. */
513 1.1 christos extern int ZEXPORT unzClose (file)
514 1.1 christos unzFile file;
515 1.1 christos {
516 1.1 christos unz_s* s;
517 1.1 christos if (file==NULL)
518 1.1 christos return UNZ_PARAMERROR;
519 1.1 christos s=(unz_s*)file;
520 1.1 christos
521 1.1 christos if (s->pfile_in_zip_read!=NULL)
522 1.1 christos unzCloseCurrentFile(file);
523 1.1 christos
524 1.1 christos ZCLOSE(s->z_filefunc, s->filestream);
525 1.1 christos TRYFREE(s);
526 1.1 christos return UNZ_OK;
527 1.1 christos }
528 1.1 christos
529 1.1 christos
530 1.1 christos /*
531 1.1 christos Write info about the ZipFile in the *pglobal_info structure.
532 1.1 christos No preparation of the structure is needed
533 1.1 christos return UNZ_OK if there is no problem. */
534 1.1 christos extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
535 1.1 christos unzFile file;
536 1.1 christos unz_global_info *pglobal_info;
537 1.1 christos {
538 1.1 christos unz_s* s;
539 1.1 christos if (file==NULL)
540 1.1 christos return UNZ_PARAMERROR;
541 1.1 christos s=(unz_s*)file;
542 1.1 christos *pglobal_info=s->gi;
543 1.1 christos return UNZ_OK;
544 1.1 christos }
545 1.1 christos
546 1.1 christos
547 1.1 christos /*
548 1.1 christos Translate date/time from Dos format to tm_unz (readable more easilty)
549 1.1 christos */
550 1.1 christos local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
551 1.1 christos uLong ulDosDate;
552 1.1 christos tm_unz* ptm;
553 1.1 christos {
554 1.1 christos uLong uDate;
555 1.1 christos uDate = (uLong)(ulDosDate>>16);
556 1.1 christos ptm->tm_mday = (uInt)(uDate&0x1f) ;
557 1.1 christos ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
558 1.1 christos ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
559 1.1 christos
560 1.1 christos ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
561 1.1 christos ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
562 1.1 christos ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
563 1.1 christos }
564 1.1 christos
565 1.1 christos /*
566 1.1 christos Get Info about the current file in the zipfile, with internal only info
567 1.1 christos */
568 1.1 christos local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
569 1.1 christos unz_file_info *pfile_info,
570 1.1 christos unz_file_info_internal
571 1.1 christos *pfile_info_internal,
572 1.1 christos char *szFileName,
573 1.1 christos uLong fileNameBufferSize,
574 1.1 christos void *extraField,
575 1.1 christos uLong extraFieldBufferSize,
576 1.1 christos char *szComment,
577 1.1 christos uLong commentBufferSize));
578 1.1 christos
579 1.1 christos local int unzlocal_GetCurrentFileInfoInternal (file,
580 1.1 christos pfile_info,
581 1.1 christos pfile_info_internal,
582 1.1 christos szFileName, fileNameBufferSize,
583 1.1 christos extraField, extraFieldBufferSize,
584 1.1 christos szComment, commentBufferSize)
585 1.1 christos unzFile file;
586 1.1 christos unz_file_info *pfile_info;
587 1.1 christos unz_file_info_internal *pfile_info_internal;
588 1.1 christos char *szFileName;
589 1.1 christos uLong fileNameBufferSize;
590 1.1 christos void *extraField;
591 1.1 christos uLong extraFieldBufferSize;
592 1.1 christos char *szComment;
593 1.1 christos uLong commentBufferSize;
594 1.1 christos {
595 1.1 christos unz_s* s;
596 1.1 christos unz_file_info file_info;
597 1.1 christos unz_file_info_internal file_info_internal;
598 1.1 christos int err=UNZ_OK;
599 1.1 christos uLong uMagic;
600 1.1 christos long lSeek=0;
601 1.1 christos
602 1.1 christos if (file==NULL)
603 1.1 christos return UNZ_PARAMERROR;
604 1.1 christos s=(unz_s*)file;
605 1.1 christos if (ZSEEK(s->z_filefunc, s->filestream,
606 1.1 christos s->pos_in_central_dir+s->byte_before_the_zipfile,
607 1.1 christos ZLIB_FILEFUNC_SEEK_SET)!=0)
608 1.1 christos err=UNZ_ERRNO;
609 1.1 christos
610 1.1 christos
611 1.1 christos /* we check the magic */
612 1.1 christos if (err==UNZ_OK)
613 1.1 christos if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
614 1.1 christos err=UNZ_ERRNO;
615 1.1 christos else if (uMagic!=0x02014b50)
616 1.1 christos err=UNZ_BADZIPFILE;
617 1.1 christos
618 1.1 christos if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
619 1.1 christos err=UNZ_ERRNO;
620 1.1 christos
621 1.1 christos if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
622 1.1 christos err=UNZ_ERRNO;
623 1.1 christos
624 1.1 christos if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
625 1.1 christos err=UNZ_ERRNO;
626 1.1 christos
627 1.1 christos if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
628 1.1 christos err=UNZ_ERRNO;
629 1.1 christos
630 1.1 christos if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
631 1.1 christos err=UNZ_ERRNO;
632 1.1 christos
633 1.1 christos unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
634 1.1 christos
635 1.1 christos if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
636 1.1 christos err=UNZ_ERRNO;
637 1.1 christos
638 1.1 christos if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
639 1.1 christos err=UNZ_ERRNO;
640 1.1 christos
641 1.1 christos if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
642 1.1 christos err=UNZ_ERRNO;
643 1.1 christos
644 1.1 christos if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
645 1.1 christos err=UNZ_ERRNO;
646 1.1 christos
647 1.1 christos if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
648 1.1 christos err=UNZ_ERRNO;
649 1.1 christos
650 1.1 christos if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
651 1.1 christos err=UNZ_ERRNO;
652 1.1 christos
653 1.1 christos if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
654 1.1 christos err=UNZ_ERRNO;
655 1.1 christos
656 1.1 christos if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
657 1.1 christos err=UNZ_ERRNO;
658 1.1 christos
659 1.1 christos if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
660 1.1 christos err=UNZ_ERRNO;
661 1.1 christos
662 1.1 christos if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
663 1.1 christos err=UNZ_ERRNO;
664 1.1 christos
665 1.1 christos lSeek+=file_info.size_filename;
666 1.1 christos if ((err==UNZ_OK) && (szFileName!=NULL))
667 1.1 christos {
668 1.1 christos uLong uSizeRead ;
669 1.1 christos if (file_info.size_filename<fileNameBufferSize)
670 1.1 christos {
671 1.1 christos *(szFileName+file_info.size_filename)='\0';
672 1.1 christos uSizeRead = file_info.size_filename;
673 1.1 christos }
674 1.1 christos else
675 1.1 christos uSizeRead = fileNameBufferSize;
676 1.1 christos
677 1.1 christos if ((file_info.size_filename>0) && (fileNameBufferSize>0))
678 1.1 christos if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
679 1.1 christos err=UNZ_ERRNO;
680 1.1 christos lSeek -= uSizeRead;
681 1.1 christos }
682 1.1 christos
683 1.1 christos
684 1.1 christos if ((err==UNZ_OK) && (extraField!=NULL))
685 1.1 christos {
686 1.1 christos uLong uSizeRead ;
687 1.1 christos if (file_info.size_file_extra<extraFieldBufferSize)
688 1.1 christos uSizeRead = file_info.size_file_extra;
689 1.1 christos else
690 1.1 christos uSizeRead = extraFieldBufferSize;
691 1.1 christos
692 1.1 christos if (lSeek!=0)
693 1.1 christos if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
694 1.1 christos lSeek=0;
695 1.1 christos else
696 1.1 christos err=UNZ_ERRNO;
697 1.1 christos if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
698 1.1 christos if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
699 1.1 christos err=UNZ_ERRNO;
700 1.1 christos lSeek += file_info.size_file_extra - uSizeRead;
701 1.1 christos }
702 1.1 christos else
703 1.1 christos lSeek+=file_info.size_file_extra;
704 1.1 christos
705 1.1 christos
706 1.1 christos if ((err==UNZ_OK) && (szComment!=NULL))
707 1.1 christos {
708 1.1 christos uLong uSizeRead ;
709 1.1 christos if (file_info.size_file_comment<commentBufferSize)
710 1.1 christos {
711 1.1 christos *(szComment+file_info.size_file_comment)='\0';
712 1.1 christos uSizeRead = file_info.size_file_comment;
713 1.1 christos }
714 1.1 christos else
715 1.1 christos uSizeRead = commentBufferSize;
716 1.1 christos
717 1.1 christos if (lSeek!=0)
718 1.1 christos if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
719 1.1 christos lSeek=0;
720 1.1 christos else
721 1.1 christos err=UNZ_ERRNO;
722 1.1 christos if ((file_info.size_file_comment>0) && (commentBufferSize>0))
723 1.1 christos if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
724 1.1 christos err=UNZ_ERRNO;
725 1.1 christos lSeek+=file_info.size_file_comment - uSizeRead;
726 1.1 christos }
727 1.1 christos else
728 1.1 christos lSeek+=file_info.size_file_comment;
729 1.1 christos
730 1.1 christos if ((err==UNZ_OK) && (pfile_info!=NULL))
731 1.1 christos *pfile_info=file_info;
732 1.1 christos
733 1.1 christos if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
734 1.1 christos *pfile_info_internal=file_info_internal;
735 1.1 christos
736 1.1 christos return err;
737 1.1 christos }
738 1.1 christos
739 1.1 christos
740 1.1 christos
741 1.1 christos /*
742 1.1 christos Write info about the ZipFile in the *pglobal_info structure.
743 1.1 christos No preparation of the structure is needed
744 1.1 christos return UNZ_OK if there is no problem.
745 1.1 christos */
746 1.1 christos extern int ZEXPORT unzGetCurrentFileInfo (file,
747 1.1 christos pfile_info,
748 1.1 christos szFileName, fileNameBufferSize,
749 1.1 christos extraField, extraFieldBufferSize,
750 1.1 christos szComment, commentBufferSize)
751 1.1 christos unzFile file;
752 1.1 christos unz_file_info *pfile_info;
753 1.1 christos char *szFileName;
754 1.1 christos uLong fileNameBufferSize;
755 1.1 christos void *extraField;
756 1.1 christos uLong extraFieldBufferSize;
757 1.1 christos char *szComment;
758 1.1 christos uLong commentBufferSize;
759 1.1 christos {
760 1.1 christos return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
761 1.1 christos szFileName,fileNameBufferSize,
762 1.1 christos extraField,extraFieldBufferSize,
763 1.1 christos szComment,commentBufferSize);
764 1.1 christos }
765 1.1 christos
766 1.1 christos /*
767 1.1 christos Set the current file of the zipfile to the first file.
768 1.1 christos return UNZ_OK if there is no problem
769 1.1 christos */
770 1.1 christos extern int ZEXPORT unzGoToFirstFile (file)
771 1.1 christos unzFile file;
772 1.1 christos {
773 1.1 christos int err=UNZ_OK;
774 1.1 christos unz_s* s;
775 1.1 christos if (file==NULL)
776 1.1 christos return UNZ_PARAMERROR;
777 1.1 christos s=(unz_s*)file;
778 1.1 christos s->pos_in_central_dir=s->offset_central_dir;
779 1.1 christos s->num_file=0;
780 1.1 christos err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
781 1.1 christos &s->cur_file_info_internal,
782 1.1 christos NULL,0,NULL,0,NULL,0);
783 1.1 christos s->current_file_ok = (err == UNZ_OK);
784 1.1 christos return err;
785 1.1 christos }
786 1.1 christos
787 1.1 christos /*
788 1.1 christos Set the current file of the zipfile to the next file.
789 1.1 christos return UNZ_OK if there is no problem
790 1.1 christos return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
791 1.1 christos */
792 1.1 christos extern int ZEXPORT unzGoToNextFile (file)
793 1.1 christos unzFile file;
794 1.1 christos {
795 1.1 christos unz_s* s;
796 1.1 christos int err;
797 1.1 christos
798 1.1 christos if (file==NULL)
799 1.1 christos return UNZ_PARAMERROR;
800 1.1 christos s=(unz_s*)file;
801 1.1 christos if (!s->current_file_ok)
802 1.1 christos return UNZ_END_OF_LIST_OF_FILE;
803 1.1 christos if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
804 1.1 christos if (s->num_file+1==s->gi.number_entry)
805 1.1 christos return UNZ_END_OF_LIST_OF_FILE;
806 1.1 christos
807 1.1 christos s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
808 1.1 christos s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
809 1.1 christos s->num_file++;
810 1.1 christos err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
811 1.1 christos &s->cur_file_info_internal,
812 1.1 christos NULL,0,NULL,0,NULL,0);
813 1.1 christos s->current_file_ok = (err == UNZ_OK);
814 1.1 christos return err;
815 1.1 christos }
816 1.1 christos
817 1.1 christos
818 1.1 christos /*
819 1.1 christos Try locate the file szFileName in the zipfile.
820 1.1 christos For the iCaseSensitivity signification, see unzipStringFileNameCompare
821 1.1 christos
822 1.1 christos return value :
823 1.1 christos UNZ_OK if the file is found. It becomes the current file.
824 1.1 christos UNZ_END_OF_LIST_OF_FILE if the file is not found
825 1.1 christos */
826 1.1 christos extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
827 1.1 christos unzFile file;
828 1.1 christos const char *szFileName;
829 1.1 christos int iCaseSensitivity;
830 1.1 christos {
831 1.1 christos unz_s* s;
832 1.1 christos int err;
833 1.1 christos
834 1.1 christos /* We remember the 'current' position in the file so that we can jump
835 1.1 christos * back there if we fail.
836 1.1 christos */
837 1.1 christos unz_file_info cur_file_infoSaved;
838 1.1 christos unz_file_info_internal cur_file_info_internalSaved;
839 1.1 christos uLong num_fileSaved;
840 1.1 christos uLong pos_in_central_dirSaved;
841 1.1 christos
842 1.1 christos
843 1.1 christos if (file==NULL)
844 1.1 christos return UNZ_PARAMERROR;
845 1.1 christos
846 1.1 christos if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
847 1.1 christos return UNZ_PARAMERROR;
848 1.1 christos
849 1.1 christos s=(unz_s*)file;
850 1.1 christos if (!s->current_file_ok)
851 1.1 christos return UNZ_END_OF_LIST_OF_FILE;
852 1.1 christos
853 1.1 christos /* Save the current state */
854 1.1 christos num_fileSaved = s->num_file;
855 1.1 christos pos_in_central_dirSaved = s->pos_in_central_dir;
856 1.1 christos cur_file_infoSaved = s->cur_file_info;
857 1.1 christos cur_file_info_internalSaved = s->cur_file_info_internal;
858 1.1 christos
859 1.1 christos err = unzGoToFirstFile(file);
860 1.1 christos
861 1.1 christos while (err == UNZ_OK)
862 1.1 christos {
863 1.1 christos char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
864 1.1 christos err = unzGetCurrentFileInfo(file,NULL,
865 1.1 christos szCurrentFileName,sizeof(szCurrentFileName)-1,
866 1.1 christos NULL,0,NULL,0);
867 1.1 christos if (err == UNZ_OK)
868 1.1 christos {
869 1.1 christos if (unzStringFileNameCompare(szCurrentFileName,
870 1.1 christos szFileName,iCaseSensitivity)==0)
871 1.1 christos return UNZ_OK;
872 1.1 christos err = unzGoToNextFile(file);
873 1.1 christos }
874 1.1 christos }
875 1.1 christos
876 1.1 christos /* We failed, so restore the state of the 'current file' to where we
877 1.1 christos * were.
878 1.1 christos */
879 1.1 christos s->num_file = num_fileSaved ;
880 1.1 christos s->pos_in_central_dir = pos_in_central_dirSaved ;
881 1.1 christos s->cur_file_info = cur_file_infoSaved;
882 1.1 christos s->cur_file_info_internal = cur_file_info_internalSaved;
883 1.1 christos return err;
884 1.1 christos }
885 1.1 christos
886 1.1 christos
887 1.1 christos /*
888 1.1 christos ///////////////////////////////////////////
889 1.1 christos // Contributed by Ryan Haksi (mailto://cryogen (at) infoserve.net)
890 1.1 christos // I need random access
891 1.1 christos //
892 1.1 christos // Further optimization could be realized by adding an ability
893 1.1 christos // to cache the directory in memory. The goal being a single
894 1.1 christos // comprehensive file read to put the file I need in a memory.
895 1.1 christos */
896 1.1 christos
897 1.1 christos /*
898 1.1 christos typedef struct unz_file_pos_s
899 1.1 christos {
900 1.1 christos uLong pos_in_zip_directory; // offset in file
901 1.1 christos uLong num_of_file; // # of file
902 1.1 christos } unz_file_pos;
903 1.1 christos */
904 1.1 christos
905 1.1 christos extern int ZEXPORT unzGetFilePos(file, file_pos)
906 1.1 christos unzFile file;
907 1.1 christos unz_file_pos* file_pos;
908 1.1 christos {
909 1.1 christos unz_s* s;
910 1.1 christos
911 1.1 christos if (file==NULL || file_pos==NULL)
912 1.1 christos return UNZ_PARAMERROR;
913 1.1 christos s=(unz_s*)file;
914 1.1 christos if (!s->current_file_ok)
915 1.1 christos return UNZ_END_OF_LIST_OF_FILE;
916 1.1 christos
917 1.1 christos file_pos->pos_in_zip_directory = s->pos_in_central_dir;
918 1.1 christos file_pos->num_of_file = s->num_file;
919 1.1 christos
920 1.1 christos return UNZ_OK;
921 1.1 christos }
922 1.1 christos
923 1.1 christos extern int ZEXPORT unzGoToFilePos(file, file_pos)
924 1.1 christos unzFile file;
925 1.1 christos unz_file_pos* file_pos;
926 1.1 christos {
927 1.1 christos unz_s* s;
928 1.1 christos int err;
929 1.1 christos
930 1.1 christos if (file==NULL || file_pos==NULL)
931 1.1 christos return UNZ_PARAMERROR;
932 1.1 christos s=(unz_s*)file;
933 1.1 christos
934 1.1 christos /* jump to the right spot */
935 1.1 christos s->pos_in_central_dir = file_pos->pos_in_zip_directory;
936 1.1 christos s->num_file = file_pos->num_of_file;
937 1.1 christos
938 1.1 christos /* set the current file */
939 1.1 christos err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
940 1.1 christos &s->cur_file_info_internal,
941 1.1 christos NULL,0,NULL,0,NULL,0);
942 1.1 christos /* return results */
943 1.1 christos s->current_file_ok = (err == UNZ_OK);
944 1.1 christos return err;
945 1.1 christos }
946 1.1 christos
947 1.1 christos /*
948 1.1 christos // Unzip Helper Functions - should be here?
949 1.1 christos ///////////////////////////////////////////
950 1.1 christos */
951 1.1 christos
952 1.1 christos /*
953 1.1 christos Read the local header of the current zipfile
954 1.1 christos Check the coherency of the local header and info in the end of central
955 1.1 christos directory about this file
956 1.1 christos store in *piSizeVar the size of extra info in local header
957 1.1 christos (filename and size of extra field data)
958 1.1 christos */
959 1.1 christos local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
960 1.1 christos poffset_local_extrafield,
961 1.1 christos psize_local_extrafield)
962 1.1 christos unz_s* s;
963 1.1 christos uInt* piSizeVar;
964 1.1 christos uLong *poffset_local_extrafield;
965 1.1 christos uInt *psize_local_extrafield;
966 1.1 christos {
967 1.1 christos uLong uMagic,uData,uFlags;
968 1.1 christos uLong size_filename;
969 1.1 christos uLong size_extra_field;
970 1.1 christos int err=UNZ_OK;
971 1.1 christos
972 1.1 christos *piSizeVar = 0;
973 1.1 christos *poffset_local_extrafield = 0;
974 1.1 christos *psize_local_extrafield = 0;
975 1.1 christos
976 1.1 christos if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
977 1.1 christos s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
978 1.1 christos return UNZ_ERRNO;
979 1.1 christos
980 1.1 christos
981 1.1 christos if (err==UNZ_OK)
982 1.1 christos if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
983 1.1 christos err=UNZ_ERRNO;
984 1.1 christos else if (uMagic!=0x04034b50)
985 1.1 christos err=UNZ_BADZIPFILE;
986 1.1 christos
987 1.1 christos if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
988 1.1 christos err=UNZ_ERRNO;
989 1.1 christos /*
990 1.1 christos else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
991 1.1 christos err=UNZ_BADZIPFILE;
992 1.1 christos */
993 1.1 christos if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
994 1.1 christos err=UNZ_ERRNO;
995 1.1 christos
996 1.1 christos if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
997 1.1 christos err=UNZ_ERRNO;
998 1.1 christos else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
999 1.1 christos err=UNZ_BADZIPFILE;
1000 1.1 christos
1001 1.1 christos if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1002 1.1 christos (s->cur_file_info.compression_method!=Z_DEFLATED))
1003 1.1 christos err=UNZ_BADZIPFILE;
1004 1.1 christos
1005 1.1 christos if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1006 1.1 christos err=UNZ_ERRNO;
1007 1.1 christos
1008 1.1 christos if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1009 1.1 christos err=UNZ_ERRNO;
1010 1.1 christos else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
1011 1.1 christos ((uFlags & 8)==0))
1012 1.1 christos err=UNZ_BADZIPFILE;
1013 1.1 christos
1014 1.1 christos if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1015 1.1 christos err=UNZ_ERRNO;
1016 1.1 christos else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
1017 1.1 christos ((uFlags & 8)==0))
1018 1.1 christos err=UNZ_BADZIPFILE;
1019 1.1 christos
1020 1.1 christos if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1021 1.1 christos err=UNZ_ERRNO;
1022 1.1 christos else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
1023 1.1 christos ((uFlags & 8)==0))
1024 1.1 christos err=UNZ_BADZIPFILE;
1025 1.1 christos
1026 1.1 christos
1027 1.1 christos if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1028 1.1 christos err=UNZ_ERRNO;
1029 1.1 christos else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1030 1.1 christos err=UNZ_BADZIPFILE;
1031 1.1 christos
1032 1.1 christos *piSizeVar += (uInt)size_filename;
1033 1.1 christos
1034 1.1 christos if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1035 1.1 christos err=UNZ_ERRNO;
1036 1.1 christos *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1037 1.1 christos SIZEZIPLOCALHEADER + size_filename;
1038 1.1 christos *psize_local_extrafield = (uInt)size_extra_field;
1039 1.1 christos
1040 1.1 christos *piSizeVar += (uInt)size_extra_field;
1041 1.1 christos
1042 1.1 christos return err;
1043 1.1 christos }
1044 1.1 christos
1045 1.1 christos /*
1046 1.1 christos Open for reading data the current file in the zipfile.
1047 1.1 christos If there is no error and the file is opened, the return value is UNZ_OK.
1048 1.1 christos */
1049 1.1 christos extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
1050 1.1 christos unzFile file;
1051 1.1 christos int* method;
1052 1.1 christos int* level;
1053 1.1 christos int raw;
1054 1.1 christos const char* password;
1055 1.1 christos {
1056 1.1 christos int err=UNZ_OK;
1057 1.1 christos uInt iSizeVar;
1058 1.1 christos unz_s* s;
1059 1.1 christos file_in_zip_read_info_s* pfile_in_zip_read_info;
1060 1.1 christos uLong offset_local_extrafield; /* offset of the local extra field */
1061 1.1 christos uInt size_local_extrafield; /* size of the local extra field */
1062 1.1 christos # ifndef NOUNCRYPT
1063 1.1 christos char source[12];
1064 1.1 christos # else
1065 1.1 christos if (password != NULL)
1066 1.1 christos return UNZ_PARAMERROR;
1067 1.1 christos # endif
1068 1.1 christos
1069 1.1 christos if (file==NULL)
1070 1.1 christos return UNZ_PARAMERROR;
1071 1.1 christos s=(unz_s*)file;
1072 1.1 christos if (!s->current_file_ok)
1073 1.1 christos return UNZ_PARAMERROR;
1074 1.1 christos
1075 1.1 christos if (s->pfile_in_zip_read != NULL)
1076 1.1 christos unzCloseCurrentFile(file);
1077 1.1 christos
1078 1.1 christos if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
1079 1.1 christos &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1080 1.1 christos return UNZ_BADZIPFILE;
1081 1.1 christos
1082 1.1 christos pfile_in_zip_read_info = (file_in_zip_read_info_s*)
1083 1.1 christos ALLOC(sizeof(file_in_zip_read_info_s));
1084 1.1 christos if (pfile_in_zip_read_info==NULL)
1085 1.1 christos return UNZ_INTERNALERROR;
1086 1.1 christos
1087 1.1 christos pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1088 1.1 christos pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1089 1.1 christos pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1090 1.1 christos pfile_in_zip_read_info->pos_local_extrafield=0;
1091 1.1 christos pfile_in_zip_read_info->raw=raw;
1092 1.1 christos
1093 1.1 christos if (pfile_in_zip_read_info->read_buffer==NULL)
1094 1.1 christos {
1095 1.1 christos TRYFREE(pfile_in_zip_read_info);
1096 1.1 christos return UNZ_INTERNALERROR;
1097 1.1 christos }
1098 1.1 christos
1099 1.1 christos pfile_in_zip_read_info->stream_initialised=0;
1100 1.1 christos
1101 1.1 christos if (method!=NULL)
1102 1.1 christos *method = (int)s->cur_file_info.compression_method;
1103 1.1 christos
1104 1.1 christos if (level!=NULL)
1105 1.1 christos {
1106 1.1 christos *level = 6;
1107 1.1 christos switch (s->cur_file_info.flag & 0x06)
1108 1.1 christos {
1109 1.1 christos case 6 : *level = 1; break;
1110 1.1 christos case 4 : *level = 2; break;
1111 1.1 christos case 2 : *level = 9; break;
1112 1.1 christos }
1113 1.1 christos }
1114 1.1 christos
1115 1.1 christos if ((s->cur_file_info.compression_method!=0) &&
1116 1.1 christos (s->cur_file_info.compression_method!=Z_DEFLATED))
1117 1.1 christos err=UNZ_BADZIPFILE;
1118 1.1 christos
1119 1.1 christos pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1120 1.1 christos pfile_in_zip_read_info->crc32=0;
1121 1.1 christos pfile_in_zip_read_info->compression_method =
1122 1.1 christos s->cur_file_info.compression_method;
1123 1.1 christos pfile_in_zip_read_info->filestream=s->filestream;
1124 1.1 christos pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1125 1.1 christos pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1126 1.1 christos
1127 1.1 christos pfile_in_zip_read_info->stream.total_out = 0;
1128 1.1 christos
1129 1.1 christos if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
1130 1.1 christos (!raw))
1131 1.1 christos {
1132 1.1 christos pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1133 1.1 christos pfile_in_zip_read_info->stream.zfree = (free_func)0;
1134 1.1 christos pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1135 1.1 christos pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1136 1.1 christos pfile_in_zip_read_info->stream.avail_in = 0;
1137 1.1 christos
1138 1.1 christos err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1139 1.1 christos if (err == Z_OK)
1140 1.1 christos pfile_in_zip_read_info->stream_initialised=1;
1141 1.1 christos else
1142 1.1 christos {
1143 1.1 christos TRYFREE(pfile_in_zip_read_info);
1144 1.1 christos return err;
1145 1.1 christos }
1146 1.1 christos /* windowBits is passed < 0 to tell that there is no zlib header.
1147 1.1 christos * Note that in this case inflate *requires* an extra "dummy" byte
1148 1.1 christos * after the compressed stream in order to complete decompression and
1149 1.1 christos * return Z_STREAM_END.
1150 1.1 christos * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1151 1.1 christos * size of both compressed and uncompressed data
1152 1.1 christos */
1153 1.1 christos }
1154 1.1 christos pfile_in_zip_read_info->rest_read_compressed =
1155 1.1 christos s->cur_file_info.compressed_size ;
1156 1.1 christos pfile_in_zip_read_info->rest_read_uncompressed =
1157 1.1 christos s->cur_file_info.uncompressed_size ;
1158 1.1 christos
1159 1.1 christos
1160 1.1 christos pfile_in_zip_read_info->pos_in_zipfile =
1161 1.1 christos s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1162 1.1 christos iSizeVar;
1163 1.1 christos
1164 1.1 christos pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1165 1.1 christos
1166 1.1 christos s->pfile_in_zip_read = pfile_in_zip_read_info;
1167 1.1 christos
1168 1.1 christos # ifndef NOUNCRYPT
1169 1.1 christos if (password != NULL)
1170 1.1 christos {
1171 1.1 christos int i;
1172 1.1 christos s->pcrc_32_tab = get_crc_table();
1173 1.1 christos init_keys(password,s->keys,s->pcrc_32_tab);
1174 1.1 christos if (ZSEEK(s->z_filefunc, s->filestream,
1175 1.1 christos s->pfile_in_zip_read->pos_in_zipfile +
1176 1.1 christos s->pfile_in_zip_read->byte_before_the_zipfile,
1177 1.1 christos SEEK_SET)!=0)
1178 1.1 christos return UNZ_INTERNALERROR;
1179 1.1 christos if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
1180 1.1 christos return UNZ_INTERNALERROR;
1181 1.1 christos
1182 1.1 christos for (i = 0; i<12; i++)
1183 1.1 christos zdecode(s->keys,s->pcrc_32_tab,source[i]);
1184 1.1 christos
1185 1.1 christos s->pfile_in_zip_read->pos_in_zipfile+=12;
1186 1.1 christos s->encrypted=1;
1187 1.1 christos }
1188 1.1 christos # endif
1189 1.1 christos
1190 1.1 christos
1191 1.1 christos return UNZ_OK;
1192 1.1 christos }
1193 1.1 christos
1194 1.1 christos extern int ZEXPORT unzOpenCurrentFile (file)
1195 1.1 christos unzFile file;
1196 1.1 christos {
1197 1.1 christos return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1198 1.1 christos }
1199 1.1 christos
1200 1.1 christos extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
1201 1.1 christos unzFile file;
1202 1.1 christos const char* password;
1203 1.1 christos {
1204 1.1 christos return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1205 1.1 christos }
1206 1.1 christos
1207 1.1 christos extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
1208 1.1 christos unzFile file;
1209 1.1 christos int* method;
1210 1.1 christos int* level;
1211 1.1 christos int raw;
1212 1.1 christos {
1213 1.1 christos return unzOpenCurrentFile3(file, method, level, raw, NULL);
1214 1.1 christos }
1215 1.1 christos
1216 1.1 christos /*
1217 1.1 christos Read bytes from the current file.
1218 1.1 christos buf contain buffer where data must be copied
1219 1.1 christos len the size of buf.
1220 1.1 christos
1221 1.1 christos return the number of byte copied if somes bytes are copied
1222 1.1 christos return 0 if the end of file was reached
1223 1.1 christos return <0 with error code if there is an error
1224 1.1 christos (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1225 1.1 christos */
1226 1.1 christos extern int ZEXPORT unzReadCurrentFile (file, buf, len)
1227 1.1 christos unzFile file;
1228 1.1 christos voidp buf;
1229 1.1 christos unsigned len;
1230 1.1 christos {
1231 1.1 christos int err=UNZ_OK;
1232 1.1 christos uInt iRead = 0;
1233 1.1 christos unz_s* s;
1234 1.1 christos file_in_zip_read_info_s* pfile_in_zip_read_info;
1235 1.1 christos if (file==NULL)
1236 1.1 christos return UNZ_PARAMERROR;
1237 1.1 christos s=(unz_s*)file;
1238 1.1 christos pfile_in_zip_read_info=s->pfile_in_zip_read;
1239 1.1 christos
1240 1.1 christos if (pfile_in_zip_read_info==NULL)
1241 1.1 christos return UNZ_PARAMERROR;
1242 1.1 christos
1243 1.1 christos
1244 1.1 christos if ((pfile_in_zip_read_info->read_buffer == NULL))
1245 1.1 christos return UNZ_END_OF_LIST_OF_FILE;
1246 1.1 christos if (len==0)
1247 1.1 christos return 0;
1248 1.1 christos
1249 1.1 christos pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1250 1.1 christos
1251 1.1 christos pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1252 1.1 christos
1253 1.1 christos if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1254 1.1 christos (!(pfile_in_zip_read_info->raw)))
1255 1.1 christos pfile_in_zip_read_info->stream.avail_out =
1256 1.1 christos (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1257 1.1 christos
1258 1.1 christos if ((len>pfile_in_zip_read_info->rest_read_compressed+
1259 1.1 christos pfile_in_zip_read_info->stream.avail_in) &&
1260 1.1 christos (pfile_in_zip_read_info->raw))
1261 1.1 christos pfile_in_zip_read_info->stream.avail_out =
1262 1.1 christos (uInt)pfile_in_zip_read_info->rest_read_compressed+
1263 1.1 christos pfile_in_zip_read_info->stream.avail_in;
1264 1.1 christos
1265 1.1 christos while (pfile_in_zip_read_info->stream.avail_out>0)
1266 1.1 christos {
1267 1.1 christos if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1268 1.1 christos (pfile_in_zip_read_info->rest_read_compressed>0))
1269 1.1 christos {
1270 1.1 christos uInt uReadThis = UNZ_BUFSIZE;
1271 1.1 christos if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1272 1.1 christos uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1273 1.1 christos if (uReadThis == 0)
1274 1.1 christos return UNZ_EOF;
1275 1.1 christos if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1276 1.1 christos pfile_in_zip_read_info->filestream,
1277 1.1 christos pfile_in_zip_read_info->pos_in_zipfile +
1278 1.1 christos pfile_in_zip_read_info->byte_before_the_zipfile,
1279 1.1 christos ZLIB_FILEFUNC_SEEK_SET)!=0)
1280 1.1 christos return UNZ_ERRNO;
1281 1.1 christos if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1282 1.1 christos pfile_in_zip_read_info->filestream,
1283 1.1 christos pfile_in_zip_read_info->read_buffer,
1284 1.1 christos uReadThis)!=uReadThis)
1285 1.1 christos return UNZ_ERRNO;
1286 1.1 christos
1287 1.1 christos
1288 1.1 christos # ifndef NOUNCRYPT
1289 1.1 christos if(s->encrypted)
1290 1.1 christos {
1291 1.1 christos uInt i;
1292 1.1 christos for(i=0;i<uReadThis;i++)
1293 1.1 christos pfile_in_zip_read_info->read_buffer[i] =
1294 1.1 christos zdecode(s->keys,s->pcrc_32_tab,
1295 1.1 christos pfile_in_zip_read_info->read_buffer[i]);
1296 1.1 christos }
1297 1.1 christos # endif
1298 1.1 christos
1299 1.1 christos
1300 1.1 christos pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1301 1.1 christos
1302 1.1 christos pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1303 1.1 christos
1304 1.1 christos pfile_in_zip_read_info->stream.next_in =
1305 1.1 christos (Bytef*)pfile_in_zip_read_info->read_buffer;
1306 1.1 christos pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1307 1.1 christos }
1308 1.1 christos
1309 1.1 christos if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1310 1.1 christos {
1311 1.1 christos uInt uDoCopy,i ;
1312 1.1 christos
1313 1.1 christos if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1314 1.1 christos (pfile_in_zip_read_info->rest_read_compressed == 0))
1315 1.1 christos return (iRead==0) ? UNZ_EOF : iRead;
1316 1.1 christos
1317 1.1 christos if (pfile_in_zip_read_info->stream.avail_out <
1318 1.1 christos pfile_in_zip_read_info->stream.avail_in)
1319 1.1 christos uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1320 1.1 christos else
1321 1.1 christos uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1322 1.1 christos
1323 1.1 christos for (i=0;i<uDoCopy;i++)
1324 1.1 christos *(pfile_in_zip_read_info->stream.next_out+i) =
1325 1.1 christos *(pfile_in_zip_read_info->stream.next_in+i);
1326 1.1 christos
1327 1.1 christos pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1328 1.1 christos pfile_in_zip_read_info->stream.next_out,
1329 1.1 christos uDoCopy);
1330 1.1 christos pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1331 1.1 christos pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1332 1.1 christos pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1333 1.1 christos pfile_in_zip_read_info->stream.next_out += uDoCopy;
1334 1.1 christos pfile_in_zip_read_info->stream.next_in += uDoCopy;
1335 1.1 christos pfile_in_zip_read_info->stream.total_out += uDoCopy;
1336 1.1 christos iRead += uDoCopy;
1337 1.1 christos }
1338 1.1 christos else
1339 1.1 christos {
1340 1.1 christos uLong uTotalOutBefore,uTotalOutAfter;
1341 1.1 christos const Bytef *bufBefore;
1342 1.1 christos uLong uOutThis;
1343 1.1 christos int flush=Z_SYNC_FLUSH;
1344 1.1 christos
1345 1.1 christos uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1346 1.1 christos bufBefore = pfile_in_zip_read_info->stream.next_out;
1347 1.1 christos
1348 1.1 christos /*
1349 1.1 christos if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1350 1.1 christos pfile_in_zip_read_info->stream.avail_out) &&
1351 1.1 christos (pfile_in_zip_read_info->rest_read_compressed == 0))
1352 1.1 christos flush = Z_FINISH;
1353 1.1 christos */
1354 1.1 christos err=inflate(&pfile_in_zip_read_info->stream,flush);
1355 1.1 christos
1356 1.1 christos if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1357 1.1 christos err = Z_DATA_ERROR;
1358 1.1 christos
1359 1.1 christos uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1360 1.1 christos uOutThis = uTotalOutAfter-uTotalOutBefore;
1361 1.1 christos
1362 1.1 christos pfile_in_zip_read_info->crc32 =
1363 1.1 christos crc32(pfile_in_zip_read_info->crc32,bufBefore,
1364 1.1 christos (uInt)(uOutThis));
1365 1.1 christos
1366 1.1 christos pfile_in_zip_read_info->rest_read_uncompressed -=
1367 1.1 christos uOutThis;
1368 1.1 christos
1369 1.1 christos iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1370 1.1 christos
1371 1.1 christos if (err==Z_STREAM_END)
1372 1.1 christos return (iRead==0) ? UNZ_EOF : iRead;
1373 1.1 christos if (err!=Z_OK)
1374 1.1 christos break;
1375 1.1 christos }
1376 1.1 christos }
1377 1.1 christos
1378 1.1 christos if (err==Z_OK)
1379 1.1 christos return iRead;
1380 1.1 christos return err;
1381 1.1 christos }
1382 1.1 christos
1383 1.1 christos
1384 1.1 christos /*
1385 1.1 christos Give the current position in uncompressed data
1386 1.1 christos */
1387 1.1 christos extern z_off_t ZEXPORT unztell (file)
1388 1.1 christos unzFile file;
1389 1.1 christos {
1390 1.1 christos unz_s* s;
1391 1.1 christos file_in_zip_read_info_s* pfile_in_zip_read_info;
1392 1.1 christos if (file==NULL)
1393 1.1 christos return UNZ_PARAMERROR;
1394 1.1 christos s=(unz_s*)file;
1395 1.1 christos pfile_in_zip_read_info=s->pfile_in_zip_read;
1396 1.1 christos
1397 1.1 christos if (pfile_in_zip_read_info==NULL)
1398 1.1 christos return UNZ_PARAMERROR;
1399 1.1 christos
1400 1.1 christos return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1401 1.1 christos }
1402 1.1 christos
1403 1.1 christos
1404 1.1 christos /*
1405 1.1 christos return 1 if the end of file was reached, 0 elsewhere
1406 1.1 christos */
1407 1.1 christos extern int ZEXPORT unzeof (file)
1408 1.1 christos unzFile file;
1409 1.1 christos {
1410 1.1 christos unz_s* s;
1411 1.1 christos file_in_zip_read_info_s* pfile_in_zip_read_info;
1412 1.1 christos if (file==NULL)
1413 1.1 christos return UNZ_PARAMERROR;
1414 1.1 christos s=(unz_s*)file;
1415 1.1 christos pfile_in_zip_read_info=s->pfile_in_zip_read;
1416 1.1 christos
1417 1.1 christos if (pfile_in_zip_read_info==NULL)
1418 1.1 christos return UNZ_PARAMERROR;
1419 1.1 christos
1420 1.1 christos if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1421 1.1 christos return 1;
1422 1.1 christos else
1423 1.1 christos return 0;
1424 1.1 christos }
1425 1.1 christos
1426 1.1 christos
1427 1.1 christos
1428 1.1 christos /*
1429 1.1 christos Read extra field from the current file (opened by unzOpenCurrentFile)
1430 1.1 christos This is the local-header version of the extra field (sometimes, there is
1431 1.1 christos more info in the local-header version than in the central-header)
1432 1.1 christos
1433 1.1 christos if buf==NULL, it return the size of the local extra field that can be read
1434 1.1 christos
1435 1.1 christos if buf!=NULL, len is the size of the buffer, the extra header is copied in
1436 1.1 christos buf.
1437 1.1 christos the return value is the number of bytes copied in buf, or (if <0)
1438 1.1 christos the error code
1439 1.1 christos */
1440 1.1 christos extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
1441 1.1 christos unzFile file;
1442 1.1 christos voidp buf;
1443 1.1 christos unsigned len;
1444 1.1 christos {
1445 1.1 christos unz_s* s;
1446 1.1 christos file_in_zip_read_info_s* pfile_in_zip_read_info;
1447 1.1 christos uInt read_now;
1448 1.1 christos uLong size_to_read;
1449 1.1 christos
1450 1.1 christos if (file==NULL)
1451 1.1 christos return UNZ_PARAMERROR;
1452 1.1 christos s=(unz_s*)file;
1453 1.1 christos pfile_in_zip_read_info=s->pfile_in_zip_read;
1454 1.1 christos
1455 1.1 christos if (pfile_in_zip_read_info==NULL)
1456 1.1 christos return UNZ_PARAMERROR;
1457 1.1 christos
1458 1.1 christos size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1459 1.1 christos pfile_in_zip_read_info->pos_local_extrafield);
1460 1.1 christos
1461 1.1 christos if (buf==NULL)
1462 1.1 christos return (int)size_to_read;
1463 1.1 christos
1464 1.1 christos if (len>size_to_read)
1465 1.1 christos read_now = (uInt)size_to_read;
1466 1.1 christos else
1467 1.1 christos read_now = (uInt)len ;
1468 1.1 christos
1469 1.1 christos if (read_now==0)
1470 1.1 christos return 0;
1471 1.1 christos
1472 1.1 christos if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1473 1.1 christos pfile_in_zip_read_info->filestream,
1474 1.1 christos pfile_in_zip_read_info->offset_local_extrafield +
1475 1.1 christos pfile_in_zip_read_info->pos_local_extrafield,
1476 1.1 christos ZLIB_FILEFUNC_SEEK_SET)!=0)
1477 1.1 christos return UNZ_ERRNO;
1478 1.1 christos
1479 1.1 christos if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1480 1.1 christos pfile_in_zip_read_info->filestream,
1481 1.1 christos buf,read_now)!=read_now)
1482 1.1 christos return UNZ_ERRNO;
1483 1.1 christos
1484 1.1 christos return (int)read_now;
1485 1.1 christos }
1486 1.1 christos
1487 1.1 christos /*
1488 1.1 christos Close the file in zip opened with unzipOpenCurrentFile
1489 1.1 christos Return UNZ_CRCERROR if all the file was read but the CRC is not good
1490 1.1 christos */
1491 1.1 christos extern int ZEXPORT unzCloseCurrentFile (file)
1492 1.1 christos unzFile file;
1493 1.1 christos {
1494 1.1 christos int err=UNZ_OK;
1495 1.1 christos
1496 1.1 christos unz_s* s;
1497 1.1 christos file_in_zip_read_info_s* pfile_in_zip_read_info;
1498 1.1 christos if (file==NULL)
1499 1.1 christos return UNZ_PARAMERROR;
1500 1.1 christos s=(unz_s*)file;
1501 1.1 christos pfile_in_zip_read_info=s->pfile_in_zip_read;
1502 1.1 christos
1503 1.1 christos if (pfile_in_zip_read_info==NULL)
1504 1.1 christos return UNZ_PARAMERROR;
1505 1.1 christos
1506 1.1 christos
1507 1.1 christos if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
1508 1.1 christos (!pfile_in_zip_read_info->raw))
1509 1.1 christos {
1510 1.1 christos if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1511 1.1 christos err=UNZ_CRCERROR;
1512 1.1 christos }
1513 1.1 christos
1514 1.1 christos
1515 1.1 christos TRYFREE(pfile_in_zip_read_info->read_buffer);
1516 1.1 christos pfile_in_zip_read_info->read_buffer = NULL;
1517 1.1 christos if (pfile_in_zip_read_info->stream_initialised)
1518 1.1 christos inflateEnd(&pfile_in_zip_read_info->stream);
1519 1.1 christos
1520 1.1 christos pfile_in_zip_read_info->stream_initialised = 0;
1521 1.1 christos TRYFREE(pfile_in_zip_read_info);
1522 1.1 christos
1523 1.1 christos s->pfile_in_zip_read=NULL;
1524 1.1 christos
1525 1.1 christos return err;
1526 1.1 christos }
1527 1.1 christos
1528 1.1 christos
1529 1.1 christos /*
1530 1.1 christos Get the global comment string of the ZipFile, in the szComment buffer.
1531 1.1 christos uSizeBuf is the size of the szComment buffer.
1532 1.1 christos return the number of byte copied or an error code <0
1533 1.1 christos */
1534 1.1 christos extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
1535 1.1 christos unzFile file;
1536 1.1 christos char *szComment;
1537 1.1 christos uLong uSizeBuf;
1538 1.1 christos {
1539 1.1 christos int err=UNZ_OK;
1540 1.1 christos unz_s* s;
1541 1.1 christos uLong uReadThis ;
1542 1.1 christos if (file==NULL)
1543 1.1 christos return UNZ_PARAMERROR;
1544 1.1 christos s=(unz_s*)file;
1545 1.1 christos
1546 1.1 christos uReadThis = uSizeBuf;
1547 1.1 christos if (uReadThis>s->gi.size_comment)
1548 1.1 christos uReadThis = s->gi.size_comment;
1549 1.1 christos
1550 1.1 christos if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
1551 1.1 christos return UNZ_ERRNO;
1552 1.1 christos
1553 1.1 christos if (uReadThis>0)
1554 1.1 christos {
1555 1.1 christos *szComment='\0';
1556 1.1 christos if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
1557 1.1 christos return UNZ_ERRNO;
1558 1.1 christos }
1559 1.1 christos
1560 1.1 christos if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1561 1.1 christos *(szComment+s->gi.size_comment)='\0';
1562 1.1 christos return (int)uReadThis;
1563 1.1 christos }
1564 1.1 christos
1565 1.1 christos /* Additions by RX '2004 */
1566 1.1 christos extern uLong ZEXPORT unzGetOffset (file)
1567 1.1 christos unzFile file;
1568 1.1 christos {
1569 1.1 christos unz_s* s;
1570 1.1 christos
1571 1.1 christos if (file==NULL)
1572 1.1 christos return UNZ_PARAMERROR;
1573 1.1 christos s=(unz_s*)file;
1574 1.1 christos if (!s->current_file_ok)
1575 1.1 christos return 0;
1576 1.1 christos if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
1577 1.1 christos if (s->num_file==s->gi.number_entry)
1578 1.1 christos return 0;
1579 1.1 christos return s->pos_in_central_dir;
1580 1.1 christos }
1581 1.1 christos
1582 1.1 christos extern int ZEXPORT unzSetOffset (file, pos)
1583 1.1 christos unzFile file;
1584 1.1 christos uLong pos;
1585 1.1 christos {
1586 1.1 christos unz_s* s;
1587 1.1 christos int err;
1588 1.1 christos
1589 1.1 christos if (file==NULL)
1590 1.1 christos return UNZ_PARAMERROR;
1591 1.1 christos s=(unz_s*)file;
1592 1.1 christos
1593 1.1 christos s->pos_in_central_dir = pos;
1594 1.1 christos s->num_file = s->gi.number_entry; /* hack */
1595 1.1 christos err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1596 1.1 christos &s->cur_file_info_internal,
1597 1.1 christos NULL,0,NULL,0,NULL,0);
1598 1.1 christos s->current_file_ok = (err == UNZ_OK);
1599 1.1 christos return err;
1600 1.1 christos }
1601