aboutsummaryrefslogtreecommitdiff
path: root/archival
diff options
context:
space:
mode:
Diffstat (limited to 'archival')
-rw-r--r--archival/rpm.c97
-rw-r--r--archival/rpm.h38
-rw-r--r--archival/rpm2cpio.c69
3 files changed, 97 insertions, 107 deletions
diff --git a/archival/rpm.c b/archival/rpm.c
index 6c1e341cd..77679c275 100644
--- a/archival/rpm.c
+++ b/archival/rpm.c
@@ -9,8 +9,8 @@
9 9
10#include "libbb.h" 10#include "libbb.h"
11#include "unarchive.h" 11#include "unarchive.h"
12#include "rpm.h"
12 13
13#define RPM_HEADER_MAGIC "\216\255\350"
14#define RPM_CHAR_TYPE 1 14#define RPM_CHAR_TYPE 1
15#define RPM_INT8_TYPE 2 15#define RPM_INT8_TYPE 2
16#define RPM_INT16_TYPE 3 16#define RPM_INT16_TYPE 3
@@ -46,6 +46,7 @@
46#define TAG_DIRINDEXES 1116 46#define TAG_DIRINDEXES 1116
47#define TAG_BASENAMES 1117 47#define TAG_BASENAMES 1117
48#define TAG_DIRNAMES 1118 48#define TAG_DIRNAMES 1118
49
49#define RPMFILE_CONFIG (1 << 0) 50#define RPMFILE_CONFIG (1 << 0)
50#define RPMFILE_DOC (1 << 1) 51#define RPMFILE_DOC (1 << 1)
51 52
@@ -147,8 +148,14 @@ int rpm_main(int argc, char **argv)
147 time_t bdate_time; 148 time_t bdate_time;
148 struct tm *bdate_ptm; 149 struct tm *bdate_ptm;
149 char bdatestring[50]; 150 char bdatestring[50];
150 printf("Name : %-29sRelocations: %s\n", rpm_getstr(TAG_NAME, 0), rpm_getstr(TAG_PREFIXS, 0) ? rpm_getstr(TAG_PREFIXS, 0) : "(not relocateable)"); 151 const char *p;
151 printf("Version : %-34sVendor: %s\n", rpm_getstr(TAG_VERSION, 0), rpm_getstr(TAG_VENDOR, 0) ? rpm_getstr(TAG_VENDOR, 0) : "(none)"); 152
153 p = rpm_getstr(TAG_PREFIXS, 0);
154 if (!p) p = "(not relocateable)";
155 printf("Name : %-29sRelocations: %s\n", rpm_getstr(TAG_NAME, 0), p);
156 p = rpm_getstr(TAG_VENDOR, 0);
157 if (!p) p = "(none)";
158 printf("Version : %-34sVendor: %s\n", rpm_getstr(TAG_VERSION, 0), p);
152 bdate_time = rpm_getint(TAG_BUILDTIME, 0); 159 bdate_time = rpm_getint(TAG_BUILDTIME, 0);
153 bdate_ptm = localtime(&bdate_time); 160 bdate_ptm = localtime(&bdate_time);
154 strftime(bdatestring, 50, "%a %d %b %Y %T %Z", bdate_ptm); 161 strftime(bdatestring, 50, "%a %d %b %Y %T %Z", bdate_ptm);
@@ -190,20 +197,15 @@ int rpm_main(int argc, char **argv)
190static void extract_cpio_gz(int fd) 197static void extract_cpio_gz(int fd)
191{ 198{
192 archive_handle_t *archive_handle; 199 archive_handle_t *archive_handle;
193 unsigned char magic[2];
194#if BB_MMU
195 IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd);
196 enum { xformer_prog = 0 };
197#else
198 enum { xformer = 0 };
199 const char *xformer_prog;
200#endif
201 200
202 /* Initialize */ 201 /* Initialize */
203 archive_handle = init_handle(); 202 archive_handle = init_handle();
204 archive_handle->seek = seek_by_read; 203 archive_handle->seek = seek_by_read;
205 //archive_handle->action_header = header_list;
206 archive_handle->action_data = data_extract_all; 204 archive_handle->action_data = data_extract_all;
205#if 0 /* For testing (rpm -i only lists the files in internal cpio): */
206 archive_handle->action_header = header_list;
207 archive_handle->action_data = data_skip;
208#endif
207 archive_handle->ah_flags = ARCHIVE_RESTORE_DATE | ARCHIVE_CREATE_LEADING_DIRS 209 archive_handle->ah_flags = ARCHIVE_RESTORE_DATE | ARCHIVE_CREATE_LEADING_DIRS
208 /* compat: overwrite existing files. 210 /* compat: overwrite existing files.
209 * try "rpm -i foo.src.rpm" few times in a row - 211 * try "rpm -i foo.src.rpm" few times in a row -
@@ -213,46 +215,15 @@ static void extract_cpio_gz(int fd)
213 archive_handle->src_fd = fd; 215 archive_handle->src_fd = fd;
214 /*archive_handle->offset = 0; - init_handle() did it */ 216 /*archive_handle->offset = 0; - init_handle() did it */
215 217
216// TODO: open_zipped does the same
217
218 xread(archive_handle->src_fd, &magic, 2);
219#if BB_MMU
220 xformer = unpack_gz_stream;
221#else
222 xformer_prog = "gunzip";
223#endif
224 if (magic[0] != 0x1f || magic[1] != 0x8b) {
225 if (!ENABLE_FEATURE_SEAMLESS_BZ2
226 || magic[0] != 'B' || magic[1] != 'Z'
227 ) {
228 bb_error_msg_and_die("no gzip"
229 IF_FEATURE_SEAMLESS_BZ2("/bzip2")
230 " magic");
231 }
232#if BB_MMU
233 xformer = unpack_bz2_stream;
234#else
235 xformer_prog = "bunzip2";
236#endif
237 } else {
238#if !BB_MMU
239 /* NOMMU version of open_transformer execs an external unzipper that should
240 * have the file position at the start of the file */
241 xlseek(archive_handle->src_fd, 0, SEEK_SET);
242#endif
243 }
244
245 xchdir("/"); /* Install RPM's to root */ 218 xchdir("/"); /* Install RPM's to root */
246 open_transformer(archive_handle->src_fd, xformer, xformer_prog); 219 setup_unzip_on_fd(archive_handle->src_fd /*, fail_if_not_detected: 1*/);
247 archive_handle->offset = 0;
248 while (get_header_cpio(archive_handle) == EXIT_SUCCESS) 220 while (get_header_cpio(archive_handle) == EXIT_SUCCESS)
249 continue; 221 continue;
250} 222}
251 223
252
253static rpm_index **rpm_gettags(int fd, int *num_tags) 224static rpm_index **rpm_gettags(int fd, int *num_tags)
254{ 225{
255 /* We should never need mode than 200, and realloc later */ 226 /* We should never need more than 200 (shrink via realloc later) */
256 rpm_index **tags = xzalloc(200 * sizeof(tags[0])); 227 rpm_index **tags = xzalloc(200 * sizeof(tags[0]));
257 int pass, tagindex = 0; 228 int pass, tagindex = 0;
258 229
@@ -260,27 +231,16 @@ static rpm_index **rpm_gettags(int fd, int *num_tags)
260 231
261 /* 1st pass is the signature headers, 2nd is the main stuff */ 232 /* 1st pass is the signature headers, 2nd is the main stuff */
262 for (pass = 0; pass < 2; pass++) { 233 for (pass = 0; pass < 2; pass++) {
263 struct { 234 struct rpm_header header;
264 char magic[3]; /* 3 byte magic: 0x8e 0xad 0xe8 */
265 uint8_t version; /* 1 byte version number */
266 uint32_t reserved; /* 4 bytes reserved */
267 uint32_t entries; /* Number of entries in header (4 bytes) */
268 uint32_t size; /* Size of store (4 bytes) */
269 } header;
270 struct BUG_header {
271 char BUG_header[sizeof(header) == 16 ? 1 : -1];
272 };
273 rpm_index *tmpindex; 235 rpm_index *tmpindex;
274 int storepos; 236 int storepos;
275 237
276 xread(fd, &header, sizeof(header)); 238 xread(fd, &header, sizeof(header));
277 if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC, 3) != 0) 239 if (header.magic_and_ver != htonl(RPM_HEADER_MAGICnVER))
278 return NULL; /* Invalid magic */ 240 return NULL; /* Invalid magic, or not version 1 */
279 if (header.version != 1)
280 return NULL; /* This program only supports v1 headers */
281 header.size = ntohl(header.size); 241 header.size = ntohl(header.size);
282 header.entries = ntohl(header.entries); 242 header.entries = ntohl(header.entries);
283 storepos = xlseek(fd,0,SEEK_CUR) + header.entries * 16; 243 storepos = xlseek(fd, 0, SEEK_CUR) + header.entries * 16;
284 244
285 while (header.entries--) { 245 while (header.entries--) {
286 tmpindex = tags[tagindex++] = xmalloc(sizeof(*tmpindex)); 246 tmpindex = tags[tagindex++] = xmalloc(sizeof(*tmpindex));
@@ -292,14 +252,16 @@ static rpm_index **rpm_gettags(int fd, int *num_tags)
292 if (pass == 0) 252 if (pass == 0)
293 tmpindex->tag -= 743; 253 tmpindex->tag -= 743;
294 } 254 }
295 xlseek(fd, header.size, SEEK_CUR); /* Seek past store */ 255 storepos = xlseek(fd, header.size, SEEK_CUR); /* Seek past store */
296 /* Skip padding to 8 byte boundary after reading signature headers */ 256 /* Skip padding to 8 byte boundary after reading signature headers */
297 if (pass == 0) 257 if (pass == 0)
298 xlseek(fd, (8 - (xlseek(fd,0,SEEK_CUR) % 8)) % 8, SEEK_CUR); 258 xlseek(fd, (-storepos) & 0x7, SEEK_CUR);
299 } 259 }
300 tags = xrealloc(tags, tagindex * sizeof(tags[0])); /* realloc tags to save space */ 260 /* realloc tags to save space */
261 tags = xrealloc(tags, tagindex * sizeof(tags[0]));
301 *num_tags = tagindex; 262 *num_tags = tagindex;
302 return tags; /* All done, leave the file at the start of the gzipped cpio archive */ 263 /* All done, leave the file at the start of the gzipped cpio archive */
264 return tags;
303} 265}
304 266
305static int bsearch_rpmtag(const void *key, const void *item) 267static int bsearch_rpmtag(const void *key, const void *item)
@@ -324,10 +286,13 @@ static char *rpm_getstr(int tag, int itemindex)
324 found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag); 286 found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
325 if (!found || itemindex >= found[0]->count) 287 if (!found || itemindex >= found[0]->count)
326 return NULL; 288 return NULL;
327 if (found[0]->type == RPM_STRING_TYPE || found[0]->type == RPM_I18NSTRING_TYPE || found[0]->type == RPM_STRING_ARRAY_TYPE) { 289 if (found[0]->type == RPM_STRING_TYPE
290 || found[0]->type == RPM_I18NSTRING_TYPE
291 || found[0]->type == RPM_STRING_ARRAY_TYPE
292 ) {
328 int n; 293 int n;
329 char *tmpstr = (char *) map + found[0]->offset; 294 char *tmpstr = (char *) map + found[0]->offset;
330 for (n=0; n < itemindex; n++) 295 for (n = 0; n < itemindex; n++)
331 tmpstr = tmpstr + strlen(tmpstr) + 1; 296 tmpstr = tmpstr + strlen(tmpstr) + 1;
332 return tmpstr; 297 return tmpstr;
333 } 298 }
diff --git a/archival/rpm.h b/archival/rpm.h
new file mode 100644
index 000000000..f7c6fc2fa
--- /dev/null
+++ b/archival/rpm.h
@@ -0,0 +1,38 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * RPM structs and consts
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
10/* RPM file starts with this struct: */
11struct rpm_lead {
12 uint32_t magic;
13 uint8_t major, minor;
14 uint16_t type;
15 uint16_t archnum;
16 char name[66];
17 uint16_t osnum;
18 uint16_t signature_type;
19 char reserved[16];
20};
21struct BUG_rpm_lead {
22 char bug[sizeof(struct rpm_lead) == 96 ? 1 : -1];
23};
24#define RPM_LEAD_MAGIC 0xedabeedb
25#define RPM_LEAD_MAGIC_STR "\355\253\356\333"
26
27/* Then follows the header: */
28struct rpm_header {
29 uint32_t magic_and_ver; /* 3 byte magic: 0x8e 0xad 0xe8; 1 byte version: 0x01 */
30 uint32_t reserved; /* 4 bytes reserved */
31 uint32_t entries; /* Number of entries in header (4 bytes) */
32 uint32_t size; /* Size of store (4 bytes) */
33};
34struct BUG_rpm_header {
35 char bug[sizeof(struct rpm_header) == 16 ? 1 : -1];
36};
37#define RPM_HEADER_MAGICnVER 0x8eade801
38#define RPM_HEADER_MAGIC_STR "\216\255\350"
diff --git a/archival/rpm2cpio.c b/archival/rpm2cpio.c
index 5403aee02..4ed5b023b 100644
--- a/archival/rpm2cpio.c
+++ b/archival/rpm2cpio.c
@@ -8,30 +8,7 @@
8 */ 8 */
9#include "libbb.h" 9#include "libbb.h"
10#include "unarchive.h" 10#include "unarchive.h"
11 11#include "rpm.h"
12#define RPM_MAGIC 0xedabeedb
13#define RPM_MAGIC_STR "\355\253\356\333"
14
15struct 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
29struct 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 12
36enum { rpm_fd = STDIN_FILENO }; 13enum { rpm_fd = STDIN_FILENO };
37 14
@@ -65,8 +42,6 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv)
65{ 42{
66 struct rpm_lead lead; 43 struct rpm_lead lead;
67 unsigned pos; 44 unsigned pos;
68 unsigned char magic[2];
69 IF_DESKTOP(long long) int FAST_FUNC (*unpack)(int src_fd, int dst_fd);
70 45
71 if (argv[1]) { 46 if (argv[1]) {
72 xmove_fd(xopen(argv[1], O_RDONLY), rpm_fd); 47 xmove_fd(xopen(argv[1], O_RDONLY), rpm_fd);
@@ -74,33 +49,45 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv)
74 xread(rpm_fd, &lead, sizeof(lead)); 49 xread(rpm_fd, &lead, sizeof(lead));
75 50
76 /* Just check the magic, the rest is irrelevant */ 51 /* Just check the magic, the rest is irrelevant */
77 if (lead.magic != htonl(RPM_MAGIC)) { 52 if (lead.magic != htonl(RPM_LEAD_MAGIC)) {
78 bb_error_msg_and_die("invalid RPM magic"); 53 bb_error_msg_and_die("invalid RPM magic");
79 } 54 }
80 55
81 /* Skip the signature header, align to 8 bytes */ 56 /* Skip the signature header, align to 8 bytes */
82 pos = skip_header(); 57 pos = skip_header();
83 seek_by_jump(rpm_fd, (8 - pos) & 7); 58 seek_by_jump(rpm_fd, (-(int)pos) & 7);
84 59
85 /* Skip the main header */ 60 /* Skip the main header */
86 skip_header(); 61 skip_header();
87 62
88 xread(rpm_fd, &magic, 2); 63#if 0
89 unpack = unpack_gz_stream; 64 /* This works, but doesn't report uncompress errors (they happen in child) */
90 if (magic[0] != 0x1f || magic[1] != 0x8b) { 65 setup_unzip_on_fd(rpm_fd /*fail_if_not_detected: 1*/);
91 if (!ENABLE_FEATURE_SEAMLESS_BZ2 66 if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0)
92 || magic[0] != 'B' || magic[1] != 'Z' 67 bb_error_msg_and_die("error unpacking");
93 ) { 68#else
94 bb_error_msg_and_die("invalid gzip" 69 /* BLOAT */
95 IF_FEATURE_SEAMLESS_BZ2("/bzip2") 70 {
96 " magic"); 71 unsigned char magic[2];
72 IF_DESKTOP(long long) int FAST_FUNC (*unpack)(int src_fd, int dst_fd);
73
74 xread(rpm_fd, &magic, 2);
75 unpack = unpack_gz_stream;
76 if (magic[0] != 0x1f || magic[1] != 0x8b) {
77 if (!ENABLE_FEATURE_SEAMLESS_BZ2
78 || magic[0] != 'B' || magic[1] != 'Z'
79 ) {
80 bb_error_msg_and_die("invalid gzip"
81 IF_FEATURE_SEAMLESS_BZ2("/bzip2")
82 " magic");
83 }
84 unpack = unpack_bz2_stream;
97 } 85 }
98 unpack = unpack_bz2_stream;
99 }
100 86
101 if (unpack(rpm_fd, STDOUT_FILENO) < 0) { 87 if (unpack(rpm_fd, STDOUT_FILENO) < 0)
102 bb_error_msg_and_die("error unpacking"); 88 bb_error_msg_and_die("error unpacking");
103 } 89 }
90#endif
104 91
105 if (ENABLE_FEATURE_CLEAN_UP) { 92 if (ENABLE_FEATURE_CLEAN_UP) {
106 close(rpm_fd); 93 close(rpm_fd);