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