zip.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. /*
  2. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  3. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  4. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  5. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  6. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  7. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  8. * OTHER DEALINGS IN THE SOFTWARE.
  9. */
  10. #pragma once
  11. #ifndef ZIP_H
  12. #define ZIP_H
  13. #include <stdint.h>
  14. #include <string.h>
  15. #include <sys/types.h>
  16. #if !defined(_POSIX_C_SOURCE) && defined(_MSC_VER)
  17. // 64-bit Windows is the only mainstream platform
  18. // where sizeof(long) != sizeof(void*)
  19. #ifdef _WIN64
  20. typedef long long ssize_t; /* byte count or error */
  21. #else
  22. typedef long ssize_t; /* byte count or error */
  23. #endif
  24. #endif
  25. #ifndef MAX_PATH
  26. #define MAX_PATH 1024 /* # chars in a path name including NULL */
  27. #endif
  28. /**
  29. * @mainpage
  30. *
  31. * Documenation for @ref zip.
  32. */
  33. /**
  34. * @addtogroup zip
  35. * @{
  36. */
  37. /**
  38. * Default zip compression level.
  39. */
  40. #define ZIP_DEFAULT_COMPRESSION_LEVEL 6
  41. /**
  42. * Error codes
  43. */
  44. #define ZIP_ENOINIT -1 // not initialized
  45. #define ZIP_EINVENTNAME -2 // invalid entry name
  46. #define ZIP_ENOENT -3 // entry not found
  47. #define ZIP_EINVMODE -4 // invalid zip mode
  48. #define ZIP_EINVLVL -5 // invalid compression level
  49. #define ZIP_ENOSUP64 -6 // no zip 64 support
  50. #define ZIP_EMEMSET -7 // memset error
  51. #define ZIP_EWRTENT -8 // cannot write data to entry
  52. #define ZIP_ETDEFLINIT -9 // cannot initialize tdefl compressor
  53. #define ZIP_EINVIDX -10 // invalid index
  54. #define ZIP_ENOHDR -11 // header not found
  55. #define ZIP_ETDEFLBUF -12 // cannot flush tdefl buffer
  56. #define ZIP_ECRTHDR -13 // cannot create entry header
  57. #define ZIP_EWRTHDR -14 // cannot write entry header
  58. #define ZIP_EWRTDIR -15 // cannot write to central dir
  59. #define ZIP_EOPNFILE -16 // cannot open file
  60. #define ZIP_EINVENTTYPE -17 // invalid entry type
  61. #define ZIP_EMEMNOALLOC -18 // extracting data using no memory allocation
  62. #define ZIP_ENOFILE -19 // file not found
  63. #define ZIP_ENOPERM -20 // no permission
  64. #define ZIP_EOOMEM -21 // out of memory
  65. #define ZIP_EINVZIPNAME -22 // invalid zip archive name
  66. #define ZIP_EMKDIR -23 // make dir error
  67. #define ZIP_ESYMLINK -24 // symlink error
  68. #define ZIP_ECLSZIP -25 // close archive error
  69. #define ZIP_ECAPSIZE -26 // capacity size too small
  70. #define ZIP_EFSEEK -27 // fseek error
  71. #define ZIP_EFREAD -28 // fread error
  72. #define ZIP_EFWRITE -29 // fwrite error
  73. /**
  74. * Looks up the error message string coresponding to an error number.
  75. * @param errnum error number
  76. * @return error message string coresponding to errnum or NULL if error is not
  77. * found.
  78. */
  79. const char *zip_strerror(int errnum);
  80. /**
  81. * @struct zip_t
  82. *
  83. * This data structure is used throughout the library to represent zip archive -
  84. * forward declaration.
  85. */
  86. struct zip_t;
  87. /**
  88. * Opens zip archive with compression level using the given mode.
  89. *
  90. * @param zipname zip archive file name.
  91. * @param level compression level (0-9 are the standard zlib-style levels).
  92. * @param mode file access mode.
  93. * - 'r': opens a file for reading/extracting (the file must exists).
  94. * - 'w': creates an empty file for writing.
  95. * - 'a': appends to an existing archive.
  96. *
  97. * @return the zip archive handler or NULL on error
  98. */
  99. struct zip_t *zip_open(const char *zipname, int level,
  100. char mode);
  101. /**
  102. * Closes the zip archive, releases resources - always finalize.
  103. *
  104. * @param zip zip archive handler.
  105. */
  106. void zip_close(struct zip_t *zip);
  107. /**
  108. * Determines if the archive has a zip64 end of central directory headers.
  109. *
  110. * @param zip zip archive handler.
  111. *
  112. * @return the return code - 1 (true), 0 (false), negative number (< 0) on
  113. * error.
  114. */
  115. int zip_is64(struct zip_t *zip);
  116. /**
  117. * Opens an entry by name in the zip archive.
  118. *
  119. * For zip archive opened in 'w' or 'a' mode the function will append
  120. * a new entry. In readonly mode the function tries to locate the entry
  121. * in global dictionary.
  122. *
  123. * @param zip zip archive handler.
  124. * @param entryname an entry name in local dictionary.
  125. *
  126. * @return the return code - 0 on success, negative number (< 0) on error.
  127. */
  128. int zip_entry_open(struct zip_t *zip, const char *entryname);
  129. /**
  130. * Opens an entry by name in the zip archive.
  131. *
  132. * For zip archive opened in 'w' or 'a' mode the function will append
  133. * a new entry. In readonly mode the function tries to locate the entry
  134. * in global dictionary (case sensitive).
  135. *
  136. * @param zip zip archive handler.
  137. * @param entryname an entry name in local dictionary (case sensitive).
  138. *
  139. * @return the return code - 0 on success, negative number (< 0) on error.
  140. */
  141. int zip_entry_opencasesensitive(struct zip_t *zip,
  142. const char *entryname);
  143. /**
  144. * Opens a new entry by index in the zip archive.
  145. *
  146. * This function is only valid if zip archive was opened in 'r' (readonly) mode.
  147. *
  148. * @param zip zip archive handler.
  149. * @param index index in local dictionary.
  150. *
  151. * @return the return code - 0 on success, negative number (< 0) on error.
  152. */
  153. int zip_entry_openbyindex(struct zip_t *zip, size_t index);
  154. /**
  155. * Closes a zip entry, flushes buffer and releases resources.
  156. *
  157. * @param zip zip archive handler.
  158. *
  159. * @return the return code - 0 on success, negative number (< 0) on error.
  160. */
  161. int zip_entry_close(struct zip_t *zip);
  162. /**
  163. * Returns a local name of the current zip entry.
  164. *
  165. * The main difference between user's entry name and local entry name
  166. * is optional relative path.
  167. * Following .ZIP File Format Specification - the path stored MUST not contain
  168. * a drive or device letter, or a leading slash.
  169. * All slashes MUST be forward slashes '/' as opposed to backwards slashes '\'
  170. * for compatibility with Amiga and UNIX file systems etc.
  171. *
  172. * @param zip: zip archive handler.
  173. *
  174. * @return the pointer to the current zip entry name, or NULL on error.
  175. */
  176. const char *zip_entry_name(struct zip_t *zip);
  177. /**
  178. * Returns an index of the current zip entry.
  179. *
  180. * @param zip zip archive handler.
  181. *
  182. * @return the index on success, negative number (< 0) on error.
  183. */
  184. ssize_t zip_entry_index(struct zip_t *zip);
  185. /**
  186. * Determines if the current zip entry is a directory entry.
  187. *
  188. * @param zip zip archive handler.
  189. *
  190. * @return the return code - 1 (true), 0 (false), negative number (< 0) on
  191. * error.
  192. */
  193. int zip_entry_isdir(struct zip_t *zip);
  194. /**
  195. * Returns the uncompressed size of the current zip entry.
  196. * Alias for zip_entry_uncomp_size (for backward compatibility).
  197. *
  198. * @param zip zip archive handler.
  199. *
  200. * @return the uncompressed size in bytes.
  201. */
  202. unsigned long long zip_entry_size(struct zip_t *zip);
  203. /**
  204. * Returns the uncompressed size of the current zip entry.
  205. *
  206. * @param zip zip archive handler.
  207. *
  208. * @return the uncompressed size in bytes.
  209. */
  210. unsigned long long zip_entry_uncomp_size(struct zip_t *zip);
  211. /**
  212. * Returns the compressed size of the current zip entry.
  213. *
  214. * @param zip zip archive handler.
  215. *
  216. * @return the compressed size in bytes.
  217. */
  218. unsigned long long zip_entry_comp_size(struct zip_t *zip);
  219. /**
  220. * Returns CRC-32 checksum of the current zip entry.
  221. *
  222. * @param zip zip archive handler.
  223. *
  224. * @return the CRC-32 checksum.
  225. */
  226. unsigned int zip_entry_crc32(struct zip_t *zip);
  227. /**
  228. * Compresses an input buffer for the current zip entry.
  229. *
  230. * @param zip zip archive handler.
  231. * @param buf input buffer.
  232. * @param bufsize input buffer size (in bytes).
  233. *
  234. * @return the return code - 0 on success, negative number (< 0) on error.
  235. */
  236. int zip_entry_write(struct zip_t *zip, const void *buf,
  237. size_t bufsize);
  238. /**
  239. * Compresses a file for the current zip entry.
  240. *
  241. * @param zip zip archive handler.
  242. * @param filename input file.
  243. *
  244. * @return the return code - 0 on success, negative number (< 0) on error.
  245. */
  246. int zip_entry_fwrite(struct zip_t *zip, const char *filename);
  247. /**
  248. * Extracts the current zip entry into output buffer.
  249. *
  250. * The function allocates sufficient memory for a output buffer.
  251. *
  252. * @param zip zip archive handler.
  253. * @param buf output buffer.
  254. * @param bufsize output buffer size (in bytes).
  255. *
  256. * @note remember to release memory allocated for a output buffer.
  257. * for large entries, please take a look at zip_entry_extract function.
  258. *
  259. * @return the return code - the number of bytes actually read on success.
  260. * Otherwise a negative number (< 0) on error.
  261. */
  262. ssize_t zip_entry_read(struct zip_t *zip, void **buf,
  263. size_t *bufsize);
  264. /**
  265. * Extracts the current zip entry into a memory buffer using no memory
  266. * allocation.
  267. *
  268. * @param zip zip archive handler.
  269. * @param buf preallocated output buffer.
  270. * @param bufsize output buffer size (in bytes).
  271. *
  272. * @note ensure supplied output buffer is large enough.
  273. * zip_entry_size function (returns uncompressed size for the current
  274. * entry) can be handy to estimate how big buffer is needed.
  275. * For large entries, please take a look at zip_entry_extract function.
  276. *
  277. * @return the return code - the number of bytes actually read on success.
  278. * Otherwise a negative number (< 0) on error (e.g. bufsize is not large
  279. * enough).
  280. */
  281. ssize_t zip_entry_noallocread(struct zip_t *zip, void *buf,
  282. size_t bufsize);
  283. /**
  284. * Extracts the current zip entry into output file.
  285. *
  286. * @param zip zip archive handler.
  287. * @param filename output file.
  288. *
  289. * @return the return code - 0 on success, negative number (< 0) on error.
  290. */
  291. int zip_entry_fread(struct zip_t *zip, const char *filename);
  292. /**
  293. * Extracts the current zip entry using a callback function (on_extract).
  294. *
  295. * @param zip zip archive handler.
  296. * @param on_extract callback function.
  297. * @param arg opaque pointer (optional argument, which you can pass to the
  298. * on_extract callback)
  299. *
  300. * @return the return code - 0 on success, negative number (< 0) on error.
  301. */
  302. int
  303. zip_entry_extract(struct zip_t *zip,
  304. size_t (*on_extract)(void *arg, uint64_t offset,
  305. const void *data, size_t size),
  306. void *arg);
  307. /**
  308. * Returns the number of all entries (files and directories) in the zip archive.
  309. *
  310. * @param zip zip archive handler.
  311. *
  312. * @return the return code - the number of entries on success, negative number
  313. * (< 0) on error.
  314. */
  315. ssize_t zip_entries_total(struct zip_t *zip);
  316. /**
  317. * Deletes zip archive entries.
  318. *
  319. * @param zip zip archive handler.
  320. * @param entries array of zip archive entries to be deleted.
  321. * @param len the number of entries to be deleted.
  322. * @return the number of deleted entries, or negative number (< 0) on error.
  323. */
  324. ssize_t zip_entries_delete(struct zip_t *zip,
  325. char *const entries[], size_t len);
  326. /**
  327. * Extracts a zip archive stream into directory.
  328. *
  329. * If on_extract is not NULL, the callback will be called after
  330. * successfully extracted each zip entry.
  331. * Returning a negative value from the callback will cause abort and return an
  332. * error. The last argument (void *arg) is optional, which you can use to pass
  333. * data to the on_extract callback.
  334. *
  335. * @param stream zip archive stream.
  336. * @param size stream size.
  337. * @param dir output directory.
  338. * @param on_extract on extract callback.
  339. * @param arg opaque pointer.
  340. *
  341. * @return the return code - 0 on success, negative number (< 0) on error.
  342. */
  343. int
  344. zip_stream_extract(const char *stream, size_t size, const char *dir,
  345. int (*on_extract)(const char *filename, void *arg),
  346. void *arg);
  347. /**
  348. * Opens zip archive stream into memory.
  349. *
  350. * @param stream zip archive stream.
  351. * @param size stream size.
  352. *
  353. * @return the zip archive handler or NULL on error
  354. */
  355. struct zip_t *zip_stream_open(const char *stream, size_t size,
  356. int level, char mode);
  357. /**
  358. * Copy zip archive stream output buffer.
  359. *
  360. * @param zip zip archive handler.
  361. * @param buf output buffer. User should free buf.
  362. * @param bufsize output buffer size (in bytes).
  363. *
  364. * @return copy size
  365. */
  366. ssize_t zip_stream_copy(struct zip_t *zip, void **buf,
  367. size_t *bufsize);
  368. /**
  369. * Close zip archive releases resources.
  370. *
  371. * @param zip zip archive handler.
  372. *
  373. * @return
  374. */
  375. void zip_stream_close(struct zip_t *zip);
  376. /**
  377. * Creates a new archive and puts files into a single zip archive.
  378. *
  379. * @param zipname zip archive file.
  380. * @param filenames input files.
  381. * @param len: number of input files.
  382. *
  383. * @return the return code - 0 on success, negative number (< 0) on error.
  384. */
  385. int zip_create(const char *zipname, const char *filenames[],
  386. size_t len);
  387. /**
  388. * Extracts a zip archive file into directory.
  389. *
  390. * If on_extract_entry is not NULL, the callback will be called after
  391. * successfully extracted each zip entry.
  392. * Returning a negative value from the callback will cause abort and return an
  393. * error. The last argument (void *arg) is optional, which you can use to pass
  394. * data to the on_extract_entry callback.
  395. *
  396. * @param zipname zip archive file.
  397. * @param dir output directory.
  398. * @param on_extract_entry on extract callback.
  399. * @param arg opaque pointer.
  400. *
  401. * @return the return code - 0 on success, negative number (< 0) on error.
  402. */
  403. int zip_extract(const char *zipname, const char *dir,
  404. int (*on_extract_entry)(const char *filename,
  405. void *arg),
  406. void *arg);
  407. #endif