diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-08-28 21:09:51 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-08-28 21:09:51 +0200 |
commit | 0a130d510dc5272dc2fc7bc5a116f0694c8bd2a9 (patch) | |
tree | 029e91a6302547df06524ae6d73ecb5b85e35360 | |
parent | 7f2149489fe62373a13792d3de6c33c39725c76c (diff) | |
download | busybox-w32-0a130d510dc5272dc2fc7bc5a116f0694c8bd2a9.tar.gz busybox-w32-0a130d510dc5272dc2fc7bc5a116f0694c8bd2a9.tar.bz2 busybox-w32-0a130d510dc5272dc2fc7bc5a116f0694c8bd2a9.zip |
rpm2cpio: handle unseekable input correctly
function old new delta
data_skip 14 20 +6
seek_by_jump 67 72 +5
data_align 81 84 +3
seek_by_read 20 19 -1
skip_header 99 94 -5
rpm2cpio_main 183 177 -6
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/3 up/down: 14/-12) Total: 2 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/libunarchive/data_align.c | 2 | ||||
-rw-r--r-- | archival/libunarchive/data_skip.c | 2 | ||||
-rw-r--r-- | archival/libunarchive/seek_by_jump.c | 6 | ||||
-rw-r--r-- | archival/libunarchive/seek_by_read.c | 6 | ||||
-rw-r--r-- | archival/rpm2cpio.c | 17 | ||||
-rw-r--r-- | include/unarchive.h | 8 |
6 files changed, 22 insertions, 19 deletions
diff --git a/archival/libunarchive/data_align.c b/archival/libunarchive/data_align.c index 9f2e8432f..0c8542bf5 100644 --- a/archival/libunarchive/data_align.c +++ b/archival/libunarchive/data_align.c | |||
@@ -10,6 +10,6 @@ void FAST_FUNC data_align(archive_handle_t *archive_handle, unsigned boundary) | |||
10 | { | 10 | { |
11 | unsigned skip_amount = (boundary - (archive_handle->offset % boundary)) % boundary; | 11 | unsigned skip_amount = (boundary - (archive_handle->offset % boundary)) % boundary; |
12 | 12 | ||
13 | archive_handle->seek(archive_handle, skip_amount); | 13 | archive_handle->seek(archive_handle->src_fd, skip_amount); |
14 | archive_handle->offset += skip_amount; | 14 | archive_handle->offset += skip_amount; |
15 | } | 15 | } |
diff --git a/archival/libunarchive/data_skip.c b/archival/libunarchive/data_skip.c index 438750fe5..06d3dced4 100644 --- a/archival/libunarchive/data_skip.c +++ b/archival/libunarchive/data_skip.c | |||
@@ -8,5 +8,5 @@ | |||
8 | 8 | ||
9 | void FAST_FUNC data_skip(archive_handle_t *archive_handle) | 9 | void FAST_FUNC data_skip(archive_handle_t *archive_handle) |
10 | { | 10 | { |
11 | archive_handle->seek(archive_handle, archive_handle->file_header->size); | 11 | archive_handle->seek(archive_handle->src_fd, archive_handle->file_header->size); |
12 | } | 12 | } |
diff --git a/archival/libunarchive/seek_by_jump.c b/archival/libunarchive/seek_by_jump.c index 0a259c963..7181cb3ce 100644 --- a/archival/libunarchive/seek_by_jump.c +++ b/archival/libunarchive/seek_by_jump.c | |||
@@ -6,13 +6,13 @@ | |||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | #include "unarchive.h" | 7 | #include "unarchive.h" |
8 | 8 | ||
9 | void FAST_FUNC seek_by_jump(const archive_handle_t *archive_handle, unsigned amount) | 9 | void FAST_FUNC seek_by_jump(int fd, off_t amount) |
10 | { | 10 | { |
11 | if (amount | 11 | if (amount |
12 | && lseek(archive_handle->src_fd, (off_t) amount, SEEK_CUR) == (off_t) -1 | 12 | && lseek(fd, amount, SEEK_CUR) == (off_t) -1 |
13 | ) { | 13 | ) { |
14 | if (errno == ESPIPE) | 14 | if (errno == ESPIPE) |
15 | seek_by_read(archive_handle, amount); | 15 | seek_by_read(fd, amount); |
16 | else | 16 | else |
17 | bb_perror_msg_and_die("seek failure"); | 17 | bb_perror_msg_and_die("seek failure"); |
18 | } | 18 | } |
diff --git a/archival/libunarchive/seek_by_read.c b/archival/libunarchive/seek_by_read.c index 2326a7512..af65e5d85 100644 --- a/archival/libunarchive/seek_by_read.c +++ b/archival/libunarchive/seek_by_read.c | |||
@@ -9,8 +9,8 @@ | |||
9 | /* If we are reading through a pipe, or from stdin then we can't lseek, | 9 | /* If we are reading through a pipe, or from stdin then we can't lseek, |
10 | * we must read and discard the data to skip over it. | 10 | * we must read and discard the data to skip over it. |
11 | */ | 11 | */ |
12 | void FAST_FUNC seek_by_read(const archive_handle_t *archive_handle, unsigned jump_size) | 12 | void FAST_FUNC seek_by_read(int fd, off_t amount) |
13 | { | 13 | { |
14 | if (jump_size) | 14 | if (amount) |
15 | bb_copyfd_exact_size(archive_handle->src_fd, -1, jump_size); | 15 | bb_copyfd_exact_size(fd, -1, amount); |
16 | } | 16 | } |
diff --git a/archival/rpm2cpio.c b/archival/rpm2cpio.c index 566a9f213..30ec80e22 100644 --- a/archival/rpm2cpio.c +++ b/archival/rpm2cpio.c | |||
@@ -33,9 +33,10 @@ struct rpm_header { | |||
33 | uint32_t size; /* Size of store (4 bytes) */ | 33 | uint32_t size; /* Size of store (4 bytes) */ |
34 | }; | 34 | }; |
35 | 35 | ||
36 | static off_t skip_header(int rpm_fd) | 36 | static unsigned skip_header(int rpm_fd) |
37 | { | 37 | { |
38 | struct rpm_header header; | 38 | struct rpm_header header; |
39 | unsigned len; | ||
39 | 40 | ||
40 | xread(rpm_fd, &header, sizeof(header)); | 41 | xread(rpm_fd, &header, sizeof(header)); |
41 | // if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC_STR, 3) != 0) { | 42 | // if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC_STR, 3) != 0) { |
@@ -48,10 +49,12 @@ static off_t skip_header(int rpm_fd) | |||
48 | bb_error_msg_and_die("invalid RPM header magic or unsupported version"); | 49 | bb_error_msg_and_die("invalid RPM header magic or unsupported version"); |
49 | // ": %x != %x", header.magic_and_ver, htonl(RPM_HEADER_VERnMAGIC)); | 50 | // ": %x != %x", header.magic_and_ver, htonl(RPM_HEADER_VERnMAGIC)); |
50 | } | 51 | } |
51 | /* Seek past index entries */ | 52 | |
52 | lseek(rpm_fd, 16 * ntohl(header.entries), SEEK_CUR); | 53 | /* Seek past index entries, and past store */ |
53 | /* Seek past store */ | 54 | len = 16 * ntohl(header.entries) + ntohl(header.size); |
54 | return lseek(rpm_fd, ntohl(header.size), SEEK_CUR); | 55 | seek_by_jump(rpm_fd, len); |
56 | |||
57 | return sizeof(header) + len; | ||
55 | } | 58 | } |
56 | 59 | ||
57 | /* No getopt required */ | 60 | /* No getopt required */ |
@@ -60,7 +63,7 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) | |||
60 | { | 63 | { |
61 | struct rpm_lead lead; | 64 | struct rpm_lead lead; |
62 | int rpm_fd; | 65 | int rpm_fd; |
63 | off_t pos; | 66 | unsigned pos; |
64 | unsigned char magic[2]; | 67 | unsigned char magic[2]; |
65 | IF_DESKTOP(long long) int FAST_FUNC (*unpack)(int src_fd, int dst_fd); | 68 | IF_DESKTOP(long long) int FAST_FUNC (*unpack)(int src_fd, int dst_fd); |
66 | 69 | ||
@@ -78,7 +81,7 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) | |||
78 | 81 | ||
79 | /* Skip the signature header, align to 8 bytes */ | 82 | /* Skip the signature header, align to 8 bytes */ |
80 | pos = skip_header(rpm_fd); | 83 | pos = skip_header(rpm_fd); |
81 | lseek(rpm_fd, (8 - (unsigned)pos) & 7, SEEK_CUR); | 84 | seek_by_jump(rpm_fd, (8 - pos) & 7); |
82 | 85 | ||
83 | /* Skip the main header */ | 86 | /* Skip the main header */ |
84 | skip_header(rpm_fd); | 87 | skip_header(rpm_fd); |
diff --git a/include/unarchive.h b/include/unarchive.h index 682e810d5..d8cb2a081 100644 --- a/include/unarchive.h +++ b/include/unarchive.h | |||
@@ -60,8 +60,8 @@ typedef struct archive_handle_t { | |||
60 | /* Count the number of bytes processed */ | 60 | /* Count the number of bytes processed */ |
61 | off_t offset; | 61 | off_t offset; |
62 | 62 | ||
63 | /* Function that skips data: read_by_char or read_by_skip */ | 63 | /* Function that skips data */ |
64 | void FAST_FUNC (*seek)(const struct archive_handle_t *archive_handle, const unsigned amount); | 64 | void FAST_FUNC (*seek)(int fd, off_t amount); |
65 | 65 | ||
66 | /* Temporary storage */ | 66 | /* Temporary storage */ |
67 | char *buffer; | 67 | char *buffer; |
@@ -107,8 +107,8 @@ extern char get_header_tar_gz(archive_handle_t *archive_handle) FAST_FUNC; | |||
107 | extern char get_header_tar_bz2(archive_handle_t *archive_handle) FAST_FUNC; | 107 | extern char get_header_tar_bz2(archive_handle_t *archive_handle) FAST_FUNC; |
108 | extern char get_header_tar_lzma(archive_handle_t *archive_handle) FAST_FUNC; | 108 | extern char get_header_tar_lzma(archive_handle_t *archive_handle) FAST_FUNC; |
109 | 109 | ||
110 | extern void seek_by_jump(const archive_handle_t *archive_handle, unsigned amount) FAST_FUNC; | 110 | extern void seek_by_jump(int fd, off_t amount) FAST_FUNC; |
111 | extern void seek_by_read(const archive_handle_t *archive_handle, unsigned amount) FAST_FUNC; | 111 | extern void seek_by_read(int fd, off_t amount) FAST_FUNC; |
112 | 112 | ||
113 | extern void data_align(archive_handle_t *archive_handle, unsigned boundary) FAST_FUNC; | 113 | extern void data_align(archive_handle_t *archive_handle, unsigned boundary) FAST_FUNC; |
114 | extern const llist_t *find_list_entry(const llist_t *list, const char *filename) FAST_FUNC; | 114 | extern const llist_t *find_list_entry(const llist_t *list, const char *filename) FAST_FUNC; |