diff options
author | Pascal Bellard <pascal.bellard@ads-lu.com> | 2009-08-28 06:20:33 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-08-28 06:20:33 +0200 |
commit | 7f2149489fe62373a13792d3de6c33c39725c76c (patch) | |
tree | 6717379b1a1df8790168543250623ae0d961d88e | |
parent | b34759251d0140d9d4b7a8143b2ba217ce773523 (diff) | |
download | busybox-w32-7f2149489fe62373a13792d3de6c33c39725c76c.tar.gz busybox-w32-7f2149489fe62373a13792d3de6c33c39725c76c.tar.bz2 busybox-w32-7f2149489fe62373a13792d3de6c33c39725c76c.zip |
rpm2cpio: handle bz2 too; code shrink
function old new delta
skip_header 142 99 -43
rpm2cpio_main 321 183 -138
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-181) Total: -181 bytes
Signed-off-by: Pascal Bellard <pascal.bellard@ads-lu.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/rpm2cpio.c | 77 | ||||
-rw-r--r-- | libbb/read.c | 2 |
2 files changed, 49 insertions, 30 deletions
diff --git a/archival/rpm2cpio.c b/archival/rpm2cpio.c index ee938716f..566a9f213 100644 --- a/archival/rpm2cpio.c +++ b/archival/rpm2cpio.c | |||
@@ -9,11 +9,11 @@ | |||
9 | #include "libbb.h" | 9 | #include "libbb.h" |
10 | #include "unarchive.h" | 10 | #include "unarchive.h" |
11 | 11 | ||
12 | #define RPM_MAGIC "\355\253\356\333" | 12 | #define RPM_MAGIC 0xedabeedb |
13 | #define RPM_HEADER_MAGIC "\216\255\350" | 13 | #define RPM_MAGIC_STR "\355\253\356\333" |
14 | 14 | ||
15 | struct rpm_lead { | 15 | struct rpm_lead { |
16 | unsigned char magic[4]; | 16 | uint32_t magic; |
17 | uint8_t major, minor; | 17 | uint8_t major, minor; |
18 | uint16_t type; | 18 | uint16_t type; |
19 | uint16_t archnum; | 19 | uint16_t archnum; |
@@ -23,67 +23,86 @@ struct rpm_lead { | |||
23 | char reserved[16]; | 23 | char reserved[16]; |
24 | }; | 24 | }; |
25 | 25 | ||
26 | #define RPM_HEADER_VERnMAGIC 0x8eade801 | ||
27 | #define RPM_HEADER_MAGIC_STR "\216\255\350" | ||
28 | |||
26 | struct rpm_header { | 29 | struct rpm_header { |
27 | char magic[3]; /* 3 byte magic: 0x8e 0xad 0xe8 */ | 30 | uint32_t magic_and_ver; /* 3 byte magic: 0x8e 0xad 0xe8; 1 byte version */ |
28 | uint8_t version; /* 1 byte version number */ | ||
29 | uint32_t reserved; /* 4 bytes reserved */ | 31 | uint32_t reserved; /* 4 bytes reserved */ |
30 | uint32_t entries; /* Number of entries in header (4 bytes) */ | 32 | uint32_t entries; /* Number of entries in header (4 bytes) */ |
31 | uint32_t size; /* Size of store (4 bytes) */ | 33 | uint32_t size; /* Size of store (4 bytes) */ |
32 | }; | 34 | }; |
33 | 35 | ||
34 | static void skip_header(int rpm_fd) | 36 | static off_t skip_header(int rpm_fd) |
35 | { | 37 | { |
36 | struct rpm_header header; | 38 | struct rpm_header header; |
37 | 39 | ||
38 | xread(rpm_fd, &header, sizeof(struct rpm_header)); | 40 | xread(rpm_fd, &header, sizeof(header)); |
39 | if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC, 3) != 0) { | 41 | // if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC_STR, 3) != 0) { |
40 | bb_error_msg_and_die("invalid RPM header magic"); /* Invalid magic */ | 42 | // bb_error_msg_and_die("invalid RPM header magic"); |
41 | } | 43 | // } |
42 | if (header.version != 1) { | 44 | // if (header.version != 1) { |
43 | bb_error_msg_and_die("unsupported RPM header version"); /* This program only supports v1 headers */ | 45 | // bb_error_msg_and_die("unsupported RPM header version"); |
46 | // } | ||
47 | if (header.magic_and_ver != htonl(RPM_HEADER_VERnMAGIC)) { | ||
48 | bb_error_msg_and_die("invalid RPM header magic or unsupported version"); | ||
49 | // ": %x != %x", header.magic_and_ver, htonl(RPM_HEADER_VERnMAGIC)); | ||
44 | } | 50 | } |
45 | header.entries = ntohl(header.entries); | 51 | /* Seek past index entries */ |
46 | header.size = ntohl(header.size); | 52 | lseek(rpm_fd, 16 * ntohl(header.entries), SEEK_CUR); |
47 | lseek (rpm_fd, 16 * header.entries, SEEK_CUR); /* Seek past index entries */ | 53 | /* Seek past store */ |
48 | lseek (rpm_fd, header.size, SEEK_CUR); /* Seek past store */ | 54 | return lseek(rpm_fd, ntohl(header.size), SEEK_CUR); |
49 | } | 55 | } |
50 | 56 | ||
51 | /* No getopt required */ | 57 | /* No getopt required */ |
52 | int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 58 | int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
53 | int rpm2cpio_main(int argc, char **argv) | 59 | int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) |
54 | { | 60 | { |
55 | struct rpm_lead lead; | 61 | struct rpm_lead lead; |
56 | int rpm_fd; | 62 | int rpm_fd; |
63 | off_t pos; | ||
57 | unsigned char magic[2]; | 64 | unsigned char magic[2]; |
65 | IF_DESKTOP(long long) int FAST_FUNC (*unpack)(int src_fd, int dst_fd); | ||
58 | 66 | ||
59 | if (argc == 1) { | 67 | if (!argv[1]) { |
60 | rpm_fd = STDIN_FILENO; | 68 | rpm_fd = STDIN_FILENO; |
61 | } else { | 69 | } else { |
62 | rpm_fd = xopen(argv[1], O_RDONLY); | 70 | rpm_fd = xopen(argv[1], O_RDONLY); |
63 | } | 71 | } |
72 | xread(rpm_fd, &lead, sizeof(lead)); | ||
64 | 73 | ||
65 | xread(rpm_fd, &lead, sizeof(struct rpm_lead)); | 74 | /* Just check the magic, the rest is irrelevant */ |
66 | if (strncmp((char *) &lead.magic, RPM_MAGIC, 4) != 0) { | 75 | if (lead.magic != htonl(RPM_MAGIC)) { |
67 | bb_error_msg_and_die("invalid RPM magic"); /* Just check the magic, the rest is irrelevant */ | 76 | bb_error_msg_and_die("invalid RPM magic"); |
68 | } | 77 | } |
69 | 78 | ||
70 | /* Skip the signature header */ | 79 | /* Skip the signature header, align to 8 bytes */ |
71 | skip_header(rpm_fd); | 80 | pos = skip_header(rpm_fd); |
72 | lseek(rpm_fd, (8 - (lseek(rpm_fd, 0, SEEK_CUR) % 8)) % 8, SEEK_CUR); | 81 | lseek(rpm_fd, (8 - (unsigned)pos) & 7, SEEK_CUR); |
73 | 82 | ||
74 | /* Skip the main header */ | 83 | /* Skip the main header */ |
75 | skip_header(rpm_fd); | 84 | skip_header(rpm_fd); |
76 | 85 | ||
77 | xread(rpm_fd, &magic, 2); | 86 | xread(rpm_fd, &magic, 2); |
78 | if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) { | 87 | unpack = unpack_gz_stream; |
79 | bb_error_msg_and_die("invalid gzip magic"); | 88 | if (magic[0] != 0x1f || magic[1] != 0x8b) { |
89 | if (!ENABLE_FEATURE_SEAMLESS_BZ2 | ||
90 | || magic[0] != 'B' || magic[1] != 'Z' | ||
91 | ) { | ||
92 | bb_error_msg_and_die("invalid gzip" | ||
93 | IF_FEATURE_SEAMLESS_BZ2("/bzip2") | ||
94 | " magic"); | ||
95 | } | ||
96 | unpack = unpack_bz2_stream; | ||
80 | } | 97 | } |
81 | 98 | ||
82 | if (unpack_gz_stream(rpm_fd, STDOUT_FILENO) < 0) { | 99 | if (unpack(rpm_fd, STDOUT_FILENO) < 0) { |
83 | bb_error_msg("error inflating"); | 100 | bb_error_msg_and_die("error unpacking"); |
84 | } | 101 | } |
85 | 102 | ||
86 | close(rpm_fd); | 103 | if (ENABLE_FEATURE_CLEAN_UP) { |
104 | close(rpm_fd); | ||
105 | } | ||
87 | 106 | ||
88 | return 0; | 107 | return 0; |
89 | } | 108 | } |
diff --git a/libbb/read.c b/libbb/read.c index b58982b32..b93a695b5 100644 --- a/libbb/read.c +++ b/libbb/read.c | |||
@@ -336,7 +336,7 @@ int FAST_FUNC open_zipped(const char *fname) | |||
336 | || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, ".bz2") == 0) | 336 | || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, ".bz2") == 0) |
337 | ) { | 337 | ) { |
338 | /* .gz and .bz2 both have 2-byte signature, and their | 338 | /* .gz and .bz2 both have 2-byte signature, and their |
339 | * unpack_XXX_stream want this header skipped. */ | 339 | * unpack_XXX_stream wants this header skipped. */ |
340 | xread(fd, &magic, 2); | 340 | xread(fd, &magic, 2); |
341 | #if ENABLE_FEATURE_SEAMLESS_GZ | 341 | #if ENABLE_FEATURE_SEAMLESS_GZ |
342 | #if BB_MMU | 342 | #if BB_MMU |