00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifdef HAVE_CONFIG_H
00011 # include <config.h>
00012 #endif
00013
00014 #ifdef HAVE_ZIP_SUPPORT
00015
00016 #include <stdio.h>
00017 #include <stdlib.h>
00018 #include <string.h>
00019 #include "zlib.h"
00020 #include "zip.h"
00021
00022
00023 #if MAX_MEM_LEVEL >= 8
00024 # define DEF_MEM_LEVEL 8
00025 #else
00026 # define DEF_MEM_LEVEL MAX_MEM_LEVEL
00027 #endif
00028
00029 #ifdef STDC
00030 # include <stddef.h>
00031 # include <string.h>
00032 # include <stdlib.h>
00033 #endif
00034 #ifdef NO_ERRNO_H
00035 extern int errno;
00036 #else
00037 # include <errno.h>
00038 #endif
00039
00040
00041 #if defined(MACOS) || defined(TARGET_OS_MAC)
00042 typedef unsigned char Byte;
00043 #endif
00044
00045 #ifndef VERSIONMADEBY
00046 # define VERSIONMADEBY (0x0)
00047 #endif
00048
00049 #ifndef Z_BUFSIZE
00050 #define Z_BUFSIZE (16384)
00051 #endif
00052
00053 #ifndef Z_MAXFILENAMEINZIP
00054 #define Z_MAXFILENAMEINZIP (256)
00055 #endif
00056
00057 #ifndef ALLOC
00058 # define ALLOC(size) (malloc(size))
00059 #endif
00060 #ifndef TRYFREE
00061 # define TRYFREE(p) {if (p) free(p);}
00062 #endif
00063
00064
00065
00066
00067
00068
00069
00070
00071 #ifndef SEEK_CUR
00072 #define SEEK_CUR 1
00073 #endif
00074
00075 #ifndef SEEK_END
00076 #define SEEK_END 2
00077 #endif
00078
00079 #ifndef SEEK_SET
00080 #define SEEK_SET 0
00081 #endif
00082
00083 const char zip_copyright[] =
00084 " zip 0.15 Copyright 1998 Gilles Vollant ";
00085
00086
00087 #define SIZEDATA_INDATABLOCK (4096-(4*4))
00088
00089 #define LOCALHEADERMAGIC (0x04034b50)
00090 #define CENTRALHEADERMAGIC (0x02014b50)
00091 #define ENDHEADERMAGIC (0x06054b50)
00092
00093 #define FLAG_LOCALHEADER_OFFSET (0x06)
00094 #define CRC_LOCALHEADER_OFFSET (0x0e)
00095
00096 #define SIZECENTRALHEADER (0x2e)
00097
00098 typedef struct linkedlist_datablock_internal_s
00099 {
00100 struct linkedlist_datablock_internal_s* next_datablock;
00101 uLong avail_in_this_block;
00102 uLong filled_in_this_block;
00103 uLong unused;
00104 unsigned char data[SIZEDATA_INDATABLOCK];
00105 } linkedlist_datablock_internal;
00106
00107 typedef struct linkedlist_data_s
00108 {
00109 linkedlist_datablock_internal* first_block;
00110 linkedlist_datablock_internal* last_block;
00111 } linkedlist_data;
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 Byte buffered_data[Z_BUFSIZE];
00127 uLong dosDate;
00128 uLong crc32;
00129 } curfile_info;
00130
00131 typedef struct
00132 {
00133 FILE * filezip;
00134 linkedlist_data central_dir;
00135 int in_opened_file_inzip;
00136 curfile_info ci;
00137
00138 uLong begin_pos;
00139 uLong number_entry;
00140 } zip_internal;
00141
00142 static linkedlist_datablock_internal* allocate_new_datablock()
00143 {
00144 linkedlist_datablock_internal* ldi;
00145 ldi = (linkedlist_datablock_internal*)
00146 ALLOC(sizeof(linkedlist_datablock_internal));
00147 if (ldi!=NULL)
00148 {
00149 ldi->next_datablock = NULL ;
00150 ldi->filled_in_this_block = 0 ;
00151 ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
00152 }
00153 return ldi;
00154 }
00155
00156 static void free_datablock(linkedlist_datablock_internal* ldi)
00157 {
00158 while (ldi!=NULL)
00159 {
00160 linkedlist_datablock_internal* ldinext = ldi->next_datablock;
00161 TRYFREE(ldi);
00162 ldi = ldinext;
00163 }
00164 }
00165
00166 static void init_linkedlist(linkedlist_data* ll)
00167 {
00168 ll->first_block = ll->last_block = NULL;
00169 }
00170
00171 static void free_linkedlist(linkedlist_data* ll)
00172 {
00173 free_datablock(ll->first_block);
00174 ll->first_block = ll->last_block = NULL;
00175 }
00176
00177
00178 static int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
00179 {
00180 linkedlist_datablock_internal* ldi;
00181 const unsigned char* from_copy;
00182
00183 if (ll==NULL)
00184 return ZIP_INTERNALERROR;
00185
00186 if (ll->last_block == NULL)
00187 {
00188 ll->first_block = ll->last_block = allocate_new_datablock();
00189 if (ll->first_block == NULL)
00190 return ZIP_INTERNALERROR;
00191 }
00192
00193 ldi = ll->last_block;
00194 from_copy = (unsigned char*)buf;
00195
00196 while (len>0)
00197 {
00198 uInt copy_this;
00199 uInt i;
00200 unsigned char* to_copy;
00201
00202 if (ldi->avail_in_this_block==0)
00203 {
00204 ldi->next_datablock = allocate_new_datablock();
00205 if (ldi->next_datablock == NULL)
00206 return ZIP_INTERNALERROR;
00207 ldi = ldi->next_datablock ;
00208 ll->last_block = ldi;
00209 }
00210
00211 if (ldi->avail_in_this_block < len)
00212 copy_this = (uInt)ldi->avail_in_this_block;
00213 else
00214 copy_this = (uInt)len;
00215
00216 to_copy = &(ldi->data[ldi->filled_in_this_block]);
00217
00218 for (i=0;i<copy_this;i++)
00219 *(to_copy+i)=*(from_copy+i);
00220
00221 ldi->filled_in_this_block += copy_this;
00222 ldi->avail_in_this_block -= copy_this;
00223 from_copy += copy_this ;
00224 len -= copy_this;
00225 }
00226 return ZIP_OK;
00227 }
00228
00229
00230 static int write_datablock(FILE* fout, linkedlist_data* ll)
00231 {
00232 linkedlist_datablock_internal* ldi;
00233 ldi = ll->first_block;
00234 while (ldi!=NULL)
00235 {
00236 if (ldi->filled_in_this_block > 0)
00237 if (fwrite(ldi->data,(uInt)ldi->filled_in_this_block,1,fout)!=1)
00238 return ZIP_ERRNO;
00239 ldi = ldi->next_datablock;
00240 }
00241 return ZIP_OK;
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251 static int ziplocal_putValue (FILE *file, uLong x, int nbByte);
00252 static int ziplocal_putValue (FILE *file, uLong x, int nbByte)
00253 {
00254 unsigned char buf[4];
00255 int n;
00256 for (n = 0; n < nbByte; n++) {
00257 buf[n] = (unsigned char)(x & 0xff);
00258 x >>= 8;
00259 }
00260 if (fwrite(buf,nbByte,1,file)!=1)
00261 return ZIP_ERRNO;
00262 else
00263 return ZIP_OK;
00264 }
00265
00266 static void ziplocal_putValue_inmemory (void* dest, uLong x, int nbByte);
00267 static void ziplocal_putValue_inmemory (void* dest, uLong x, int nbByte)
00268 {
00269 unsigned char* buf=(unsigned char*)dest;
00270 int n;
00271 for (n = 0; n < nbByte; n++) {
00272 buf[n] = (unsigned char)(x & 0xff);
00273 x >>= 8;
00274 }
00275 }
00276
00277
00278
00279 static uLong ziplocal_TmzDateToDosDate(const tm_zip* ptm, uLong uLongdosDate)
00280 {
00281 uLong year = (uLong)ptm->tm_year;
00282 if (year>1980)
00283 year-=1980;
00284 else if (year>80)
00285 year-=80;
00286 return
00287 (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
00288 ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
00289 }
00290
00291
00292
00293
00294 extern zipFile ZEXPORT zipOpen (const char *pathname, int append)
00295 {
00296 zip_internal ziinit;
00297 zip_internal* zi;
00298
00299 ziinit.filezip = NULL;
00300
00301
00302
00303
00304 if (append != 0)
00305 ziinit.filezip = fopen(pathname,"r+b");
00306
00307
00308 if (ziinit.filezip == NULL)
00309 ziinit.filezip = fopen(pathname,"wb");
00310
00311
00312 if (ziinit.filezip == NULL)
00313 return NULL;
00314
00315
00316 fseek (ziinit.filezip, 0, SEEK_END);
00317
00318
00319
00320 ziinit.begin_pos = ftell(ziinit.filezip);
00321 ziinit.in_opened_file_inzip = 0;
00322 ziinit.ci.stream_initialised = 0;
00323 ziinit.number_entry = 0;
00324 init_linkedlist(&(ziinit.central_dir));
00325
00326
00327 zi = (zip_internal*)ALLOC(sizeof(zip_internal));
00328 if (zi==NULL)
00329 {
00330 fclose(ziinit.filezip);
00331 return NULL;
00332 }
00333
00334 *zi = ziinit;
00335 return (zipFile)zi;
00336 }
00337
00338 extern int ZEXPORT zipOpenNewFileInZip (zipFile file,
00339 const char* filename,
00340 const zip_fileinfo* zipfi,
00341 const void* extrafield_local,
00342 uInt size_extrafield_local,
00343 const void* extrafield_global,
00344 uInt size_extrafield_global,
00345 const char* comment,
00346 int method,
00347 int level)
00348 {
00349 zip_internal* zi;
00350 uInt size_filename;
00351 uInt size_comment;
00352 uInt i;
00353 int err = ZIP_OK;
00354
00355 if (file == NULL)
00356 return ZIP_PARAMERROR;
00357 if ((method!=0) && (method!=Z_DEFLATED))
00358 return ZIP_PARAMERROR;
00359
00360 zi = (zip_internal*)file;
00361
00362 if (zi->in_opened_file_inzip == 1)
00363 {
00364 err = zipCloseFileInZip (file);
00365 if (err != ZIP_OK)
00366 return err;
00367 }
00368
00369
00370 if (filename==NULL)
00371 filename="-";
00372
00373 if (comment==NULL)
00374 size_comment = 0;
00375 else
00376 size_comment = strlen(comment);
00377
00378 size_filename = strlen(filename);
00379
00380 if (zipfi == NULL)
00381 zi->ci.dosDate = 0;
00382 else
00383 {
00384 if (zipfi->dosDate != 0)
00385 zi->ci.dosDate = zipfi->dosDate;
00386 else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
00387 }
00388
00389 zi->ci.flag = 0;
00390 if ((level==8) || (level==9))
00391 zi->ci.flag |= 2;
00392 if ((level==2))
00393 zi->ci.flag |= 4;
00394 if ((level==1))
00395 zi->ci.flag |= 6;
00396
00397 zi->ci.crc32 = 0;
00398 zi->ci.method = method;
00399 zi->ci.stream_initialised = 0;
00400 zi->ci.pos_in_buffered_data = 0;
00401 zi->ci.pos_local_header = ftell(zi->filezip);
00402 zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
00403 size_extrafield_global + size_comment;
00404 zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
00405
00406 ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
00407
00408 ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
00409 ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
00410 ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
00411 ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
00412 ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
00413 ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4);
00414 ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4);
00415 ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4);
00416 ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
00417 ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
00418 ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
00419 ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2);
00420
00421 if (zipfi==NULL)
00422 ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
00423 else
00424 ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
00425
00426 if (zipfi==NULL)
00427 ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
00428 else
00429 ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
00430
00431 ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header,4);
00432
00433 for (i=0;i<size_filename;i++)
00434 *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
00435
00436 for (i=0;i<size_extrafield_global;i++)
00437 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
00438 *(((const char*)extrafield_global)+i);
00439
00440 for (i=0;i<size_comment;i++)
00441 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
00442 size_extrafield_global+i) = *(filename+i);
00443 if (zi->ci.central_header == NULL)
00444 return ZIP_INTERNALERROR;
00445
00446
00447 err = ziplocal_putValue(zi->filezip,(uLong)LOCALHEADERMAGIC,4);
00448
00449 if (err==ZIP_OK)
00450 err = ziplocal_putValue(zi->filezip,(uLong)20,2);
00451 if (err==ZIP_OK)
00452 err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.flag,2);
00453
00454 if (err==ZIP_OK)
00455 err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.method,2);
00456
00457 if (err==ZIP_OK)
00458 err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.dosDate,4);
00459
00460 if (err==ZIP_OK)
00461 err = ziplocal_putValue(zi->filezip,(uLong)0,4);
00462 if (err==ZIP_OK)
00463 err = ziplocal_putValue(zi->filezip,(uLong)0,4);
00464 if (err==ZIP_OK)
00465 err = ziplocal_putValue(zi->filezip,(uLong)0,4);
00466
00467 if (err==ZIP_OK)
00468 err = ziplocal_putValue(zi->filezip,(uLong)size_filename,2);
00469
00470 if (err==ZIP_OK)
00471 err = ziplocal_putValue(zi->filezip,(uLong)size_extrafield_local,2);
00472
00473 if ((err==ZIP_OK) && (size_filename>0))
00474 if (fwrite(filename,(uInt)size_filename,1,zi->filezip)!=1)
00475 err = ZIP_ERRNO;
00476
00477 if ((err==ZIP_OK) && (size_extrafield_local>0))
00478 if (fwrite(extrafield_local,(uInt)size_extrafield_local,1,zi->filezip)
00479 !=1)
00480 err = ZIP_ERRNO;
00481
00482 zi->ci.stream.avail_in = (uInt)0;
00483 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
00484 zi->ci.stream.next_out = zi->ci.buffered_data;
00485 zi->ci.stream.total_in = 0;
00486 zi->ci.stream.total_out = 0;
00487
00488 if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED))
00489 {
00490 zi->ci.stream.zalloc = (alloc_func)0;
00491 zi->ci.stream.zfree = (free_func)0;
00492 zi->ci.stream.opaque = (voidpf)0;
00493
00494 err = deflateInit2(&zi->ci.stream, level,
00495 Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0);
00496
00497 if (err==Z_OK)
00498 zi->ci.stream_initialised = 1;
00499 }
00500
00501
00502 if (err==Z_OK)
00503 zi->in_opened_file_inzip = 1;
00504 return err;
00505 }
00506
00507 extern int ZEXPORT zipWriteInFileInZip (zipFile file, const voidp buf, unsigned len)
00508 {
00509 zip_internal* zi;
00510 int err=ZIP_OK;
00511
00512 if (file == NULL)
00513 return ZIP_PARAMERROR;
00514 zi = (zip_internal*)file;
00515
00516 if (zi->in_opened_file_inzip == 0)
00517 return ZIP_PARAMERROR;
00518
00519 zi->ci.stream.next_in = (Bytef *)buf;
00520 zi->ci.stream.avail_in = len;
00521 zi->ci.crc32 = crc32(zi->ci.crc32,(Bytef *)buf,len);
00522
00523 while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
00524 {
00525 if (zi->ci.stream.avail_out == 0)
00526 {
00527 if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip)
00528 !=1)
00529 err = ZIP_ERRNO;
00530 zi->ci.pos_in_buffered_data = 0;
00531 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
00532 zi->ci.stream.next_out = zi->ci.buffered_data;
00533 }
00534
00535 if (zi->ci.method == Z_DEFLATED)
00536 {
00537 uLong uTotalOutBefore = zi->ci.stream.total_out;
00538 err=deflate(&zi->ci.stream, Z_NO_FLUSH);
00539 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
00540
00541 }
00542 else
00543 {
00544 uInt copy_this,i;
00545 if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
00546 copy_this = zi->ci.stream.avail_in;
00547 else
00548 copy_this = zi->ci.stream.avail_out;
00549 for (i=0;i<copy_this;i++)
00550 *(((char*)zi->ci.stream.next_out)+i) =
00551 *(((const char*)zi->ci.stream.next_in)+i);
00552 {
00553 zi->ci.stream.avail_in -= copy_this;
00554 zi->ci.stream.avail_out-= copy_this;
00555 zi->ci.stream.next_in+= copy_this;
00556 zi->ci.stream.next_out+= copy_this;
00557 zi->ci.stream.total_in+= copy_this;
00558 zi->ci.stream.total_out+= copy_this;
00559 zi->ci.pos_in_buffered_data += copy_this;
00560 }
00561 }
00562 }
00563
00564 return 0;
00565 }
00566
00567 extern int ZEXPORT zipCloseFileInZip (zipFile file)
00568 {
00569 zip_internal* zi;
00570 int err=ZIP_OK;
00571
00572 if (file == NULL)
00573 return ZIP_PARAMERROR;
00574 zi = (zip_internal*)file;
00575
00576 if (zi->in_opened_file_inzip == 0)
00577 return ZIP_PARAMERROR;
00578 zi->ci.stream.avail_in = 0;
00579
00580 if (zi->ci.method == Z_DEFLATED)
00581 while (err==ZIP_OK)
00582 {
00583 uLong uTotalOutBefore;
00584 if (zi->ci.stream.avail_out == 0)
00585 {
00586 if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip)
00587 !=1)
00588 err = ZIP_ERRNO;
00589 zi->ci.pos_in_buffered_data = 0;
00590 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
00591 zi->ci.stream.next_out = zi->ci.buffered_data;
00592 }
00593 uTotalOutBefore = zi->ci.stream.total_out;
00594 err=deflate(&zi->ci.stream, Z_FINISH);
00595 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
00596 }
00597
00598 if (err==Z_STREAM_END)
00599 err=ZIP_OK;
00600
00601 if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
00602 if (fwrite(zi->ci.buffered_data,(uInt)zi->ci.pos_in_buffered_data,1,zi->filezip)
00603 !=1)
00604 err = ZIP_ERRNO;
00605
00606 if ((zi->ci.method == Z_DEFLATED) && (err==ZIP_OK))
00607 {
00608 err=deflateEnd(&zi->ci.stream);
00609 zi->ci.stream_initialised = 0;
00610 }
00611
00612 ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)zi->ci.crc32,4);
00613 ziplocal_putValue_inmemory(zi->ci.central_header+20,
00614 (uLong)zi->ci.stream.total_out,4);
00615 ziplocal_putValue_inmemory(zi->ci.central_header+24,
00616 (uLong)zi->ci.stream.total_in,4);
00617
00618 if (err==ZIP_OK)
00619 err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
00620 (uLong)zi->ci.size_centralheader);
00621 free(zi->ci.central_header);
00622
00623 if (err==ZIP_OK)
00624 {
00625 long cur_pos_inzip = ftell(zi->filezip);
00626 if (fseek(zi->filezip,
00627 zi->ci.pos_local_header + 14,SEEK_SET)!=0)
00628 err = ZIP_ERRNO;
00629
00630 if (err==ZIP_OK)
00631 err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.crc32,4);
00632
00633 if (err==ZIP_OK)
00634 err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.stream.total_out,4);
00635
00636 if (err==ZIP_OK)
00637 err = ziplocal_putValue(zi->filezip,(uLong)zi->ci.stream.total_in,4);
00638
00639 if (fseek(zi->filezip,
00640 cur_pos_inzip,SEEK_SET)!=0)
00641 err = ZIP_ERRNO;
00642 }
00643
00644 zi->number_entry ++;
00645 zi->in_opened_file_inzip = 0;
00646
00647 return err;
00648 }
00649
00650 extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
00651 {
00652 zip_internal* zi;
00653 int err = 0;
00654 uLong size_centraldir = 0;
00655 uLong centraldir_pos_inzip ;
00656 uInt size_global_comment;
00657 if (file == NULL)
00658 return ZIP_PARAMERROR;
00659 zi = (zip_internal*)file;
00660
00661 if (zi->in_opened_file_inzip == 1)
00662 {
00663 err = zipCloseFileInZip (file);
00664 }
00665
00666 if (global_comment==NULL)
00667 size_global_comment = 0;
00668 else
00669 size_global_comment = strlen(global_comment);
00670
00671
00672 centraldir_pos_inzip = ftell(zi->filezip);
00673 if (err==ZIP_OK)
00674 {
00675 linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
00676 while (ldi!=NULL)
00677 {
00678 if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
00679 if (fwrite(ldi->data,(uInt)ldi->filled_in_this_block,
00680 1,zi->filezip) !=1 )
00681 err = ZIP_ERRNO;
00682
00683 size_centraldir += ldi->filled_in_this_block;
00684 ldi = ldi->next_datablock;
00685 }
00686 }
00687 free_datablock(zi->central_dir.first_block);
00688
00689 if (err==ZIP_OK)
00690 err = ziplocal_putValue(zi->filezip,(uLong)ENDHEADERMAGIC,4);
00691
00692 if (err==ZIP_OK)
00693 err = ziplocal_putValue(zi->filezip,(uLong)0,2);
00694
00695 if (err==ZIP_OK)
00696 err = ziplocal_putValue(zi->filezip,(uLong)0,2);
00697
00698 if (err==ZIP_OK)
00699 err = ziplocal_putValue(zi->filezip,(uLong)zi->number_entry,2);
00700
00701 if (err==ZIP_OK)
00702 err = ziplocal_putValue(zi->filezip,(uLong)zi->number_entry,2);
00703
00704 if (err==ZIP_OK)
00705 err = ziplocal_putValue(zi->filezip,(uLong)size_centraldir,4);
00706
00707 if (err==ZIP_OK)
00708
00709 err = ziplocal_putValue(zi->filezip,(uLong)centraldir_pos_inzip ,4);
00710
00711 if (err==ZIP_OK)
00712 err = ziplocal_putValue(zi->filezip,(uLong)size_global_comment,2);
00713
00714 if ((err==ZIP_OK) && (size_global_comment>0))
00715 if (fwrite(global_comment,(uInt)size_global_comment,1,zi->filezip) !=1 )
00716 err = ZIP_ERRNO;
00717 fclose(zi->filezip);
00718 TRYFREE(zi);
00719
00720 return err;
00721 }
00722
00723
00724 #endif