Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/networking/udhcp/script.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/networking/udhcp/script.c
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 /* script.c 2 3 * … … 8 9 */ 9 10 10 #include <string.h>11 #include <unistd.h>12 #include <stdio.h>13 #include <stdlib.h>14 #include <sys/socket.h>15 #include <netinet/in.h>16 #include <arpa/inet.h>17 #include <sys/types.h>18 #include <sys/wait.h>19 20 11 #include "common.h" 12 #include "dhcpc.h" 21 13 #include "options.h" 22 #include "dhcpd.h" 23 #include "dhcpc.h" 14 24 15 25 16 /* get a rough idea of how long an option will be (rounding up...) */ 26 static const int max_option_length[] = {17 static const uint8_t max_option_length[] = { 27 18 [OPTION_IP] = sizeof("255.255.255.255 "), 28 19 [OPTION_IP_PAIR] = sizeof("255.255.255.255 ") * 2, 29 20 [OPTION_STRING] = 1, 21 #if ENABLE_FEATURE_RFC3397 22 [OPTION_STR1035] = 1, 23 #endif 30 24 [OPTION_BOOLEAN] = sizeof("yes "), 31 25 [OPTION_U8] = sizeof("255 "), … … 44 38 45 39 46 static int sprintip(char *dest, c har *pre,uint8_t *ip)40 static int sprintip(char *dest, const char *pre, const uint8_t *ip) 47 41 { 48 42 return sprintf(dest, "%s%d.%d.%d.%d", pre, ip[0], ip[1], ip[2], ip[3]); … … 62 56 63 57 64 /* Fill destwith the text of option 'option'. */65 static void fill_options(char *dest, uint8_t *option,struct dhcp_option *type_p)66 { 67 int type, optlen;58 /* Allocate and fill with the text of option 'option'. */ 59 static char *alloc_fill_opts(uint8_t *option, const struct dhcp_option *type_p) 60 { 61 int len, type, optlen; 68 62 uint16_t val_u16; 69 63 int16_t val_s16; 70 64 uint32_t val_u32; 71 65 int32_t val_s32; 72 int len = option[OPT_LEN - 2]; 73 74 dest += sprintf(dest, "%s=", type_p->name); 75 66 char *dest, *ret; 67 68 len = option[OPT_LEN - 2]; 76 69 type = type_p->flags & TYPE_MASK; 77 70 optlen = option_lengths[type]; 78 for(;;) { 71 72 dest = ret = xmalloc(upper_length(len, type) + strlen(type_p->name) + 2); 73 dest += sprintf(ret, "%s=", type_p->name); 74 75 for (;;) { 79 76 switch (type) { 80 77 case OPTION_IP_PAIR: 81 78 dest += sprintip(dest, "", option); 82 * (dest++)= '/';79 *dest++ = '/'; 83 80 option += 4; 84 81 optlen = 4; … … 111 108 memcpy(dest, option, len); 112 109 dest[len] = '\0'; 113 return; /* Short circuit this case */ 110 return ret; /* Short circuit this case */ 111 #if ENABLE_FEATURE_RFC3397 112 case OPTION_STR1035: 113 /* unpack option into dest; use ret for prefix (i.e., "optname=") */ 114 dest = dname_dec(option, len, ret); 115 free(ret); 116 return dest; 117 #endif 114 118 } 115 119 option += optlen; … … 118 122 dest += sprintf(dest, " "); 119 123 } 124 return ret; 120 125 } 121 126 … … 127 132 int i, j; 128 133 char **envp; 134 char *var; 129 135 uint8_t *temp; 130 136 struct in_addr subnet; 131 137 char over = 0; 132 138 133 if (packet == NULL) 134 num_options = 0; 135 else { 136 for (i = 0; dhcp_options[i].code; i++) 139 if (packet) { 140 for (i = 0; dhcp_options[i].code; i++) { 137 141 if (get_option(packet, dhcp_options[i].code)) { 138 142 num_options++; … … 140 144 num_options++; /* for mton */ 141 145 } 142 if (packet->siaddr) num_options++; 143 if ((temp = get_option(packet, DHCP_OPTION_OVER))) 146 } 147 if (packet->siaddr) 148 num_options++; 149 temp = get_option(packet, DHCP_OPTION_OVER); 150 if (temp) 144 151 over = *temp; 145 if (!(over & FILE_FIELD) && packet->file[0]) num_options++; 146 if (!(over & SNAME_FIELD) && packet->sname[0]) num_options++; 152 if (!(over & FILE_FIELD) && packet->file[0]) 153 num_options++; 154 if (!(over & SNAME_FIELD) && packet->sname[0]) 155 num_options++; 147 156 } 148 157 149 158 envp = xzalloc(sizeof(char *) * (num_options + 5)); 150 159 j = 0; 151 envp[j++] = bb_xasprintf("interface=%s", client_config.interface); 152 envp[j++] = bb_xasprintf("PATH=%s", 153 getenv("PATH") ? : "/bin:/usr/bin:/sbin:/usr/sbin"); 154 envp[j++] = bb_xasprintf("HOME=%s", getenv("HOME") ? : "/"); 155 156 if (packet == NULL) return envp; 160 envp[j++] = xasprintf("interface=%s", client_config.interface); 161 var = getenv("PATH"); 162 if (var) 163 envp[j++] = xasprintf("PATH=%s", var); 164 var = getenv("HOME"); 165 if (var) 166 envp[j++] = xasprintf("HOME=%s", var); 167 168 if (packet == NULL) 169 return envp; 157 170 158 171 envp[j] = xmalloc(sizeof("ip=255.255.255.255")); 159 172 sprintip(envp[j++], "ip=", (uint8_t *) &packet->yiaddr); 160 173 161 162 174 for (i = 0; dhcp_options[i].code; i++) { 163 if (!(temp = get_option(packet, dhcp_options[i].code))) 175 temp = get_option(packet, dhcp_options[i].code); 176 if (!temp) 164 177 continue; 165 envp[j] = xmalloc(upper_length(temp[OPT_LEN - 2], 166 dhcp_options[i].flags & TYPE_MASK) + strlen(dhcp_options[i].name) + 2); 167 fill_options(envp[j++], temp, &dhcp_options[i]); 178 envp[j++] = alloc_fill_opts(temp, &dhcp_options[i]); 168 179 169 180 /* Fill in a subnet bits option for things like /24 */ 170 181 if (dhcp_options[i].code == DHCP_SUBNET) { 171 182 memcpy(&subnet, temp, 4); 172 envp[j++] = bb_xasprintf("mask=%d", mton(&subnet));183 envp[j++] = xasprintf("mask=%d", mton(&subnet)); 173 184 } 174 185 } … … 180 191 /* watch out for invalid packets */ 181 192 packet->file[sizeof(packet->file) - 1] = '\0'; 182 envp[j++] = bb_xasprintf("boot_file=%s", packet->file);193 envp[j++] = xasprintf("boot_file=%s", packet->file); 183 194 } 184 195 if (!(over & SNAME_FIELD) && packet->sname[0]) { 185 196 /* watch out for invalid packets */ 186 197 packet->sname[sizeof(packet->sname) - 1] = '\0'; 187 envp[j++] = bb_xasprintf("sname=%s", packet->sname);198 envp[j++] = xasprintf("sname=%s", packet->sname); 188 199 } 189 200 return envp; … … 200 211 return; 201 212 202 DEBUG( LOG_INFO, "vforking and execle'ing %s", client_config.script);213 DEBUG("vfork'ing and execle'ing %s", client_config.script); 203 214 204 215 envp = fill_envp(packet); 216 205 217 /* call script */ 218 // can we use wait4pid(spawn(...)) here? 206 219 pid = vfork(); 207 if (pid) { 208 waitpid(pid, NULL, 0); 209 for (curr = envp; *curr; curr++) free(*curr); 210 free(envp); 211 return; 212 } else if (pid == 0) { 220 if (pid < 0) return; 221 if (pid == 0) { 213 222 /* close fd's? */ 214 215 223 /* exec script */ 216 224 execle(client_config.script, client_config.script, 217 225 name, NULL, envp); 218 LOG(LOG_ERR, "script %s failed: %m", client_config.script); 219 exit(1); 220 } 221 } 226 bb_perror_msg_and_die("script %s failed", client_config.script); 227 } 228 waitpid(pid, NULL, 0); 229 for (curr = envp; *curr; curr++) 230 free(*curr); 231 free(envp); 232 }
Note:
See TracChangeset
for help on using the changeset viewer.