zip.c 36 KB

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