busybox/archival/rpm2cpio.c
<<
>>
Prefs
   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#include "rpm.h"
  12
  13enum { rpm_fd = STDIN_FILENO };
  14
  15static unsigned skip_header(void)
  16{
  17        struct rpm_header header;
  18        unsigned len;
  19
  20        xread(rpm_fd, &header, sizeof(header));
  21//      if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC_STR, 3) != 0) {
  22//              bb_error_msg_and_die("invalid RPM header magic");
  23//      }
  24//      if (header.version != 1) {
  25//              bb_error_msg_and_die("unsupported RPM header version");
  26//      }
  27        if (header.magic_and_ver != htonl(RPM_HEADER_MAGICnVER)) {
  28                bb_error_msg_and_die("invalid RPM header magic or unsupported version");
  29                // ": %x != %x", header.magic_and_ver, htonl(RPM_HEADER_MAGICnVER));
  30        }
  31
  32        /* Seek past index entries, and past store */
  33        len = 16 * ntohl(header.entries) + ntohl(header.size);
  34        seek_by_jump(rpm_fd, len);
  35
  36        return sizeof(header) + len;
  37}
  38
  39/* No getopt required */
  40int rpm2cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  41int rpm2cpio_main(int argc UNUSED_PARAM, char **argv)
  42{
  43        struct rpm_lead lead;
  44        unsigned pos;
  45
  46        if (argv[1]) {
  47                xmove_fd(xopen(argv[1], O_RDONLY), rpm_fd);
  48        }
  49        xread(rpm_fd, &lead, sizeof(lead));
  50
  51        /* Just check the magic, the rest is irrelevant */
  52        if (lead.magic != htonl(RPM_LEAD_MAGIC)) {
  53                bb_error_msg_and_die("invalid RPM magic");
  54        }
  55
  56        /* Skip the signature header, align to 8 bytes */
  57        pos = skip_header();
  58        seek_by_jump(rpm_fd, (-(int)pos) & 7);
  59
  60        /* Skip the main header */
  61        skip_header();
  62
  63#if 0
  64        /* This works, but doesn't report uncompress errors (they happen in child) */
  65        setup_unzip_on_fd(rpm_fd /*fail_if_not_detected: 1*/);
  66        if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0)
  67                bb_error_msg_and_die("error unpacking");
  68#else
  69        /* BLOAT */
  70        {
  71                union {
  72                        uint8_t b[4];
  73                        uint16_t b16[2];
  74                        uint32_t b32[1];
  75                } magic;
  76                IF_DESKTOP(long long) int FAST_FUNC (*unpack)(int src_fd, int dst_fd);
  77
  78                xread(rpm_fd, magic.b16, sizeof(magic.b16[0]));
  79                if (magic.b16[0] == GZIP_MAGIC) {
  80                        unpack = unpack_gz_stream;
  81                } else
  82                if (ENABLE_FEATURE_SEAMLESS_BZ2
  83                 && magic.b16[0] == BZIP2_MAGIC
  84                ) {
  85                        unpack = unpack_bz2_stream;
  86                } else
  87                if (ENABLE_FEATURE_SEAMLESS_XZ
  88                 && magic.b16[0] == XZ_MAGIC1
  89                ) {
  90                        xread(rpm_fd, magic.b32, sizeof(magic.b32[0]));
  91                        if (magic.b32[0] != XZ_MAGIC2)
  92                                goto no_magic;
  93                        /* unpack_xz_stream wants fd at position 6, no need to seek */
  94                        //xlseek(rpm_fd, -6, SEEK_CUR);
  95                        unpack = unpack_xz_stream;
  96                } else {
  97 no_magic:
  98                        bb_error_msg_and_die("no gzip"
  99                                        IF_FEATURE_SEAMLESS_BZ2("/bzip2")
 100                                        IF_FEATURE_SEAMLESS_XZ("/xz")
 101                                        " magic");
 102                }
 103                if (unpack(rpm_fd, STDOUT_FILENO) < 0)
 104                        bb_error_msg_and_die("error unpacking");
 105        }
 106#endif
 107
 108        if (ENABLE_FEATURE_CLEAN_UP) {
 109                close(rpm_fd);
 110        }
 111
 112        return 0;
 113}
 114