Ignore:
Timestamp:
Nov 4, 2007, 3:16:40 AM (17 years ago)
Author:
Bruno Cornec
Message:

Update to busybox 1.7.2

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.5/mindi-busybox/networking/udhcp/files.c

    r821 r1765  
     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.