diff options
author | Ron Yorston <rmy@pobox.com> | 2015-10-31 17:13:47 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2015-10-31 17:13:47 +0000 |
commit | 4432dbba6559d3d88e18ecf2c33d9e5a39e82074 (patch) | |
tree | f6db886523a04e0b45926336223ff8c32761dc43 /archival | |
parent | bc09f29f78547856e2152dc47051aeed548f28e8 (diff) | |
parent | 6bd3fff51aa74e2ee2d87887b12182a3b09792ef (diff) | |
download | busybox-w32-4432dbba6559d3d88e18ecf2c33d9e5a39e82074.tar.gz busybox-w32-4432dbba6559d3d88e18ecf2c33d9e5a39e82074.tar.bz2 busybox-w32-4432dbba6559d3d88e18ecf2c33d9e5a39e82074.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'archival')
-rw-r--r-- | archival/Config.src | 2 | ||||
-rw-r--r-- | archival/ar.c | 16 | ||||
-rw-r--r-- | archival/bbunzip.c | 23 | ||||
-rw-r--r-- | archival/gzip.c | 1 | ||||
-rw-r--r-- | archival/libarchive/data_extract_all.c | 118 | ||||
-rw-r--r-- | archival/libarchive/decompress_gunzip.c | 36 | ||||
-rw-r--r-- | archival/libarchive/get_header_tar.c | 1 | ||||
-rw-r--r-- | archival/lzop.c | 14 | ||||
-rw-r--r-- | archival/tar.c | 89 |
9 files changed, 209 insertions, 91 deletions
diff --git a/archival/Config.src b/archival/Config.src index 76635ba78..a9afaea5b 100644 --- a/archival/Config.src +++ b/archival/Config.src | |||
@@ -31,7 +31,7 @@ config FEATURE_SEAMLESS_GZ | |||
31 | 31 | ||
32 | config FEATURE_SEAMLESS_Z | 32 | config FEATURE_SEAMLESS_Z |
33 | bool "tar, rpm, modprobe etc understand .Z data" | 33 | bool "tar, rpm, modprobe etc understand .Z data" |
34 | default n | 34 | default n # it is ancient |
35 | help | 35 | help |
36 | Make tar, rpm, modprobe etc understand .Z data. | 36 | Make tar, rpm, modprobe etc understand .Z data. |
37 | 37 | ||
diff --git a/archival/ar.c b/archival/ar.c index 89e6a1207..a850868f6 100644 --- a/archival/ar.c +++ b/archival/ar.c | |||
@@ -22,23 +22,13 @@ | |||
22 | //config: default n # needs to be improved to be able to replace binutils ar | 22 | //config: default n # needs to be improved to be able to replace binutils ar |
23 | //config: help | 23 | //config: help |
24 | //config: ar is an archival utility program used to create, modify, and | 24 | //config: ar is an archival utility program used to create, modify, and |
25 | //config: extract contents from archives. An archive is a single file holding | 25 | //config: extract contents from archives. In practice, it is used exclusively |
26 | //config: a collection of other files in a structure that makes it possible to | 26 | //config: for object module archives used by compilers. |
27 | //config: retrieve the original individual files (called archive members). | ||
28 | //config: The original files' contents, mode (permissions), timestamp, owner, | ||
29 | //config: and group are preserved in the archive, and can be restored on | ||
30 | //config: extraction. | ||
31 | //config: | 27 | //config: |
32 | //config: The stored filename is limited to 15 characters. (for more information | ||
33 | //config: see long filename support). | ||
34 | //config: ar has 60 bytes of overheads for every stored file. | ||
35 | //config: | ||
36 | //config: This implementation of ar can extract archives, it cannot create or | ||
37 | //config: modify them. | ||
38 | //config: On an x86 system, the ar applet adds about 1K. | 28 | //config: On an x86 system, the ar applet adds about 1K. |
39 | //config: | 29 | //config: |
40 | //config: Unless you have a specific application which requires ar, you should | 30 | //config: Unless you have a specific application which requires ar, you should |
41 | //config: probably say N here. | 31 | //config: probably say N here: most compilers come with their own ar utility. |
42 | //config: | 32 | //config: |
43 | //config:config FEATURE_AR_LONG_FILENAMES | 33 | //config:config FEATURE_AR_LONG_FILENAMES |
44 | //config: bool "Support for long filenames (not needed for debs)" | 34 | //config: bool "Support for long filenames (not needed for debs)" |
diff --git a/archival/bbunzip.c b/archival/bbunzip.c index a859ef201..aaaf67e03 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c | |||
@@ -222,7 +222,7 @@ char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext) | |||
222 | 222 | ||
223 | //config:config UNCOMPRESS | 223 | //config:config UNCOMPRESS |
224 | //config: bool "uncompress" | 224 | //config: bool "uncompress" |
225 | //config: default n | 225 | //config: default n # ancient |
226 | //config: help | 226 | //config: help |
227 | //config: uncompress is used to decompress archives created by compress. | 227 | //config: uncompress is used to decompress archives created by compress. |
228 | //config: Not much used anymore, replaced by gzip/gunzip. | 228 | //config: Not much used anymore, replaced by gzip/gunzip. |
@@ -292,6 +292,13 @@ int uncompress_main(int argc UNUSED_PARAM, char **argv) | |||
292 | //config: gunzip is used to decompress archives created by gzip. | 292 | //config: gunzip is used to decompress archives created by gzip. |
293 | //config: You can use the `-t' option to test the integrity of | 293 | //config: You can use the `-t' option to test the integrity of |
294 | //config: an archive, without decompressing it. | 294 | //config: an archive, without decompressing it. |
295 | //config: | ||
296 | //config:config FEATURE_GUNZIP_LONG_OPTIONS | ||
297 | //config: bool "Enable long options" | ||
298 | //config: default y | ||
299 | //config: depends on GUNZIP && LONG_OPTS | ||
300 | //config: help | ||
301 | //config: Enable use of long options. | ||
295 | 302 | ||
296 | //applet:IF_GUNZIP(APPLET(gunzip, BB_DIR_BIN, BB_SUID_DROP)) | 303 | //applet:IF_GUNZIP(APPLET(gunzip, BB_DIR_BIN, BB_SUID_DROP)) |
297 | //applet:IF_GUNZIP(APPLET_ODDNAME(zcat, gunzip, BB_DIR_BIN, BB_SUID_DROP, zcat)) | 304 | //applet:IF_GUNZIP(APPLET_ODDNAME(zcat, gunzip, BB_DIR_BIN, BB_SUID_DROP, zcat)) |
@@ -323,6 +330,17 @@ char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UN | |||
323 | } | 330 | } |
324 | return filename; | 331 | return filename; |
325 | } | 332 | } |
333 | |||
334 | #if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS | ||
335 | static const char gunzip_longopts[] ALIGN1 = | ||
336 | "stdout\0" No_argument "c" | ||
337 | "to-stdout\0" No_argument "c" | ||
338 | "force\0" No_argument "f" | ||
339 | "test\0" No_argument "t" | ||
340 | "no-name\0" No_argument "n" | ||
341 | ; | ||
342 | #endif | ||
343 | |||
326 | /* | 344 | /* |
327 | * Linux kernel build uses gzip -d -n. We accept and ignore it. | 345 | * Linux kernel build uses gzip -d -n. We accept and ignore it. |
328 | * Man page says: | 346 | * Man page says: |
@@ -339,6 +357,9 @@ char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UN | |||
339 | int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 357 | int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
340 | int gunzip_main(int argc UNUSED_PARAM, char **argv) | 358 | int gunzip_main(int argc UNUSED_PARAM, char **argv) |
341 | { | 359 | { |
360 | #if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS | ||
361 | applet_long_options = gunzip_longopts; | ||
362 | #endif | ||
342 | getopt32(argv, "cfvqdtn"); | 363 | getopt32(argv, "cfvqdtn"); |
343 | argv += optind; | 364 | argv += optind; |
344 | 365 | ||
diff --git a/archival/gzip.c b/archival/gzip.c index c9171304a..f9bb3c742 100644 --- a/archival/gzip.c +++ b/archival/gzip.c | |||
@@ -2160,6 +2160,7 @@ static const char gzip_longopts[] ALIGN1 = | |||
2160 | "quiet\0" No_argument "q" | 2160 | "quiet\0" No_argument "q" |
2161 | "fast\0" No_argument "1" | 2161 | "fast\0" No_argument "1" |
2162 | "best\0" No_argument "9" | 2162 | "best\0" No_argument "9" |
2163 | "no-name\0" No_argument "n" | ||
2163 | ; | 2164 | ; |
2164 | #endif | 2165 | #endif |
2165 | 2166 | ||
diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c index 45776dcbe..bd034afdc 100644 --- a/archival/libarchive/data_extract_all.c +++ b/archival/libarchive/data_extract_all.c | |||
@@ -11,6 +11,12 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
11 | file_header_t *file_header = archive_handle->file_header; | 11 | file_header_t *file_header = archive_handle->file_header; |
12 | int dst_fd; | 12 | int dst_fd; |
13 | int res; | 13 | int res; |
14 | char *hard_link; | ||
15 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | ||
16 | char *dst_name; | ||
17 | #else | ||
18 | # define dst_name (file_header->name) | ||
19 | #endif | ||
14 | 20 | ||
15 | #if ENABLE_FEATURE_TAR_SELINUX | 21 | #if ENABLE_FEATURE_TAR_SELINUX |
16 | char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE]; | 22 | char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE]; |
@@ -23,11 +29,49 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
23 | } | 29 | } |
24 | #endif | 30 | #endif |
25 | 31 | ||
32 | /* Hard links are encoded as regular files of size 0 | ||
33 | * with a nonempty link field */ | ||
34 | hard_link = NULL; | ||
35 | if (S_ISREG(file_header->mode) && file_header->size == 0) | ||
36 | hard_link = file_header->link_target; | ||
37 | |||
38 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | ||
39 | dst_name = file_header->name; | ||
40 | if (archive_handle->tar__strip_components) { | ||
41 | unsigned n = archive_handle->tar__strip_components; | ||
42 | do { | ||
43 | dst_name = strchr(dst_name, '/'); | ||
44 | if (!dst_name || dst_name[1] == '\0') { | ||
45 | data_skip(archive_handle); | ||
46 | goto ret; | ||
47 | } | ||
48 | dst_name++; | ||
49 | /* | ||
50 | * Link target is shortened only for hardlinks: | ||
51 | * softlinks restored unchanged. | ||
52 | */ | ||
53 | if (hard_link) { | ||
54 | // GNU tar 1.26 does not check that we reached end of link name: | ||
55 | // if "dir/hardlink" is hardlinked to "file", | ||
56 | // tar xvf a.tar --strip-components=1 says: | ||
57 | // tar: hardlink: Cannot hard link to '': No such file or directory | ||
58 | // and continues processing. We silently skip such entries. | ||
59 | hard_link = strchr(hard_link, '/'); | ||
60 | if (!hard_link || hard_link[1] == '\0') { | ||
61 | data_skip(archive_handle); | ||
62 | goto ret; | ||
63 | } | ||
64 | hard_link++; | ||
65 | } | ||
66 | } while (--n != 0); | ||
67 | } | ||
68 | #endif | ||
69 | |||
26 | if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) { | 70 | if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) { |
27 | char *slash = strrchr(file_header->name, '/'); | 71 | char *slash = strrchr(dst_name, '/'); |
28 | if (slash) { | 72 | if (slash) { |
29 | *slash = '\0'; | 73 | *slash = '\0'; |
30 | bb_make_directory(file_header->name, -1, FILEUTILS_RECUR); | 74 | bb_make_directory(dst_name, -1, FILEUTILS_RECUR); |
31 | *slash = '/'; | 75 | *slash = '/'; |
32 | } | 76 | } |
33 | } | 77 | } |
@@ -35,12 +79,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
35 | if (archive_handle->ah_flags & ARCHIVE_UNLINK_OLD) { | 79 | if (archive_handle->ah_flags & ARCHIVE_UNLINK_OLD) { |
36 | /* Remove the entry if it exists */ | 80 | /* Remove the entry if it exists */ |
37 | if (!S_ISDIR(file_header->mode)) { | 81 | if (!S_ISDIR(file_header->mode)) { |
38 | /* Is it hardlink? | 82 | if (hard_link) { |
39 | * We encode hard links as regular files of size 0 with a symlink */ | ||
40 | if (S_ISREG(file_header->mode) | ||
41 | && file_header->link_target | ||
42 | && file_header->size == 0 | ||
43 | ) { | ||
44 | /* Ugly special case: | 83 | /* Ugly special case: |
45 | * tar cf t.tar hardlink1 hardlink2 hardlink1 | 84 | * tar cf t.tar hardlink1 hardlink2 hardlink1 |
46 | * results in this tarball structure: | 85 | * results in this tarball structure: |
@@ -48,22 +87,22 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
48 | * hardlink2 -> hardlink1 | 87 | * hardlink2 -> hardlink1 |
49 | * hardlink1 -> hardlink1 <== !!! | 88 | * hardlink1 -> hardlink1 <== !!! |
50 | */ | 89 | */ |
51 | if (strcmp(file_header->link_target, file_header->name) == 0) | 90 | if (strcmp(hard_link, dst_name) == 0) |
52 | goto ret; | 91 | goto ret; |
53 | } | 92 | } |
54 | /* Proceed with deleting */ | 93 | /* Proceed with deleting */ |
55 | if (unlink(file_header->name) == -1 | 94 | if (unlink(dst_name) == -1 |
56 | && errno != ENOENT | 95 | && errno != ENOENT |
57 | ) { | 96 | ) { |
58 | bb_perror_msg_and_die("can't remove old file %s", | 97 | bb_perror_msg_and_die("can't remove old file %s", |
59 | file_header->name); | 98 | dst_name); |
60 | } | 99 | } |
61 | } | 100 | } |
62 | } | 101 | } |
63 | else if (archive_handle->ah_flags & ARCHIVE_EXTRACT_NEWER) { | 102 | else if (archive_handle->ah_flags & ARCHIVE_EXTRACT_NEWER) { |
64 | /* Remove the existing entry if its older than the extracted entry */ | 103 | /* Remove the existing entry if its older than the extracted entry */ |
65 | struct stat existing_sb; | 104 | struct stat existing_sb; |
66 | if (lstat(file_header->name, &existing_sb) == -1) { | 105 | if (lstat(dst_name, &existing_sb) == -1) { |
67 | if (errno != ENOENT) { | 106 | if (errno != ENOENT) { |
68 | bb_perror_msg_and_die("can't stat old file"); | 107 | bb_perror_msg_and_die("can't stat old file"); |
69 | } | 108 | } |
@@ -73,30 +112,25 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
73 | && !S_ISDIR(file_header->mode) | 112 | && !S_ISDIR(file_header->mode) |
74 | ) { | 113 | ) { |
75 | bb_error_msg("%s not created: newer or " | 114 | bb_error_msg("%s not created: newer or " |
76 | "same age file exists", file_header->name); | 115 | "same age file exists", dst_name); |
77 | } | 116 | } |
78 | data_skip(archive_handle); | 117 | data_skip(archive_handle); |
79 | goto ret; | 118 | goto ret; |
80 | } | 119 | } |
81 | else if ((unlink(file_header->name) == -1) && (errno != EISDIR)) { | 120 | else if ((unlink(dst_name) == -1) && (errno != EISDIR)) { |
82 | bb_perror_msg_and_die("can't remove old file %s", | 121 | bb_perror_msg_and_die("can't remove old file %s", |
83 | file_header->name); | 122 | dst_name); |
84 | } | 123 | } |
85 | } | 124 | } |
86 | 125 | ||
87 | /* Handle hard links separately | 126 | /* Handle hard links separately */ |
88 | * We encode hard links as regular files of size 0 with a symlink */ | 127 | if (hard_link) { |
89 | if (S_ISREG(file_header->mode) | 128 | res = link(hard_link, dst_name); |
90 | && file_header->link_target | 129 | if (res != 0 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) { |
91 | && file_header->size == 0 | ||
92 | ) { | ||
93 | /* hard link */ | ||
94 | res = link(file_header->link_target, file_header->name); | ||
95 | if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) { | ||
96 | bb_perror_msg("can't create %slink " | 130 | bb_perror_msg("can't create %slink " |
97 | "from %s to %s", "hard", | 131 | "from %s to %s", "hard", |
98 | file_header->name, | 132 | dst_name, |
99 | file_header->link_target); | 133 | hard_link); |
100 | } | 134 | } |
101 | /* Hardlinks have no separate mode/ownership, skip chown/chmod */ | 135 | /* Hardlinks have no separate mode/ownership, skip chown/chmod */ |
102 | goto ret; | 136 | goto ret; |
@@ -106,17 +140,17 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
106 | switch (file_header->mode & S_IFMT) { | 140 | switch (file_header->mode & S_IFMT) { |
107 | case S_IFREG: { | 141 | case S_IFREG: { |
108 | /* Regular file */ | 142 | /* Regular file */ |
109 | char *dst_name; | 143 | char *dst_nameN; |
110 | int flags = O_WRONLY | O_CREAT | O_EXCL; | 144 | int flags = O_WRONLY | O_CREAT | O_EXCL; |
111 | if (archive_handle->ah_flags & ARCHIVE_O_TRUNC) | 145 | if (archive_handle->ah_flags & ARCHIVE_O_TRUNC) |
112 | flags = O_WRONLY | O_CREAT | O_TRUNC; | 146 | flags = O_WRONLY | O_CREAT | O_TRUNC; |
113 | dst_name = file_header->name; | 147 | dst_nameN = dst_name; |
114 | #ifdef ARCHIVE_REPLACE_VIA_RENAME | 148 | #ifdef ARCHIVE_REPLACE_VIA_RENAME |
115 | if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) | 149 | if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) |
116 | /* rpm-style temp file name */ | 150 | /* rpm-style temp file name */ |
117 | dst_name = xasprintf("%s;%x", dst_name, (int)getpid()); | 151 | dst_nameN = xasprintf("%s;%x", dst_name, (int)getpid()); |
118 | #endif | 152 | #endif |
119 | dst_fd = xopen3(dst_name, | 153 | dst_fd = xopen3(dst_nameN, |
120 | flags, | 154 | flags, |
121 | file_header->mode | 155 | file_header->mode |
122 | ); | 156 | ); |
@@ -124,32 +158,32 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
124 | close(dst_fd); | 158 | close(dst_fd); |
125 | #ifdef ARCHIVE_REPLACE_VIA_RENAME | 159 | #ifdef ARCHIVE_REPLACE_VIA_RENAME |
126 | if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) { | 160 | if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) { |
127 | xrename(dst_name, file_header->name); | 161 | xrename(dst_nameN, dst_name); |
128 | free(dst_name); | 162 | free(dst_nameN); |
129 | } | 163 | } |
130 | #endif | 164 | #endif |
131 | break; | 165 | break; |
132 | } | 166 | } |
133 | case S_IFDIR: | 167 | case S_IFDIR: |
134 | res = mkdir(file_header->name, file_header->mode); | 168 | res = mkdir(dst_name, file_header->mode); |
135 | if ((res == -1) | 169 | if ((res == -1) |
136 | && (errno != EISDIR) /* btw, Linux doesn't return this */ | 170 | && (errno != EISDIR) /* btw, Linux doesn't return this */ |
137 | && (errno != EEXIST) | 171 | && (errno != EEXIST) |
138 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) | 172 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) |
139 | ) { | 173 | ) { |
140 | bb_perror_msg("can't make dir %s", file_header->name); | 174 | bb_perror_msg("can't make dir %s", dst_name); |
141 | } | 175 | } |
142 | break; | 176 | break; |
143 | case S_IFLNK: | 177 | case S_IFLNK: |
144 | /* Symlink */ | 178 | /* Symlink */ |
145 | //TODO: what if file_header->link_target == NULL (say, corrupted tarball?) | 179 | //TODO: what if file_header->link_target == NULL (say, corrupted tarball?) |
146 | res = symlink(file_header->link_target, file_header->name); | 180 | res = symlink(file_header->link_target, dst_name); |
147 | if ((res == -1) | 181 | if (res != 0 |
148 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) | 182 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) |
149 | ) { | 183 | ) { |
150 | bb_perror_msg("can't create %slink " | 184 | bb_perror_msg("can't create %slink " |
151 | "from %s to %s", "sym", | 185 | "from %s to %s", "sym", |
152 | file_header->name, | 186 | dst_name, |
153 | file_header->link_target); | 187 | file_header->link_target); |
154 | } | 188 | } |
155 | break; | 189 | break; |
@@ -157,11 +191,11 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
157 | case S_IFBLK: | 191 | case S_IFBLK: |
158 | case S_IFCHR: | 192 | case S_IFCHR: |
159 | case S_IFIFO: | 193 | case S_IFIFO: |
160 | res = mknod(file_header->name, file_header->mode, file_header->device); | 194 | res = mknod(dst_name, file_header->mode, file_header->device); |
161 | if ((res == -1) | 195 | if ((res == -1) |
162 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) | 196 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) |
163 | ) { | 197 | ) { |
164 | bb_perror_msg("can't create node %s", file_header->name); | 198 | bb_perror_msg("can't create node %s", dst_name); |
165 | } | 199 | } |
166 | break; | 200 | break; |
167 | default: | 201 | default: |
@@ -186,20 +220,20 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
186 | } | 220 | } |
187 | #endif | 221 | #endif |
188 | /* GNU tar 1.15.1 uses chown, not lchown */ | 222 | /* GNU tar 1.15.1 uses chown, not lchown */ |
189 | chown(file_header->name, uid, gid); | 223 | chown(dst_name, uid, gid); |
190 | } | 224 | } |
191 | /* uclibc has no lchmod, glibc is even stranger - | 225 | /* uclibc has no lchmod, glibc is even stranger - |
192 | * it has lchmod which seems to do nothing! | 226 | * it has lchmod which seems to do nothing! |
193 | * so we use chmod... */ | 227 | * so we use chmod... */ |
194 | if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_PERM)) { | 228 | if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_PERM)) { |
195 | chmod(file_header->name, file_header->mode); | 229 | chmod(dst_name, file_header->mode); |
196 | } | 230 | } |
197 | if (archive_handle->ah_flags & ARCHIVE_RESTORE_DATE) { | 231 | if (archive_handle->ah_flags & ARCHIVE_RESTORE_DATE) { |
198 | struct timeval t[2]; | 232 | struct timeval t[2]; |
199 | 233 | ||
200 | t[1].tv_sec = t[0].tv_sec = file_header->mtime; | 234 | t[1].tv_sec = t[0].tv_sec = file_header->mtime; |
201 | t[1].tv_usec = t[0].tv_usec = 0; | 235 | t[1].tv_usec = t[0].tv_usec = 0; |
202 | utimes(file_header->name, t); | 236 | utimes(dst_name, t); |
203 | } | 237 | } |
204 | } | 238 | } |
205 | 239 | ||
diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c index b6ae7f738..eb64645ae 100644 --- a/archival/libarchive/decompress_gunzip.c +++ b/archival/libarchive/decompress_gunzip.c | |||
@@ -308,11 +308,11 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
308 | unsigned i; /* counter, current code */ | 308 | unsigned i; /* counter, current code */ |
309 | unsigned j; /* counter */ | 309 | unsigned j; /* counter */ |
310 | int k; /* number of bits in current code */ | 310 | int k; /* number of bits in current code */ |
311 | unsigned *p; /* pointer into c[], b[], or v[] */ | 311 | const unsigned *p; /* pointer into c[], b[], or v[] */ |
312 | huft_t *q; /* points to current table */ | 312 | huft_t *q; /* points to current table */ |
313 | huft_t r; /* table entry for structure assignment */ | 313 | huft_t r; /* table entry for structure assignment */ |
314 | huft_t *u[BMAX]; /* table stack */ | 314 | huft_t *u[BMAX]; /* table stack */ |
315 | unsigned v[N_MAX]; /* values in order of bit length */ | 315 | unsigned v[N_MAX + 1]; /* values in order of bit length. last v[] is never used */ |
316 | int ws[BMAX + 1]; /* bits decoded stack */ | 316 | int ws[BMAX + 1]; /* bits decoded stack */ |
317 | int w; /* bits decoded */ | 317 | int w; /* bits decoded */ |
318 | unsigned x[BMAX + 1]; /* bit offsets, then code stack */ | 318 | unsigned x[BMAX + 1]; /* bit offsets, then code stack */ |
@@ -327,7 +327,7 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
327 | 327 | ||
328 | /* Generate counts for each bit length */ | 328 | /* Generate counts for each bit length */ |
329 | memset(c, 0, sizeof(c)); | 329 | memset(c, 0, sizeof(c)); |
330 | p = (unsigned *) b; /* cast allows us to reuse p for pointing to b */ | 330 | p = b; |
331 | i = n; | 331 | i = n; |
332 | do { | 332 | do { |
333 | c[*p]++; /* assume all entries <= BMAX */ | 333 | c[*p]++; /* assume all entries <= BMAX */ |
@@ -367,8 +367,12 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
367 | *xp++ = j; | 367 | *xp++ = j; |
368 | } | 368 | } |
369 | 369 | ||
370 | /* Make a table of values in order of bit lengths */ | 370 | /* Make a table of values in order of bit lengths. |
371 | p = (unsigned *) b; | 371 | * To detect bad input, unused v[i]'s are set to invalid value UINT_MAX. |
372 | * In particular, last v[i] is never filled and must not be accessed. | ||
373 | */ | ||
374 | memset(v, 0xff, sizeof(v)); | ||
375 | p = b; | ||
372 | i = 0; | 376 | i = 0; |
373 | do { | 377 | do { |
374 | j = *p++; | 378 | j = *p++; |
@@ -435,7 +439,9 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
435 | 439 | ||
436 | /* set up table entry in r */ | 440 | /* set up table entry in r */ |
437 | r.b = (unsigned char) (k - w); | 441 | r.b = (unsigned char) (k - w); |
438 | if (p >= v + n) { | 442 | if (/*p >= v + n || -- redundant, caught by the second check: */ |
443 | *p == UINT_MAX /* do we access uninited v[i]? (see memset(v))*/ | ||
444 | ) { | ||
439 | r.e = 99; /* out of values--invalid code */ | 445 | r.e = 99; /* out of values--invalid code */ |
440 | } else if (*p < s) { | 446 | } else if (*p < s) { |
441 | r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is EOB code */ | 447 | r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is EOB code */ |
@@ -520,8 +526,9 @@ static NOINLINE int inflate_codes(STATE_PARAM_ONLY) | |||
520 | e = t->e; | 526 | e = t->e; |
521 | if (e > 16) | 527 | if (e > 16) |
522 | do { | 528 | do { |
523 | if (e == 99) | 529 | if (e == 99) { |
524 | abort_unzip(PASS_STATE_ONLY);; | 530 | abort_unzip(PASS_STATE_ONLY); |
531 | } | ||
525 | bb >>= t->b; | 532 | bb >>= t->b; |
526 | k -= t->b; | 533 | k -= t->b; |
527 | e -= 16; | 534 | e -= 16; |
@@ -557,8 +564,9 @@ static NOINLINE int inflate_codes(STATE_PARAM_ONLY) | |||
557 | e = t->e; | 564 | e = t->e; |
558 | if (e > 16) | 565 | if (e > 16) |
559 | do { | 566 | do { |
560 | if (e == 99) | 567 | if (e == 99) { |
561 | abort_unzip(PASS_STATE_ONLY); | 568 | abort_unzip(PASS_STATE_ONLY); |
569 | } | ||
562 | bb >>= t->b; | 570 | bb >>= t->b; |
563 | k -= t->b; | 571 | k -= t->b; |
564 | e -= 16; | 572 | e -= 16; |
@@ -824,8 +832,9 @@ static int inflate_block(STATE_PARAM smallint *e) | |||
824 | 832 | ||
825 | b_dynamic >>= 4; | 833 | b_dynamic >>= 4; |
826 | k_dynamic -= 4; | 834 | k_dynamic -= 4; |
827 | if (nl > 286 || nd > 30) | 835 | if (nl > 286 || nd > 30) { |
828 | abort_unzip(PASS_STATE_ONLY); /* bad lengths */ | 836 | abort_unzip(PASS_STATE_ONLY); /* bad lengths */ |
837 | } | ||
829 | 838 | ||
830 | /* read in bit-length-code lengths */ | 839 | /* read in bit-length-code lengths */ |
831 | for (j = 0; j < nb; j++) { | 840 | for (j = 0; j < nb; j++) { |
@@ -906,12 +915,14 @@ static int inflate_block(STATE_PARAM smallint *e) | |||
906 | bl = lbits; | 915 | bl = lbits; |
907 | 916 | ||
908 | i = huft_build(ll, nl, 257, cplens, cplext, &inflate_codes_tl, &bl); | 917 | i = huft_build(ll, nl, 257, cplens, cplext, &inflate_codes_tl, &bl); |
909 | if (i != 0) | 918 | if (i != 0) { |
910 | abort_unzip(PASS_STATE_ONLY); | 919 | abort_unzip(PASS_STATE_ONLY); |
920 | } | ||
911 | bd = dbits; | 921 | bd = dbits; |
912 | i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &inflate_codes_td, &bd); | 922 | i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &inflate_codes_td, &bd); |
913 | if (i != 0) | 923 | if (i != 0) { |
914 | abort_unzip(PASS_STATE_ONLY); | 924 | abort_unzip(PASS_STATE_ONLY); |
925 | } | ||
915 | 926 | ||
916 | /* set up data for inflate_codes() */ | 927 | /* set up data for inflate_codes() */ |
917 | inflate_codes_setup(PASS_STATE bl, bd); | 928 | inflate_codes_setup(PASS_STATE bl, bd); |
@@ -999,6 +1010,7 @@ inflate_unzip_internal(STATE_PARAM transformer_state_t *xstate) | |||
999 | error_msg = "corrupted data"; | 1010 | error_msg = "corrupted data"; |
1000 | if (setjmp(error_jmp)) { | 1011 | if (setjmp(error_jmp)) { |
1001 | /* Error from deep inside zip machinery */ | 1012 | /* Error from deep inside zip machinery */ |
1013 | bb_error_msg(error_msg); | ||
1002 | n = -1; | 1014 | n = -1; |
1003 | goto ret; | 1015 | goto ret; |
1004 | } | 1016 | } |
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index fb68673b9..ac2be726f 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c | |||
@@ -418,6 +418,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
418 | 418 | ||
419 | /* Everything up to and including last ".." component is stripped */ | 419 | /* Everything up to and including last ".." component is stripped */ |
420 | overlapping_strcpy(file_header->name, strip_unsafe_prefix(file_header->name)); | 420 | overlapping_strcpy(file_header->name, strip_unsafe_prefix(file_header->name)); |
421 | //TODO: do the same for file_header->link_target? | ||
421 | 422 | ||
422 | /* Strip trailing '/' in directories */ | 423 | /* Strip trailing '/' in directories */ |
423 | /* Must be done after mode is set as '/' is used to check if it's a directory */ | 424 | /* Must be done after mode is set as '/' is used to check if it's a directory */ |
diff --git a/archival/lzop.c b/archival/lzop.c index 73d11a705..a5fc01941 100644 --- a/archival/lzop.c +++ b/archival/lzop.c | |||
@@ -640,7 +640,7 @@ static int lzo_get_method(header_t *h) | |||
640 | /**********************************************************************/ | 640 | /**********************************************************************/ |
641 | // compress a file | 641 | // compress a file |
642 | /**********************************************************************/ | 642 | /**********************************************************************/ |
643 | static NOINLINE smallint lzo_compress(const header_t *h) | 643 | static NOINLINE int lzo_compress(const header_t *h) |
644 | { | 644 | { |
645 | unsigned block_size = LZO_BLOCK_SIZE; | 645 | unsigned block_size = LZO_BLOCK_SIZE; |
646 | int r = 0; /* LZO_E_OK */ | 646 | int r = 0; /* LZO_E_OK */ |
@@ -650,7 +650,6 @@ static NOINLINE smallint lzo_compress(const header_t *h) | |||
650 | uint32_t d_adler32 = ADLER32_INIT_VALUE; | 650 | uint32_t d_adler32 = ADLER32_INIT_VALUE; |
651 | uint32_t d_crc32 = CRC32_INIT_VALUE; | 651 | uint32_t d_crc32 = CRC32_INIT_VALUE; |
652 | int l; | 652 | int l; |
653 | smallint ok = 1; | ||
654 | uint8_t *wrk_mem = NULL; | 653 | uint8_t *wrk_mem = NULL; |
655 | 654 | ||
656 | if (h->method == M_LZO1X_1) | 655 | if (h->method == M_LZO1X_1) |
@@ -732,7 +731,7 @@ static NOINLINE smallint lzo_compress(const header_t *h) | |||
732 | free(wrk_mem); | 731 | free(wrk_mem); |
733 | free(b1); | 732 | free(b1); |
734 | free(b2); | 733 | free(b2); |
735 | return ok; | 734 | return 1; |
736 | } | 735 | } |
737 | 736 | ||
738 | static FAST_FUNC void lzo_check( | 737 | static FAST_FUNC void lzo_check( |
@@ -753,7 +752,7 @@ static FAST_FUNC void lzo_check( | |||
753 | /**********************************************************************/ | 752 | /**********************************************************************/ |
754 | // decompress a file | 753 | // decompress a file |
755 | /**********************************************************************/ | 754 | /**********************************************************************/ |
756 | static NOINLINE smallint lzo_decompress(const header_t *h) | 755 | static NOINLINE int lzo_decompress(const header_t *h) |
757 | { | 756 | { |
758 | unsigned block_size = LZO_BLOCK_SIZE; | 757 | unsigned block_size = LZO_BLOCK_SIZE; |
759 | int r; | 758 | int r; |
@@ -761,7 +760,6 @@ static NOINLINE smallint lzo_decompress(const header_t *h) | |||
761 | uint32_t c_adler32 = ADLER32_INIT_VALUE; | 760 | uint32_t c_adler32 = ADLER32_INIT_VALUE; |
762 | uint32_t d_adler32 = ADLER32_INIT_VALUE; | 761 | uint32_t d_adler32 = ADLER32_INIT_VALUE; |
763 | uint32_t c_crc32 = CRC32_INIT_VALUE, d_crc32 = CRC32_INIT_VALUE; | 762 | uint32_t c_crc32 = CRC32_INIT_VALUE, d_crc32 = CRC32_INIT_VALUE; |
764 | smallint ok = 1; | ||
765 | uint8_t *b1; | 763 | uint8_t *b1; |
766 | uint32_t mcs_block_size = MAX_COMPRESSED_SIZE(block_size); | 764 | uint32_t mcs_block_size = MAX_COMPRESSED_SIZE(block_size); |
767 | uint8_t *b2 = NULL; | 765 | uint8_t *b2 = NULL; |
@@ -865,7 +863,7 @@ static NOINLINE smallint lzo_decompress(const header_t *h) | |||
865 | } | 863 | } |
866 | 864 | ||
867 | free(b2); | 865 | free(b2); |
868 | return ok; | 866 | return 1; |
869 | } | 867 | } |
870 | 868 | ||
871 | /**********************************************************************/ | 869 | /**********************************************************************/ |
@@ -1050,7 +1048,7 @@ static void lzo_set_method(header_t *h) | |||
1050 | h->level = level; | 1048 | h->level = level; |
1051 | } | 1049 | } |
1052 | 1050 | ||
1053 | static smallint do_lzo_compress(void) | 1051 | static int do_lzo_compress(void) |
1054 | { | 1052 | { |
1055 | header_t header; | 1053 | header_t header; |
1056 | 1054 | ||
@@ -1078,7 +1076,7 @@ static smallint do_lzo_compress(void) | |||
1078 | /**********************************************************************/ | 1076 | /**********************************************************************/ |
1079 | // decompress | 1077 | // decompress |
1080 | /**********************************************************************/ | 1078 | /**********************************************************************/ |
1081 | static smallint do_lzo_decompress(void) | 1079 | static int do_lzo_decompress(void) |
1082 | { | 1080 | { |
1083 | header_t header; | 1081 | header_t header; |
1084 | 1082 | ||
diff --git a/archival/tar.c b/archival/tar.c index 0dd675f64..adb0b934f 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -152,9 +152,12 @@ | |||
152 | # define FNM_LEADING_DIR 0 | 152 | # define FNM_LEADING_DIR 0 |
153 | #endif | 153 | #endif |
154 | 154 | ||
155 | 155 | #if 0 | |
156 | //#define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__) | 156 | # define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__) |
157 | #define DBG(...) ((void)0) | 157 | #else |
158 | # define DBG(...) ((void)0) | ||
159 | #endif | ||
160 | #define DBG_OPTION_PARSING 0 | ||
158 | 161 | ||
159 | 162 | ||
160 | #define block_buf bb_common_bufsiz1 | 163 | #define block_buf bb_common_bufsiz1 |
@@ -884,6 +887,7 @@ enum { | |||
884 | IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) | 887 | IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) |
885 | IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) | 888 | IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) |
886 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | 889 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS |
890 | OPTBIT_STRIP_COMPONENTS, | ||
887 | OPTBIT_NORECURSION, | 891 | OPTBIT_NORECURSION, |
888 | IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,) | 892 | IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,) |
889 | OPTBIT_NUMERIC_OWNER, | 893 | OPTBIT_NUMERIC_OWNER, |
@@ -908,12 +912,13 @@ enum { | |||
908 | OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z | 912 | OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z |
909 | OPT_XZ = IF_FEATURE_SEAMLESS_XZ( (1 << OPTBIT_XZ )) + 0, // J | 913 | OPT_XZ = IF_FEATURE_SEAMLESS_XZ( (1 << OPTBIT_XZ )) + 0, // J |
910 | OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z | 914 | OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z |
911 | OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m | 915 | OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m |
912 | OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion | 916 | OPT_STRIP_COMPONENTS = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_STRIP_COMPONENTS)) + 0, // strip-components |
913 | OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command | 917 | OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion |
914 | OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner | 918 | OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command |
915 | OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions | 919 | OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner |
916 | OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite | 920 | OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions |
921 | OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite | ||
917 | 922 | ||
918 | OPT_ANY_COMPRESS = (OPT_BZIP2 | OPT_LZMA | OPT_GZIP | OPT_XZ | OPT_COMPRESS), | 923 | OPT_ANY_COMPRESS = (OPT_BZIP2 | OPT_LZMA | OPT_GZIP | OPT_XZ | OPT_COMPRESS), |
919 | }; | 924 | }; |
@@ -957,6 +962,7 @@ static const char tar_longopts[] ALIGN1 = | |||
957 | # if ENABLE_FEATURE_TAR_NOPRESERVE_TIME | 962 | # if ENABLE_FEATURE_TAR_NOPRESERVE_TIME |
958 | "touch\0" No_argument "m" | 963 | "touch\0" No_argument "m" |
959 | # endif | 964 | # endif |
965 | "strip-components\0" Required_argument "\xf9" | ||
960 | "no-recursion\0" No_argument "\xfa" | 966 | "no-recursion\0" No_argument "\xfa" |
961 | # if ENABLE_FEATURE_TAR_TO_COMMAND | 967 | # if ENABLE_FEATURE_TAR_TO_COMMAND |
962 | "to-command\0" Required_argument "\xfb" | 968 | "to-command\0" Required_argument "\xfb" |
@@ -1002,15 +1008,28 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1002 | "tt:vv:" // count -t,-v | 1008 | "tt:vv:" // count -t,-v |
1003 | IF_FEATURE_TAR_FROM("X::T::") // cumulative lists | 1009 | IF_FEATURE_TAR_FROM("X::T::") // cumulative lists |
1004 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM | 1010 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM |
1005 | "\xff::" // cumulative lists for --exclude | 1011 | "\xff::" // --exclude=PATTERN is a list |
1006 | #endif | 1012 | #endif |
1007 | IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd | 1013 | IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd |
1008 | IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive | 1014 | IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive |
1009 | IF_NOT_FEATURE_TAR_CREATE("t--x:x--t"); // mutually exclusive | 1015 | IF_NOT_FEATURE_TAR_CREATE("t--x:x--t") // mutually exclusive |
1016 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | ||
1017 | ":\xf9+" // --strip-components=NUM | ||
1018 | #endif | ||
1019 | ; | ||
1010 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | 1020 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS |
1011 | applet_long_options = tar_longopts; | 1021 | applet_long_options = tar_longopts; |
1012 | #endif | 1022 | #endif |
1013 | #if ENABLE_DESKTOP | 1023 | #if ENABLE_DESKTOP |
1024 | /* Lie to buildroot when it starts asking stupid questions. */ | ||
1025 | if (argv[1] && strcmp(argv[1], "--version") == 0) { | ||
1026 | // Output of 'tar --version' examples: | ||
1027 | // tar (GNU tar) 1.15.1 | ||
1028 | // tar (GNU tar) 1.25 | ||
1029 | // bsdtar 2.8.3 - libarchive 2.8.3 | ||
1030 | puts("tar (busybox) " BB_VER); | ||
1031 | return 0; | ||
1032 | } | ||
1014 | if (argv[1] && argv[1][0] != '-') { | 1033 | if (argv[1] && argv[1][0] != '-') { |
1015 | /* Compat: | 1034 | /* Compat: |
1016 | * 1st argument without dash handles options with parameters | 1035 | * 1st argument without dash handles options with parameters |
@@ -1047,10 +1066,14 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1047 | IF_FEATURE_SEAMLESS_XZ( "J" ) | 1066 | IF_FEATURE_SEAMLESS_XZ( "J" ) |
1048 | IF_FEATURE_SEAMLESS_Z( "Z" ) | 1067 | IF_FEATURE_SEAMLESS_Z( "Z" ) |
1049 | IF_FEATURE_TAR_NOPRESERVE_TIME("m") | 1068 | IF_FEATURE_TAR_NOPRESERVE_TIME("m") |
1069 | IF_FEATURE_TAR_LONG_OPTIONS("\xf9:") // --strip-components | ||
1050 | , &base_dir // -C dir | 1070 | , &base_dir // -C dir |
1051 | , &tar_filename // -f filename | 1071 | , &tar_filename // -f filename |
1052 | IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T | 1072 | IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T |
1053 | IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X | 1073 | IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X |
1074 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | ||
1075 | , &tar_handle->tar__strip_components // --strip-components | ||
1076 | #endif | ||
1054 | IF_FEATURE_TAR_TO_COMMAND(, &(tar_handle->tar__to_command)) // --to-command | 1077 | IF_FEATURE_TAR_TO_COMMAND(, &(tar_handle->tar__to_command)) // --to-command |
1055 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM | 1078 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM |
1056 | , &excludes // --exclude | 1079 | , &excludes // --exclude |
@@ -1058,11 +1081,49 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1058 | , &verboseFlag // combined count for -t and -v | 1081 | , &verboseFlag // combined count for -t and -v |
1059 | , &verboseFlag // combined count for -t and -v | 1082 | , &verboseFlag // combined count for -t and -v |
1060 | ); | 1083 | ); |
1061 | //bb_error_msg("opt:%08x", opt); | 1084 | #if DBG_OPTION_PARSING |
1085 | bb_error_msg("opt: 0x%08x", opt); | ||
1086 | # define showopt(o) bb_error_msg("opt & %s(%x): %x", #o, o, opt & o); | ||
1087 | showopt(OPT_TEST ); | ||
1088 | showopt(OPT_EXTRACT ); | ||
1089 | showopt(OPT_BASEDIR ); | ||
1090 | showopt(OPT_TARNAME ); | ||
1091 | showopt(OPT_2STDOUT ); | ||
1092 | showopt(OPT_NOPRESERVE_OWNER); | ||
1093 | showopt(OPT_P ); | ||
1094 | showopt(OPT_VERBOSE ); | ||
1095 | showopt(OPT_KEEP_OLD ); | ||
1096 | showopt(OPT_CREATE ); | ||
1097 | showopt(OPT_DEREFERENCE ); | ||
1098 | showopt(OPT_BZIP2 ); | ||
1099 | showopt(OPT_LZMA ); | ||
1100 | showopt(OPT_INCLUDE_FROM ); | ||
1101 | showopt(OPT_EXCLUDE_FROM ); | ||
1102 | showopt(OPT_GZIP ); | ||
1103 | showopt(OPT_XZ ); | ||
1104 | showopt(OPT_COMPRESS ); | ||
1105 | showopt(OPT_NOPRESERVE_TIME ); | ||
1106 | showopt(OPT_STRIP_COMPONENTS); | ||
1107 | showopt(OPT_NORECURSION ); | ||
1108 | showopt(OPT_2COMMAND ); | ||
1109 | showopt(OPT_NUMERIC_OWNER ); | ||
1110 | showopt(OPT_NOPRESERVE_PERM ); | ||
1111 | showopt(OPT_OVERWRITE ); | ||
1112 | showopt(OPT_ANY_COMPRESS ); | ||
1113 | bb_error_msg("base_dir:'%s'", base_dir); | ||
1114 | bb_error_msg("tar_filename:'%s'", tar_filename); | ||
1115 | bb_error_msg("verboseFlag:%d", verboseFlag); | ||
1116 | bb_error_msg("tar_handle->tar__to_command:'%s'", tar_handle->tar__to_command); | ||
1117 | bb_error_msg("tar_handle->tar__strip_components:%u", tar_handle->tar__strip_components); | ||
1118 | return 0; | ||
1119 | # undef showopt | ||
1120 | #endif | ||
1062 | argv += optind; | 1121 | argv += optind; |
1063 | 1122 | ||
1064 | if (verboseFlag) tar_handle->action_header = header_verbose_list; | 1123 | if (verboseFlag) |
1065 | if (verboseFlag == 1) tar_handle->action_header = header_list; | 1124 | tar_handle->action_header = header_verbose_list; |
1125 | if (verboseFlag == 1) | ||
1126 | tar_handle->action_header = header_list; | ||
1066 | 1127 | ||
1067 | if (opt & OPT_EXTRACT) | 1128 | if (opt & OPT_EXTRACT) |
1068 | tar_handle->action_data = data_extract_all; | 1129 | tar_handle->action_data = data_extract_all; |