Update portability notes.
[darkstat] / dns.c
diff --git a/dns.c b/dns.c
index df2342b..163aa56 100644 (file)
--- a/dns.c
+++ b/dns.c
@@ -1,5 +1,5 @@
 /* darkstat 3
- * copyright (c) 2001-2011 Emil Mikulic.
+ * copyright (c) 2001-2014 Emil Mikulic.
  *
  * dns.c: synchronous DNS in a child process.
  *
@@ -8,6 +8,7 @@
  */
 
 #include "cdefs.h"
+#include "cap.h"
 #include "conv.h"
 #include "decode.h"
 #include "dns.h"
 #include <string.h>
 #include <unistd.h>
 
+#ifdef __NetBSD__
+# define gethostbyaddr(addr, len, type) \
+         gethostbyaddr((const char *)(addr), len, type)
+#endif
+
 static void dns_main(void) _noreturn_; /* the child process runs this */
 
 #define CHILD 0 /* child process uses this socket */
 #define PARENT 1
-static int sock[2];
+static int dns_sock[2];
 static pid_t pid = -1;
 
 struct dns_reply {
@@ -45,7 +51,7 @@ struct dns_reply {
 void
 dns_init(const char *privdrop_user)
 {
-   if (socketpair(AF_UNIX, SOCK_STREAM, 0, sock) == -1)
+   if (socketpair(AF_UNIX, SOCK_STREAM, 0, dns_sock) == -1)
       err(1, "socketpair");
 
    pid = fork();
@@ -55,19 +61,19 @@ dns_init(const char *privdrop_user)
    if (pid == 0) {
       /* We are the child. */
       privdrop(NULL /* don't chroot */, privdrop_user);
-      close(sock[PARENT]);
-      sock[PARENT] = -1;
+      close(dns_sock[PARENT]);
+      dns_sock[PARENT] = -1;
       daemonize_finish(); /* drop our copy of the lifeline! */
       if (signal(SIGUSR1, SIG_IGN) == SIG_ERR)
          errx(1, "signal(SIGUSR1, ignore) failed");
+      cap_free_args();
       dns_main();
-      verbosef("fell out of dns_main()");
-      exit(0);
+      errx(1, "DNS child fell out of dns_main()");
    } else {
       /* We are the parent. */
-      close(sock[CHILD]);
-      sock[CHILD] = -1;
-      fd_set_nonblock(sock[PARENT]);
+      close(dns_sock[CHILD]);
+      dns_sock[CHILD] = -1;
+      fd_set_nonblock(dns_sock[PARENT]);
       verbosef("DNS child has PID %d", pid);
    }
 }
@@ -77,7 +83,7 @@ dns_stop(void)
 {
    if (pid == -1)
       return; /* no child was started */
-   close(sock[PARENT]);
+   close(dns_sock[PARENT]);
    if (kill(pid, SIGINT) == -1)
       err(1, "kill");
    verbosef("dns_stop() waiting for child");
@@ -107,12 +113,7 @@ tree_cmp(struct tree_rec *a, struct tree_rec *b)
 }
 
 static RB_HEAD(tree_t, tree_rec) ip_tree = RB_INITIALIZER(&tree_rec);
-/* Quiet warnings. */
-static struct tree_rec * tree_t_RB_NEXT(struct tree_rec *elm)
-   _unused_;
-static struct tree_rec * tree_t_RB_MINMAX(struct tree_t *head, int val)
-   _unused_;
-RB_GENERATE(tree_t, tree_rec, ptree, tree_cmp)
+RB_GENERATE_STATIC(tree_t, tree_rec, ptree, tree_cmp)
 
 void
 dns_queue(const struct addr *const ipaddr)
@@ -139,7 +140,7 @@ dns_queue(const struct addr *const ipaddr)
       return;
    }
 
-   num_w = write(sock[PARENT], ipaddr, sizeof(*ipaddr)); /* won't block */
+   num_w = write(dns_sock[PARENT], ipaddr, sizeof(*ipaddr)); /* won't block */
    if (num_w == 0)
       warnx("dns_queue: write: ignoring end of file");
    else if (num_w == -1)
@@ -172,7 +173,7 @@ dns_get_result(struct addr *ipaddr, char **name)
    struct dns_reply reply;
    ssize_t numread;
 
-   numread = read(sock[PARENT], &reply, sizeof(reply));
+   numread = read(dns_sock[PARENT], &reply, sizeof(reply));
    if (numread == -1) {
       if (errno == EAGAIN)
          return (0); /* no input waiting */
@@ -198,8 +199,9 @@ dns_get_result(struct addr *ipaddr, char **name)
             type = "site-local";
          else if (IN6_IS_ADDR_MULTICAST(&reply.addr.ip.v6))
             type = "multicast";
-      } else { /* AF_INET */
-         if (IN_MULTICAST(reply.addr.ip.v4))
+      } else {
+         assert(reply.addr.family == IPv4);
+         if (IN_MULTICAST(htonl(reply.addr.ip.v4)))
             type = "multicast";
       }
       xasprintf(name, "(%s)", type);
@@ -250,7 +252,7 @@ struct qitem {
    struct addr ip;
 };
 
-STAILQ_HEAD(qhead, qitem) queue = STAILQ_HEAD_INITIALIZER(queue);
+static STAILQ_HEAD(qhead, qitem) queue = STAILQ_HEAD_INITIALIZER(queue);
 
 static void
 enqueue(const struct addr *const ip)
@@ -296,23 +298,23 @@ dns_main(void)
    struct addr ip;
 
    setproctitle("DNS child");
-   fd_set_nonblock(sock[CHILD]);
+   fd_set_nonblock(dns_sock[CHILD]);
    verbosef("DNS child entering main DNS loop");
    for (;;) {
       int blocking;
 
       if (STAILQ_EMPTY(&queue)) {
          blocking = 1;
-         fd_set_block(sock[CHILD]);
+         fd_set_block(dns_sock[CHILD]);
          verbosef("entering blocking read loop");
       } else {
          blocking = 0;
-         fd_set_nonblock(sock[CHILD]);
+         fd_set_nonblock(dns_sock[CHILD]);
          verbosef("non-blocking poll");
       }
       for (;;) {
          /* While we have input to process... */
-         ssize_t numread = read(sock[CHILD], &ip, sizeof(ip));
+         ssize_t numread = read(dns_sock[CHILD], &ip, sizeof(ip));
          if (numread == 0)
             exit(0); /* end of file, nothing more to do here. */
          if (numread == -1) {
@@ -330,7 +332,7 @@ dns_main(void)
              * run out of input we fall through to queue processing.
              */
             blocking = 0;
-            fd_set_nonblock(sock[CHILD]);
+            fd_set_nonblock(dns_sock[CHILD]);
          }
       }
 
@@ -375,7 +377,7 @@ dns_main(void)
                                  host, sizeof(host), NULL, 0, flags);
                break;
             default:
-               ret = EAI_FAMILY;
+               errx(1, "unexpected ip.family = %d", ip.family);
          }
 
          if (ret != 0) {
@@ -386,8 +388,8 @@ dns_main(void)
             strlcpy(reply.name, host, sizeof(reply.name));
             reply.error = 0;
          }
-         fd_set_block(sock[CHILD]);
-         xwrite(sock[CHILD], &reply, sizeof(reply));
+         fd_set_block(dns_sock[CHILD]);
+         xwrite(dns_sock[CHILD], &reply, sizeof(reply));
          verbosef("DNS: %s is \"%s\".", addr_to_str(&reply.addr),
             (ret == 0) ? reply.name : gai_strerror(ret));
       }