misc/quazip/zip.c
changeset 8057 93e16240f178
parent 8051 f26422ef0333
parent 8055 04dd8b7fb605
child 8058 bcebfc477459
equal deleted inserted replaced
8051:f26422ef0333 8057:93e16240f178
     1 /* zip.c -- IO on .zip files using zlib
       
     2    Version 1.01e, February 12th, 2005
       
     3 
       
     4    27 Dec 2004 Rolf Kalbermatter
       
     5    Modification to zipOpen2 to support globalComment retrieval.
       
     6 
       
     7    Copyright (C) 1998-2005 Gilles Vollant
       
     8 
       
     9    Read zip.h for more info
       
    10 
       
    11    Modified by Sergey A. Tachenov to integrate with Qt.
       
    12 */
       
    13 
       
    14 
       
    15 #include <stdio.h>
       
    16 #include <stdlib.h>
       
    17 #include <string.h>
       
    18 #include <time.h>
       
    19 #include "zlib.h"
       
    20 #include "zip.h"
       
    21 #include "quazip_global.h"
       
    22 
       
    23 #ifdef STDC
       
    24 #  include <stddef.h>
       
    25 #  include <string.h>
       
    26 #  include <stdlib.h>
       
    27 #endif
       
    28 #ifdef NO_ERRNO_H
       
    29     extern int errno;
       
    30 #else
       
    31 #   include <errno.h>
       
    32 #endif
       
    33 
       
    34 
       
    35 #ifndef local
       
    36 #  define local static
       
    37 #endif
       
    38 /* compile with -Dlocal if your debugger can't find static symbols */
       
    39 
       
    40 #ifndef VERSIONMADEBY
       
    41 # define VERSIONMADEBY   (0x031e) /* best for standard pkware crypt */
       
    42 #endif
       
    43 
       
    44 #ifndef Z_BUFSIZE
       
    45 #define Z_BUFSIZE (16384)
       
    46 #endif
       
    47 
       
    48 #ifndef Z_MAXFILENAMEINZIP
       
    49 #define Z_MAXFILENAMEINZIP (256)
       
    50 #endif
       
    51 
       
    52 #ifndef ALLOC
       
    53 # define ALLOC(size) (malloc(size))
       
    54 #endif
       
    55 #ifndef TRYFREE
       
    56 # define TRYFREE(p) {if (p) free(p);}
       
    57 #endif
       
    58 
       
    59 /*
       
    60 #define SIZECENTRALDIRITEM (0x2e)
       
    61 #define SIZEZIPLOCALHEADER (0x1e)
       
    62 */
       
    63 
       
    64 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
       
    65 
       
    66 #ifndef SEEK_CUR
       
    67 #define SEEK_CUR    1
       
    68 #endif
       
    69 
       
    70 #ifndef SEEK_END
       
    71 #define SEEK_END    2
       
    72 #endif
       
    73 
       
    74 #ifndef SEEK_SET
       
    75 #define SEEK_SET    0
       
    76 #endif
       
    77 
       
    78 #ifndef DEF_MEM_LEVEL
       
    79 #if MAX_MEM_LEVEL >= 8
       
    80 #  define DEF_MEM_LEVEL 8
       
    81 #else
       
    82 #  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
       
    83 #endif
       
    84 #endif
       
    85 const char zip_copyright[] =
       
    86    " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
       
    87 
       
    88 
       
    89 #define SIZEDATA_INDATABLOCK (4096-(4*4))
       
    90 
       
    91 #define LOCALHEADERMAGIC    (0x04034b50)
       
    92 #define DESCRIPTORHEADERMAGIC    (0x08074b50)
       
    93 #define CENTRALHEADERMAGIC  (0x02014b50)
       
    94 #define ENDHEADERMAGIC      (0x06054b50)
       
    95 
       
    96 #define FLAG_LOCALHEADER_OFFSET (0x06)
       
    97 #define CRC_LOCALHEADER_OFFSET  (0x0e)
       
    98 
       
    99 #define SIZECENTRALHEADER (0x2e) /* 46 */
       
   100 
       
   101 typedef struct linkedlist_datablock_internal_s
       
   102 {
       
   103   struct linkedlist_datablock_internal_s* next_datablock;
       
   104   uLong  avail_in_this_block;
       
   105   uLong  filled_in_this_block;
       
   106   uLong  unused; /* for future use and alignement */
       
   107   unsigned char data[SIZEDATA_INDATABLOCK];
       
   108 } linkedlist_datablock_internal;
       
   109 
       
   110 typedef struct linkedlist_data_s
       
   111 {
       
   112     linkedlist_datablock_internal* first_block;
       
   113     linkedlist_datablock_internal* last_block;
       
   114 } linkedlist_data;
       
   115 
       
   116 
       
   117 typedef struct
       
   118 {
       
   119     z_stream stream;            /* zLib stream structure for inflate */
       
   120     int  stream_initialised;    /* 1 is stream is initialised */
       
   121     uInt pos_in_buffered_data;  /* last written byte in buffered_data */
       
   122 
       
   123     uLong pos_local_header;     /* offset of the local header of the file
       
   124                                      currenty writing */
       
   125     char* central_header;       /* central header data for the current file */
       
   126     uLong size_centralheader;   /* size of the central header for cur file */
       
   127     uLong flag;                 /* flag of the file currently writing */
       
   128 
       
   129     int  method;                /* compression method of file currenty wr.*/
       
   130     int  raw;                   /* 1 for directly writing raw data */
       
   131     Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
       
   132     uLong dosDate;
       
   133     uLong crc32;
       
   134     int  encrypt;
       
   135 #ifndef NOCRYPT
       
   136     unsigned long keys[3];     /* keys defining the pseudo-random sequence */
       
   137     const unsigned long* pcrc_32_tab;
       
   138     int crypt_header_size;
       
   139 #endif
       
   140 } curfile_info;
       
   141 
       
   142 typedef struct
       
   143 {
       
   144     zlib_filefunc_def z_filefunc;
       
   145     voidpf filestream;        /* io structore of the zipfile */
       
   146     linkedlist_data central_dir;/* datablock with central dir in construction*/
       
   147     int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/
       
   148     curfile_info ci;            /* info on the file curretly writing */
       
   149 
       
   150     uLong begin_pos;            /* position of the beginning of the zipfile */
       
   151     uLong add_position_when_writting_offset;
       
   152     uLong number_entry;
       
   153 #ifndef NO_ADDFILEINEXISTINGZIP
       
   154     char *globalcomment;
       
   155 #endif
       
   156 } zip_internal;
       
   157 
       
   158 
       
   159 
       
   160 #ifndef NOCRYPT
       
   161 #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
       
   162 #include "crypt.h"
       
   163 #endif
       
   164 
       
   165 local linkedlist_datablock_internal* allocate_new_datablock()
       
   166 {
       
   167     linkedlist_datablock_internal* ldi;
       
   168     ldi = (linkedlist_datablock_internal*)
       
   169                  ALLOC(sizeof(linkedlist_datablock_internal));
       
   170     if (ldi!=NULL)
       
   171     {
       
   172         ldi->next_datablock = NULL ;
       
   173         ldi->filled_in_this_block = 0 ;
       
   174         ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
       
   175     }
       
   176     return ldi;
       
   177 }
       
   178 
       
   179 local void free_datablock(ldi)
       
   180     linkedlist_datablock_internal* ldi;
       
   181 {
       
   182     while (ldi!=NULL)
       
   183     {
       
   184         linkedlist_datablock_internal* ldinext = ldi->next_datablock;
       
   185         TRYFREE(ldi);
       
   186         ldi = ldinext;
       
   187     }
       
   188 }
       
   189 
       
   190 local void init_linkedlist(ll)
       
   191     linkedlist_data* ll;
       
   192 {
       
   193     ll->first_block = ll->last_block = NULL;
       
   194 }
       
   195 
       
   196 #if 0 // unused
       
   197 local void free_linkedlist(ll)
       
   198     linkedlist_data* ll;
       
   199 {
       
   200     free_datablock(ll->first_block);
       
   201     ll->first_block = ll->last_block = NULL;
       
   202 }
       
   203 #endif
       
   204 
       
   205 local int add_data_in_datablock(ll,buf,len)
       
   206     linkedlist_data* ll;
       
   207     const void* buf;
       
   208     uLong len;
       
   209 {
       
   210     linkedlist_datablock_internal* ldi;
       
   211     const unsigned char* from_copy;
       
   212 
       
   213     if (ll==NULL)
       
   214         return ZIP_INTERNALERROR;
       
   215 
       
   216     if (ll->last_block == NULL)
       
   217     {
       
   218         ll->first_block = ll->last_block = allocate_new_datablock();
       
   219         if (ll->first_block == NULL)
       
   220             return ZIP_INTERNALERROR;
       
   221     }
       
   222 
       
   223     ldi = ll->last_block;
       
   224     from_copy = (unsigned char*)buf;
       
   225 
       
   226     while (len>0)
       
   227     {
       
   228         uInt copy_this;
       
   229         uInt i;
       
   230         unsigned char* to_copy;
       
   231 
       
   232         if (ldi->avail_in_this_block==0)
       
   233         {
       
   234             ldi->next_datablock = allocate_new_datablock();
       
   235             if (ldi->next_datablock == NULL)
       
   236                 return ZIP_INTERNALERROR;
       
   237             ldi = ldi->next_datablock ;
       
   238             ll->last_block = ldi;
       
   239         }
       
   240 
       
   241         if (ldi->avail_in_this_block < len)
       
   242             copy_this = (uInt)ldi->avail_in_this_block;
       
   243         else
       
   244             copy_this = (uInt)len;
       
   245 
       
   246         to_copy = &(ldi->data[ldi->filled_in_this_block]);
       
   247 
       
   248         for (i=0;i<copy_this;i++)
       
   249             *(to_copy+i)=*(from_copy+i);
       
   250 
       
   251         ldi->filled_in_this_block += copy_this;
       
   252         ldi->avail_in_this_block -= copy_this;
       
   253         from_copy += copy_this ;
       
   254         len -= copy_this;
       
   255     }
       
   256     return ZIP_OK;
       
   257 }
       
   258 
       
   259 
       
   260 
       
   261 /****************************************************************************/
       
   262 
       
   263 #ifndef NO_ADDFILEINEXISTINGZIP
       
   264 /* ===========================================================================
       
   265    Inputs a long in LSB order to the given file
       
   266    nbByte == 1, 2 or 4 (byte, short or long)
       
   267 */
       
   268 
       
   269 local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def,
       
   270                                 voidpf filestream, uLong x, int nbByte));
       
   271 local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte)
       
   272     const zlib_filefunc_def* pzlib_filefunc_def;
       
   273     voidpf filestream;
       
   274     uLong x;
       
   275     int nbByte;
       
   276 {
       
   277     unsigned char buf[4];
       
   278     int n;
       
   279     for (n = 0; n < nbByte; n++)
       
   280     {
       
   281         buf[n] = (unsigned char)(x & 0xff);
       
   282         x >>= 8;
       
   283     }
       
   284     if (x != 0)
       
   285       {     /* data overflow - hack for ZIP64 (X Roche) */
       
   286       for (n = 0; n < nbByte; n++)
       
   287         {
       
   288           buf[n] = 0xff;
       
   289         }
       
   290       }
       
   291 
       
   292     if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
       
   293         return ZIP_ERRNO;
       
   294     else
       
   295         return ZIP_OK;
       
   296 }
       
   297 
       
   298 local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
       
   299 local void ziplocal_putValue_inmemory (dest, x, nbByte)
       
   300     void* dest;
       
   301     uLong x;
       
   302     int nbByte;
       
   303 {
       
   304     unsigned char* buf=(unsigned char*)dest;
       
   305     int n;
       
   306     for (n = 0; n < nbByte; n++) {
       
   307         buf[n] = (unsigned char)(x & 0xff);
       
   308         x >>= 8;
       
   309     }
       
   310 
       
   311     if (x != 0)
       
   312     {     /* data overflow - hack for ZIP64 */
       
   313        for (n = 0; n < nbByte; n++)
       
   314        {
       
   315           buf[n] = 0xff;
       
   316        }
       
   317     }
       
   318 }
       
   319 
       
   320 /****************************************************************************/
       
   321 
       
   322 
       
   323 local uLong ziplocal_TmzDateToDosDate(ptm,dosDate)
       
   324     const tm_zip* ptm;
       
   325     uLong dosDate UNUSED;
       
   326 {
       
   327     uLong year = (uLong)ptm->tm_year;
       
   328     if (year>1980)
       
   329         year-=1980;
       
   330     else if (year>80)
       
   331         year-=80;
       
   332     return
       
   333       (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
       
   334         ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
       
   335 }
       
   336 
       
   337 
       
   338 /****************************************************************************/
       
   339 
       
   340 local int ziplocal_getByte OF((
       
   341     const zlib_filefunc_def* pzlib_filefunc_def,
       
   342     voidpf filestream,
       
   343     int *pi));
       
   344 
       
   345 local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi)
       
   346     const zlib_filefunc_def* pzlib_filefunc_def;
       
   347     voidpf filestream;
       
   348     int *pi;
       
   349 {
       
   350     unsigned char c;
       
   351     int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
       
   352     if (err==1)
       
   353     {
       
   354         *pi = (int)c;
       
   355         return ZIP_OK;
       
   356     }
       
   357     else
       
   358     {
       
   359         if (ZERROR(*pzlib_filefunc_def,filestream))
       
   360             return ZIP_ERRNO;
       
   361         else
       
   362             return ZIP_EOF;
       
   363     }
       
   364 }
       
   365 
       
   366 
       
   367 /* ===========================================================================
       
   368    Reads a long in LSB order from the given gz_stream. Sets
       
   369 */
       
   370 local int ziplocal_getShort OF((
       
   371     const zlib_filefunc_def* pzlib_filefunc_def,
       
   372     voidpf filestream,
       
   373     uLong *pX));
       
   374 
       
   375 local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX)
       
   376     const zlib_filefunc_def* pzlib_filefunc_def;
       
   377     voidpf filestream;
       
   378     uLong *pX;
       
   379 {
       
   380     uLong x ;
       
   381     int i;
       
   382     int err;
       
   383 
       
   384     err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
       
   385     x = (uLong)i;
       
   386 
       
   387     if (err==ZIP_OK)
       
   388         err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
       
   389     x += ((uLong)i)<<8;
       
   390 
       
   391     if (err==ZIP_OK)
       
   392         *pX = x;
       
   393     else
       
   394         *pX = 0;
       
   395     return err;
       
   396 }
       
   397 
       
   398 local int ziplocal_getLong OF((
       
   399     const zlib_filefunc_def* pzlib_filefunc_def,
       
   400     voidpf filestream,
       
   401     uLong *pX));
       
   402 
       
   403 local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX)
       
   404     const zlib_filefunc_def* pzlib_filefunc_def;
       
   405     voidpf filestream;
       
   406     uLong *pX;
       
   407 {
       
   408     uLong x ;
       
   409     int i;
       
   410     int err;
       
   411 
       
   412     err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
       
   413     x = (uLong)i;
       
   414 
       
   415     if (err==ZIP_OK)
       
   416         err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
       
   417     x += ((uLong)i)<<8;
       
   418 
       
   419     if (err==ZIP_OK)
       
   420         err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
       
   421     x += ((uLong)i)<<16;
       
   422 
       
   423     if (err==ZIP_OK)
       
   424         err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
       
   425     x += ((uLong)i)<<24;
       
   426 
       
   427     if (err==ZIP_OK)
       
   428         *pX = x;
       
   429     else
       
   430         *pX = 0;
       
   431     return err;
       
   432 }
       
   433 
       
   434 #ifndef BUFREADCOMMENT
       
   435 #define BUFREADCOMMENT (0x400)
       
   436 #endif
       
   437 /*
       
   438   Locate the Central directory of a zipfile (at the end, just before
       
   439     the global comment)
       
   440 */
       
   441 local uLong ziplocal_SearchCentralDir OF((
       
   442     const zlib_filefunc_def* pzlib_filefunc_def,
       
   443     voidpf filestream));
       
   444 
       
   445 local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream)
       
   446     const zlib_filefunc_def* pzlib_filefunc_def;
       
   447     voidpf filestream;
       
   448 {
       
   449     unsigned char* buf;
       
   450     uLong uSizeFile;
       
   451     uLong uBackRead;
       
   452     uLong uMaxBack=0xffff; /* maximum size of global comment */
       
   453     uLong uPosFound=0;
       
   454 
       
   455     if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
       
   456         return 0;
       
   457 
       
   458 
       
   459     uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
       
   460 
       
   461     if (uMaxBack>uSizeFile)
       
   462         uMaxBack = uSizeFile;
       
   463 
       
   464     buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
       
   465     if (buf==NULL)
       
   466         return 0;
       
   467 
       
   468     uBackRead = 4;
       
   469     while (uBackRead<uMaxBack)
       
   470     {
       
   471         uLong uReadSize,uReadPos ;
       
   472         int i;
       
   473         if (uBackRead+BUFREADCOMMENT>uMaxBack)
       
   474             uBackRead = uMaxBack;
       
   475         else
       
   476             uBackRead+=BUFREADCOMMENT;
       
   477         uReadPos = uSizeFile-uBackRead ;
       
   478 
       
   479         uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
       
   480                      (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
       
   481         if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
       
   482             break;
       
   483 
       
   484         if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
       
   485             break;
       
   486 
       
   487         for (i=(int)uReadSize-3; (i--)>0;)
       
   488             if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
       
   489                 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
       
   490             {
       
   491                 uPosFound = uReadPos+i;
       
   492                 break;
       
   493             }
       
   494 
       
   495         if (uPosFound!=0)
       
   496             break;
       
   497     }
       
   498     TRYFREE(buf);
       
   499     return uPosFound;
       
   500 }
       
   501 #endif /* !NO_ADDFILEINEXISTINGZIP*/
       
   502 
       
   503 /************************************************************/
       
   504 extern zipFile ZEXPORT zipOpen2 (file, append, globalcomment, pzlib_filefunc_def)
       
   505     voidpf file;
       
   506     int append;
       
   507     zipcharpc* globalcomment;
       
   508     zlib_filefunc_def* pzlib_filefunc_def;
       
   509 {
       
   510     zip_internal ziinit;
       
   511     zip_internal* zi;
       
   512     int err=ZIP_OK;
       
   513 
       
   514 
       
   515     if (pzlib_filefunc_def==NULL)
       
   516         fill_qiodevice_filefunc(&ziinit.z_filefunc);
       
   517     else
       
   518         ziinit.z_filefunc = *pzlib_filefunc_def;
       
   519 
       
   520     ziinit.filestream = (*(ziinit.z_filefunc.zopen_file))
       
   521                  (ziinit.z_filefunc.opaque,
       
   522                   file,
       
   523                   (append == APPEND_STATUS_CREATE) ?
       
   524                   (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
       
   525                     (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
       
   526 
       
   527     if (ziinit.filestream == NULL)
       
   528         return NULL;
       
   529     ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream);
       
   530     ziinit.in_opened_file_inzip = 0;
       
   531     ziinit.ci.stream_initialised = 0;
       
   532     ziinit.number_entry = 0;
       
   533     ziinit.add_position_when_writting_offset = 0;
       
   534     init_linkedlist(&(ziinit.central_dir));
       
   535 
       
   536 
       
   537     zi = (zip_internal*)ALLOC(sizeof(zip_internal));
       
   538     if (zi==NULL)
       
   539     {
       
   540         ZCLOSE(ziinit.z_filefunc,ziinit.filestream);
       
   541         return NULL;
       
   542     }
       
   543 
       
   544     /* now we add file in a zipfile */
       
   545 #    ifndef NO_ADDFILEINEXISTINGZIP
       
   546     ziinit.globalcomment = NULL;
       
   547     if (append == APPEND_STATUS_ADDINZIP)
       
   548     {
       
   549         uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
       
   550 
       
   551         uLong size_central_dir;     /* size of the central directory  */
       
   552         uLong offset_central_dir;   /* offset of start of central directory */
       
   553         uLong central_pos,uL;
       
   554 
       
   555         uLong number_disk;          /* number of the current dist, used for
       
   556                                     spaning ZIP, unsupported, always 0*/
       
   557         uLong number_disk_with_CD;  /* number the the disk with central dir, used
       
   558                                     for spaning ZIP, unsupported, always 0*/
       
   559         uLong number_entry;
       
   560         uLong number_entry_CD;      /* total number of entries in
       
   561                                     the central dir
       
   562                                     (same than number_entry on nospan) */
       
   563         uLong size_comment;
       
   564 
       
   565         central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);
       
   566         if (central_pos==0)
       
   567             err=ZIP_ERRNO;
       
   568 
       
   569         if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
       
   570                                         central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
       
   571             err=ZIP_ERRNO;
       
   572 
       
   573         /* the signature, already checked */
       
   574         if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK)
       
   575             err=ZIP_ERRNO;
       
   576 
       
   577         /* number of this disk */
       
   578         if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK)
       
   579             err=ZIP_ERRNO;
       
   580 
       
   581         /* number of the disk with the start of the central directory */
       
   582         if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK)
       
   583             err=ZIP_ERRNO;
       
   584 
       
   585         /* total number of entries in the central dir on this disk */
       
   586         if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK)
       
   587             err=ZIP_ERRNO;
       
   588 
       
   589         /* total number of entries in the central dir */
       
   590         if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK)
       
   591             err=ZIP_ERRNO;
       
   592 
       
   593         if ((number_entry_CD!=number_entry) ||
       
   594             (number_disk_with_CD!=0) ||
       
   595             (number_disk!=0))
       
   596             err=ZIP_BADZIPFILE;
       
   597 
       
   598         /* size of the central directory */
       
   599         if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK)
       
   600             err=ZIP_ERRNO;
       
   601 
       
   602         /* offset of start of central directory with respect to the
       
   603             starting disk number */
       
   604         if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK)
       
   605             err=ZIP_ERRNO;
       
   606 
       
   607         /* zipfile global comment length */
       
   608         if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK)
       
   609             err=ZIP_ERRNO;
       
   610 
       
   611         if ((central_pos<offset_central_dir+size_central_dir) &&
       
   612             (err==ZIP_OK))
       
   613             err=ZIP_BADZIPFILE;
       
   614 
       
   615         if (err!=ZIP_OK)
       
   616         {
       
   617             ZCLOSE(ziinit.z_filefunc, ziinit.filestream);
       
   618             return NULL;
       
   619         }
       
   620 
       
   621         if (size_comment>0)
       
   622         {
       
   623             ziinit.globalcomment = ALLOC(size_comment+1);
       
   624             if (ziinit.globalcomment)
       
   625             {
       
   626                size_comment = ZREAD(ziinit.z_filefunc, ziinit.filestream,ziinit.globalcomment,size_comment);
       
   627                ziinit.globalcomment[size_comment]=0;
       
   628             }
       
   629         }
       
   630 
       
   631         byte_before_the_zipfile = central_pos -
       
   632                                 (offset_central_dir+size_central_dir);
       
   633         ziinit.add_position_when_writting_offset = byte_before_the_zipfile;
       
   634 
       
   635         {
       
   636             uLong size_central_dir_to_read = size_central_dir;
       
   637             size_t buf_size = SIZEDATA_INDATABLOCK;
       
   638             void* buf_read = (void*)ALLOC(buf_size);
       
   639             if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
       
   640                   offset_central_dir + byte_before_the_zipfile,
       
   641                   ZLIB_FILEFUNC_SEEK_SET) != 0)
       
   642                   err=ZIP_ERRNO;
       
   643 
       
   644             while ((size_central_dir_to_read>0) && (err==ZIP_OK))
       
   645             {
       
   646                 uLong read_this = SIZEDATA_INDATABLOCK;
       
   647                 if (read_this > size_central_dir_to_read)
       
   648                     read_this = size_central_dir_to_read;
       
   649                 if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this)
       
   650                     err=ZIP_ERRNO;
       
   651 
       
   652                 if (err==ZIP_OK)
       
   653                     err = add_data_in_datablock(&ziinit.central_dir,buf_read,
       
   654                                                 (uLong)read_this);
       
   655                 size_central_dir_to_read-=read_this;
       
   656             }
       
   657             TRYFREE(buf_read);
       
   658         }
       
   659         ziinit.begin_pos = byte_before_the_zipfile;
       
   660         ziinit.number_entry = number_entry_CD;
       
   661 
       
   662         if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
       
   663                   offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
       
   664             err=ZIP_ERRNO;
       
   665     }
       
   666 
       
   667     if (globalcomment)
       
   668     {
       
   669       *globalcomment = ziinit.globalcomment;
       
   670     }
       
   671 #    endif /* !NO_ADDFILEINEXISTINGZIP*/
       
   672 
       
   673     if (err != ZIP_OK)
       
   674     {
       
   675 #    ifndef NO_ADDFILEINEXISTINGZIP
       
   676         TRYFREE(ziinit.globalcomment);
       
   677 #    endif /* !NO_ADDFILEINEXISTINGZIP*/
       
   678         TRYFREE(zi);
       
   679         return NULL;
       
   680     }
       
   681     else
       
   682     {
       
   683         *zi = ziinit;
       
   684         return (zipFile)zi;
       
   685     }
       
   686 }
       
   687 
       
   688 extern zipFile ZEXPORT zipOpen (file, append)
       
   689     voidpf file;
       
   690     int append;
       
   691 {
       
   692     return zipOpen2(file,append,NULL,NULL);
       
   693 }
       
   694 
       
   695 extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi,
       
   696                                          extrafield_local, size_extrafield_local,
       
   697                                          extrafield_global, size_extrafield_global,
       
   698                                          comment, method, level, raw,
       
   699                                          windowBits, memLevel, strategy,
       
   700                                          password, crcForCrypting)
       
   701     zipFile file;
       
   702     const char* filename;
       
   703     const zip_fileinfo* zipfi;
       
   704     const void* extrafield_local;
       
   705     uInt size_extrafield_local;
       
   706     const void* extrafield_global;
       
   707     uInt size_extrafield_global;
       
   708     const char* comment;
       
   709     int method;
       
   710     int level;
       
   711     int raw;
       
   712     int windowBits;
       
   713     int memLevel;
       
   714     int strategy;
       
   715     const char* password;
       
   716     uLong crcForCrypting;
       
   717 {
       
   718     zip_internal* zi;
       
   719     uInt size_filename;
       
   720     uInt size_comment;
       
   721     uInt i;
       
   722     int err = ZIP_OK;
       
   723 
       
   724 #    ifdef NOCRYPT
       
   725     if (password != NULL)
       
   726         return ZIP_PARAMERROR;
       
   727 #    endif
       
   728 
       
   729     if (file == NULL)
       
   730         return ZIP_PARAMERROR;
       
   731     if ((method!=0) && (method!=Z_DEFLATED))
       
   732         return ZIP_PARAMERROR;
       
   733 
       
   734     zi = (zip_internal*)file;
       
   735 
       
   736     if (zi->in_opened_file_inzip == 1)
       
   737     {
       
   738         err = zipCloseFileInZip (file);
       
   739         if (err != ZIP_OK)
       
   740             return err;
       
   741     }
       
   742 
       
   743 
       
   744     if (filename==NULL)
       
   745         filename="-";
       
   746 
       
   747     if (comment==NULL)
       
   748         size_comment = 0;
       
   749     else
       
   750         size_comment = (uInt)strlen(comment);
       
   751 
       
   752     size_filename = (uInt)strlen(filename);
       
   753 
       
   754     if (zipfi == NULL)
       
   755         zi->ci.dosDate = 0;
       
   756     else
       
   757     {
       
   758         if (zipfi->dosDate != 0)
       
   759             zi->ci.dosDate = zipfi->dosDate;
       
   760         else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
       
   761     }
       
   762 
       
   763     zi->ci.flag = 0;
       
   764     if ((level==8) || (level==9))
       
   765       zi->ci.flag |= 2;
       
   766     if ((level==2))
       
   767       zi->ci.flag |= 4;
       
   768     if ((level==1))
       
   769       zi->ci.flag |= 6;
       
   770     if (password != NULL)
       
   771     {
       
   772       zi->ci.flag |= 1;
       
   773     }
       
   774     zi->ci.flag |= 8;
       
   775     zi->ci.crc32 = 0;
       
   776     zi->ci.method = method;
       
   777     zi->ci.encrypt = 0;
       
   778     zi->ci.stream_initialised = 0;
       
   779     zi->ci.pos_in_buffered_data = 0;
       
   780     zi->ci.raw = raw;
       
   781     zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ;
       
   782     zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
       
   783                                       size_extrafield_global + size_comment;
       
   784     zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
       
   785 
       
   786     ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
       
   787     /* version info */
       
   788     ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
       
   789     ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
       
   790     ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
       
   791     ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
       
   792     ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
       
   793     ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
       
   794     ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
       
   795     ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
       
   796     ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
       
   797     ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
       
   798     ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
       
   799     ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
       
   800 
       
   801     if (zipfi==NULL)
       
   802         ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
       
   803     else
       
   804         ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
       
   805 
       
   806     if (zipfi==NULL)
       
   807         ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
       
   808     else
       
   809         ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
       
   810 
       
   811     ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);
       
   812 
       
   813     for (i=0;i<size_filename;i++)
       
   814         *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
       
   815 
       
   816     for (i=0;i<size_extrafield_global;i++)
       
   817         *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
       
   818               *(((const char*)extrafield_global)+i);
       
   819 
       
   820     for (i=0;i<size_comment;i++)
       
   821         *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
       
   822               size_extrafield_global+i) = *(comment+i);
       
   823     if (zi->ci.central_header == NULL)
       
   824         return ZIP_INTERNALERROR;
       
   825 
       
   826     /* write the local header */
       
   827     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);
       
   828 
       
   829     if (err==ZIP_OK)
       
   830         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
       
   831     if (err==ZIP_OK)
       
   832         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
       
   833 
       
   834     if (err==ZIP_OK)
       
   835         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
       
   836 
       
   837     if (err==ZIP_OK)
       
   838         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
       
   839 
       
   840     if (err==ZIP_OK)
       
   841         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
       
   842     if (err==ZIP_OK)
       
   843         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
       
   844     if (err==ZIP_OK)
       
   845         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
       
   846 
       
   847     if (err==ZIP_OK)
       
   848         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
       
   849 
       
   850     if (err==ZIP_OK)
       
   851         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);
       
   852 
       
   853     if ((err==ZIP_OK) && (size_filename>0))
       
   854         if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
       
   855                 err = ZIP_ERRNO;
       
   856 
       
   857     if ((err==ZIP_OK) && (size_extrafield_local>0))
       
   858         if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local)
       
   859                                                                            !=size_extrafield_local)
       
   860                 err = ZIP_ERRNO;
       
   861 
       
   862     zi->ci.stream.avail_in = (uInt)0;
       
   863     zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
       
   864     zi->ci.stream.next_out = zi->ci.buffered_data;
       
   865     zi->ci.stream.total_in = 0;
       
   866     zi->ci.stream.total_out = 0;
       
   867 
       
   868     if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
       
   869     {
       
   870         zi->ci.stream.zalloc = (alloc_func)0;
       
   871         zi->ci.stream.zfree = (free_func)0;
       
   872         zi->ci.stream.opaque = (voidpf)0;
       
   873 
       
   874         if (windowBits>0)
       
   875             windowBits = -windowBits;
       
   876 
       
   877         err = deflateInit2(&zi->ci.stream, level,
       
   878                Z_DEFLATED, windowBits, memLevel, strategy);
       
   879 
       
   880         if (err==Z_OK)
       
   881             zi->ci.stream_initialised = 1;
       
   882     }
       
   883 #    ifndef NOCRYPT
       
   884     zi->ci.crypt_header_size = 0;
       
   885     if ((err==Z_OK) && (password != NULL))
       
   886     {
       
   887         unsigned char bufHead[RAND_HEAD_LEN];
       
   888         unsigned int sizeHead;
       
   889         zi->ci.encrypt = 1;
       
   890         zi->ci.pcrc_32_tab = get_crc_table();
       
   891         /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
       
   892 
       
   893         crcForCrypting = (uLong)zi->ci.dosDate << 16; // ATTANTION! Without this row, you don't unpack your password protected archive in other app.
       
   894 
       
   895         sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
       
   896         zi->ci.crypt_header_size = sizeHead;
       
   897 
       
   898         if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
       
   899                 err = ZIP_ERRNO;
       
   900     }
       
   901 #    endif
       
   902 
       
   903     if (err==Z_OK)
       
   904         zi->in_opened_file_inzip = 1;
       
   905     return err;
       
   906 }
       
   907 
       
   908 extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi,
       
   909                                         extrafield_local, size_extrafield_local,
       
   910                                         extrafield_global, size_extrafield_global,
       
   911                                         comment, method, level, raw)
       
   912     zipFile file;
       
   913     const char* filename;
       
   914     const zip_fileinfo* zipfi;
       
   915     const void* extrafield_local;
       
   916     uInt size_extrafield_local;
       
   917     const void* extrafield_global;
       
   918     uInt size_extrafield_global;
       
   919     const char* comment;
       
   920     int method;
       
   921     int level;
       
   922     int raw;
       
   923 {
       
   924     return zipOpenNewFileInZip3 (file, filename, zipfi,
       
   925                                  extrafield_local, size_extrafield_local,
       
   926                                  extrafield_global, size_extrafield_global,
       
   927                                  comment, method, level, raw,
       
   928                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
       
   929                                  NULL, 0);
       
   930 }
       
   931 
       
   932 extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi,
       
   933                                         extrafield_local, size_extrafield_local,
       
   934                                         extrafield_global, size_extrafield_global,
       
   935                                         comment, method, level)
       
   936     zipFile file;
       
   937     const char* filename;
       
   938     const zip_fileinfo* zipfi;
       
   939     const void* extrafield_local;
       
   940     uInt size_extrafield_local;
       
   941     const void* extrafield_global;
       
   942     uInt size_extrafield_global;
       
   943     const char* comment;
       
   944     int method;
       
   945     int level;
       
   946 {
       
   947     return zipOpenNewFileInZip2 (file, filename, zipfi,
       
   948                                  extrafield_local, size_extrafield_local,
       
   949                                  extrafield_global, size_extrafield_global,
       
   950                                  comment, method, level, 0);
       
   951 }
       
   952 
       
   953 local int zipFlushWriteBuffer(zi)
       
   954   zip_internal* zi;
       
   955 {
       
   956     int err=ZIP_OK;
       
   957 
       
   958     if (zi->ci.encrypt != 0)
       
   959     {
       
   960 #ifndef NOCRYPT
       
   961         uInt i;
       
   962         int t;
       
   963         for (i=0;i<zi->ci.pos_in_buffered_data;i++)
       
   964             zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab,
       
   965                                        zi->ci.buffered_data[i],t);
       
   966 #endif
       
   967     }
       
   968     if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data)
       
   969                                                                     !=zi->ci.pos_in_buffered_data)
       
   970       err = ZIP_ERRNO;
       
   971     zi->ci.pos_in_buffered_data = 0;
       
   972     return err;
       
   973 }
       
   974 
       
   975 extern int ZEXPORT zipWriteInFileInZip (file, buf, len)
       
   976     zipFile file;
       
   977     const void* buf;
       
   978     unsigned len;
       
   979 {
       
   980     zip_internal* zi;
       
   981     int err=ZIP_OK;
       
   982 
       
   983     if (file == NULL)
       
   984         return ZIP_PARAMERROR;
       
   985     zi = (zip_internal*)file;
       
   986 
       
   987     if (zi->in_opened_file_inzip == 0)
       
   988         return ZIP_PARAMERROR;
       
   989 
       
   990     zi->ci.stream.next_in = (void*)buf;
       
   991     zi->ci.stream.avail_in = len;
       
   992     zi->ci.crc32 = crc32(zi->ci.crc32,buf,len);
       
   993 
       
   994     while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
       
   995     {
       
   996         if (zi->ci.stream.avail_out == 0)
       
   997         {
       
   998             if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
       
   999                 err = ZIP_ERRNO;
       
  1000             zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
       
  1001             zi->ci.stream.next_out = zi->ci.buffered_data;
       
  1002         }
       
  1003 
       
  1004 
       
  1005         if(err != ZIP_OK)
       
  1006             break;
       
  1007 
       
  1008         if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
       
  1009         {
       
  1010             uLong uTotalOutBefore = zi->ci.stream.total_out;
       
  1011             err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
       
  1012             zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
       
  1013 
       
  1014         }
       
  1015         else
       
  1016         {
       
  1017             uInt copy_this,i;
       
  1018             if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
       
  1019                 copy_this = zi->ci.stream.avail_in;
       
  1020             else
       
  1021                 copy_this = zi->ci.stream.avail_out;
       
  1022             for (i=0;i<copy_this;i++)
       
  1023                 *(((char*)zi->ci.stream.next_out)+i) =
       
  1024                     *(((const char*)zi->ci.stream.next_in)+i);
       
  1025             {
       
  1026                 zi->ci.stream.avail_in -= copy_this;
       
  1027                 zi->ci.stream.avail_out-= copy_this;
       
  1028                 zi->ci.stream.next_in+= copy_this;
       
  1029                 zi->ci.stream.next_out+= copy_this;
       
  1030                 zi->ci.stream.total_in+= copy_this;
       
  1031                 zi->ci.stream.total_out+= copy_this;
       
  1032                 zi->ci.pos_in_buffered_data += copy_this;
       
  1033             }
       
  1034         }
       
  1035     }
       
  1036 
       
  1037     return err;
       
  1038 }
       
  1039 
       
  1040 extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32)
       
  1041     zipFile file;
       
  1042     uLong uncompressed_size;
       
  1043     uLong crc32;
       
  1044 {
       
  1045     zip_internal* zi;
       
  1046     uLong compressed_size;
       
  1047     int err=ZIP_OK;
       
  1048 
       
  1049     if (file == NULL)
       
  1050         return ZIP_PARAMERROR;
       
  1051     zi = (zip_internal*)file;
       
  1052 
       
  1053     if (zi->in_opened_file_inzip == 0)
       
  1054         return ZIP_PARAMERROR;
       
  1055     zi->ci.stream.avail_in = 0;
       
  1056 
       
  1057     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
       
  1058         while (err==ZIP_OK)
       
  1059     {
       
  1060         uLong uTotalOutBefore;
       
  1061         if (zi->ci.stream.avail_out == 0)
       
  1062         {
       
  1063             if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
       
  1064                 err = ZIP_ERRNO;
       
  1065             zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
       
  1066             zi->ci.stream.next_out = zi->ci.buffered_data;
       
  1067         }
       
  1068         uTotalOutBefore = zi->ci.stream.total_out;
       
  1069         err=deflate(&zi->ci.stream,  Z_FINISH);
       
  1070         zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
       
  1071     }
       
  1072 
       
  1073     if (err==Z_STREAM_END)
       
  1074         err=ZIP_OK; /* this is normal */
       
  1075 
       
  1076     if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
       
  1077         if (zipFlushWriteBuffer(zi)==ZIP_ERRNO)
       
  1078             err = ZIP_ERRNO;
       
  1079 
       
  1080     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
       
  1081     {
       
  1082         err=deflateEnd(&zi->ci.stream);
       
  1083         zi->ci.stream_initialised = 0;
       
  1084     }
       
  1085 
       
  1086     if (!zi->ci.raw)
       
  1087     {
       
  1088         crc32 = (uLong)zi->ci.crc32;
       
  1089         uncompressed_size = (uLong)zi->ci.stream.total_in;
       
  1090     }
       
  1091     compressed_size = (uLong)zi->ci.stream.total_out;
       
  1092 #    ifndef NOCRYPT
       
  1093     compressed_size += zi->ci.crypt_header_size;
       
  1094 #    endif
       
  1095 
       
  1096     ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
       
  1097     ziplocal_putValue_inmemory(zi->ci.central_header+20,
       
  1098                                 compressed_size,4); /*compr size*/
       
  1099     if (zi->ci.stream.data_type == Z_ASCII)
       
  1100         ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
       
  1101     ziplocal_putValue_inmemory(zi->ci.central_header+24,
       
  1102                                 uncompressed_size,4); /*uncompr size*/
       
  1103 
       
  1104     if (err==ZIP_OK)
       
  1105         err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
       
  1106                                        (uLong)zi->ci.size_centralheader);
       
  1107     free(zi->ci.central_header);
       
  1108 
       
  1109     if (err==ZIP_OK)
       
  1110     {
       
  1111         uLong cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
       
  1112         if (ZSEEK(zi->z_filefunc,zi->filestream,
       
  1113                   zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
       
  1114             err = ZIP_ERRNO;
       
  1115 
       
  1116         if (err==ZIP_OK)
       
  1117             err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
       
  1118 
       
  1119         if (err==ZIP_OK) /* compressed size, unknown */
       
  1120             err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
       
  1121 
       
  1122         if (err==ZIP_OK) /* uncompressed size, unknown */
       
  1123             err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
       
  1124 
       
  1125         if (ZSEEK(zi->z_filefunc,zi->filestream,
       
  1126                   cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
       
  1127             err = ZIP_ERRNO;
       
  1128 
       
  1129         /* Write local Descriptor after file data */
       
  1130         if (err==ZIP_OK)
       
  1131             err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)DESCRIPTORHEADERMAGIC,4);
       
  1132 
       
  1133         if (err==ZIP_OK)
       
  1134             err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
       
  1135 
       
  1136         if (err==ZIP_OK) /* compressed size, unknown */
       
  1137             err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
       
  1138 
       
  1139         if (err==ZIP_OK) /* uncompressed size, unknown */
       
  1140             err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
       
  1141 
       
  1142 
       
  1143     }
       
  1144 
       
  1145     zi->number_entry ++;
       
  1146     zi->in_opened_file_inzip = 0;
       
  1147 
       
  1148     return err;
       
  1149 }
       
  1150 
       
  1151 extern int ZEXPORT zipCloseFileInZip (file)
       
  1152     zipFile file;
       
  1153 {
       
  1154     return zipCloseFileInZipRaw (file,0,0);
       
  1155 }
       
  1156 
       
  1157 extern int ZEXPORT zipClose (file, global_comment)
       
  1158     zipFile file;
       
  1159     const char* global_comment;
       
  1160 {
       
  1161     zip_internal* zi;
       
  1162     int err = 0;
       
  1163     uLong size_centraldir = 0;
       
  1164     uLong centraldir_pos_inzip;
       
  1165     uInt size_global_comment;
       
  1166     if (file == NULL)
       
  1167         return ZIP_PARAMERROR;
       
  1168     zi = (zip_internal*)file;
       
  1169 
       
  1170     if (zi->in_opened_file_inzip == 1)
       
  1171     {
       
  1172         err = zipCloseFileInZip (file);
       
  1173     }
       
  1174 
       
  1175 #ifndef NO_ADDFILEINEXISTINGZIP
       
  1176     if (global_comment==NULL)
       
  1177         global_comment = zi->globalcomment;
       
  1178 #endif
       
  1179     if (global_comment==NULL)
       
  1180         size_global_comment = 0;
       
  1181     else
       
  1182         size_global_comment = (uInt)strlen(global_comment);
       
  1183 
       
  1184     centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
       
  1185     if (err==ZIP_OK)
       
  1186     {
       
  1187         linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
       
  1188         while (ldi!=NULL)
       
  1189         {
       
  1190             if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
       
  1191                 if (ZWRITE(zi->z_filefunc,zi->filestream,
       
  1192                            ldi->data,ldi->filled_in_this_block)
       
  1193                               !=ldi->filled_in_this_block )
       
  1194                     err = ZIP_ERRNO;
       
  1195 
       
  1196             size_centraldir += ldi->filled_in_this_block;
       
  1197             ldi = ldi->next_datablock;
       
  1198         }
       
  1199     }
       
  1200     free_datablock(zi->central_dir.first_block);
       
  1201 
       
  1202     if (err==ZIP_OK) /* Magic End */
       
  1203         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
       
  1204 
       
  1205     if (err==ZIP_OK) /* number of this disk */
       
  1206         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
       
  1207 
       
  1208     if (err==ZIP_OK) /* number of the disk with the start of the central directory */
       
  1209         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
       
  1210 
       
  1211     if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
       
  1212         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
       
  1213 
       
  1214     if (err==ZIP_OK) /* total number of entries in the central dir */
       
  1215         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
       
  1216 
       
  1217     if (err==ZIP_OK) /* size of the central directory */
       
  1218         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
       
  1219 
       
  1220     if (err==ZIP_OK) /* offset of start of central directory with respect to the
       
  1221                             starting disk number */
       
  1222         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,
       
  1223                                 (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
       
  1224 
       
  1225     if (err==ZIP_OK) /* zipfile comment length */
       
  1226         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
       
  1227 
       
  1228     if ((err==ZIP_OK) && (size_global_comment>0))
       
  1229         if (ZWRITE(zi->z_filefunc,zi->filestream,
       
  1230                    global_comment,size_global_comment) != size_global_comment)
       
  1231                 err = ZIP_ERRNO;
       
  1232 
       
  1233     if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0)
       
  1234         if (err == ZIP_OK)
       
  1235             err = ZIP_ERRNO;
       
  1236 
       
  1237 #ifndef NO_ADDFILEINEXISTINGZIP
       
  1238     TRYFREE(zi->globalcomment);
       
  1239 #endif
       
  1240     TRYFREE(zi);
       
  1241 
       
  1242     return err;
       
  1243 }