]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/dsi/dsi_tcp.c
Set version to 2.1
[netatalk.git] / libatalk / dsi / dsi_tcp.c
index 9fcf6146cce20408e961df0b20cc8d6470d119a6..35fc5bacfda3baad6ce0757ed916795fcb382373 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: dsi_tcp.c,v 1.18 2009-11-05 14:38:08 franklahm Exp $
+ * $Id: dsi_tcp.c,v 1.25 2009-12-08 22:34:37 didg Exp $
  *
  * Copyright (c) 1997, 1998 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
@@ -234,6 +234,64 @@ static int dsi_tcp_open(DSI *dsi)
     return pid;
 }
 
+/* get it from the interface list */
+#ifndef IFF_SLAVE
+#define IFF_SLAVE 0
+#endif
+
+static void guess_interface(DSI *dsi, const char *hostname)
+{
+    int fd;
+    char **start, **list;
+    struct ifreq ifr;
+    struct sockaddr_in *sa = (struct sockaddr_in *)&dsi->server;
+
+    start = list = getifacelist();
+    if (!start)
+        return;
+        
+    fd = socket(PF_INET, SOCK_STREAM, 0);
+
+    while (list && *list) {
+        strlcpy(ifr.ifr_name, *list, sizeof(ifr.ifr_name));
+        list++;
+
+
+        if (ioctl(dsi->serversock, SIOCGIFFLAGS, &ifr) < 0)
+            continue;
+
+        if (ifr.ifr_flags & (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_SLAVE))
+            continue;
+
+        if (!(ifr.ifr_flags & (IFF_UP | IFF_RUNNING)) )
+            continue;
+
+        if (ioctl(fd, SIOCGIFADDR, &ifr) < 0)
+            continue;
+
+        memset(&dsi->server, 0, sizeof(struct sockaddr_storage));
+        sa->sin_family = AF_INET;
+        sa->sin_port = htons(548);
+        sa->sin_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
+
+        LOG(log_info, logtype_default, "dsi_tcp: '%s' on interface '%s' will be used instead.",
+                  getip_string((struct sockaddr *)&dsi->server), ifr.ifr_name);
+        goto iflist_done;
+    }
+    LOG(log_info, logtype_default, "dsi_tcp (Chooser will not select afp/tcp) "
+        "Check to make sure %s is in /etc/hosts and the correct domain is in "
+        "/etc/resolv.conf: %s", hostname, strerror(errno));
+
+iflist_done:
+    close(fd);
+    freeifacelist(start);
+}
+
+
+#ifndef AI_NUMERICSERV
+#define AI_NUMERICSERV 0
+#endif
+
 /* this needs to accept passed in addresses */
 int dsi_tcp_init(DSI *dsi, const char *hostname, const char *address,
                  const char *port, const int proxy)
@@ -331,8 +389,8 @@ int dsi_tcp_init(DSI *dsi, const char *hostname, const char *address,
     hints.ai_socktype = SOCK_STREAM;
 
     if ((ret = getaddrinfo(hostname, port ? port : "548", &hints, &servinfo)) != 0) {
-        LOG(log_error, logtype_default, "dsi_tcp_init: getaddrinfo: %s\n", gai_strerror(ret));
-        return 0;
+        LOG(log_info, logtype_default, "dsi_tcp_init: getaddrinfo '%s': %s\n", hostname, gai_strerror(ret));
+        goto interfaces;
     }
 
     for (p = servinfo; p != NULL; p = p->ai_next) {
@@ -348,61 +406,17 @@ int dsi_tcp_init(DSI *dsi, const char *hostname, const char *address,
         }
     }
 
-    if (p == NULL) { /* no advertisable address found */
-        LOG(log_info, logtype_default, "dsi_tcp: cannot resolve hostname '%s'", hostname);
+    if (p) {
+        /* Store found address in dsi->server */
+        memcpy(&dsi->server, p->ai_addr, p->ai_addrlen);
         freeaddrinfo(servinfo);
-        return 0;
+        return 1;
     }
-
-    /* Store found address in dsi->server */
-    memcpy(&dsi->server, p->ai_addr, p->ai_addrlen);
+    LOG(log_info, logtype_default, "dsi_tcp: hostname '%s' resolves to loopback address", hostname);
     freeaddrinfo(servinfo);
-    return 1;
-
-    /*
-     * Note: I'll leave this code just in case. With getaddrinfo I guess we
-     * should be able to get an IP != 127.0.0.1 or ::1 from the hostname. Hopefully.
-     */
-#if 0
-    /* get it from the interface list */
-    char **start, **list;
-    struct ifreq ifr;
-    start = list = getifacelist();
-    while (list && *list) {
-        strlcpy(ifr.ifr_name, *list, sizeof(ifr.ifr_name));
-        list++;
-
-#ifndef IFF_SLAVE
-#define IFF_SLAVE 0
-#endif
-
-        if (ioctl(dsi->serversock, SIOCGIFFLAGS, &ifr) < 0)
-            continue;
-
-        if (ifr.ifr_flags & (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_SLAVE))
-            continue;
-
-        if (!(ifr.ifr_flags & (IFF_UP | IFF_RUNNING)) )
-            continue;
-
-        if (ioctl(dsi->serversock, SIOCGIFADDR, &ifr) < 0)
-            continue;
 
-        dsi->server.sin_addr.s_addr =
-            ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr;
-        LOG(log_info, logtype_default, "dsi_tcp: '%s' on interface '%s' will be used instead.",
-            inet_ntoa(dsi->server.sin_addr), ifr.ifr_name);
-        goto iflist_done;
-    }
-    LOG(log_info, logtype_default, "dsi_tcp (Chooser will not select afp/tcp) "
-        "Check to make sure %s is in /etc/hosts and the correct domain is in "
-        "/etc/resolv.conf: %s", hostname, strerror(errno));
-
-iflist_done:
-    if (start)
-        freeifacelist(start);
+interfaces:
+    guess_interface(dsi, hostname);
     return 1;
-
-#endif
 }