Contents of /trunk/src/unzip.c

Parent Directory Parent Directory | Revision Log Revision Log


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