/*
- * $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.
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)
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) {
}
}
- 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
}