Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/archival/rpm.c


Ignore:
Timestamp:
Nov 6, 2007, 11:01:53 AM (16 years ago)
Author:
Bruno Cornec
Message:
  • Better output for mindi-busybox revision
  • Remove dummy file created on NFS - report from Arnaud Tiger <arnaud.tiger_at_hp.com>
  • strace useful for debug
  • fix new versions for pb (2.0.0 for mindi and 1.7.2 for mindi-busybox)
  • fix build process for mindi-busybox + options used in that version (dd for label-partitions-as-necessary)
  • fix typo in label-partitions-as-necessary which doesn't seem to work
  • Update to busybox 1.7.2
  • perl is now required at restore time to support uuid swap partitions (and will be used for many other thigs

in the future for sure)

  • next mindi version will be 2.0.0 due to all the changes made in it (udev may break working distros)
  • small optimization in mindi on keyboard handling (one single find instead of multiple)
  • better interaction for USB device when launching mindi manually
  • attempt to automatically guess block disk size for ramdisk
  • fix typos in bkphw
  • Fix the remaining problem with UUID support for swap partitions
  • Updates mondoarchive man page for USB support
  • Adds preliminary Hardware support to mindi (Proliant SSSTK)
  • Tries to add udev support also for rhel4
  • Fix UUID support which was still broken.
  • Be conservative in test for the start-nfs script
  • Update config file for mindi-busybox for 1.7.2 migration
  • Try to run around a busybox bug (1.2.2 pb on inexistant links)
  • Add build content for mindi-busybox in pb
  • Remove distributions content for mindi-busybox
  • Fix a warning on inexistant raidtab
  • Solve problem on tmpfs in restore init (Problem of inexistant symlink and busybox)
  • Create MONDO_CACHE and use it everywhere + creation at start
  • Really never try to eject a USB device
  • Fix a issue with &> usage (replaced with 1> and 2>)
  • Adds magic file to depllist in order to have file working + ldd which helps for debugging issues
  • tty modes correct to avoid sh error messages
  • Use ext3 normally and not ext2 instead
  • USB device should be corrected after reading (take 1st part)
  • Adds a mount_USB_here function derived from mount_CDROM_here
  • usb detection place before /dev detection in device name at restore time
  • Fix when restoring from USB: media is asked in interactive mode
  • Adds USB support for mondorestore
  • mount_cdrom => mount_media
  • elilo.efi is now searched throughout /boot/efi and not in a fixed place as there is no standard
  • untar-and-softlink => untar (+ interface change)
  • suppress useless softlinks creation/removal in boot process
  • avoids udevd messages on groups
  • Increase # of disks to 99 as in mindi at restore time (should be a conf file parameter)
  • skip existing big file creation
  • seems to work correctly for USB mindi boot
  • Adds group and tty link to udev conf
  • Always load usb-torage (even 2.6) to initiate USB bus discovery
  • Better printing of messages
  • Attempt to fix a bug in supporting OpenSusE 10.3 kernel for initramfs (mindi may now use multiple regex for kernel initrd detection)
  • Links were not correctly done as non relative for modules in mindi
  • exclusion of modules denied now works
  • Also create modules in their ordinary place, so that classical modprobe works + copy modules.dep
  • Fix bugs for DENY_MODS handling
  • Add device /dev/console for udev
  • ide-generic should now really be excluded
  • Fix a bug in major number for tty
  • If udev then adds modprobe/insmod to rootfs
  • tty0 is also cretaed with udev
  • ide-generic put rather in DENY_MODS
  • udevd remove from deplist s handled in mindi directly
  • better default for mindi when using --usb
  • Handles dynamically linked busybox (in case we want to use it soon ;-)
  • Adds fixed devices to create for udev
  • ide-generic should not be part of the initrd when using libata v2
  • support a dynamically linked udev (case on Ubuntu 7.10 and Mandriva 2008.0 so should be quite generic) This will give incitation to move to dyn. linked binaries in the initrd which will help for other tasks (ia6 4)
  • Improvement in udev support (do not use cl options not available in busybox)
  • Udev in mindi
    • auto creation of the right links at boot time with udev-links.conf(from Mandriva 2008.0)
    • rework startup of udev as current makes kernel crash (from Mandriva 2008.0)
    • add support for 64 bits udev
  • Try to render MyInsmod silent at boot time
  • Adds udev support (mandatory for newest distributions to avoid remapping of devices in a different way as on the original system)
  • We also need vaft format support for USB boot
  • Adds libusual support (Ubuntu 7.10 needs it for USB)
  • Improve Ubuntu/Debian keyboard detection and support
  • pbinit adapted to new pb (0.8.10). Filtering of docs done in it
  • Suppress some mondo warnings and errors on USB again
  • Tries to fix lack of files in deb mindi package
  • Verify should now work for USB devices
  • More log/mesages improvement for USB support
  • - Supress g_erase_tmpdir_and_scratchdir
  • Improve some log messages for USB support
  • Try to improve install in mindi to avoid issues with isolinux.cfg not installed vene if in the pkg :-(
  • Improve mindi-busybox build
  • In conformity with pb 0.8.9
  • Add support for Ubuntu 7.10 in build process
  • Add USB Key button to Menu UI (CD streamer removed)
  • Attempt to fix error messages on tmp/scratch files at the end by removing those dir at the latest possible.
  • Fix a bug linked to the size of the -E param which could be used (Arnaud Tiger/René Ribaud).
  • Integrate ~/.pbrc content into mondorescue.pb (required project-builder >= 0.8.7)
  • Put mondorescue in conformity with new pb filtering rules
  • Add USB support at restore time (no test done yet). New start-usb script PB varibale added where useful
  • Unmounting USB device before removal of temporary scratchdir
  • Stil refining USB copy back to mondo (one command was not executed)
  • No need to have the image subdor in the csratchdir when USB.
  • umount the USB partition before attempting to use it
  • Remove useless copy from mindi to mondo at end of USB handling

(risky merge, we are raising the limits of 2 diverging branches. The status of stable is not completely sure as such. Will need lots of tests, but it's not yet done :-()
(merge -r1692:1769 $SVN_M/branches/2.2.5)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/stable/mindi-busybox/archival/rpm.c

    r821 r1770  
    88 */
    99
    10 #include <stdio.h>
    11 #include <unistd.h>
    12 #include <signal.h>
    13 #include <stdlib.h>
    14 #include <fcntl.h>
    15 #include <netinet/in.h> /* For ntohl & htonl function */
    16 #include <string.h> /* For strncmp */
    17 #include <sys/mman.h> /* For mmap */
    18 #include <time.h> /* For ctime */
    19 
    20 #include "busybox.h"
     10#include "libbb.h"
    2111#include "unarchive.h"
    2212
    23 #define RPM_HEADER_MAGIC "\216\255\350"
    24 #define RPM_CHAR_TYPE       1
    25 #define RPM_INT8_TYPE       2
    26 #define RPM_INT16_TYPE      3
    27 #define RPM_INT32_TYPE      4
    28 /* #define RPM_INT64_TYPE   5   ---- These aren't supported (yet) */
    29 #define RPM_STRING_TYPE     6
    30 #define RPM_BIN_TYPE        7
    31 #define RPM_STRING_ARRAY_TYPE   8
    32 #define RPM_I18NSTRING_TYPE 9
    33 
    34 #define RPMTAG_NAME             1000
    35 #define RPMTAG_VERSION          1001
    36 #define RPMTAG_RELEASE          1002
    37 #define RPMTAG_SUMMARY          1004
    38 #define RPMTAG_DESCRIPTION      1005
    39 #define RPMTAG_BUILDTIME        1006
    40 #define RPMTAG_BUILDHOST        1007
    41 #define RPMTAG_SIZE         1009
    42 #define RPMTAG_VENDOR           1011
    43 #define RPMTAG_LICENSE          1014
    44 #define RPMTAG_PACKAGER         1015
    45 #define RPMTAG_GROUP            1016
    46 #define RPMTAG_URL          1020
    47 #define RPMTAG_PREIN            1023
    48 #define RPMTAG_POSTIN           1024
    49 #define RPMTAG_FILEFLAGS        1037
    50 #define RPMTAG_FILEUSERNAME     1039
    51 #define RPMTAG_FILEGROUPNAME        1040
    52 #define RPMTAG_SOURCERPM        1044
    53 #define RPMTAG_PREINPROG        1085
    54 #define RPMTAG_POSTINPROG       1086
    55 #define RPMTAG_PREFIXS          1098
    56 #define RPMTAG_DIRINDEXES       1116
    57 #define RPMTAG_BASENAMES        1117
    58 #define RPMTAG_DIRNAMES         1118
    59 #define RPMFILE_CONFIG          (1 << 0)
    60 #define RPMFILE_DOC         (1 << 1)
     13#define RPM_HEADER_MAGIC        "\216\255\350"
     14#define RPM_CHAR_TYPE           1
     15#define RPM_INT8_TYPE           2
     16#define RPM_INT16_TYPE          3
     17#define RPM_INT32_TYPE          4
     18/* #define RPM_INT64_TYPE       5   ---- These aren't supported (yet) */
     19#define RPM_STRING_TYPE         6
     20#define RPM_BIN_TYPE            7
     21#define RPM_STRING_ARRAY_TYPE   8
     22#define RPM_I18NSTRING_TYPE     9
     23
     24#define TAG_NAME                1000
     25#define TAG_VERSION             1001
     26#define TAG_RELEASE             1002
     27#define TAG_SUMMARY             1004
     28#define TAG_DESCRIPTION         1005
     29#define TAG_BUILDTIME           1006
     30#define TAG_BUILDHOST           1007
     31#define TAG_SIZE                1009
     32#define TAG_VENDOR              1011
     33#define TAG_LICENSE             1014
     34#define TAG_PACKAGER            1015
     35#define TAG_GROUP               1016
     36#define TAG_URL                 1020
     37#define TAG_PREIN               1023
     38#define TAG_POSTIN              1024
     39#define TAG_FILEFLAGS           1037
     40#define TAG_FILEUSERNAME        1039
     41#define TAG_FILEGROUPNAME       1040
     42#define TAG_SOURCERPM           1044
     43#define TAG_PREINPROG           1085
     44#define TAG_POSTINPROG          1086
     45#define TAG_PREFIXS             1098
     46#define TAG_DIRINDEXES          1116
     47#define TAG_BASENAMES           1117
     48#define TAG_DIRNAMES            1118
     49#define RPMFILE_CONFIG          (1 << 0)
     50#define RPMFILE_DOC             (1 << 1)
    6151
    6252enum rpm_functions_e {
     
    8171static int tagcount;
    8272
    83 void extract_cpio_gz(int fd);
    84 rpm_index **rpm_gettags(int fd, int *num_tags);
    85 int bsearch_rpmtag(const void *key, const void *item);
    86 char *rpm_getstring(int tag, int itemindex);
    87 int rpm_getint(int tag, int itemindex);
    88 int rpm_getcount(int tag);
    89 void exec_script(int progtag, int datatag, char *prefix);
    90 void fileaction_dobackup(char *filename, int fileref);
    91 void fileaction_setowngrp(char *filename, int fileref);
    92 void fileaction_list(char *filename, int itemno);
    93 void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref));
    94 
     73static void extract_cpio_gz(int fd);
     74static rpm_index **rpm_gettags(int fd, int *num_tags);
     75static int bsearch_rpmtag(const void *key, const void *item);
     76static char *rpm_getstr(int tag, int itemindex);
     77static int rpm_getint(int tag, int itemindex);
     78static int rpm_getcount(int tag);
     79static void fileaction_dobackup(char *filename, int fileref);
     80static void fileaction_setowngrp(char *filename, int fileref);
     81static void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref));
     82
     83int rpm_main(int argc, char **argv);
    9584int rpm_main(int argc, char **argv)
    9685{
    9786    int opt = 0, func = 0, rpm_fd, offset;
     87    const int pagesize = getpagesize();
    9888
    9989    while ((opt = getopt(argc, argv, "iqpldc")) != -1) {
    10090        switch (opt) {
    101         case 'i': // First arg: Install mode, with q: Information
    102             if (!func) func |= rpm_install;
     91        case 'i': /* First arg: Install mode, with q: Information */
     92            if (!func) func = rpm_install;
    10393            else func |= rpm_query_info;
    10494            break;
    105         case 'q': // First arg: Query mode
    106             if (!func) func |= rpm_query;
    107             else bb_show_usage();
    108             break;
    109         case 'p': // Query a package
     95        case 'q': /* First arg: Query mode */
     96            if (func) bb_show_usage();
     97            func = rpm_query;
     98            break;
     99        case 'p': /* Query a package */
    110100            func |= rpm_query_package;
    111101            break;
    112         case 'l': // List files in a package
     102        case 'l': /* List files in a package */
    113103            func |= rpm_query_list;
    114104            break;
    115         case 'd': // List doc files in a package (implies list)
     105        case 'd': /* List doc files in a package (implies list) */
    116106            func |= rpm_query_list;
    117107            func |= rpm_query_list_doc;
    118108            break;
    119         case 'c': // List config files in a package (implies list)
     109        case 'c': /* List config files in a package (implies list) */
    120110            func |= rpm_query_list;
    121111            func |= rpm_query_list_config;
     
    125115        }
    126116    }
    127 
    128     if (optind == argc) bb_show_usage();
    129     while (optind < argc) {
    130         rpm_fd = bb_xopen(argv[optind], O_RDONLY);
    131         mytags = rpm_gettags(rpm_fd, (int *) &tagcount);
    132         offset = lseek(rpm_fd, 0, SEEK_CUR);
    133         if (!mytags) { printf("Error reading rpm header\n"); exit(-1); }
    134         map = mmap(0, offset > getpagesize() ? (offset + offset % getpagesize()) : getpagesize(), PROT_READ, MAP_PRIVATE, rpm_fd, 0); // Mimimum is one page
     117    argv += optind;
     118    argc -= optind;
     119    if (!argc) bb_show_usage();
     120
     121    while (*argv) {
     122        rpm_fd = xopen(*argv++, O_RDONLY);
     123        mytags = rpm_gettags(rpm_fd, &tagcount);
     124        if (!mytags)
     125            bb_error_msg_and_die("error reading rpm header");
     126        offset = xlseek(rpm_fd, 0, SEEK_CUR);
     127        /* Mimimum is one page */
     128        map = mmap(0, offset > pagesize ? (offset + offset % pagesize) : pagesize, PROT_READ, MAP_PRIVATE, rpm_fd, 0);
     129
    135130        if (func & rpm_install) {
    136             loop_through_files(RPMTAG_BASENAMES, fileaction_dobackup); /* Backup any config files */
    137             extract_cpio_gz(rpm_fd); // Extact the archive
    138             loop_through_files(RPMTAG_BASENAMES, fileaction_setowngrp); /* Set the correct file uid/gid's */
    139         } else if (func & rpm_query && func & rpm_query_package) {
    140             if (!((func & rpm_query_info) || (func & rpm_query_list))) { // If just a straight query, just give package name
    141                 printf("%s-%s-%s\n", rpm_getstring(RPMTAG_NAME, 0), rpm_getstring(RPMTAG_VERSION, 0), rpm_getstring(RPMTAG_RELEASE, 0));
     131            /* Backup any config files */
     132            loop_through_files(TAG_BASENAMES, fileaction_dobackup);
     133            /* Extact the archive */
     134            extract_cpio_gz(rpm_fd);
     135            /* Set the correct file uid/gid's */
     136            loop_through_files(TAG_BASENAMES, fileaction_setowngrp);
     137        }
     138        else if ((func & (rpm_query|rpm_query_package)) == (rpm_query|rpm_query_package)) {
     139            if (!(func & (rpm_query_info|rpm_query_list))) {
     140                /* If just a straight query, just give package name */
     141                printf("%s-%s-%s\n", rpm_getstr(TAG_NAME, 0), rpm_getstr(TAG_VERSION, 0), rpm_getstr(TAG_RELEASE, 0));
    142142            }
    143143            if (func & rpm_query_info) {
     
    146146                struct tm *bdate;
    147147                char bdatestring[50];
    148                 printf("Name        : %-29sRelocations: %s\n", rpm_getstring(RPMTAG_NAME, 0), rpm_getstring(RPMTAG_PREFIXS, 0) ? rpm_getstring(RPMTAG_PREFIXS, 0) : "(not relocateable)");
    149                 printf("Version     : %-34sVendor: %s\n", rpm_getstring(RPMTAG_VERSION, 0), rpm_getstring(RPMTAG_VENDOR, 0) ? rpm_getstring(RPMTAG_VENDOR, 0) : "(none)");
    150                 bdate_time = rpm_getint(RPMTAG_BUILDTIME, 0);
     148                printf("Name        : %-29sRelocations: %s\n", rpm_getstr(TAG_NAME, 0), rpm_getstr(TAG_PREFIXS, 0) ? rpm_getstr(TAG_PREFIXS, 0) : "(not relocateable)");
     149                printf("Version     : %-34sVendor: %s\n", rpm_getstr(TAG_VERSION, 0), rpm_getstr(TAG_VENDOR, 0) ? rpm_getstr(TAG_VENDOR, 0) : "(none)");
     150                bdate_time = rpm_getint(TAG_BUILDTIME, 0);
    151151                bdate = localtime((time_t *) &bdate_time);
    152152                strftime(bdatestring, 50, "%a %d %b %Y %T %Z", bdate);
    153                 printf("Release     : %-30sBuild Date: %s\n", rpm_getstring(RPMTAG_RELEASE, 0), bdatestring);
    154                 printf("Install date: %-30sBuild Host: %s\n", "(not installed)", rpm_getstring(RPMTAG_BUILDHOST, 0));
    155                 printf("Group       : %-30sSource RPM: %s\n", rpm_getstring(RPMTAG_GROUP, 0), rpm_getstring(RPMTAG_SOURCERPM, 0));
    156                 printf("Size        : %-33dLicense: %s\n", rpm_getint(RPMTAG_SIZE, 0), rpm_getstring(RPMTAG_LICENSE, 0));
    157                 printf("URL         : %s\n", rpm_getstring(RPMTAG_URL, 0));
    158                 printf("Summary     : %s\n", rpm_getstring(RPMTAG_SUMMARY, 0));
    159                 printf("Description :\n%s\n", rpm_getstring(RPMTAG_DESCRIPTION, 0));
     153                printf("Release     : %-30sBuild Date: %s\n", rpm_getstr(TAG_RELEASE, 0), bdatestring);
     154                printf("Install date: %-30sBuild Host: %s\n", "(not installed)", rpm_getstr(TAG_BUILDHOST, 0));
     155                printf("Group       : %-30sSource RPM: %s\n", rpm_getstr(TAG_GROUP, 0), rpm_getstr(TAG_SOURCERPM, 0));
     156                printf("Size        : %-33dLicense: %s\n", rpm_getint(TAG_SIZE, 0), rpm_getstr(TAG_LICENSE, 0));
     157                printf("URL         : %s\n", rpm_getstr(TAG_URL, 0));
     158                printf("Summary     : %s\n", rpm_getstr(TAG_SUMMARY, 0));
     159                printf("Description :\n%s\n", rpm_getstr(TAG_DESCRIPTION, 0));
    160160            }
    161161            if (func & rpm_query_list) {
    162162                int count, it, flags;
    163                 count = rpm_getcount(RPMTAG_BASENAMES);
     163                count = rpm_getcount(TAG_BASENAMES);
    164164                for (it = 0; it < count; it++) {
    165                     flags = rpm_getint(RPMTAG_FILEFLAGS, it);
    166                     switch ((func & rpm_query_list_doc) + (func & rpm_query_list_config))
    167                     {
    168                         case rpm_query_list_doc: if (!(flags & RPMFILE_DOC)) continue; break;
    169                         case rpm_query_list_config: if (!(flags & RPMFILE_CONFIG)) continue; break;
    170                         case rpm_query_list_doc + rpm_query_list_config: if (!((flags & RPMFILE_CONFIG) || (flags & RPMFILE_DOC))) continue; break;
     165                    flags = rpm_getint(TAG_FILEFLAGS, it);
     166                    switch (func & (rpm_query_list_doc|rpm_query_list_config)) {
     167                    case rpm_query_list_doc:
     168                        if (!(flags & RPMFILE_DOC)) continue;
     169                        break;
     170                    case rpm_query_list_config:
     171                        if (!(flags & RPMFILE_CONFIG)) continue;
     172                        break;
     173                    case rpm_query_list_doc|rpm_query_list_config:
     174                        if (!(flags & (RPMFILE_CONFIG|RPMFILE_DOC))) continue;
     175                        break;
    171176                    }
    172                     printf("%s%s\n", rpm_getstring(RPMTAG_DIRNAMES, rpm_getint(RPMTAG_DIRINDEXES, it)), rpm_getstring(RPMTAG_BASENAMES, it));
     177                    printf("%s%s\n",
     178                        rpm_getstr(TAG_DIRNAMES, rpm_getint(TAG_DIRINDEXES, it)),
     179                        rpm_getstr(TAG_BASENAMES, it));
    173180                }
    174181            }
    175182        }
    176         optind++;
    177         free (mytags);
     183        free(mytags);
    178184    }
    179185    return 0;
    180186}
    181187
    182 void extract_cpio_gz(int fd) {
     188static void extract_cpio_gz(int fd)
     189{
    183190    archive_handle_t *archive_handle;
    184191    unsigned char magic[2];
    185 
    186     /* Initialise */
     192#if BB_MMU
     193    USE_DESKTOP(long long) int (*xformer)(int src_fd, int dst_fd);
     194    enum { xformer_prog = 0 };
     195#else
     196    enum { xformer = 0 };
     197    const char *xformer_prog;
     198#endif
     199
     200    /* Initialize */
    187201    archive_handle = init_handle();
    188     archive_handle->seek = seek_by_char;
     202    archive_handle->seek = seek_by_read;
    189203    //archive_handle->action_header = header_list;
    190204    archive_handle->action_data = data_extract_all;
     
    194208    archive_handle->offset = 0;
    195209
    196     bb_xread_all(archive_handle->src_fd, &magic, 2);
     210    xread(archive_handle->src_fd, &magic, 2);
     211#if BB_MMU
     212    xformer = unpack_gz_stream;
     213#else
     214    xformer_prog = "gunzip";
     215#endif
    197216    if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) {
    198         bb_error_msg_and_die("Invalid gzip magic");
    199     }
    200     check_header_gzip(archive_handle->src_fd);
    201     bb_xchdir("/"); // Install RPM's to root
    202 
    203     archive_handle->src_fd = open_transformer(archive_handle->src_fd, inflate_gunzip);
     217        if (ENABLE_FEATURE_RPM_BZ2
     218         && (magic[0] == 0x42) && (magic[1] == 0x5a)) {
     219#if BB_MMU
     220            xformer = unpack_bz2_stream;
     221#else
     222            xformer_prog = "bunzip2";
     223#endif
     224    /* We can do better, need modifying unpack_bz2_stream to not require
     225     * first 2 bytes. Not very hard to do... I mean, TODO :) */
     226            xlseek(archive_handle->src_fd, -2, SEEK_CUR);
     227        } else
     228            bb_error_msg_and_die("no gzip"
     229                USE_FEATURE_RPM_BZ2("/bzip")
     230                " magic");
     231    } else {
     232        check_header_gzip_or_die(archive_handle->src_fd);
     233#if !BB_MMU
     234        /* NOMMU version of open_transformer execs an external unzipper that should
     235         * have the file position at the start of the file */
     236        xlseek(archive_handle->src_fd, 0, SEEK_SET);
     237#endif
     238    }
     239
     240    xchdir("/"); /* Install RPM's to root */
     241    archive_handle->src_fd = open_transformer(archive_handle->src_fd, xformer, xformer_prog, xformer_prog, "-cf", "-", NULL);
    204242    archive_handle->offset = 0;
    205     while (get_header_cpio(archive_handle) == EXIT_SUCCESS);
    206 }
    207 
    208 
    209 rpm_index **rpm_gettags(int fd, int *num_tags)
    210 {
    211     rpm_index **tags = xzalloc(200 * sizeof(struct rpmtag *)); /* We should never need mode than 200, and realloc later */
     243    while (get_header_cpio(archive_handle) == EXIT_SUCCESS)
     244        continue;
     245}
     246
     247
     248static rpm_index **rpm_gettags(int fd, int *num_tags)
     249{
     250    /* We should never need mode than 200, and realloc later */
     251    rpm_index **tags = xzalloc(200 * sizeof(struct rpmtag *));
    212252    int pass, tagindex = 0;
    213     lseek(fd, 96, SEEK_CUR); /* Seek past the unused lead */
    214 
    215     for (pass = 0; pass < 2; pass++) { /* 1st pass is the signature headers, 2nd is the main stuff */
     253
     254    xlseek(fd, 96, SEEK_CUR); /* Seek past the unused lead */
     255
     256    /* 1st pass is the signature headers, 2nd is the main stuff */
     257    for (pass = 0; pass < 2; pass++) {
    216258        struct {
    217259            char magic[3]; /* 3 byte magic: 0x8e 0xad 0xe8 */
     
    224266        int storepos;
    225267
    226         read(fd, &header, sizeof(header));
    227         if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC, 3) != 0) return NULL; /* Invalid magic */
    228         if (header.version != 1) return NULL; /* This program only supports v1 headers */
     268        xread(fd, &header, sizeof(header));
     269        if (strncmp((char *) &header.magic, RPM_HEADER_MAGIC, 3) != 0)
     270            return NULL; /* Invalid magic */
     271        if (header.version != 1)
     272            return NULL; /* This program only supports v1 headers */
    229273        header.size = ntohl(header.size);
    230274        header.entries = ntohl(header.entries);
    231         storepos = lseek(fd,0,SEEK_CUR) + header.entries * 16;
     275        storepos = xlseek(fd,0,SEEK_CUR) + header.entries * 16;
    232276
    233277        while (header.entries--) {
    234278            tmpindex = tags[tagindex++] = xmalloc(sizeof(rpm_index));
    235             read(fd, tmpindex, sizeof(rpm_index));
    236             tmpindex->tag = ntohl(tmpindex->tag); tmpindex->type = ntohl(tmpindex->type); tmpindex->count = ntohl(tmpindex->count);
     279            xread(fd, tmpindex, sizeof(rpm_index));
     280            tmpindex->tag = ntohl(tmpindex->tag);
     281            tmpindex->type = ntohl(tmpindex->type);
     282            tmpindex->count = ntohl(tmpindex->count);
    237283            tmpindex->offset = storepos + ntohl(tmpindex->offset);
    238             if (pass==0) tmpindex->tag -= 743;
    239         }
    240         lseek(fd, header.size, SEEK_CUR); /* Seek past store */
    241         if (pass==0) lseek(fd, (8 - (lseek(fd,0,SEEK_CUR) % 8)) % 8, SEEK_CUR); /* Skip padding to 8 byte boundary after reading signature headers */
    242     }
    243     tags = realloc(tags, tagindex * sizeof(struct rpmtag *)); /* realloc tags to save space */
     284            if (pass==0)
     285                tmpindex->tag -= 743;
     286        }
     287        xlseek(fd, header.size, SEEK_CUR); /* Seek past store */
     288        /* Skip padding to 8 byte boundary after reading signature headers */
     289        if (pass==0)
     290            xlseek(fd, (8 - (xlseek(fd,0,SEEK_CUR) % 8)) % 8, SEEK_CUR);
     291    }
     292    tags = xrealloc(tags, tagindex * sizeof(struct rpmtag *)); /* realloc tags to save space */
    244293    *num_tags = tagindex;
    245294    return tags; /* All done, leave the file at the start of the gzipped cpio archive */
    246295}
    247296
    248 int bsearch_rpmtag(const void *key, const void *item)
     297static int bsearch_rpmtag(const void *key, const void *item)
    249298{
    250299    int *tag = (int *)key;
     
    253302}
    254303
    255 int rpm_getcount(int tag)
     304static int rpm_getcount(int tag)
    256305{
    257306    rpm_index **found;
    258307    found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
    259     if (!found) return 0;
    260     else return found[0]->count;
    261 }
    262 
    263 char *rpm_getstring(int tag, int itemindex)
     308    if (!found)
     309        return 0;
     310    return found[0]->count;
     311}
     312
     313static char *rpm_getstr(int tag, int itemindex)
    264314{
    265315    rpm_index **found;
    266316    found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
    267     if (!found || itemindex >= found[0]->count) return NULL;
     317    if (!found || itemindex >= found[0]->count)
     318        return NULL;
    268319    if (found[0]->type == RPM_STRING_TYPE || found[0]->type == RPM_I18NSTRING_TYPE || found[0]->type == RPM_STRING_ARRAY_TYPE) {
    269320        int n;
    270321        char *tmpstr = (char *) (map + found[0]->offset);
    271         for (n=0; n < itemindex; n++) tmpstr = tmpstr + strlen(tmpstr) + 1;
     322        for (n=0; n < itemindex; n++)
     323            tmpstr = tmpstr + strlen(tmpstr) + 1;
    272324        return tmpstr;
    273     } else return NULL;
    274 }
    275 
    276 int rpm_getint(int tag, int itemindex)
     325    }
     326    return NULL;
     327}
     328
     329static int rpm_getint(int tag, int itemindex)
    277330{
    278331    rpm_index **found;
    279     int n, *tmpint;
     332    int *tmpint; /* NB: using int8_t* would be easier to code */
     333
    280334    /* gcc throws warnings here when sizeof(void*)!=sizeof(int) ...
    281335     * it's ok to ignore it because tag won't be used as a pointer */
    282336    found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
    283     if (!found || itemindex >= found[0]->count) return -1;
     337    if (!found || itemindex >= found[0]->count)
     338        return -1;
     339
    284340    tmpint = (int *) (map + found[0]->offset);
     341
    285342    if (found[0]->type == RPM_INT32_TYPE) {
    286         for (n=0; n<itemindex; n++) tmpint = (int *) ((void *) tmpint + 4);
    287         return ntohl(*tmpint);
    288     } else if (found[0]->type == RPM_INT16_TYPE) {
    289         for (n=0; n<itemindex; n++) tmpint = (int *) ((void *) tmpint + 2);
    290         return ntohs(*tmpint);
    291     } else if (found[0]->type == RPM_INT8_TYPE) {
    292         for (n=0; n<itemindex; n++) tmpint = (int *) ((void *) tmpint + 1);
    293         return ntohs(*tmpint);
    294     } else return -1;
    295 }
    296 
    297 void fileaction_dobackup(char *filename, int fileref)
     343        tmpint = (int *) ((char *) tmpint + itemindex*4);
     344        /*return ntohl(*tmpint);*/
     345        /* int can be != int32_t */
     346        return ntohl(*(int32_t*)tmpint);
     347    }
     348    if (found[0]->type == RPM_INT16_TYPE) {
     349        tmpint = (int *) ((char *) tmpint + itemindex*2);
     350        /* ??? read int, and THEN ntohs() it?? */
     351        /*return ntohs(*tmpint);*/
     352        return ntohs(*(int16_t*)tmpint);
     353    }
     354    if (found[0]->type == RPM_INT8_TYPE) {
     355        tmpint = (int *) ((char *) tmpint + itemindex);
     356        /* ??? why we don't read byte here??? */
     357        /*return ntohs(*tmpint);*/
     358        return *(int8_t*)tmpint;
     359    }
     360    return -1;
     361}
     362
     363static void fileaction_dobackup(char *filename, int fileref)
    298364{
    299365    struct stat oldfile;
    300366    int stat_res;
    301367    char *newname;
    302     if (rpm_getint(RPMTAG_FILEFLAGS, fileref) & RPMFILE_CONFIG) { /* Only need to backup config files */
    303         stat_res = lstat (filename, &oldfile);
    304         if (stat_res == 0 && S_ISREG(oldfile.st_mode)) { /* File already exists  - really should check MD5's etc to see if different */
    305             newname = bb_xstrdup(filename);
    306             newname = strcat(newname, ".rpmorig");
     368    if (rpm_getint(TAG_FILEFLAGS, fileref) & RPMFILE_CONFIG) {
     369        /* Only need to backup config files */
     370        stat_res = lstat(filename, &oldfile);
     371        if (stat_res == 0 && S_ISREG(oldfile.st_mode)) {
     372            /* File already exists  - really should check MD5's etc to see if different */
     373            newname = xasprintf("%s.rpmorig", filename);
    307374            copy_file(filename, newname, FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS);
    308375            remove_file(filename, FILEUTILS_RECUR | FILEUTILS_FORCE);
     
    312379}
    313380
    314 void fileaction_setowngrp(char *filename, int fileref)
     381static void fileaction_setowngrp(char *filename, int fileref)
    315382{
    316383    int uid, gid;
    317     uid = bb_xgetpwnam(rpm_getstring(RPMTAG_FILEUSERNAME, fileref));
    318     gid = bb_xgetgrnam(rpm_getstring(RPMTAG_FILEGROUPNAME, fileref));
    319     chown (filename, uid, gid);
    320 }
    321 
    322 void fileaction_list(char *filename, int ATTRIBUTE_UNUSED fileref)
    323 {
    324     printf("%s\n", filename);
    325 }
    326 
    327 void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref))
     384    uid = xuname2uid(rpm_getstr(TAG_FILEUSERNAME, fileref));
     385    gid = xgroup2gid(rpm_getstr(TAG_FILEGROUPNAME, fileref));
     386    chown(filename, uid, gid);
     387}
     388
     389static void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref))
    328390{
    329391    int count = 0;
    330     while (rpm_getstring(filetag, count)) {
    331         char * filename = bb_xasprintf("%s%s",
    332             rpm_getstring(RPMTAG_DIRNAMES, rpm_getint(RPMTAG_DIRINDEXES,
    333             count)), rpm_getstring(RPMTAG_BASENAMES, count));
     392    while (rpm_getstr(filetag, count)) {
     393        char* filename = xasprintf("%s%s",
     394            rpm_getstr(TAG_DIRNAMES, rpm_getint(TAG_DIRINDEXES, count)),
     395            rpm_getstr(TAG_BASENAMES, count));
    334396        fileaction(filename, count++);
    335397        free(filename);
Note: See TracChangeset for help on using the changeset viewer.