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