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/dpkg.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    2  *  Mini dpkg implementation for busybox.
    3  *  This is not meant as a replacement for dpkg
     3 *  mini dpkg implementation for busybox.
     4 *  this is not meant as a replacement for dpkg
    45 *
    5  *  Written By Glenn McGrath with the help of others
    6  *  Copyright (C) 2001 by Glenn McGrath
     6 *  written by glenn mcgrath with the help of others
     7 *  copyright (c) 2001 by glenn mcgrath
    78 *
    8  *  Started life as a busybox implementation of udpkg
     9 *  started life as a busybox implementation of udpkg
    910 *
    10  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     11 * licensed under gplv2 or later, see file license in this tarball for details.
    1112 */
    1213
    1314/*
    14  * Known difference between busybox dpkg and the official dpkg that i don't
     15 * known difference between busybox dpkg and the official dpkg that i don't
    1516 * consider important, its worth keeping a note of differences anyway, just to
    1617 * make it easier to maintain.
    17  *  - The first value for the Confflile: field isnt placed on a new line.
    18  *  - When installing a package the Status: field is placed at the end of the
    19  *      section, rather than just after the Package: field.
     18 *  - the first value for the confflile: field isnt placed on a new line.
     19 *  - when installing a package the status: field is placed at the end of the
     20 *      section, rather than just after the package: field.
    2021 *
    21  * Bugs that need to be fixed
     22 * bugs that need to be fixed
    2223 *  - (unknown, please let me know when you find any)
    2324 *
    2425 */
    2526
    26 #include <fcntl.h>
    27 #include <getopt.h>
    28 #include <stdlib.h>
    29 #include <string.h>
    30 #include <unistd.h>
     27#include "libbb.h"
    3128#include "unarchive.h"
    32 #include "busybox.h"
    33 
    34 /* NOTE: If you vary HASH_PRIME sizes be aware,
    35  * 1) Tweaking these will have a big effect on how much memory this program uses.
    36  * 2) For computational efficiency these hash tables should be at least 20%
     29
     30/* note: if you vary hash_prime sizes be aware,
     31 * 1) tweaking these will have a big effect on how much memory this program uses.
     32 * 2) for computational efficiency these hash tables should be at least 20%
    3733 *    larger than the maximum number of elements stored in it.
    38  * 3) All _HASH_PRIME's must be a prime number or chaos is assured, if your looking
     34 * 3) all _hash_prime's must be a prime number or chaos is assured, if your looking
    3935 *    for a prime, try http://www.utm.edu/research/primes/lists/small/10000.txt
    40  * 4) If you go bigger than 15 bits you may get into trouble (untested) as its
    41  *    sometimes cast to an unsigned int, if you go to 16 bit you will overlap
     36 * 4) if you go bigger than 15 bits you may get into trouble (untested) as its
     37 *    sometimes cast to an unsigned, if you go to 16 bit you will overlap
    4238 *    int's and chaos is assured, 16381 is the max prime for 14 bit field
    4339 */
     
    4743 * as there a lot of duplicate version numbers */
    4844#define NAME_HASH_PRIME 16381
    49 static char *name_hashtable[NAME_HASH_PRIME + 1];
    5045
    5146/* PACKAGE_HASH_PRIME, Maximum number of unique packages,
     
    5954#define PACKAGE_HASH_PRIME 10007
    6055typedef struct edge_s {
    61     unsigned int operator:3;
    62     unsigned int type:4;
    63     unsigned int name:14;
    64     unsigned int version:14;
     56    unsigned operator:4; /* was:3 */
     57    unsigned type:4;
     58    unsigned name:16; /* was:14 */
     59    unsigned version:16; /* was:14 */
    6560} edge_t;
    6661
    6762typedef struct common_node_s {
    68     unsigned int name:14;
    69     unsigned int version:14;
    70     unsigned int num_of_edges:14;
     63    unsigned name:16; /* was:14 */
     64    unsigned version:16; /* was:14 */
     65    unsigned num_of_edges:16; /* was:14 */
    7166    edge_t **edge;
    7267} common_node_t;
    73 static common_node_t *package_hashtable[PACKAGE_HASH_PRIME + 1];
    7468
    7569/* Currently it doesnt store packages that have state-status of not-installed
     
    7872#define STATUS_HASH_PRIME 8191
    7973typedef struct status_node_s {
    80     unsigned int package:14;    /* has to fit PACKAGE_HASH_PRIME */
    81     unsigned int status:14;     /* has to fit STATUS_HASH_PRIME */
     74    unsigned package:16; /* was:14 */       /* has to fit PACKAGE_HASH_PRIME */
     75    unsigned status:16; /* was:14 */        /* has to fit STATUS_HASH_PRIME */
    8276} status_node_t;
    83 static status_node_t *status_hashtable[STATUS_HASH_PRIME + 1];
     77
     78/* Were statically declared here, but such a big bss is nommu-unfriendly */
     79static char **name_hashtable;             /* [NAME_HASH_PRIME + 1] */
     80static common_node_t **package_hashtable; /* [PACKAGE_HASH_PRIME + 1] */
     81static status_node_t **status_hashtable;  /* [STATUS_HASH_PRIME + 1] */
    8482
    8583/* Even numbers are for 'extras', like ored dependencies or null */
     
    107105};
    108106
    109 enum dpkg_opt_e {
    110     dpkg_opt_purge = 1,
    111     dpkg_opt_remove = 2,
    112     dpkg_opt_unpack = 4,
    113     dpkg_opt_configure = 8,
    114     dpkg_opt_install = 16,
    115     dpkg_opt_package_name = 32,
    116     dpkg_opt_filename = 64,
    117     dpkg_opt_list_installed = 128,
    118     dpkg_opt_force_ignore_depends = 256
    119 };
    120 
    121107typedef struct deb_file_s {
    122108    char *control_file;
    123109    char *filename;
    124     unsigned int package:14;
     110    unsigned package:16; /* was:14 */
    125111} deb_file_t;
    126112
    127113
    128 static void make_hash(const char *key, unsigned int *start, unsigned int *decrement, const int hash_prime)
    129 {
    130     unsigned long int hash_num = key[0];
     114static void make_hash(const char *key, unsigned *start, unsigned *decrement, const int hash_prime)
     115{
     116    unsigned long hash_num = key[0];
    131117    int len = strlen(key);
    132118    int i;
     
    134120    /* Maybe i should have uses a "proper" hashing algorithm here instead
    135121     * of making one up myself, seems to be working ok though. */
    136     for(i = 1; i < len; i++) {
     122    for (i = 1; i < len; i++) {
    137123        /* shifts the ascii based value and adds it to previous value
    138124         * shift amount is mod 24 because long int is 32 bit and data
     
    141127        hash_num += ((key[i] + key[i-1]) << ((key[i] * i) % 24));
    142128    }
    143     *start = (unsigned int) hash_num % hash_prime;
    144     *decrement = (unsigned int) 1 + (hash_num % (hash_prime - 1));
     129    *start = (unsigned) hash_num % hash_prime;
     130    *decrement = (unsigned) 1 + (hash_num % (hash_prime - 1));
    145131}
    146132
     
    148134static int search_name_hashtable(const char *key)
    149135{
    150     unsigned int probe_address = 0;
    151     unsigned int probe_decrement = 0;
    152 //  char *temp;
     136    unsigned probe_address = 0;
     137    unsigned probe_decrement = 0;
    153138
    154139    make_hash(key, &probe_address, &probe_decrement, NAME_HASH_PRIME);
    155     while(name_hashtable[probe_address] != NULL) {
     140    while (name_hashtable[probe_address] != NULL) {
    156141        if (strcmp(name_hashtable[probe_address], key) == 0) {
    157             return(probe_address);
    158         } else {
    159             probe_address -= probe_decrement;
    160             if ((int)probe_address < 0) {
    161                 probe_address += NAME_HASH_PRIME;
    162             }
    163         }
    164     }
    165     name_hashtable[probe_address] = bb_xstrdup(key);
    166     return(probe_address);
     142            return probe_address;
     143        }
     144        probe_address -= probe_decrement;
     145        if ((int)probe_address < 0) {
     146            probe_address += NAME_HASH_PRIME;
     147        }
     148    }
     149    name_hashtable[probe_address] = xstrdup(key);
     150    return probe_address;
    167151}
    168152
     
    170154 * TODO make it consistent with search_name_hashtable
    171155 */
    172 static unsigned int search_status_hashtable(const char *key)
    173 {
    174     unsigned int probe_address = 0;
    175     unsigned int probe_decrement = 0;
     156static unsigned search_status_hashtable(const char *key)
     157{
     158    unsigned probe_address = 0;
     159    unsigned probe_decrement = 0;
    176160
    177161    make_hash(key, &probe_address, &probe_decrement, STATUS_HASH_PRIME);
    178     while(status_hashtable[probe_address] != NULL) {
     162    while (status_hashtable[probe_address] != NULL) {
    179163        if (strcmp(key, name_hashtable[package_hashtable[status_hashtable[probe_address]->package]->name]) == 0) {
    180164            break;
    181         } else {
    182             probe_address -= probe_decrement;
    183             if ((int)probe_address < 0) {
    184                 probe_address += STATUS_HASH_PRIME;
    185             }
    186         }
    187     }
    188     return(probe_address);
     165        }
     166        probe_address -= probe_decrement;
     167        if ((int)probe_address < 0) {
     168            probe_address += STATUS_HASH_PRIME;
     169        }
     170    }
     171    return probe_address;
    189172}
    190173
     
    201184    int ver_num1;
    202185    int ver_num2;
    203     int ret;
    204186
    205187    if (version1 == NULL) {
    206         version1 = bb_xstrdup("");
     188        version1 = xstrdup("");
    207189    }
    208190    if (version2 == NULL) {
    209         version2 = bb_xstrdup("");
     191        version2 = xstrdup("");
    210192    }
    211193    upstream_len1 = strlen(version1);
     
    215197        /* Compare non-digit section */
    216198        tmp_int = strcspn(&version1[len1], "0123456789");
    217         name1_char = bb_xstrndup(&version1[len1], tmp_int);
     199        name1_char = xstrndup(&version1[len1], tmp_int);
    218200        len1 += tmp_int;
    219201        tmp_int = strcspn(&version2[len2], "0123456789");
    220         name2_char = bb_xstrndup(&version2[len2], tmp_int);
     202        name2_char = xstrndup(&version2[len2], tmp_int);
    221203        len2 += tmp_int;
    222204        tmp_int = strcmp(name1_char, name2_char);
     
    224206        free(name2_char);
    225207        if (tmp_int != 0) {
    226             ret = tmp_int;
    227             goto cleanup_version_compare_part;
     208            return tmp_int;
    228209        }
    229210
    230211        /* Compare digits */
    231212        tmp_int = strspn(&version1[len1], "0123456789");
    232         name1_char = bb_xstrndup(&version1[len1], tmp_int);
     213        name1_char = xstrndup(&version1[len1], tmp_int);
    233214        len1 += tmp_int;
    234215        tmp_int = strspn(&version2[len2], "0123456789");
    235         name2_char = bb_xstrndup(&version2[len2], tmp_int);
     216        name2_char = xstrndup(&version2[len2], tmp_int);
    236217        len2 += tmp_int;
    237218        ver_num1 = atoi(name1_char);
     
    240221        free(name2_char);
    241222        if (ver_num1 < ver_num2) {
    242             ret = -1;
    243             goto cleanup_version_compare_part;
    244         }
    245         else if (ver_num1 > ver_num2) {
    246             ret = 1;
    247             goto cleanup_version_compare_part;
    248         }
    249     }
    250     ret = 0;
    251 cleanup_version_compare_part:
    252     return(ret);
     223            return -1;
     224        }
     225        if (ver_num1 > ver_num2) {
     226            return 1;
     227        }
     228    }
     229    return 0;
    253230}
    254231
     
    257234 * if ver1 > ver2 return 1,
    258235 */
    259 static int version_compare(const unsigned int ver1, const unsigned int ver2)
     236static int version_compare(const unsigned ver1, const unsigned ver2)
    260237{
    261238    char *ch_ver1 = name_hashtable[ver1];
     
    285262    }
    286263    if (epoch1 < epoch2) {
    287         return(-1);
     264        return -1;
    288265    }
    289266    else if (epoch1 > epoch2) {
    290         return(1);
     267        return 1;
    291268    }
    292269
    293270    /* Compare upstream version */
    294     upstream_ver1 = bb_xstrdup(ver1_ptr);
    295     upstream_ver2 = bb_xstrdup(ver2_ptr);
     271    upstream_ver1 = xstrdup(ver1_ptr);
     272    upstream_ver2 = xstrdup(ver2_ptr);
    296273
    297274    /* Chop off debian version, and store for later use */
     
    307284    }
    308285    result = version_compare_part(upstream_ver1, upstream_ver2);
     286    if (!result)
     287        /* Compare debian versions */
     288        result = version_compare_part(deb_ver1, deb_ver2);
    309289
    310290    free(upstream_ver1);
    311291    free(upstream_ver2);
    312 
    313     if (result != 0) {
    314         return(result);
    315     }
    316 
    317     /* Compare debian versions */
    318     return(version_compare_part(deb_ver1, deb_ver2));
    319 }
    320 
    321 static int test_version(const unsigned int version1, const unsigned int version2, const unsigned int operator)
     292    return result;
     293}
     294
     295static int test_version(const unsigned version1, const unsigned version2, const unsigned operator)
    322296{
    323297    const int version_result = version_compare(version1, version2);
    324     switch(operator) {
    325         case (VER_ANY):
    326             return(TRUE);
    327         case (VER_EQUAL):
    328             if (version_result == 0) {
    329                 return(TRUE);
    330             }
    331             break;
    332         case (VER_LESS):
    333             if (version_result < 0) {
    334                 return(TRUE);
    335             }
    336             break;
    337         case (VER_LESS_EQUAL):
    338             if (version_result <= 0) {
    339                 return(TRUE);
    340             }
    341             break;
    342         case (VER_MORE):
    343             if (version_result > 0) {
    344                 return(TRUE);
    345             }
    346             break;
    347         case (VER_MORE_EQUAL):
    348             if (version_result >= 0) {
    349                 return(TRUE);
    350             }
    351             break;
    352     }
    353     return(FALSE);
    354 }
    355 
    356 
    357 static int search_package_hashtable(const unsigned int name, const unsigned int version, const unsigned int operator)
    358 {
    359     unsigned int probe_address = 0;
    360     unsigned int probe_decrement = 0;
     298    switch (operator) {
     299    case VER_ANY:
     300        return TRUE;
     301    case VER_EQUAL:
     302        return (version_result == 0);
     303    case VER_LESS:
     304        return (version_result < 0);
     305    case VER_LESS_EQUAL:
     306        return (version_result <= 0);
     307    case VER_MORE:
     308        return (version_result > 0);
     309    case VER_MORE_EQUAL:
     310        return (version_result >= 0);
     311    }
     312    return FALSE;
     313}
     314
     315
     316static int search_package_hashtable(const unsigned name, const unsigned version, const unsigned operator)
     317{
     318    unsigned probe_address = 0;
     319    unsigned probe_decrement = 0;
    361320
    362321    make_hash(name_hashtable[name], &probe_address, &probe_decrement, PACKAGE_HASH_PRIME);
    363     while(package_hashtable[probe_address] != NULL) {
     322    while (package_hashtable[probe_address] != NULL) {
    364323        if (package_hashtable[probe_address]->name == name) {
    365324            if (operator == VER_ANY) {
    366                 return(probe_address);
     325                return probe_address;
    367326            }
    368327            if (test_version(package_hashtable[probe_address]->version, version, operator)) {
    369                 return(probe_address);
     328                return probe_address;
    370329            }
    371330        }
     
    375334        }
    376335    }
    377     return(probe_address);
     336    return probe_address;
    378337}
    379338
     
    394353 * it simple for now until it proves to be a problem.
    395354 */
    396 static int search_for_provides(int needle, int start_at) {
     355static int search_for_provides(int needle, int start_at)
     356{
    397357    int i, j;
    398358    common_node_t *p;
    399359    for (i = start_at + 1; i < PACKAGE_HASH_PRIME; i++) {
    400360        p = package_hashtable[i];
    401         if ( p == NULL ) continue;
    402         for(j = 0; j < p->num_of_edges; j++)
    403             if ( p->edge[j]->type == EDGE_PROVIDES && p->edge[j]->name == needle )
     361        if (p == NULL)
     362            continue;
     363        for (j = 0; j < p->num_of_edges; j++)
     364            if (p->edge[j]->type == EDGE_PROVIDES && p->edge[j]->name == needle)
    404365                return i;
    405366    }
     
    427388 * this alternative.
    428389 */
    429 static void add_split_dependencies(common_node_t *parent_node, const char *whole_line, unsigned int edge_type)
    430 {
    431     char *line = bb_xstrdup(whole_line);
     390static void add_split_dependencies(common_node_t *parent_node, const char *whole_line, unsigned edge_type)
     391{
     392    char *line = xstrdup(whole_line);
    432393    char *line2;
    433394    char *line_ptr1 = NULL;
     
    444405        /* skip leading spaces */
    445406        field += strspn(field, " ");
    446         line2 = bb_xstrdup(field);
     407        line2 = xstrdup(field);
    447408        field2 = strtok_r(line2, "|", &line_ptr2);
    448         if ( (edge_type == EDGE_DEPENDS || edge_type == EDGE_PRE_DEPENDS) &&
    449              (strcmp(field, field2) != 0)) {
    450             or_edge = (edge_t *)xmalloc(sizeof(edge_t));
     409        or_edge = NULL;
     410        if ((edge_type == EDGE_DEPENDS || edge_type == EDGE_PRE_DEPENDS)
     411         && (strcmp(field, field2) != 0)
     412        ) {
     413            or_edge = xmalloc(sizeof(edge_t));
    451414            or_edge->type = edge_type + 1;
    452         } else {
    453             or_edge = NULL;
    454         }
    455 
    456         if ( or_edge ) {
    457415            or_edge->name = search_name_hashtable(field);
    458             or_edge->version = 0; // tracks the number of altenatives
    459 
     416            or_edge->version = 0; // tracks the number of alternatives
    460417            add_edge_to_node(parent_node, or_edge);
    461418        }
    462419
    463420        do {
    464             edge = (edge_t *) xmalloc(sizeof(edge_t));
     421            edge = xmalloc(sizeof(edge_t));
    465422            edge->type = edge_type;
    466423
     
    476433            } else {
    477434                /* Skip leading ' ' or '(' */
    478                 version += strspn(field2, " ");
    479                 version += strspn(version, "(");
     435                version += strspn(version, " (");
    480436                /* Calculate length of any operator characters */
    481437                offset_ch = strspn(version, "<=>");
     
    497453                        edge->operator = VER_MORE_EQUAL;
    498454                    } else {
    499                         bb_error_msg_and_die("Illegal operator\n");
     455                        bb_error_msg_and_die("illegal operator");
    500456                    }
    501457                }
     
    514470            edge->name = search_name_hashtable(field2);
    515471
    516             if ( or_edge )
     472            if (or_edge)
    517473                or_edge->version++;
    518474
    519475            add_edge_to_node(parent_node, edge);
    520         } while ((field2 = strtok_r(NULL, "|", &line_ptr2)) != NULL);
     476            field2 = strtok_r(NULL, "|", &line_ptr2);
     477        } while (field2 != NULL);
     478
    521479        free(line2);
    522     } while ((field = strtok_r(NULL, ",", &line_ptr1)) != NULL);
     480        field = strtok_r(NULL, ",", &line_ptr1);
     481    } while (field != NULL);
     482
    523483    free(line);
    524 
    525     return;
    526484}
    527485
    528486static void free_package(common_node_t *node)
    529487{
    530     unsigned short i;
     488    unsigned i;
    531489    if (node) {
    532490        for (i = 0; i < node->num_of_edges; i++) {
     
    538496}
    539497
    540 static unsigned int fill_package_struct(char *control_buffer)
    541 {
    542     static const char *const field_names[] = { "Package", "Version",
    543         "Pre-Depends", "Depends","Replaces", "Provides",
    544         "Conflicts", "Suggests", "Recommends", "Enhances", 0
    545     };
    546 
    547     common_node_t *new_node = (common_node_t *) xzalloc(sizeof(common_node_t));
     498/*
     499 * Gets the next package field from package_buffer, seperated into the field name
     500 * and field value, it returns the int offset to the first character of the next field
     501 */
     502static int read_package_field(const char *package_buffer, char **field_name, char **field_value)
     503{
     504    int offset_name_start = 0;
     505    int offset_name_end = 0;
     506    int offset_value_start = 0;
     507    int offset_value_end = 0;
     508    int offset = 0;
     509    int next_offset;
     510    int name_length;
     511    int value_length;
     512    int exit_flag = FALSE;
     513
     514    if (package_buffer == NULL) {
     515        *field_name = NULL;
     516        *field_value = NULL;
     517        return -1;
     518    }
     519    while (1) {
     520        next_offset = offset + 1;
     521        switch (package_buffer[offset]) {
     522            case '\0':
     523                exit_flag = TRUE;
     524                break;
     525            case ':':
     526                if (offset_name_end == 0) {
     527                    offset_name_end = offset;
     528                    offset_value_start = next_offset;
     529                }
     530                /* TODO: Name might still have trailing spaces if ':' isnt
     531                 * immediately after name */
     532                break;
     533            case '\n':
     534                /* TODO: The char next_offset may be out of bounds */
     535                if (package_buffer[next_offset] != ' ') {
     536                    exit_flag = TRUE;
     537                    break;
     538                }
     539            case '\t':
     540            case ' ':
     541                /* increment the value start point if its a just filler */
     542                if (offset_name_start == offset) {
     543                    offset_name_start++;
     544                }
     545                if (offset_value_start == offset) {
     546                    offset_value_start++;
     547                }
     548                break;
     549        }
     550        if (exit_flag) {
     551            /* Check that the names are valid */
     552            offset_value_end = offset;
     553            name_length = offset_name_end - offset_name_start;
     554            value_length = offset_value_end - offset_value_start;
     555            if (name_length == 0) {
     556                break;
     557            }
     558            if ((name_length > 0) && (value_length > 0)) {
     559                break;
     560            }
     561
     562            /* If not valid, start fresh with next field */
     563            exit_flag = FALSE;
     564            offset_name_start = offset + 1;
     565            offset_name_end = 0;
     566            offset_value_start = offset + 1;
     567            offset_value_end = offset + 1;
     568            offset++;
     569        }
     570        offset++;
     571    }
     572    *field_name = NULL;
     573    if (name_length) {
     574        *field_name = xstrndup(&package_buffer[offset_name_start], name_length);
     575    }
     576    *field_value = NULL;
     577    if (value_length > 0) {
     578        *field_value = xstrndup(&package_buffer[offset_value_start], value_length);
     579    }
     580    return next_offset;
     581}
     582
     583static unsigned fill_package_struct(char *control_buffer)
     584{
     585    static const char field_names[] ALIGN1 =
     586        "Package\0""Version\0"
     587        "Pre-Depends\0""Depends\0""Replaces\0""Provides\0"
     588        "Conflicts\0""Suggests\0""Recommends\0""Enhances\0";
     589
     590    common_node_t *new_node = xzalloc(sizeof(common_node_t));
    548591    char *field_name;
    549592    char *field_value;
     
    554597    new_node->version = search_name_hashtable("unknown");
    555598    while (field_start < buffer_length) {
    556         unsigned short field_num;
     599        unsigned field_num;
    557600
    558601        field_start += read_package_field(&control_buffer[field_start],
     
    560603
    561604        if (field_name == NULL) {
    562             goto fill_package_struct_cleanup; /* Oh no, the dreaded goto statement ! */
    563         }
    564 
    565         field_num = compare_string_array(field_names, field_name);
    566         switch(field_num) {
    567             case 0: /* Package */
    568                 new_node->name = search_name_hashtable(field_value);
    569                 break;
    570             case 1: /* Version */
    571                 new_node->version = search_name_hashtable(field_value);
    572                 break;
    573             case 2: /* Pre-Depends */
    574                 add_split_dependencies(new_node, field_value, EDGE_PRE_DEPENDS);
    575                 break;
    576             case 3: /* Depends */
    577                 add_split_dependencies(new_node, field_value, EDGE_DEPENDS);
    578                 break;
    579             case 4: /* Replaces */
    580                 add_split_dependencies(new_node, field_value, EDGE_REPLACES);
    581                 break;
    582             case 5: /* Provides */
    583                 add_split_dependencies(new_node, field_value, EDGE_PROVIDES);
    584                 break;
    585             case 6: /* Conflicts */
    586                 add_split_dependencies(new_node, field_value, EDGE_CONFLICTS);
    587                 break;
    588             case 7: /* Suggests */
    589                 add_split_dependencies(new_node, field_value, EDGE_SUGGESTS);
    590                 break;
    591             case 8: /* Recommends */
    592                 add_split_dependencies(new_node, field_value, EDGE_RECOMMENDS);
    593                 break;
    594             case 9: /* Enhances */
    595                 add_split_dependencies(new_node, field_value, EDGE_ENHANCES);
    596                 break;
    597         }
    598 fill_package_struct_cleanup:
     605            goto fill_package_struct_cleanup; /* Oh no, the dreaded goto statement! */
     606        }
     607
     608        field_num = index_in_strings(field_names, field_name);
     609        switch (field_num) {
     610        case 0: /* Package */
     611            new_node->name = search_name_hashtable(field_value);
     612            break;
     613        case 1: /* Version */
     614            new_node->version = search_name_hashtable(field_value);
     615            break;
     616        case 2: /* Pre-Depends */
     617            add_split_dependencies(new_node, field_value, EDGE_PRE_DEPENDS);
     618            break;
     619        case 3: /* Depends */
     620            add_split_dependencies(new_node, field_value, EDGE_DEPENDS);
     621            break;
     622        case 4: /* Replaces */
     623            add_split_dependencies(new_node, field_value, EDGE_REPLACES);
     624            break;
     625        case 5: /* Provides */
     626            add_split_dependencies(new_node, field_value, EDGE_PROVIDES);
     627            break;
     628        case 6: /* Conflicts */
     629            add_split_dependencies(new_node, field_value, EDGE_CONFLICTS);
     630            break;
     631        case 7: /* Suggests */
     632            add_split_dependencies(new_node, field_value, EDGE_SUGGESTS);
     633            break;
     634        case 8: /* Recommends */
     635            add_split_dependencies(new_node, field_value, EDGE_RECOMMENDS);
     636            break;
     637        case 9: /* Enhances */
     638            add_split_dependencies(new_node, field_value, EDGE_ENHANCES);
     639            break;
     640        }
     641 fill_package_struct_cleanup:
    599642        free(field_name);
    600643        free(field_value);
     
    603646    if (new_node->version == search_name_hashtable("unknown")) {
    604647        free_package(new_node);
    605         return(-1);
     648        return -1;
    606649    }
    607650    num = search_package_hashtable(new_node->name, new_node->version, VER_EQUAL);
    608     if (package_hashtable[num] == NULL) {
    609         package_hashtable[num] = new_node;
    610     } else {
    611         free_package(new_node);
    612     }
    613     return(num);
     651    free_package(package_hashtable[num]);
     652    package_hashtable[num] = new_node;
     653    return num;
    614654}
    615655
    616656/* if num = 1, it returns the want status, 2 returns flag, 3 returns status */
    617 static unsigned int get_status(const unsigned int status_node, const int num)
     657static unsigned get_status(const unsigned status_node, const int num)
    618658{
    619659    char *status_string = name_hashtable[status_hashtable[status_node]->status];
    620660    char *state_sub_string;
    621     unsigned int state_sub_num;
     661    unsigned state_sub_num;
    622662    int len;
    623663    int i;
     
    630670        status_string += strspn(status_string, " ");
    631671    }
    632     len = strcspn(status_string, " \n\0");
    633     state_sub_string = bb_xstrndup(status_string, len);
     672    len = strcspn(status_string, " \n");
     673    state_sub_string = xstrndup(status_string, len);
    634674    state_sub_num = search_name_hashtable(state_sub_string);
    635675    free(state_sub_string);
    636     return(state_sub_num);
    637 }
    638 
    639 static void set_status(const unsigned int status_node_num, const char *new_value, const int position)
    640 {
    641     const unsigned int new_value_len = strlen(new_value);
    642     const unsigned int new_value_num = search_name_hashtable(new_value);
    643     unsigned int want = get_status(status_node_num, 1);
    644     unsigned int flag = get_status(status_node_num, 2);
    645     unsigned int status = get_status(status_node_num, 3);
     676    return state_sub_num;
     677}
     678
     679static void set_status(const unsigned status_node_num, const char *new_value, const int position)
     680{
     681    const unsigned new_value_len = strlen(new_value);
     682    const unsigned new_value_num = search_name_hashtable(new_value);
     683    unsigned want = get_status(status_node_num, 1);
     684    unsigned flag = get_status(status_node_num, 2);
     685    unsigned status = get_status(status_node_num, 3);
    646686    int want_len = strlen(name_hashtable[want]);
    647687    int flag_len = strlen(name_hashtable[flag]);
     
    650690
    651691    switch (position) {
    652         case (1):
     692        case 1:
    653693            want = new_value_num;
    654694            want_len = new_value_len;
    655695            break;
    656         case (2):
     696        case 2:
    657697            flag = new_value_num;
    658698            flag_len = new_value_len;
    659699            break;
    660         case (3):
     700        case 3:
    661701            status = new_value_num;
    662702            status_len = new_value_len;
     
    666706    }
    667707
    668     new_status = bb_xasprintf("%s %s %s", name_hashtable[want], name_hashtable[flag], name_hashtable[status]);
     708    new_status = xasprintf("%s %s %s", name_hashtable[want], name_hashtable[flag], name_hashtable[status]);
    669709    status_hashtable[status_node_num]->status = search_name_hashtable(new_status);
    670710    free(new_status);
    671     return;
    672 }
    673 
    674 static const char *describe_status(int status_num) {
    675     int status_want, status_state ;
    676     if ( status_hashtable[status_num] == NULL || status_hashtable[status_num]->status == 0 )
    677         return "is not installed or flagged to be installed\n";
     711}
     712
     713static const char *describe_status(int status_num)
     714{
     715    int status_want, status_state;
     716    if (status_hashtable[status_num] == NULL || status_hashtable[status_num]->status == 0)
     717        return "is not installed or flagged to be installed";
    678718
    679719    status_want = get_status(status_num, 1);
    680720    status_state = get_status(status_num, 3);
    681721
    682     if ( status_state == search_name_hashtable("installed") ) {
    683         if ( status_want == search_name_hashtable("install") )
     722    if (status_state == search_name_hashtable("installed")) {
     723        if (status_want == search_name_hashtable("install"))
    684724            return "is installed";
    685         if ( status_want == search_name_hashtable("deinstall") )
     725        if (status_want == search_name_hashtable("deinstall"))
    686726            return "is marked to be removed";
    687         if ( status_want == search_name_hashtable("purge") )
     727        if (status_want == search_name_hashtable("purge"))
    688728            return "is marked to be purged";
    689729    }
    690     if ( status_want ==  search_name_hashtable("unknown") )
     730    if (status_want == search_name_hashtable("unknown"))
    691731        return "is in an indeterminate state";
    692     if ( status_want == search_name_hashtable("install") )
     732    if (status_want == search_name_hashtable("install"))
    693733        return "is marked to be installed";
    694734
     
    703743    char *status_line;
    704744    status_node_t *status_node = NULL;
    705     unsigned int status_num;
    706 
    707     status_file = bb_xfopen(filename, "r");
    708     while ((control_buffer = fgets_str(status_file, "\n\n")) != NULL) {
    709         const unsigned int package_num = fill_package_struct(control_buffer);
     745    unsigned status_num;
     746
     747    status_file = xfopen(filename, "r");
     748    while ((control_buffer = xmalloc_fgets_str(status_file, "\n\n")) != NULL) {
     749        const unsigned package_num = fill_package_struct(control_buffer);
    710750        if (package_num != -1) {
    711751            status_node = xmalloc(sizeof(status_node_t));
     
    715755                status_line += 7;
    716756                status_line += strspn(status_line, " \n\t");
    717                 status_line = bb_xstrndup(status_line, strcspn(status_line, "\n\0"));
     757                status_line = xstrndup(status_line, strcspn(status_line, "\n"));
    718758                status_node->status = search_name_hashtable(status_line);
    719759                free(status_line);
     
    726766    }
    727767    fclose(status_file);
    728     return;
    729768}
    730769
     
    743782        }
    744783    }
    745     return;
    746784}
    747785
     
    749787static void write_status_file(deb_file_t **deb_file)
    750788{
    751     FILE *old_status_file = bb_xfopen("/var/lib/dpkg/status", "r");
    752     FILE *new_status_file = bb_xfopen("/var/lib/dpkg/status.udeb", "w");
     789    FILE *old_status_file = xfopen("/var/lib/dpkg/status", "r");
     790    FILE *new_status_file = xfopen("/var/lib/dpkg/status.udeb", "w");
    753791    char *package_name;
    754792    char *status_from_file;
     
    761799
    762800    /* Update previously known packages */
    763     while ((control_buffer = fgets_str(old_status_file, "\n\n")) != NULL) {
    764         if ((tmp_string = strstr(control_buffer, "Package:")) == NULL) {
     801    while ((control_buffer = xmalloc_fgets_str(old_status_file, "\n\n")) != NULL) {
     802        tmp_string = strstr(control_buffer, "Package:");
     803        if (tmp_string == NULL) {
    765804            continue;
    766805        }
     
    768807        tmp_string += 8;
    769808        tmp_string += strspn(tmp_string, " \n\t");
    770         package_name = bb_xstrndup(tmp_string, strcspn(tmp_string, "\n\0"));
     809        package_name = xstrndup(tmp_string, strcspn(tmp_string, "\n"));
    771810        write_flag = FALSE;
    772811        tmp_string = strstr(control_buffer, "Status:");
     
    775814            tmp_string += 7;
    776815            tmp_string += strspn(tmp_string, " \n\t");
    777             status_from_file = bb_xstrndup(tmp_string, strcspn(tmp_string, "\n"));
     816            status_from_file = xstrndup(tmp_string, strcspn(tmp_string, "\n"));
    778817        } else {
    779818            status_from_file = NULL;
     
    787826                /* New status isnt exactly the same as old status */
    788827                const int state_status = get_status(status_num, 3);
    789                 if ((strcmp("installed", name_hashtable[state_status]) == 0) ||
    790                     (strcmp("unpacked", name_hashtable[state_status]) == 0)) {
     828                if ((strcmp("installed", name_hashtable[state_status]) == 0)
     829                 || (strcmp("unpacked", name_hashtable[state_status]) == 0)
     830                ) {
    791831                    /* We need to add the control file from the package */
    792832                    i = 0;
    793                     while(deb_file[i] != NULL) {
     833                    while (deb_file[i] != NULL) {
    794834                        if (strcmp(package_name, name_hashtable[package_hashtable[deb_file[i]->package]->name]) == 0) {
    795835                            /* Write a status file entry with a modified status */
     
    797837                            write_buffer_no_status(new_status_file, deb_file[i]->control_file);
    798838                            set_status(status_num, "ok", 2);
    799                             fprintf(new_status_file, "Status: %s\n\n", name_hashtable[status_hashtable[status_num]->status]);
     839                            fprintf(new_status_file, "Status: %s\n\n",
     840                                    name_hashtable[status_hashtable[status_num]->status]);
    800841                            write_flag = TRUE;
    801842                            break;
     
    805846                    /* This is temperary, debugging only */
    806847                    if (deb_file[i] == NULL) {
    807                         bb_error_msg_and_die("ALERT: Couldnt find a control file, your status file may be broken, status may be incorrect for %s", package_name);
     848                        bb_error_msg_and_die("ALERT: cannot find a control file, "
     849                            "your status file may be broken, status may be "
     850                            "incorrect for %s", package_name);
    808851                    }
    809852                }
     
    850893        }
    851894        /* If the package from the status file wasnt handle above, do it now*/
    852         if (! write_flag) {
     895        if (!write_flag) {
    853896            fprintf(new_status_file, "%s\n\n", control_buffer);
    854897        }
     
    860903
    861904    /* Write any new packages */
    862     for(i = 0; deb_file[i] != NULL; i++) {
     905    for (i = 0; deb_file[i] != NULL; i++) {
    863906        status_num = search_status_hashtable(name_hashtable[package_hashtable[deb_file[i]->package]->name]);
    864907        if (strcmp("reinstreq", name_hashtable[get_status(status_num, 2)]) == 0) {
     
    878921        /* Its ok if renaming the status file fails because status
    879922         * file doesnt exist, maybe we are starting from scratch */
    880         bb_error_msg("No status file found, creating new one");
     923        bb_error_msg("no status file found, creating new one");
    881924    }
    882925
    883926    if (rename("/var/lib/dpkg/status.udeb", "/var/lib/dpkg/status") == -1) {
    884         bb_error_msg_and_die("DANGER: Couldnt create status file, you need to manually repair your status file");
     927        bb_error_msg_and_die("DANGER: cannot create status file, "
     928            "you need to manually repair your status file");
    885929    }
    886930}
     
    900944     * provides which cannot satisfy any dependency by itself.
    901945     */
    902     if ( status_hashtable[status_num] == NULL )
     946    if (status_hashtable[status_num] == NULL)
    903947        return 0;
    904948
     
    927971     * installed package for conflicts*/
    928972    while (deb_file[i] != NULL) {
    929         const unsigned int package_num = deb_file[i]->package;
     973        const unsigned package_num = deb_file[i]->package;
    930974        conflicts = xrealloc(conflicts, sizeof(int) * (conflicts_num + 1));
    931975        conflicts[conflicts_num] = package_num;
     
    940984                if (package_hashtable[conflicts_package_num] == NULL) {
    941985                    /* create a new package */
    942                     common_node_t *new_node = (common_node_t *) xzalloc(sizeof(common_node_t));
     986                    common_node_t *new_node = xzalloc(sizeof(common_node_t));
    943987                    new_node->name = package_hashtable[package_num]->edge[j]->name;
    944988                    new_node->version = package_hashtable[package_num]->edge[j]->version;
     
    9691013
    9701014            if (package_edge->type == EDGE_CONFLICTS) {
    971                 const unsigned int package_num =
     1015                const unsigned package_num =
    9721016                    search_package_hashtable(package_edge->name,
    9731017                                 package_edge->version,
     
    9841028
    9851029                if (result) {
    986                     bb_error_msg_and_die("Package %s conflicts with %s",
     1030                    bb_error_msg_and_die("package %s conflicts with %s",
    9871031                        name_hashtable[package_node->name],
    9881032                        name_hashtable[package_edge->name]);
     
    10051049         * no dependencies to check.
    10061050         */
    1007         if ( package_node == NULL ) continue;
     1051        if (package_node == NULL) continue;
    10081052
    10091053        status_num = search_status_hashtable(name_hashtable[package_node->name]);
     
    10131057         * case there are no dependencies to check.
    10141058         */
    1015         if ( status_hashtable[status_num] == NULL ) continue;
     1059        if (status_hashtable[status_num] == NULL) continue;
    10161060
    10171061        /* If we don't want this package installed then we may
     
    10211065            continue;
    10221066        }
    1023 
    1024 #if 0
    1025         /* This might be needed so we don't complain about
    1026          * things which are broken but unrelated to the
    1027          * packages that are currently being installed
    1028          */
    1029         if (state_status == search_name_hashtable("installed"))
    1030             continue;
    1031 #endif
    10321067
    10331068        /* This code is tested only for EDGE_DEPENDS, since I
     
    10371072        for (j = 0; j < package_node->num_of_edges; j++) {
    10381073            const edge_t *package_edge = package_node->edge[j];
    1039             unsigned int package_num;
    1040 
    1041             if ( package_edge->type == EDGE_OR_PRE_DEPENDS ||
    1042                  package_edge->type == EDGE_OR_DEPENDS ) {  /* start an EDGE_OR_ list */
     1074            unsigned package_num;
     1075
     1076            if (package_edge->type == EDGE_OR_PRE_DEPENDS
     1077             || package_edge->type == EDGE_OR_DEPENDS
     1078            ) { /* start an EDGE_OR_ list */
    10431079                number_of_alternatives = package_edge->version;
    10441080                root_of_alternatives = package_edge;
    10451081                continue;
    1046             } else if ( number_of_alternatives == 0 ) { /* not in the middle of an EDGE_OR_ list */
     1082            }
     1083            if (number_of_alternatives == 0) {  /* not in the middle of an EDGE_OR_ list */
    10471084                number_of_alternatives = 1;
    10481085                root_of_alternatives = NULL;
     
    10521089
    10531090            if (package_edge->type == EDGE_PRE_DEPENDS ||
    1054                 package_edge->type == EDGE_DEPENDS ) {
     1091                package_edge->type == EDGE_DEPENDS) {
    10551092                int result=1;
    10561093                status_num = 0;
     
    10621099                 * EDGE_PRE_DEPENDS == OR_PRE_DEPENDS -1
    10631100                 */
    1064                 if ( root_of_alternatives && package_edge->type != root_of_alternatives->type - 1)
    1065                     bb_error_msg_and_die("Fatal error. Package dependencies corrupt: %d != %d - 1 \n",
     1101                if (root_of_alternatives && package_edge->type != root_of_alternatives->type - 1)
     1102                    bb_error_msg_and_die("fatal error, package dependencies corrupt: %d != %d - 1",
    10661103                                 package_edge->type, root_of_alternatives->type);
    10671104
     
    10721109                    int provider = -1;
    10731110
    1074                     while ( (provider = search_for_provides(package_edge->name, provider) ) > -1 ) {
    1075                         if ( package_hashtable[provider] == NULL ) {
    1076                             printf("Have a provider but no package information for it\n");
     1111                    while ((provider = search_for_provides(package_edge->name, provider)) > -1) {
     1112                        if (package_hashtable[provider] == NULL) {
     1113                            puts("Have a provider but no package information for it");
    10771114                            continue;
    10781115                        }
    10791116                        result = !package_satisfies_dependency(provider, package_edge->type);
    10801117
    1081                         if ( result == 0 )
     1118                        if (result == 0)
    10821119                            break;
    10831120                    }
     
    10871124                number_of_alternatives--;
    10881125                if (result && number_of_alternatives == 0) {
    1089                     if ( root_of_alternatives )
     1126                    if (root_of_alternatives)
    10901127                        bb_error_msg_and_die(
    1091                             "Package %s %sdepends on %s, "
     1128                            "package %s %sdepends on %s, "
    10921129                            "which cannot be satisfied",
    10931130                            name_hashtable[package_node->name],
    10941131                            package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "",
    10951132                            name_hashtable[root_of_alternatives->name]);
    1096                     else
    1097                         bb_error_msg_and_die(
    1098                             "Package %s %sdepends on %s, which %s\n",
    1099                             name_hashtable[package_node->name],
    1100                             package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "",
    1101                             name_hashtable[package_edge->name],
    1102                             describe_status(status_num));
    1103                 } else if ( result == 0 && number_of_alternatives ) {
     1133                    bb_error_msg_and_die(
     1134                        "package %s %sdepends on %s, which %s\n",
     1135                        name_hashtable[package_node->name],
     1136                        package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "",
     1137                        name_hashtable[package_edge->name],
     1138                        describe_status(status_num));
     1139                }
     1140                if (result == 0 && number_of_alternatives) {
    11041141                    /* we've found a package which
    11051142                     * satisfies the dependency,
     
    11141151    }
    11151152    free(conflicts);
    1116     return(TRUE);
     1153    return TRUE;
    11171154}
    11181155
     
    11271164    list_stream = fopen(filename, "r");
    11281165    if (list_stream == NULL) {
    1129         return(NULL);
    1130     }
    1131 
    1132     while ((line = bb_get_chomped_line_from_file(list_stream)) != NULL) {
     1166        return NULL;
     1167    }
     1168
     1169    while ((line = xmalloc_getline(list_stream)) != NULL) {
    11331170        file_list = xrealloc(file_list, sizeof(char *) * (count + 2));
    11341171        file_list[count] = line;
     
    11381175
    11391176    if (count == 0) {
    1140         return(NULL);
    1141     } else {
    1142         file_list[count] = NULL;
    1143         return(file_list);
    1144     }
     1177        return NULL;
     1178    }
     1179    file_list[count] = NULL;
     1180    return file_list;
    11451181}
    11461182
     
    11491185{
    11501186    struct stat path_stat;
    1151     int match_flag;
    1152     int remove_flag = FALSE;
    1153     int i,j;
     1187    int remove_flag = 1; /* not removed anything yet */
     1188    int i, j;
    11541189
    11551190    if (remove_names == NULL) {
    1156         return(FALSE);
     1191        return 0;
    11571192    }
    11581193    for (i = 0; remove_names[i] != NULL; i++) {
    1159         match_flag = FALSE;
    11601194        if (exclude_names != NULL) {
    1161             for (j = 0; exclude_names[j] != 0; j++) {
     1195            for (j = 0; exclude_names[j] != NULL; j++) {
    11621196                if (strcmp(remove_names[i], exclude_names[j]) == 0) {
    1163                     match_flag = TRUE;
    1164                     break;
     1197                    goto skip;
    11651198                }
    11661199            }
    11671200        }
    1168         if (!match_flag) {
    1169             if (lstat(remove_names[i], &path_stat) < 0) {
    1170                 continue;
    1171             }
    1172             if (S_ISDIR(path_stat.st_mode)) {
    1173                 if (rmdir(remove_names[i]) != -1) {
    1174                     remove_flag = TRUE;
    1175                 }
    1176             } else {
    1177                 if (unlink(remove_names[i]) != -1) {
    1178                     remove_flag = TRUE;
    1179                 }
    1180             }
    1181         }
    1182     }
    1183     return(remove_flag);
     1201        /* TODO: why we are checking lstat? we can just try rm/rmdir */
     1202        if (lstat(remove_names[i], &path_stat) < 0) {
     1203            continue;
     1204        }
     1205        if (S_ISDIR(path_stat.st_mode)) {
     1206            remove_flag &= rmdir(remove_names[i]); /* 0 if no error */
     1207        } else {
     1208            remove_flag &= unlink(remove_names[i]); /* 0 if no error */
     1209        }
     1210 skip:
     1211        continue;
     1212    }
     1213    return (remove_flag == 0);
    11841214}
    11851215
     
    11901220    int result;
    11911221
    1192     script_path = bb_xasprintf("/var/lib/dpkg/info/%s.%s", package_name, script_type);
     1222    script_path = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, script_type);
    11931223
    11941224    /* If the file doesnt exist is isnt a fatal */
    11951225    result = lstat(script_path, &path_stat) < 0 ? EXIT_SUCCESS : system(script_path);
    11961226    free(script_path);
    1197     return(result);
    1198 }
    1199 
    1200 static const char *all_control_files[] = {"preinst", "postinst", "prerm", "postrm",
    1201     "list", "md5sums", "shlibs", "conffiles", "config", "templates", NULL };
     1227    return result;
     1228}
     1229
     1230static const char *const all_control_files[] = {
     1231    "preinst", "postinst", "prerm", "postrm",
     1232    "list", "md5sums", "shlibs", "conffiles",
     1233    "config", "templates", NULL
     1234};
    12021235
    12031236static char **all_control_list(const char *package_name)
    12041237{
    1205     unsigned short i = 0;
     1238    unsigned i = 0;
    12061239    char **remove_files;
    12071240
     
    12091242    remove_files = xzalloc(sizeof(all_control_files));
    12101243    while (all_control_files[i]) {
    1211         remove_files[i] = bb_xasprintf("/var/lib/dpkg/info/%s.%s", package_name, all_control_files[i]);
     1244        remove_files[i] = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, all_control_files[i]);
    12121245        i++;
    12131246    }
    12141247
    1215     return(remove_files);
     1248    return remove_files;
    12161249}
    12171250
    12181251static void free_array(char **array)
    12191252{
    1220 
    12211253    if (array) {
    1222         unsigned short i = 0;
     1254        unsigned i = 0;
    12231255        while (array[i]) {
    12241256            free(array[i]);
     
    12371269    int i;
    12381270
    1239     printf("    Name           Version\n");
    1240     printf("+++-==============-==============\n");
     1271    puts("    Name           Version");
     1272    puts("+++-==============-==============");
    12411273
    12421274    /* go through status hash, dereference package hash and finally strings */
    1243     for (i=0; i<STATUS_HASH_PRIME+1; i++) {
    1244 
    1245             if (status_hashtable[i]) {
    1246                 const char *stat_str;  /* status string */
     1275    for (i = 0; i < STATUS_HASH_PRIME+1; i++) {
     1276        if (status_hashtable[i]) {
     1277            const char *stat_str;  /* status string */
    12471278            const char *name_str;  /* package name */
    12481279            const char *vers_str;  /* version */
     
    12591290
    12601291            /* get abbreviation for status field 2 */
    1261             for (j=0, spccnt=0; stat_str[j] && spccnt<2; j++) {
    1262                     if (stat_str[j] == ' ') spccnt++;
     1292            for (j = 0, spccnt = 0; stat_str[j] && spccnt < 2; j++) {
     1293                if (stat_str[j] == ' ') spccnt++;
    12631294            }
    12641295            s2 = stat_str[j];
     
    12671298            printf("%c%c  %-14s %s\n", s1, s2, name_str, vers_str);
    12681299        }
    1269     }
    1270 }
    1271 
    1272 static void remove_package(const unsigned int package_num, int noisy)
     1300    }
     1301}
     1302
     1303static void remove_package(const unsigned package_num, int noisy)
    12731304{
    12741305    const char *package_name = name_hashtable[package_hashtable[package_num]->name];
    12751306    const char *package_version = name_hashtable[package_hashtable[package_num]->version];
    1276     const unsigned int status_num = search_status_hashtable(package_name);
     1307    const unsigned status_num = search_status_hashtable(package_name);
    12771308    const int package_name_length = strlen(package_name);
    12781309    char **remove_files;
     
    12801311    char list_name[package_name_length + 25];
    12811312    char conffile_name[package_name_length + 30];
    1282     int return_value;
    1283 
    1284     if ( noisy )
    1285         printf("Removing %s (%s) ...\n", package_name, package_version);
     1313
     1314    if (noisy)
     1315        printf("Removing %s (%s)...\n", package_name, package_version);
    12861316
    12871317    /* run prerm script */
    1288     return_value = run_package_script(package_name, "prerm");
    1289     if (return_value == -1) {
     1318    if (run_package_script(package_name, "prerm") != 0) {
    12901319        bb_error_msg_and_die("script failed, prerm failure");
    12911320    }
     
    12981327    exclude_files = create_list(conffile_name);
    12991328
    1300     /* Some directories cant be removed straight away, so do multiple passes */
    1301     while (remove_file_array(remove_files, exclude_files));
     1329    /* Some directories can't be removed straight away, so do multiple passes */
     1330    while (remove_file_array(remove_files, exclude_files)) /*repeat */;
    13021331    free_array(exclude_files);
    13031332    free_array(remove_files);
     
    13051334    /* Create a list of files in /var/lib/dpkg/info/<package>.* to keep  */
    13061335    exclude_files = xzalloc(sizeof(char*) * 3);
    1307     exclude_files[0] = bb_xstrdup(conffile_name);
    1308     exclude_files[1] = bb_xasprintf("/var/lib/dpkg/info/%s.postrm", package_name);
     1336    exclude_files[0] = xstrdup(conffile_name);
     1337    exclude_files[1] = xasprintf("/var/lib/dpkg/info/%s.postrm", package_name);
    13091338
    13101339    /* Create a list of all /var/lib/dpkg/info/<package> files */
     
    13221351}
    13231352
    1324 static void purge_package(const unsigned int package_num)
     1353static void purge_package(const unsigned package_num)
    13251354{
    13261355    const char *package_name = name_hashtable[package_hashtable[package_num]->name];
    13271356    const char *package_version = name_hashtable[package_hashtable[package_num]->version];
    1328     const unsigned int status_num = search_status_hashtable(package_name);
     1357    const unsigned status_num = search_status_hashtable(package_name);
    13291358    char **remove_files;
    13301359    char **exclude_files;
    13311360    char list_name[strlen(package_name) + 25];
    13321361
    1333     printf("Purging %s (%s) ...\n", package_name, package_version);
     1362    printf("Purging %s (%s)...\n", package_name, package_version);
    13341363
    13351364    /* run prerm script */
     
    13451374
    13461375    /* Some directories cant be removed straight away, so do multiple passes */
    1347     while (remove_file_array(remove_files, exclude_files));
     1376    while (remove_file_array(remove_files, exclude_files)) /* repeat */;
    13481377    free_array(remove_files);
    13491378
     
    13551384
    13561385    /* run postrm script */
    1357     if (run_package_script(package_name, "postrm") == -1) {
    1358         bb_error_msg_and_die("postrm fialure.. set status to what?");
     1386    if (run_package_script(package_name, "postrm") != 0) {
     1387        bb_error_msg_and_die("postrm failure.. set status to what?");
    13591388    }
    13601389
     
    13701399    ar_handle = init_handle();
    13711400    ar_handle->filter = filter_accept_list_reassign;
    1372     ar_handle->src_fd = bb_xopen(filename, O_RDONLY);
    1373 
    1374     return(ar_handle);
     1401    ar_handle->src_fd = xopen(filename, O_RDONLY);
     1402
     1403    return ar_handle;
    13751404}
    13761405
     
    13841413
    13851414    /* We don't care about data.tar.* or debian-binary, just control.tar.* */
    1386 #ifdef CONFIG_FEATURE_DEB_TAR_GZ
    1387     llist_add_to(&(ar_handle->accept), "control.tar.gz");
     1415#if ENABLE_FEATURE_DEB_TAR_GZ
     1416    llist_add_to(&(ar_handle->accept), (char*)"control.tar.gz");
    13881417#endif
    1389 #ifdef CONFIG_FEATURE_DEB_TAR_BZ2
    1390     llist_add_to(&(ar_handle->accept), "control.tar.bz2");
     1418#if ENABLE_FEATURE_DEB_TAR_BZ2
     1419    llist_add_to(&(ar_handle->accept), (char*)"control.tar.bz2");
    13911420#endif
    13921421
    13931422    /* Assign the tar handle as a subarchive of the ar handle */
    13941423    ar_handle->sub_archive = tar_handle;
    1395 
    1396     return;
    13971424}
    13981425
     
    14061433
    14071434    /* We don't care about control.tar.* or debian-binary, just data.tar.* */
    1408 #ifdef CONFIG_FEATURE_DEB_TAR_GZ
    1409     llist_add_to(&(ar_handle->accept), "data.tar.gz");
     1435#if ENABLE_FEATURE_DEB_TAR_GZ
     1436    llist_add_to(&(ar_handle->accept), (char*)"data.tar.gz");
    14101437#endif
    1411 #ifdef CONFIG_FEATURE_DEB_TAR_BZ2
    1412     llist_add_to(&(ar_handle->accept), "data.tar.bz2");
     1438#if ENABLE_FEATURE_DEB_TAR_BZ2
     1439    llist_add_to(&(ar_handle->accept), (char*)"data.tar.bz2");
    14131440#endif
    14141441
    14151442    /* Assign the tar handle as a subarchive of the ar handle */
    14161443    ar_handle->sub_archive = tar_handle;
    1417 
    1418     return;
    14191444}
    14201445
     
    14281453    close(ar_handle->src_fd);
    14291454
    1430     return(ar_handle->sub_archive->buffer);
     1455    return ar_handle->sub_archive->buffer;
    14311456}
    14321457
     
    14371462    name_ptr += strspn(name_ptr, "./");
    14381463    if (name_ptr[0] != '\0') {
    1439         archive_handle->file_header->name = bb_xasprintf("%s%s", archive_handle->buffer, name_ptr);
     1464        archive_handle->file_header->name = xasprintf("%s%s", archive_handle->buffer, name_ptr);
    14401465        data_extract_all(archive_handle);
    14411466    }
    1442     return;
    14431467}
    14441468
     
    14461470{
    14471471    const char *package_name = name_hashtable[package_hashtable[deb_file->package]->name];
    1448     const unsigned int status_num = search_status_hashtable(package_name);
    1449     const unsigned int status_package_num = status_hashtable[status_num]->package;
     1472    const unsigned status_num = search_status_hashtable(package_name);
     1473    const unsigned status_package_num = status_hashtable[status_num]->package;
    14501474    char *info_prefix;
     1475    char *list_filename;
    14511476    archive_handle_t *archive_handle;
    14521477    FILE *out_stream;
     
    14571482    if (strcmp(name_hashtable[get_status(status_num, 3)], "installed") == 0) {
    14581483        /* Package is already installed, remove old version first */
    1459         printf("Preparing to replace %s %s (using %s) ...\n", package_name,
     1484        printf("Preparing to replace %s %s (using %s)...\n", package_name,
    14601485            name_hashtable[package_hashtable[status_package_num]->version],
    14611486            deb_file->filename);
    14621487        remove_package(status_package_num, 0);
    14631488    } else {
    1464         printf("Unpacking %s (from %s) ...\n", package_name, deb_file->filename);
     1489        printf("Unpacking %s (from %s)...\n", package_name, deb_file->filename);
    14651490    }
    14661491
    14671492    /* Extract control.tar.gz to /var/lib/dpkg/info/<package>.filename */
    1468     info_prefix = bb_xasprintf("/var/lib/dpkg/info/%s.", package_name);
     1493    info_prefix = xasprintf("/var/lib/dpkg/info/%s.", package_name);
    14691494    archive_handle = init_archive_deb_ar(deb_file->filename);
    14701495    init_archive_deb_control(archive_handle);
    14711496
    1472     while(all_control_files[i]) {
    1473         char *c = bb_xasprintf("./%s", all_control_files[i]);
     1497    while (all_control_files[i]) {
     1498        char *c = xasprintf("./%s", all_control_files[i]);
    14741499        llist_add_to(&accept_list, c);
    14751500        i++;
     
    14851510    if (run_package_script(package_name, "preinst") != 0) {
    14861511        /* when preinst returns exit code != 0 then quit installation process */
    1487         bb_error_msg_and_die("subprocess pre-installation script returned error.");
     1512        bb_error_msg_and_die("subprocess pre-installation script returned error");
    14881513    }
    14891514
     
    14921517    init_archive_deb_data(archive_handle);
    14931518    archive_handle->sub_archive->action_data = data_extract_all_prefix;
    1494     archive_handle->sub_archive->buffer = "/";
     1519    archive_handle->sub_archive->buffer = (char*)"/"; /* huh? */
    14951520    archive_handle->sub_archive->flags |= ARCHIVE_EXTRACT_UNCONDITIONAL;
    14961521    unpack_ar_archive(archive_handle);
    14971522
    14981523    /* Create the list file */
    1499     strcat(info_prefix, "list");
    1500     out_stream = bb_xfopen(info_prefix, "w");
     1524    list_filename = xasprintf("/var/lib/dpkg/info/%s.list", package_name);
     1525    out_stream = xfopen(list_filename, "w");
    15011526    while (archive_handle->sub_archive->passed) {
    15021527        /* the leading . has been stripped by data_extract_all_prefix already */
     
    15121537
    15131538    free(info_prefix);
     1539    free(list_filename);
    15141540}
    15151541
     
    15201546    const int status_num = search_status_hashtable(package_name);
    15211547
    1522     printf("Setting up %s (%s) ...\n", package_name, package_version);
     1548    printf("Setting up %s (%s)...\n", package_name, package_version);
    15231549
    15241550    /* Run the postinst script */
    15251551    if (run_package_script(package_name, "postinst") != 0) {
    15261552        /* TODO: handle failure gracefully */
    1527         bb_error_msg_and_die("postrm failure.. set status to what?");
     1553        bb_error_msg_and_die("postinst failure.. set status to what?");
    15281554    }
    15291555    /* Change status to reflect success */
     
    15321558}
    15331559
     1560int dpkg_main(int argc, char **argv);
    15341561int dpkg_main(int argc, char **argv)
    15351562{
    15361563    deb_file_t **deb_file = NULL;
    15371564    status_node_t *status_node;
     1565    char *str_f;
    15381566    int opt;
    15391567    int package_num;
    1540     int dpkg_opt = 0;
    15411568    int deb_count = 0;
    15421569    int state_status;
    15431570    int status_num;
    15441571    int i;
    1545 
    1546     while ((opt = getopt(argc, argv, "CF:ilPru")) != -1) {
    1547         switch (opt) {
    1548             case 'C': // equivalent to --configure in official dpkg
    1549                 dpkg_opt |= dpkg_opt_configure;
    1550                 dpkg_opt |= dpkg_opt_package_name;
    1551                 break;
    1552             case 'F': // equivalent to --force in official dpkg
    1553                 if (strcmp(optarg, "depends") == 0) {
    1554                     dpkg_opt |= dpkg_opt_force_ignore_depends;
    1555                 }
    1556                 break;
    1557             case 'i':
    1558                 dpkg_opt |= dpkg_opt_install;
    1559                 dpkg_opt |= dpkg_opt_filename;
    1560                 break;
    1561             case 'l':
    1562                 dpkg_opt |= dpkg_opt_list_installed;
    1563                 break;
    1564             case 'P':
    1565                 dpkg_opt |= dpkg_opt_purge;
    1566                 dpkg_opt |= dpkg_opt_package_name;
    1567                 break;
    1568             case 'r':
    1569                 dpkg_opt |= dpkg_opt_remove;
    1570                 dpkg_opt |= dpkg_opt_package_name;
    1571                 break;
    1572             case 'u':   /* Equivalent to --unpack in official dpkg */
    1573                 dpkg_opt |= dpkg_opt_unpack;
    1574                 dpkg_opt |= dpkg_opt_filename;
    1575                 break;
    1576             default:
    1577                 bb_show_usage();
    1578         }
    1579     }
    1580     /* check for non-otion argument if expected  */
    1581     if ((dpkg_opt == 0) || ((argc == optind) && !(dpkg_opt && dpkg_opt_list_installed))) {
     1572    enum {
     1573        OPT_configure = 0x1,
     1574        OPT_force_ignore_depends = 0x2,
     1575        OPT_install = 0x4,
     1576        OPT_list_installed = 0x8,
     1577        OPT_purge = 0x10,
     1578        OPT_remove = 0x20,
     1579        OPT_unpack = 0x40,
     1580    };
     1581
     1582    opt = getopt32(argv, "CF:ilPru", &str_f);
     1583    //if (opt & OPT_configure) ... // -C
     1584    if (opt & OPT_force_ignore_depends) { // -F (--force in official dpkg)
     1585        if (strcmp(str_f, "depends"))
     1586            opt &= ~OPT_force_ignore_depends;
     1587    }
     1588    //if (opt & OPT_install) ... // -i
     1589    //if (opt & OPT_list_installed) ... // -l
     1590    //if (opt & OPT_purge) ... // -P
     1591    //if (opt & OPT_remove) ... // -r
     1592    //if (opt & OPT_unpack) ... // -u (--unpack in official dpkg)
     1593    argc -= optind;
     1594    argv += optind;
     1595    /* check for non-option argument if expected  */
     1596    if (!opt || (!argc && !(opt && OPT_list_installed)))
    15821597        bb_show_usage();
    1583     }
     1598
     1599    name_hashtable = xzalloc(sizeof(name_hashtable[0]) * (NAME_HASH_PRIME + 1));
     1600    package_hashtable = xzalloc(sizeof(package_hashtable[0]) * (PACKAGE_HASH_PRIME + 1));
     1601    status_hashtable = xzalloc(sizeof(status_hashtable[0]) * (STATUS_HASH_PRIME + 1));
    15841602
    15851603/*  puts("(Reading database ... xxxxx files and directories installed.)"); */
     
    15871605
    15881606    /* if the list action was given print the installed packages and exit */
    1589     if (dpkg_opt & dpkg_opt_list_installed) {
     1607    if (opt & OPT_list_installed) {
    15901608        list_packages();
    1591         return(EXIT_SUCCESS);
     1609        return EXIT_SUCCESS;
    15921610    }
    15931611
    15941612    /* Read arguments and store relevant info in structs */
    1595     while (optind < argc) {
     1613    while (*argv) {
    15961614        /* deb_count = nb_elem - 1 and we need nb_elem + 1 to allocate terminal node [NULL pointer] */
    1597         deb_file = xrealloc(deb_file, sizeof(deb_file_t *) * (deb_count + 2));
    1598         deb_file[deb_count] = (deb_file_t *) xzalloc(sizeof(deb_file_t));
    1599         if (dpkg_opt & dpkg_opt_filename) {
     1615        deb_file = xrealloc(deb_file, sizeof(deb_file[0]) * (deb_count + 2));
     1616        deb_file[deb_count] = xzalloc(sizeof(deb_file[0][0]));
     1617        if (opt & (OPT_install | OPT_unpack)) {
     1618            /* -i/-u: require filename */
    16001619            archive_handle_t *archive_handle;
    16011620            llist_t *control_list = NULL;
    16021621
    16031622            /* Extract the control file */
    1604             llist_add_to(&control_list, "./control");
    1605             archive_handle = init_archive_deb_ar(argv[optind]);
     1623            llist_add_to(&control_list, (char*)"./control");
     1624            archive_handle = init_archive_deb_ar(argv[0]);
    16061625            init_archive_deb_control(archive_handle);
    16071626            deb_file[deb_count]->control_file = deb_extract_control_file_to_buffer(archive_handle, control_list);
    16081627            if (deb_file[deb_count]->control_file == NULL) {
    1609                 bb_error_msg_and_die("Couldnt extract control file");
    1610             }
    1611             deb_file[deb_count]->filename = bb_xstrdup(argv[optind]);
     1628                bb_error_msg_and_die("cannot extract control file");
     1629            }
     1630            deb_file[deb_count]->filename = xstrdup(argv[0]);
    16121631            package_num = fill_package_struct(deb_file[deb_count]->control_file);
    16131632
    16141633            if (package_num == -1) {
    1615                 bb_error_msg("Invalid control file in %s", argv[optind]);
    1616                 optind++;
     1634                bb_error_msg("invalid control file in %s", argv[0]);
     1635                argv++;
    16171636                continue;
    16181637            }
    1619             deb_file[deb_count]->package = (unsigned int) package_num;
     1638            deb_file[deb_count]->package = (unsigned) package_num;
    16201639
    16211640            /* Add the package to the status hashtable */
    1622             if ((dpkg_opt & dpkg_opt_unpack) || (dpkg_opt & dpkg_opt_install)) {
     1641            if (opt & (OPT_unpack | OPT_install)) {
    16231642                /* Try and find a currently installed version of this package */
    16241643                status_num = search_status_hashtable(name_hashtable[package_hashtable[deb_file[deb_count]->package]->name]);
    16251644                /* If no previous entry was found initialise a new entry */
    1626                 if ((status_hashtable[status_num] == NULL) ||
    1627                     (status_hashtable[status_num]->status == 0)) {
    1628                     status_node = (status_node_t *) xmalloc(sizeof(status_node_t));
     1645                if (status_hashtable[status_num] == NULL
     1646                 || status_hashtable[status_num]->status == 0
     1647                ) {
     1648                    status_node = xmalloc(sizeof(status_node_t));
    16291649                    status_node->package = deb_file[deb_count]->package;
    16301650                    /* reinstreq isnt changed to "ok" until the package control info
     
    16371657                }
    16381658            }
    1639         }
    1640         else if (dpkg_opt & dpkg_opt_package_name) {
     1659        } else if (opt & (OPT_configure | OPT_purge | OPT_remove)) {
     1660            /* -C/-p/-r: require package name */
    16411661            deb_file[deb_count]->package = search_package_hashtable(
    1642                 search_name_hashtable(argv[optind]),
    1643                 search_name_hashtable("ANY"), VER_ANY);
     1662                    search_name_hashtable(argv[0]),
     1663                    search_name_hashtable("ANY"), VER_ANY);
    16441664            if (package_hashtable[deb_file[deb_count]->package] == NULL) {
    1645                 bb_error_msg_and_die("Package %s is uninstalled or unknown\n", argv[optind]);
     1665                bb_error_msg_and_die("package %s is uninstalled or unknown", argv[0]);
    16461666            }
    16471667            package_num = deb_file[deb_count]->package;
     
    16501670
    16511671            /* check package status is "installed" */
    1652             if (dpkg_opt & dpkg_opt_remove) {
    1653                 if ((strcmp(name_hashtable[state_status], "not-installed") == 0) ||
    1654                     (strcmp(name_hashtable[state_status], "config-files") == 0)) {
    1655                     bb_error_msg_and_die("%s is already removed.", name_hashtable[package_hashtable[package_num]->name]);
     1672            if (opt & OPT_remove) {
     1673                if (strcmp(name_hashtable[state_status], "not-installed") == 0
     1674                 || strcmp(name_hashtable[state_status], "config-files") == 0
     1675                ) {
     1676                    bb_error_msg_and_die("%s is already removed", name_hashtable[package_hashtable[package_num]->name]);
    16561677                }
    16571678                set_status(status_num, "deinstall", 1);
    1658             }
    1659             else if (dpkg_opt & dpkg_opt_purge) {
     1679            } else if (opt & OPT_purge) {
    16601680                /* if package status is "conf-files" then its ok */
    16611681                if (strcmp(name_hashtable[state_status], "not-installed") == 0) {
    1662                     bb_error_msg_and_die("%s is already purged.", name_hashtable[package_hashtable[package_num]->name]);
     1682                    bb_error_msg_and_die("%s is already purged", name_hashtable[package_hashtable[package_num]->name]);
    16631683                }
    16641684                set_status(status_num, "purge", 1);
     
    16661686        }
    16671687        deb_count++;
    1668         optind++;
    1669     }
     1688        argv++;
     1689    }
     1690    if (!deb_count)
     1691        bb_error_msg_and_die("no package files specified");
    16701692    deb_file[deb_count] = NULL;
    16711693
    16721694    /* Check that the deb file arguments are installable */
    1673     if ((dpkg_opt & dpkg_opt_force_ignore_depends) != dpkg_opt_force_ignore_depends) {
     1695    if (!(opt & OPT_force_ignore_depends)) {
    16741696        if (!check_deps(deb_file, 0, deb_count)) {
    1675             bb_error_msg_and_die("Dependency check failed");
     1697            bb_error_msg_and_die("dependency check failed");
    16761698        }
    16771699    }
     
    16801702    for (i = 0; i < deb_count; i++) {
    16811703        /* Remove or purge packages */
    1682         if (dpkg_opt & dpkg_opt_remove) {
     1704        if (opt & OPT_remove) {
    16831705            remove_package(deb_file[i]->package, 1);
    16841706        }
    1685         else if (dpkg_opt & dpkg_opt_purge) {
     1707        else if (opt & OPT_purge) {
    16861708            purge_package(deb_file[i]->package);
    16871709        }
    1688         else if (dpkg_opt & dpkg_opt_unpack) {
     1710        else if (opt & OPT_unpack) {
    16891711            unpack_package(deb_file[i]);
    16901712        }
    1691         else if (dpkg_opt & dpkg_opt_install) {
     1713        else if (opt & OPT_install) {
    16921714            unpack_package(deb_file[i]);
    16931715            /* package is configured in second pass below */
    16941716        }
    1695         else if (dpkg_opt & dpkg_opt_configure) {
     1717        else if (opt & OPT_configure) {
    16961718            configure_package(deb_file[i]);
    16971719        }
    16981720    }
    16991721    /* configure installed packages */
    1700     if (dpkg_opt & dpkg_opt_install) {
     1722    if (opt & OPT_install) {
    17011723        for (i = 0; i < deb_count; i++)
    17021724            configure_package(deb_file[i]);
     
    17051727    write_status_file(deb_file);
    17061728
    1707     for (i = 0; i < deb_count; i++) {
    1708         free(deb_file[i]->control_file);
    1709         free(deb_file[i]->filename);
    1710         free(deb_file[i]);
    1711     }
    1712 
    1713     free(deb_file);
    1714 
    1715     for (i = 0; i < NAME_HASH_PRIME; i++) {
    1716         free(name_hashtable[i]);
    1717     }
    1718 
    1719     for (i = 0; i < PACKAGE_HASH_PRIME; i++) {
    1720         if (package_hashtable[i] != NULL) {
     1729    if (ENABLE_FEATURE_CLEAN_UP) {
     1730        for (i = 0; i < deb_count; i++) {
     1731            free(deb_file[i]->control_file);
     1732            free(deb_file[i]->filename);
     1733            free(deb_file[i]);
     1734        }
     1735
     1736        free(deb_file);
     1737
     1738        for (i = 0; i < NAME_HASH_PRIME; i++) {
     1739            free(name_hashtable[i]);
     1740        }
     1741
     1742        for (i = 0; i < PACKAGE_HASH_PRIME; i++) {
    17211743            free_package(package_hashtable[i]);
    17221744        }
    1723     }
    1724 
    1725     for (i = 0; i < STATUS_HASH_PRIME; i++) {
    1726         free(status_hashtable[i]);
    1727     }
    1728 
    1729     return(EXIT_SUCCESS);
    1730 }
    1731 
     1745
     1746        for (i = 0; i < STATUS_HASH_PRIME; i++) {
     1747            free(status_hashtable[i]);
     1748        }
     1749
     1750        free(status_hashtable);
     1751        free(package_hashtable);
     1752        free(name_hashtable);
     1753    }
     1754
     1755    return EXIT_SUCCESS;
     1756}
Note: See TracChangeset for help on using the changeset viewer.