diff options
| author | Roy Marples <roy@marples.name> | 2008-04-12 23:00:23 +0000 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2008-04-12 23:00:23 +0000 |
| commit | 5a98646f72f9be4fe116d544f8b3d607d682789f (patch) | |
| tree | ac94c307c8cffa8754bb16358f4398aa4addb8b2 /configure.c | |
| parent | 3ab998f88b6fb39c3e8247d17a2707f5bd37d3a1 (diff) | |
| download | dhcpcd-5a98646f72f9be4fe116d544f8b3d607d682789f.tar.xz | |
Move configuration file setup to dhcpcd.sh so that it's possible for the user to change more easily. We now have enter/exit hooks similar to dhclient to make things even easier for the user. At this time, we are still 100% commandline compatible. However, we have lost the feature to lookup hostnames.
Diffstat (limited to 'configure.c')
| -rw-r--r-- | configure.c | 419 |
1 files changed, 19 insertions, 400 deletions
diff --git a/configure.c b/configure.c index 2fabd8c5..4eea2ce4 100644 --- a/configure.c +++ b/configure.c @@ -26,14 +26,12 @@ */ #include <sys/stat.h> +#include <sys/wait.h> #include <netinet/in.h> #include <arpa/inet.h> -#include <ctype.h> #include <errno.h> -#include <netdb.h> -#include <resolv.h> #include <signal.h> #include <stdarg.h> #include <stdlib.h> @@ -56,6 +54,8 @@ exec_cmd(const char *cmd, const char *args, ...) int n = 1; int ret = 0; pid_t pid; + pid_t wpid; + int status = 0; sigset_t full; sigset_t old; @@ -107,8 +107,21 @@ exec_cmd(const char *cmd, const char *args, ...) /* Restore our signals */ sigprocmask(SIG_SETMASK, &old, NULL); - free(argv); + + /* Wait for the script to finish */ + do { + wpid = waitpid(pid, &status, 0); + if (wpid < 1) + logger(LOG_ERR, "waitpid: %s", strerror(errno)); + } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + + if (WIFEXITED(status)) + ret = WEXITSTATUS(status); + else + ret = -1; + if (ret != 0) + logger(LOG_ERR, "%s exited non zero", cmd); return ret; } @@ -124,380 +137,10 @@ exec_script(const char *script, _unused const char *infofile, const char *arg) return; } -#ifdef ENABLE_INFO logger(LOG_DEBUG, "exec \"%s\" \"%s\" \"%s\"", script, infofile, arg); exec_cmd(script, infofile, arg, (char *)NULL); -#else - logger(LOG_DEBUG, "exec \"%s\" \"\" \"%s\"", script, arg); - exec_cmd(script, "", arg, (char *)NULL); -#endif -} - -static char * -lookuphostname(in_addr_t addr) -{ - union { - struct sockaddr sa; - struct sockaddr_in sin; - } su; - socklen_t salen; - char *name; - struct addrinfo hints; - struct addrinfo *res = NULL; - int r; - - name = xmalloc(sizeof(char) * NI_MAXHOST); - salen = sizeof(su.sa); - memset(&su.sa, 0, salen); - su.sin.sin_family = AF_INET; - su.sin.sin_addr.s_addr = addr; - - r = getnameinfo(&su.sa, salen, name, NI_MAXHOST, NULL, 0, NI_NAMEREQD); - if (r != 0) { - free(name); - switch (r) { -#ifdef EAI_NODATA - case EAI_NODATA: /* FALLTHROUGH */ -#endif - case EAI_NONAME: - errno = ENOENT; - break; - case EAI_SYSTEM: - break; - default: - errno = EIO; - break; - } - return NULL; - } - - /* Check for a malicious PTR record */ - memset(&hints, 0, sizeof(hints)); - hints.ai_socktype = SOCK_DGRAM; - hints.ai_flags = AI_NUMERICHOST; - r = getaddrinfo(name, "0", &hints, &res); - if (res) - freeaddrinfo(res); - if (r == 0 || !*name) { - free(name); - errno = ENOENT; - return NULL; - } - - return name; -} - -static int -configure_hostname(const struct dhcp_message *dhcp, in_addr_t addr, int h) -{ - char *newhostname; - char *curhostname; - - curhostname = xmalloc(sizeof(char) * MAXHOSTNAMELEN); - *curhostname = '\0'; - - gethostname(curhostname, MAXHOSTNAMELEN); - if (h || - strlen(curhostname) == 0 || - strcmp(curhostname, "(none)") == 0 || - strcmp(curhostname, "localhost") == 0) - { - newhostname = get_option_string(dhcp, DHCP_HOSTNAME); - if (!newhostname || h) - newhostname = lookuphostname(addr); - - if (newhostname) { - logger(LOG_INFO, "setting hostname to `%s'", newhostname); - sethostname(newhostname, (int)strlen(newhostname)); - free(newhostname); - } - } - - free(curhostname); - return 0; -} - -#ifdef ENABLE_NIS -#define PREFIXSIZE 300 -static int -configure_nis(const char *ifname, const struct dhcp_message *dhcp) -{ - const uint8_t *servers; - char *domain; - FILE *f; - char *prefix; - const uint8_t *e; - uint8_t l; - struct in_addr addr; - - servers = get_option(dhcp, DHCP_NISSERVER); - domain = get_option_string(dhcp, DHCP_NISDOMAIN); - - if (!servers && !domain) { - if (errno == ENOENT) - return 0; - return -1; - } - - if (!(f = fopen(NISFILE, "w"))) - return -1; - - prefix = xmalloc(sizeof(char) * PREFIXSIZE); - *prefix = '\0'; - fprintf(f, "# Generated by dhcpcd for interface %s\n", ifname); - - if (domain) { - setdomainname(domain, (int)strlen(domain)); - if (servers) - snprintf(prefix, PREFIXSIZE, "domain %s server", - domain); - else - fprintf(f, "domain %s broadcast\n", domain); - free(domain); - } - else - strlcpy(prefix, "ypserver", PREFIXSIZE); - - if (servers) { - l = *servers++; - e = servers + l; - for(; servers < e; servers += sizeof(uint32_t)) { - memcpy(&addr.s_addr, servers, sizeof(uint32_t)); - fprintf(f, "%s %s\n", prefix, inet_ntoa(addr)); - } - } - - free(prefix); - fclose(f); - - return exec_cmd(NISSERVICE, NISRESTARTARGS, (char *)NULL); -} -#endif - -#ifdef ENABLE_NTP -static int -in_addresses(const uint8_t *addresses, uint32_t addr) -{ - uint8_t l = *addresses++; - const uint8_t *e = addresses + l; - uint32_t a; - - for (; addresses < e; addresses += sizeof(a)) { - memcpy(&a, addresses, sizeof(a)); - if (a == addr) - return 0; - } - return -1; -} - -static int -_make_ntp(const char *file, const char *ifname, const uint8_t *ntp) -{ - FILE *f; - char *a; - char *line = NULL; - size_t len = 0; - char *token; - struct in_addr addr; - uint8_t tomatch = *ntp; - const uint8_t *e; -#ifdef NTPFILE - int ntpfile; -#endif - - /* Check that we really need to update the servers. - * We do this because ntp has to be restarted to - * work with a changed config. */ - if (!(f = fopen(file, "r"))) { - if (errno != ENOENT) - return -1; - } else { - while (tomatch != 0 && (get_line(&line, &len, f))) { - a = line; - token = strsep(&a, " "); - if (!token || strcmp(token, "server") != 0) - continue; - if ((token = strsep(&a, " \n")) == NULL) - continue; - if (inet_aton(token, &addr) == 1 && - in_addresses(ntp, addr.s_addr) == 0) - tomatch--; - } - fclose(f); - free(line); - - /* File has the same name servers that we do, - * so no need to restart ntp */ - if (tomatch == 0) - return 0; - } - - if (!(f = fopen(file, "w"))) - return -1; - - fprintf(f, "# Generated by dhcpcd for interface %s\n", ifname); -#ifdef NTPFILE - if ((ntpfile = strcmp(file, NTPFILE)) == 0) { - fprintf(f, "restrict default noquery notrust nomodify\n"); - fprintf(f, "restrict 127.0.0.1\n"); - } -#endif - - tomatch = *ntp++; - e = ntp + tomatch; - for (; ntp < e; ntp += sizeof(uint32_t)) { - memcpy(&addr.s_addr, ntp, sizeof(uint32_t)); - a = inet_ntoa(addr); -#ifdef NTPFILE - if (ntpfile == 0) - fprintf(f, "restrict %s nomodify notrap noquery\n", a); -#endif - fprintf(f, "server %s\n", a); - } - fclose(f); - - return 1; -} -#endif - -static int -configure_ntp(const char *ifname, const struct dhcp_message *dhcp) -{ - const uint8_t *ntp = get_option(dhcp, DHCP_NTPSERVER); - int restart = 0; - int r; - - if (!ntp) { - if (errno == ENOENT) - return 0; - return -1; - } - -#ifdef NTPFILE - r = _make_ntp(NTPFILE, ifname, ntp); - if (r == -1) - return -1; - if (r > 0) - restart |= 1; -#endif - -#ifdef OPENNTPFILE - r = _make_ntp(OPENNTPFILE, ifname, ntp); - if (r == -1) - return -1; - if (r > 0) - restart |= 2; -#endif - - if (restart) - return exec_cmd(NTPSERVICE, NTPRESTARTARGS, (char *)NULL); - return 0; -} - -#ifdef ENABLE_RESOLVCONF -static int -file_in_path(const char *file) -{ - char *p = getenv("PATH"); - char *path; - char *token; - struct stat s; - char mypath[PATH_MAX]; - int retval = -1; - - if (!p) { - errno = ENOENT; - return -1; - } - - path = strdup(p); - p = path; - while ((token = strsep(&p, ":"))) { - snprintf(mypath, PATH_MAX, "%s/%s", token, file); - if (stat(mypath, &s) == 0) { - retval = 0; - break; - } - } - free(path); - return(retval); -} -#endif - -static int -configure_resolv(const char *ifname, const struct dhcp_message *dhcp) -{ - FILE *f = NULL; - const uint8_t *servers; - const uint8_t *e; - uint8_t l; - struct in_addr addr; - char *p; - -#ifdef ENABLE_RESOLVCONF - char *resolvconf = NULL; - size_t len; -#endif - - servers = get_option(dhcp, DHCP_DNSSERVER); - if (!servers) { - if (errno == ENOENT) - return 0; - return -1; - } - -#ifdef ENABLE_RESOLVCONF - if (file_in_path("resolvconf") == 0) { - len = strlen("resolvconf -a ") + strlen(ifname) + 1; - resolvconf = xmalloc(sizeof(char) * len); - snprintf(resolvconf, len, "resolvconf -a %s", ifname); - f = popen(resolvconf , "w"); - free(resolvconf); - } -#endif - if (!f && !(f = fopen(RESOLVFILE, "w"))) - return -1; - - fprintf(f, "# Generated by dhcpcd for interface %s\n", ifname); - p = get_option_string(dhcp, DHCP_DNSSEARCH); - if (!p) - p = get_option_string(dhcp, DHCP_DNSDOMAIN); - if (p) { - fprintf(f, "search %s\n", p); - free(p); - } - - l = *servers++; - e = servers + l; - for (; servers < e; servers += sizeof(uint32_t)) { - memcpy(&addr.s_addr, servers, sizeof(uint32_t)); - fprintf(f, "nameserver %s\n", inet_ntoa(addr)); - } - -#ifdef ENABLE_RESOLVCONF - if (resolvconf) - pclose(f); - else -#endif - fclose(f); - - /* Refresh the local resolver */ - res_init(); - return 0; } -#ifdef ENABLE_RESOLVCONF -static int -restore_resolv(const char *ifname) -{ - if (file_in_path("resolvconf") != 0) - return 0; - - return exec_cmd("resolvconf", "-d", ifname, (char *)NULL); -} -#endif - - static struct rt * reverse_routes(struct rt *routes) { @@ -728,7 +371,6 @@ configure_routes(struct interface *iface, const struct dhcp_message *dhcp, return retval; } -#ifdef ENABLE_INFO static void print_clean(FILE *f, const char *name, const char *value) { @@ -848,7 +490,6 @@ write_info(const struct interface *iface, const struct dhcp_message *dhcp, fclose(f); return 0; } -#endif int configure(struct interface *iface, const struct dhcp_message *dhcp, @@ -884,14 +525,12 @@ configure(struct interface *iface, const struct dhcp_message *dhcp, iface->mtu = iface->initial_mtu; } -#ifdef ENABLE_INFO /* If we haven't created an info file, do so now */ if (!lease->frominfo) { if (write_info(iface, dhcp, lease, options, 0) == -1) logger(LOG_ERR, "write_info: %s", strerror(errno)); } -#endif /* Only reset things if we had set them before */ if (iface->addr.s_addr != 0) { @@ -908,10 +547,6 @@ configure(struct interface *iface, const struct dhcp_message *dhcp, iface->addr.s_addr = 0; iface->net.s_addr = 0; } -#ifdef ENABLE_RESOLVCONF - if (options->options & DHCPCD_DNS) - restore_resolv(iface->name); -#endif } exec_script(options->script, iface->infofile, "down"); @@ -961,32 +596,16 @@ configure(struct interface *iface, const struct dhcp_message *dhcp, #endif configure_routes(iface, dhcp, options); - if (options->options & DHCPCD_DNS) - configure_resolv(iface->name, dhcp); -#ifdef ENABLE_NTP - if (options->options & DHCPCD_NTP) - configure_ntp(iface->name, dhcp); -#endif -#ifdef ENABLE_NIS - if (options->options & DHCPCD_NIS) - configure_nis(iface->name, dhcp); -#endif - configure_hostname(dhcp, addr.s_addr, - options->options & DHCPCD_HOSTNAME); - up = (iface->addr.s_addr != addr.s_addr || iface->net.s_addr != net.s_addr); - iface->addr.s_addr = addr.s_addr; iface->net.s_addr = net.s_addr; -#ifdef ENABLE_INFO - //if (!lease->frominfo) + if (!lease->frominfo) write_info(iface, dhcp, lease, options, 1); if (write_lease(iface, dhcp) == -1) logger(LOG_ERR, "write_lease: %s", strerror(errno)); -#endif - + exec_script(options->script, iface->infofile, up ? "new" : "up"); return 0; |
