diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:04:11 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:04:11 -0800 |
commit | 4c5a5fb53bccceff331bae70f748bf9b4609fe0a (patch) | |
tree | d6ae69d0d3f4a4d760a3254ec326bca4a8afacfe /configure.c | |
parent | e95877ecfa1170d77b1ec1f66752725cdda01b64 (diff) | |
download | external_dhcpcd-4c5a5fb53bccceff331bae70f748bf9b4609fe0a.zip external_dhcpcd-4c5a5fb53bccceff331bae70f748bf9b4609fe0a.tar.gz external_dhcpcd-4c5a5fb53bccceff331bae70f748bf9b4609fe0a.tar.bz2 |
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'configure.c')
-rw-r--r-- | configure.c | 224 |
1 files changed, 74 insertions, 150 deletions
diff --git a/configure.c b/configure.c index 8c024f8..dad3bce 100644 --- a/configure.c +++ b/configure.c @@ -48,22 +48,50 @@ #define DEFAULT_PATH "PATH=/usr/bin:/usr/sbin:/bin:/sbin" + +static int +exec_script(char *const *argv, char *const *env) +{ + pid_t pid; + sigset_t full; + sigset_t old; + + /* OK, we need to block signals */ + sigfillset(&full); + sigprocmask(SIG_SETMASK, &full, &old); + signal_reset(); + + switch (pid = vfork()) { + case -1: + logger(LOG_ERR, "vfork: %s", strerror(errno)); + break; + case 0: + sigprocmask(SIG_SETMASK, &old, NULL); + execve(argv[0], argv, env); + logger(LOG_ERR, "%s: %s", argv[0], strerror(errno)); + _exit(127); + /* NOTREACHED */ + } + + /* Restore our signals */ + signal_setup(); + sigprocmask(SIG_SETMASK, &old, NULL); + return pid; +} + int -exec_script(const struct options *options, const char *iface, - const char *reason, - const struct dhcp_message *dhcpn, const struct dhcp_message *dhcpo) +run_script(const struct options *options, const char *iface, + const char *reason, + const struct dhcp_message *dhcpn, const struct dhcp_message *dhcpo) { char *const argv[2] = { UNCONST(options->script), NULL }; char **env = NULL, **ep; char *path; ssize_t e, elen; - int ret = 0; pid_t pid; int status = 0; - sigset_t full; - sigset_t old; - logger(LOG_DEBUG, "executing `%s'", options->script); + logger(LOG_DEBUG, "executing `%s', reason %s", options->script, reason); /* Make our env */ elen = 5; @@ -115,50 +143,17 @@ exec_script(const struct options *options, const char *iface, } env[elen] = '\0'; - /* OK, we need to block signals */ - sigfillset(&full); - sigprocmask(SIG_SETMASK, &full, &old); - -#ifdef THERE_IS_NO_FORK - signal_reset(); - pid = vfork(); -#else - pid = fork(); -#endif - - switch (pid) { - case -1: -#ifdef THERE_IS_NO_FORK - logger(LOG_ERR, "vfork: %s", strerror(errno)); -#else - logger(LOG_ERR, "fork: %s", strerror(errno)); -#endif - ret = -1; - break; - case 0: -#ifndef THERE_IS_NO_FORK - signal_reset(); -#endif - sigprocmask(SIG_SETMASK, &old, NULL); - execve(options->script, argv, env); - logger(LOG_ERR, "%s: %s", options->script, strerror(errno)); - _exit(111); - /* NOTREACHED */ - } - -#ifdef THERE_IS_NO_FORK - signal_setup(); -#endif - - /* Restore our signals */ - sigprocmask(SIG_SETMASK, &old, NULL); - - /* Wait for the script to finish */ - while (waitpid(pid, &status, 0) == -1) { - if (errno != EINTR) { - logger(LOG_ERR, "waitpid: %s", strerror(errno)); - status = -1; - break; + pid = exec_script(argv, env); + if (pid == -1) + status = -1; + else if (pid != 0) { + /* Wait for the script to finish */ + while (waitpid(pid, &status, 0) == -1) { + if (errno != EINTR) { + logger(LOG_ERR, "waitpid: %s", strerror(errno)); + status = -1; + break; + } } } @@ -167,7 +162,6 @@ exec_script(const struct options *options, const char *iface, while (*ep) free(*ep++); free(env); - return status; } @@ -193,14 +187,13 @@ delete_route(const char *iface, struct rt *rt, int metric) int retval; addr = xstrdup(inet_ntoa(rt->dest)); - logger(LOG_DEBUG, "removing route %s/%d via %s", - addr, inet_ntocidr(rt->net), inet_ntoa(rt->gate)); + logger(LOG_DEBUG, "deleting route %s/%d via %s", + addr, inet_ntocidr(rt->net), inet_ntoa(rt->gate)); free(addr); retval = del_route(iface, &rt->dest, &rt->net, &rt->gate, metric); - if (retval != 0) + if (retval != 0 && errno != ENOENT && errno != ESRCH) logger(LOG_ERR," del_route: %s", strerror(errno)); return retval; - } static int @@ -245,22 +238,9 @@ configure_routes(struct interface *iface, const struct dhcp_message *dhcp, int retval = 0; char *addr; -#ifdef THERE_IS_NO_FORK - char *skipp; - size_t skiplen; - int skip = 0; - - free(dhcpcd_skiproutes); - /* We can never have more than 255 routes. So we need space - * for 255 3 digit numbers and commas */ - skiplen = 255 * 4 + 1; - skipp = dhcpcd_skiproutes = xmalloc(sizeof(char) * skiplen); - *skipp = '\0'; -#endif - ort = get_option_routes(dhcp); -#ifdef ENABLE_IPV4LL_ALWAYSROUTE +#ifdef IPV4LL_ALWAYSROUTE if (options->options & DHCPCD_IPV4LL && IN_PRIVATE(ntohl(dhcp->yiaddr))) { @@ -287,43 +267,6 @@ configure_routes(struct interface *iface, const struct dhcp_message *dhcp, } #endif -#ifdef THERE_IS_NO_FORK - if (dhcpcd_skiproutes) { - int i = -1; - char *sk, *skp, *token; - free_routes(iface->routes); - for (rt = ort; rt; rt = rt->next) { - i++; - /* Check that we did add this route or not */ - sk = skp = xstrdup(dhcpcd_skiproutes); - while ((token = strsep(&skp, ","))) { - if (isdigit((unsigned char)*token) && - atoi(token) == i) - break; - } - free(sk); - if (token) - continue; - if (nr) { - rtn->next = xmalloc(sizeof(*rtn)); - rtn = rtn->next; - } else { - nr = rtn = xmalloc(sizeof(*rtn)); - } - rtn->dest.s_addr = rt->dest.s_addr; - rtn->net.s_addr = rt->net.s_addr; - rtn->gate.s_addr = rt->gate.s_addr; - rtn->next = NULL; - } - iface->routes = nr; - nr = NULL; - - /* We no longer need this */ - free(dhcpcd_skiproutes); - dhcpcd_skiproutes = NULL; - } -#endif - /* Now remove old routes we no longer use. * We should do this in reverse order. */ iface->routes = reverse_routes(iface->routes); @@ -370,37 +313,25 @@ configure_routes(struct interface *iface, const struct dhcp_message *dhcp, rtn->gate.s_addr = rt->gate.s_addr; rtn->next = NULL; } -#ifdef THERE_IS_NO_FORK - /* If we have daemonised yet we need to record which routes - * we failed to add so we can skip them */ - else if (!(options->options & DHCPCD_DAEMONISED)) { - /* We can never have more than 255 / 4 routes, - * so 3 chars is plently */ - printf("foo\n"); - if (*skipp) - *skipp++ = ','; - skipp += snprintf(skipp, - dhcpcd_skiproutes + skiplen - skipp, - "%d", skip); - } - skip++; -#endif } free_routes(ort); free_routes(iface->routes); iface->routes = nr; + return retval; +} -#ifdef THERE_IS_NO_FORK - if (dhcpcd_skiproutes) { - if (*dhcpcd_skiproutes) - *skipp = '\0'; - else { - free(dhcpcd_skiproutes); - dhcpcd_skiproutes = NULL; - } - } -#endif - +static int +delete_address(struct interface *iface) +{ + int retval; + logger(LOG_DEBUG, "deleting IP address %s/%d", + inet_ntoa(iface->addr), + inet_ntocidr(iface->net)); + retval = del_address(iface->name, &iface->addr, &iface->net); + if (retval == -1 && errno != EADDRNOTAVAIL) + logger(LOG_ERR, "del_address: %s", strerror(errno)); + iface->addr.s_addr = 0; + iface->net.s_addr = 0; return retval; } @@ -419,14 +350,16 @@ configure(struct interface *iface, const char *reason, #endif /* Grab our IP config */ - if (dhcp == NULL || dhcp->yiaddr == 0) + if (dhcp == NULL) up = 0; else { addr.s_addr = dhcp->yiaddr; + if (addr.s_addr == 0) + addr.s_addr = lease->addr.s_addr; /* Ensure we have all the needed values */ - if (get_option_addr(&net.s_addr, dhcp, DHCP_SUBNETMASK) == -1) + if (get_option_addr(&net.s_addr, dhcp, DHO_SUBNETMASK) == -1) net.s_addr = get_netmask(addr.s_addr); - if (get_option_addr(&brd.s_addr, dhcp, DHCP_BROADCAST) == -1) + if (get_option_addr(&brd.s_addr, dhcp, DHO_BROADCAST) == -1) brd.s_addr = addr.s_addr | ~net.s_addr; } @@ -435,19 +368,10 @@ configure(struct interface *iface, const char *reason, /* Only reset things if we had set them before */ if (iface->addr.s_addr != 0) { delete_routes(iface, options->metric); - logger(LOG_DEBUG, "deleting IP address %s/%d", - inet_ntoa(iface->addr), - inet_ntocidr(iface->net)); - if (del_address(iface->name, &iface->addr, - &iface->net) == -1 && - errno != ENOENT) - logger(LOG_ERR, "del_address: %s", - strerror(errno)); - iface->addr.s_addr = 0; - iface->net.s_addr = 0; + delete_address(iface); } - exec_script(options, iface->name, reason, NULL, old); + run_script(options, iface->name, reason, NULL, old); return 0; } @@ -466,8 +390,8 @@ configure(struct interface *iface, const char *reason, /* Now delete the old address if different */ if (iface->addr.s_addr != addr.s_addr && - iface->addr.s_addr != 0) - del_address(iface->name, &iface->addr, &iface->net); + iface->addr.s_addr != 0) + delete_address(iface); #ifdef __linux__ /* On linux, we need to change the subnet route to have our metric. */ @@ -491,6 +415,6 @@ configure(struct interface *iface, const char *reason, if (write_lease(iface, dhcp) == -1) logger(LOG_ERR, "write_lease: %s", strerror(errno)); - exec_script(options, iface->name, reason, dhcp, old); + run_script(options, iface->name, reason, dhcp, old); return 0; } |