/src/libtomahawk/thirdparty/quazip/quazip/zip.c

http://github.com/tomahawk-player/tomahawk · C · 1243 lines · 982 code · 208 blank · 53 comment · 218 complexity · 0ab4dd75d8bbe611d192eb2ed2c3a353 MD5 · raw file

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