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 <string.h>
16#include <sys/types.h>
17
18#ifdef __cplusplus
19extern "C" {
20#endif
21
22#if !defined(_POSIX_C_SOURCE) && defined(_MSC_VER)
23// 64-bit Windows is the only mainstream platform
24// where sizeof(long) != sizeof(void*)
25#ifdef _WIN64
26typedef long long ssize_t; /* byte count or error */
27#else
28typedef long ssize_t; /* byte count or error */
29#endif
30#endif
31
32#ifndef MAX_PATH
33#define MAX_PATH 32767 /* # chars in a path name including NULL */
34#endif
35
36/**
37 * @mainpage
38 *
39 * Documenation for @ref zip.
40 */
41
42/**
43 * @addtogroup zip
44 * @{
45 */
46
47/**
48 * Default zip compression level.
49 */
50
51#define ZIP_DEFAULT_COMPRESSION_LEVEL 6
52
53/**
54 * @struct zip_t
55 *
56 * This data structure is used throughout the library to represent zip archive -
57 * forward declaration.
58 */
59struct zip_t;
60
61/**
62 * Opens zip archive with compression level using the given mode.
63 *
64 * @param zipname zip archive file name.
65 * @param level compression level (0-9 are the standard zlib-style levels).
66 * @param mode file access mode.
67 * - 'r': opens a file for reading/extracting (the file must exists).
68 * - 'w': creates an empty file for writing.
69 * - 'a': appends to an existing archive.
70 *
71 * @return the zip archive handler or NULL on error
72 */
73extern struct zip_t *zip_open(const char *zipname, int level, char mode);
74
75/**
76 * Closes the zip archive, releases resources - always finalize.
77 *
78 * @param zip zip archive handler.
79 */
80extern void zip_close(struct zip_t *zip);
81
82/**
83 * Determines if the archive has a zip64 end of central directory headers.
84 *
85 * @param zip zip archive handler.
86 *
87 * @return the return code - 1 (true), 0 (false), negative number (< 0) on
88 * error.
89 */
90extern int zip_is64(struct zip_t *zip);
91
92/**
93 * Opens an entry by name in the zip archive.
94 *
95 * For zip archive opened in 'w' or 'a' mode the function will append
96 * a new entry. In readonly mode the function tries to locate the entry
97 * in global dictionary.
98 *
99 * @param zip zip archive handler.
100 * @param entryname an entry name in local dictionary.
101 *
102 * @return the return code - 0 on success, negative number (< 0) on error.
103 */
104extern int zip_entry_open(struct zip_t *zip, const char *entryname);
105
106/**
107 * Opens a new entry by index in the zip archive.
108 *
109 * This function is only valid if zip archive was opened in 'r' (readonly) mode.
110 *
111 * @param zip zip archive handler.
112 * @param index index in local dictionary.
113 *
114 * @return the return code - 0 on success, negative number (< 0) on error.
115 */
116extern int zip_entry_openbyindex(struct zip_t *zip, int index);
117
118/**
119 * Closes a zip entry, flushes buffer and releases resources.
120 *
121 * @param zip zip archive handler.
122 *
123 * @return the return code - 0 on success, negative number (< 0) on error.
124 */
125extern int zip_entry_close(struct zip_t *zip);
126
127/**
128 * Returns a local name of the current zip entry.
129 *
130 * The main difference between user's entry name and local entry name
131 * is optional relative path.
132 * Following .ZIP File Format Specification - the path stored MUST not contain
133 * a drive or device letter, or a leading slash.
134 * All slashes MUST be forward slashes '/' as opposed to backwards slashes '\'
135 * for compatibility with Amiga and UNIX file systems etc.
136 *
137 * @param zip: zip archive handler.
138 *
139 * @return the pointer to the current zip entry name, or NULL on error.
140 */
141extern const char *zip_entry_name(struct zip_t *zip);
142
143/**
144 * Returns an index of the current zip entry.
145 *
146 * @param zip zip archive handler.
147 *
148 * @return the index on success, negative number (< 0) on error.
149 */
150extern int zip_entry_index(struct zip_t *zip);
151
152/**
153 * Determines if the current zip entry is a directory entry.
154 *
155 * @param zip zip archive handler.
156 *
157 * @return the return code - 1 (true), 0 (false), negative number (< 0) on
158 * error.
159 */
160extern int zip_entry_isdir(struct zip_t *zip);
161
162/**
163 * Returns an uncompressed size of the current zip entry.
164 *
165 * @param zip zip archive handler.
166 *
167 * @return the uncompressed size in bytes.
168 */
169extern unsigned long long zip_entry_size(struct zip_t *zip);
170
171/**
172 * Returns CRC-32 checksum of the current zip entry.
173 *
174 * @param zip zip archive handler.
175 *
176 * @return the CRC-32 checksum.
177 */
178extern unsigned int zip_entry_crc32(struct zip_t *zip);
179
180/**
181 * Compresses an input buffer for the current zip entry.
182 *
183 * @param zip zip archive handler.
184 * @param buf input buffer.
185 * @param bufsize input buffer size (in bytes).
186 *
187 * @return the return code - 0 on success, negative number (< 0) on error.
188 */
189extern int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize);
190
191/**
192 * Compresses a file for the current zip entry.
193 *
194 * @param zip zip archive handler.
195 * @param filename input file.
196 *
197 * @return the return code - 0 on success, negative number (< 0) on error.
198 */
199extern int zip_entry_fwrite(struct zip_t *zip, const char *filename);
200
201/**
202 * Extracts the current zip entry into output buffer.
203 *
204 * The function allocates sufficient memory for a output buffer.
205 *
206 * @param zip zip archive handler.
207 * @param buf output buffer.
208 * @param bufsize output buffer size (in bytes).
209 *
210 * @note remember to release memory allocated for a output buffer.
211 * for large entries, please take a look at zip_entry_extract function.
212 *
213 * @return the return code - the number of bytes actually read on success.
214 * Otherwise a -1 on error.
215 */
216extern ssize_t zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize);
217
218/**
219 * Extracts the current zip entry into a memory buffer using no memory
220 * allocation.
221 *
222 * @param zip zip archive handler.
223 * @param buf preallocated output buffer.
224 * @param bufsize output buffer size (in bytes).
225 *
226 * @note ensure supplied output buffer is large enough.
227 * zip_entry_size function (returns uncompressed size for the current
228 * entry) can be handy to estimate how big buffer is needed. for large
229 * entries, please take a look at zip_entry_extract function.
230 *
231 * @return the return code - the number of bytes actually read on success.
232 * Otherwise a -1 on error (e.g. bufsize is not large enough).
233 */
234extern ssize_t zip_entry_noallocread(struct zip_t *zip, void *buf,
235 size_t bufsize);
236
237/**
238 * Extracts the current zip entry into output file.
239 *
240 * @param zip zip archive handler.
241 * @param filename output file.
242 *
243 * @return the return code - 0 on success, negative number (< 0) on error.
244 */
245extern int zip_entry_fread(struct zip_t *zip, const char *filename);
246
247/**
248 * Extracts the current zip entry using a callback function (on_extract).
249 *
250 * @param zip zip archive handler.
251 * @param on_extract callback function.
252 * @param arg opaque pointer (optional argument, which you can pass to the
253 * on_extract callback)
254 *
255 * @return the return code - 0 on success, negative number (< 0) on error.
256 */
257extern int
258zip_entry_extract(struct zip_t *zip,
259 size_t (*on_extract)(void *arg, unsigned long long offset,
260 const void *data, size_t size),
261 void *arg);
262
263/**
264 * Returns the number of all entries (files and directories) in the zip archive.
265 *
266 * @param zip zip archive handler.
267 *
268 * @return the return code - the number of entries on success, negative number
269 * (< 0) on error.
270 */
271extern int zip_total_entries(struct zip_t *zip);
272
273/**
274 * Creates a new archive and puts files into a single zip archive.
275 *
276 * @param zipname zip archive file.
277 * @param filenames input files.
278 * @param len: number of input files.
279 *
280 * @return the return code - 0 on success, negative number (< 0) on error.
281 */
282extern int zip_create(const char *zipname, const char *filenames[], size_t len);
283
284/**
285 * Extracts a zip archive file into directory.
286 *
287 * If on_extract_entry is not NULL, the callback will be called after
288 * successfully extracted each zip entry.
289 * Returning a negative value from the callback will cause abort and return an
290 * error. The last argument (void *arg) is optional, which you can use to pass
291 * data to the on_extract_entry callback.
292 *
293 * @param zipname zip archive file.
294 * @param dir output directory.
295 * @param on_extract_entry on extract callback.
296 * @param arg opaque pointer.
297 *
298 * @return the return code - 0 on success, negative number (< 0) on error.
299 */
300extern int zip_extract(const char *zipname, const char *dir,
301 int (*on_extract_entry)(const char *filename, void *arg),
302 void *arg);
303
304/**
305 * Extracts a zip archive stream into directory.
306 *
307 * If on_extract is not NULL, the callback will be called after
308 * successfully extracted each zip entry.
309 * Returning a negative value from the callback will cause abort and return an
310 * error. The last argument (void *arg) is optional, which you can use to pass
311 * data to the on_extract callback.
312 *
313 * @param stream zip archive stream.
314 * @param size stream size.
315 * @param dir output directory.
316 * @param on_extract on extract callback.
317 * @param arg opaque pointer.
318 *
319 * @return the return code - 0 on success, negative number (< 0) on error.
320 */
321extern int zip_extract_stream(const char *stream, size_t size, const char *dir,
322 int (*on_extract)(const char *filename,
323 void *arg),
324 void *arg);
325
326/**
327 * Opens zip archive stream into memory.
328 *
329 * @param stream zip archive stream.
330 * @param size stream size.
331 *
332 * @return the zip archive handler or NULL on error
333 */
334extern struct zip_t *zip_open_stream(const char *stream, size_t size);
335
336/**
337 * Deletes zip archive entries.
338 *
339 * @param zip zip archive handler.
340 * @param entries array of zip archive entries to be deleted.
341 * @param len the number of entries to be deleted.
342 * @return the number of deleted entries, or negative number (< 0) on error.
343 */
344extern int zip_entries_delete(struct zip_t *zip, char *const entries[],
345 size_t len);
346/** @} */
347#ifdef __cplusplus
348}
349#endif
350
351#endif
352