chiark / gitweb /
Add a config option to suppres rescan on (un)mount.
[disorder] / lib / addr.c
index 8082cad5cf659644a39a437d5fd5bba198688343..052466c649ff50ba866917f8b5565b2e89407088 100644 (file)
@@ -63,23 +63,24 @@ struct addrinfo *get_address(const struct stringlist *a,
   case 1:
     byte_xasprintf(&name, "host * service %s", a->s[0]);
     if((rc = getaddrinfo(0, a->s[0], pref, &res))) {
-      error(0, "getaddrinfo %s: %s", a->s[0], gai_strerror(rc));
+      disorder_error(0, "getaddrinfo %s: %s", a->s[0], gai_strerror(rc));
       return 0;
     }
     break;
   case 2:
     byte_xasprintf(&name, "host %s service %s", a->s[0], a->s[1]);
     if((rc = getaddrinfo(a->s[0], a->s[1], pref, &res))) {
-      error(0, "getaddrinfo %s %s: %s", a->s[0], a->s[1], gai_strerror(rc));
+      disorder_error(0, "getaddrinfo %s %s: %s",
+                    a->s[0], a->s[1], gai_strerror(rc));
       return 0;
     }
     break;
   default:
-    error(0, "invalid network address specification (n=%d)", a->n);
+    disorder_error(0, "invalid network address specification (n=%d)", a->n);
     return 0;
   }
   if(!res || (pref && res->ai_socktype != pref->ai_socktype)) {
-    error(0, "getaddrinfo didn't give us a suitable socket address");
+    disorder_error(0, "getaddrinfo didn't give us a suitable socket address");
     if(res)
       freeaddrinfo(res);
     return 0;
@@ -95,29 +96,38 @@ struct addrinfo *get_address(const struct stringlist *a,
  */
 int addrinfocmp(const struct addrinfo *a,
                const struct addrinfo *b) {
-  const struct sockaddr_in *ina, *inb;
-  const struct sockaddr_in6 *in6a, *in6b;
-  
   if(a->ai_family != b->ai_family) return a->ai_family - b->ai_family;
   if(a->ai_socktype != b->ai_socktype) return a->ai_socktype - b->ai_socktype;
   if(a->ai_protocol != b->ai_protocol) return a->ai_protocol - b->ai_protocol;
-  switch(a->ai_family) {
+  return sockaddrcmp(a->ai_addr, b->ai_addr);
+}
+
+/** @brief Comparison function for socket addresses
+ *
+ * Suitable for qsort().
+ */
+int sockaddrcmp(const struct sockaddr *a,
+               const struct sockaddr *b) {
+  const struct sockaddr_in *ina, *inb;
+  const struct sockaddr_in6 *in6a, *in6b;
+  
+  if(a->sa_family != b->sa_family) return a->sa_family - b->sa_family;
+  switch(a->sa_family) {
   case PF_INET:
-    ina = (const struct sockaddr_in *)a->ai_addr;
-    inb = (const struct sockaddr_in *)b->ai_addr;
+    ina = (const struct sockaddr_in *)a;
+    inb = (const struct sockaddr_in *)b;
     if(ina->sin_port != inb->sin_port) return ina->sin_port - inb->sin_port;
     return ina->sin_addr.s_addr - inb->sin_addr.s_addr;
     break;
   case PF_INET6:
-    in6a = (const struct sockaddr_in6 *)a->ai_addr;
-    in6b = (const struct sockaddr_in6 *)b->ai_addr;
+    in6a = (const struct sockaddr_in6 *)a;
+    in6b = (const struct sockaddr_in6 *)b;
     if(in6a->sin6_port != in6b->sin6_port)
       return in6a->sin6_port - in6b->sin6_port;
     return memcmp(&in6a->sin6_addr, &in6b->sin6_addr,
                  sizeof (struct in6_addr));
   default:
-    error(0, "unsupported protocol family %d", a->ai_protocol);
-    return memcmp(a->ai_addr, b->ai_addr, a->ai_addrlen); /* kludge */
+    disorder_fatal(0, "unsupported protocol family %d", a->sa_family);
   }
 }
 
@@ -325,9 +335,9 @@ struct addrinfo *netaddress_resolve(const struct netaddress *na,
   snprintf(service, sizeof service, "%d", na->port);
   rc = getaddrinfo(na->address, service, hints, &res);
   if(rc) {
-    error(0, "getaddrinfo %s %d: %s",
-         na->address ? na->address : "*",
-         na->port, gai_strerror(rc));
+    disorder_error(0, "getaddrinfo %s %d: %s",
+                  na->address ? na->address : "*",
+                  na->port, gai_strerror(rc));
     return NULL;
   }
   return res;