zip.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281
  1. /* zip.c -- IO on .zip files using zlib
  2. Version 1.01e, February 12th, 2005
  3. 27 Dec 2004 Rolf Kalbermatter
  4. Modification to zipOpen2 to support globalComment retrieval.
  5. Copyright (C) 1998-2005 Gilles Vollant
  6. Read zip.h for more info
  7. Modified by Sergey A. Tachenov to integrate with Qt.
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <time.h>
  13. #include "zlib.h"
  14. #include "zip.h"
  15. #include "quazip_global.h"
  16. #ifdef STDC
  17. # include <stddef.h>
  18. # include <string.h>
  19. # include <stdlib.h>
  20. #endif
  21. #ifdef NO_ERRNO_H
  22. extern int errno;
  23. #else
  24. # include <errno.h>
  25. #endif
  26. #ifndef local
  27. # define local static
  28. #endif
  29. /* compile with -Dlocal if your debugger can't find static symbols */
  30. #ifndef VERSIONMADEBY
  31. # define VERSIONMADEBY (0x031e) /* best for standard pkware crypt */
  32. #endif
  33. #ifndef Z_BUFSIZE
  34. #define Z_BUFSIZE (16384)
  35. #endif
  36. #ifndef Z_MAXFILENAMEINZIP
  37. #define Z_MAXFILENAMEINZIP (256)
  38. #endif
  39. #ifndef ALLOC
  40. # define ALLOC(size) (malloc(size))
  41. #endif
  42. #ifndef TRYFREE
  43. # define TRYFREE(p) {if (p) free(p);}
  44. #endif
  45. /*
  46. #define SIZECENTRALDIRITEM (0x2e)
  47. #define SIZEZIPLOCALHEADER (0x1e)
  48. */
  49. /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
  50. #ifndef SEEK_CUR
  51. #define SEEK_CUR 1
  52. #endif
  53. #ifndef SEEK_END
  54. #define SEEK_END 2
  55. #endif
  56. #ifndef SEEK_SET
  57. #define SEEK_SET 0
  58. #endif
  59. #ifndef DEF_MEM_LEVEL
  60. #if MAX_MEM_LEVEL >= 8
  61. # define DEF_MEM_LEVEL 8
  62. #else
  63. # define DEF_MEM_LEVEL MAX_MEM_LEVEL
  64. #endif
  65. #endif
  66. const char zip_copyright[] =
  67. " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
  68. #define SIZEDATA_INDATABLOCK (4096-(4*4))
  69. #define LOCALHEADERMAGIC (0x04034b50)
  70. #define DESCRIPTORHEADERMAGIC (0x08074b50)
  71. #define CENTRALHEADERMAGIC (0x02014b50)
  72. #define ENDHEADERMAGIC (0x06054b50)
  73. #define FLAG_LOCALHEADER_OFFSET (0x06)
  74. #define CRC_LOCALHEADER_OFFSET (0x0e)
  75. #define SIZECENTRALHEADER (0x2e) /* 46 */
  76. typedef struct linkedlist_datablock_internal_s
  77. {
  78. struct linkedlist_datablock_internal_s* next_datablock;
  79. uLong avail_in_this_block;
  80. uLong filled_in_this_block;
  81. uLong unused; /* for future use and alignement */
  82. unsigned char data[SIZEDATA_INDATABLOCK];
  83. } linkedlist_datablock_internal;
  84. typedef struct linkedlist_data_s
  85. {
  86. linkedlist_datablock_internal* first_block;
  87. linkedlist_datablock_internal* last_block;
  88. } linkedlist_data;
  89. typedef struct
  90. {
  91. z_stream stream; /* zLib stream structure for inflate */
  92. int stream_initialised; /* 1 is stream is initialised */
  93. uInt pos_in_buffered_data; /* last written byte in buffered_data */
  94. uLong pos_local_header; /* offset of the local header of the file
  95. currenty writing */
  96. char* central_header; /* central header data for the current file */
  97. uLong size_centralheader; /* size of the central header for cur file */
  98. uLong flag; /* flag of the file currently writing */
  99. int method; /* compression method of file currenty wr.*/
  100. int raw; /* 1 for directly writing raw data */
  101. Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
  102. uLong dosDate;
  103. uLong crc32;
  104. int encrypt;
  105. #ifndef NOCRYPT
  106. unsigned long keys[3]; /* keys defining the pseudo-random sequence */
  107. const unsigned long* pcrc_32_tab;
  108. int crypt_header_size;
  109. #endif
  110. } curfile_info;
  111. typedef struct
  112. {
  113. zlib_filefunc_def z_filefunc;
  114. voidpf filestream; /* io structore of the zipfile */
  115. linkedlist_data central_dir;/* datablock with central dir in construction*/
  116. int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
  117. curfile_info ci; /* info on the file curretly writing */
  118. uLong begin_pos; /* position of the beginning of the zipfile */
  119. uLong add_position_when_writting_offset;
  120. uLong number_entry;
  121. #ifndef NO_ADDFILEINEXISTINGZIP
  122. char *globalcomment;
  123. #endif
  124. unsigned flags;
  125. } zip_internal;
  126. #ifndef NOCRYPT
  127. #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
  128. #include "crypt.h"
  129. #endif
  130. local linkedlist_datablock_internal* allocate_new_datablock()
  131. {
  132. linkedlist_datablock_internal* ldi;
  133. ldi = (linkedlist_datablock_internal*)
  134. ALLOC(sizeof(linkedlist_datablock_internal));
  135. if (ldi!=NULL)
  136. {
  137. ldi->next_datablock = NULL ;
  138. ldi->filled_in_this_block = 0 ;
  139. ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
  140. }
  141. return ldi;
  142. }
  143. local void free_datablock(ldi)
  144. linkedlist_datablock_internal* ldi;
  145. {
  146. while (ldi!=NULL)
  147. {
  148. linkedlist_datablock_internal* ldinext = ldi->next_datablock;
  149. TRYFREE(ldi);
  150. ldi = ldinext;
  151. }
  152. }
  153. local void init_linkedlist(ll)
  154. linkedlist_data* ll;
  155. {
  156. ll->first_block = ll->last_block = NULL;
  157. }
  158. #if 0 // unused
  159. local void free_linkedlist(ll)
  160. linkedlist_data* ll;
  161. {
  162. free_datablock(ll->first_block);
  163. ll->first_block = ll->last_block = NULL;
  164. }
  165. #endif
  166. local int add_data_in_datablock(ll,buf,len)
  167. linkedlist_data* ll;
  168. const void* buf;
  169. uLong len;
  170. {
  171. linkedlist_datablock_internal* ldi;
  172. const unsigned char* from_copy;
  173. if (ll==NULL)
  174. return ZIP_INTERNALERROR;
  175. if (ll->last_block == NULL)
  176. {
  177. ll->first_block = ll->last_block = allocate_new_datablock();
  178. if (ll->first_block == NULL)
  179. return ZIP_INTERNALERROR;
  180. }
  181. ldi = ll->last_block;
  182. from_copy = (unsigned char*)buf;
  183. while (len>0)
  184. {
  185. uInt copy_this;
  186. uInt i;
  187. unsigned char* to_copy;
  188. if (ldi->avail_in_this_block==0)
  189. {
  190. ldi->next_datablock = allocate_new_datablock();
  191. if (ldi->next_datablock == NULL)
  192. return ZIP_INTERNALERROR;
  193. ldi = ldi->next_datablock ;
  194. ll->last_block = ldi;
  195. }
  196. if (ldi->avail_in_this_block < len)
  197. copy_this = (uInt)ldi->avail_in_this_block;
  198. else
  199. copy_this = (uInt)len;
  200. to_copy = &(ldi->data[ldi->filled_in_this_block]);
  201. for (i=0;i<copy_this;i++)
  202. *(to_copy+i)=*(from_copy+i);
  203. ldi->filled_in_this_block += copy_this;
  204. ldi->avail_in_this_block -= copy_this;
  205. from_copy += copy_this ;
  206. len -= copy_this;
  207. }
  208. return ZIP_OK;
  209. }
  210. /****************************************************************************/
  211. #ifndef NO_ADDFILEINEXISTINGZIP
  212. /* ===========================================================================
  213. Inputs a long in LSB order to the given file
  214. nbByte == 1, 2 or 4 (byte, short or long)
  215. */
  216. local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def,
  217. voidpf filestream, uLong x, int nbByte));
  218. local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte)
  219. const zlib_filefunc_def* pzlib_filefunc_def;
  220. voidpf filestream;
  221. uLong x;
  222. int nbByte;
  223. {
  224. unsigned char buf[4];
  225. int n;
  226. for (n = 0; n < nbByte; n++)
  227. {
  228. buf[n] = (unsigned char)(x & 0xff);
  229. x >>= 8;
  230. }
  231. if (x != 0)
  232. { /* data overflow - hack for ZIP64 (X Roche) */
  233. for (n = 0; n < nbByte; n++)
  234. {
  235. buf[n] = 0xff;
  236. }
  237. }
  238. if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
  239. return ZIP_ERRNO;
  240. else
  241. return ZIP_OK;
  242. }
  243. local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
  244. local void ziplocal_putValue_inmemory (dest, x, nbByte)
  245. void* dest;
  246. uLong x;
  247. int nbByte;
  248. {
  249. unsigned char* buf=(unsigned char*)dest;
  250. int n;
  251. for (n = 0; n < nbByte; n++) {
  252. buf[n] = (unsigned char)(x & 0xff);
  253. x >>= 8;
  254. }
  255. if (x != 0)
  256. { /* data overflow - hack for ZIP64 */
  257. for (n = 0; n < nbByte; n++)
  258. {
  259. buf[n] = 0xff;
  260. }
  261. }
  262. }
  263. /****************************************************************************/
  264. local uLong ziplocal_TmzDateToDosDate(ptm,dosDate)
  265. const tm_zip* ptm;
  266. uLong dosDate UNUSED;
  267. {
  268. uLong year = (uLong)ptm->tm_year;
  269. if (year>1980)
  270. year-=1980;
  271. else if (year>80)
  272. year-=80;
  273. return
  274. (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
  275. ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
  276. }
  277. /****************************************************************************/
  278. local int ziplocal_getByte OF((
  279. const zlib_filefunc_def* pzlib_filefunc_def,
  280. voidpf filestream,
  281. int *pi));
  282. local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi)
  283. const zlib_filefunc_def* pzlib_filefunc_def;
  284. voidpf filestream;
  285. int *pi;
  286. {
  287. unsigned char c;
  288. int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
  289. if (err==1)
  290. {
  291. *pi = (int)c;
  292. return ZIP_OK;
  293. }
  294. else
  295. {
  296. if (ZERROR(*pzlib_filefunc_def,filestream))
  297. return ZIP_ERRNO;
  298. else
  299. return ZIP_EOF;
  300. }
  301. }
  302. /* ===========================================================================
  303. Reads a long in LSB order from the given gz_stream. Sets
  304. */
  305. local int ziplocal_getShort OF((
  306. const zlib_filefunc_def* pzlib_filefunc_def,
  307. voidpf filestream,
  308. uLong *pX));
  309. local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX)
  310. const zlib_filefunc_def* pzlib_filefunc_def;
  311. voidpf filestream;
  312. uLong *pX;
  313. {
  314. uLong x ;
  315. int i;
  316. int err;
  317. err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
  318. x = (uLong)i;
  319. if (err==ZIP_OK)
  320. err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
  321. x += ((uLong)i)<<8;
  322. if (err==ZIP_OK)
  323. *pX = x;
  324. else
  325. *pX = 0;
  326. return err;
  327. }
  328. local int ziplocal_getLong OF((
  329. const zlib_filefunc_def* pzlib_filefunc_def,
  330. voidpf filestream,
  331. uLong *pX));
  332. local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX)
  333. const zlib_filefunc_def* pzlib_filefunc_def;
  334. voidpf filestream;
  335. uLong *pX;
  336. {
  337. uLong x ;
  338. int i;
  339. int err;
  340. err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
  341. x = (uLong)i;
  342. if (err==ZIP_OK)
  343. err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
  344. x += ((uLong)i)<<8;
  345. if (err==ZIP_OK)
  346. err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
  347. x += ((uLong)i)<<16;
  348. if (err==ZIP_OK)
  349. err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
  350. x += ((uLong)i)<<24;
  351. if (err==ZIP_OK)
  352. *pX = x;
  353. else
  354. *pX = 0;
  355. return err;
  356. }
  357. #ifndef BUFREADCOMMENT
  358. #define BUFREADCOMMENT (0x400)
  359. #endif
  360. /*
  361. Locate the Central directory of a zipfile (at the end, just before
  362. the global comment)
  363. */
  364. local uLong ziplocal_SearchCentralDir OF((
  365. const zlib_filefunc_def* pzlib_filefunc_def,
  366. voidpf filestream));
  367. local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream)
  368. const zlib_filefunc_def* pzlib_filefunc_def;
  369. voidpf filestream;
  370. {
  371. unsigned char* buf;
  372. uLong uSizeFile;
  373. uLong uBackRead;
  374. uLong uMaxBack=0xffff; /* maximum size of global comment */
  375. uLong uPosFound=0;
  376. if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
  377. return 0;
  378. uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
  379. if (uMaxBack>uSizeFile)
  380. uMaxBack = uSizeFile;
  381. buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
  382. if (buf==NULL)
  383. return 0;
  384. uBackRead = 4;
  385. while (uBackRead<uMaxBack)
  386. {
  387. uLong uReadSize,uReadPos ;
  388. int i;
  389. if (uBackRead+BUFREADCOMMENT>uMaxBack)
  390. uBackRead = uMaxBack;
  391. else
  392. uBackRead+=BUFREADCOMMENT;
  393. uReadPos = uSizeFile-uBackRead ;
  394. uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
  395. (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
  396. if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
  397. break;
  398. if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
  399. break;
  400. for (i=(int)uReadSize-3; (i--)>0;)
  401. if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
  402. ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
  403. {
  404. uPosFound = uReadPos+i;
  405. break;
  406. }
  407. if (uPosFound!=0)
  408. break;
  409. }
  410. TRYFREE(buf);
  411. return uPosFound;
  412. }
  413. #endif /* !NO_ADDFILEINEXISTINGZIP*/
  414. /************************************************************/
  415. extern zipFile ZEXPORT zipOpen2 (file, append, globalcomment, pzlib_filefunc_def)
  416. voidpf file;
  417. int append;
  418. zipcharpc* globalcomment;
  419. zlib_filefunc_def* pzlib_filefunc_def;
  420. {
  421. zip_internal ziinit;
  422. zip_internal* zi;
  423. int err=ZIP_OK;
  424. if (pzlib_filefunc_def==NULL)
  425. fill_qiodevice_filefunc(&ziinit.z_filefunc);
  426. else
  427. ziinit.z_filefunc = *pzlib_filefunc_def;
  428. ziinit.filestream = (*(ziinit.z_filefunc.zopen_file))
  429. (ziinit.z_filefunc.opaque,
  430. file,
  431. (append == APPEND_STATUS_CREATE) ?
  432. (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
  433. (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
  434. if (ziinit.filestream == NULL)
  435. return NULL;
  436. ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream);
  437. ziinit.in_opened_file_inzip = 0;
  438. ziinit.ci.stream_initialised = 0;
  439. ziinit.number_entry = 0;
  440. ziinit.add_position_when_writting_offset = 0;
  441. ziinit.flags = ZIP_WRITE_DATA_DESCRIPTOR;
  442. init_linkedlist(&(ziinit.central_dir));
  443. zi = (zip_internal*)ALLOC(sizeof(zip_internal));
  444. if (zi==NULL)
  445. {
  446. ZCLOSE(ziinit.z_filefunc,ziinit.filestream);
  447. return NULL;
  448. }
  449. /* now we add file in a zipfile */
  450. # ifndef NO_ADDFILEINEXISTINGZIP
  451. ziinit.globalcomment = NULL;
  452. if (append == APPEND_STATUS_ADDINZIP)
  453. {
  454. uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
  455. uLong size_central_dir; /* size of the central directory */
  456. uLong offset_central_dir; /* offset of start of central directory */
  457. uLong central_pos,uL;
  458. uLong number_disk; /* number of the current dist, used for
  459. spaning ZIP, unsupported, always 0*/
  460. uLong number_disk_with_CD; /* number the the disk with central dir, used
  461. for spaning ZIP, unsupported, always 0*/
  462. uLong number_entry;
  463. uLong number_entry_CD; /* total number of entries in
  464. the central dir
  465. (same than number_entry on nospan) */
  466. uLong size_comment;
  467. central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);
  468. if (central_pos==0)
  469. err=ZIP_ERRNO;
  470. if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
  471. central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
  472. err=ZIP_ERRNO;
  473. /* the signature, already checked */
  474. if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK)
  475. err=ZIP_ERRNO;
  476. /* number of this disk */
  477. if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK)
  478. err=ZIP_ERRNO;
  479. /* number of the disk with the start of the central directory */
  480. if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK)
  481. err=ZIP_ERRNO;
  482. /* total number of entries in the central dir on this disk */
  483. if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK)
  484. err=ZIP_ERRNO;
  485. /* total number of entries in the central dir */
  486. if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK)
  487. err=ZIP_ERRNO;
  488. if ((number_entry_CD!=number_entry) ||
  489. (number_disk_with_CD!=0) ||
  490. (number_disk!=0))
  491. err=ZIP_BADZIPFILE;
  492. /* size of the central directory */
  493. if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK)
  494. err=ZIP_ERRNO;
  495. /* offset of start of central directory with respect to the
  496. starting disk number */
  497. if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK)
  498. err=ZIP_ERRNO;
  499. /* zipfile global comment length */
  500. if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK)
  501. err=ZIP_ERRNO;
  502. if ((central_pos<offset_central_dir+size_central_dir) &&
  503. (err==ZIP_OK))
  504. err=ZIP_BADZIPFILE;
  505. if (err!=ZIP_OK)
  506. {
  507. ZCLOSE(ziinit.z_filefunc, ziinit.filestream);
  508. return NULL;
  509. }
  510. if (size_comment>0)
  511. {
  512. ziinit.globalcomment = ALLOC(size_comment+1);
  513. if (ziinit.globalcomment)
  514. {
  515. size_comment = ZREAD(ziinit.z_filefunc, ziinit.filestream,ziinit.globalcomment,size_comment);
  516. ziinit.globalcomment[size_comment]=0;
  517. }
  518. }
  519. byte_before_the_zipfile = central_pos -
  520. (offset_central_dir+size_central_dir);
  521. ziinit.add_position_when_writting_offset = byte_before_the_zipfile;
  522. {
  523. uLong size_central_dir_to_read = size_central_dir;
  524. size_t buf_size = SIZEDATA_INDATABLOCK;
  525. void* buf_read = (void*)ALLOC(buf_size);
  526. if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
  527. offset_central_dir + byte_before_the_zipfile,
  528. ZLIB_FILEFUNC_SEEK_SET) != 0)
  529. err=ZIP_ERRNO;
  530. while ((size_central_dir_to_read>0) && (err==ZIP_OK))
  531. {
  532. uLong read_this = SIZEDATA_INDATABLOCK;
  533. if (read_this > size_central_dir_to_read)
  534. read_this = size_central_dir_to_read;
  535. if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this)
  536. err=ZIP_ERRNO;
  537. if (err==ZIP_OK)
  538. err = add_data_in_datablock(&ziinit.central_dir,buf_read,
  539. (uLong)read_this);
  540. size_central_dir_to_read-=read_this;
  541. }
  542. TRYFREE(buf_read);
  543. }
  544. ziinit.begin_pos = byte_before_the_zipfile;
  545. ziinit.number_entry = number_entry_CD;
  546. if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
  547. offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
  548. err=ZIP_ERRNO;
  549. }
  550. if (globalcomment)
  551. {
  552. *globalcomment = ziinit.globalcomment;
  553. }
  554. # endif /* !NO_ADDFILEINEXISTINGZIP*/
  555. if (err != ZIP_OK)
  556. {
  557. # ifndef NO_ADDFILEINEXISTINGZIP
  558. TRYFREE(ziinit.globalcomment);
  559. # endif /* !NO_ADDFILEINEXISTINGZIP*/
  560. TRYFREE(zi);
  561. return NULL;
  562. }
  563. else
  564. {
  565. *zi = ziinit;
  566. return (zipFile)zi;
  567. }
  568. }
  569. extern zipFile ZEXPORT zipOpen (file, append)
  570. voidpf file;
  571. int append;
  572. {
  573. return zipOpen2(file,append,NULL,NULL);
  574. }
  575. extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi,
  576. extrafield_local, size_extrafield_local,
  577. extrafield_global, size_extrafield_global,
  578. comment, method, level, raw,
  579. windowBits, memLevel, strategy,
  580. password, crcForCrypting)
  581. zipFile file;
  582. const char* filename;
  583. const zip_fileinfo* zipfi;
  584. const void* extrafield_local;
  585. uInt size_extrafield_local;
  586. const void* extrafield_global;
  587. uInt size_extrafield_global;
  588. const char* comment;
  589. int method;
  590. int level;
  591. int raw;
  592. int windowBits;
  593. int memLevel;
  594. int strategy;
  595. const char* password;
  596. uLong crcForCrypting;
  597. {
  598. zip_internal* zi;
  599. uInt size_filename;
  600. uInt size_comment;
  601. uInt i;
  602. int err = ZIP_OK;
  603. uLong version_to_extract;
  604. # ifdef NOCRYPT
  605. if (password != NULL)
  606. return ZIP_PARAMERROR;
  607. # endif
  608. if (file == NULL)
  609. return ZIP_PARAMERROR;
  610. if ((method!=0) && (method!=Z_DEFLATED))
  611. return ZIP_PARAMERROR;
  612. zi = (zip_internal*)file;
  613. if (zi->in_opened_file_inzip == 1)
  614. {
  615. err = zipCloseFileInZip (file);
  616. if (err != ZIP_OK)
  617. return err;
  618. }
  619. if (method == 0
  620. && (level == 0 || (zi->flags & ZIP_WRITE_DATA_DESCRIPTOR) == 0))
  621. {
  622. version_to_extract = 10;
  623. }
  624. else
  625. {
  626. version_to_extract = 20;
  627. }
  628. if (filename==NULL)
  629. filename="-";
  630. if (comment==NULL)
  631. size_comment = 0;
  632. else
  633. size_comment = (uInt)strlen(comment);
  634. size_filename = (uInt)strlen(filename);
  635. if (zipfi == NULL)
  636. zi->ci.dosDate = 0;
  637. else
  638. {
  639. if (zipfi->dosDate != 0)
  640. zi->ci.dosDate = zipfi->dosDate;
  641. else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
  642. }
  643. zi->ci.flag = 0;
  644. if ((level==8) || (level==9))
  645. zi->ci.flag |= 2;
  646. if ((level==2))
  647. zi->ci.flag |= 4;
  648. if ((level==1))
  649. zi->ci.flag |= 6;
  650. if (password != NULL)
  651. {
  652. zi->ci.flag |= 1;
  653. }
  654. if (version_to_extract >= 20
  655. && (zi->flags & ZIP_WRITE_DATA_DESCRIPTOR) != 0)
  656. zi->ci.flag |= 8;
  657. zi->ci.crc32 = 0;
  658. zi->ci.method = method;
  659. zi->ci.encrypt = 0;
  660. zi->ci.stream_initialised = 0;
  661. zi->ci.pos_in_buffered_data = 0;
  662. zi->ci.raw = raw;
  663. zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ;
  664. zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
  665. size_extrafield_global + size_comment;
  666. zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
  667. ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
  668. /* version info */
  669. ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
  670. ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)version_to_extract,2);
  671. ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
  672. ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
  673. ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
  674. ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
  675. ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
  676. ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
  677. ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
  678. ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
  679. ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
  680. ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
  681. if (zipfi==NULL)
  682. ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
  683. else
  684. ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
  685. if (zipfi==NULL)
  686. ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
  687. else
  688. ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
  689. ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);
  690. for (i=0;i<size_filename;i++)
  691. *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
  692. for (i=0;i<size_extrafield_global;i++)
  693. *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
  694. *(((const char*)extrafield_global)+i);
  695. for (i=0;i<size_comment;i++)
  696. *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
  697. size_extrafield_global+i) = *(comment+i);
  698. if (zi->ci.central_header == NULL)
  699. return ZIP_INTERNALERROR;
  700. /* write the local header */
  701. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);
  702. if (err==ZIP_OK)
  703. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)version_to_extract,2);
  704. if (err==ZIP_OK)
  705. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
  706. if (err==ZIP_OK)
  707. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
  708. if (err==ZIP_OK)
  709. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
  710. if (err==ZIP_OK)
  711. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
  712. if (err==ZIP_OK)
  713. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
  714. if (err==ZIP_OK)
  715. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
  716. if (err==ZIP_OK)
  717. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
  718. if (err==ZIP_OK)
  719. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);
  720. if ((err==ZIP_OK) && (size_filename>0))
  721. if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
  722. err = ZIP_ERRNO;
  723. if ((err==ZIP_OK) && (size_extrafield_local>0))
  724. if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local)
  725. !=size_extrafield_local)
  726. err = ZIP_ERRNO;
  727. zi->ci.stream.avail_in = (uInt)0;
  728. zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
  729. zi->ci.stream.next_out = zi->ci.buffered_data;
  730. zi->ci.stream.total_in = 0;
  731. zi->ci.stream.total_out = 0;
  732. if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
  733. {
  734. zi->ci.stream.zalloc = (alloc_func)0;
  735. zi->ci.stream.zfree = (free_func)0;
  736. zi->ci.stream.opaque = (voidpf)0;
  737. if (windowBits>0)
  738. windowBits = -windowBits;
  739. err = deflateInit2(&zi->ci.stream, level,
  740. Z_DEFLATED, windowBits, memLevel, strategy);
  741. if (err==Z_OK)
  742. zi->ci.stream_initialised = 1;
  743. }
  744. # ifndef NOCRYPT
  745. zi->ci.crypt_header_size = 0;
  746. if ((err==Z_OK) && (password != NULL))
  747. {
  748. unsigned char bufHead[RAND_HEAD_LEN];
  749. unsigned int sizeHead;
  750. zi->ci.encrypt = 1;
  751. zi->ci.pcrc_32_tab = get_crc_table();
  752. /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
  753. crcForCrypting = (uLong)zi->ci.dosDate << 16; // ATTANTION! Without this row, you don't unpack your password protected archive in other app.
  754. sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
  755. zi->ci.crypt_header_size = sizeHead;
  756. if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
  757. err = ZIP_ERRNO;
  758. }
  759. # endif
  760. if (err==Z_OK)
  761. zi->in_opened_file_inzip = 1;
  762. return err;
  763. }
  764. extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi,
  765. extrafield_local, size_extrafield_local,
  766. extrafield_global, size_extrafield_global,
  767. comment, method, level, raw)
  768. zipFile file;
  769. const char* filename;
  770. const zip_fileinfo* zipfi;
  771. const void* extrafield_local;
  772. uInt size_extrafield_local;
  773. const void* extrafield_global;
  774. uInt size_extrafield_global;
  775. const char* comment;
  776. int method;
  777. int level;
  778. int raw;
  779. {
  780. return zipOpenNewFileInZip3 (file, filename, zipfi,
  781. extrafield_local, size_extrafield_local,
  782. extrafield_global, size_extrafield_global,
  783. comment, method, level, raw,
  784. -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
  785. NULL, 0);
  786. }
  787. extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi,
  788. extrafield_local, size_extrafield_local,
  789. extrafield_global, size_extrafield_global,
  790. comment, method, level)
  791. zipFile file;
  792. const char* filename;
  793. const zip_fileinfo* zipfi;
  794. const void* extrafield_local;
  795. uInt size_extrafield_local;
  796. const void* extrafield_global;
  797. uInt size_extrafield_global;
  798. const char* comment;
  799. int method;
  800. int level;
  801. {
  802. return zipOpenNewFileInZip2 (file, filename, zipfi,
  803. extrafield_local, size_extrafield_local,
  804. extrafield_global, size_extrafield_global,
  805. comment, method, level, 0);
  806. }
  807. local int zipFlushWriteBuffer(zi)
  808. zip_internal* zi;
  809. {
  810. int err=ZIP_OK;
  811. if (zi->ci.encrypt != 0)
  812. {
  813. #ifndef NOCRYPT
  814. uInt i;
  815. int t;
  816. for (i=0;i<zi->ci.pos_in_buffered_data;i++)
  817. zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab,
  818. zi->ci.buffered_data[i],t);
  819. #endif
  820. }
  821. if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data)
  822. !=zi->ci.pos_in_buffered_data)
  823. err = ZIP_ERRNO;
  824. zi->ci.pos_in_buffered_data = 0;
  825. return err;
  826. }
  827. extern int ZEXPORT zipWriteInFileInZip (file, buf, len)
  828. zipFile file;
  829. const void* buf;
  830. unsigned len;
  831. {
  832. zip_internal* zi;
  833. int err=ZIP_OK;
  834. if (file == NULL)
  835. return ZIP_PARAMERROR;
  836. zi = (zip_internal*)file;
  837. if (zi->in_opened_file_inzip == 0)
  838. return ZIP_PARAMERROR;
  839. zi->ci.stream.next_in = (void*)buf;
  840. zi->ci.stream.avail_in = len;
  841. zi->ci.crc32 = crc32(zi->ci.crc32,buf,len);
  842. while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
  843. {
  844. if (zi->ci.stream.avail_out == 0)
  845. {
  846. if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
  847. err = ZIP_ERRNO;
  848. zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
  849. zi->ci.stream.next_out = zi->ci.buffered_data;
  850. }
  851. if(err != ZIP_OK)
  852. break;
  853. if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
  854. {
  855. uLong uTotalOutBefore = zi->ci.stream.total_out;
  856. err=deflate(&zi->ci.stream, Z_NO_FLUSH);
  857. zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
  858. }
  859. else
  860. {
  861. uInt copy_this,i;
  862. if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
  863. copy_this = zi->ci.stream.avail_in;
  864. else
  865. copy_this = zi->ci.stream.avail_out;
  866. for (i=0;i<copy_this;i++)
  867. *(((char*)zi->ci.stream.next_out)+i) =
  868. *(((const char*)zi->ci.stream.next_in)+i);
  869. {
  870. zi->ci.stream.avail_in -= copy_this;
  871. zi->ci.stream.avail_out-= copy_this;
  872. zi->ci.stream.next_in+= copy_this;
  873. zi->ci.stream.next_out+= copy_this;
  874. zi->ci.stream.total_in+= copy_this;
  875. zi->ci.stream.total_out+= copy_this;
  876. zi->ci.pos_in_buffered_data += copy_this;
  877. }
  878. }
  879. }
  880. return err;
  881. }
  882. extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32)
  883. zipFile file;
  884. uLong uncompressed_size;
  885. uLong crc32;
  886. {
  887. zip_internal* zi;
  888. uLong compressed_size;
  889. int err=ZIP_OK;
  890. if (file == NULL)
  891. return ZIP_PARAMERROR;
  892. zi = (zip_internal*)file;
  893. if (zi->in_opened_file_inzip == 0)
  894. return ZIP_PARAMERROR;
  895. zi->ci.stream.avail_in = 0;
  896. if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
  897. while (err==ZIP_OK)
  898. {
  899. uLong uTotalOutBefore;
  900. if (zi->ci.stream.avail_out == 0)
  901. {
  902. if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
  903. err = ZIP_ERRNO;
  904. zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
  905. zi->ci.stream.next_out = zi->ci.buffered_data;
  906. }
  907. uTotalOutBefore = zi->ci.stream.total_out;
  908. err=deflate(&zi->ci.stream, Z_FINISH);
  909. zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
  910. }
  911. if (err==Z_STREAM_END)
  912. err=ZIP_OK; /* this is normal */
  913. if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
  914. if (zipFlushWriteBuffer(zi)==ZIP_ERRNO)
  915. err = ZIP_ERRNO;
  916. if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
  917. {
  918. err=deflateEnd(&zi->ci.stream);
  919. zi->ci.stream_initialised = 0;
  920. }
  921. if (!zi->ci.raw)
  922. {
  923. crc32 = (uLong)zi->ci.crc32;
  924. uncompressed_size = (uLong)zi->ci.stream.total_in;
  925. }
  926. compressed_size = (uLong)zi->ci.stream.total_out;
  927. # ifndef NOCRYPT
  928. compressed_size += zi->ci.crypt_header_size;
  929. # endif
  930. ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
  931. ziplocal_putValue_inmemory(zi->ci.central_header+20,
  932. compressed_size,4); /*compr size*/
  933. if (zi->ci.stream.data_type == Z_ASCII)
  934. ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
  935. ziplocal_putValue_inmemory(zi->ci.central_header+24,
  936. uncompressed_size,4); /*uncompr size*/
  937. if (err==ZIP_OK)
  938. err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
  939. (uLong)zi->ci.size_centralheader);
  940. free(zi->ci.central_header);
  941. if (err==ZIP_OK)
  942. {
  943. uLong cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
  944. if (ZSEEK(zi->z_filefunc,zi->filestream,
  945. zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
  946. err = ZIP_ERRNO;
  947. if (err==ZIP_OK)
  948. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
  949. if (err==ZIP_OK) /* compressed size, unknown */
  950. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
  951. if (err==ZIP_OK) /* uncompressed size, unknown */
  952. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
  953. if (ZSEEK(zi->z_filefunc,zi->filestream,
  954. cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
  955. err = ZIP_ERRNO;
  956. if ((zi->ci.flag & 8) != 0) {
  957. /* Write local Descriptor after file data */
  958. if (err==ZIP_OK)
  959. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)DESCRIPTORHEADERMAGIC,4);
  960. if (err==ZIP_OK)
  961. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
  962. if (err==ZIP_OK) /* compressed size, unknown */
  963. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
  964. if (err==ZIP_OK) /* uncompressed size, unknown */
  965. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
  966. }
  967. }
  968. zi->number_entry ++;
  969. zi->in_opened_file_inzip = 0;
  970. return err;
  971. }
  972. extern int ZEXPORT zipCloseFileInZip (file)
  973. zipFile file;
  974. {
  975. return zipCloseFileInZipRaw (file,0,0);
  976. }
  977. extern int ZEXPORT zipClose (file, global_comment)
  978. zipFile file;
  979. const char* global_comment;
  980. {
  981. zip_internal* zi;
  982. int err = 0;
  983. uLong size_centraldir = 0;
  984. uLong centraldir_pos_inzip;
  985. uInt size_global_comment;
  986. if (file == NULL)
  987. return ZIP_PARAMERROR;
  988. zi = (zip_internal*)file;
  989. if (zi->in_opened_file_inzip == 1)
  990. {
  991. err = zipCloseFileInZip (file);
  992. }
  993. #ifndef NO_ADDFILEINEXISTINGZIP
  994. if (global_comment==NULL)
  995. global_comment = zi->globalcomment;
  996. #endif
  997. if (global_comment==NULL)
  998. size_global_comment = 0;
  999. else
  1000. size_global_comment = (uInt)strlen(global_comment);
  1001. centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
  1002. if (err==ZIP_OK)
  1003. {
  1004. linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
  1005. while (ldi!=NULL)
  1006. {
  1007. if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
  1008. if (ZWRITE(zi->z_filefunc,zi->filestream,
  1009. ldi->data,ldi->filled_in_this_block)
  1010. !=ldi->filled_in_this_block )
  1011. err = ZIP_ERRNO;
  1012. size_centraldir += ldi->filled_in_this_block;
  1013. ldi = ldi->next_datablock;
  1014. }
  1015. }
  1016. free_datablock(zi->central_dir.first_block);
  1017. if (err==ZIP_OK) /* Magic End */
  1018. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
  1019. if (err==ZIP_OK) /* number of this disk */
  1020. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
  1021. if (err==ZIP_OK) /* number of the disk with the start of the central directory */
  1022. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
  1023. if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
  1024. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
  1025. if (err==ZIP_OK) /* total number of entries in the central dir */
  1026. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
  1027. if (err==ZIP_OK) /* size of the central directory */
  1028. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
  1029. if (err==ZIP_OK) /* offset of start of central directory with respect to the
  1030. starting disk number */
  1031. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,
  1032. (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
  1033. if (err==ZIP_OK) /* zipfile comment length */
  1034. err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
  1035. if ((err==ZIP_OK) && (size_global_comment>0))
  1036. if (ZWRITE(zi->z_filefunc,zi->filestream,
  1037. global_comment,size_global_comment) != size_global_comment)
  1038. err = ZIP_ERRNO;
  1039. if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0)
  1040. if (err == ZIP_OK)
  1041. err = ZIP_ERRNO;
  1042. #ifndef NO_ADDFILEINEXISTINGZIP
  1043. TRYFREE(zi->globalcomment);
  1044. #endif
  1045. TRYFREE(zi);
  1046. return err;
  1047. }
  1048. extern int ZEXPORT zipSetFlags(zipFile file, unsigned flags)
  1049. {
  1050. zip_internal* zi;
  1051. if (file == NULL)
  1052. return ZIP_PARAMERROR;
  1053. zi = (zip_internal*)file;
  1054. zi->flags |= flags;
  1055. return ZIP_OK;
  1056. }
  1057. extern int ZEXPORT zipClearFlags(zipFile file, unsigned flags)
  1058. {
  1059. zip_internal* zi;
  1060. if (file == NULL)
  1061. return ZIP_PARAMERROR;
  1062. zi = (zip_internal*)file;
  1063. zi->flags &= ~flags;
  1064. return ZIP_OK;
  1065. }