diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-10 23:06:00 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-10 23:06:00 +0000 |
commit | 0381d422d9b40c0cf887d299224c7759875aefd8 (patch) | |
tree | 764583282951c07bb6b611bef2858c5375647094 /archival/libunarchive | |
parent | b6052724ffc9d45894147b70e7aff226938bd2d3 (diff) | |
download | busybox-w32-0381d422d9b40c0cf887d299224c7759875aefd8.tar.gz busybox-w32-0381d422d9b40c0cf887d299224c7759875aefd8.tar.bz2 busybox-w32-0381d422d9b40c0cf887d299224c7759875aefd8.zip |
dpkg_deb: slight code shrink
ar: reuse existing ar unpacking code
get_header_tar: handle autodetection for tiny .tar.gz files too
unarchive.h: do not include CONFIGed out things
function old new delta
get_header_tar 1521 1534 +13
dpkg_deb_main 400 380 -20
ar_main 260 196 -64
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/2 up/down: 13/-84) Total: -71 bytes
Diffstat (limited to 'archival/libunarchive')
-rw-r--r-- | archival/libunarchive/filter_accept_list_reassign.c | 20 | ||||
-rw-r--r-- | archival/libunarchive/get_header_ar.c | 5 | ||||
-rw-r--r-- | archival/libunarchive/get_header_tar.c | 27 | ||||
-rw-r--r-- | archival/libunarchive/get_header_tar_gz.c | 1 | ||||
-rw-r--r-- | archival/libunarchive/unpack_ar_archive.c | 3 |
5 files changed, 37 insertions, 19 deletions
diff --git a/archival/libunarchive/filter_accept_list_reassign.c b/archival/libunarchive/filter_accept_list_reassign.c index 4f2d4cde5..4dbc2d13e 100644 --- a/archival/libunarchive/filter_accept_list_reassign.c +++ b/archival/libunarchive/filter_accept_list_reassign.c | |||
@@ -8,6 +8,8 @@ | |||
8 | #include "libbb.h" | 8 | #include "libbb.h" |
9 | #include "unarchive.h" | 9 | #include "unarchive.h" |
10 | 10 | ||
11 | /* Built and used only if ENABLE_DPKG || ENABLE_DPKG_DEB */ | ||
12 | |||
11 | /* | 13 | /* |
12 | * Reassign the subarchive metadata parser based on the filename extension | 14 | * Reassign the subarchive metadata parser based on the filename extension |
13 | * e.g. if its a .tar.gz modify archive_handle->sub_archive to process a .tar.gz | 15 | * e.g. if its a .tar.gz modify archive_handle->sub_archive to process a .tar.gz |
@@ -19,23 +21,25 @@ char FAST_FUNC filter_accept_list_reassign(archive_handle_t *archive_handle) | |||
19 | if (find_list_entry(archive_handle->accept, archive_handle->file_header->name)) { | 21 | if (find_list_entry(archive_handle->accept, archive_handle->file_header->name)) { |
20 | const char *name_ptr; | 22 | const char *name_ptr; |
21 | 23 | ||
22 | /* Extract the last 2 extensions */ | 24 | /* Find extension */ |
23 | name_ptr = strrchr(archive_handle->file_header->name, '.'); | 25 | name_ptr = strrchr(archive_handle->file_header->name, '.'); |
24 | 26 | ||
25 | /* Modify the subarchive handler based on the extension */ | 27 | /* Modify the subarchive handler based on the extension */ |
26 | #if ENABLE_FEATURE_DEB_TAR_GZ | 28 | if (ENABLE_FEATURE_DEB_TAR_GZ |
27 | if (strcmp(name_ptr, ".gz") == 0) { | 29 | && strcmp(name_ptr, ".gz") == 0 |
30 | ) { | ||
28 | archive_handle->action_data_subarchive = get_header_tar_gz; | 31 | archive_handle->action_data_subarchive = get_header_tar_gz; |
29 | return EXIT_SUCCESS; | 32 | return EXIT_SUCCESS; |
30 | } | 33 | } |
31 | #endif | 34 | if (ENABLE_FEATURE_DEB_TAR_BZ2 |
32 | #if ENABLE_FEATURE_DEB_TAR_BZ2 | 35 | && strcmp(name_ptr, ".bz2") == 0 |
33 | if (strcmp(name_ptr, ".bz2") == 0) { | 36 | ) { |
34 | archive_handle->action_data_subarchive = get_header_tar_bz2; | 37 | archive_handle->action_data_subarchive = get_header_tar_bz2; |
35 | return EXIT_SUCCESS; | 38 | return EXIT_SUCCESS; |
36 | } | 39 | } |
37 | #endif | 40 | if (ENABLE_FEATURE_DEB_TAR_LZMA |
38 | if (ENABLE_FEATURE_DEB_TAR_LZMA && !strcmp(name_ptr, ".lzma")) { | 41 | && strcmp(name_ptr, ".lzma") == 0 |
42 | ) { | ||
39 | archive_handle->action_data_subarchive = get_header_tar_lzma; | 43 | archive_handle->action_data_subarchive = get_header_tar_lzma; |
40 | return EXIT_SUCCESS; | 44 | return EXIT_SUCCESS; |
41 | } | 45 | } |
diff --git a/archival/libunarchive/get_header_ar.c b/archival/libunarchive/get_header_ar.c index 59fd34c73..d476a9d24 100644 --- a/archival/libunarchive/get_header_ar.c +++ b/archival/libunarchive/get_header_ar.c | |||
@@ -108,12 +108,13 @@ char FAST_FUNC get_header_ar(archive_handle_t *archive_handle) | |||
108 | 108 | ||
109 | if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { | 109 | if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { |
110 | archive_handle->action_header(typed); | 110 | archive_handle->action_header(typed); |
111 | #if ENABLE_DPKG || ENABLE_DPKG_DEB | ||
111 | if (archive_handle->sub_archive) { | 112 | if (archive_handle->sub_archive) { |
112 | while (archive_handle->action_data_subarchive(archive_handle->sub_archive) == EXIT_SUCCESS) | 113 | while (archive_handle->action_data_subarchive(archive_handle->sub_archive) == EXIT_SUCCESS) |
113 | continue; | 114 | continue; |
114 | } else { | 115 | } else |
116 | #endif | ||
115 | archive_handle->action_data(archive_handle); | 117 | archive_handle->action_data(archive_handle); |
116 | } | ||
117 | } else { | 118 | } else { |
118 | data_skip(archive_handle); | 119 | data_skip(archive_handle); |
119 | } | 120 | } |
diff --git a/archival/libunarchive/get_header_tar.c b/archival/libunarchive/get_header_tar.c index 69362f1cc..cf35d41a0 100644 --- a/archival/libunarchive/get_header_tar.c +++ b/archival/libunarchive/get_header_tar.c | |||
@@ -92,22 +92,32 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
92 | again_after_align: | 92 | again_after_align: |
93 | 93 | ||
94 | #if ENABLE_DESKTOP | 94 | #if ENABLE_DESKTOP |
95 | /* to prevent misdetection of bz2 sig */ | ||
96 | *(uint32_t*)(&tar) = 0; | ||
95 | i = full_read(archive_handle->src_fd, &tar, 512); | 97 | i = full_read(archive_handle->src_fd, &tar, 512); |
96 | /* If GNU tar sees EOF in above read, it says: | 98 | /* If GNU tar sees EOF in above read, it says: |
97 | * "tar: A lone zero block at N", where N = kilobyte | 99 | * "tar: A lone zero block at N", where N = kilobyte |
98 | * where EOF was met (not EOF block, actual EOF!), | 100 | * where EOF was met (not EOF block, actual EOF!), |
99 | * and tar will exit with error code 0. | 101 | * and exits with EXIT_SUCCESS. |
100 | * We will mimic exit(EXIT_SUCCESS), although we will not mimic | 102 | * We will mimic exit(EXIT_SUCCESS), although we will not mimic |
101 | * the message and we don't check whether we indeed | 103 | * the message and we don't check whether we indeed |
102 | * saw zero block directly before this. */ | 104 | * saw zero block directly before this. */ |
103 | if (i == 0) | 105 | if (i == 0) { |
104 | xfunc_error_retval = 0; | 106 | xfunc_error_retval = 0; |
105 | if (i != 512) | 107 | short_read: |
106 | bb_error_msg_and_die("short read"); | 108 | bb_error_msg_and_die("short read"); |
109 | } | ||
110 | if (i != 512) { | ||
111 | if (ENABLE_FEATURE_TAR_AUTODETECT) | ||
112 | goto autodetect; | ||
113 | goto short_read; | ||
114 | } | ||
115 | |||
107 | #else | 116 | #else |
108 | xread(archive_handle->src_fd, &tar, 512); | 117 | i = 512; |
118 | xread(archive_handle->src_fd, &tar, i); | ||
109 | #endif | 119 | #endif |
110 | archive_handle->offset += 512; | 120 | archive_handle->offset += i; |
111 | 121 | ||
112 | /* If there is no filename its an empty header */ | 122 | /* If there is no filename its an empty header */ |
113 | if (tar.name[0] == 0 && tar.prefix[0] == 0) { | 123 | if (tar.name[0] == 0 && tar.prefix[0] == 0) { |
@@ -133,6 +143,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
133 | #if ENABLE_FEATURE_TAR_AUTODETECT | 143 | #if ENABLE_FEATURE_TAR_AUTODETECT |
134 | char FAST_FUNC (*get_header_ptr)(archive_handle_t *); | 144 | char FAST_FUNC (*get_header_ptr)(archive_handle_t *); |
135 | 145 | ||
146 | USE_DESKTOP(autodetect:) | ||
136 | /* tar gz/bz autodetect: check for gz/bz2 magic. | 147 | /* tar gz/bz autodetect: check for gz/bz2 magic. |
137 | * If we see the magic, and it is the very first block, | 148 | * If we see the magic, and it is the very first block, |
138 | * we can switch to get_header_tar_gz/bz2/lzma(). | 149 | * we can switch to get_header_tar_gz/bz2/lzma(). |
@@ -154,7 +165,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
154 | /* Two different causes for lseek() != 0: | 165 | /* Two different causes for lseek() != 0: |
155 | * unseekable fd (would like to support that too, but...), | 166 | * unseekable fd (would like to support that too, but...), |
156 | * or not first block (false positive, it's not .gz/.bz2!) */ | 167 | * or not first block (false positive, it's not .gz/.bz2!) */ |
157 | if (lseek(archive_handle->src_fd, -512, SEEK_CUR) != 0) | 168 | if (lseek(archive_handle->src_fd, -i, SEEK_CUR) != 0) |
158 | goto err; | 169 | goto err; |
159 | while (get_header_ptr(archive_handle) == EXIT_SUCCESS) | 170 | while (get_header_ptr(archive_handle) == EXIT_SUCCESS) |
160 | continue; | 171 | continue; |
@@ -328,7 +339,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
328 | p_linkname = NULL; | 339 | p_linkname = NULL; |
329 | } | 340 | } |
330 | #endif | 341 | #endif |
331 | if (!strncmp(file_header->name, "/../"+1, 3) | 342 | if (strncmp(file_header->name, "/../"+1, 3) == 0 |
332 | || strstr(file_header->name, "/../") | 343 | || strstr(file_header->name, "/../") |
333 | ) { | 344 | ) { |
334 | bb_error_msg_and_die("name with '..' encountered: '%s'", | 345 | bb_error_msg_and_die("name with '..' encountered: '%s'", |
@@ -340,7 +351,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
340 | cp = last_char_is(file_header->name, '/'); | 351 | cp = last_char_is(file_header->name, '/'); |
341 | 352 | ||
342 | if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { | 353 | if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { |
343 | archive_handle->action_header(archive_handle->file_header); | 354 | archive_handle->action_header(/*archive_handle->*/ file_header); |
344 | /* Note that we kill the '/' only after action_header() */ | 355 | /* Note that we kill the '/' only after action_header() */ |
345 | /* (like GNU tar 1.15.1: verbose mode outputs "dir/dir/") */ | 356 | /* (like GNU tar 1.15.1: verbose mode outputs "dir/dir/") */ |
346 | if (cp) *cp = '\0'; | 357 | if (cp) *cp = '\0'; |
diff --git a/archival/libunarchive/get_header_tar_gz.c b/archival/libunarchive/get_header_tar_gz.c index 086c6df42..e88b720a8 100644 --- a/archival/libunarchive/get_header_tar_gz.c +++ b/archival/libunarchive/get_header_tar_gz.c | |||
@@ -20,6 +20,7 @@ char FAST_FUNC get_header_tar_gz(archive_handle_t *archive_handle) | |||
20 | * need the header. */ | 20 | * need the header. */ |
21 | #if BB_MMU | 21 | #if BB_MMU |
22 | xread(archive_handle->src_fd, &magic, 2); | 22 | xread(archive_handle->src_fd, &magic, 2); |
23 | /* Can skip this check, but error message will be less clear */ | ||
23 | if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) { | 24 | if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) { |
24 | bb_error_msg_and_die("invalid gzip magic"); | 25 | bb_error_msg_and_die("invalid gzip magic"); |
25 | } | 26 | } |
diff --git a/archival/libunarchive/unpack_ar_archive.c b/archival/libunarchive/unpack_ar_archive.c index 9c2f68b14..dc2eec223 100644 --- a/archival/libunarchive/unpack_ar_archive.c +++ b/archival/libunarchive/unpack_ar_archive.c | |||
@@ -16,5 +16,6 @@ void FAST_FUNC unpack_ar_archive(archive_handle_t *ar_archive) | |||
16 | } | 16 | } |
17 | ar_archive->offset += 7; | 17 | ar_archive->offset += 7; |
18 | 18 | ||
19 | while (get_header_ar(ar_archive) == EXIT_SUCCESS); | 19 | while (get_header_ar(ar_archive) == EXIT_SUCCESS) |
20 | continue; | ||
20 | } | 21 | } |