MythTV  0.26-pre
unzip.c
Go to the documentation of this file.
00001 /* unzip.c -- IO on .zip files using zlib 
00002    Version 0.15 beta, Mar 19th, 1998,
00003 
00004    Read unzip.h for more info
00005 */
00006 
00007 
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include <string.h>
00011 #include "zlib.h"
00012 #include "unzip.h"
00013 
00014 #ifdef STDC
00015 #  include <stddef.h>
00016 #  include <string.h>
00017 #  include <stdlib.h>
00018 #endif
00019 #ifdef NO_ERRNO_H
00020     extern int errno;
00021 #else
00022 #   include <errno.h>
00023 #endif
00024 
00025 
00026 #ifndef local
00027 #  define local static
00028 #endif
00029 /* compile with -Dlocal if your debugger can't find static symbols */
00030 
00031 
00032 
00033 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
00034                       !defined(CASESENSITIVITYDEFAULT_NO)
00035 #define CASESENSITIVITYDEFAULT_NO
00036 #endif
00037 
00038 
00039 #ifndef UNZ_BUFSIZE
00040 #define UNZ_BUFSIZE (16384)
00041 #endif
00042 
00043 #ifndef UNZ_MAXFILENAMEINZIP
00044 #define UNZ_MAXFILENAMEINZIP (256)
00045 #endif
00046 
00047 #ifndef ALLOC
00048 # define ALLOC(size) (malloc(size))
00049 #endif
00050 #ifndef TRYFREE
00051 # define TRYFREE(p) {if (p) free(p);}
00052 #endif
00053 
00054 #define SIZECENTRALDIRITEM (0x2e)
00055 #define SIZEZIPLOCALHEADER (0x1e)
00056 
00057 
00058 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
00059 
00060 #ifndef SEEK_CUR
00061 #define SEEK_CUR    1
00062 #endif
00063 
00064 #ifndef SEEK_END
00065 #define SEEK_END    2
00066 #endif
00067 
00068 #ifndef SEEK_SET
00069 #define SEEK_SET    0
00070 #endif
00071 
00072 const char unz_copyright[] =
00073    " unzip 0.15 Copyright 1998 Gilles Vollant ";
00074 
00075 /* unz_file_info_interntal contain internal info about a file in zipfile*/
00076 typedef struct unz_file_info_internal_s
00077 {
00078     uLong offset_curfile;/* relative offset of local header 4 bytes */
00079 } unz_file_info_internal;
00080 
00081 
00082 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
00083     when reading and decompress it */
00084 typedef struct
00085 {
00086         char  *read_buffer;         /* internal buffer for compressed data */
00087         z_stream stream;            /* zLib stream structure for inflate */
00088 
00089         uLong pos_in_zipfile;       /* position in byte on the zipfile, for fseek*/
00090         uLong stream_initialised;   /* flag set if stream structure is initialised*/
00091 
00092         uLong offset_local_extrafield;/* offset of the local extra field */
00093         uInt  size_local_extrafield;/* size of the local extra field */
00094         uLong pos_local_extrafield;   /* position in the local extra field in read*/
00095 
00096         uLong crc32;                /* crc32 of all data uncompressed */
00097         uLong crc32_wait;           /* crc32 we must obtain after decompress all */
00098         uLong rest_read_compressed; /* number of byte to be decompressed */
00099         uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
00100         FILE* file;                 /* io structore of the zipfile */
00101         uLong compression_method;   /* compression method (0==store) */
00102         uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
00103 } file_in_zip_read_info_s;
00104 
00105 
00106 /* unz_s contain internal information about the zipfile
00107 */
00108 typedef struct
00109 {
00110         FILE* file;                 /* io structore of the zipfile */
00111         unz_global_info gi;       /* public global information */
00112         uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
00113         uLong num_file;             /* number of the current file in the zipfile*/
00114         uLong pos_in_central_dir;   /* pos of the current file in the central dir*/
00115         uLong current_file_ok;      /* flag about the usability of the current file*/
00116         uLong central_pos;          /* position of the beginning of the central dir*/
00117 
00118         uLong size_central_dir;     /* size of the central directory  */
00119         uLong offset_central_dir;   /* offset of start of central directory with
00120                                                                    respect to the starting disk number */
00121 
00122         unz_file_info cur_file_info; /* public info about the current file in zip*/
00123         unz_file_info_internal cur_file_info_internal; /* private info about it*/
00124     file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
00125                                             file if we are decompressing it */
00126 } unz_s;
00127 
00128 
00129 /* ===========================================================================
00130      Read a byte from a gz_stream; update next_in and avail_in. Return EOF
00131    for end of file.
00132    IN assertion: the stream s has been sucessfully opened for reading.
00133 */
00134 
00135 
00136 local int unzlocal_getByte(fin,pi)
00137         FILE *fin;
00138         int *pi;
00139 {
00140     unsigned char c;
00141         int err = fread(&c, 1, 1, fin);
00142     if (err==1)
00143     {
00144         *pi = (int)c;
00145         return UNZ_OK;
00146     }
00147     else
00148     {
00149         if (ferror(fin)) 
00150             return UNZ_ERRNO;
00151         else
00152             return UNZ_EOF;
00153     }
00154 }
00155 
00156 
00157 /* ===========================================================================
00158    Reads a long in LSB order from the given gz_stream. Sets 
00159 */
00160 local int unzlocal_getShort (fin,pX)
00161         FILE* fin;
00162     uLong *pX;
00163 {
00164     uLong x ;
00165     int i = 0;
00166     int err;
00167 
00168     err = unzlocal_getByte(fin,&i);
00169     x = (uLong)i;
00170     
00171     if (err==UNZ_OK)
00172         err = unzlocal_getByte(fin,&i);
00173     x += ((uLong)i)<<8;
00174    
00175     if (err==UNZ_OK)
00176         *pX = x;
00177     else
00178         *pX = 0;
00179     return err;
00180 }
00181 
00182 local int unzlocal_getLong (fin,pX)
00183         FILE* fin;
00184     uLong *pX;
00185 {
00186     uLong x ;
00187     int i = 0;
00188     int err;
00189 
00190     err = unzlocal_getByte(fin,&i);
00191     x = (uLong)i;
00192     
00193     if (err==UNZ_OK)
00194         err = unzlocal_getByte(fin,&i);
00195     x += ((uLong)i)<<8;
00196 
00197     if (err==UNZ_OK)
00198         err = unzlocal_getByte(fin,&i);
00199     x += ((uLong)i)<<16;
00200 
00201     if (err==UNZ_OK)
00202         err = unzlocal_getByte(fin,&i);
00203     x += ((uLong)i)<<24;
00204    
00205     if (err==UNZ_OK)
00206         *pX = x;
00207     else
00208         *pX = 0;
00209     return err;
00210 }
00211 
00212 
00213 /* My own strcmpi / strcasecmp */
00214 local int strcmpcasenosensitive_internal (fileName1,fileName2)
00215         const char* fileName1;
00216         const char* fileName2;
00217 {
00218         for (;;)
00219         {
00220                 char c1=*(fileName1++);
00221                 char c2=*(fileName2++);
00222                 if ((c1>='a') && (c1<='z'))
00223                         c1 -= 0x20;
00224                 if ((c2>='a') && (c2<='z'))
00225                         c2 -= 0x20;
00226                 if (c1=='\0')
00227                         return ((c2=='\0') ? 0 : -1);
00228                 if (c2=='\0')
00229                         return 1;
00230                 if (c1<c2)
00231                         return -1;
00232                 if (c1>c2)
00233                         return 1;
00234         }
00235 }
00236 
00237 
00238 #ifdef  CASESENSITIVITYDEFAULT_NO
00239 #define CASESENSITIVITYDEFAULTVALUE 2
00240 #else
00241 #define CASESENSITIVITYDEFAULTVALUE 1
00242 #endif
00243 
00244 #ifndef STRCMPCASENOSENTIVEFUNCTION
00245 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
00246 #endif
00247 
00248 /* 
00249    Compare two filename (fileName1,fileName2).
00250    If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
00251    If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
00252                                                                 or strcasecmp)
00253    If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
00254         (like 1 on Unix, 2 on Windows)
00255 
00256 */
00257 extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
00258         const char* fileName1;
00259         const char* fileName2;
00260         int iCaseSensitivity;
00261 {
00262         if (iCaseSensitivity==0)
00263                 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
00264 
00265         if (iCaseSensitivity==1)
00266                 return strcmp(fileName1,fileName2);
00267 
00268         return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
00269 } 
00270 
00271 #define BUFREADCOMMENT (0x400)
00272 
00273 /*
00274   Locate the Central directory of a zipfile (at the end, just before
00275     the global comment)
00276 */
00277 local uLong unzlocal_SearchCentralDir(fin)
00278         FILE *fin;
00279 {
00280         unsigned char* buf;
00281         uLong uSizeFile;
00282         uLong uBackRead;
00283         uLong uMaxBack=0xffff; /* maximum size of global comment */
00284         uLong uPosFound=0;
00285         
00286         if (fseek(fin,0,SEEK_END) != 0)
00287                 return 0;
00288 
00289 
00290         uSizeFile = ftell( fin );
00291         
00292         if (uMaxBack>uSizeFile)
00293                 uMaxBack = uSizeFile;
00294 
00295         buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
00296         if (buf==NULL)
00297                 return 0;
00298 
00299         uBackRead = 4;
00300         while (uBackRead<uMaxBack)
00301         {
00302                 uLong uReadSize,uReadPos ;
00303                 int i;
00304                 if (uBackRead+BUFREADCOMMENT>uMaxBack) 
00305                         uBackRead = uMaxBack;
00306                 else
00307                         uBackRead+=BUFREADCOMMENT;
00308                 uReadPos = uSizeFile-uBackRead ;
00309                 
00310                 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? 
00311                      (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
00312                 if (fseek(fin,uReadPos,SEEK_SET)!=0)
00313                         break;
00314 
00315                 if (fread(buf,(uInt)uReadSize,1,fin)!=1)
00316                         break;
00317 
00318                 for (i=(int)uReadSize-3; (i--)>0;)
00319                         if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && 
00320                                 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
00321                         {
00322                                 uPosFound = uReadPos+i;
00323                                 break;
00324                         }
00325 
00326                 if (uPosFound!=0)
00327                         break;
00328         }
00329         TRYFREE(buf);
00330         return uPosFound;
00331 }
00332 
00333 /*
00334   Open a Zip file. path contain the full pathname (by example,
00335      on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
00336          "zlib/zlib109.zip".
00337          If the zipfile cannot be opened (file don't exist or in not valid), the
00338            return value is NULL.
00339      Else, the return value is a unzFile Handle, usable with other function
00340            of this unzip package.
00341 */
00342 extern unzFile ZEXPORT unzOpen (path)
00343         const char *path;
00344 {
00345         unz_s us;
00346         unz_s *s;
00347         uLong central_pos,uL;
00348         FILE * fin ;
00349 
00350         uLong number_disk;          /* number of the current dist, used for 
00351                                                                    spaning ZIP, unsupported, always 0*/
00352         uLong number_disk_with_CD;  /* number the the disk with central dir, used
00353                                                                    for spaning ZIP, unsupported, always 0*/
00354         uLong number_entry_CD;      /* total number of entries in
00355                                        the central dir 
00356                                        (same than number_entry on nospan) */
00357 
00358         int err=UNZ_OK;
00359 
00360     if (unz_copyright[0]!=' ')
00361         return NULL;
00362 
00363     fin=fopen(path,"rb");
00364         if (fin==NULL)
00365                 return NULL;
00366 
00367         central_pos = unzlocal_SearchCentralDir(fin);
00368         if (central_pos==0)
00369                 err=UNZ_ERRNO;
00370 
00371         if (fseek(fin,central_pos,SEEK_SET)!=0)
00372                 err=UNZ_ERRNO;
00373 
00374         /* the signature, already checked */
00375         if (unzlocal_getLong(fin,&uL)!=UNZ_OK)
00376                 err=UNZ_ERRNO;
00377 
00378         /* number of this disk */
00379         if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK)
00380                 err=UNZ_ERRNO;
00381 
00382         /* number of the disk with the start of the central directory */
00383         if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK)
00384                 err=UNZ_ERRNO;
00385 
00386         /* total number of entries in the central dir on this disk */
00387         if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK)
00388                 err=UNZ_ERRNO;
00389 
00390         /* total number of entries in the central dir */
00391         if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK)
00392                 err=UNZ_ERRNO;
00393 
00394         if ((number_entry_CD!=us.gi.number_entry) ||
00395                 (number_disk_with_CD!=0) ||
00396                 (number_disk!=0))
00397                 err=UNZ_BADZIPFILE;
00398 
00399         /* size of the central directory */
00400         if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK)
00401                 err=UNZ_ERRNO;
00402 
00403         /* offset of start of central directory with respect to the 
00404               starting disk number */
00405         if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK)
00406                 err=UNZ_ERRNO;
00407 
00408         /* zipfile comment length */
00409         if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK)
00410                 err=UNZ_ERRNO;
00411 
00412         if ((central_pos<us.offset_central_dir+us.size_central_dir) && 
00413                 (err==UNZ_OK))
00414                 err=UNZ_BADZIPFILE;
00415 
00416         if (err!=UNZ_OK)
00417         {
00418                 fclose(fin);
00419                 return NULL;
00420         }
00421 
00422         us.file=fin;
00423         us.byte_before_the_zipfile = central_pos -
00424                                     (us.offset_central_dir+us.size_central_dir);
00425         us.central_pos = central_pos;
00426     us.pfile_in_zip_read = NULL;
00427         
00428 
00429         s=(unz_s*)ALLOC(sizeof(unz_s));
00430         *s=us;
00431         unzGoToFirstFile((unzFile)s);   
00432         return (unzFile)s;      
00433 }
00434 
00435 
00436 /*
00437   Close a ZipFile opened with unzipOpen.
00438   If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
00439     these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
00440   return UNZ_OK if there is no problem. */
00441 extern int ZEXPORT unzClose (file)
00442         unzFile file;
00443 {
00444         unz_s* s;
00445         if (file==NULL)
00446                 return UNZ_PARAMERROR;
00447         s=(unz_s*)file;
00448 
00449     if (s->pfile_in_zip_read!=NULL)
00450         unzCloseCurrentFile(file);
00451 
00452         fclose(s->file);
00453         TRYFREE(s);
00454         return UNZ_OK;
00455 }
00456 
00457 
00458 /*
00459   Write info about the ZipFile in the *pglobal_info structure.
00460   No preparation of the structure is needed
00461   return UNZ_OK if there is no problem. */
00462 extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
00463         unzFile file;
00464         unz_global_info *pglobal_info;
00465 {
00466         unz_s* s;
00467         if (file==NULL)
00468                 return UNZ_PARAMERROR;
00469         s=(unz_s*)file;
00470         *pglobal_info=s->gi;
00471         return UNZ_OK;
00472 }
00473 
00474 
00475 /*
00476    Translate date/time from Dos format to tm_unz (readable more easilty)
00477 */
00478 local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
00479     uLong ulDosDate;
00480     tm_unz* ptm;
00481 {
00482     uLong uDate;
00483     uDate = (uLong)(ulDosDate>>16);
00484     ptm->tm_mday = (uInt)(uDate&0x1f) ;
00485     ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;
00486     ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
00487 
00488     ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
00489     ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;
00490     ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;
00491 }
00492 
00493 /*
00494   Get Info about the current file in the zipfile, with internal only info
00495 */
00496 local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
00497                                                   unz_file_info *pfile_info,
00498                                                   unz_file_info_internal 
00499                                                   *pfile_info_internal,
00500                                                   char *szFileName,
00501                                                                                                   uLong fileNameBufferSize,
00502                                                   void *extraField,
00503                                                                                                   uLong extraFieldBufferSize,
00504                                                   char *szComment,
00505                                                                                                   uLong commentBufferSize));
00506 
00507 local int unzlocal_GetCurrentFileInfoInternal (file,
00508                                               pfile_info,
00509                                               pfile_info_internal,
00510                                               szFileName, fileNameBufferSize,
00511                                               extraField, extraFieldBufferSize,
00512                                               szComment,  commentBufferSize)
00513         unzFile file;
00514         unz_file_info *pfile_info;
00515         unz_file_info_internal *pfile_info_internal;
00516         char *szFileName;
00517         uLong fileNameBufferSize;
00518         void *extraField;
00519         uLong extraFieldBufferSize;
00520         char *szComment;
00521         uLong commentBufferSize;
00522 {
00523         unz_s* s;
00524         unz_file_info file_info;
00525         unz_file_info_internal file_info_internal;
00526         int err=UNZ_OK;
00527         uLong uMagic;
00528         long lSeek=0;
00529 
00530         if (file==NULL)
00531                 return UNZ_PARAMERROR;
00532         s=(unz_s*)file;
00533         if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0)
00534                 err=UNZ_ERRNO;
00535 
00536 
00537         /* we check the magic */
00538         if (err==UNZ_OK){ 
00539                 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) {
00540                         err=UNZ_ERRNO;
00541                 } else if (uMagic!=0x02014b50) {
00542                         err=UNZ_BADZIPFILE;
00543                 }
00544         }
00545 
00546         if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK)
00547                 err=UNZ_ERRNO;
00548 
00549         if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK)
00550                 err=UNZ_ERRNO;
00551 
00552         if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK)
00553                 err=UNZ_ERRNO;
00554 
00555         if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK)
00556                 err=UNZ_ERRNO;
00557 
00558         if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK)
00559                 err=UNZ_ERRNO;
00560 
00561     unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
00562 
00563         if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK)
00564                 err=UNZ_ERRNO;
00565 
00566         if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK)
00567                 err=UNZ_ERRNO;
00568 
00569         if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK)
00570                 err=UNZ_ERRNO;
00571 
00572         if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK)
00573                 err=UNZ_ERRNO;
00574 
00575         if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK)
00576                 err=UNZ_ERRNO;
00577 
00578         if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK)
00579                 err=UNZ_ERRNO;
00580 
00581         if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK)
00582                 err=UNZ_ERRNO;
00583 
00584         if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK)
00585                 err=UNZ_ERRNO;
00586 
00587         if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK)
00588                 err=UNZ_ERRNO;
00589 
00590         if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK)
00591                 err=UNZ_ERRNO;
00592 
00593         lSeek+=file_info.size_filename;
00594         if ((err==UNZ_OK) && (szFileName!=NULL))
00595         {
00596                 uLong uSizeRead ;
00597                 if (file_info.size_filename<fileNameBufferSize)
00598                 {
00599                         *(szFileName+file_info.size_filename)='\0';
00600                         uSizeRead = file_info.size_filename;
00601                 } else {
00602                         uSizeRead = fileNameBufferSize;
00603                 }
00604 
00605                 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
00606                         if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1)
00607                                 err=UNZ_ERRNO;
00608                 lSeek -= uSizeRead;
00609         }
00610 
00611         
00612         if ((err==UNZ_OK) && (extraField!=NULL))
00613         {
00614                 uLong uSizeRead ;
00615                 if (file_info.size_file_extra<extraFieldBufferSize)
00616                         uSizeRead = file_info.size_file_extra;
00617                 else
00618                         uSizeRead = extraFieldBufferSize;
00619 
00620                 if (lSeek!=0) {
00621                         if (fseek(s->file,lSeek,SEEK_CUR)==0) {
00622                                 lSeek=0;
00623                         } else {
00624                                 err=UNZ_ERRNO;
00625                         }
00626                 }
00627                 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
00628                         if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1)
00629                                 err=UNZ_ERRNO;
00630                 lSeek += file_info.size_file_extra - uSizeRead;
00631         }
00632         else
00633                 lSeek+=file_info.size_file_extra; 
00634 
00635         
00636         if ((err==UNZ_OK) && (szComment!=NULL))
00637         {
00638                 uLong uSizeRead ;
00639                 if (file_info.size_file_comment<commentBufferSize)
00640                 {
00641                         *(szComment+file_info.size_file_comment)='\0';
00642                         uSizeRead = file_info.size_file_comment;
00643                 }
00644                 else
00645                         uSizeRead = commentBufferSize;
00646 
00647                 if (lSeek!=0) {
00648                         if (fseek(s->file,lSeek,SEEK_CUR)==0)
00649                             lSeek=0;
00650                         else
00651                             err=UNZ_ERRNO;
00652                 }
00653                 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
00654                         if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1)
00655                                 err=UNZ_ERRNO;
00656                 lSeek+=file_info.size_file_comment - uSizeRead;
00657         }
00658         else
00659                 lSeek+=file_info.size_file_comment;
00660 
00661         if ((err==UNZ_OK) && (pfile_info!=NULL))
00662                 *pfile_info=file_info;
00663 
00664         if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
00665                 *pfile_info_internal=file_info_internal;
00666 
00667         return err;
00668 }
00669 
00670 
00671 
00672 /*
00673   Write info about the ZipFile in the *pglobal_info structure.
00674   No preparation of the structure is needed
00675   return UNZ_OK if there is no problem.
00676 */
00677 extern int ZEXPORT unzGetCurrentFileInfo (file,
00678                                                   pfile_info,
00679                                                   szFileName, fileNameBufferSize,
00680                                                   extraField, extraFieldBufferSize,
00681                                                   szComment,  commentBufferSize)
00682         unzFile file;
00683         unz_file_info *pfile_info;
00684         char *szFileName;
00685         uLong fileNameBufferSize;
00686         void *extraField;
00687         uLong extraFieldBufferSize;
00688         char *szComment;
00689         uLong commentBufferSize;
00690 {
00691         return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
00692                                                                                                 szFileName,fileNameBufferSize,
00693                                                                                                 extraField,extraFieldBufferSize,
00694                                                                                                 szComment,commentBufferSize);
00695 }
00696 
00697 /*
00698   Set the current file of the zipfile to the first file.
00699   return UNZ_OK if there is no problem
00700 */
00701 extern int ZEXPORT unzGoToFirstFile (file)
00702         unzFile file;
00703 {
00704         int err=UNZ_OK;
00705         unz_s* s;
00706         if (file==NULL)
00707                 return UNZ_PARAMERROR;
00708         s=(unz_s*)file;
00709         s->pos_in_central_dir=s->offset_central_dir;
00710         s->num_file=0;
00711         err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
00712                                                                                          &s->cur_file_info_internal,
00713                                                                                          NULL,0,NULL,0,NULL,0);
00714         s->current_file_ok = (err == UNZ_OK);
00715         return err;
00716 }
00717 
00718 
00719 /*
00720   Set the current file of the zipfile to the next file.
00721   return UNZ_OK if there is no problem
00722   return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
00723 */
00724 extern int ZEXPORT unzGoToNextFile (file)
00725         unzFile file;
00726 {
00727         unz_s* s;       
00728         int err;
00729 
00730         if (file==NULL)
00731                 return UNZ_PARAMERROR;
00732         s=(unz_s*)file;
00733         if (!s->current_file_ok)
00734                 return UNZ_END_OF_LIST_OF_FILE;
00735         if (s->num_file+1==s->gi.number_entry)
00736                 return UNZ_END_OF_LIST_OF_FILE;
00737 
00738         s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
00739                         s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
00740         s->num_file++;
00741         err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
00742                                                                                            &s->cur_file_info_internal,
00743                                                                                            NULL,0,NULL,0,NULL,0);
00744         s->current_file_ok = (err == UNZ_OK);
00745         return err;
00746 }
00747 
00748 
00749 /*
00750   Try locate the file szFileName in the zipfile.
00751   For the iCaseSensitivity signification, see unzipStringFileNameCompare
00752 
00753   return value :
00754   UNZ_OK if the file is found. It becomes the current file.
00755   UNZ_END_OF_LIST_OF_FILE if the file is not found
00756 */
00757 extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
00758         unzFile file;
00759         const char *szFileName;
00760         int iCaseSensitivity;
00761 {
00762         unz_s* s;       
00763         int err;
00764 
00765         
00766         uLong num_fileSaved;
00767         uLong pos_in_central_dirSaved;
00768 
00769 
00770         if (file==NULL)
00771                 return UNZ_PARAMERROR;
00772 
00773     if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
00774         return UNZ_PARAMERROR;
00775 
00776         s=(unz_s*)file;
00777         if (!s->current_file_ok)
00778                 return UNZ_END_OF_LIST_OF_FILE;
00779 
00780         num_fileSaved = s->num_file;
00781         pos_in_central_dirSaved = s->pos_in_central_dir;
00782 
00783         err = unzGoToFirstFile(file);
00784 
00785         while (err == UNZ_OK)
00786         {
00787                 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
00788                 unzGetCurrentFileInfo(file,NULL,
00789                                                                 szCurrentFileName,sizeof(szCurrentFileName)-1,
00790                                                                 NULL,0,NULL,0);
00791                 if (unzStringFileNameCompare(szCurrentFileName,
00792                                                                                 szFileName,iCaseSensitivity)==0)
00793                         return UNZ_OK;
00794                 err = unzGoToNextFile(file);
00795         }
00796 
00797         s->num_file = num_fileSaved ;
00798         s->pos_in_central_dir = pos_in_central_dirSaved ;
00799         return err;
00800 }
00801 
00802 
00803 /*
00804   Read the local header of the current zipfile
00805   Check the coherency of the local header and info in the end of central
00806         directory about this file
00807   store in *piSizeVar the size of extra info in local header
00808         (filename and size of extra field data)
00809 */
00810 local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
00811                                                                                                         poffset_local_extrafield,
00812                                                                                                         psize_local_extrafield)
00813         unz_s* s;
00814         uInt* piSizeVar;
00815         uLong *poffset_local_extrafield;
00816         uInt  *psize_local_extrafield;
00817 {
00818         uLong uMagic,uData,uFlags;
00819         uLong size_filename;
00820         uLong size_extra_field;
00821         int err=UNZ_OK;
00822 
00823         *piSizeVar = 0;
00824         *poffset_local_extrafield = 0;
00825         *psize_local_extrafield = 0;
00826 
00827         if (fseek(s->file,s->cur_file_info_internal.offset_curfile +
00828                                                                 s->byte_before_the_zipfile,SEEK_SET)!=0)
00829                 return UNZ_ERRNO;
00830 
00831 
00832         if (err==UNZ_OK) {
00833                 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
00834                         err=UNZ_ERRNO;
00835                 else if (uMagic!=0x04034b50)
00836                         err=UNZ_BADZIPFILE;
00837         }
00838 
00839         if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
00840                 err=UNZ_ERRNO;
00841 /*
00842         else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
00843                 err=UNZ_BADZIPFILE;
00844 */
00845         if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK)
00846                 err=UNZ_ERRNO;
00847 
00848         if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
00849                 err=UNZ_ERRNO;
00850         else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
00851                 err=UNZ_BADZIPFILE;
00852 
00853     if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
00854                          (s->cur_file_info.compression_method!=Z_DEFLATED))
00855         err=UNZ_BADZIPFILE;
00856 
00857         if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */
00858                 err=UNZ_ERRNO;
00859 
00860         if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */
00861                 err=UNZ_ERRNO;
00862         else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
00863                                       ((uFlags & 8)==0))
00864                 err=UNZ_BADZIPFILE;
00865 
00866         if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */
00867                 err=UNZ_ERRNO;
00868         else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
00869                                                           ((uFlags & 8)==0))
00870                 err=UNZ_BADZIPFILE;
00871 
00872         if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */
00873                 err=UNZ_ERRNO;
00874         else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && 
00875                                                           ((uFlags & 8)==0))
00876                 err=UNZ_BADZIPFILE;
00877 
00878 
00879         if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK)
00880                 err=UNZ_ERRNO;
00881         else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
00882                 err=UNZ_BADZIPFILE;
00883 
00884         *piSizeVar += (uInt)size_filename;
00885 
00886         if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK)
00887                 err=UNZ_ERRNO;
00888         *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
00889                                                                         SIZEZIPLOCALHEADER + size_filename;
00890         *psize_local_extrafield = (uInt)size_extra_field;
00891 
00892         *piSizeVar += (uInt)size_extra_field;
00893 
00894         return err;
00895 }
00896                                                                                                 
00897 /*
00898   Open for reading data the current file in the zipfile.
00899   If there is no error and the file is opened, the return value is UNZ_OK.
00900 */
00901 extern int ZEXPORT unzOpenCurrentFile (file)
00902         unzFile file;
00903 {
00904         int err=UNZ_OK;
00905         int Store;
00906         uInt iSizeVar;
00907         unz_s* s;
00908         file_in_zip_read_info_s* pfile_in_zip_read_info;
00909         uLong offset_local_extrafield;  /* offset of the local extra field */
00910         uInt  size_local_extrafield;    /* size of the local extra field */
00911 
00912         if (file==NULL)
00913                 return UNZ_PARAMERROR;
00914         s=(unz_s*)file;
00915         if (!s->current_file_ok)
00916                 return UNZ_PARAMERROR;
00917 
00918     if (s->pfile_in_zip_read != NULL)
00919         unzCloseCurrentFile(file);
00920 
00921         if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
00922                                 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
00923                 return UNZ_BADZIPFILE;
00924 
00925         pfile_in_zip_read_info = (file_in_zip_read_info_s*)
00926                                                                             ALLOC(sizeof(file_in_zip_read_info_s));
00927         if (pfile_in_zip_read_info==NULL)
00928                 return UNZ_INTERNALERROR;
00929 
00930         pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
00931         pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
00932         pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
00933         pfile_in_zip_read_info->pos_local_extrafield=0;
00934 
00935         if (pfile_in_zip_read_info->read_buffer==NULL)
00936         {
00937                 TRYFREE(pfile_in_zip_read_info);
00938                 return UNZ_INTERNALERROR;
00939         }
00940 
00941         pfile_in_zip_read_info->stream_initialised=0;
00942         
00943         if ((s->cur_file_info.compression_method!=0) &&
00944         (s->cur_file_info.compression_method!=Z_DEFLATED))
00945                 err=UNZ_BADZIPFILE;
00946         Store = s->cur_file_info.compression_method==0;
00947 
00948         pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
00949         pfile_in_zip_read_info->crc32=0;
00950         pfile_in_zip_read_info->compression_method =
00951             s->cur_file_info.compression_method;
00952         pfile_in_zip_read_info->file=s->file;
00953         pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
00954 
00955     pfile_in_zip_read_info->stream.total_out = 0;
00956 
00957         if (!Store)
00958         {
00959           pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
00960           pfile_in_zip_read_info->stream.zfree = (free_func)0;
00961           pfile_in_zip_read_info->stream.opaque = (voidpf)0; 
00962       
00963           err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
00964           if (err == Z_OK)
00965             pfile_in_zip_read_info->stream_initialised=1;
00966         /* windowBits is passed < 0 to tell that there is no zlib header.
00967          * Note that in this case inflate *requires* an extra "dummy" byte
00968          * after the compressed stream in order to complete decompression and
00969          * return Z_STREAM_END. 
00970          * In unzip, i don't wait absolutely Z_STREAM_END because I known the 
00971          * size of both compressed and uncompressed data
00972          */
00973         }
00974         pfile_in_zip_read_info->rest_read_compressed = 
00975             s->cur_file_info.compressed_size ;
00976         pfile_in_zip_read_info->rest_read_uncompressed = 
00977             s->cur_file_info.uncompressed_size ;
00978 
00979         
00980         pfile_in_zip_read_info->pos_in_zipfile = 
00981             s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + 
00982                           iSizeVar;
00983         
00984         pfile_in_zip_read_info->stream.avail_in = (uInt)0;
00985 
00986 
00987         s->pfile_in_zip_read = pfile_in_zip_read_info;
00988     return UNZ_OK;
00989 }
00990 
00991 
00992 /*
00993   Read bytes from the current file.
00994   buf contain buffer where data must be copied
00995   len the size of buf.
00996 
00997   return the number of byte copied if somes bytes are copied
00998   return 0 if the end of file was reached
00999   return <0 with error code if there is an error
01000     (UNZ_ERRNO for IO error, or zLib error for uncompress error)
01001 */
01002 extern int ZEXPORT unzReadCurrentFile  (file, buf, len)
01003         unzFile file;
01004         voidp buf;
01005         unsigned len;
01006 {
01007         int err=UNZ_OK;
01008         uInt iRead = 0;
01009         unz_s* s;
01010         file_in_zip_read_info_s* pfile_in_zip_read_info;
01011         if (file==NULL)
01012                 return UNZ_PARAMERROR;
01013         s=(unz_s*)file;
01014     pfile_in_zip_read_info=s->pfile_in_zip_read;
01015 
01016         if (pfile_in_zip_read_info==NULL)
01017                 return UNZ_PARAMERROR;
01018 
01019 
01020         if ((pfile_in_zip_read_info->read_buffer == NULL))
01021                 return UNZ_END_OF_LIST_OF_FILE;
01022         if (len==0)
01023                 return 0;
01024 
01025         pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
01026 
01027         pfile_in_zip_read_info->stream.avail_out = (uInt)len;
01028         
01029         if (len>pfile_in_zip_read_info->rest_read_uncompressed)
01030                 pfile_in_zip_read_info->stream.avail_out = 
01031                   (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
01032 
01033         while (pfile_in_zip_read_info->stream.avail_out>0)
01034         {
01035                 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
01036             (pfile_in_zip_read_info->rest_read_compressed>0))
01037                 {
01038                         uInt uReadThis = UNZ_BUFSIZE;
01039                         if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
01040                                 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
01041                         if (uReadThis == 0)
01042                                 return UNZ_EOF;
01043                         if (fseek(pfile_in_zip_read_info->file,
01044                       pfile_in_zip_read_info->pos_in_zipfile + 
01045                          pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0)
01046                                 return UNZ_ERRNO;
01047                         if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,
01048                          pfile_in_zip_read_info->file)!=1)
01049                                 return UNZ_ERRNO;
01050                         pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
01051 
01052                         pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
01053                         
01054                         pfile_in_zip_read_info->stream.next_in = 
01055                 (Bytef*)pfile_in_zip_read_info->read_buffer;
01056                         pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
01057                 }
01058 
01059                 if (pfile_in_zip_read_info->compression_method==0)
01060                 {
01061                         uInt uDoCopy,i ;
01062                         if (pfile_in_zip_read_info->stream.avail_out < 
01063                             pfile_in_zip_read_info->stream.avail_in)
01064                                 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
01065                         else
01066                                 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
01067                                 
01068                         for (i=0;i<uDoCopy;i++)
01069                                 *(pfile_in_zip_read_info->stream.next_out+i) =
01070                         *(pfile_in_zip_read_info->stream.next_in+i);
01071                                         
01072                         pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
01073                                                                 pfile_in_zip_read_info->stream.next_out,
01074                                                                 uDoCopy);
01075                         pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
01076                         pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
01077                         pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
01078                         pfile_in_zip_read_info->stream.next_out += uDoCopy;
01079                         pfile_in_zip_read_info->stream.next_in += uDoCopy;
01080             pfile_in_zip_read_info->stream.total_out += uDoCopy;
01081                         iRead += uDoCopy;
01082                 }
01083                 else
01084                 {
01085                         uLong uTotalOutBefore,uTotalOutAfter;
01086                         const Bytef *bufBefore;
01087                         uLong uOutThis;
01088                         int flush=Z_SYNC_FLUSH;
01089 
01090                         uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
01091                         bufBefore = pfile_in_zip_read_info->stream.next_out;
01092 
01093                         /*
01094                         if ((pfile_in_zip_read_info->rest_read_uncompressed ==
01095                                  pfile_in_zip_read_info->stream.avail_out) &&
01096                                 (pfile_in_zip_read_info->rest_read_compressed == 0))
01097                                 flush = Z_FINISH;
01098                         */
01099                         err=inflate(&pfile_in_zip_read_info->stream,flush);
01100 
01101                         uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
01102                         uOutThis = uTotalOutAfter-uTotalOutBefore;
01103                         
01104                         pfile_in_zip_read_info->crc32 = 
01105                 crc32(pfile_in_zip_read_info->crc32,bufBefore,
01106                         (uInt)(uOutThis));
01107 
01108                         pfile_in_zip_read_info->rest_read_uncompressed -=
01109                 uOutThis;
01110 
01111                         iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
01112             
01113                         if (err==Z_STREAM_END)
01114                                 return (iRead==0) ? UNZ_EOF : iRead;
01115                         if (err!=Z_OK) 
01116                                 break;
01117                 }
01118         }
01119 
01120         if (err==Z_OK)
01121                 return iRead;
01122         return err;
01123 }
01124 
01125 
01126 /*
01127   Give the current position in uncompressed data
01128 */
01129 extern z_off_t ZEXPORT unztell (file)
01130         unzFile file;
01131 {
01132         unz_s* s;
01133         file_in_zip_read_info_s* pfile_in_zip_read_info;
01134         if (file==NULL)
01135                 return UNZ_PARAMERROR;
01136         s=(unz_s*)file;
01137     pfile_in_zip_read_info=s->pfile_in_zip_read;
01138 
01139         if (pfile_in_zip_read_info==NULL)
01140                 return UNZ_PARAMERROR;
01141 
01142         return (z_off_t)pfile_in_zip_read_info->stream.total_out;
01143 }
01144 
01145 
01146 /*
01147   return 1 if the end of file was reached, 0 elsewhere 
01148 */
01149 extern int ZEXPORT unzeof (file)
01150         unzFile file;
01151 {
01152         unz_s* s;
01153         file_in_zip_read_info_s* pfile_in_zip_read_info;
01154         if (file==NULL)
01155                 return UNZ_PARAMERROR;
01156         s=(unz_s*)file;
01157     pfile_in_zip_read_info=s->pfile_in_zip_read;
01158 
01159         if (pfile_in_zip_read_info==NULL)
01160                 return UNZ_PARAMERROR;
01161         
01162         if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
01163                 return 1;
01164         else
01165                 return 0;
01166 }
01167 
01168 
01169 
01170 /*
01171   Read extra field from the current file (opened by unzOpenCurrentFile)
01172   This is the local-header version of the extra field (sometimes, there is
01173     more info in the local-header version than in the central-header)
01174 
01175   if buf==NULL, it return the size of the local extra field that can be read
01176 
01177   if buf!=NULL, len is the size of the buffer, the extra header is copied in
01178         buf.
01179   the return value is the number of bytes copied in buf, or (if <0) 
01180         the error code
01181 */
01182 extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
01183         unzFile file;
01184         voidp buf;
01185         unsigned len;
01186 {
01187         unz_s* s;
01188         file_in_zip_read_info_s* pfile_in_zip_read_info;
01189         uInt read_now;
01190         uLong size_to_read;
01191 
01192         if (file==NULL)
01193                 return UNZ_PARAMERROR;
01194         s=(unz_s*)file;
01195     pfile_in_zip_read_info=s->pfile_in_zip_read;
01196 
01197         if (pfile_in_zip_read_info==NULL)
01198                 return UNZ_PARAMERROR;
01199 
01200         size_to_read = (pfile_in_zip_read_info->size_local_extrafield - 
01201                                 pfile_in_zip_read_info->pos_local_extrafield);
01202 
01203         if (buf==NULL)
01204                 return (int)size_to_read;
01205         
01206         if (len>size_to_read)
01207                 read_now = (uInt)size_to_read;
01208         else
01209                 read_now = (uInt)len ;
01210 
01211         if (read_now==0)
01212                 return 0;
01213         
01214         if (fseek(pfile_in_zip_read_info->file,
01215               pfile_in_zip_read_info->offset_local_extrafield + 
01216                           pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0)
01217                 return UNZ_ERRNO;
01218 
01219         if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1)
01220                 return UNZ_ERRNO;
01221 
01222         return (int)read_now;
01223 }
01224 
01225 /*
01226   Close the file in zip opened with unzipOpenCurrentFile
01227   Return UNZ_CRCERROR if all the file was read but the CRC is not good
01228 */
01229 extern int ZEXPORT unzCloseCurrentFile (file)
01230         unzFile file;
01231 {
01232         int err=UNZ_OK;
01233 
01234         unz_s* s;
01235         file_in_zip_read_info_s* pfile_in_zip_read_info;
01236         if (file==NULL)
01237                 return UNZ_PARAMERROR;
01238         s=(unz_s*)file;
01239     pfile_in_zip_read_info=s->pfile_in_zip_read;
01240 
01241         if (pfile_in_zip_read_info==NULL)
01242                 return UNZ_PARAMERROR;
01243 
01244 
01245         if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
01246         {
01247                 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
01248                         err=UNZ_CRCERROR;
01249         }
01250 
01251 
01252         TRYFREE(pfile_in_zip_read_info->read_buffer);
01253         pfile_in_zip_read_info->read_buffer = NULL;
01254         if (pfile_in_zip_read_info->stream_initialised)
01255                 inflateEnd(&pfile_in_zip_read_info->stream);
01256 
01257         pfile_in_zip_read_info->stream_initialised = 0;
01258         TRYFREE(pfile_in_zip_read_info);
01259 
01260     s->pfile_in_zip_read=NULL;
01261 
01262         return err;
01263 }
01264 
01265 
01266 /*
01267   Get the global comment string of the ZipFile, in the szComment buffer.
01268   uSizeBuf is the size of the szComment buffer.
01269   return the number of byte copied or an error code <0
01270 */
01271 extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
01272         unzFile file;
01273         char *szComment;
01274         uLong uSizeBuf;
01275 {
01276 //      int err=UNZ_OK;
01277         unz_s* s;
01278         uLong uReadThis ;
01279         if (file==NULL)
01280                 return UNZ_PARAMERROR;
01281         s=(unz_s*)file;
01282 
01283         uReadThis = uSizeBuf;
01284         if (uReadThis>s->gi.size_comment)
01285                 uReadThis = s->gi.size_comment;
01286 
01287         if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0)
01288                 return UNZ_ERRNO;
01289 
01290         if (uReadThis>0)
01291     {
01292       *szComment='\0';
01293           if (fread(szComment,(uInt)uReadThis,1,s->file)!=1)
01294                 return UNZ_ERRNO;
01295     }
01296 
01297         if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
01298                 *(szComment+s->gi.size_comment)='\0';
01299         return (int)uReadThis;
01300 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends