LCOV - code coverage report
Current view: directory - port - cpl_minizip_zip.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 504 394 78.2 %
Date: 2012-12-26 Functions: 26 25 96.2 %

       1                 : /******************************************************************************
       2                 :  * $Id: cpl_minizip_zip.cpp 23818 2012-01-28 20:16:38Z 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              36 : local linkedlist_datablock_internal* allocate_new_datablock()
     180                 : {
     181                 :     linkedlist_datablock_internal* ldi;
     182                 :     ldi = (linkedlist_datablock_internal*)
     183              36 :                  ALLOC(sizeof(linkedlist_datablock_internal));
     184              36 :     if (ldi!=NULL)
     185                 :     {
     186              36 :         ldi->next_datablock = NULL ;
     187              36 :         ldi->filled_in_this_block = 0 ;
     188              36 :         ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
     189                 :     }
     190              36 :     return ldi;
     191                 : }
     192                 : 
     193              36 : local void free_datablock(linkedlist_datablock_internal*ldi)
     194                 : {
     195             108 :     while (ldi!=NULL)
     196                 :     {
     197              36 :         linkedlist_datablock_internal* ldinext = ldi->next_datablock;
     198              36 :         TRYFREE(ldi);
     199              36 :         ldi = ldinext;
     200                 :     }
     201              36 : }
     202                 : 
     203              36 : local void init_linkedlist(linkedlist_data*ll)
     204                 : {
     205              36 :     ll->first_block = ll->last_block = NULL;
     206              36 : }
     207                 : 
     208             122 : 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             122 :     if (ll==NULL)
     215               0 :         return ZIP_INTERNALERROR;
     216                 : 
     217             122 :     if (ll->last_block == NULL)
     218                 :     {
     219              36 :         ll->first_block = ll->last_block = allocate_new_datablock();
     220              36 :         if (ll->first_block == NULL)
     221               0 :             return ZIP_INTERNALERROR;
     222                 :     }
     223                 : 
     224             122 :     ldi = ll->last_block;
     225             122 :     from_copy = (unsigned char*)buf;
     226                 : 
     227             366 :     while (len>0)
     228                 :     {
     229                 :         uInt copy_this;
     230                 :         uInt i;
     231                 :         unsigned char* to_copy;
     232                 : 
     233             122 :         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             122 :         if (ldi->avail_in_this_block < len)
     243               0 :             copy_this = (uInt)ldi->avail_in_this_block;
     244                 :         else
     245             122 :             copy_this = (uInt)len;
     246                 : 
     247             122 :         to_copy = &(ldi->data[ldi->filled_in_this_block]);
     248                 : 
     249           10422 :         for (i=0;i<copy_this;i++)
     250           10300 :             *(to_copy+i)=*(from_copy+i);
     251                 : 
     252             122 :         ldi->filled_in_this_block += copy_this;
     253             122 :         ldi->avail_in_this_block -= copy_this;
     254             122 :         from_copy += copy_this ;
     255             122 :         len -= copy_this;
     256                 :     }
     257             122 :     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            1718 : 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            7130 :     for (n = 0; n < nbByte; n++)
     279                 :     {
     280            5412 :         buf[n] = (unsigned char)(x & 0xff);
     281            5412 :         x >>= 8;
     282                 :     }
     283            1718 :     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            1718 :     if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
     292               0 :         return ZIP_ERRNO;
     293                 :     else
     294            1718 :         return ZIP_OK;
     295                 : }
     296                 : 
     297                 : local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
     298            2176 : local void ziplocal_putValue_inmemory (void *dest, uLong x, int nbByte)
     299                 : {
     300            2176 :     unsigned char* buf=(unsigned char*)dest;
     301                 :     int n;
     302            8728 :     for (n = 0; n < nbByte; n++) {
     303            6552 :         buf[n] = (unsigned char)(x & 0xff);
     304            6552 :         x >>= 8;
     305                 :     }
     306                 : 
     307            2176 :     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            2176 : }
     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             264 : local int ziplocal_getByte(const zlib_filefunc_def* pzlib_filefunc_def,
     340                 :                            voidpf filestream, int *pi)
     341                 : {
     342                 :     unsigned char c;
     343             264 :     int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
     344             264 :     if (err==1)
     345                 :     {
     346             264 :         *pi = (int)c;
     347             264 :         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              60 : 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              60 :     err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
     375              60 :     x = (uLong)i;
     376                 : 
     377              60 :     if (err==ZIP_OK)
     378              60 :         err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
     379              60 :     x += ((uLong)i)<<8;
     380                 : 
     381              60 :     if (err==ZIP_OK)
     382              60 :         *pX = x;
     383                 :     else
     384               0 :         *pX = 0;
     385              60 :     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              36 : 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              36 :     err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
     403              36 :     x = (uLong)i;
     404                 : 
     405              36 :     if (err==ZIP_OK)
     406              36 :         err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
     407              36 :     x += ((uLong)i)<<8;
     408                 : 
     409              36 :     if (err==ZIP_OK)
     410              36 :         err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
     411              36 :     x += ((uLong)i)<<16;
     412                 : 
     413              36 :     if (err==ZIP_OK)
     414              36 :         err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
     415              36 :     x += ((uLong)i)<<24;
     416                 : 
     417              36 :     if (err==ZIP_OK)
     418              36 :         *pX = x;
     419                 :     else
     420               0 :         *pX = 0;
     421              36 :     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              12 : 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              12 :     uLong uMaxBack=0xffff; /* maximum size of global comment */
     443              12 :     uLong uPosFound=0;
     444                 : 
     445              12 :     if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
     446               0 :         return 0;
     447                 : 
     448                 : 
     449              12 :     uSizeFile = (uLong) ZTELL(*pzlib_filefunc_def,filestream);
     450                 : 
     451              12 :     if (uMaxBack>uSizeFile)
     452              12 :         uMaxBack = uSizeFile;
     453                 : 
     454              12 :     buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
     455              12 :     if (buf==NULL)
     456               0 :         return 0;
     457                 : 
     458              12 :     uBackRead = 4;
     459              24 :     while (uBackRead<uMaxBack)
     460                 :     {
     461                 :         uLong uReadSize,uReadPos ;
     462                 :         int i;
     463              12 :         if (uBackRead+BUFREADCOMMENT>uMaxBack)
     464               8 :             uBackRead = uMaxBack;
     465                 :         else
     466               4 :             uBackRead+=BUFREADCOMMENT;
     467              12 :         uReadPos = uSizeFile-uBackRead ;
     468                 : 
     469                 :         uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
     470              12 :                      (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
     471              12 :         if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
     472               0 :             break;
     473                 : 
     474              12 :         if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
     475               0 :             break;
     476                 : 
     477             240 :         for (i=(int)uReadSize-3; (i--)>0;)
     478             228 :             if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
     479                 :                 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
     480                 :             {
     481              12 :                 uPosFound = uReadPos+i;
     482              12 :                 break;
     483                 :             }
     484                 : 
     485              12 :         if (uPosFound!=0)
     486              12 :             break;
     487                 :     }
     488              12 :     TRYFREE(buf);
     489              12 :     return uPosFound;
     490                 : }
     491                 : #endif /* !NO_ADDFILEINEXISTINGZIP*/
     492                 : 
     493                 : /************************************************************/
     494              36 : 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              36 :     int err=ZIP_OK;
     503                 : 
     504                 : 
     505              36 :     if (pzlib_filefunc_def==NULL)
     506              36 :         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              36 :                     (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
     516                 : 
     517              36 :     if (ziinit.filestream == NULL)
     518               0 :         return NULL;
     519              36 :     ziinit.begin_pos = (uLong) ZTELL(ziinit.z_filefunc,ziinit.filestream);
     520              36 :     ziinit.in_opened_file_inzip = 0;
     521              36 :     ziinit.ci.stream_initialised = 0;
     522              36 :     ziinit.number_entry = 0;
     523              36 :     ziinit.add_position_when_writting_offset = 0;
     524              36 :     init_linkedlist(&(ziinit.central_dir));
     525                 : 
     526                 : 
     527              36 :     zi = (zip_internal*)ALLOC(sizeof(zip_internal));
     528              36 :     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              36 :     ziinit.globalcomment = NULL;
     537              36 :     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              12 :         central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);
     556              12 :         if (central_pos==0)
     557               0 :             err=ZIP_ERRNO;
     558                 : 
     559              12 :         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              12 :         if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK)
     565               0 :             err=ZIP_ERRNO;
     566                 : 
     567                 :         /* number of this disk */
     568              12 :         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              12 :         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              12 :         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              12 :         if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK)
     581               0 :             err=ZIP_ERRNO;
     582                 : 
     583              12 :         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              12 :         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              12 :         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              12 :         if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK)
     599               0 :             err=ZIP_ERRNO;
     600                 : 
     601              12 :         if ((central_pos<offset_central_dir+size_central_dir) &&
     602                 :             (err==ZIP_OK))
     603               0 :             err=ZIP_BADZIPFILE;
     604                 : 
     605              12 :         if (err!=ZIP_OK)
     606                 :         {
     607               0 :             ZCLOSE(ziinit.z_filefunc, ziinit.filestream);
     608               0 :             return NULL;
     609                 :         }
     610                 : 
     611              12 :         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              12 :                                 (offset_central_dir+size_central_dir);
     623              12 :         ziinit.add_position_when_writting_offset = byte_before_the_zipfile;
     624                 : 
     625                 :         {
     626              12 :             uLong size_central_dir_to_read = size_central_dir;
     627              12 :             size_t buf_size = SIZEDATA_INDATABLOCK;
     628              12 :             void* buf_read = (void*)ALLOC(buf_size);
     629              12 :             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              36 :             while ((size_central_dir_to_read>0) && (err==ZIP_OK))
     635                 :             {
     636              12 :                 uLong read_this = SIZEDATA_INDATABLOCK;
     637              12 :                 if (read_this > size_central_dir_to_read)
     638              12 :                     read_this = size_central_dir_to_read;
     639              12 :                 if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this)
     640               0 :                     err=ZIP_ERRNO;
     641                 : 
     642              12 :                 if (err==ZIP_OK)
     643                 :                     err = add_data_in_datablock(&ziinit.central_dir,buf_read,
     644              12 :                                                 (uLong)read_this);
     645              12 :                 size_central_dir_to_read-=read_this;
     646                 :             }
     647              12 :             TRYFREE(buf_read);
     648                 :         }
     649              12 :         ziinit.begin_pos = byte_before_the_zipfile;
     650              12 :         ziinit.number_entry = number_entry_CD;
     651                 : 
     652              12 :         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              36 :     if (globalcomment)
     658                 :     {
     659               0 :       *globalcomment = ziinit.globalcomment;
     660                 :     }
     661                 : #    endif /* !NO_ADDFILEINEXISTINGZIP*/
     662                 : 
     663              36 :     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              36 :         *zi = ziinit;
     674              36 :         return (zipFile)zi;
     675                 :     }
     676                 : }
     677                 : 
     678              36 : extern zipFile ZEXPORT cpl_zipOpen (const char *pathname, int append)
     679                 : {
     680              36 :     return cpl_zipOpen2(pathname,append,NULL,NULL);
     681                 : }
     682                 : 
     683             110 : 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             110 :     int err = ZIP_OK;
     706                 : 
     707                 : #    ifdef NOCRYPT
     708             110 :     if (password != NULL)
     709               0 :         return ZIP_PARAMERROR;
     710                 : #    endif
     711                 : 
     712             110 :     if (file == NULL)
     713               0 :         return ZIP_PARAMERROR;
     714             110 :     if ((method!=0) && (method!=Z_DEFLATED))
     715               0 :         return ZIP_PARAMERROR;
     716                 : 
     717             110 :     zi = (zip_internal*)file;
     718                 : 
     719             110 :     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             110 :     if (filename==NULL)
     728               0 :         filename="-";
     729                 : 
     730             110 :     if (comment==NULL)
     731               0 :         size_comment = 0;
     732                 :     else
     733             110 :         size_comment = (uInt)strlen(comment);
     734                 : 
     735             110 :     size_filename = (uInt)strlen(filename);
     736                 : 
     737             110 :     if (zipfi == NULL)
     738             110 :         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             110 :     zi->ci.flag = 0;
     747             110 :     if ((level==8) || (level==9))
     748               0 :       zi->ci.flag |= 2;
     749             110 :     if (level==2)
     750               0 :       zi->ci.flag |= 4;
     751             110 :     if (level==1)
     752               0 :       zi->ci.flag |= 6;
     753             110 :     if (password != NULL)
     754               0 :       zi->ci.flag |= 1;
     755                 : 
     756             110 :     zi->ci.crc32 = 0;
     757             110 :     zi->ci.method = method;
     758             110 :     zi->ci.encrypt = 0;
     759             110 :     zi->ci.stream_initialised = 0;
     760             110 :     zi->ci.pos_in_buffered_data = 0;
     761             110 :     zi->ci.raw = raw;
     762             110 :     zi->ci.pos_local_header = (uLong) ZTELL(zi->z_filefunc,zi->filestream) ;
     763                 :     zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
     764             110 :                                       size_extrafield_global + size_comment;
     765             110 :     zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
     766                 : 
     767             110 :     ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
     768                 :     /* version info */
     769             110 :     ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
     770             110 :     ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
     771             110 :     ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
     772             110 :     ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
     773             110 :     ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
     774             110 :     ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
     775             110 :     ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
     776             110 :     ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
     777             110 :     ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
     778             110 :     ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
     779             110 :     ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
     780             110 :     ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
     781                 : 
     782             110 :     if (zipfi==NULL)
     783             110 :         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             110 :     if (zipfi==NULL)
     788             110 :         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             110 :     ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);
     793                 : 
     794            3455 :     for (i=0;i<size_filename;i++)
     795            3345 :         *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
     796                 : 
     797             110 :     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             110 :     for (i=0;i<size_comment;i++)
     802                 :         *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
     803               0 :               size_extrafield_global+i) = *(comment+i);
     804             110 :     if (zi->ci.central_header == NULL)
     805               0 :         return ZIP_INTERNALERROR;
     806                 : 
     807                 :     /* write the local header */
     808             110 :     err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);
     809                 : 
     810             110 :     if (err==ZIP_OK)
     811             110 :         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
     812             110 :     if (err==ZIP_OK)
     813             110 :         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
     814                 : 
     815             110 :     if (err==ZIP_OK)
     816             110 :         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
     817                 : 
     818             110 :     if (err==ZIP_OK)
     819             110 :         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
     820                 : 
     821             110 :     if (err==ZIP_OK)
     822             110 :         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
     823             110 :     if (err==ZIP_OK)
     824             110 :         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
     825             110 :     if (err==ZIP_OK)
     826             110 :         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
     827                 : 
     828             110 :     if (err==ZIP_OK)
     829             110 :         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
     830                 : 
     831             110 :     if (err==ZIP_OK)
     832             110 :         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);
     833                 : 
     834             110 :     if ((err==ZIP_OK) && (size_filename>0))
     835             110 :         if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
     836               0 :                 err = ZIP_ERRNO;
     837                 : 
     838             110 :     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             110 :     zi->ci.stream.avail_in = (uInt)0;
     844             110 :     zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
     845             110 :     zi->ci.stream.next_out = zi->ci.buffered_data;
     846             110 :     zi->ci.stream.total_in = 0;
     847             110 :     zi->ci.stream.total_out = 0;
     848                 : 
     849             110 :     if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
     850                 :     {
     851             108 :         zi->ci.stream.zalloc = (alloc_func)0;
     852             108 :         zi->ci.stream.zfree = (free_func)0;
     853             108 :         zi->ci.stream.opaque = (voidpf)0;
     854                 : 
     855             108 :         if (windowBits>0)
     856               0 :             windowBits = -windowBits;
     857                 : 
     858                 :         err = deflateInit2(&zi->ci.stream, level,
     859             108 :                Z_DEFLATED, windowBits, memLevel, strategy);
     860                 : 
     861             108 :         if (err==Z_OK)
     862             108 :             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             110 :     if (err==Z_OK)
     883             110 :         zi->in_opened_file_inzip = 1;
     884             110 :     return err;
     885                 : }
     886                 : 
     887             110 : 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             110 :                                  NULL, 0);
     906                 : }
     907                 : 
     908             110 : 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             110 :                                  comment, method, level, 0);
     924                 : }
     925                 : 
     926             125 : local int zipFlushWriteBuffer(
     927                 :     zip_internal* zi )
     928                 : {
     929             125 :     int err=ZIP_OK;
     930                 : 
     931             125 :     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             125 :     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             125 :     zi->ci.pos_in_buffered_data = 0;
     945             125 :     return err;
     946                 : }
     947                 : 
     948            2398 : extern int ZEXPORT cpl_zipWriteInFileInZip (
     949                 :     zipFile file,
     950                 :     const void* buf,
     951                 :     unsigned len )
     952                 : {
     953                 :     zip_internal* zi;
     954            2398 :     int err=ZIP_OK;
     955                 : 
     956            2398 :     if (file == NULL)
     957               0 :         return ZIP_PARAMERROR;
     958            2398 :     zi = (zip_internal*)file;
     959                 : 
     960            2398 :     if (zi->in_opened_file_inzip == 0)
     961               0 :         return ZIP_PARAMERROR;
     962                 : 
     963            2398 :     zi->ci.stream.next_in = (Bytef*)buf;
     964            2398 :     zi->ci.stream.avail_in = len;
     965            2398 :     zi->ci.crc32 = crc32(zi->ci.crc32,(const Bytef *) buf,len);
     966                 : 
     967            7194 :     while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
     968                 :     {
     969            2398 :         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            2398 :         if(err != ZIP_OK)
     979               0 :             break;
     980                 : 
     981            4794 :         if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
     982                 :         {
     983            2396 :             uLong uTotalOutBefore = zi->ci.stream.total_out;
     984            2396 :             err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
     985            2396 :             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            2398 :     return err;
    1011                 : }
    1012                 : 
    1013             110 : 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             110 :     int err=ZIP_OK;
    1021                 : 
    1022             110 :     if (file == NULL)
    1023               0 :         return ZIP_PARAMERROR;
    1024             110 :     zi = (zip_internal*)file;
    1025                 : 
    1026             110 :     if (zi->in_opened_file_inzip == 0)
    1027               0 :         return ZIP_PARAMERROR;
    1028             110 :     zi->ci.stream.avail_in = 0;
    1029                 : 
    1030             110 :     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
    1031             324 :         while (err==ZIP_OK)
    1032                 :     {
    1033                 :         uLong uTotalOutBefore;
    1034             108 :         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             108 :         uTotalOutBefore = zi->ci.stream.total_out;
    1042             108 :         err=deflate(&zi->ci.stream,  Z_FINISH);
    1043             108 :         zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
    1044                 :     }
    1045                 : 
    1046             110 :     if (err==Z_STREAM_END)
    1047             108 :         err=ZIP_OK; /* this is normal */
    1048                 : 
    1049             110 :     if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
    1050             110 :         if (zipFlushWriteBuffer(zi)==ZIP_ERRNO)
    1051               0 :             err = ZIP_ERRNO;
    1052                 : 
    1053             110 :     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
    1054                 :     {
    1055             108 :         err=deflateEnd(&zi->ci.stream);
    1056             108 :         zi->ci.stream_initialised = 0;
    1057                 :     }
    1058                 : 
    1059             110 :     if (!zi->ci.raw)
    1060                 :     {
    1061             110 :         crc32 = (uLong)zi->ci.crc32;
    1062             110 :         uncompressed_size = (uLong)zi->ci.stream.total_in;
    1063                 :     }
    1064             110 :     compressed_size = (uLong)zi->ci.stream.total_out;
    1065                 : #    ifndef NOCRYPT
    1066                 :     compressed_size += zi->ci.crypt_header_size;
    1067                 : #    endif
    1068                 : 
    1069             110 :     ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
    1070                 :     ziplocal_putValue_inmemory(zi->ci.central_header+20,
    1071             110 :                                 compressed_size,4); /*compr size*/
    1072             110 :     if (zi->ci.stream.data_type == Z_ASCII)
    1073              86 :         ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
    1074                 :     ziplocal_putValue_inmemory(zi->ci.central_header+24,
    1075             110 :                                 uncompressed_size,4); /*uncompr size*/
    1076                 : 
    1077             110 :     if (err==ZIP_OK)
    1078                 :         err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
    1079             110 :                                        (uLong)zi->ci.size_centralheader);
    1080             110 :     free(zi->ci.central_header);
    1081                 : 
    1082             110 :     if (err==ZIP_OK)
    1083                 :     {
    1084             110 :         long cur_pos_inzip = (uLong) ZTELL(zi->z_filefunc,zi->filestream);
    1085             110 :         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             110 :         if (err==ZIP_OK)
    1090             110 :             err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
    1091                 : 
    1092             110 :         if (err==ZIP_OK) /* compressed size, unknown */
    1093             110 :             err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
    1094                 : 
    1095             110 :         if (err==ZIP_OK) /* uncompressed size, unknown */
    1096             110 :             err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
    1097                 : 
    1098             110 :         if (ZSEEK(zi->z_filefunc,zi->filestream,
    1099                 :                   cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
    1100               0 :             err = ZIP_ERRNO;
    1101                 :     }
    1102                 : 
    1103             110 :     zi->number_entry ++;
    1104             110 :     zi->in_opened_file_inzip = 0;
    1105                 : 
    1106             110 :     return err;
    1107                 : }
    1108                 : 
    1109             110 : extern int ZEXPORT cpl_zipCloseFileInZip (
    1110                 :     zipFile file )
    1111                 : {
    1112             110 :     return cpl_zipCloseFileInZipRaw (file,0,0);
    1113                 : }
    1114                 : 
    1115              36 : extern int ZEXPORT cpl_zipClose (
    1116                 :     zipFile file,
    1117                 :     const char* global_comment)
    1118                 : {
    1119                 :     zip_internal* zi;
    1120              36 :     int err = 0;
    1121              36 :     uLong size_centraldir = 0;
    1122                 :     uLong centraldir_pos_inzip;
    1123                 :     uInt size_global_comment;
    1124              36 :     if (file == NULL)
    1125               0 :         return ZIP_PARAMERROR;
    1126              36 :     zi = (zip_internal*)file;
    1127                 : 
    1128              36 :     if (zi->in_opened_file_inzip == 1)
    1129                 :     {
    1130               0 :         err = cpl_zipCloseFileInZip (file);
    1131                 :     }
    1132                 : 
    1133                 : #ifndef NO_ADDFILEINEXISTINGZIP
    1134              36 :     if (global_comment==NULL)
    1135              36 :         global_comment = zi->globalcomment;
    1136                 : #endif
    1137              36 :     if (global_comment==NULL)
    1138              36 :         size_global_comment = 0;
    1139                 :     else
    1140               0 :         size_global_comment = (uInt)strlen(global_comment);
    1141                 : 
    1142              36 :     centraldir_pos_inzip = (uLong) ZTELL(zi->z_filefunc,zi->filestream);
    1143              36 :     if (err==ZIP_OK)
    1144                 :     {
    1145              36 :         linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
    1146             108 :         while (ldi!=NULL)
    1147                 :         {
    1148              36 :             if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
    1149              36 :                 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              36 :             size_centraldir += ldi->filled_in_this_block;
    1155              36 :             ldi = ldi->next_datablock;
    1156                 :         }
    1157                 :     }
    1158              36 :     free_datablock(zi->central_dir.first_block);
    1159                 : 
    1160              36 :     if (err==ZIP_OK) /* Magic End */
    1161              36 :         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
    1162                 : 
    1163              36 :     if (err==ZIP_OK) /* number of this disk */
    1164              36 :         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
    1165                 : 
    1166              36 :     if (err==ZIP_OK) /* number of the disk with the start of the central directory */
    1167              36 :         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
    1168                 : 
    1169              36 :     if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
    1170              36 :         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
    1171                 : 
    1172              36 :     if (err==ZIP_OK) /* total number of entries in the central dir */
    1173              36 :         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
    1174                 : 
    1175              36 :     if (err==ZIP_OK) /* size of the central directory */
    1176              36 :         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
    1177                 : 
    1178              36 :     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              36 :                                 (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
    1182                 : 
    1183              36 :     if (err==ZIP_OK) /* zipfile comment length */
    1184              36 :         err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
    1185                 : 
    1186              36 :     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              36 :     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              36 :     TRYFREE(zi->globalcomment);
    1197                 : #endif
    1198              36 :     TRYFREE(zi);
    1199                 : 
    1200              36 :     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                 : /************************************************************************/
    1211                 : /*                            CPLCreateZip()                            */
    1212                 : /************************************************************************/
    1213                 : 
    1214              36 : void *CPLCreateZip( const char *pszZipFilename, char **papszOptions )
    1215                 : 
    1216                 : {
    1217                 :     (void) papszOptions;
    1218                 : 
    1219              36 :     int bAppend = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "APPEND", "FALSE"));
    1220                 : 
    1221              36 :     return cpl_zipOpen( pszZipFilename, bAppend ? APPEND_STATUS_ADDINZIP : APPEND_STATUS_CREATE);
    1222                 : }
    1223                 : 
    1224                 : /************************************************************************/
    1225                 : /*                         CPLCreateFileInZip()                         */
    1226                 : /************************************************************************/
    1227                 : 
    1228             110 : CPLErr CPLCreateFileInZip( void *hZip, const char *pszFilename, 
    1229                 :                            char **papszOptions )
    1230                 : 
    1231                 : {
    1232                 :     int  nErr;
    1233                 : 
    1234                 :     (void) papszOptions;
    1235                 : 
    1236             110 :     if( hZip == NULL )
    1237               0 :         return CE_Failure;
    1238                 : 
    1239             110 :     int bCompressed = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "COMPRESSED", "TRUE"));
    1240                 : 
    1241                 :     nErr = cpl_zipOpenNewFileInZip( (zipFile) hZip, pszFilename, NULL, 
    1242                 :                                     NULL, 0, NULL, 0, "", 
    1243             110 :                                     bCompressed ? Z_DEFLATED : 0, bCompressed ? Z_DEFAULT_COMPRESSION : 0 );
    1244                 :     
    1245             110 :     if( nErr != ZIP_OK )
    1246               0 :         return CE_Failure;
    1247                 :     else
    1248             110 :         return CE_None;
    1249                 : }
    1250                 : 
    1251                 : /************************************************************************/
    1252                 : /*                         CPLWriteFileInZip()                          */
    1253                 : /************************************************************************/
    1254                 : 
    1255            2398 : CPLErr CPLWriteFileInZip( void *hZip, const void *pBuffer, int nBufferSize )
    1256                 : 
    1257                 : {
    1258                 :     int nErr;
    1259                 :     
    1260                 :     nErr = cpl_zipWriteInFileInZip( (zipFile) hZip, pBuffer, 
    1261            2398 :                                     (unsigned int) nBufferSize );
    1262                 : 
    1263            2398 :     if( nErr != ZIP_OK )
    1264               0 :         return CE_Failure;
    1265                 :     else
    1266            2398 :         return CE_None;
    1267                 : }
    1268                 : 
    1269                 : /************************************************************************/
    1270                 : /*                         CPLCloseFileInZip()                          */
    1271                 : /************************************************************************/
    1272                 : 
    1273             110 : CPLErr CPLCloseFileInZip( void *hZip )
    1274                 : 
    1275                 : {
    1276                 :     int nErr;
    1277                 : 
    1278             110 :     nErr = cpl_zipCloseFileInZip( (zipFile) hZip );
    1279                 : 
    1280             110 :     if( nErr != ZIP_OK )
    1281               0 :         return CE_Failure;
    1282                 :     else
    1283             110 :         return CE_None;
    1284                 : }
    1285                 : 
    1286                 : /************************************************************************/
    1287                 : /*                            CPLCloseZip()                             */
    1288                 : /************************************************************************/
    1289                 : 
    1290              36 : CPLErr CPLCloseZip( void *hZip )
    1291                 : 
    1292                 : {
    1293                 :     int nErr;
    1294                 : 
    1295              36 :     nErr = cpl_zipClose((zipFile) hZip, NULL);
    1296                 : 
    1297              36 :     if( nErr != ZIP_OK )
    1298               0 :         return CE_Failure;
    1299                 :     else
    1300              36 :         return CE_None;
    1301                 : }

Generated by: LCOV version 1.7