diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-09 18:20:01 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-09 18:20:01 +0200 |
commit | 9be166b5dd5161ea537d662660cc0142aa2db92b (patch) | |
tree | 2c3fd12f8d4c3321fcddf231cb6db9f1818c1d76 | |
parent | cde46f75cbe8069e06b68396a7f6dc9564fbf2c4 (diff) | |
download | busybox-w32-9be166b5dd5161ea537d662660cc0142aa2db92b.tar.gz busybox-w32-9be166b5dd5161ea537d662660cc0142aa2db92b.tar.bz2 busybox-w32-9be166b5dd5161ea537d662660cc0142aa2db92b.zip |
rpm: code shrink
function old new delta
rpm_getstr0 - 7 +7
rpm_getstr 112 110 -2
rpm_getint 120 118 -2
bsearch_rpmtag 15 13 -2
shell_builtin_read 1334 1320 -14
rpm_main 1548 1474 -74
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 0/5 up/down: 7/-94) Total: -87 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/rpm.c | 250 | ||||
-rw-r--r-- | archival/rpm2cpio.c | 7 |
2 files changed, 168 insertions, 89 deletions
diff --git a/archival/rpm.c b/archival/rpm.c index 98039d499..89b36dd46 100644 --- a/archival/rpm.c +++ b/archival/rpm.c | |||
@@ -16,18 +16,6 @@ | |||
16 | //applet:IF_RPM(APPLET(rpm, BB_DIR_BIN, BB_SUID_DROP)) | 16 | //applet:IF_RPM(APPLET(rpm, BB_DIR_BIN, BB_SUID_DROP)) |
17 | //kbuild:lib-$(CONFIG_RPM) += rpm.o | 17 | //kbuild:lib-$(CONFIG_RPM) += rpm.o |
18 | 18 | ||
19 | //usage:#define rpm_trivial_usage | ||
20 | //usage: "-i PACKAGE.rpm; rpm -qp[ildc] PACKAGE.rpm" | ||
21 | //usage:#define rpm_full_usage "\n\n" | ||
22 | //usage: "Manipulate RPM packages\n" | ||
23 | //usage: "\nCommands:" | ||
24 | //usage: "\n -i Install package" | ||
25 | //usage: "\n -qp Query package" | ||
26 | //usage: "\n -qpi Show information" | ||
27 | //usage: "\n -qpl List contents" | ||
28 | //usage: "\n -qpd List documents" | ||
29 | //usage: "\n -qpc List config files" | ||
30 | |||
31 | #include "libbb.h" | 19 | #include "libbb.h" |
32 | #include "common_bufsiz.h" | 20 | #include "common_bufsiz.h" |
33 | #include "bb_archive.h" | 21 | #include "bb_archive.h" |
@@ -91,8 +79,9 @@ typedef struct { | |||
91 | 79 | ||
92 | struct globals { | 80 | struct globals { |
93 | void *map; | 81 | void *map; |
94 | rpm_index **mytags; | 82 | rpm_index *mytags; |
95 | int tagcount; | 83 | int tagcount; |
84 | unsigned mapsize, pagesize; | ||
96 | } FIX_ALIASING; | 85 | } FIX_ALIASING; |
97 | #define G (*(struct globals*)bb_common_bufsiz1) | 86 | #define G (*(struct globals*)bb_common_bufsiz1) |
98 | #define INIT_G() do { setup_common_bufsiz(); } while (0) | 87 | #define INIT_G() do { setup_common_bufsiz(); } while (0) |
@@ -128,105 +117,122 @@ static void extract_cpio(int fd, const char *source_rpm) | |||
128 | continue; | 117 | continue; |
129 | } | 118 | } |
130 | 119 | ||
131 | static rpm_index **rpm_gettags(int fd, int *num_tags) | 120 | static rpm_index *rpm_gettags(int fd) |
132 | { | 121 | { |
133 | /* We should never need more than 200 (shrink via realloc later) */ | 122 | rpm_index *tags; |
134 | rpm_index **tags = xzalloc(200 * sizeof(tags[0])); | 123 | unsigned pass, idx; |
135 | int pass, tagindex = 0; | 124 | unsigned storepos; |
136 | 125 | ||
137 | xlseek(fd, 96, SEEK_CUR); /* Seek past the unused lead */ | 126 | storepos = xlseek(fd, 96, SEEK_CUR); /* Seek past the unused lead */ |
138 | 127 | ||
128 | G.tagcount = 0; | ||
129 | tags = NULL; | ||
130 | idx = 0; | ||
139 | /* 1st pass is the signature headers, 2nd is the main stuff */ | 131 | /* 1st pass is the signature headers, 2nd is the main stuff */ |
140 | for (pass = 0; pass < 2; pass++) { | 132 | for (pass = 0; pass < 2; pass++) { |
141 | struct rpm_header header; | 133 | struct rpm_header header; |
142 | rpm_index *tmpindex; | 134 | unsigned cnt; |
143 | int storepos; | ||
144 | 135 | ||
145 | xread(fd, &header, sizeof(header)); | 136 | xread(fd, &header, sizeof(header)); |
146 | if (header.magic_and_ver != htonl(RPM_HEADER_MAGICnVER)) | 137 | if (header.magic_and_ver != htonl(RPM_HEADER_MAGICnVER)) |
147 | return NULL; /* Invalid magic, or not version 1 */ | 138 | return NULL; /* Invalid magic, or not version 1 */ |
148 | header.size = ntohl(header.size); | 139 | header.size = ntohl(header.size); |
149 | header.entries = ntohl(header.entries); | 140 | cnt = ntohl(header.entries); |
150 | storepos = xlseek(fd, 0, SEEK_CUR) + header.entries * 16; | 141 | storepos += sizeof(header) + cnt * 16; |
151 | 142 | ||
152 | while (header.entries--) { | 143 | G.tagcount += cnt; |
153 | tmpindex = tags[tagindex++] = xmalloc(sizeof(*tmpindex)); | 144 | tags = xrealloc(tags, G.tagcount * sizeof(tags[0])); |
154 | xread(fd, tmpindex, sizeof(*tmpindex)); | 145 | xread(fd, &tags[idx], sizeof(tags[0]) * cnt); |
155 | tmpindex->tag = ntohl(tmpindex->tag); | 146 | while (cnt--) { |
156 | tmpindex->type = ntohl(tmpindex->type); | 147 | rpm_index *tag = &tags[idx]; |
157 | tmpindex->count = ntohl(tmpindex->count); | 148 | tag->tag = ntohl(tag->tag); |
158 | tmpindex->offset = storepos + ntohl(tmpindex->offset); | 149 | tag->type = ntohl(tag->type); |
150 | tag->count = ntohl(tag->count); | ||
151 | tag->offset = storepos + ntohl(tag->offset); | ||
159 | if (pass == 0) | 152 | if (pass == 0) |
160 | tmpindex->tag -= 743; | 153 | tag->tag -= 743; |
154 | idx++; | ||
161 | } | 155 | } |
162 | storepos = xlseek(fd, header.size, SEEK_CUR); /* Seek past store */ | ||
163 | /* Skip padding to 8 byte boundary after reading signature headers */ | 156 | /* Skip padding to 8 byte boundary after reading signature headers */ |
164 | if (pass == 0) | 157 | if (pass == 0) |
165 | xlseek(fd, (-storepos) & 0x7, SEEK_CUR); | 158 | while (header.size & 7) |
159 | header.size++; | ||
160 | /* Seek past store */ | ||
161 | storepos = xlseek(fd, header.size, SEEK_CUR); | ||
166 | } | 162 | } |
167 | /* realloc tags to save space */ | 163 | |
168 | tags = xrealloc(tags, tagindex * sizeof(tags[0])); | 164 | /* Map the store */ |
169 | *num_tags = tagindex; | 165 | storepos = (storepos + G.pagesize) & -(int)G.pagesize; |
170 | /* All done, leave the file at the start of the gzipped cpio archive */ | 166 | /* remember size for munmap */ |
167 | G.mapsize = storepos; | ||
168 | /* some NOMMU systems prefer MAP_PRIVATE over MAP_SHARED */ | ||
169 | G.map = mmap(0, storepos, PROT_READ, MAP_PRIVATE, fd, 0); | ||
170 | if (G.map == MAP_FAILED) | ||
171 | return NULL; /* error */ | ||
172 | |||
171 | return tags; | 173 | return tags; |
172 | } | 174 | } |
173 | 175 | ||
174 | static int bsearch_rpmtag(const void *key, const void *item) | 176 | static int bsearch_rpmtag(const void *key, const void *item) |
175 | { | 177 | { |
176 | int *tag = (int *)key; | 178 | int *tag = (int *)key; |
177 | rpm_index **tmp = (rpm_index **) item; | 179 | rpm_index *tmp = (rpm_index *) item; |
178 | return (*tag - tmp[0]->tag); | 180 | return (*tag - tmp->tag); |
179 | } | 181 | } |
180 | 182 | ||
181 | static int rpm_getcount(int tag) | 183 | static int rpm_getcount(int tag) |
182 | { | 184 | { |
183 | rpm_index **found; | 185 | rpm_index *found; |
184 | found = bsearch(&tag, G.mytags, G.tagcount, sizeof(struct rpmtag *), bsearch_rpmtag); | 186 | found = bsearch(&tag, G.mytags, G.tagcount, sizeof(G.mytags[0]), bsearch_rpmtag); |
185 | if (!found) | 187 | if (!found) |
186 | return 0; | 188 | return 0; |
187 | return found[0]->count; | 189 | return found->count; |
188 | } | 190 | } |
189 | 191 | ||
190 | static char *rpm_getstr(int tag, int itemindex) | 192 | static char *rpm_getstr(int tag, int itemindex) |
191 | { | 193 | { |
192 | rpm_index **found; | 194 | rpm_index *found; |
193 | found = bsearch(&tag, G.mytags, G.tagcount, sizeof(struct rpmtag *), bsearch_rpmtag); | 195 | found = bsearch(&tag, G.mytags, G.tagcount, sizeof(G.mytags[0]), bsearch_rpmtag); |
194 | if (!found || itemindex >= found[0]->count) | 196 | if (!found || itemindex >= found->count) |
195 | return NULL; | 197 | return NULL; |
196 | if (found[0]->type == RPM_STRING_TYPE | 198 | if (found->type == RPM_STRING_TYPE |
197 | || found[0]->type == RPM_I18NSTRING_TYPE | 199 | || found->type == RPM_I18NSTRING_TYPE |
198 | || found[0]->type == RPM_STRING_ARRAY_TYPE | 200 | || found->type == RPM_STRING_ARRAY_TYPE |
199 | ) { | 201 | ) { |
200 | int n; | 202 | int n; |
201 | char *tmpstr = (char *) G.map + found[0]->offset; | 203 | char *tmpstr = (char *) G.map + found->offset; |
202 | for (n = 0; n < itemindex; n++) | 204 | for (n = 0; n < itemindex; n++) |
203 | tmpstr = tmpstr + strlen(tmpstr) + 1; | 205 | tmpstr = tmpstr + strlen(tmpstr) + 1; |
204 | return tmpstr; | 206 | return tmpstr; |
205 | } | 207 | } |
206 | return NULL; | 208 | return NULL; |
207 | } | 209 | } |
210 | static char *rpm_getstr0(int tag) | ||
211 | { | ||
212 | return rpm_getstr(tag, 0); | ||
213 | } | ||
208 | 214 | ||
209 | static int rpm_getint(int tag, int itemindex) | 215 | static int rpm_getint(int tag, int itemindex) |
210 | { | 216 | { |
211 | rpm_index **found; | 217 | rpm_index *found; |
212 | char *tmpint; | 218 | char *tmpint; |
213 | 219 | ||
214 | /* gcc throws warnings here when sizeof(void*)!=sizeof(int) ... | 220 | /* gcc throws warnings here when sizeof(void*)!=sizeof(int) ... |
215 | * it's ok to ignore it because tag won't be used as a pointer */ | 221 | * it's ok to ignore it because tag won't be used as a pointer */ |
216 | found = bsearch(&tag, G.mytags, G.tagcount, sizeof(struct rpmtag *), bsearch_rpmtag); | 222 | found = bsearch(&tag, G.mytags, G.tagcount, sizeof(G.mytags[0]), bsearch_rpmtag); |
217 | if (!found || itemindex >= found[0]->count) | 223 | if (!found || itemindex >= found->count) |
218 | return -1; | 224 | return -1; |
219 | 225 | ||
220 | tmpint = (char *) G.map + found[0]->offset; | 226 | tmpint = (char *) G.map + found->offset; |
221 | if (found[0]->type == RPM_INT32_TYPE) { | 227 | if (found->type == RPM_INT32_TYPE) { |
222 | tmpint += itemindex*4; | 228 | tmpint += itemindex*4; |
223 | return ntohl(*(int32_t*)tmpint); | 229 | return ntohl(*(int32_t*)tmpint); |
224 | } | 230 | } |
225 | if (found[0]->type == RPM_INT16_TYPE) { | 231 | if (found->type == RPM_INT16_TYPE) { |
226 | tmpint += itemindex*2; | 232 | tmpint += itemindex*2; |
227 | return ntohs(*(int16_t*)tmpint); | 233 | return ntohs(*(int16_t*)tmpint); |
228 | } | 234 | } |
229 | if (found[0]->type == RPM_INT8_TYPE) { | 235 | if (found->type == RPM_INT8_TYPE) { |
230 | tmpint += itemindex; | 236 | tmpint += itemindex; |
231 | return *(int8_t*)tmpint; | 237 | return *(int8_t*)tmpint; |
232 | } | 238 | } |
@@ -273,11 +279,71 @@ static void loop_through_files(int filetag, void (*fileaction)(char *filename, i | |||
273 | } | 279 | } |
274 | } | 280 | } |
275 | 281 | ||
282 | #if 0 //DEBUG | ||
283 | static void print_all_tags(void) | ||
284 | { | ||
285 | unsigned i = 0; | ||
286 | while (i < G.tagcount) { | ||
287 | rpm_index *tag = &G.mytags[i]; | ||
288 | if (tag->type == RPM_STRING_TYPE | ||
289 | || tag->type == RPM_I18NSTRING_TYPE | ||
290 | || tag->type == RPM_STRING_ARRAY_TYPE | ||
291 | ) { | ||
292 | unsigned n; | ||
293 | char *str = (char *) G.map + tag->offset; | ||
294 | |||
295 | printf("tag[%u] %08x type %08x offset %08x count %d '%s'\n", | ||
296 | i, tag->tag, tag->type, tag->offset, tag->count, str | ||
297 | ); | ||
298 | for (n = 1; n < tag->count; n++) { | ||
299 | str += strlen(str) + 1; | ||
300 | printf("\t'%s'\n", str); | ||
301 | } | ||
302 | } | ||
303 | i++; | ||
304 | } | ||
305 | } | ||
306 | #else | ||
307 | #define print_all_tags() ((void)0) | ||
308 | #endif | ||
309 | |||
310 | //usage:#define rpm_trivial_usage | ||
311 | //usage: "-i PACKAGE.rpm; rpm -qp[ildc] PACKAGE.rpm" | ||
312 | //usage:#define rpm_full_usage "\n\n" | ||
313 | //usage: "Manipulate RPM packages\n" | ||
314 | //usage: "\nCommands:" | ||
315 | //usage: "\n -i Install package" | ||
316 | //usage: "\n -qp Query package" | ||
317 | //usage: "\n -qpi Show information" | ||
318 | //usage: "\n -qpl List contents" | ||
319 | //usage: "\n -qpd List documents" | ||
320 | //usage: "\n -qpc List config files" | ||
321 | |||
322 | /* RPM version 4.13.0.1: | ||
323 | * Unlike -q, -i seems to imply -p: -i, -ip and -pi work the same. | ||
324 | * OTOH, with -q order is important: "-piq FILE.rpm" works as -qp, not -qpi | ||
325 | * (IOW: shows only package name, not package info). | ||
326 | * "-iq ARG" works as -q: treats ARG as package name, not a file. | ||
327 | * | ||
328 | * "man rpm" on -l option and options implying it: | ||
329 | * -l, --list List files in package. | ||
330 | * -c, --configfiles List only configuration files (implies -l). | ||
331 | * -d, --docfiles List only documentation files (implies -l). | ||
332 | * -L, --licensefiles List only license files (implies -l). | ||
333 | * --dump Dump file information as follows (implies -l): | ||
334 | * path size mtime digest mode owner group isconfig isdoc rdev symlink | ||
335 | * -s, --state Display the states of files in the package (implies -l). | ||
336 | * The state of each file is one of normal, not installed, or replaced. | ||
337 | * | ||
338 | * Looks like we can switch to getopt32 here: in practice, people | ||
339 | * do place -q first if they intend to use it (misinterpreting "-piq" wouldn't matter). | ||
340 | */ | ||
276 | int rpm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 341 | int rpm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
277 | int rpm_main(int argc, char **argv) | 342 | int rpm_main(int argc, char **argv) |
278 | { | 343 | { |
279 | int opt, func = 0; | 344 | int opt, func = 0; |
280 | const unsigned pagesize = getpagesize(); | 345 | |
346 | G.pagesize = getpagesize(); | ||
281 | 347 | ||
282 | while ((opt = getopt(argc, argv, "iqpldc")) != -1) { | 348 | while ((opt = getopt(argc, argv, "iqpldc")) != -1) { |
283 | switch (opt) { | 349 | switch (opt) { |
@@ -289,17 +355,17 @@ int rpm_main(int argc, char **argv) | |||
289 | if (func) bb_show_usage(); | 355 | if (func) bb_show_usage(); |
290 | func = rpm_query; | 356 | func = rpm_query; |
291 | break; | 357 | break; |
292 | case 'p': /* Query a package */ | 358 | case 'p': /* Query a package (IOW: .rpm file, we are not querying RPMDB) */ |
293 | func |= rpm_query_package; | 359 | func |= rpm_query_package; |
294 | break; | 360 | break; |
295 | case 'l': /* List files in a package */ | 361 | case 'l': /* List files in a package */ |
296 | func |= rpm_query_list; | 362 | func |= rpm_query_list; |
297 | break; | 363 | break; |
298 | case 'd': /* List doc files in a package (implies list) */ | 364 | case 'd': /* List doc files in a package (implies -l) */ |
299 | func |= rpm_query_list; | 365 | func |= rpm_query_list; |
300 | func |= rpm_query_list_doc; | 366 | func |= rpm_query_list_doc; |
301 | break; | 367 | break; |
302 | case 'c': /* List config files in a package (implies list) */ | 368 | case 'c': /* List config files in a package (implies -l) */ |
303 | func |= rpm_query_list; | 369 | func |= rpm_query_list; |
304 | func |= rpm_query_list_config; | 370 | func |= rpm_query_list_config; |
305 | break; | 371 | break; |
@@ -313,24 +379,22 @@ int rpm_main(int argc, char **argv) | |||
313 | bb_show_usage(); | 379 | bb_show_usage(); |
314 | } | 380 | } |
315 | 381 | ||
316 | while (*argv) { | 382 | for (;;) { |
317 | int rpm_fd; | 383 | int rpm_fd; |
318 | unsigned mapsize; | ||
319 | const char *source_rpm; | 384 | const char *source_rpm; |
320 | 385 | ||
321 | rpm_fd = xopen(*argv++, O_RDONLY); | 386 | rpm_fd = xopen(*argv, O_RDONLY); |
322 | G.mytags = rpm_gettags(rpm_fd, &G.tagcount); | 387 | G.mytags = rpm_gettags(rpm_fd); |
323 | if (!G.mytags) | 388 | if (!G.mytags) |
324 | bb_error_msg_and_die("error reading rpm header"); | 389 | bb_error_msg_and_die("error reading rpm header from '%s'", *argv); |
325 | mapsize = xlseek(rpm_fd, 0, SEEK_CUR); | 390 | |
326 | mapsize = (mapsize + pagesize) & -(int)pagesize; | 391 | print_all_tags(); |
327 | /* Some NOMMU systems prefer MAP_PRIVATE over MAP_SHARED */ | ||
328 | G.map = mmap(0, mapsize, PROT_READ, MAP_PRIVATE, rpm_fd, 0); | ||
329 | //FIXME: error check? | ||
330 | 392 | ||
331 | source_rpm = rpm_getstr(TAG_SOURCERPM, 0); | 393 | source_rpm = rpm_getstr0(TAG_SOURCERPM); |
332 | 394 | ||
333 | if (func & rpm_install) { | 395 | if (func & rpm_install) { |
396 | /* -i (and not -qi) */ | ||
397 | |||
334 | /* Backup any config files */ | 398 | /* Backup any config files */ |
335 | loop_through_files(TAG_BASENAMES, fileaction_dobackup); | 399 | loop_through_files(TAG_BASENAMES, fileaction_dobackup); |
336 | /* Extact the archive */ | 400 | /* Extact the archive */ |
@@ -338,10 +402,13 @@ int rpm_main(int argc, char **argv) | |||
338 | /* Set the correct file uid/gid's */ | 402 | /* Set the correct file uid/gid's */ |
339 | loop_through_files(TAG_BASENAMES, fileaction_setowngrp); | 403 | loop_through_files(TAG_BASENAMES, fileaction_setowngrp); |
340 | } | 404 | } |
341 | else if ((func & (rpm_query|rpm_query_package)) == (rpm_query|rpm_query_package)) { | 405 | else |
406 | if ((func & (rpm_query|rpm_query_package)) == (rpm_query|rpm_query_package)) { | ||
407 | /* -qp */ | ||
408 | |||
342 | if (!(func & (rpm_query_info|rpm_query_list))) { | 409 | if (!(func & (rpm_query_info|rpm_query_list))) { |
343 | /* If just a straight query, just give package name */ | 410 | /* If just a straight query, just give package name */ |
344 | printf("%s-%s-%s\n", rpm_getstr(TAG_NAME, 0), rpm_getstr(TAG_VERSION, 0), rpm_getstr(TAG_RELEASE, 0)); | 411 | printf("%s-%s-%s\n", rpm_getstr0(TAG_NAME), rpm_getstr0(TAG_VERSION), rpm_getstr0(TAG_RELEASE)); |
345 | } | 412 | } |
346 | if (func & rpm_query_info) { | 413 | if (func & rpm_query_info) { |
347 | /* Do the nice printout */ | 414 | /* Do the nice printout */ |
@@ -350,30 +417,33 @@ int rpm_main(int argc, char **argv) | |||
350 | char bdatestring[50]; | 417 | char bdatestring[50]; |
351 | const char *p; | 418 | const char *p; |
352 | 419 | ||
353 | printf("%-12s: %s\n", "Name" , rpm_getstr(TAG_NAME, 0)); | 420 | printf("%-12s: %s\n", "Name" , rpm_getstr0(TAG_NAME)); |
354 | /* TODO compat: add "Epoch" here */ | 421 | /* TODO compat: add "Epoch" here */ |
355 | printf("%-12s: %s\n", "Version" , rpm_getstr(TAG_VERSION, 0)); | 422 | printf("%-12s: %s\n", "Version" , rpm_getstr0(TAG_VERSION)); |
356 | printf("%-12s: %s\n", "Release" , rpm_getstr(TAG_RELEASE, 0)); | 423 | printf("%-12s: %s\n", "Release" , rpm_getstr0(TAG_RELEASE)); |
357 | /* add "Architecture" */ | 424 | /* add "Architecture" */ |
358 | printf("%-12s: %s\n", "Install Date", "(not installed)"); | 425 | /* printf("%-12s: %s\n", "Install Date", "(not installed)"); - we don't know */ |
359 | printf("%-12s: %s\n", "Group" , rpm_getstr(TAG_GROUP, 0)); | 426 | printf("%-12s: %s\n", "Group" , rpm_getstr0(TAG_GROUP)); |
360 | printf("%-12s: %d\n", "Size" , rpm_getint(TAG_SIZE, 0)); | 427 | printf("%-12s: %d\n", "Size" , rpm_getint(TAG_SIZE, 0)); |
361 | printf("%-12s: %s\n", "License" , rpm_getstr(TAG_LICENSE, 0)); | 428 | printf("%-12s: %s\n", "License" , rpm_getstr0(TAG_LICENSE)); |
362 | /* add "Signature" */ | 429 | /* add "Signature" */ |
363 | printf("%-12s: %s\n", "Source RPM" , source_rpm ? source_rpm : "(none)"); | 430 | printf("%-12s: %s\n", "Source RPM" , source_rpm ? source_rpm : "(none)"); |
364 | bdate_time = rpm_getint(TAG_BUILDTIME, 0); | 431 | bdate_time = rpm_getint(TAG_BUILDTIME, 0); |
365 | bdate_ptm = localtime(&bdate_time); | 432 | bdate_ptm = localtime(&bdate_time); |
366 | strftime(bdatestring, 50, "%a %d %b %Y %T %Z", bdate_ptm); | 433 | strftime(bdatestring, 50, "%a %d %b %Y %T %Z", bdate_ptm); |
367 | printf("%-12s: %s\n", "Build Date" , bdatestring); | 434 | printf("%-12s: %s\n", "Build Date" , bdatestring); |
368 | printf("%-12s: %s\n", "Build Host" , rpm_getstr(TAG_BUILDHOST, 0)); | 435 | printf("%-12s: %s\n", "Build Host" , rpm_getstr0(TAG_BUILDHOST)); |
369 | p = rpm_getstr(TAG_PREFIXS, 0); | 436 | p = rpm_getstr0(TAG_PREFIXS); |
370 | printf("%-12s: %s\n", "Relocations" , p ? p : "(not relocatable)"); | 437 | printf("%-12s: %s\n", "Relocations" , p ? p : "(not relocatable)"); |
371 | /* add "Packager" */ | 438 | /* add "Packager" */ |
372 | p = rpm_getstr(TAG_VENDOR, 0); | 439 | p = rpm_getstr0(TAG_VENDOR); |
373 | printf("%-12s: %s\n", "Vendor" , p ? p : "(none)"); | 440 | if (p) /* rpm 4.13.0.1 does not show "(none)" for Vendor: */ |
374 | printf("%-12s: %s\n", "URL" , rpm_getstr(TAG_URL, 0)); | 441 | printf("%-12s: %s\n", "Vendor" , p); |
375 | printf("%-12s: %s\n", "Summary" , rpm_getstr(TAG_SUMMARY, 0)); | 442 | p = rpm_getstr0(TAG_URL); |
376 | printf("Description :\n%s\n", rpm_getstr(TAG_DESCRIPTION, 0)); | 443 | if (p) /* rpm 4.13.0.1 does not show "(none)"/"(null)" for URL: */ |
444 | printf("%-12s: %s\n", "URL" , p); | ||
445 | printf("%-12s: %s\n", "Summary" , rpm_getstr0(TAG_SUMMARY)); | ||
446 | printf("Description :\n%s\n", rpm_getstr0(TAG_DESCRIPTION)); | ||
377 | } | 447 | } |
378 | if (func & rpm_query_list) { | 448 | if (func & rpm_query_list) { |
379 | int count, it, flags; | 449 | int count, it, flags; |
@@ -396,10 +466,16 @@ int rpm_main(int argc, char **argv) | |||
396 | rpm_getstr(TAG_BASENAMES, it)); | 466 | rpm_getstr(TAG_BASENAMES, it)); |
397 | } | 467 | } |
398 | } | 468 | } |
469 | } else { | ||
470 | /* Unsupported (help text shows what we support) */ | ||
471 | bb_show_usage(); | ||
399 | } | 472 | } |
400 | munmap(G.map, mapsize); | 473 | if (!*++argv) |
474 | break; | ||
475 | munmap(G.map, G.mapsize); | ||
401 | free(G.mytags); | 476 | free(G.mytags); |
402 | close(rpm_fd); | 477 | close(rpm_fd); |
403 | } | 478 | } |
479 | |||
404 | return 0; | 480 | return 0; |
405 | } | 481 | } |
diff --git a/archival/rpm2cpio.c b/archival/rpm2cpio.c index 3e4a6a249..a6db19c13 100644 --- a/archival/rpm2cpio.c +++ b/archival/rpm2cpio.c | |||
@@ -75,11 +75,14 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) | |||
75 | /* Skip the main header */ | 75 | /* Skip the main header */ |
76 | skip_header(); | 76 | skip_header(); |
77 | 77 | ||
78 | //if (SEAMLESS_COMPRESSION) | 78 | //if (SEAMLESS_COMPRESSION) - we do this at the end instead. |
79 | // /* We need to know whether child (gzip/bzip/etc) exits abnormally */ | 79 | // /* We need to know whether child (gzip/bzip/etc) exits abnormally */ |
80 | // signal(SIGCHLD, check_errors_in_children); | 80 | // signal(SIGCHLD, check_errors_in_children); |
81 | 81 | ||
82 | /* This works, but doesn't report uncompress errors (they happen in child) */ | 82 | //TODO: look for rpm tag RPMTAG_PAYLOADCOMPRESSOR (dec 1125, hex 0x465), |
83 | // if the value is "lzma", set up decompressor without detection | ||
84 | // (lzma can't be detected). | ||
85 | |||
83 | setup_unzip_on_fd(rpm_fd, /*fail_if_not_compressed:*/ 1); | 86 | setup_unzip_on_fd(rpm_fd, /*fail_if_not_compressed:*/ 1); |
84 | if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0) | 87 | if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0) |
85 | bb_error_msg_and_die("error unpacking"); | 88 | bb_error_msg_and_die("error unpacking"); |