Fix memory leak.
[darkstat] / db.c
diff --git a/db.c b/db.c
index 6a15ade..cf50da9 100644 (file)
--- a/db.c
+++ b/db.c
@@ -1,7 +1,7 @@
 /* darkstat 3
  *
  * db.c: load and save in-memory database from/to file
- * copyright (c) 2007 Ben Stewart, Emil Mikulic.
+ * copyright (c) 2007-2011 Ben Stewart, Emil Mikulic.
  *
  * You may use, modify and redistribute this file under the terms of the
  * GNU General Public License version 2. (see COPYING.GPL)
 #define _GNU_SOURCE 1 /* for O_NOFOLLOW in Linux */
 
 #include <sys/types.h>
-
-#include "darkstat.h"
-#include "err.h"
-#include "hosts_db.h"
-#include "graph_db.h"
-#include "db.h"
-
 #include <netinet/in.h> /* for ntohs() and friends */
 #include <assert.h>
 #include <fcntl.h>
 #include <string.h>
 #include <unistd.h>
 
+#include "cdefs.h"
+#include "err.h"
+#include "hosts_db.h"
+#include "graph_db.h"
+#include "db.h"
+
 static const unsigned char export_file_header[] = {0xDA, 0x31, 0x41, 0x59};
 static const unsigned char export_tag_hosts_ver1[] = {0xDA, 'H', 'S', 0x01};
 static const unsigned char export_tag_graph_ver1[] = {0xDA, 'G', 'R', 0x01};
 
 #ifndef swap64
-static inline uint64_t
-swap64(uint64_t _x)
-{
+static uint64_t swap64(uint64_t _x) {
    /* this is __bswap64 from:
     * $FreeBSD: src/sys/i386/include/endian.h,v 1.41$
     */
@@ -41,17 +38,12 @@ swap64(uint64_t _x)
 }
 #endif
 
-uint64_t
-hton64(const uint64_t ho)
-{
-   if (ntohs(0x1234) == 0x1234) return ho;
-   else return swap64(ho);
-}
-
-uint64_t
-ntoh64(const uint64_t no)
-{
-   return hton64(no);
+#define ntoh64 hton64
+static inline uint64_t hton64(const uint64_t ho) {
+   if (ntohs(0x1234) == 0x1234)
+      return ho;
+   else
+      return swap64(ho);
 }
 
 void
@@ -152,20 +144,37 @@ read32(const int fd, uint32_t *dest)
    return 1;
 }
 
-/* Read a struct addr46 from a file.  Addresses are always stored in network
+/* Read an IPv4 addr from a file.  This is for backward compatibility with
+ * host records version 1 and 2.
+ */
+int
+readaddr_ipv4(const int fd, struct addr *dest)
+{
+   dest->family = IPv4;
+   return readn(fd, &(dest->ip.v4), sizeof(dest->ip.v4));
+}
+
+/* Read a struct addr from a file.  Addresses are always stored in network
  * order, both in the file and in the host's memory (FIXME: is that right?)
- * The component "dest->af" must specify AF_INET or AF_INET6.
  */
 int
-readaddr(const int fd, struct addr46 *dest)
+readaddr(const int fd, struct addr *dest)
 {
-   assert(sizeof(*dest) == sizeof(struct addr46));
-   assert(dest->af == AF_INET || dest->af == AF_INET6);
+   unsigned char family;
 
-   if (dest->af == AF_INET)
-      return readn(fd, &dest->addr.ip, sizeof(struct in_addr));
+   if (!read8(fd, &family))
+      return 0;
+
+   if (family == 4) {
+      dest->family = IPv4;
+      return readn(fd, &(dest->ip.v4), sizeof(dest->ip.v4));
+   }
+   else if (family == 6) {
+      dest->family = IPv6;
+      return readn(fd, dest->ip.v6.s6_addr, sizeof(dest->ip.v6.s6_addr));
+   }
    else
-      return readn(fd, &dest->addr.ip6, sizeof(struct in6_addr));
+      return 0; /* no address family I ever heard of */
 }
 
 /* Read a network order uint64_t from a file
@@ -243,20 +252,22 @@ write64(const int fd, const uint64_t i)
 }
 
 
-/* Write the active address part in a struct addr46 structure to a file.
+/* Write the active address part in a struct addr to a file.
  * Addresses are always stored in network order, both in the file and
  * in the host's memory (FIXME: is that right?)
  */
 int
-writeaddr(const int fd, const struct addr46 *const ip)
+writeaddr(const int fd, const struct addr *const a)
 {
-   assert(sizeof(*ip) == sizeof(struct addr46));
-   assert(ip->af == AF_INET || ip->af == AF_INET6);
+   if (!write8(fd, a->family))
+      return 0;
 
-   if (ip->af == AF_INET)
-      return writen(fd, &ip->addr.ip, sizeof(ip->addr.ip));
-   else
-      return writen(fd, &ip->addr.ip6, sizeof(ip->addr.ip6));
+   if (a->family == IPv4)
+      return writen(fd, &(a->ip.v4), sizeof(a->ip.v4));
+   else {
+      assert(a->family == IPv6);
+      return writen(fd, a->ip.v6.s6_addr, sizeof(a->ip.v6.s6_addr));
+   }
 }
 
 /* ---------------------------------------------------------------------------