diff options
author | Denis Vlasenko | 2008-07-10 23:06:00 +0000 |
---|---|---|
committer | Denis Vlasenko | 2008-07-10 23:06:00 +0000 |
commit | 0381d422d9b40c0cf887d299224c7759875aefd8 (patch) | |
tree | 764583282951c07bb6b611bef2858c5375647094 /archival/libunarchive/get_header_tar.c | |
parent | b6052724ffc9d45894147b70e7aff226938bd2d3 (diff) | |
download | busybox-0381d422d9b40c0cf887d299224c7759875aefd8.zip busybox-0381d422d9b40c0cf887d299224c7759875aefd8.tar.gz |
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/get_header_tar.c')
-rw-r--r-- | archival/libunarchive/get_header_tar.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/archival/libunarchive/get_header_tar.c b/archival/libunarchive/get_header_tar.c index 69362f1..cf35d41 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) again_after_align: #if ENABLE_DESKTOP + /* to prevent misdetection of bz2 sig */ + *(uint32_t*)(&tar) = 0; i = full_read(archive_handle->src_fd, &tar, 512); /* If GNU tar sees EOF in above read, it says: * "tar: A lone zero block at N", where N = kilobyte * where EOF was met (not EOF block, actual EOF!), - * and tar will exit with error code 0. + * and exits with EXIT_SUCCESS. * We will mimic exit(EXIT_SUCCESS), although we will not mimic * the message and we don't check whether we indeed * saw zero block directly before this. */ - if (i == 0) + if (i == 0) { xfunc_error_retval = 0; - if (i != 512) + short_read: bb_error_msg_and_die("short read"); + } + if (i != 512) { + if (ENABLE_FEATURE_TAR_AUTODETECT) + goto autodetect; + goto short_read; + } + #else - xread(archive_handle->src_fd, &tar, 512); + i = 512; + xread(archive_handle->src_fd, &tar, i); #endif - archive_handle->offset += 512; + archive_handle->offset += i; /* If there is no filename its an empty header */ if (tar.name[0] == 0 && tar.prefix[0] == 0) { @@ -133,6 +143,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) #if ENABLE_FEATURE_TAR_AUTODETECT char FAST_FUNC (*get_header_ptr)(archive_handle_t *); + USE_DESKTOP(autodetect:) /* tar gz/bz autodetect: check for gz/bz2 magic. * If we see the magic, and it is the very first block, * 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) /* Two different causes for lseek() != 0: * unseekable fd (would like to support that too, but...), * or not first block (false positive, it's not .gz/.bz2!) */ - if (lseek(archive_handle->src_fd, -512, SEEK_CUR) != 0) + if (lseek(archive_handle->src_fd, -i, SEEK_CUR) != 0) goto err; while (get_header_ptr(archive_handle) == EXIT_SUCCESS) continue; @@ -328,7 +339,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) p_linkname = NULL; } #endif - if (!strncmp(file_header->name, "/../"+1, 3) + if (strncmp(file_header->name, "/../"+1, 3) == 0 || strstr(file_header->name, "/../") ) { bb_error_msg_and_die("name with '..' encountered: '%s'", @@ -340,7 +351,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) cp = last_char_is(file_header->name, '/'); if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { - archive_handle->action_header(archive_handle->file_header); + archive_handle->action_header(/*archive_handle->*/ file_header); /* Note that we kill the '/' only after action_header() */ /* (like GNU tar 1.15.1: verbose mode outputs "dir/dir/") */ if (cp) *cp = '\0'; |