Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/archival/tar.c
- Timestamp:
- Dec 20, 2016, 4:07:32 PM (7 years ago)
- Location:
- branches/3.3
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mindi-busybox/archival/tar.c
r3232 r3621 23 23 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 24 24 */ 25 26 25 /* TODO: security with -C DESTDIR option can be enhanced. 27 26 * Consider tar file created via: … … 43 42 */ 44 43 44 //config:config TAR 45 //config: bool "tar" 46 //config: default y 47 //config: help 48 //config: tar is an archiving program. It's commonly used with gzip to 49 //config: create compressed archives. It's probably the most widely used 50 //config: UNIX archive program. 51 //config: 52 //config:config FEATURE_TAR_CREATE 53 //config: bool "Enable archive creation" 54 //config: default y 55 //config: depends on TAR 56 //config: help 57 //config: If you enable this option you'll be able to create 58 //config: tar archives using the `-c' option. 59 //config: 60 //config:config FEATURE_TAR_AUTODETECT 61 //config: bool "Autodetect compressed tarballs" 62 //config: default y 63 //config: depends on TAR && (FEATURE_SEAMLESS_Z || FEATURE_SEAMLESS_GZ || FEATURE_SEAMLESS_BZ2 || FEATURE_SEAMLESS_LZMA || FEATURE_SEAMLESS_XZ) 64 //config: help 65 //config: With this option tar can automatically detect compressed 66 //config: tarballs. Currently it works only on files (not pipes etc). 67 //config: 68 //config:config FEATURE_TAR_FROM 69 //config: bool "Enable -X (exclude from) and -T (include from) options)" 70 //config: default y 71 //config: depends on TAR 72 //config: help 73 //config: If you enable this option you'll be able to specify 74 //config: a list of files to include or exclude from an archive. 75 //config: 76 //config:config FEATURE_TAR_OLDGNU_COMPATIBILITY 77 //config: bool "Support for old tar header format" 78 //config: default y 79 //config: depends on TAR || DPKG 80 //config: help 81 //config: This option is required to unpack archives created in 82 //config: the old GNU format; help to kill this old format by 83 //config: repacking your ancient archives with the new format. 84 //config: 85 //config:config FEATURE_TAR_OLDSUN_COMPATIBILITY 86 //config: bool "Enable untarring of tarballs with checksums produced by buggy Sun tar" 87 //config: default y 88 //config: depends on TAR || DPKG 89 //config: help 90 //config: This option is required to unpack archives created by some old 91 //config: version of Sun's tar (it was calculating checksum using signed 92 //config: arithmetic). It is said to be fixed in newer Sun tar, but "old" 93 //config: tarballs still exist. 94 //config: 95 //config:config FEATURE_TAR_GNU_EXTENSIONS 96 //config: bool "Support for GNU tar extensions (long filenames)" 97 //config: default y 98 //config: depends on TAR || DPKG 99 //config: help 100 //config: With this option busybox supports GNU long filenames and 101 //config: linknames. 102 //config: 103 //config:config FEATURE_TAR_LONG_OPTIONS 104 //config: bool "Enable long options" 105 //config: default y 106 //config: depends on TAR && LONG_OPTS 107 //config: help 108 //config: Enable use of long options, increases size by about 400 Bytes 109 //config: 110 //config:config FEATURE_TAR_TO_COMMAND 111 //config: bool "Support for writing to an external program" 112 //config: default y 113 //config: depends on TAR && FEATURE_TAR_LONG_OPTIONS 114 //config: help 115 //config: If you enable this option you'll be able to instruct tar to send 116 //config: the contents of each extracted file to the standard input of an 117 //config: external program. 118 //config: 119 //config:config FEATURE_TAR_UNAME_GNAME 120 //config: bool "Enable use of user and group names" 121 //config: default y 122 //config: depends on TAR 123 //config: help 124 //config: Enables use of user and group names in tar. This affects contents 125 //config: listings (-t) and preserving permissions when unpacking (-p). 126 //config: +200 bytes. 127 //config: 128 //config:config FEATURE_TAR_NOPRESERVE_TIME 129 //config: bool "Enable -m (do not preserve time) option" 130 //config: default y 131 //config: depends on TAR 132 //config: help 133 //config: With this option busybox supports GNU tar -m 134 //config: (do not preserve time) option. 135 //config: 136 //config:config FEATURE_TAR_SELINUX 137 //config: bool "Support for extracting SELinux labels" 138 //config: default n 139 //config: depends on TAR && SELINUX 140 //config: help 141 //config: With this option busybox supports restoring SELinux labels 142 //config: when extracting files from tar archives. 143 144 //applet:IF_TAR(APPLET(tar, BB_DIR_BIN, BB_SUID_DROP)) 145 //kbuild:lib-$(CONFIG_TAR) += tar.o 146 45 147 #include <fnmatch.h> 46 148 #include "libbb.h" 149 #include "common_bufsiz.h" 47 150 #include "bb_archive.h" 48 151 /* FIXME: Stop using this non-standard feature */ … … 51 154 #endif 52 155 53 54 //#define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__) 55 #define DBG(...) ((void)0) 156 #if 0 157 # define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__) 158 #else 159 # define DBG(...) ((void)0) 160 #endif 161 #define DBG_OPTION_PARSING 0 56 162 57 163 58 164 #define block_buf bb_common_bufsiz1 59 60 61 #if !ENABLE_FEATURE_SEAMLESS_GZ && !ENABLE_FEATURE_SEAMLESS_BZ2 62 /* Do not pass gzip flag to writeTarFile() */ 63 #define writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude, gzip) \ 64 writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude) 65 #endif 165 #define INIT_G() do { setup_common_bufsiz(); } while (0) 66 166 67 167 … … 520 620 } 521 621 522 #if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 523 # if !(ENABLE_FEATURE_SEAMLESS_GZ && ENABLE_FEATURE_SEAMLESS_BZ2) 524 # define vfork_compressor(tar_fd, gzip) vfork_compressor(tar_fd) 525 # endif 622 #if SEAMLESS_COMPRESSION 526 623 /* Don't inline: vfork scares gcc and pessimizes code */ 527 static void NOINLINE vfork_compressor(int tar_fd, intgzip)624 static void NOINLINE vfork_compressor(int tar_fd, const char *gzip) 528 625 { 529 626 pid_t gzipPid; 530 # if ENABLE_FEATURE_SEAMLESS_GZ && ENABLE_FEATURE_SEAMLESS_BZ2 531 const char *zip_exec = (gzip == 1) ? "gzip" : "bzip2"; 532 # elif ENABLE_FEATURE_SEAMLESS_GZ 533 const char *zip_exec = "gzip"; 534 # else /* only ENABLE_FEATURE_SEAMLESS_BZ2 */ 535 const char *zip_exec = "bzip2"; 536 # endif 627 537 628 // On Linux, vfork never unpauses parent early, although standard 538 629 // allows for that. Do we want to waste bytes checking for it? … … 547 638 548 639 signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */ 549 550 # if defined(__GNUC__) && __GNUC__551 /* Avoid vfork clobbering */552 (void) &zip_exec;553 # endif554 640 555 641 gzipPid = xvfork(); … … 568 654 xmove_fd(tar_fd, 1); 569 655 /* exec gzip/bzip2 program/applet */ 570 BB_EXECLP( zip_exec, zip_exec, "-f", NULL);656 BB_EXECLP(gzip, gzip, "-f", (char *)0); 571 657 vfork_exec_errno = errno; 572 658 _exit(EXIT_FAILURE); … … 591 677 if (vfork_exec_errno) { 592 678 errno = vfork_exec_errno; 593 bb_perror_msg_and_die("can't execute '%s'", zip_exec);679 bb_perror_msg_and_die("can't execute '%s'", gzip); 594 680 } 595 681 } 596 #endif /* ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 */ 597 598 682 #endif /* SEAMLESS_COMPRESSION */ 683 684 685 #if !SEAMLESS_COMPRESSION 686 /* Do not pass gzip flag to writeTarFile() */ 687 #define writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude, gzip) \ 688 writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude) 689 #endif 599 690 /* gcc 4.2.1 inlines it, making code bigger */ 600 691 static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, 601 692 int recurseFlags, const llist_t *include, 602 const llist_t *exclude, intgzip)693 const llist_t *exclude, const char *gzip) 603 694 { 604 695 int errorFlag = FALSE; … … 613 704 xfstat(tbInfo.tarFd, &tbInfo.tarFileStatBuf, "can't stat tar file"); 614 705 615 #if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2706 #if SEAMLESS_COMPRESSION 616 707 if (gzip) 617 708 vfork_compressor(tbInfo.tarFd, gzip); … … 648 739 bb_error_msg("error exit delayed from previous errors"); 649 740 650 #if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2741 #if SEAMLESS_COMPRESSION 651 742 if (gzip) { 652 743 int status; … … 660 751 return errorFlag; 661 752 } 662 #else 663 int writeTarFile(int tar_fd, int verboseFlag, 664 int recurseFlags, const llist_t *include, 665 const llist_t *exclude, int gzip); 666 #endif /* FEATURE_TAR_CREATE */ 753 #else /* !FEATURE_TAR_CREATE */ 754 # define writeTarFile(...) 0 755 #endif 667 756 668 757 #if ENABLE_FEATURE_TAR_FROM … … 680 769 if (cp > line) 681 770 *cp = '\0'; 682 llist_add_to (&newlist, line);771 llist_add_to_end(&newlist, line); 683 772 } 684 773 fclose(src_stream); … … 686 775 return newlist; 687 776 } 688 #else689 # define append_file_list_to_list(x) 0690 777 #endif 691 778 … … 774 861 IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) 775 862 #if ENABLE_FEATURE_TAR_LONG_OPTIONS 863 OPTBIT_STRIP_COMPONENTS, 776 864 OPTBIT_NORECURSION, 777 865 IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,) … … 798 886 OPT_XZ = IF_FEATURE_SEAMLESS_XZ( (1 << OPTBIT_XZ )) + 0, // J 799 887 OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z 800 OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m 801 OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion 802 OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command 803 OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner 804 OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions 805 OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite 888 OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m 889 OPT_STRIP_COMPONENTS = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_STRIP_COMPONENTS)) + 0, // strip-components 890 OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion 891 OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command 892 OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner 893 OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions 894 OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite 806 895 807 896 OPT_ANY_COMPRESS = (OPT_BZIP2 | OPT_LZMA | OPT_GZIP | OPT_XZ | OPT_COMPRESS), … … 847 936 "touch\0" No_argument "m" 848 937 # endif 938 "strip-components\0" Required_argument "\xf9" 849 939 "no-recursion\0" No_argument "\xfa" 850 940 # if ENABLE_FEATURE_TAR_TO_COMMAND … … 876 966 llist_t *excludes = NULL; 877 967 #endif 968 INIT_G(); 878 969 879 970 /* Initialise default values */ … … 892 983 IF_FEATURE_TAR_FROM("X::T::") // cumulative lists 893 984 #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM 894 "\xff::" // cumulative lists for --exclude985 "\xff::" // --exclude=PATTERN is a list 895 986 #endif 896 987 IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd 897 988 IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive 898 IF_NOT_FEATURE_TAR_CREATE("t--x:x--t"); // mutually exclusive 989 IF_NOT_FEATURE_TAR_CREATE("t--x:x--t") // mutually exclusive 990 #if ENABLE_FEATURE_TAR_LONG_OPTIONS 991 ":\xf9+" // --strip-components=NUM 992 #endif 993 ; 899 994 #if ENABLE_FEATURE_TAR_LONG_OPTIONS 900 995 applet_long_options = tar_longopts; 901 996 #endif 902 997 #if ENABLE_DESKTOP 998 /* Lie to buildroot when it starts asking stupid questions. */ 999 if (argv[1] && strcmp(argv[1], "--version") == 0) { 1000 // Output of 'tar --version' examples: 1001 // tar (GNU tar) 1.15.1 1002 // tar (GNU tar) 1.25 1003 // bsdtar 2.8.3 - libarchive 2.8.3 1004 puts("tar (busybox) " BB_VER); 1005 return 0; 1006 } 903 1007 if (argv[1] && argv[1][0] != '-') { 904 1008 /* Compat: … … 937 1041 IF_FEATURE_SEAMLESS_Z( "Z" ) 938 1042 IF_FEATURE_TAR_NOPRESERVE_TIME("m") 1043 IF_FEATURE_TAR_LONG_OPTIONS("\xf9:") // --strip-components 939 1044 , &base_dir // -C dir 940 1045 , &tar_filename // -f filename 941 1046 IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T 942 1047 IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X 1048 #if ENABLE_FEATURE_TAR_LONG_OPTIONS 1049 , &tar_handle->tar__strip_components // --strip-components 1050 #endif 943 1051 IF_FEATURE_TAR_TO_COMMAND(, &(tar_handle->tar__to_command)) // --to-command 944 1052 #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM … … 948 1056 , &verboseFlag // combined count for -t and -v 949 1057 ); 950 //bb_error_msg("opt:%08x", opt); 1058 #if DBG_OPTION_PARSING 1059 bb_error_msg("opt: 0x%08x", opt); 1060 # define showopt(o) bb_error_msg("opt & %s(%x): %x", #o, o, opt & o); 1061 showopt(OPT_TEST ); 1062 showopt(OPT_EXTRACT ); 1063 showopt(OPT_BASEDIR ); 1064 showopt(OPT_TARNAME ); 1065 showopt(OPT_2STDOUT ); 1066 showopt(OPT_NOPRESERVE_OWNER); 1067 showopt(OPT_P ); 1068 showopt(OPT_VERBOSE ); 1069 showopt(OPT_KEEP_OLD ); 1070 showopt(OPT_CREATE ); 1071 showopt(OPT_DEREFERENCE ); 1072 showopt(OPT_BZIP2 ); 1073 showopt(OPT_LZMA ); 1074 showopt(OPT_INCLUDE_FROM ); 1075 showopt(OPT_EXCLUDE_FROM ); 1076 showopt(OPT_GZIP ); 1077 showopt(OPT_XZ ); 1078 showopt(OPT_COMPRESS ); 1079 showopt(OPT_NOPRESERVE_TIME ); 1080 showopt(OPT_STRIP_COMPONENTS); 1081 showopt(OPT_NORECURSION ); 1082 showopt(OPT_2COMMAND ); 1083 showopt(OPT_NUMERIC_OWNER ); 1084 showopt(OPT_NOPRESERVE_PERM ); 1085 showopt(OPT_OVERWRITE ); 1086 showopt(OPT_ANY_COMPRESS ); 1087 bb_error_msg("base_dir:'%s'", base_dir); 1088 bb_error_msg("tar_filename:'%s'", tar_filename); 1089 bb_error_msg("verboseFlag:%d", verboseFlag); 1090 bb_error_msg("tar_handle->tar__to_command:'%s'", tar_handle->tar__to_command); 1091 bb_error_msg("tar_handle->tar__strip_components:%u", tar_handle->tar__strip_components); 1092 return 0; 1093 # undef showopt 1094 #endif 951 1095 argv += optind; 952 1096 953 if (verboseFlag) tar_handle->action_header = header_verbose_list; 954 if (verboseFlag == 1) tar_handle->action_header = header_list; 1097 if (verboseFlag) 1098 tar_handle->action_header = header_verbose_list; 1099 if (verboseFlag == 1) 1100 tar_handle->action_header = header_list; 955 1101 956 1102 if (opt & OPT_EXTRACT) … … 1038 1184 && !(opt & OPT_ANY_COMPRESS) 1039 1185 ) { 1040 tar_handle->src_fd = open_zipped(tar_filename );1186 tar_handle->src_fd = open_zipped(tar_filename, /*fail_if_not_compressed:*/ 0); 1041 1187 if (tar_handle->src_fd < 0) 1042 1188 bb_perror_msg_and_die("can't open '%s'", tar_filename); … … 1050 1196 xchdir(base_dir); 1051 1197 1052 //if (SEAMLESS_COMPRESSION || OPT_COMPRESS)1198 //if (SEAMLESS_COMPRESSION) 1053 1199 // /* We need to know whether child (gzip/bzip/etc) exits abnormally */ 1054 1200 // signal(SIGCHLD, check_errors_in_children); 1055 1201 1202 #if ENABLE_FEATURE_TAR_CREATE 1056 1203 /* Create an archive */ 1057 1204 if (opt & OPT_CREATE) { 1058 #if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 1059 int zipMode = 0; 1060 if (ENABLE_FEATURE_SEAMLESS_GZ && (opt & OPT_GZIP)) 1061 zipMode = 1; 1062 if (ENABLE_FEATURE_SEAMLESS_BZ2 && (opt & OPT_BZIP2)) 1063 zipMode = 2; 1064 #endif 1205 # if SEAMLESS_COMPRESSION 1206 const char *zipMode = NULL; 1207 if (opt & OPT_COMPRESS) 1208 zipMode = "compress"; 1209 if (opt & OPT_GZIP) 1210 zipMode = "gzip"; 1211 if (opt & OPT_BZIP2) 1212 zipMode = "bzip2"; 1213 if (opt & OPT_LZMA) 1214 zipMode = "lzma"; 1215 if (opt & OPT_XZ) 1216 zipMode = "xz"; 1217 # endif 1065 1218 /* NB: writeTarFile() closes tar_handle->src_fd */ 1066 1219 return writeTarFile(tar_handle->src_fd, verboseFlag, … … 1070 1223 tar_handle->reject, zipMode); 1071 1224 } 1225 #endif 1072 1226 1073 1227 if (opt & OPT_ANY_COMPRESS) { 1074 USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_ aux_data_t *aux, int src_fd, int dst_fd);)1228 USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_state_t *xstate);) 1075 1229 USE_FOR_NOMMU(const char *xformer_prog;) 1076 1230 … … 1091 1245 USE_FOR_NOMMU(xformer_prog = "unxz";) 1092 1246 1093 open_transformer_with_sig(tar_handle->src_fd, xformer, xformer_prog);1247 fork_transformer_with_sig(tar_handle->src_fd, xformer, xformer_prog); 1094 1248 /* Can't lseek over pipes */ 1095 1249 tar_handle->seek = seek_by_read; … … 1097 1251 } 1098 1252 1253 /* Zero processed headers (== empty file) is not a valid tarball. 1254 * We (ab)use bb_got_signal as exitcode here, 1255 * because check_errors_in_children() uses _it_ as error indicator. 1256 */ 1257 bb_got_signal = EXIT_FAILURE; 1258 1099 1259 while (get_header_tar(tar_handle) == EXIT_SUCCESS) 1100 continue;1260 bb_got_signal = EXIT_SUCCESS; /* saw at least one header, good */ 1101 1261 1102 1262 /* Check that every file that should have been extracted was */ … … 1114 1274 1115 1275 if (SEAMLESS_COMPRESSION || OPT_COMPRESS) { 1276 /* Set bb_got_signal to 1 if a child died with !0 exitcode */ 1116 1277 check_errors_in_children(0); 1117 return bb_got_signal;1118 } 1119 return EXIT_SUCCESS;1278 } 1279 1280 return bb_got_signal; 1120 1281 }
Note:
See TracChangeset
for help on using the changeset viewer.