Add assert()s to tree.h to soothe Clang static analyzer.
[darkstat] / localip.c
index 53820d6..f7b7f93 100644 (file)
--- a/localip.c
+++ b/localip.c
@@ -8,11 +8,12 @@
  */
 
 #include "addr.h"
+#include "bsd.h" /* for strlcpy */
 #include "config.h" /* for HAVE_IFADDRS_H */
 #include "conv.h"
 #include "err.h"
 #include "localip.h"
-#include "bsd.h" /* for strlcpy */
+#include "now.h"
 
 #include <sys/socket.h>
 #include <net/if.h>
 # include <sys/ioctl.h>
 #endif
 
-struct local_ips *local_ips;
-
-struct local_ips *localip_make(void) {
-   struct local_ips *ips = xmalloc(sizeof(*ips));
-
+void localip_init(struct local_ips *ips) {
    ips->is_valid = 0;
-   ips->last_update = 0;
+   ips->last_update_mono = 0;
    ips->num_addrs = 0;
    ips->addrs = NULL;
-   return ips;
 }
 
 void localip_free(struct local_ips *ips) {
    if (ips->addrs != NULL)
       free(ips->addrs);
-   free(ips);
 }
 
-static void add_ip(const char *iface, struct local_ips *ips,
-                   int *index, struct addr *a) {
-   if (ips->num_addrs <= *index) {
+static void add_ip(const char *iface,
+                   struct local_ips *ips,
+                   int *idx,
+                   struct addr *a) {
+   if (ips->num_addrs <= *idx) {
       /* Grow. */
-      ips->addrs = xrealloc(ips->addrs, sizeof(*(ips->addrs)) * (*index + 1));
+      ips->addrs = xrealloc(ips->addrs, sizeof(*(ips->addrs)) * (*idx + 1));
       ips->num_addrs++;
-      assert(ips->num_addrs > *index);
+      assert(ips->num_addrs > *idx);
       verbosef("interface '%s' gained new address %s", iface, addr_to_str(a));
    } else {
       /* Warn about changed address. */
-      if (!addr_equal(ips->addrs + *index, a)) {
+      if (!addr_equal(ips->addrs + *idx, a)) {
          static char before[INET6_ADDRSTRLEN];
-         strncpy(before, addr_to_str(ips->addrs + *index), INET6_ADDRSTRLEN);
+         strncpy(before, addr_to_str(ips->addrs + *idx), INET6_ADDRSTRLEN);
          verbosef("interface '%s' address %d/%d changed from %s to %s",
-            iface, *index+1, ips->num_addrs, before, addr_to_str(a));
+            iface, *idx+1, ips->num_addrs, before, addr_to_str(a));
       }
    }
-   ips->addrs[*index] = *a;
-   (*index)++;
+   ips->addrs[*idx] = *a;
+   (*idx)++;
 }
 
 /* Returns 0 on failure. */
@@ -82,6 +79,12 @@ void localip_update(const char *iface, struct local_ips *ips) {
       return;
    }
 
+   if (ips->last_update_mono == now_mono()) {
+      /* Too soon, bail out. */
+      return;
+   }
+   ips->last_update_mono = now_mono();
+
 #ifdef HAVE_IFADDRS_H
    {
       struct ifaddrs *ifas, *ifa;
@@ -100,7 +103,8 @@ void localip_update(const char *iface, struct local_ips *ips) {
             a.family = IPv4;
             a.ip.v4 = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
             add_ip(iface, ips, &new_addrs, &a);
-         } else if (ifa->ifa_addr->sa_family == AF_INET6) {
+         }
+         if (ifa->ifa_addr->sa_family == AF_INET6) {
             struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)ifa->ifa_addr;
 # if 0
             if ( IN6_IS_ADDR_LINKLOCAL(&(sa6->sin6_addr))
@@ -110,13 +114,7 @@ void localip_update(const char *iface, struct local_ips *ips) {
             a.family = IPv6;
             memcpy(&(a.ip.v6), &sa6->sin6_addr, sizeof(a.ip.v6));
             add_ip(iface, ips, &new_addrs, &a);
-# ifdef AF_PACKET
-         } else if (ifa->ifa_addr->sa_family == AF_PACKET) {
-            /* ignore */
-# endif
-         } else
-            verbosef("unknown sa_family=%d on interface '%s'",
-               (int)ifa->ifa_addr->sa_family, iface);
+         }
       }
       freeifaddrs(ifas);
    }
@@ -150,7 +148,6 @@ void localip_update(const char *iface, struct local_ips *ips) {
             iface, ips->num_addrs, new_addrs);
       ips->num_addrs = new_addrs;
    }
-   ips->last_update = time(NULL);
 }
 
 int is_localip(const struct addr * const a,