aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp/script.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/udhcp/script.c')
-rw-r--r--networking/udhcp/script.c52
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}