aboutsummaryrefslogtreecommitdiff
path: root/archival/libunarchive
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-07-10 23:06:00 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-07-10 23:06:00 +0000
commit0381d422d9b40c0cf887d299224c7759875aefd8 (patch)
tree764583282951c07bb6b611bef2858c5375647094 /archival/libunarchive
parentb6052724ffc9d45894147b70e7aff226938bd2d3 (diff)
downloadbusybox-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.c20
-rw-r--r--archival/libunarchive/get_header_ar.c5
-rw-r--r--archival/libunarchive/get_header_tar.c27
-rw-r--r--archival/libunarchive/get_header_tar_gz.c1
-rw-r--r--archival/libunarchive/unpack_ar_archive.c3
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}