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