LCOV - code coverage report
Current view: directory - port - cpl_minizip_zip.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 539 424 78.7 %
Date: 2013-03-30 Functions: 26 25 96.2 %

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

Generated by: LCOV version 1.7