Ignore:
Timestamp:
Nov 6, 2007, 11:01:53 AM (13 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/networking/udhcp/files.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * files.c -- DHCP server file manipulation *
     
    45 */
    56
    6 #include <sys/socket.h>
    7 #include <arpa/inet.h>
    8 #include <string.h>
    9 #include <stdlib.h>
    10 #include <time.h>
    11 #include <ctype.h>
    12 #include <netdb.h>
    13 
    147#include <netinet/ether.h>
    15 #include "static_leases.h"
    16 
     8
     9#include "common.h"
    1710#include "dhcpd.h"
    1811#include "options.h"
    19 #include "files.h"
    20 #include "common.h"
     12
     13
     14/* on these functions, make sure your datatype matches */
     15static int read_ip(const char *line, void *arg)
     16{
     17    len_and_sockaddr *lsa;
     18
     19    lsa = host_and_af2sockaddr(line, 0, AF_INET);
     20    if (!lsa)
     21        return 0;
     22    *(uint32_t*)arg = lsa->sin.sin_addr.s_addr;
     23    free(lsa);
     24    return 1;
     25}
     26
     27static int read_mac(const char *line, void *arg)
     28{
     29    uint8_t *mac_bytes = arg;
     30    struct ether_addr *temp_ether_addr;
     31
     32    temp_ether_addr = ether_aton(line);
     33    if (temp_ether_addr == NULL)
     34        return 0;
     35    memcpy(mac_bytes, temp_ether_addr, 6);
     36    return 1;
     37}
     38
     39
     40static int read_str(const char *line, void *arg)
     41{
     42    char **dest = arg;
     43
     44    free(*dest);
     45    *dest = xstrdup(line);
     46    return 1;
     47}
     48
     49
     50static int read_u32(const char *line, void *arg)
     51{
     52    *(uint32_t*)arg = bb_strtou32(line, NULL, 10);
     53    return errno == 0;
     54}
     55
     56
     57static int read_yn(const char *line, void *arg)
     58{
     59    char *dest = arg;
     60
     61    if (!strcasecmp("yes", line)) {
     62        *dest = 1;
     63        return 1;
     64    }
     65    if (!strcasecmp("no", line)) {
     66        *dest = 0;
     67        return 1;
     68    }
     69    return 0;
     70}
     71
     72
     73/* find option 'code' in opt_list */
     74struct option_set *find_option(struct option_set *opt_list, char code)
     75{
     76    while (opt_list && opt_list->data[OPT_CODE] < code)
     77        opt_list = opt_list->next;
     78
     79    if (opt_list && opt_list->data[OPT_CODE] == code)
     80        return opt_list;
     81    return NULL;
     82}
     83
     84
     85/* add an option to the opt_list */
     86static void attach_option(struct option_set **opt_list,
     87        const struct dhcp_option *option, char *buffer, int length)
     88{
     89    struct option_set *existing, *new, **curr;
     90
     91    existing = find_option(*opt_list, option->code);
     92    if (!existing) {
     93        DEBUG("Attaching option %s to list", option->name);
     94
     95#if ENABLE_FEATURE_RFC3397
     96        if ((option->flags & TYPE_MASK) == OPTION_STR1035)
     97            /* reuse buffer and length for RFC1035-formatted string */
     98            buffer = dname_enc(NULL, 0, buffer, &length);
     99#endif
     100
     101        /* make a new option */
     102        new = xmalloc(sizeof(*new));
     103        new->data = xmalloc(length + 2);
     104        new->data[OPT_CODE] = option->code;
     105        new->data[OPT_LEN] = length;
     106        memcpy(new->data + 2, buffer, length);
     107
     108        curr = opt_list;
     109        while (*curr && (*curr)->data[OPT_CODE] < option->code)
     110            curr = &(*curr)->next;
     111
     112        new->next = *curr;
     113        *curr = new;
     114#if ENABLE_FEATURE_RFC3397
     115        if ((option->flags & TYPE_MASK) == OPTION_STR1035 && buffer != NULL)
     116            free(buffer);
     117#endif
     118        return;
     119    }
     120
     121    /* add it to an existing option */
     122    DEBUG("Attaching option %s to existing member of list", option->name);
     123    if (option->flags & OPTION_LIST) {
     124#if ENABLE_FEATURE_RFC3397
     125        if ((option->flags & TYPE_MASK) == OPTION_STR1035)
     126            /* reuse buffer and length for RFC1035-formatted string */
     127            buffer = dname_enc(existing->data + 2,
     128                    existing->data[OPT_LEN], buffer, &length);
     129#endif
     130        if (existing->data[OPT_LEN] + length <= 255) {
     131            existing->data = xrealloc(existing->data,
     132                    existing->data[OPT_LEN] + length + 3);
     133            if ((option->flags & TYPE_MASK) == OPTION_STRING) {
     134                /* ' ' can bring us to 256 - bad */
     135                if (existing->data[OPT_LEN] + length >= 255)
     136                    return;
     137                /* add space separator between STRING options in a list */
     138                existing->data[existing->data[OPT_LEN] + 2] = ' ';
     139                existing->data[OPT_LEN]++;
     140            }
     141            memcpy(existing->data + existing->data[OPT_LEN] + 2, buffer, length);
     142            existing->data[OPT_LEN] += length;
     143        } /* else, ignore the data, we could put this in a second option in the future */
     144#if ENABLE_FEATURE_RFC3397
     145        if ((option->flags & TYPE_MASK) == OPTION_STR1035 && buffer != NULL)
     146            free(buffer);
     147#endif
     148    } /* else, ignore the new data */
     149}
     150
     151
     152/* read a dhcp option and add it to opt_list */
     153static int read_opt(const char *const_line, void *arg)
     154{
     155    struct option_set **opt_list = arg;
     156    char *opt, *val, *endptr;
     157    const struct dhcp_option *option;
     158    int retval = 0, length;
     159    char buffer[8];
     160    char *line;
     161    uint16_t *result_u16 = (uint16_t *) buffer;
     162    uint32_t *result_u32 = (uint32_t *) buffer;
     163
     164    /* Cheat, the only const line we'll actually get is "" */
     165    line = (char *) const_line;
     166    opt = strtok(line, " \t=");
     167    if (!opt) return 0;
     168
     169    option = dhcp_options;
     170    while (1) {
     171        if (!option->code)
     172            return 0;
     173        if (!strcasecmp(option->name, opt))
     174            break;
     175        option++;
     176    }
     177
     178    do {
     179        val = strtok(NULL, ", \t");
     180        if (!val) break;
     181        length = option_lengths[option->flags & TYPE_MASK];
     182        retval = 0;
     183        opt = buffer; /* new meaning for variable opt */
     184        switch (option->flags & TYPE_MASK) {
     185        case OPTION_IP:
     186            retval = read_ip(val, buffer);
     187            break;
     188        case OPTION_IP_PAIR:
     189            retval = read_ip(val, buffer);
     190            val = strtok(NULL, ", \t/-");
     191            if (!val)
     192                retval = 0;
     193            if (retval)
     194                retval = read_ip(val, buffer + 4);
     195            break;
     196        case OPTION_STRING:
     197#if ENABLE_FEATURE_RFC3397
     198        case OPTION_STR1035:
     199#endif
     200            length = strlen(val);
     201            if (length > 0) {
     202                if (length > 254) length = 254;
     203                opt = val;
     204                retval = 1;
     205            }
     206            break;
     207        case OPTION_BOOLEAN:
     208            retval = read_yn(val, buffer);
     209            break;
     210        case OPTION_U8:
     211            buffer[0] = strtoul(val, &endptr, 0);
     212            retval = (endptr[0] == '\0');
     213            break;
     214        /* htonX are macros in older libc's, using temp var
     215         * in code below for safety */
     216        /* TODO: use bb_strtoX? */
     217        case OPTION_U16: {
     218            unsigned long tmp = strtoul(val, &endptr, 0);
     219            *result_u16 = htons(tmp);
     220            retval = (endptr[0] == '\0' /*&& tmp < 0x10000*/);
     221            break;
     222        }
     223        case OPTION_S16: {
     224            long tmp = strtol(val, &endptr, 0);
     225            *result_u16 = htons(tmp);
     226            retval = (endptr[0] == '\0');
     227            break;
     228        }
     229        case OPTION_U32: {
     230            unsigned long tmp = strtoul(val, &endptr, 0);
     231            *result_u32 = htonl(tmp);
     232            retval = (endptr[0] == '\0');
     233            break;
     234        }
     235        case OPTION_S32: {
     236            long tmp = strtol(val, &endptr, 0);
     237            *result_u32 = htonl(tmp);
     238            retval = (endptr[0] == '\0');
     239            break;
     240        }
     241        default:
     242            break;
     243        }
     244        if (retval)
     245            attach_option(opt_list, option, opt, length);
     246    } while (retval && option->flags & OPTION_LIST);
     247    return retval;
     248}
     249
     250static int read_staticlease(const char *const_line, void *arg)
     251{
     252    char *line;
     253    char *mac_string;
     254    char *ip_string;
     255    uint8_t *mac_bytes;
     256    uint32_t *ip;
     257
     258    /* Allocate memory for addresses */
     259    mac_bytes = xmalloc(sizeof(unsigned char) * 8);
     260    ip = xmalloc(sizeof(uint32_t));
     261
     262    /* Read mac */
     263    line = (char *) const_line;
     264    mac_string = strtok(line, " \t");
     265    read_mac(mac_string, mac_bytes);
     266
     267    /* Read ip */
     268    ip_string = strtok(NULL, " \t");
     269    read_ip(ip_string, ip);
     270
     271    addStaticLease(arg, mac_bytes, ip);
     272
     273    if (ENABLE_FEATURE_UDHCP_DEBUG) printStaticLeases(arg);
     274
     275    return 1;
     276}
     277
     278
     279struct config_keyword {
     280    const char *keyword;
     281    int (*handler)(const char *line, void *var);
     282    void *var;
     283    const char *def;
     284};
     285
     286static const struct config_keyword keywords[] = {
     287    /* keyword       handler   variable address               default */
     288    {"start",        read_ip,  &(server_config.start_ip),     "192.168.0.20"},
     289    {"end",          read_ip,  &(server_config.end_ip),       "192.168.0.254"},
     290    {"interface",    read_str, &(server_config.interface),    "eth0"},
     291    {"option",       read_opt, &(server_config.options),      ""},
     292    {"opt",          read_opt, &(server_config.options),      ""},
     293    /* Avoid "max_leases value not sane" warning by setting default
     294     * to default_end_ip - default_start_ip + 1: */
     295    {"max_leases",   read_u32, &(server_config.max_leases),   "235"},
     296    {"remaining",    read_yn,  &(server_config.remaining),    "yes"},
     297    {"auto_time",    read_u32, &(server_config.auto_time),    "7200"},
     298    {"decline_time", read_u32, &(server_config.decline_time), "3600"},
     299    {"conflict_time",read_u32, &(server_config.conflict_time),"3600"},
     300    {"offer_time",   read_u32, &(server_config.offer_time),   "60"},
     301    {"min_lease",    read_u32, &(server_config.min_lease),    "60"},
     302    {"lease_file",   read_str, &(server_config.lease_file),   LEASES_FILE},
     303    {"pidfile",      read_str, &(server_config.pidfile),      "/var/run/udhcpd.pid"},
     304    {"notify_file",  read_str, &(server_config.notify_file),  ""},
     305    {"siaddr",       read_ip,  &(server_config.siaddr),       "0.0.0.0"},
     306    {"sname",        read_str, &(server_config.sname),        ""},
     307    {"boot_file",    read_str, &(server_config.boot_file),    ""},
     308    {"static_lease", read_staticlease, &(server_config.static_leases), ""},
     309    /* ADDME: static lease */
     310};
     311
    21312
    22313/*
     
    27318#define READ_CONFIG_BUF_SIZE 80
    28319
    29 /* on these functions, make sure you datatype matches */
    30 static int read_ip(const char *line, void *arg)
    31 {
    32     struct in_addr *addr = arg;
    33     struct hostent *host;
    34     int retval = 1;
    35 
    36     if (!inet_aton(line, addr)) {
    37         if ((host = gethostbyname(line)))
    38             addr->s_addr = *((unsigned long *) host->h_addr_list[0]);
    39         else retval = 0;
    40     }
    41     return retval;
    42 }
    43 
    44 static int read_mac(const char *line, void *arg)
    45 {
    46     uint8_t *mac_bytes = arg;
    47     struct ether_addr *temp_ether_addr;
    48     int retval = 1;
    49 
    50     temp_ether_addr = ether_aton(line);
    51 
    52     if(temp_ether_addr == NULL)
    53         retval = 0;
    54     else
    55         memcpy(mac_bytes, temp_ether_addr, 6);
    56 
    57     return retval;
    58 }
    59 
    60 
    61 static int read_str(const char *line, void *arg)
    62 {
    63     char **dest = arg;
    64 
    65     free(*dest);
    66     *dest = strdup(line);
    67 
    68     return 1;
    69 }
    70 
    71 
    72 static int read_u32(const char *line, void *arg)
    73 {
    74     uint32_t *dest = arg;
    75     char *endptr;
    76     *dest = strtoul(line, &endptr, 0);
    77     return endptr[0] == '\0';
    78 }
    79 
    80 
    81 static int read_yn(const char *line, void *arg)
    82 {
    83     char *dest = arg;
    84     int retval = 1;
    85 
    86     if (!strcasecmp("yes", line))
    87         *dest = 1;
    88     else if (!strcasecmp("no", line))
    89         *dest = 0;
    90     else retval = 0;
    91 
    92     return retval;
    93 }
    94 
    95 
    96 /* find option 'code' in opt_list */
    97 struct option_set *find_option(struct option_set *opt_list, char code)
    98 {
    99     while (opt_list && opt_list->data[OPT_CODE] < code)
    100         opt_list = opt_list->next;
    101 
    102     if (opt_list && opt_list->data[OPT_CODE] == code) return opt_list;
    103     else return NULL;
    104 }
    105 
    106 
    107 /* add an option to the opt_list */
    108 static void attach_option(struct option_set **opt_list, struct dhcp_option *option, char *buffer, int length)
    109 {
    110     struct option_set *existing, *new, **curr;
    111 
    112     /* add it to an existing option */
    113     if ((existing = find_option(*opt_list, option->code))) {
    114         DEBUG(LOG_INFO, "Attaching option %s to existing member of list", option->name);
    115         if (option->flags & OPTION_LIST) {
    116             if (existing->data[OPT_LEN] + length <= 255) {
    117                 existing->data = realloc(existing->data,
    118                         existing->data[OPT_LEN] + length + 2);
    119                 memcpy(existing->data + existing->data[OPT_LEN] + 2, buffer, length);
    120                 existing->data[OPT_LEN] += length;
    121             } /* else, ignore the data, we could put this in a second option in the future */
    122         } /* else, ignore the new data */
    123     } else {
    124         DEBUG(LOG_INFO, "Attaching option %s to list", option->name);
    125 
    126         /* make a new option */
    127         new = xmalloc(sizeof(struct option_set));
    128         new->data = xmalloc(length + 2);
    129         new->data[OPT_CODE] = option->code;
    130         new->data[OPT_LEN] = length;
    131         memcpy(new->data + 2, buffer, length);
    132 
    133         curr = opt_list;
    134         while (*curr && (*curr)->data[OPT_CODE] < option->code)
    135             curr = &(*curr)->next;
    136 
    137         new->next = *curr;
    138         *curr = new;
    139     }
    140 }
    141 
    142 
    143 /* read a dhcp option and add it to opt_list */
    144 static int read_opt(const char *const_line, void *arg)
    145 {
    146     struct option_set **opt_list = arg;
    147     char *opt, *val, *endptr;
    148     struct dhcp_option *option;
    149     int retval = 0, length;
    150     char buffer[8];
    151     char *line;
    152     uint16_t *result_u16 = (uint16_t *) buffer;
    153     uint32_t *result_u32 = (uint32_t *) buffer;
    154 
    155     /* Cheat, the only const line we'll actually get is "" */
    156     line = (char *) const_line;
    157     if (!(opt = strtok(line, " \t="))) return 0;
    158 
    159     for (option = dhcp_options; option->code; option++)
    160         if (!strcasecmp(option->name, opt))
    161             break;
    162 
    163     if (!option->code) return 0;
    164 
    165     do {
    166         if (!(val = strtok(NULL, ", \t"))) break;
    167         length = option_lengths[option->flags & TYPE_MASK];
    168         retval = 0;
    169         opt = buffer; /* new meaning for variable opt */
    170         switch (option->flags & TYPE_MASK) {
    171         case OPTION_IP:
    172             retval = read_ip(val, buffer);
    173             break;
    174         case OPTION_IP_PAIR:
    175             retval = read_ip(val, buffer);
    176             if (!(val = strtok(NULL, ", \t/-"))) retval = 0;
    177             if (retval) retval = read_ip(val, buffer + 4);
    178             break;
    179         case OPTION_STRING:
    180             length = strlen(val);
    181             if (length > 0) {
    182                 if (length > 254) length = 254;
    183                 opt = val;
    184                 retval = 1;
    185             }
    186             break;
    187         case OPTION_BOOLEAN:
    188             retval = read_yn(val, buffer);
    189             break;
    190         case OPTION_U8:
    191             buffer[0] = strtoul(val, &endptr, 0);
    192             retval = (endptr[0] == '\0');
    193             break;
    194         case OPTION_U16:
    195             *result_u16 = htons(strtoul(val, &endptr, 0));
    196             retval = (endptr[0] == '\0');
    197             break;
    198         case OPTION_S16:
    199             *result_u16 = htons(strtol(val, &endptr, 0));
    200             retval = (endptr[0] == '\0');
    201             break;
    202         case OPTION_U32:
    203             *result_u32 = htonl(strtoul(val, &endptr, 0));
    204             retval = (endptr[0] == '\0');
    205             break;
    206         case OPTION_S32:
    207             *result_u32 = htonl(strtol(val, &endptr, 0));
    208             retval = (endptr[0] == '\0');
    209             break;
    210         default:
    211             break;
    212         }
    213         if (retval)
    214             attach_option(opt_list, option, opt, length);
    215     } while (retval && option->flags & OPTION_LIST);
    216     return retval;
    217 }
    218 
    219 static int read_staticlease(const char *const_line, void *arg)
    220 {
    221 
    222     char *line;
    223     char *mac_string;
    224     char *ip_string;
    225     uint8_t *mac_bytes;
    226     uint32_t *ip;
    227 
    228 
    229     /* Allocate memory for addresses */
    230     mac_bytes = xmalloc(sizeof(unsigned char) * 8);
    231     ip = xmalloc(sizeof(uint32_t));
    232 
    233     /* Read mac */
    234     line = (char *) const_line;
    235     mac_string = strtok(line, " \t");
    236     read_mac(mac_string, mac_bytes);
    237 
    238     /* Read ip */
    239     ip_string = strtok(NULL, " \t");
    240     read_ip(ip_string, ip);
    241 
    242     addStaticLease(arg, mac_bytes, ip);
    243 
    244     if (ENABLE_FEATURE_UDHCP_DEBUG) printStaticLeases(arg);
    245 
    246     return 1;
    247 
    248 }
    249 
    250 
    251 static const struct config_keyword keywords[] = {
    252     /* keyword  handler   variable address      default */
    253     {"start",   read_ip,  &(server_config.start),   "192.168.0.20"},
    254     {"end",     read_ip,  &(server_config.end),     "192.168.0.254"},
    255     {"interface",   read_str, &(server_config.interface),   "eth0"},
    256     {"option",  read_opt, &(server_config.options), ""},
    257     {"opt",     read_opt, &(server_config.options), ""},
    258     {"max_leases",  read_u32, &(server_config.max_leases),  "254"},
    259     {"remaining",   read_yn,  &(server_config.remaining),   "yes"},
    260     {"auto_time",   read_u32, &(server_config.auto_time),   "7200"},
    261     {"decline_time",read_u32, &(server_config.decline_time),"3600"},
    262     {"conflict_time",read_u32,&(server_config.conflict_time),"3600"},
    263     {"offer_time",  read_u32, &(server_config.offer_time),  "60"},
    264     {"min_lease",   read_u32, &(server_config.min_lease),   "60"},
    265     {"lease_file",  read_str, &(server_config.lease_file),  LEASES_FILE},
    266     {"pidfile", read_str, &(server_config.pidfile), "/var/run/udhcpd.pid"},
    267     {"notify_file", read_str, &(server_config.notify_file), ""},
    268     {"siaddr",  read_ip,  &(server_config.siaddr),  "0.0.0.0"},
    269     {"sname",   read_str, &(server_config.sname),   ""},
    270     {"boot_file",   read_str, &(server_config.boot_file),   ""},
    271     {"static_lease",read_staticlease, &(server_config.static_leases),   ""},
    272     /*ADDME: static lease */
    273     {"",        NULL,     NULL,             ""}
    274 };
    275 
    276 
    277320int read_config(const char *file)
    278321{
     
    281324    int i, lm = 0;
    282325
    283     for (i = 0; keywords[i].keyword[0]; i++)
     326    for (i = 0; i < ARRAY_SIZE(keywords); i++)
    284327        if (keywords[i].def[0])
    285328            keywords[i].handler(keywords[i].def, keywords[i].var);
    286329
    287     if (!(in = fopen(file, "r"))) {
    288         LOG(LOG_ERR, "unable to open config file: %s", file);
     330    in = fopen_or_warn(file, "r");
     331    if (!in) {
    289332        return 0;
    290333    }
     
    292335    while (fgets(buffer, READ_CONFIG_BUF_SIZE, in)) {
    293336        char debug_orig[READ_CONFIG_BUF_SIZE];
     337        char *p;
    294338
    295339        lm++;
    296         if (strchr(buffer, '\n')) *(strchr(buffer, '\n')) = '\0';
     340        p = strchr(buffer, '\n');
     341        if (p) *p = '\0';
    297342        if (ENABLE_FEATURE_UDHCP_DEBUG) strcpy(debug_orig, buffer);
    298         if (strchr(buffer, '#')) *(strchr(buffer, '#')) = '\0';
     343        p = strchr(buffer, '#');
     344        if (p) *p = '\0';
    299345
    300346        if (!(token = strtok(buffer, " \t"))) continue;
     
    302348
    303349        /* eat leading whitespace */
    304         line = line + strspn(line, " \t=");
     350        line = skip_whitespace(line);
    305351        /* eat trailing whitespace */
    306         for (i = strlen(line); i > 0 && isspace(line[i - 1]); i--);
    307         line[i] = '\0';
    308 
    309         for (i = 0; keywords[i].keyword[0]; i++)
     352        i = strlen(line) - 1;
     353        while (i >= 0 && isspace(line[i]))
     354            line[i--] = '\0';
     355
     356        for (i = 0; i < ARRAY_SIZE(keywords); i++)
    310357            if (!strcasecmp(token, keywords[i].keyword))
    311358                if (!keywords[i].handler(line, keywords[i].var)) {
    312                     LOG(LOG_ERR, "Failure parsing line %d of %s", lm, file);
    313                     DEBUG(LOG_ERR, "unable to parse '%s'", debug_orig);
     359                    bb_error_msg("cannot parse line %d of %s", lm, file);
     360                    if (ENABLE_FEATURE_UDHCP_DEBUG)
     361                        bb_error_msg("cannot parse '%s'", debug_orig);
    314362                    /* reset back to the default value */
    315363                    keywords[i].handler(keywords[i].def, keywords[i].var);
     
    317365    }
    318366    fclose(in);
     367
     368    server_config.start_ip = ntohl(server_config.start_ip);
     369    server_config.end_ip = ntohl(server_config.end_ip);
     370
    319371    return 1;
    320372}
     
    323375void write_leases(void)
    324376{
    325     FILE *fp;
    326     unsigned int i;
    327     char buf[255];
     377    int fp;
     378    unsigned i;
    328379    time_t curr = time(0);
    329380    unsigned long tmp_time;
    330381
    331     if (!(fp = fopen(server_config.lease_file, "w"))) {
    332         LOG(LOG_ERR, "Unable to open %s for writing", server_config.lease_file);
     382    fp = open3_or_warn(server_config.lease_file, O_WRONLY|O_CREAT|O_TRUNC, 0666);
     383    if (fp < 0) {
    333384        return;
    334385    }
     
    346397            } /* else stick with the time we got */
    347398            leases[i].expires = htonl(leases[i].expires);
    348             fwrite(&leases[i], sizeof(struct dhcpOfferedAddr), 1, fp);
    349 
    350             /* Then restore it when done. */
     399            // FIXME: error check??
     400            full_write(fp, &leases[i], sizeof(leases[i]));
     401
     402            /* then restore it when done */
    351403            leases[i].expires = tmp_time;
    352404        }
    353405    }
    354     fclose(fp);
     406    close(fp);
    355407
    356408    if (server_config.notify_file) {
    357         sprintf(buf, "%s %s", server_config.notify_file, server_config.lease_file);
    358         system(buf);
     409        char *cmd = xasprintf("%s %s", server_config.notify_file, server_config.lease_file);
     410        system(cmd);
     411        free(cmd);
    359412    }
    360413}
     
    363416void read_leases(const char *file)
    364417{
    365     FILE *fp;
     418    int fp;
    366419    unsigned int i = 0;
    367420    struct dhcpOfferedAddr lease;
    368421
    369     if (!(fp = fopen(file, "r"))) {
    370         LOG(LOG_ERR, "Unable to open %s for reading", file);
     422    fp = open_or_warn(file, O_RDONLY);
     423    if (fp < 0) {
    371424        return;
    372425    }
    373426
    374     while (i < server_config.max_leases && (fread(&lease, sizeof lease, 1, fp) == 1)) {
     427    while (i < server_config.max_leases
     428     && full_read(fp, &lease, sizeof(lease)) == sizeof(lease)
     429    ) {
    375430        /* ADDME: is it a static lease */
    376         if (lease.yiaddr >= server_config.start && lease.yiaddr <= server_config.end) {
     431        uint32_t y = ntohl(lease.yiaddr);
     432        if (y >= server_config.start_ip && y <= server_config.end_ip) {
    377433            lease.expires = ntohl(lease.expires);
    378             if (!server_config.remaining) lease.expires -= time(0);
     434            if (!server_config.remaining)
     435                lease.expires -= time(0);
    379436            if (!(add_lease(lease.chaddr, lease.yiaddr, lease.expires))) {
    380                 LOG(LOG_WARNING, "Too many leases while loading %s\n", file);
     437                bb_error_msg("too many leases while loading %s", file);
    381438                break;
    382439            }
     
    384441        }
    385442    }
    386     DEBUG(LOG_INFO, "Read %d leases", i);
    387     fclose(fp);
    388 }
     443    DEBUG("Read %d leases", i);
     444    close(fp);
     445}
Note: See TracChangeset for help on using the changeset viewer.