Contents of /trunk/src/unzip.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide 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 harbaum 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     }