diff options
Diffstat (limited to 'networking/udhcp/script.c')
-rw-r--r-- | networking/udhcp/script.c | 52 |
1 files changed, 30 insertions, 22 deletions
diff --git a/networking/udhcp/script.c b/networking/udhcp/script.c index dc8ff7a1c..98706a592 100644 --- a/networking/udhcp/script.c +++ b/networking/udhcp/script.c | |||
@@ -9,7 +9,6 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include "common.h" | 11 | #include "common.h" |
12 | #include "dhcpd.h" | ||
13 | #include "dhcpc.h" | 12 | #include "dhcpc.h" |
14 | #include "options.h" | 13 | #include "options.h" |
15 | 14 | ||
@@ -77,7 +76,7 @@ static char *alloc_fill_opts(uint8_t *option, const struct dhcp_option *type_p) | |||
77 | switch (type) { | 76 | switch (type) { |
78 | case OPTION_IP_PAIR: | 77 | case OPTION_IP_PAIR: |
79 | dest += sprintip(dest, "", option); | 78 | dest += sprintip(dest, "", option); |
80 | *(dest++) = '/'; | 79 | *dest++ = '/'; |
81 | option += 4; | 80 | option += 4; |
82 | optlen = 4; | 81 | optlen = 4; |
83 | case OPTION_IP: /* Works regardless of host byte order. */ | 82 | case OPTION_IP: /* Works regardless of host byte order. */ |
@@ -132,34 +131,42 @@ static char **fill_envp(struct dhcpMessage *packet) | |||
132 | int num_options = 0; | 131 | int num_options = 0; |
133 | int i, j; | 132 | int i, j; |
134 | char **envp; | 133 | char **envp; |
134 | char *var; | ||
135 | uint8_t *temp; | 135 | uint8_t *temp; |
136 | struct in_addr subnet; | 136 | struct in_addr subnet; |
137 | char over = 0; | 137 | char over = 0; |
138 | 138 | ||
139 | if (packet == NULL) | 139 | if (packet) { |
140 | num_options = 0; | 140 | for (i = 0; dhcp_options[i].code; i++) { |
141 | else { | ||
142 | for (i = 0; dhcp_options[i].code; i++) | ||
143 | if (get_option(packet, dhcp_options[i].code)) { | 141 | if (get_option(packet, dhcp_options[i].code)) { |
144 | num_options++; | 142 | num_options++; |
145 | if (dhcp_options[i].code == DHCP_SUBNET) | 143 | if (dhcp_options[i].code == DHCP_SUBNET) |
146 | num_options++; /* for mton */ | 144 | num_options++; /* for mton */ |
147 | } | 145 | } |
148 | if (packet->siaddr) num_options++; | 146 | } |
149 | if ((temp = get_option(packet, DHCP_OPTION_OVER))) | 147 | if (packet->siaddr) |
148 | num_options++; | ||
149 | temp = get_option(packet, DHCP_OPTION_OVER); | ||
150 | if (temp) | ||
150 | over = *temp; | 151 | over = *temp; |
151 | if (!(over & FILE_FIELD) && packet->file[0]) num_options++; | 152 | if (!(over & FILE_FIELD) && packet->file[0]) |
152 | if (!(over & SNAME_FIELD) && packet->sname[0]) num_options++; | 153 | num_options++; |
154 | if (!(over & SNAME_FIELD) && packet->sname[0]) | ||
155 | num_options++; | ||
153 | } | 156 | } |
154 | 157 | ||
155 | envp = xzalloc(sizeof(char *) * (num_options + 5)); | 158 | envp = xzalloc(sizeof(char *) * (num_options + 5)); |
156 | j = 0; | 159 | j = 0; |
157 | envp[j++] = xasprintf("interface=%s", client_config.interface); | 160 | envp[j++] = xasprintf("interface=%s", client_config.interface); |
158 | envp[j++] = xasprintf("PATH=%s", | 161 | var = getenv("PATH"); |
159 | getenv("PATH") ? : "/bin:/usr/bin:/sbin:/usr/sbin"); | 162 | if (var) |
160 | envp[j++] = xasprintf("HOME=%s", getenv("HOME") ? : "/"); | 163 | envp[j++] = xasprintf("PATH=%s", var); |
164 | var = getenv("HOME"); | ||
165 | if (var) | ||
166 | envp[j++] = xasprintf("HOME=%s", var); | ||
161 | 167 | ||
162 | if (packet == NULL) return envp; | 168 | if (packet == NULL) |
169 | return envp; | ||
163 | 170 | ||
164 | envp[j] = xmalloc(sizeof("ip=255.255.255.255")); | 171 | envp[j] = xmalloc(sizeof("ip=255.255.255.255")); |
165 | sprintip(envp[j++], "ip=", (uint8_t *) &packet->yiaddr); | 172 | sprintip(envp[j++], "ip=", (uint8_t *) &packet->yiaddr); |
@@ -206,19 +213,20 @@ void udhcp_run_script(struct dhcpMessage *packet, const char *name) | |||
206 | DEBUG("vfork'ing and execle'ing %s", client_config.script); | 213 | DEBUG("vfork'ing and execle'ing %s", client_config.script); |
207 | 214 | ||
208 | envp = fill_envp(packet); | 215 | envp = fill_envp(packet); |
216 | |||
209 | /* call script */ | 217 | /* call script */ |
218 | // can we use wait4pid(spawn(...)) here? | ||
210 | pid = vfork(); | 219 | pid = vfork(); |
211 | if (pid) { | 220 | if (pid < 0) return; |
212 | waitpid(pid, NULL, 0); | 221 | if (pid == 0) { |
213 | for (curr = envp; *curr; curr++) free(*curr); | ||
214 | free(envp); | ||
215 | return; | ||
216 | } else if (pid == 0) { | ||
217 | /* close fd's? */ | 222 | /* close fd's? */ |
218 | /* exec script */ | 223 | /* exec script */ |
219 | execle(client_config.script, client_config.script, | 224 | execle(client_config.script, client_config.script, |
220 | name, NULL, envp); | 225 | name, NULL, envp); |
221 | bb_perror_msg("script %s failed", client_config.script); | 226 | bb_perror_msg_and_die("script %s failed", client_config.script); |
222 | exit(1); | ||
223 | } | 227 | } |
228 | waitpid(pid, NULL, 0); | ||
229 | for (curr = envp; *curr; curr++) | ||
230 | free(*curr); | ||
231 | free(envp); | ||
224 | } | 232 | } |