zip.c

Go to the documentation of this file.
00001 /* zip.c -- IO on .zip files using zlib
00002    Version 1.01e, February 12th, 2005
00003 
00004    27 Dec 2004 Rolf Kalbermatter
00005    Modification to zipOpen2 to support globalComment retrieval.
00006 
00007    Copyright (C) 1998-2005 Gilles Vollant
00008 
00009    Read zip.h for more info
00010 */
00011 
00012 
00013 #include <stdio.h>
00014 #include <stdlib.h>
00015 #include <string.h>
00016 #include <time.h>
00017 #include "zlib.h"
00018 #include "zip.h"
00019 
00020 #ifdef STDC
00021 #  include <stddef.h>
00022 #  include <string.h>
00023 #  include <stdlib.h>
00024 #endif
00025 #ifdef NO_ERRNO_H
00026     extern int errno;
00027 #else
00028 #   include <errno.h>
00029 #endif
00030 
00031 
00032 #ifndef local
00033 #  define local static
00034 #endif
00035 /* compile with -Dlocal if your debugger can't find static symbols */
00036 
00037 #ifndef VERSIONMADEBY
00038 # define VERSIONMADEBY   (0x0) /* platform depedent */
00039 #endif
00040 
00041 #ifndef Z_BUFSIZE
00042 #define Z_BUFSIZE (16384)
00043 #endif
00044 
00045 #ifndef Z_MAXFILENAMEINZIP
00046 #define Z_MAXFILENAMEINZIP (256)
00047 #endif
00048 
00049 #ifndef ALLOC
00050 # define ALLOC(size) (malloc(size))
00051 #endif
00052 #ifndef TRYFREE
00053 # define TRYFREE(p) {if (p) free(p);}
00054 #endif
00055 
00056 /*
00057 #define SIZECENTRALDIRITEM (0x2e)
00058 #define SIZEZIPLOCALHEADER (0x1e)
00059 */
00060 
00061 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
00062 
00063 #ifndef SEEK_CUR
00064 #define SEEK_CUR    1
00065 #endif
00066 
00067 #ifndef SEEK_END
00068 #define SEEK_END    2
00069 #endif
00070 
00071 #ifndef SEEK_SET
00072 #define SEEK_SET    0
00073 #endif
00074 
00075 #ifndef DEF_MEM_LEVEL
00076 #if MAX_MEM_LEVEL >= 8
00077 #  define DEF_MEM_LEVEL 8
00078 #else
00079 #  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
00080 #endif
00081 #endif
00082 const char zip_copyright[] =
00083    " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
00084 
00085 
00086 #define SIZEDATA_INDATABLOCK (4096-(4*4))
00087 
00088 #define LOCALHEADERMAGIC    (0x04034b50)
00089 #define CENTRALHEADERMAGIC  (0x02014b50)
00090 #define ENDHEADERMAGIC      (0x06054b50)
00091 
00092 #define FLAG_LOCALHEADER_OFFSET (0x06)
00093 #define CRC_LOCALHEADER_OFFSET  (0x0e)
00094 
00095 #define SIZECENTRALHEADER (0x2e) /* 46 */
00096 
00097 typedef struct linkedlist_datablock_internal_s
00098 {
00099   struct linkedlist_datablock_internal_s* next_datablock;
00100   uLong  avail_in_this_block;
00101   uLong  filled_in_this_block;
00102   uLong  unused; /* for future use and alignement */
00103   unsigned char data[SIZEDATA_INDATABLOCK];
00104 } linkedlist_datablock_internal;
00105 
00106 typedef struct linkedlist_data_s
00107 {
00108     linkedlist_datablock_internal* first_block;
00109     linkedlist_datablock_internal* last_block;
00110 } linkedlist_data;
00111 
00112 
00113 typedef struct
00114 {
00115     z_stream stream;            /* zLib stream structure for inflate */
00116     int  stream_initialised;    /* 1 is stream is initialised */
00117     uInt pos_in_buffered_data;  /* last written byte in buffered_data */
00118 
00119     uLong pos_local_header;     /* offset of the local header of the file
00120                                      currenty writing */
00121     char* central_header;       /* central header data for the current file */
00122     uLong size_centralheader;   /* size of the central header for cur file */
00123     uLong flag;                 /* flag of the file currently writing */
00124 
00125     int  method;                /* compression method of file currenty wr.*/
00126     int  raw;                   /* 1 for directly writing raw data */
00127     Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
00128     uLong dosDate;
00129     uLong crc32;
00130     int  encrypt;
00131 #ifndef NOCRYPT
00132     unsigned long keys[3];     /* keys defining the pseudo-random sequence */
00133     const unsigned long* pcrc_32_tab;
00134     int crypt_header_size;
00135 #endif
00136 } curfile_info;
00137 
00138 typedef struct
00139 {
00140     zlib_filefunc_def z_filefunc;
00141     voidpf filestream;        /* io structore of the zipfile */
00142     linkedlist_data central_dir;/* datablock with central dir in construction*/
00143     int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/
00144     curfile_info ci;            /* info on the file curretly writing */
00145 
00146     uLong begin_pos;            /* position of the beginning of the zipfile */
00147     uLong add_position_when_writting_offset;
00148     uLong number_entry;
00149 #ifndef NO_ADDFILEINEXISTINGZIP
00150     char *globalcomment;
00151 #endif
00152 } zip_internal;
00153 
00154 
00155 
00156 #ifndef NOCRYPT
00157 #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
00158 #include "crypt.h"
00159 #endif
00160 
00161 local linkedlist_datablock_internal* allocate_new_datablock()
00162 {
00163     linkedlist_datablock_internal* ldi;
00164     ldi = (linkedlist_datablock_internal*)
00165                  ALLOC(sizeof(linkedlist_datablock_internal));
00166     if (ldi!=NULL)
00167     {
00168         ldi->next_datablock = NULL ;
00169         ldi->filled_in_this_block = 0 ;
00170         ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
00171     }
00172     return ldi;
00173 }
00174 
00175 local void free_datablock(ldi)
00176     linkedlist_datablock_internal* ldi;
00177 {
00178     while (ldi!=NULL)
00179     {
00180         linkedlist_datablock_internal* ldinext = ldi->next_datablock;
00181         TRYFREE(ldi);
00182         ldi = ldinext;
00183     }
00184 }
00185 
00186 local void init_linkedlist(ll)
00187     linkedlist_data* ll;
00188 {
00189     ll->first_block = ll->last_block = NULL;
00190 }
00191 
00192 local void free_linkedlist(ll)
00193     linkedlist_data* ll;
00194 {
00195     free_datablock(ll->first_block);
00196     ll->first_block = ll->last_block = NULL;
00197 }
00198 
00199 
00200 local int add_data_in_datablock(ll,buf,len)
00201     linkedlist_data* ll;
00202     const void* buf;
00203     uLong len;
00204 {
00205     linkedlist_datablock_internal* ldi;
00206     const unsigned char* from_copy;
00207 
00208     if (ll==NULL)
00209         return ZIP_INTERNALERROR;
00210 
00211     if (ll->last_block == NULL)
00212     {
00213         ll->first_block = ll->last_block = allocate_new_datablock();
00214         if (ll->first_block == NULL)
00215             return ZIP_INTERNALERROR;
00216     }
00217 
00218     ldi = ll->last_block;
00219     from_copy = (unsigned char*)buf;
00220 
00221     while (len>0)
00222     {
00223         uInt copy_this;
00224         uInt i;
00225         unsigned char* to_copy;
00226 
00227         if (ldi->avail_in_this_block==0)
00228         {
00229             ldi->next_datablock = allocate_new_datablock();
00230             if (ldi->next_datablock == NULL)
00231                 return ZIP_INTERNALERROR;
00232             ldi = ldi->next_datablock ;
00233             ll->last_block = ldi;
00234         }
00235 
00236         if (ldi->avail_in_this_block < len)
00237             copy_this = (uInt)ldi->avail_in_this_block;
00238         else
00239             copy_this = (uInt)len;
00240 
00241         to_copy = &(ldi->data[ldi->filled_in_this_block]);
00242 
00243         for (i=0;i<copy_this;i++)
00244             *(to_copy+i)=*(from_copy+i);
00245 
00246         ldi->filled_in_this_block += copy_this;
00247         ldi->avail_in_this_block -= copy_this;
00248         from_copy += copy_this ;
00249         len -= copy_this;
00250     }
00251     return ZIP_OK;
00252 }
00253 
00254 
00255 
00256 /****************************************************************************/
00257 
00258 #ifndef NO_ADDFILEINEXISTINGZIP
00259 /* ===========================================================================
00260    Inputs a long in LSB order to the given file
00261    nbByte == 1, 2 or 4 (byte, short or long)
00262 */
00263 
00264 local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def,
00265                                 voidpf filestream, uLong x, int nbByte));
00266 local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte)
00267     const zlib_filefunc_def* pzlib_filefunc_def;
00268     voidpf filestream;
00269     uLong x;
00270     int nbByte;
00271 {
00272     unsigned char buf[4];
00273     int n;
00274     for (n = 0; n < nbByte; n++)
00275     {
00276         buf[n] = (unsigned char)(x & 0xff);
00277         x >>= 8;
00278     }
00279     if (x != 0)
00280       {     /* data overflow - hack for ZIP64 (X Roche) */
00281       for (n = 0; n < nbByte; n++)
00282         {
00283           buf[n] = 0xff;
00284         }
00285       }
00286 
00287     if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
00288         return ZIP_ERRNO;
00289     else
00290         return ZIP_OK;
00291 }
00292 
00293 local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
00294 local void ziplocal_putValue_inmemory (dest, x, nbByte)
00295     void* dest;
00296     uLong x;
00297     int nbByte;
00298 {
00299     unsigned char* buf=(unsigned char*)dest;
00300     int n;
00301     for (n = 0; n < nbByte; n++) {
00302         buf[n] = (unsigned char)(x & 0xff);
00303         x >>= 8;
00304     }
00305 
00306     if (x != 0)
00307     {     /* data overflow - hack for ZIP64 */
00308        for (n = 0; n < nbByte; n++)
00309        {
00310           buf[n] = 0xff;
00311        }
00312     }
00313 }
00314 
00315 /****************************************************************************/
00316 
00317 
00318 local uLong ziplocal_TmzDateToDosDate(ptm,dosDate)
00319     const tm_zip* ptm;
00320     uLong dosDate;
00321 {
00322     uLong year = (uLong)ptm->tm_year;
00323     if (year>1980)
00324         year-=1980;
00325     else if (year>80)
00326         year-=80;
00327     return
00328       (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
00329         ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
00330 }
00331 
00332 
00333 /****************************************************************************/
00334 
00335 local int ziplocal_getByte OF((
00336     const zlib_filefunc_def* pzlib_filefunc_def,
00337     voidpf filestream,
00338     int *pi));
00339 
00340 local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi)
00341     const zlib_filefunc_def* pzlib_filefunc_def;
00342     voidpf filestream;
00343     int *pi;
00344 {
00345     unsigned char c;
00346     int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
00347     if (err==1)
00348     {
00349         *pi = (int)c;
00350         return ZIP_OK;
00351     }
00352     else
00353     {
00354         if (ZERROR(*pzlib_filefunc_def,filestream))
00355             return ZIP_ERRNO;
00356         else
00357             return ZIP_EOF;
00358     }
00359 }
00360 
00361 
00362 /* ===========================================================================
00363    Reads a long in LSB order from the given gz_stream. Sets
00364 */
00365 local int ziplocal_getShort OF((
00366     const zlib_filefunc_def* pzlib_filefunc_def,
00367     voidpf filestream,
00368     uLong *pX));
00369 
00370 local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX)
00371     const zlib_filefunc_def* pzlib_filefunc_def;
00372     voidpf filestream;
00373     uLong *pX;
00374 {
00375     uLong x ;
00376     int i;
00377     int err;
00378 
00379     err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
00380     x = (uLong)i;
00381 
00382     if (err==ZIP_OK)
00383         err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
00384     x += ((uLong)i)<<8;
00385 
00386     if (err==ZIP_OK)
00387         *pX = x;
00388     else
00389         *pX = 0;
00390     return err;
00391 }
00392 
00393 local int ziplocal_getLong OF((
00394     const zlib_filefunc_def* pzlib_filefunc_def,
00395     voidpf filestream,
00396     uLong *pX));
00397 
00398 local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX)
00399     const zlib_filefunc_def* pzlib_filefunc_def;
00400     voidpf filestream;
00401     uLong *pX;
00402 {
00403     uLong x ;
00404     int i;
00405     int err;
00406 
00407     err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
00408     x = (uLong)i;
00409 
00410     if (err==ZIP_OK)
00411         err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
00412     x += ((uLong)i)<<8;
00413 
00414     if (err==ZIP_OK)
00415         err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
00416     x += ((uLong)i)<<16;
00417 
00418     if (err==ZIP_OK)
00419         err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
00420     x += ((uLong)i)<<24;
00421 
00422     if (err==ZIP_OK)
00423         *pX = x;
00424     else
00425         *pX = 0;
00426     return err;
00427 }
00428 
00429 #ifndef BUFREADCOMMENT
00430 #define BUFREADCOMMENT (0x400)
00431 #endif
00432 /*
00433   Locate the Central directory of a zipfile (at the end, just before
00434     the global comment)
00435 */
00436 local uLong ziplocal_SearchCentralDir OF((
00437     const zlib_filefunc_def* pzlib_filefunc_def,
00438     voidpf filestream));
00439 
00440 local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream)
00441     const zlib_filefunc_def* pzlib_filefunc_def;
00442     voidpf filestream;
00443 {
00444     unsigned char* buf;
00445     uLong uSizeFile;
00446     uLong uBackRead;
00447     uLong uMaxBack=0xffff; /* maximum size of global comment */
00448     uLong uPosFound=0;
00449 
00450     if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
00451         return 0;
00452 
00453 
00454     uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
00455 
00456     if (uMaxBack>uSizeFile)
00457         uMaxBack = uSizeFile;
00458 
00459     buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
00460     if (buf==NULL)
00461         return 0;
00462 
00463     uBackRead = 4;
00464     while (uBackRead<uMaxBack)
00465     {
00466         uLong uReadSize,uReadPos ;
00467         int i;
00468         if (uBackRead+BUFREADCOMMENT>uMaxBack)
00469             uBackRead = uMaxBack;
00470         else
00471             uBackRead+=BUFREADCOMMENT;
00472         uReadPos = uSizeFile-uBackRead ;
00473 
00474         uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
00475                      (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
00476         if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
00477             break;
00478 
00479         if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
00480             break;
00481 
00482         for (i=(int)uReadSize-3; (i--)>0;)
00483             if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
00484                 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
00485             {
00486                 uPosFound = uReadPos+i;
00487                 break;
00488             }
00489 
00490         if (uPosFound!=0)
00491             break;
00492     }
00493     TRYFREE(buf);
00494     return uPosFound;
00495 }
00496 #endif /* !NO_ADDFILEINEXISTINGZIP*/
00497 
00498 /************************************************************/
00499 extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def)
00500     const char *pathname;
00501     int append;
00502     zipcharpc* globalcomment;
00503     zlib_filefunc_def* pzlib_filefunc_def;
00504 {
00505     zip_internal ziinit;
00506     zip_internal* zi;
00507     int err=ZIP_OK;
00508 
00509 
00510     if (pzlib_filefunc_def==NULL)
00511         fill_fopen_filefunc(&ziinit.z_filefunc);
00512     else
00513         ziinit.z_filefunc = *pzlib_filefunc_def;
00514 
00515     ziinit.filestream = (*(ziinit.z_filefunc.zopen_file))
00516                  (ziinit.z_filefunc.opaque,
00517                   pathname,
00518                   (append == APPEND_STATUS_CREATE) ?
00519                   (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
00520                     (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
00521 
00522     if (ziinit.filestream == NULL)
00523         return NULL;
00524     ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream);
00525     ziinit.in_opened_file_inzip = 0;
00526     ziinit.ci.stream_initialised = 0;
00527     ziinit.number_entry = 0;
00528     ziinit.add_position_when_writting_offset = 0;
00529     init_linkedlist(&(ziinit.central_dir));
00530 
00531 
00532     zi = (zip_internal*)ALLOC(sizeof(zip_internal));
00533     if (zi==NULL)
00534     {
00535         ZCLOSE(ziinit.z_filefunc,ziinit.filestream);
00536         return NULL;
00537     }
00538 
00539     /* now we add file in a zipfile */
00540 #    ifndef NO_ADDFILEINEXISTINGZIP
00541     ziinit.globalcomment = NULL;
00542     if (append == APPEND_STATUS_ADDINZIP)
00543     {
00544         uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
00545 
00546         uLong size_central_dir;     /* size of the central directory  */
00547         uLong offset_central_dir;   /* offset of start of central directory */
00548         uLong central_pos,uL;
00549 
00550         uLong number_disk;          /* number of the current dist, used for
00551                                     spaning ZIP, unsupported, always 0*/
00552         uLong number_disk_with_CD;  /* number the the disk with central dir, used
00553                                     for spaning ZIP, unsupported, always 0*/
00554         uLong number_entry;
00555         uLong number_entry_CD;      /* total number of entries in
00556                                     the central dir
00557                                     (same than number_entry on nospan) */
00558         uLong size_comment;
00559 
00560         central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);
00561         if (central_pos==0)
00562             err=ZIP_ERRNO;
00563 
00564         if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
00565                                         central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
00566             err=ZIP_ERRNO;
00567 
00568         /* the signature, already checked */
00569         if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK)
00570             err=ZIP_ERRNO;
00571 
00572         /* number of this disk */
00573         if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK)
00574             err=ZIP_ERRNO;
00575 
00576         /* number of the disk with the start of the central directory */
00577         if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK)
00578             err=ZIP_ERRNO;
00579 
00580         /* total number of entries in the central dir on this disk */
00581         if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK)
00582             err=ZIP_ERRNO;
00583 
00584         /* total number of entries in the central dir */
00585         if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK)
00586             err=ZIP_ERRNO;
00587 
00588         if ((number_entry_CD!=number_entry) ||
00589             (number_disk_with_CD!=0) ||
00590             (number_disk!=0))
00591             err=ZIP_BADZIPFILE;
00592 
00593         /* size of the central directory */
00594         if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK)
00595             err=ZIP_ERRNO;
00596 
00597         /* offset of start of central directory with respect to the
00598             starting disk number */
00599         if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK)
00600             err=ZIP_ERRNO;
00601 
00602         /* zipfile global comment length */
00603         if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK)
00604             err=ZIP_ERRNO;
00605 
00606         if ((central_pos<offset_central_dir+size_central_dir) &&
00607             (err==ZIP_OK))
00608             err=ZIP_BADZIPFILE;
00609 
00610         if (err!=ZIP_OK)
00611         {
00612             ZCLOSE(ziinit.z_filefunc, ziinit.filestream);
00613             return NULL;
00614         }
00615 
00616         if (size_comment>0)
00617         {
00618             ziinit.globalcomment = ALLOC(size_comment+1);
00619             if (ziinit.globalcomment)
00620             {
00621                size_comment = ZREAD(ziinit.z_filefunc, ziinit.filestream,ziinit.globalcomment,size_comment);
00622                ziinit.globalcomment[size_comment]=0;
00623             }
00624         }
00625 
00626         byte_before_the_zipfile = central_pos -
00627                                 (offset_central_dir+size_central_dir);
00628         ziinit.add_position_when_writting_offset = byte_before_the_zipfile;
00629 
00630         {
00631             uLong size_central_dir_to_read = size_central_dir;
00632             size_t buf_size = SIZEDATA_INDATABLOCK;
00633             void* buf_read = (void*)ALLOC(buf_size);
00634             if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
00635                   offset_central_dir + byte_before_the_zipfile,
00636                   ZLIB_FILEFUNC_SEEK_SET) != 0)
00637                   err=ZIP_ERRNO;
00638 
00639             while ((size_central_dir_to_read>0) && (err==ZIP_OK))
00640             {
00641                 uLong read_this = SIZEDATA_INDATABLOCK;
00642                 if (read_this > size_central_dir_to_read)
00643                     read_this = size_central_dir_to_read;
00644                 if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this)
00645                     err=ZIP_ERRNO;
00646 
00647                 if (err==ZIP_OK)
00648                     err = add_data_in_datablock(&ziinit.central_dir,buf_read,
00649                                                 (uLong)read_this);
00650                 size_central_dir_to_read-=read_this;
00651             }
00652             TRYFREE(buf_read);
00653         }
00654         ziinit.begin_pos = byte_before_the_zipfile;
00655         ziinit.number_entry = number_entry_CD;
00656 
00657         if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
00658                   offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
00659             err=ZIP_ERRNO;
00660     }
00661 
00662     if (globalcomment)
00663     {
00664       *globalcomment = ziinit.globalcomment;
00665     }
00666 #    endif /* !NO_ADDFILEINEXISTINGZIP*/
00667 
00668     if (err != ZIP_OK)
00669     {
00670 #    ifndef NO_ADDFILEINEXISTINGZIP
00671         TRYFREE(ziinit.globalcomment);
00672 #    endif /* !NO_ADDFILEINEXISTINGZIP*/
00673         TRYFREE(zi);
00674         return NULL;
00675     }
00676     else
00677     {
00678         *zi = ziinit;
00679         return (zipFile)zi;
00680     }
00681 }
00682 
00683 extern zipFile ZEXPORT zipOpen (pathname, append)
00684     const char *pathname;
00685     int append;
00686 {
00687     return zipOpen2(pathname,append,NULL,NULL);
00688 }
00689 
00690 extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi,
00691                                          extrafield_local, size_extrafield_local,
00692                                          extrafield_global, size_extrafield_global,
00693                                          comment, method, level, raw,
00694                                          windowBits, memLevel, strategy,
00695                                          password, crcForCrypting)
00696     zipFile file;
00697     const char* filename;
00698     const zip_fileinfo* zipfi;
00699     const void* extrafield_local;
00700     uInt size_extrafield_local;
00701     const void* extrafield_global;
00702     uInt size_extrafield_global;
00703     const char* comment;
00704     int method;
00705     int level;
00706     int raw;
00707     int windowBits;
00708     int memLevel;
00709     int strategy;
00710     const char* password;
00711     uLong crcForCrypting;
00712 {
00713     zip_internal* zi;
00714     uInt size_filename;
00715     uInt size_comment;
00716     uInt i;
00717     int err = ZIP_OK;
00718 
00719 #    ifdef NOCRYPT
00720     if (password != NULL)
00721         return ZIP_PARAMERROR;
00722 #    endif
00723 
00724     if (file == NULL)
00725         return ZIP_PARAMERROR;
00726     if ((method!=0) && (method!=Z_DEFLATED))
00727         return ZIP_PARAMERROR;
00728 
00729     zi = (zip_internal*)file;
00730 
00731     if (zi->in_opened_file_inzip == 1)
00732     {
00733         err = zipCloseFileInZip (file);
00734         if (err != ZIP_OK)
00735             return err;
00736     }
00737 
00738 
00739     if (filename==NULL)
00740         filename="-";
00741 
00742     if (comment==NULL)
00743         size_comment = 0;
00744     else
00745         size_comment = (uInt)strlen(comment);
00746 
00747     size_filename = (uInt)strlen(filename);
00748 
00749     if (zipfi == NULL)
00750         zi->ci.dosDate = 0;
00751     else
00752     {
00753         if (zipfi->dosDate != 0)
00754             zi->ci.dosDate = zipfi->dosDate;
00755         else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
00756     }
00757 
00758     zi->ci.flag = 0;
00759     if ((level==8) || (level==9))
00760       zi->ci.flag |= 2;
00761     if ((level==2))
00762       zi->ci.flag |= 4;
00763     if ((level==1))
00764       zi->ci.flag |= 6;
00765     if (password != NULL)
00766       zi->ci.flag |= 1;
00767 
00768     zi->ci.crc32 = 0;
00769     zi->ci.method = method;
00770     zi->ci.encrypt = 0;
00771     zi->ci.stream_initialised = 0;
00772     zi->ci.pos_in_buffered_data = 0;
00773     zi->ci.raw = raw;
00774     zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ;
00775     zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
00776                                       size_extrafield_global + size_comment;
00777     zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
00778 
00779     ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
00780     /* version info */
00781     ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
00782     ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
00783     ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
00784     ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
00785     ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
00786     ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
00787     ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
00788     ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
00789     ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
00790     ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
00791     ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
00792     ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
00793 
00794     if (zipfi==NULL)
00795         ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
00796     else
00797         ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
00798 
00799     if (zipfi==NULL)
00800         ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
00801     else
00802         ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
00803 
00804     ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);
00805 
00806     for (i=0;i<size_filename;i++)
00807         *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
00808 
00809     for (i=0;i<size_extrafield_global;i++)
00810         *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
00811               *(((const char*)extrafield_global)+i);
00812 
00813     for (i=0;i<size_comment;i++)
00814         *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
00815               size_extrafield_global+i) = *(comment+i);
00816     if (zi->ci.central_header == NULL)
00817         return ZIP_INTERNALERROR;
00818 
00819     /* write the local header */
00820     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);
00821 
00822     if (err==ZIP_OK)
00823         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
00824     if (err==ZIP_OK)
00825         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
00826 
00827     if (err==ZIP_OK)
00828         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
00829 
00830     if (err==ZIP_OK)
00831         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
00832 
00833     if (err==ZIP_OK)
00834         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
00835     if (err==ZIP_OK)
00836         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
00837     if (err==ZIP_OK)
00838         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
00839 
00840     if (err==ZIP_OK)
00841         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
00842 
00843     if (err==ZIP_OK)
00844         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);
00845 
00846     if ((err==ZIP_OK) && (size_filename>0))
00847         if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
00848                 err = ZIP_ERRNO;
00849 
00850     if ((err==ZIP_OK) && (size_extrafield_local>0))
00851         if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local)
00852                                                                            !=size_extrafield_local)
00853                 err = ZIP_ERRNO;
00854 
00855     zi->ci.stream.avail_in = (uInt)0;
00856     zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
00857     zi->ci.stream.next_out = zi->ci.buffered_data;
00858     zi->ci.stream.total_in = 0;
00859     zi->ci.stream.total_out = 0;
00860 
00861     if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
00862     {
00863         zi->ci.stream.zalloc = (alloc_func)0;
00864         zi->ci.stream.zfree = (free_func)0;
00865         zi->ci.stream.opaque = (voidpf)0;
00866 
00867         if (windowBits>0)
00868             windowBits = -windowBits;
00869 
00870         err = deflateInit2(&zi->ci.stream, level,
00871                Z_DEFLATED, windowBits, memLevel, strategy);
00872 
00873         if (err==Z_OK)
00874             zi->ci.stream_initialised = 1;
00875     }
00876 #    ifndef NOCRYPT
00877     zi->ci.crypt_header_size = 0;
00878     if ((err==Z_OK) && (password != NULL))
00879     {
00880         unsigned char bufHead[RAND_HEAD_LEN];
00881         unsigned int sizeHead;
00882         zi->ci.encrypt = 1;
00883         zi->ci.pcrc_32_tab = get_crc_table();
00884         /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
00885 
00886         sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
00887         zi->ci.crypt_header_size = sizeHead;
00888 
00889         if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
00890                 err = ZIP_ERRNO;
00891     }
00892 #    endif
00893 
00894     if (err==Z_OK)
00895         zi->in_opened_file_inzip = 1;
00896     return err;
00897 }
00898 
00899 extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi,
00900                                         extrafield_local, size_extrafield_local,
00901                                         extrafield_global, size_extrafield_global,
00902                                         comment, method, level, raw)
00903     zipFile file;
00904     const char* filename;
00905     const zip_fileinfo* zipfi;
00906     const void* extrafield_local;
00907     uInt size_extrafield_local;
00908     const void* extrafield_global;
00909     uInt size_extrafield_global;
00910     const char* comment;
00911     int method;
00912     int level;
00913     int raw;
00914 {
00915     return zipOpenNewFileInZip3 (file, filename, zipfi,
00916                                  extrafield_local, size_extrafield_local,
00917                                  extrafield_global, size_extrafield_global,
00918                                  comment, method, level, raw,
00919                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
00920                                  NULL, 0);
00921 }
00922 
00923 extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi,
00924                                         extrafield_local, size_extrafield_local,
00925                                         extrafield_global, size_extrafield_global,
00926                                         comment, method, level)
00927     zipFile file;
00928     const char* filename;
00929     const zip_fileinfo* zipfi;
00930     const void* extrafield_local;
00931     uInt size_extrafield_local;
00932     const void* extrafield_global;
00933     uInt size_extrafield_global;
00934     const char* comment;
00935     int method;
00936     int level;
00937 {
00938     return zipOpenNewFileInZip2 (file, filename, zipfi,
00939                                  extrafield_local, size_extrafield_local,
00940                                  extrafield_global, size_extrafield_global,
00941                                  comment, method, level, 0);
00942 }
00943 
00944 local int zipFlushWriteBuffer(zi)
00945   zip_internal* zi;
00946 {
00947     int err=ZIP_OK;
00948 
00949     if (zi->ci.encrypt != 0)
00950     {
00951 #ifndef NOCRYPT
00952         uInt i;
00953         int t;
00954         for (i=0;i<zi->ci.pos_in_buffered_data;i++)
00955             zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab,
00956                                        zi->ci.buffered_data[i],t);
00957 #endif
00958     }
00959     if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data)
00960                                                                     !=zi->ci.pos_in_buffered_data)
00961       err = ZIP_ERRNO;
00962     zi->ci.pos_in_buffered_data = 0;
00963     return err;
00964 }
00965 
00966 extern int ZEXPORT zipWriteInFileInZip (file, buf, len)
00967     zipFile file;
00968     const void* buf;
00969     unsigned len;
00970 {
00971     zip_internal* zi;
00972     int err=ZIP_OK;
00973 
00974     if (file == NULL)
00975         return ZIP_PARAMERROR;
00976     zi = (zip_internal*)file;
00977 
00978     if (zi->in_opened_file_inzip == 0)
00979         return ZIP_PARAMERROR;
00980 
00981     zi->ci.stream.next_in = (void*)buf;
00982     zi->ci.stream.avail_in = len;
00983     zi->ci.crc32 = crc32(zi->ci.crc32,buf,len);
00984 
00985     while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
00986     {
00987         if (zi->ci.stream.avail_out == 0)
00988         {
00989             if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
00990                 err = ZIP_ERRNO;
00991             zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
00992             zi->ci.stream.next_out = zi->ci.buffered_data;
00993         }
00994 
00995 
00996         if(err != ZIP_OK)
00997             break;
00998 
00999         if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
01000         {
01001             uLong uTotalOutBefore = zi->ci.stream.total_out;
01002             err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
01003             zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
01004 
01005         }
01006         else
01007         {
01008             uInt copy_this,i;
01009             if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
01010                 copy_this = zi->ci.stream.avail_in;
01011             else
01012                 copy_this = zi->ci.stream.avail_out;
01013             for (i=0;i<copy_this;i++)
01014                 *(((char*)zi->ci.stream.next_out)+i) =
01015                     *(((const char*)zi->ci.stream.next_in)+i);
01016             {
01017                 zi->ci.stream.avail_in -= copy_this;
01018                 zi->ci.stream.avail_out-= copy_this;
01019                 zi->ci.stream.next_in+= copy_this;
01020                 zi->ci.stream.next_out+= copy_this;
01021                 zi->ci.stream.total_in+= copy_this;
01022                 zi->ci.stream.total_out+= copy_this;
01023                 zi->ci.pos_in_buffered_data += copy_this;
01024             }
01025         }
01026     }
01027 
01028     return err;
01029 }
01030 
01031 extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32)
01032     zipFile file;
01033     uLong uncompressed_size;
01034     uLong crc32;
01035 {
01036     zip_internal* zi;
01037     uLong compressed_size;
01038     int err=ZIP_OK;
01039 
01040     if (file == NULL)
01041         return ZIP_PARAMERROR;
01042     zi = (zip_internal*)file;
01043 
01044     if (zi->in_opened_file_inzip == 0)
01045         return ZIP_PARAMERROR;
01046     zi->ci.stream.avail_in = 0;
01047 
01048     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
01049         while (err==ZIP_OK)
01050     {
01051         uLong uTotalOutBefore;
01052         if (zi->ci.stream.avail_out == 0)
01053         {
01054             if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
01055                 err = ZIP_ERRNO;
01056             zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
01057             zi->ci.stream.next_out = zi->ci.buffered_data;
01058         }
01059         uTotalOutBefore = zi->ci.stream.total_out;
01060         err=deflate(&zi->ci.stream,  Z_FINISH);
01061         zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
01062     }
01063 
01064     if (err==Z_STREAM_END)
01065         err=ZIP_OK; /* this is normal */
01066 
01067     if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
01068         if (zipFlushWriteBuffer(zi)==ZIP_ERRNO)
01069             err = ZIP_ERRNO;
01070 
01071     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
01072     {
01073         err=deflateEnd(&zi->ci.stream);
01074         zi->ci.stream_initialised = 0;
01075     }
01076 
01077     if (!zi->ci.raw)
01078     {
01079         crc32 = (uLong)zi->ci.crc32;
01080         uncompressed_size = (uLong)zi->ci.stream.total_in;
01081     }
01082     compressed_size = (uLong)zi->ci.stream.total_out;
01083 #    ifndef NOCRYPT
01084     compressed_size += zi->ci.crypt_header_size;
01085 #    endif
01086 
01087     ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
01088     ziplocal_putValue_inmemory(zi->ci.central_header+20,
01089                                 compressed_size,4); /*compr size*/
01090     if (zi->ci.stream.data_type == Z_ASCII)
01091         ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
01092     ziplocal_putValue_inmemory(zi->ci.central_header+24,
01093                                 uncompressed_size,4); /*uncompr size*/
01094 
01095     if (err==ZIP_OK)
01096         err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
01097                                        (uLong)zi->ci.size_centralheader);
01098     free(zi->ci.central_header);
01099 
01100     if (err==ZIP_OK)
01101     {
01102         long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
01103         if (ZSEEK(zi->z_filefunc,zi->filestream,
01104                   zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
01105             err = ZIP_ERRNO;
01106 
01107         if (err==ZIP_OK)
01108             err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
01109 
01110         if (err==ZIP_OK) /* compressed size, unknown */
01111             err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
01112 
01113         if (err==ZIP_OK) /* uncompressed size, unknown */
01114             err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
01115 
01116         if (ZSEEK(zi->z_filefunc,zi->filestream,
01117                   cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
01118             err = ZIP_ERRNO;
01119     }
01120 
01121     zi->number_entry ++;
01122     zi->in_opened_file_inzip = 0;
01123 
01124     return err;
01125 }
01126 
01127 extern int ZEXPORT zipCloseFileInZip (file)
01128     zipFile file;
01129 {
01130     return zipCloseFileInZipRaw (file,0,0);
01131 }
01132 
01133 extern int ZEXPORT zipClose (file, global_comment)
01134     zipFile file;
01135     const char* global_comment;
01136 {
01137     zip_internal* zi;
01138     int err = 0;
01139     uLong size_centraldir = 0;
01140     uLong centraldir_pos_inzip;
01141     uInt size_global_comment;
01142     if (file == NULL)
01143         return ZIP_PARAMERROR;
01144     zi = (zip_internal*)file;
01145 
01146     if (zi->in_opened_file_inzip == 1)
01147     {
01148         err = zipCloseFileInZip (file);
01149     }
01150 
01151 #ifndef NO_ADDFILEINEXISTINGZIP
01152     if (global_comment==NULL)
01153         global_comment = zi->globalcomment;
01154 #endif
01155     if (global_comment==NULL)
01156         size_global_comment = 0;
01157     else
01158         size_global_comment = (uInt)strlen(global_comment);
01159 
01160     centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
01161     if (err==ZIP_OK)
01162     {
01163         linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
01164         while (ldi!=NULL)
01165         {
01166             if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
01167                 if (ZWRITE(zi->z_filefunc,zi->filestream,
01168                            ldi->data,ldi->filled_in_this_block)
01169                               !=ldi->filled_in_this_block )
01170                     err = ZIP_ERRNO;
01171 
01172             size_centraldir += ldi->filled_in_this_block;
01173             ldi = ldi->next_datablock;
01174         }
01175     }
01176     free_datablock(zi->central_dir.first_block);
01177 
01178     if (err==ZIP_OK) /* Magic End */
01179         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
01180 
01181     if (err==ZIP_OK) /* number of this disk */
01182         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
01183 
01184     if (err==ZIP_OK) /* number of the disk with the start of the central directory */
01185         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
01186 
01187     if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
01188         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
01189 
01190     if (err==ZIP_OK) /* total number of entries in the central dir */
01191         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
01192 
01193     if (err==ZIP_OK) /* size of the central directory */
01194         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
01195 
01196     if (err==ZIP_OK) /* offset of start of central directory with respect to the
01197                             starting disk number */
01198         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,
01199                                 (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
01200 
01201     if (err==ZIP_OK) /* zipfile comment length */
01202         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
01203 
01204     if ((err==ZIP_OK) && (size_global_comment>0))
01205         if (ZWRITE(zi->z_filefunc,zi->filestream,
01206                    global_comment,size_global_comment) != size_global_comment)
01207                 err = ZIP_ERRNO;
01208 
01209     if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0)
01210         if (err == ZIP_OK)
01211             err = ZIP_ERRNO;
01212 
01213 #ifndef NO_ADDFILEINEXISTINGZIP
01214     TRYFREE(zi->globalcomment);
01215 #endif
01216     TRYFREE(zi);
01217 
01218     return err;
01219 }

Generated on Fri Apr 14 22:57:28 2006 for minix by  doxygen 1.4.6