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