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