Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/archival/unzip.c
- Timestamp:
- Jan 1, 2014, 12:47:38 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.2/mindi-busybox/archival/unzip.c
r2725 r3232 20 20 */ 21 21 22 //usage:#define unzip_trivial_usage 23 //usage: "[-lnopq] FILE[.zip] [FILE]... [-x FILE...] [-d DIR]" 24 //usage:#define unzip_full_usage "\n\n" 25 //usage: "Extract FILEs from ZIP archive\n" 26 //usage: "\n -l List contents (with -q for short form)" 27 //usage: "\n -n Never overwrite files (default: ask)" 28 //usage: "\n -o Overwrite" 29 //usage: "\n -p Print to stdout" 30 //usage: "\n -q Quiet" 31 //usage: "\n -x FILE Exclude FILEs" 32 //usage: "\n -d DIR Extract into DIR" 33 22 34 #include "libbb.h" 23 #include " archive.h"35 #include "bb_archive.h" 24 36 25 37 enum { … … 224 236 char *name = xstrdup(fn); 225 237 if (bb_make_directory(dirname(name), 0777, FILEUTILS_RECUR)) { 226 bb_error_msg_and_die("exiting"); /* bb_make_directory is noisy */238 xfunc_die(); /* bb_make_directory is noisy */ 227 239 } 228 240 free(name); … … 238 250 } else { 239 251 /* Method 8 - inflate */ 240 inflate_unzip_result res; 241 if (inflate_unzip(&res, zip_header->formatted.cmpsize, zip_fd, dst_fd) < 0) 252 transformer_aux_data_t aux; 253 init_transformer_aux_data(&aux); 254 aux.bytes_in = zip_header->formatted.cmpsize; 255 if (inflate_unzip(&aux, zip_fd, dst_fd) < 0) 242 256 bb_error_msg_and_die("inflate error"); 243 257 /* Validate decompression - crc */ 244 if (zip_header->formatted.crc32 != ( res.crc^ 0xffffffffL)) {258 if (zip_header->formatted.crc32 != (aux.crc32 ^ 0xffffffffL)) { 245 259 bb_error_msg_and_die("crc error"); 246 260 } 247 261 /* Validate decompression - size */ 248 if (zip_header->formatted.ucmpsize != res.bytes_out) {262 if (zip_header->formatted.ucmpsize != aux.bytes_out) { 249 263 /* Don't die. Who knows, maybe len calculation 250 264 * was botched somewhere. After all, crc matched! */ … … 264 278 smallint listing = 0; 265 279 smallint overwrite = O_PROMPT; 280 smallint x_opt_seen; 266 281 #if ENABLE_DESKTOP 267 282 uint32_t cdf_offset; … … 277 292 char *base_dir = NULL; 278 293 int i, opt; 279 int opt_range = 0;280 294 char key_buf[80]; 281 295 struct stat stat_buf; … … 322 336 */ 323 337 338 x_opt_seen = 0; 324 339 /* '-' makes getopt return 1 for non-options */ 325 340 while ((opt = getopt(argc, argv, "-d:lnopqxv")) != -1) { 326 switch (opt_range) { 327 case 0: /* Options */ 328 switch (opt) { 329 case 'l': /* List */ 330 listing = 1; 331 break; 332 333 case 'n': /* Never overwrite existing files */ 334 overwrite = O_NEVER; 335 break; 336 337 case 'o': /* Always overwrite existing files */ 338 overwrite = O_ALWAYS; 339 break; 340 341 case 'p': /* Extract files to stdout and fall through to set verbosity */ 342 dst_fd = STDOUT_FILENO; 343 344 case 'q': /* Be quiet */ 345 quiet++; 346 break; 347 348 case 'v': /* Verbose list */ 349 IF_DESKTOP(verbose++;) 350 listing = 1; 351 break; 352 353 case 1: /* The zip file */ 341 switch (opt) { 342 case 'd': /* Extract to base directory */ 343 base_dir = optarg; 344 break; 345 346 case 'l': /* List */ 347 listing = 1; 348 break; 349 350 case 'n': /* Never overwrite existing files */ 351 overwrite = O_NEVER; 352 break; 353 354 case 'o': /* Always overwrite existing files */ 355 overwrite = O_ALWAYS; 356 break; 357 358 case 'p': /* Extract files to stdout and fall through to set verbosity */ 359 dst_fd = STDOUT_FILENO; 360 361 case 'q': /* Be quiet */ 362 quiet++; 363 break; 364 365 case 'v': /* Verbose list */ 366 IF_DESKTOP(verbose++;) 367 listing = 1; 368 break; 369 370 case 'x': 371 x_opt_seen = 1; 372 break; 373 374 case 1: 375 if (!src_fn) { 376 /* The zip file */ 354 377 /* +5: space for ".zip" and NUL */ 355 378 src_fn = xmalloc(strlen(optarg) + 5); 356 379 strcpy(src_fn, optarg); 357 opt_range++; 358 break; 359 360 default: 361 bb_show_usage(); 380 } else if (!x_opt_seen) { 381 /* Include files */ 382 llist_add_to(&zaccept, optarg); 383 } else { 384 /* Exclude files */ 385 llist_add_to(&zreject, optarg); 362 386 } 363 387 break; 364 365 case 1: /* Include files */366 if (opt == 1) {367 llist_add_to(&zaccept, optarg);368 break;369 }370 if (opt == 'd') {371 base_dir = optarg;372 opt_range += 2;373 break;374 }375 if (opt == 'x') {376 opt_range++;377 break;378 }379 bb_show_usage();380 381 case 2 : /* Exclude files */382 if (opt == 1) {383 llist_add_to(&zreject, optarg);384 break;385 }386 if (opt == 'd') { /* Extract to base directory */387 base_dir = optarg;388 opt_range++;389 break;390 }391 /* fall through */392 388 393 389 default: … … 396 392 } 397 393 398 if (src_fn == NULL) { 394 #ifndef __GLIBC__ 395 /* 396 * This code is needed for non-GNU getopt 397 * which doesn't understand "-" in option string. 398 * The -x option won't work properly in this case: 399 * "unzip a.zip q -x w e" will be interpreted as 400 * "unzip a.zip q w e -x" = "unzip a.zip q w e" 401 */ 402 argv += optind; 403 if (argv[0]) { 404 /* +5: space for ".zip" and NUL */ 405 src_fn = xmalloc(strlen(argv[0]) + 5); 406 strcpy(src_fn, argv[0]); 407 while (*++argv) 408 llist_add_to(&zaccept, *argv); 409 } 410 #endif 411 412 if (!src_fn) { 399 413 bb_show_usage(); 400 414 } … … 407 421 overwrite = O_NEVER; 408 422 } else { 409 static const char extn[][5] = { "", ".zip", ".ZIP"};410 int orig_src_fn_len =strlen(src_fn);411 int src_fd = -1;412 413 for (i = 0; (i < 3) && (src_fd == -1); i++) {414 strcpy(src_fn + orig_src_fn_len, extn[i]);423 static const char extn[][5] = { ".zip", ".ZIP" }; 424 char *ext = src_fn + strlen(src_fn); 425 int src_fd; 426 427 i = 0; 428 for (;;) { 415 429 src_fd = open(src_fn, O_RDONLY); 416 } 417 if (src_fd == -1) { 418 src_fn[orig_src_fn_len] = '\0'; 419 bb_error_msg_and_die("can't open %s, %s.zip, %s.ZIP", src_fn, src_fn, src_fn); 430 if (src_fd >= 0) 431 break; 432 if (++i > 2) { 433 *ext = '\0'; 434 bb_error_msg_and_die("can't open %s[.zip]", src_fn); 435 } 436 strcpy(ext, extn[i - 1]); 420 437 } 421 438 xmove_fd(src_fd, zip_fd); … … 583 600 } 584 601 unzip_create_leading_dirs(dst_fn); 585 if (bb_make_directory(dst_fn, dir_mode, 0)) {586 bb_error_msg_and_die("exiting");602 if (bb_make_directory(dst_fn, dir_mode, FILEUTILS_IGNORE_CHMOD_ERR)) { 603 xfunc_die(); 587 604 } 588 605 } else { … … 608 625 } else { 609 626 printf("replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", dst_fn); 627 fflush_all(); 610 628 if (!fgets(key_buf, sizeof(key_buf), stdin)) { 611 629 bb_perror_msg_and_die("can't read input");
Note:
See TracChangeset
for help on using the changeset viewer.