*: more readable handling of pipe fds. No code changes.
[oweals/busybox.git] / networking / udhcp / script.c
index 98706a592977e9d3c406bf29f55758e4270103a0..71f0333280bdbc2b8f6882c4c5129819973fc9f3 100644 (file)
@@ -14,7 +14,7 @@
 
 
 /* get a rough idea of how long an option will be (rounding up...) */
-static const int max_option_length[] = {
+static const uint8_t max_option_length[] = {
        [OPTION_IP] =           sizeof("255.255.255.255 "),
        [OPTION_IP_PAIR] =      sizeof("255.255.255.255 ") * 2,
        [OPTION_STRING] =       1,
@@ -33,7 +33,7 @@ static const int max_option_length[] = {
 static inline int upper_length(int length, int opt_index)
 {
        return max_option_length[opt_index] *
-               (length / option_lengths[opt_index]);
+               (length / dhcp_option_lengths[opt_index]);
 }
 
 
@@ -44,19 +44,20 @@ static int sprintip(char *dest, const char *pre, const uint8_t *ip)
 
 
 /* really simple implementation, just count the bits */
-static int mton(struct in_addr *mask)
+static int mton(uint32_t mask)
 {
-       int i;
-       unsigned long bits = ntohl(mask->s_addr);
-       /* too bad one can't check the carry bit, etc in c bit
-        * shifting */
-       for (i = 0; i < 32 && !((bits >> i) & 1); i++);
-       return 32 - i;
+       int i = 0;
+       mask = ntohl(mask); /* 111110000-like bit pattern */
+       while (mask) {
+               i++;
+               mask <<= 1;
+       }
+       return i;
 }
 
 
 /* Allocate and fill with the text of option 'option'. */
-static char *alloc_fill_opts(uint8_t *option, const struct dhcp_option *type_p)
+static char *alloc_fill_opts(uint8_t *option, const struct dhcp_option *type_p, const char *opt_name)
 {
        int len, type, optlen;
        uint16_t val_u16;
@@ -67,10 +68,10 @@ static char *alloc_fill_opts(uint8_t *option, const struct dhcp_option *type_p)
 
        len = option[OPT_LEN - 2];
        type = type_p->flags & TYPE_MASK;
-       optlen = option_lengths[type];
+       optlen = dhcp_option_lengths[type];
 
-       dest = ret = xmalloc(upper_length(len, type) + strlen(type_p->name) + 2);
-       dest += sprintf(ret, "%s=", type_p->name);
+       dest = ret = xmalloc(upper_length(len, type) + strlen(opt_name) + 2);
+       dest += sprintf(ret, "%s=", opt_name);
 
        for (;;) {
                switch (type) {
@@ -132,8 +133,8 @@ static char **fill_envp(struct dhcpMessage *packet)
        int i, j;
        char **envp;
        char *var;
+       const char *opt_name;
        uint8_t *temp;
-       struct in_addr subnet;
        char over = 0;
 
        if (packet) {
@@ -171,17 +172,23 @@ static char **fill_envp(struct dhcpMessage *packet)
        envp[j] = xmalloc(sizeof("ip=255.255.255.255"));
        sprintip(envp[j++], "ip=", (uint8_t *) &packet->yiaddr);
 
-       for (i = 0; dhcp_options[i].code; i++) {
+       opt_name = dhcp_option_strings;
+       i = 0;
+       while (*opt_name) {
                temp = get_option(packet, dhcp_options[i].code);
                if (!temp)
-                       continue;
-               envp[j++] = alloc_fill_opts(temp, &dhcp_options[i]);
+                       goto next;
+               envp[j++] = alloc_fill_opts(temp, &dhcp_options[i], opt_name);
 
                /* Fill in a subnet bits option for things like /24 */
                if (dhcp_options[i].code == DHCP_SUBNET) {
+                       uint32_t subnet;
                        memcpy(&subnet, temp, 4);
-                       envp[j++] = xasprintf("mask=%d", mton(&subnet));
+                       envp[j++] = xasprintf("mask=%d", mton(subnet));
                }
+ next:
+               opt_name += strlen(opt_name) + 1;
+               i++;
        }
        if (packet->siaddr) {
                envp[j] = xmalloc(sizeof("siaddr=255.255.255.255"));
@@ -225,7 +232,7 @@ void udhcp_run_script(struct dhcpMessage *packet, const char *name)
                       name, NULL, envp);
                bb_perror_msg_and_die("script %s failed", client_config.script);
        }
-       waitpid(pid, NULL, 0);
+       safe_waitpid(pid, NULL, 0);
        for (curr = envp; *curr; curr++)
                free(*curr);
        free(envp);