Contents of /trunk/mkinitrd-magellan/busybox/archival/rpm2cpio.c
Parent Directory | Revision Log
Revision 984 -
(show annotations)
(download)
Sun May 30 11:32:42 2010 UTC (14 years, 4 months ago) by niro
File MIME type: text/plain
File size: 2756 byte(s)
Sun May 30 11:32:42 2010 UTC (14 years, 4 months ago) by niro
File MIME type: text/plain
File size: 2756 byte(s)
-updated to busybox-1.16.1 and enabled blkid/uuid support in default config
1 | /* vi: set sw=4 ts=4: */ |
2 | /* |
3 | * Mini rpm2cpio implementation for busybox |
4 | * |
5 | * Copyright (C) 2001 by Laurence Anderson |
6 | * |
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
8 | */ |
9 | #include "libbb.h" |
10 | #include "unarchive.h" |
11 | |
12 | #define RPM_MAGIC 0xedabeedb |
13 | #define RPM_MAGIC_STR "\355\253\356\333" |
14 | |
15 | struct rpm_lead { |
16 | uint32_t magic; |
17 | uint8_t major, minor; |
18 | uint16_t type; |
19 | uint16_t archnum; |
20 | char name[66]; |
21 | uint16_t osnum; |
22 | uint16_t signature_type; |
23 | char reserved[16]; |
24 | }; |
25 | |
26 | #define RPM_HEADER_MAGICnVER 0x8eade801 |
27 | #define RPM_HEADER_MAGIC_STR "\216\255\350" |
28 | |
29 | struct rpm_header { |
30 | uint32_t magic_and_ver; /* 3 byte magic: 0x8e 0xad 0xe8; 1 byte version */ |
31 | uint32_t reserved; /* 4 bytes reserved */ |
32 | uint32_t entries; /* Number of entries in header (4 bytes) */ |
33 | uint32_t size; /* Size of store (4 bytes) */ |
34 | }; |
35 | |
36 | enum { rpm_fd = STDIN_FILENO }; |
37 | |
38 | static unsigned skip_header(void) |
39 | { |
40 | struct rpm_header header; |
41 | unsigned len; |
42 | |
43 | xread(rpm_fd, &header, sizeof(header)); |
44 | // if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC_STR, 3) != 0) { |
45 | // bb_error_msg_and_die("invalid RPM header magic"); |
46 | // } |
47 | // if (header.version != 1) { |
48 | // bb_error_msg_and_die("unsupported RPM header version"); |
49 | // } |
50 | if (header.magic_and_ver != htonl(RPM_HEADER_MAGICnVER)) { |
51 | bb_error_msg_and_die("invalid RPM header magic or unsupported version"); |
52 | // ": %x != %x", header.magic_and_ver, htonl(RPM_HEADER_MAGICnVER)); |
53 | } |
54 | |
55 | /* Seek past index entries, and past store */ |
56 | len = 16 * ntohl(header.entries) + ntohl(header.size); |
57 | seek_by_jump(rpm_fd, len); |
58 | |
59 | return sizeof(header) + len; |
60 | } |
61 | |
62 | /* No getopt required */ |
63 | int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
64 | int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) |
65 | { |
66 | struct rpm_lead lead; |
67 | unsigned pos; |
68 | unsigned char magic[2]; |
69 | IF_DESKTOP(long long) int FAST_FUNC (*unpack)(int src_fd, int dst_fd); |
70 | |
71 | if (argv[1]) { |
72 | xmove_fd(xopen(argv[1], O_RDONLY), rpm_fd); |
73 | } |
74 | xread(rpm_fd, &lead, sizeof(lead)); |
75 | |
76 | /* Just check the magic, the rest is irrelevant */ |
77 | if (lead.magic != htonl(RPM_MAGIC)) { |
78 | bb_error_msg_and_die("invalid RPM magic"); |
79 | } |
80 | |
81 | /* Skip the signature header, align to 8 bytes */ |
82 | pos = skip_header(); |
83 | seek_by_jump(rpm_fd, (8 - pos) & 7); |
84 | |
85 | /* Skip the main header */ |
86 | skip_header(); |
87 | |
88 | xread(rpm_fd, &magic, 2); |
89 | unpack = unpack_gz_stream; |
90 | if (magic[0] != 0x1f || magic[1] != 0x8b) { |
91 | if (!ENABLE_FEATURE_SEAMLESS_BZ2 |
92 | || magic[0] != 'B' || magic[1] != 'Z' |
93 | ) { |
94 | bb_error_msg_and_die("invalid gzip" |
95 | IF_FEATURE_SEAMLESS_BZ2("/bzip2") |
96 | " magic"); |
97 | } |
98 | unpack = unpack_bz2_stream; |
99 | } |
100 | |
101 | if (unpack(rpm_fd, STDOUT_FILENO) < 0) { |
102 | bb_error_msg_and_die("error unpacking"); |
103 | } |
104 | |
105 | if (ENABLE_FEATURE_CLEAN_UP) { |
106 | close(rpm_fd); |
107 | } |
108 | |
109 | return 0; |
110 | } |