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