1 /* minizip.c
2 Version 2.8.1, December 1, 2018
3 part of the MiniZip project
4
5 Copyright (C) 2010-2018 Nathan Moinvaziri
6 https://github.com/nmoinvaz/minizip
7 Copyright (C) 1998-2010 Gilles Vollant
8 https://www.winimage.com/zLibDll/minizip.html
9
10 This program is distributed under the terms of the same license as zlib.
11 See the accompanying LICENSE file for the full text of the license.
12 */
13
14
15 #include "mz.h"
16 #include "mz_os.h"
17 #include "mz_strm.h"
18 #include "mz_strm_buf.h"
19 #include "mz_strm_split.h"
20 #include "mz_zip.h"
21 #include "mz_zip_rw.h"
22
23 #include <stdio.h> /* printf */
24
25 /***************************************************************************/
26
27 typedef struct minizip_opt_s {
28 uint8_t include_path;
29 int16_t compress_level;
30 uint8_t compress_method;
31 uint8_t overwrite;
32 uint8_t append;
33 int64_t disk_size;
34 uint8_t zip_cd;
35 int32_t encoding;
36 uint8_t verbose;
37 uint8_t aes;
38 const char *cert_path;
39 const char *cert_pwd;
40 } minizip_opt;
41
42 /***************************************************************************/
43
44 int32_t minizip_banner(void);
45 int32_t minizip_help(void);
46
47 int32_t minizip_list(const char *path);
48
49 int32_t minizip_add_entry_cb(void *handle, void *userdata, mz_zip_file *file_info);
50 int32_t minizip_add_progress_cb(void *handle, void *userdata, mz_zip_file *file_info, int64_t position);
51 int32_t minizip_add_overwrite_cb(void *handle, void *userdata, const char *path);
52 int32_t minizip_add(const char *path, const char *password, minizip_opt *options, int32_t arg_count, const char **args);
53
54 int32_t minizip_extract_entry_cb(void *handle, void *userdata, mz_zip_file *file_info, const char *path);
55 int32_t minizip_extract_progress_cb(void *handle, void *userdata, mz_zip_file *file_info, int64_t position);
56 int32_t minizip_extract_overwrite_cb(void *handle, void *userdata, mz_zip_file *file_info, const char *path);
57 int32_t minizip_extract(const char *path, const char *pattern, const char *destination, const char *password, minizip_opt *options);
58
59 int32_t minizip_erase(const char *src_path, const char *target_path, int32_t arg_count, const char **args);
60
61 /***************************************************************************/
62
minizip_banner(void)63 int32_t minizip_banner(void)
64 {
65 printf("Minizip %s - https://github.com/nmoinvaz/minizip\n", MZ_VERSION);
66 printf("---------------------------------------------------\n");
67 return MZ_OK;
68 }
69
minizip_help(void)70 int32_t minizip_help(void)
71 {
72 printf("Usage : minizip [-x -d dir|-l|-e] [-o] [-c codepage] [-a] [-j] [-0 to -9] [-b|-m] [-k 512] [-p pwd] [-s] file.zip [files]\n\n" \
73 " -x Extract files\n" \
74 " -l List files\n" \
75 " -d Destination directory\n" \
76 " -o Overwrite existing files\n" \
77 " -c File names use cp437 encoding\n" \
78 " -a Append to existing zip file\n" \
79 " -i Include full path of files\n" \
80 " -v Verbose info\n" \
81 " -0 Store only\n" \
82 " -1 Compress faster\n" \
83 " -9 Compress better\n" \
84 " -k Disk size in KB\n" \
85 " -z Zip central directory\n" \
86 " -p Encryption password\n" \
87 " -s AES encryption\n" \
88 " -h Pkcs12 certificate path\n" \
89 " -w Pkcs12 certificate password\n" \
90 " -b BZIP2 compression\n" \
91 " -m LZMA compression\n\n");
92 return MZ_OK;
93 }
94
95 /***************************************************************************/
96
minizip_list(const char * path)97 int32_t minizip_list(const char *path)
98 {
99 mz_zip_file *file_info = NULL;
100 uint32_t ratio = 0;
101 int16_t level = 0;
102 int32_t err = MZ_OK;
103 struct tm tmu_date;
104 const char *string_method = NULL;
105 char crypt = ' ';
106 void *reader = NULL;
107
108
109 mz_zip_reader_create(&reader);
110 err = mz_zip_reader_open_file(reader, path);
111 if (err != MZ_OK)
112 {
113 printf("Error %"PRId32" opening zip file %s\n", err, path);
114 mz_zip_reader_delete(&reader);
115 return err;
116 }
117
118 err = mz_zip_reader_goto_first_entry(reader);
119
120 if (err != MZ_OK && err != MZ_END_OF_LIST)
121 {
122 printf("Error %"PRId32" going to first entry in zip file\n", err);
123 mz_zip_reader_delete(&reader);
124 return err;
125 }
126
127 printf(" Packed Unpacked Ratio Method Attribs Date Time CRC-32 Name\n");
128 printf(" ------ -------- ----- ------ ------- ---- ---- ------ ----\n");
129
130 /* Enumerate all entries in the zip */
131 do
132 {
133 err = mz_zip_reader_entry_get_info(reader, &file_info);
134
135 if (err != MZ_OK)
136 {
137 printf("Error %"PRId32" getting entry info in zip file\n", err);
138 break;
139 }
140
141 ratio = 0;
142 if (file_info->uncompressed_size > 0)
143 ratio = (uint32_t)((file_info->compressed_size * 100) / file_info->uncompressed_size);
144
145 /* Display a '*' if the file is encrypted */
146 if (file_info->flag & MZ_ZIP_FLAG_ENCRYPTED)
147 crypt = '*';
148
149 switch (file_info->compression_method)
150 {
151 case MZ_COMPRESS_METHOD_STORE:
152 string_method = "Stored";
153 break;
154 case MZ_COMPRESS_METHOD_DEFLATE:
155 level = (int16_t)((file_info->flag & 0x6) / 2);
156 if (level == 0)
157 string_method = "Defl:N";
158 else if (level == 1)
159 string_method = "Defl:X";
160 else if ((level == 2) || (level == 3))
161 string_method = "Defl:F"; /* 2: fast , 3: extra fast */
162 else
163 string_method = "Defl:?";
164 break;
165 case MZ_COMPRESS_METHOD_BZIP2:
166 string_method = "BZip2";
167 break;
168 case MZ_COMPRESS_METHOD_LZMA:
169 string_method = "LZMA";
170 break;
171 default:
172 string_method = "?";
173 }
174
175 mz_zip_time_t_to_tm(file_info->modified_date, &tmu_date);
176
177 /* Print entry information */
178 printf("%12"PRId64" %12"PRId64" %3"PRIu32"%% %6s%c %8"PRIx32" %2.2"PRIu32\
179 "-%2.2"PRIu32"-%2.2"PRIu32" %2.2"PRIu32":%2.2"PRIu32" %8.8"PRIx32" %s\n",
180 file_info->compressed_size, file_info->uncompressed_size, ratio,
181 string_method, crypt, file_info->external_fa,
182 (uint32_t)tmu_date.tm_mon + 1, (uint32_t)tmu_date.tm_mday,
183 (uint32_t)tmu_date.tm_year % 100,
184 (uint32_t)tmu_date.tm_hour, (uint32_t)tmu_date.tm_min,
185 file_info->crc, file_info->filename);
186
187 err = mz_zip_reader_goto_next_entry(reader);
188
189 if (err != MZ_OK && err != MZ_END_OF_LIST)
190 {
191 printf("Error %"PRId32" going to next entry in zip file\n", err);
192 break;
193 }
194 }
195 while (err == MZ_OK);
196
197 mz_zip_reader_delete(&reader);
198
199 if (err == MZ_END_OF_LIST)
200 return MZ_OK;
201
202 return err;
203 }
204
205 /***************************************************************************/
206
minizip_add_entry_cb(void * handle,void * userdata,mz_zip_file * file_info)207 int32_t minizip_add_entry_cb(void *handle, void *userdata, mz_zip_file *file_info)
208 {
209 MZ_UNUSED(handle);
210 MZ_UNUSED(userdata);
211
212 /* Print the current file we are trying to compress */
213 printf("Adding %s\n", file_info->filename);
214 return MZ_OK;
215 }
216
minizip_add_progress_cb(void * handle,void * userdata,mz_zip_file * file_info,int64_t position)217 int32_t minizip_add_progress_cb(void *handle, void *userdata, mz_zip_file *file_info, int64_t position)
218 {
219 minizip_opt *options = (minizip_opt *)userdata;
220 double progress = 0;
221 uint8_t raw = 0;
222
223 MZ_UNUSED(userdata);
224
225 mz_zip_writer_get_raw(handle, &raw);
226
227 if (raw && file_info->compressed_size > 0)
228 progress = ((double)position / file_info->compressed_size) * 100;
229 else if (!raw && file_info->uncompressed_size > 0)
230 progress = ((double)position / file_info->uncompressed_size) * 100;
231
232 /* Print the progress of the current compress operation */
233 if (options->verbose)
234 printf("%s - %"PRId64" / %"PRId64" (%.02f%%)\n", file_info->filename, position,
235 file_info->uncompressed_size, progress);
236 return MZ_OK;
237 }
238
minizip_add_overwrite_cb(void * handle,void * userdata,const char * path)239 int32_t minizip_add_overwrite_cb(void *handle, void *userdata, const char *path)
240 {
241 minizip_opt *options = (minizip_opt *)userdata;
242
243 MZ_UNUSED(handle);
244
245 if (options->overwrite == 0)
246 {
247 /* If ask the user what to do because append and overwrite args not set */
248 char rep = 0;
249 do
250 {
251 char answer[128];
252 printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ", path);
253 if (scanf("%1s", answer) != 1)
254 exit(EXIT_FAILURE);
255 rep = answer[0];
256
257 if ((rep >= 'a') && (rep <= 'z'))
258 rep -= 0x20;
259 }
260 while ((rep != 'Y') && (rep != 'N') && (rep != 'A'));
261
262 if (rep == 'A')
263 {
264 return MZ_EXIST_ERROR;
265 }
266 else if (rep == 'N')
267 {
268 return MZ_INTERNAL_ERROR;
269 }
270 }
271
272 return MZ_OK;
273 }
274
minizip_add(const char * path,const char * password,minizip_opt * options,int32_t arg_count,const char ** args)275 int32_t minizip_add(const char *path, const char *password, minizip_opt *options, int32_t arg_count, const char **args)
276 {
277 void *writer = NULL;
278 int32_t err = MZ_OK;
279 int32_t err_close = MZ_OK;
280 int32_t i = 0;
281 const char *filename_in_zip = NULL;
282
283
284 printf("Archive %s\n", path);
285
286 /* Create zip writer */
287 mz_zip_writer_create(&writer);
288 mz_zip_writer_set_password(writer, password);
289 mz_zip_writer_set_compress_method(writer, options->compress_method);
290 mz_zip_writer_set_compress_level(writer, options->compress_level);
291 mz_zip_writer_set_overwrite_cb(writer, options, minizip_add_overwrite_cb);
292 mz_zip_writer_set_comment(writer, "xyz");
293 mz_zip_writer_set_progress_cb(writer, options, minizip_add_progress_cb);
294 mz_zip_writer_set_entry_cb(writer, options, minizip_add_entry_cb);
295 mz_zip_writer_set_zip_cd(writer, options->zip_cd);
296 if (options->cert_path != NULL)
297 mz_zip_writer_set_certificate(writer, options->cert_path, options->cert_pwd);
298
299 err = mz_zip_writer_open_file(writer, path, options->disk_size, options->append);
300
301 if (err == MZ_OK)
302 {
303 for (i = 0; i < arg_count; i += 1)
304 {
305 filename_in_zip = args[i];
306
307 /* Add file system path to zip */
308 err = mz_zip_writer_add_path(writer, filename_in_zip, NULL, options->include_path, 1);
309 if (err != MZ_OK)
310 printf("Error %"PRId32" adding path to zip %s\n", err, filename_in_zip);
311 }
312 }
313 else
314 {
315 printf("Error %"PRId32" opening zip for writing\n", err);
316 }
317
318 err_close = mz_zip_writer_close(writer);
319 if (err_close != MZ_OK)
320 {
321 printf("Error %"PRId32" closing zip for writing %s\n", err_close, path);
322 err = err_close;
323 }
324
325 mz_zip_writer_delete(&writer);
326 return err;
327 }
328
329 /***************************************************************************/
330
minizip_extract_entry_cb(void * handle,void * userdata,mz_zip_file * file_info,const char * path)331 int32_t minizip_extract_entry_cb(void *handle, void *userdata, mz_zip_file *file_info, const char *path)
332 {
333 MZ_UNUSED(handle);
334 MZ_UNUSED(userdata);
335 MZ_UNUSED(path);
336
337 /* Print the current entry extracting */
338 printf("Extracting %s\n", file_info->filename);
339 return MZ_OK;
340 }
341
minizip_extract_progress_cb(void * handle,void * userdata,mz_zip_file * file_info,int64_t position)342 int32_t minizip_extract_progress_cb(void *handle, void *userdata, mz_zip_file *file_info, int64_t position)
343 {
344 minizip_opt *options = (minizip_opt *)userdata;
345 double progress = 0;
346 uint8_t raw = 0;
347
348 MZ_UNUSED(userdata);
349
350 mz_zip_reader_get_raw(handle, &raw);
351
352 if (raw && file_info->compressed_size > 0)
353 progress = ((double)position / file_info->compressed_size) * 100;
354 else if (!raw && file_info->uncompressed_size > 0)
355 progress = ((double)position / file_info->uncompressed_size) * 100;
356
357 /* Print the progress of the current extraction */
358 if (options->verbose)
359 printf("%s - %"PRId64" / %"PRId64" (%.02f%%)\n", file_info->filename, position,
360 file_info->uncompressed_size, progress);
361
362 return MZ_OK;
363 }
364
minizip_extract_overwrite_cb(void * handle,void * userdata,mz_zip_file * file_info,const char * path)365 int32_t minizip_extract_overwrite_cb(void *handle, void *userdata, mz_zip_file *file_info, const char *path)
366 {
367 minizip_opt *options = (minizip_opt *)userdata;
368
369 MZ_UNUSED(handle);
370 MZ_UNUSED(file_info);
371
372 /* Verify if we want to overwrite current entry on disk */
373 if (options->overwrite == 0)
374 {
375 char rep = 0;
376 do
377 {
378 char answer[128];
379 printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ", path);
380 if (scanf("%1s", answer) != 1)
381 exit(EXIT_FAILURE);
382 rep = answer[0];
383 if ((rep >= 'a') && (rep <= 'z'))
384 rep -= 0x20;
385 } while ((rep != 'Y') && (rep != 'N') && (rep != 'A'));
386
387 if (rep == 'N')
388 return MZ_EXIST_ERROR;
389 if (rep == 'A')
390 options->overwrite = 1;
391 }
392
393 return MZ_OK;
394 }
395
minizip_extract(const char * path,const char * pattern,const char * destination,const char * password,minizip_opt * options)396 int32_t minizip_extract(const char *path, const char *pattern, const char *destination, const char *password, minizip_opt *options)
397 {
398 void *reader = NULL;
399 int32_t err = MZ_OK;
400 int32_t err_close = MZ_OK;
401
402
403 printf("Archive %s\n", path);
404
405 /* Create zip reader */
406 mz_zip_reader_create(&reader);
407 mz_zip_reader_set_pattern(reader, pattern, 1);
408 mz_zip_reader_set_password(reader, password);
409 mz_zip_reader_set_encoding(reader, options->encoding);
410 mz_zip_reader_set_entry_cb(reader, options, minizip_extract_entry_cb);
411 mz_zip_reader_set_progress_cb(reader, options, minizip_extract_progress_cb);
412 mz_zip_reader_set_overwrite_cb(reader, options, minizip_extract_overwrite_cb);
413
414 err = mz_zip_reader_open_file(reader, path);
415
416 if (err != MZ_OK)
417 {
418 printf("Error %"PRId32" opening zip file %s\n", err, path);
419 }
420 else
421 {
422 /* Save all entries in zip file to destination directory */
423 err = mz_zip_reader_save_all(reader, destination);
424
425 if (err == MZ_END_OF_LIST && pattern != NULL)
426 printf("Files matching %s not found in zip file\n", pattern);
427 if (err != MZ_OK)
428 printf("Error %"PRId32" saving zip entries to disk %s\n", err, path);
429 }
430
431 err_close = mz_zip_reader_close(reader);
432 if (err_close != MZ_OK)
433 {
434 printf("Error %"PRId32" closing zip for reading\n", err_close);
435 err = err_close;
436 }
437
438 mz_zip_reader_delete(&reader);
439 return err;
440 }
441
442 /***************************************************************************/
443
minizip_erase(const char * src_path,const char * target_path,int32_t arg_count,const char ** args)444 int32_t minizip_erase(const char *src_path, const char *target_path, int32_t arg_count, const char **args)
445 {
446 mz_zip_file *file_info = NULL;
447 const char *filename_in_zip = NULL;
448 const char *target_path_ptr = target_path;
449 void *reader = NULL;
450 void *writer = NULL;
451 int32_t skip = 0;
452 int32_t err = MZ_OK;
453 int32_t i = 0;
454 uint8_t zip_cd = 0;
455 char bak_path[256];
456 char tmp_path[256];
457
458 if (target_path == NULL)
459 {
460 /* Construct temporary zip name */
461 strncpy(tmp_path, src_path, sizeof(tmp_path) - 1);
462 tmp_path[sizeof(tmp_path) - 1] = 0;
463 strncat(tmp_path, ".tmp.zip", sizeof(tmp_path) - strlen(tmp_path) - 1);
464 target_path_ptr = tmp_path;
465 }
466
467 mz_zip_reader_create(&reader);
468 mz_zip_writer_create(&writer);
469
470 /* Open original zip file we want to erase an entry in */
471 err = mz_zip_reader_open_file(reader, src_path);
472 if (err != MZ_OK)
473 {
474 printf("Error %"PRId32" opening zip for reading %s\n", err, src_path);
475 mz_zip_reader_delete(&reader);
476 return err;
477 }
478
479 /* Open temporary zip file */
480 err = mz_zip_writer_open_file(writer, target_path_ptr, 0, 0);
481 if (err != MZ_OK)
482 {
483 printf("Error %"PRId32" opening zip for writing %s\n", err, target_path_ptr);
484 mz_zip_reader_delete(&reader);
485 mz_zip_writer_delete(&writer);
486 return err;
487 }
488
489 err = mz_zip_reader_goto_first_entry(reader);
490
491 if (err != MZ_OK && err != MZ_END_OF_LIST)
492 printf("Error %"PRId32" going to first entry in zip file\n", err);
493
494 while (err == MZ_OK)
495 {
496 err = mz_zip_reader_entry_get_info(reader, &file_info);
497 if (err != MZ_OK)
498 {
499 printf("Error %"PRId32" getting info from zip\n", err);
500 break;
501 }
502
503 /* Copy all entries from original zip file to temporary zip file
504 except the ones we don't want */
505 for (i = 0, skip = 0; i < arg_count; i += 1)
506 {
507 filename_in_zip = args[i];
508
509 if (mz_path_compare_wc(file_info->filename, filename_in_zip, 1) == MZ_OK)
510 skip = 1;
511 }
512
513 if (skip)
514 {
515 printf("Skipping %s\n", file_info->filename);
516 }
517 else
518 {
519 printf("Copying %s\n", file_info->filename);
520 err = mz_zip_writer_copy_from_reader(writer, reader);
521 }
522
523 if (err != MZ_OK)
524 {
525 printf("Error %"PRId32" copying entry into new zip\n", err);
526 break;
527 }
528
529 err = mz_zip_reader_goto_next_entry(reader);
530
531 if (err != MZ_OK && err != MZ_END_OF_LIST)
532 printf("Error %"PRId32" going to next entry in zip file\n", err);
533 }
534
535 mz_zip_reader_get_zip_cd(reader, &zip_cd);
536 mz_zip_writer_set_zip_cd(writer, zip_cd);
537
538 mz_zip_reader_close(reader);
539 mz_zip_reader_delete(&reader);
540
541 mz_zip_writer_close(writer);
542 mz_zip_writer_delete(&writer);
543
544 if (err == MZ_END_OF_LIST)
545 {
546 if (target_path == NULL)
547 {
548 /* Swap original zip with temporary zip, backup old zip if possible */
549 strncpy(bak_path, src_path, sizeof(bak_path) - 1);
550 bak_path[sizeof(bak_path) - 1] = 0;
551 strncat(bak_path, ".bak", sizeof(bak_path) - strlen(bak_path) - 1);
552
553 if (mz_os_file_exists(bak_path) == MZ_OK)
554 mz_os_delete(bak_path);
555
556 if (mz_os_rename(src_path, bak_path) != MZ_OK)
557 printf("Error backing up zip before replacing %s\n", bak_path);
558
559 if (mz_os_rename(tmp_path, src_path) != MZ_OK)
560 printf("Error replacing zip with temp %s\n", tmp_path);
561 }
562
563 return MZ_OK;
564 }
565
566 return err;
567 }
568
569 /***************************************************************************/
570
571 #if !defined(MZ_ZIP_NO_MAIN)
main(int argc,const char * argv[])572 int main(int argc, const char *argv[])
573 {
574 minizip_opt options;
575 int32_t path_arg = 0;
576 int32_t err = 0;
577 int32_t i = 0;
578 uint8_t do_list = 0;
579 uint8_t do_extract = 0;
580 uint8_t do_erase = 0;
581 const char *path = NULL;
582 const char *password = NULL;
583 const char *destination = NULL;
584 const char *filename_to_extract = NULL;
585
586
587 minizip_banner();
588 if (argc == 1)
589 {
590 minizip_help();
591 return 0;
592 }
593
594 memset(&options, 0, sizeof(options));
595
596 options.compress_method = MZ_COMPRESS_METHOD_DEFLATE;
597 options.compress_level = MZ_COMPRESS_LEVEL_DEFAULT;
598
599 /* Parse command line options */
600 for (i = 1; i < argc; i += 1)
601 {
602 printf("%s ", argv[i]);
603 if (argv[i][0] == '-')
604 {
605 char c = argv[i][1];
606 if ((c == 'l') || (c == 'L'))
607 do_list = 1;
608 else if ((c == 'x') || (c == 'X'))
609 do_extract = 1;
610 else if ((c == 'e') || (c == 'E'))
611 do_erase = 1;
612 else if ((c == 'a') || (c == 'A'))
613 options.append = 1;
614 else if ((c == 'o') || (c == 'O'))
615 options.overwrite = 1;
616 else if ((c == 'i') || (c == 'I'))
617 options.include_path = 1;
618 else if ((c == 'z') || (c == 'Z'))
619 options.zip_cd = 1;
620 else if ((c == 'v') || (c == 'V'))
621 options.verbose = 1;
622 else if ((c >= '0') && (c <= '9'))
623 {
624 options.compress_level = (c - '0');
625 if (options.compress_level == 0)
626 options.compress_method = MZ_COMPRESS_METHOD_STORE;
627 }
628 else if ((c == 'b') || (c == 'B'))
629 #ifdef HAVE_BZIP2
630 options.compress_method = MZ_COMPRESS_METHOD_BZIP2;
631 #else
632 err = MZ_SUPPORT_ERROR;
633 #endif
634 else if ((c == 'm') || (c == 'M'))
635 #ifdef HAVE_LZMA
636 options.compress_method = MZ_COMPRESS_METHOD_LZMA;
637 #else
638 err = MZ_SUPPORT_ERROR;
639 #endif
640 else if ((c == 's') || (c == 'S'))
641 #ifdef HAVE_WZAES
642 options.aes = 1;
643 #else
644 err = MZ_SUPPORT_ERROR;
645 #endif
646 else if (((c == 'h') || (c == 'H')) && (i + 1 < argc))
647 {
648 #ifndef MZ_ZIP_NO_SIGNING
649 options.cert_path = argv[i + 1];
650 printf("%s ", argv[i + 1]);
651 #else
652 err = MZ_SUPPORT_ERROR;
653 #endif
654 i += 1;
655 }
656 else if (((c == 'w') || (c == 'W')) && (i + 1 < argc))
657 {
658 #ifndef MZ_ZIP_NO_SIGNING
659 options.cert_pwd = argv[i + 1];
660 printf("%s ", argv[i + 1]);
661 #else
662 err = MZ_SUPPORT_ERROR;
663 #endif
664 i += 1;
665 }
666 else if (((c == 'c') || (c == 'C')) && (i + 1 < argc))
667 {
668 options.encoding = (int32_t)atoi(argv[i + 1]);
669 i += 1;
670 }
671 else if (((c == 'k') || (c == 'K')) && (i + 1 < argc))
672 {
673 options.disk_size = (int64_t)atoi(argv[i + 1]) * 1024;
674 printf("%s ", argv[i + 1]);
675 i += 1;
676 }
677 else if (((c == 'd') || (c == 'D')) && (i + 1 < argc))
678 {
679 destination = argv[i + 1];
680 printf("%s ", argv[i + 1]);
681 i += 1;
682 }
683 else if (((c == 'p') || (c == 'P')) && (i + 1 < argc))
684 {
685 #ifndef MZ_ZIP_NO_ENCRYPTION
686 password = argv[i + 1];
687 printf("*** ");
688 #else
689 err = MZ_SUPPORT_ERROR;
690 #endif
691 i += 1;
692 }
693 }
694 else if (path_arg == 0)
695 path_arg = i;
696 }
697 printf("\n");
698
699 if (err == MZ_SUPPORT_ERROR)
700 {
701 printf("Feature not supported\n");
702 return err;
703 }
704
705 if (path_arg == 0)
706 {
707 minizip_help();
708 return 0;
709 }
710
711
712 path = argv[path_arg];
713
714 if (do_list)
715 {
716 /* List zip file contents */
717 err = minizip_list(path);
718 }
719 else if (do_extract)
720 {
721 if (argc > path_arg + 1)
722 filename_to_extract = argv[path_arg + 1];
723
724 /* Extract zip file*/
725 err = minizip_extract(path, filename_to_extract, destination, password, &options);
726 }
727 else if (do_erase)
728 {
729 /* Erase file from zip */
730 err = minizip_erase(path, NULL, argc - (path_arg + 1), &argv[path_arg + 1]);
731 }
732 else
733 {
734 /* Add files to zip */
735 err = minizip_add(path, password, &options, argc - (path_arg + 1), &argv[path_arg + 1]);
736 }
737
738
739 return err;
740 }
741 #endif
742