summaryrefslogtreecommitdiffstats
path: root/configure.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2008-04-12 23:00:23 +0000
committerRoy Marples <roy@marples.name>2008-04-12 23:00:23 +0000
commit5a98646f72f9be4fe116d544f8b3d607d682789f (patch)
treeac94c307c8cffa8754bb16358f4398aa4addb8b2 /configure.c
parent3ab998f88b6fb39c3e8247d17a2707f5bd37d3a1 (diff)
downloaddhcpcd-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.c419
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;