Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

file 119 lines (103 sloc) 3.032 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
/* vi: set sw=4 ts=4: */
/*
* Mini rpm2cpio implementation for busybox
*
* Copyright (C) 2001 by Laurence Anderson
*
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
*/

//usage:#define rpm2cpio_trivial_usage
//usage: "package.rpm"
//usage:#define rpm2cpio_full_usage "\n\n"
//usage: "Output a cpio archive of the rpm file"

#include "libbb.h"
#include "archive.h"
#include "rpm.h"

enum { rpm_fd = STDIN_FILENO };

static unsigned skip_header(void)
{
struct rpm_header header;
unsigned len;

xread(rpm_fd, &header, sizeof(header));
// if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC_STR, 3) != 0) {
// bb_error_msg_and_die("invalid RPM header magic");
// }
// if (header.version != 1) {
// bb_error_msg_and_die("unsupported RPM header version");
// }
if (header.magic_and_ver != htonl(RPM_HEADER_MAGICnVER)) {
bb_error_msg_and_die("invalid RPM header magic or unsupported version");
// ": %x != %x", header.magic_and_ver, htonl(RPM_HEADER_MAGICnVER));
}

/* Seek past index entries, and past store */
len = 16 * ntohl(header.entries) + ntohl(header.size);
seek_by_jump(rpm_fd, len);

return sizeof(header) + len;
}

/* No getopt required */
int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int rpm2cpio_main(int argc UNUSED_PARAM, char **argv)
{
struct rpm_lead lead;
unsigned pos;

if (argv[1]) {
xmove_fd(xopen(argv[1], O_RDONLY), rpm_fd);
}
xread(rpm_fd, &lead, sizeof(lead));

/* Just check the magic, the rest is irrelevant */
if (lead.magic != htonl(RPM_LEAD_MAGIC)) {
bb_error_msg_and_die("invalid RPM magic");
}

/* Skip the signature header, align to 8 bytes */
pos = skip_header();
seek_by_jump(rpm_fd, (-(int)pos) & 7);

/* Skip the main header */
skip_header();

#if 0
/* This works, but doesn't report uncompress errors (they happen in child) */
setup_unzip_on_fd(rpm_fd /*fail_if_not_detected: 1*/);
if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0)
bb_error_msg_and_die("error unpacking");
#else
/* BLOAT */
{
union {
uint8_t b[4];
uint16_t b16[2];
uint32_t b32[1];
} magic;
IF_DESKTOP(long long) int FAST_FUNC (*unpack)(int src_fd, int dst_fd);

xread(rpm_fd, magic.b16, sizeof(magic.b16[0]));
if (magic.b16[0] == GZIP_MAGIC) {
unpack = unpack_gz_stream;
} else
if (ENABLE_FEATURE_SEAMLESS_BZ2
&& magic.b16[0] == BZIP2_MAGIC
) {
unpack = unpack_bz2_stream;
} else
if (ENABLE_FEATURE_SEAMLESS_XZ
&& magic.b16[0] == XZ_MAGIC1
) {
xread(rpm_fd, magic.b32, sizeof(magic.b32[0]));
if (magic.b32[0] != XZ_MAGIC2)
goto no_magic;
/* unpack_xz_stream wants fd at position 6, no need to seek */
//xlseek(rpm_fd, -6, SEEK_CUR);
unpack = unpack_xz_stream;
} else {
 no_magic:
bb_error_msg_and_die("no gzip"
IF_FEATURE_SEAMLESS_BZ2("/bzip2")
IF_FEATURE_SEAMLESS_XZ("/xz")
" magic");
}
if (unpack(rpm_fd, STDOUT_FILENO) < 0)
bb_error_msg_and_die("error unpacking");
}
#endif

if (ENABLE_FEATURE_CLEAN_UP) {
close(rpm_fd);
}

return 0;
}
Something went wrong with that request. Please try again.