gftp r960 - in trunk: . lib



Author: masneyb
Date: Fri Mar 28 11:44:36 2008
New Revision: 960
URL: http://svn.gnome.org/viewvc/gftp?rev=960&view=rev

Log:
2008-03-28 Brian Masney <masneyb gftp org>

        * lib/Makefile.am lib/misc.c lib/socket-connect.c
	lib/socket-connect-getaddrinfo.c lib/socket-connect-gethostbyname.c
        lib/sockutils.c lib/gftp.h - cleaned up more of the socket functions
        and split them up into their own files. Cleanups and bug fixes to the
        DNS lookup code.



Added:
   trunk/lib/socket-connect-getaddrinfo.c
   trunk/lib/socket-connect-gethostbyname.c
Modified:
   trunk/ChangeLog
   trunk/lib/Makefile.am
   trunk/lib/gftp.h
   trunk/lib/misc.c
   trunk/lib/socket-connect.c
   trunk/lib/sockutils.c

Modified: trunk/lib/Makefile.am
==============================================================================
--- trunk/lib/Makefile.am	(original)
+++ trunk/lib/Makefile.am	Fri Mar 28 11:44:36 2008
@@ -5,6 +5,7 @@
 libgftp_a_SOURCES=bookmark.c cache.c charset-conv.c config_file.c fsp.c ftps.c \
                   https.c local.c misc.c mkstemps.c parse-dir-listing.c \
                   protocols.c pty.c rfc959.c rfc2068.c sshv2.c sslcommon.c \
-                  socket-connect.c sockutils.c
+                  socket-connect.c socket-connect-getaddrinfo.c \
+                  socket-connect-gethostbyname.c sockutils.c
 INCLUDES= GLIB_CFLAGS@ @PTHREAD_CFLAGS@ -I../intl -DSHARE_DIR=\"$(datadir)/gftp\" -DLOCALE_DIR=\"$(datadir)/locale\"
 noinst_HEADERS=gftp.h ftpcommon.h httpcommon.h options.h

Modified: trunk/lib/gftp.h
==============================================================================
--- trunk/lib/gftp.h	(original)
+++ trunk/lib/gftp.h	Fri Mar 28 11:44:36 2008
@@ -385,10 +385,8 @@
   int wakeup_main_thread[2];	/* FD that gets written to by the threads
                                    to wakeup the parent */
 
-#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
   void *remote_addr;
   size_t remote_addr_len;
-#endif
   int ai_family;
 
   int server_type;		/* The type of server we are connected to.
@@ -1010,15 +1008,6 @@
 					  void (*update_func) 
 						( gftp_transfer * transfer ));
 
-struct hostent *r_gethostbyname 	( const char *name, 
-					  struct hostent *result_buf, 
-					  int *h_errnop );
-
-struct servent *r_getservbyname 	( const char *name, 
-					  const char *proto,
-					  /* out@*/ struct servent *result_buf, 
-					  int *h_errnop );
-
 int gftp_set_config_options 		( gftp_request * request );
 
 void print_file_list 			( GList * list );
@@ -1094,6 +1083,29 @@
 					  char *proxy_hostname,
 					  unsigned int proxy_port );
 
+/* socket-connect-getaddrinfo.c */
+struct addrinfo * lookup_host_with_getaddrinfo
+					( gftp_request *request,
+					  char *service,
+					  char *proxy_hostname,
+					  int proxy_port );
+
+int gftp_connect_server_with_getaddrinfo
+					( gftp_request * request,
+					  char *service,
+					  char *proxy_hostname,
+					  unsigned int proxy_port );
+
+/* socket-connect-gethostbyname.c */
+int lookup_host_with_gethostbyname	( gftp_request *request,
+					  char *proxy_hostname,
+					  struct hostent *hostp );
+
+int gftp_connect_server_legacy		( gftp_request * request,
+					  char *service,
+					  char *proxy_hostname,
+					  unsigned int proxy_port );
+
 /* sockutils.c */
 ssize_t gftp_get_line 			( gftp_request * request, 
 					  /* out@*/ gftp_getline_buffer ** rbuf,
@@ -1122,3 +1134,8 @@
 					  int fd, 
 					  int non_blocking );
 
+struct servent * r_getservbyname	( const char *name,
+					  const char *proto,
+					  struct servent *result_buf,
+					  int *h_errnop );
+

Modified: trunk/lib/misc.c
==============================================================================
--- trunk/lib/misc.c	(original)
+++ trunk/lib/misc.c	Fri Mar 28 11:44:36 2008
@@ -930,60 +930,6 @@
 }
 
 
-struct hostent *
-r_gethostbyname (const char *name, struct hostent *result_buf, int *h_errnop)
-{
-  static GStaticMutex hostfunclock = G_STATIC_MUTEX_INIT; 
-  struct hostent *hent;
-
-  if (g_thread_supported ())
-    g_static_mutex_lock (&hostfunclock);
-
-  if ((hent = gethostbyname (name)) == NULL)
-    {
-      if (h_errnop)
-        *h_errnop = h_errno;
-    }
-  else
-    {
-      *result_buf = *hent;
-      hent = result_buf;
-    }
-
-  if (g_thread_supported ())
-    g_static_mutex_unlock (&hostfunclock);
-
-  return (hent);
-}
-
-
-struct servent *
-r_getservbyname (const char *name, const char *proto,
-                 struct servent *result_buf, int *h_errnop)
-{
-  static GStaticMutex servfunclock = G_STATIC_MUTEX_INIT;
-  struct servent *sent;
-
-  if (g_thread_supported ())
-    g_static_mutex_lock (&servfunclock);
-
-  if ((sent = getservbyname (name, proto)) == NULL)
-    {
-      if (h_errnop)
-        *h_errnop = h_errno;
-    }
-  else
-    {
-      *result_buf = *sent;
-      sent = result_buf;
-    }
-
-  if (g_thread_supported ())
-    g_static_mutex_unlock (&servfunclock);
-  return (sent);
-}
-
-
 char *
 base64_encode (char *str)
 {

Added: trunk/lib/socket-connect-getaddrinfo.c
==============================================================================
--- (empty file)
+++ trunk/lib/socket-connect-getaddrinfo.c	Fri Mar 28 11:44:36 2008
@@ -0,0 +1,158 @@
+/*****************************************************************************/
+/*  socket-connect-getaddrinfo.c - uses getaddrinfo for connections          */
+/*  Copyright (C) 1998-2008 Brian Masney <masneyb gftp org>                  */
+/*                                                                           */
+/*  This program is free software; you can redistribute it and/or modify     */
+/*  it under the terms of the GNU General Public License as published by     */
+/*  the Free Software Foundation; either version 2 of the License, or        */
+/*  (at your option) any later version.                                      */
+/*                                                                           */
+/*  This program is distributed in the hope that it will be useful,          */
+/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
+/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
+/*  GNU General Public License for more details.                             */
+/*                                                                           */
+/*  You should have received a copy of the GNU General Public License        */
+/*  along with this program; if not, write to the Free Software              */
+/*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA      */
+/*****************************************************************************/
+
+#include "gftp.h"
+static const char cvsid[] = "$Id: protocols.c 952 2008-01-24 23:31:26Z masneyb $";
+
+#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
+
+static int
+get_port (struct addrinfo *addr)
+{
+  struct sockaddr_in * saddr;
+  int port;
+
+  if (addr->ai_family == AF_INET)
+    {
+      saddr = (struct sockaddr_in *) addr->ai_addr;
+      port = ntohs (saddr->sin_port);
+    }
+  else
+    port = 0;
+
+  return (port);
+}
+
+
+struct addrinfo *
+lookup_host_with_getaddrinfo (gftp_request *request, char *service,
+                              char *proxy_hostname, int proxy_port)
+{
+  struct addrinfo hints, *hostp;
+  intptr_t enable_ipv6;
+  char serv[8], *connect_host;
+  int ret, connect_port;
+
+  if (request->use_proxy)
+    {
+      connect_host = proxy_hostname;
+      connect_port = proxy_port;
+    }
+  else
+    {
+      connect_host = request->hostname;
+      connect_port = request->port;
+    }
+
+  gftp_lookup_request_option (request, "enable_ipv6", &enable_ipv6);
+
+  memset (&hints, 0, sizeof (hints));
+  hints.ai_flags = AI_CANONNAME;
+
+  hints.ai_family = enable_ipv6 ? PF_UNSPEC : AF_INET;
+  hints.ai_socktype = SOCK_STREAM;
+
+  if (connect_port == 0)
+    strcpy (serv, service); 
+  else
+    snprintf (serv, sizeof (serv), "%d", connect_port);
+
+  request->logging_function (gftp_logging_misc, request,
+                             _("Looking up %s\n"), connect_host);
+  if ((ret = getaddrinfo (connect_host, serv, &hints, 
+                             &hostp)) != 0)
+    {
+      request->logging_function (gftp_logging_error, request,
+                                 _("Cannot look up hostname %s: %s\n"),
+                                 connect_host, gai_strerror (ret));
+      return (NULL);
+    }
+
+  return (hostp);
+}
+
+
+int
+gftp_connect_server_with_getaddrinfo (gftp_request * request, char *service,
+                                      char *proxy_hostname,
+                                      unsigned int proxy_port)
+{
+  struct addrinfo *res, *hostp, *current_hostp;
+  unsigned int port;
+  int sock = -1;
+
+  hostp = lookup_host_with_getaddrinfo (request, service, proxy_hostname,
+                                        proxy_port);
+  if (hostp == NULL)
+    return (GFTP_ERETRYABLE);
+
+  for (res = hostp; res != NULL; res = res->ai_next)
+    {
+      port = get_port (res);
+      if (!request->use_proxy)
+        request->port = port;
+
+      if ((sock = socket (res->ai_family, res->ai_socktype, 
+                          res->ai_protocol)) < 0)
+        {
+          request->logging_function (gftp_logging_error, request,
+                                     _("Failed to create a socket: %s\n"),
+                                     g_strerror (errno));
+          continue; 
+        } 
+
+      request->logging_function (gftp_logging_misc, request,
+                                 _("Trying %s:%d\n"), res[0].ai_canonname,
+                                 port);
+
+      if (connect (sock, res->ai_addr, res->ai_addrlen) == -1)
+        {
+          request->logging_function (gftp_logging_error, request,
+                                     _("Cannot connect to %s: %s\n"),
+                                     res[0].ai_canonname, g_strerror (errno));
+          close (sock);
+          continue;
+        }
+
+      current_hostp = res;
+      request->ai_family = res->ai_family;
+      break;
+    }
+
+  if (res == NULL)
+    {
+      if (hostp != NULL)
+        freeaddrinfo (hostp);
+      
+      return (GFTP_ERETRYABLE);
+    }
+
+  request->remote_addr_len = current_hostp->ai_addrlen;
+  request->remote_addr = g_malloc0 (request->remote_addr_len);
+  memcpy (request->remote_addr, &((struct sockaddr_in *) current_hostp->ai_addr)->sin_addr,
+          request->remote_addr_len);
+
+  request->logging_function (gftp_logging_misc, request,
+                             _("Connected to %s:%d\n"), res[0].ai_canonname,
+                             port);
+
+  return (sock);
+}
+
+#endif

Added: trunk/lib/socket-connect-gethostbyname.c
==============================================================================
--- (empty file)
+++ trunk/lib/socket-connect-gethostbyname.c	Fri Mar 28 11:44:36 2008
@@ -0,0 +1,165 @@
+/*****************************************************************************/
+/*  socket-connect.c - contains functions for connecting to a server         */
+/*  Copyright (C) 1998-2008 Brian Masney <masneyb gftp org>                  */
+/*                                                                           */
+/*  This program is free software; you can redistribute it and/or modify     */
+/*  it under the terms of the GNU General Public License as published by     */
+/*  the Free Software Foundation; either version 2 of the License, or        */
+/*  (at your option) any later version.                                      */
+/*                                                                           */
+/*  This program is distributed in the hope that it will be useful,          */
+/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
+/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
+/*  GNU General Public License for more details.                             */
+/*                                                                           */
+/*  You should have received a copy of the GNU General Public License        */
+/*  along with this program; if not, write to the Free Software              */
+/*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA      */
+/*****************************************************************************/
+
+#include "gftp.h"
+static const char cvsid[] = "$Id: protocols.c 952 2008-01-24 23:31:26Z masneyb $";
+
+#if !defined (HAVE_GETADDRINFO) || !defined (HAVE_GAI_STRERROR)
+
+static struct hostent *
+r_gethostbyname (const char *name, struct hostent *result_buf, int *h_errnop)
+{
+  static GStaticMutex hostfunclock = G_STATIC_MUTEX_INIT; 
+  struct hostent *hent;
+
+  if (g_thread_supported ())
+    g_static_mutex_lock (&hostfunclock);
+
+  if ((hent = gethostbyname (name)) == NULL)
+    {
+      if (h_errnop)
+        *h_errnop = h_errno;
+    }
+  else
+    {
+      *result_buf = *hent;
+      hent = result_buf;
+    }
+
+  if (g_thread_supported ())
+    g_static_mutex_unlock (&hostfunclock);
+
+  return (hent);
+}
+
+
+int
+lookup_host_with_gethostbyname (gftp_request *request, char *proxy_hostname,
+                                struct hostent *hostp)
+{
+  char *connect_host;
+
+  if (request->use_proxy)
+    connect_host = proxy_hostname;
+  else
+    connect_host = request->hostname;
+
+  request->logging_function (gftp_logging_misc, request,
+                             _("Looking up %s\n"), connect_host);
+
+  if ((r_gethostbyname (connect_host, hostp, NULL)) == NULL)
+    {
+      request->logging_function (gftp_logging_error, request,
+                                 _("Cannot look up hostname %s: %s\n"),
+                                 connect_host, g_strerror (errno));
+      return (GFTP_ERETRYABLE);
+    }
+
+  return (0);
+}
+
+
+int
+gftp_connect_server_legacy (gftp_request * request, char *service,
+                            char *proxy_hostname, unsigned int proxy_port)
+{
+  int sock, curhost, ret, connect_port;
+  struct sockaddr_in remote_address;
+  struct servent serv_struct;
+  struct hostent host;
+
+  ret = lookup_host_with_gethostbyname (request, proxy_hostname, &host);
+  if (ret != 0)
+    return (ret);
+
+  if (request->use_proxy)
+    connect_port = proxy_port;
+  else
+    connect_port = request->port;
+
+  if (connect_port == 0)
+    {
+      if (!r_getservbyname (service, "tcp", &serv_struct, NULL))
+        {
+          request->logging_function (gftp_logging_error, request,
+                                     _("Cannot look up service name %s/tcp. Please check your services file\n"),
+                                     service);
+          return (GFTP_ERETRYABLE);
+        }
+
+      connect_port = ntohs (serv_struct.s_port);
+
+      if (!request->use_proxy)
+        request->port = connect_port;
+    }
+
+  sock = GFTP_ERETRYABLE;
+  request->ai_family = AF_INET;
+
+  for (curhost = 0; host.h_addr_list[curhost] != NULL; curhost++)
+    {
+      if ((sock = socket (request->ai_family, SOCK_STREAM, IPPROTO_TCP)) < 0)
+        {
+          request->logging_function (gftp_logging_error, request,
+                                     _("Failed to create a IPv4 socket: %s\n"),
+                                     g_strerror (errno));
+          return (GFTP_ERETRYABLE);
+        }
+
+      memset (&remote_address, 0, sizeof (remote_address));
+      remote_address.sin_family = AF_INET;
+      remote_address.sin_port = htons (connect_port);
+
+      memcpy (&remote_address.sin_addr,
+              host.h_addr_list[curhost],
+              host.h_length);
+
+      request->logging_function (gftp_logging_misc, request,
+                                 _("Trying %s:%d\n"),
+                                 host.h_name, ntohs (remote_address.sin_port));
+
+      if (connect (sock, (struct sockaddr *) &remote_address,
+                   sizeof (remote_address)) == -1)
+        {
+          request->logging_function (gftp_logging_error, request,
+                                     _("Cannot connect to %s: %s\n"),
+                                     host.h_name, g_strerror (errno));
+          close (sock);
+          continue;
+        }
+
+      break;
+    }
+
+  if (host.h_addr_list[curhost] == NULL)
+    return (GFTP_ERETRYABLE);
+
+  request->remote_addr_len = host.h_length;
+  request->remote_addr = g_malloc0 (request->remote_addr_len);
+  memcpy (request->remote_addr, &host.h_addr_list[curhost],
+          request->remote_addr_len);
+
+  request->logging_function (gftp_logging_misc, request,
+                             _("Connected to %s:%d\n"), host.h_name,
+                             ntohs (remote_address.sin_port));
+
+  return (sock);
+}
+
+#endif

Modified: trunk/lib/socket-connect.c
==============================================================================
--- trunk/lib/socket-connect.c	(original)
+++ trunk/lib/socket-connect.c	Fri Mar 28 11:44:36 2008
@@ -20,26 +20,21 @@
 #include "gftp.h"
 static const char cvsid[] = "$Id: protocols.c 952 2008-01-24 23:31:26Z masneyb $";
 
-/* FIXME - clean up this function */
 static int
 gftp_need_proxy (gftp_request * request, char *service, char *proxy_hostname, 
-                 unsigned int proxy_port)
+                 unsigned int proxy_port, void **connect_data)
 {
   gftp_config_list_vars * proxy_hosts;
   gftp_proxy_hosts * hostname;
   size_t hostlen, domlen;
   unsigned char addy[4];
-  struct sockaddr *addr;
   GList * templist;
   gint32 netaddr;
   char *pos;
-#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
-  struct addrinfo hints, *hostp;
-  unsigned int port;
-  int errnum;
-  char serv[8];
-#else
-  struct hostent host, *hostp;
+
+#if !defined (HAVE_GETADDRINFO) || !defined (HAVE_GAI_STRERROR)
+  struct hostent host;
+  int ret;
 #endif
 
   gftp_lookup_global_option ("dont_use_proxy", &proxy_hosts);
@@ -50,48 +45,22 @@
     return (proxy_hostname != NULL && 
             *proxy_hostname != '\0');
 
-  hostp = NULL;
 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
-  memset (&hints, 0, sizeof (hints));
-  hints.ai_flags = AI_CANONNAME;
-  hints.ai_family = PF_UNSPEC;
-  hints.ai_socktype = SOCK_STREAM;
-
-  port = request->use_proxy ? proxy_port : request->port;
-  if (port == 0)
-    strcpy (serv, service);
-  else
-    snprintf (serv, sizeof (serv), "%d", port);
-
-  request->logging_function (gftp_logging_misc, request,
-                             _("Looking up %s\n"), request->hostname);
 
-  if ((errnum = getaddrinfo (request->hostname, serv, &hints, 
-                             &hostp)) != 0)
-    {
-      request->logging_function (gftp_logging_error, request,
-                                 _("Cannot look up hostname %s: %s\n"),
-                                 request->hostname, gai_strerror (errnum));
-      return (GFTP_ERETRYABLE);
-    }
-
-  addr = hostp->ai_addr;
+  *connect_data = lookup_host_with_getaddrinfo (request, service,
+                                                proxy_hostname, proxy_port);
+  if (*connect_data == NULL)
+    return (GFTP_ERETRYABLE);
 
 #else /* !HAVE_GETADDRINFO */
-  request->logging_function (gftp_logging_misc, request,
-                             _("Looking up %s\n"), request->hostname);
 
-  if (!(hostp = r_gethostbyname (request->hostname, &host, NULL)))
-    {
-      request->logging_function (gftp_logging_error, request,
-                                 _("Cannot look up hostname %s: %s\n"),
-                                 request->hostname, g_strerror (errno));
-      return (GFTP_ERETRYABLE);
-    }
+  ret = lookup_host_with_gethostbyname (request, proxy_hostname, &host);
+  if (ret != 0)
+    return (ret);
 
-  addr = (struct sockaddr *) host.h_addr_list[0];
+  connect_data = NULL; /* FIXME */
 
-#endif /* HAVE_GETADDRINFO */
+#endif
 
   templist = proxy_hosts->list;
   while (templist != NULL)
@@ -111,7 +80,7 @@
 
       if (hostname->ipv4_network_address != 0)
         {
-          memcpy (addy, addr, sizeof (*addy));
+          memcpy (addy, request->remote_addr, sizeof (*addy));
           netaddr =
             (((addy[0] & 0xff) << 24) | ((addy[1] & 0xff) << 16) |
              ((addy[2] & 0xff) << 8) | (addy[3] & 0xff)) & 
@@ -126,248 +95,23 @@
 }
 
 
-#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
-static int
-get_port (struct addrinfo *addr)
-{
-  struct sockaddr_in * saddr;
-  int port;
-
-  if (addr->ai_family == AF_INET)
-    {
-      saddr = (struct sockaddr_in *) addr->ai_addr;
-      port = ntohs (saddr->sin_port);
-    }
-  else
-    port = 0;
-
-  return (port);
-}
-
-
-static int
-gftp_connect_server_with_getaddr (gftp_request * request, char *service,
-                                  char *proxy_hostname, unsigned int proxy_port)
-{
-  struct addrinfo *hostp, *current_hostp;
-  char *connect_host, *disphost;
-  struct addrinfo hints, *res;
-  intptr_t enable_ipv6;
-  unsigned int port;
-  int ret, sock = -1;
-  char serv[8];
-
-  if ((ret = gftp_need_proxy (request, service, proxy_hostname,
-                                 proxy_port)) < 0)
-    return (ret);
-  else
-    request->use_proxy = ret;
-
-  gftp_lookup_request_option (request, "enable_ipv6", &enable_ipv6);
-
-  memset (&hints, 0, sizeof (hints));
-  hints.ai_flags = AI_CANONNAME;
-
-  hints.ai_family = enable_ipv6 ? PF_UNSPEC : AF_INET;
-  hints.ai_socktype = SOCK_STREAM;
-
-  if (request->use_proxy)
-    {
-      connect_host = proxy_hostname;
-      port = proxy_port;
-    }
-  else
-    {
-      connect_host = request->hostname;
-      port = request->port;
-    }
-
-  if (port == 0)
-    strcpy (serv, service); 
-  else
-    snprintf (serv, sizeof (serv), "%d", port);
-
-  request->logging_function (gftp_logging_misc, request,
-                             _("Looking up %s\n"), connect_host);
-  if ((ret = getaddrinfo (connect_host, serv, &hints, 
-                             &hostp)) != 0)
-    {
-      request->logging_function (gftp_logging_error, request,
-                                 _("Cannot look up hostname %s: %s\n"),
-                                 connect_host, gai_strerror (ret));
-      return (GFTP_ERETRYABLE);
-    }
-
-  disphost = connect_host;
-  for (res = hostp; res != NULL; res = res->ai_next)
-    {
-      disphost = res->ai_canonname ? res->ai_canonname : connect_host;
-      port = get_port (res);
-      if (!request->use_proxy)
-        request->port = port;
-
-      if ((sock = socket (res->ai_family, res->ai_socktype, 
-                          res->ai_protocol)) < 0)
-        {
-          request->logging_function (gftp_logging_error, request,
-                                     _("Failed to create a socket: %s\n"),
-                                     g_strerror (errno));
-          continue; 
-        } 
-
-      request->logging_function (gftp_logging_misc, request,
-                                 _("Trying %s:%d\n"), disphost, port);
-
-      if (connect (sock, res->ai_addr, res->ai_addrlen) == -1)
-        {
-          request->logging_function (gftp_logging_error, request,
-                                     _("Cannot connect to %s: %s\n"),
-                                     disphost, g_strerror (errno));
-          close (sock);
-          continue;
-        }
-
-      current_hostp = res;
-      request->ai_family = res->ai_family;
-      break;
-    }
-
-  if (res == NULL)
-    {
-      if (hostp != NULL)
-        freeaddrinfo (hostp);
-      
-      return (GFTP_ERETRYABLE);
-    }
-
-  request->remote_addr_len = current_hostp->ai_addrlen;
-  request->remote_addr = g_malloc0 (request->remote_addr_len);
-  memcpy (request->remote_addr, &((struct sockaddr_in *) current_hostp->ai_addr)->sin_addr,
-          request->remote_addr_len);
-
-  request->logging_function (gftp_logging_misc, request,
-                             _("Connected to %s:%d\n"), connect_host, port);
-
-  return (sock);
-}
-#endif
-
-
-static int
-gftp_connect_server_legacy (gftp_request * request, char *service,
-                            char *proxy_hostname, unsigned int proxy_port)
+int
+gftp_connect_server (gftp_request * request, char *service,
+                     char *proxy_hostname, unsigned int proxy_port)
 {
-  struct sockaddr_in remote_address;
-  char *connect_host, *disphost;
-  struct hostent host, *hostp;
-  struct servent serv_struct;
-  int ret, sock, curhost;
-  unsigned int port;
+  void *connect_data;
+  int sock, ret;
 
   if ((ret = gftp_need_proxy (request, service, proxy_hostname,
-                              proxy_port)) < 0)
+                              proxy_port, &connect_data)) < 0)
     return (ret);
-
   request->use_proxy = ret;
-  if (request->use_proxy == 1)
-    hostp = NULL;
-
-  request->ai_family = AF_INET;
-  if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
-    {
-      request->logging_function (gftp_logging_error, request,
-                                 _("Failed to create a IPv4 socket: %s\n"),
-                                 g_strerror (errno));
-      return (GFTP_ERETRYABLE);
-    }
-
-  memset (&remote_address, 0, sizeof (remote_address));
-  remote_address.sin_family = AF_INET;
-
-  if (request->use_proxy)
-    {
-      connect_host = proxy_hostname;
-      port = proxy_port;
-    }
-  else
-    {
-      connect_host = request->hostname;
-      port = request->port;
-    }
-
-  if (port == 0)
-    {
-      if (!r_getservbyname (service, "tcp", &serv_struct, NULL))
-        {
-          request->logging_function (gftp_logging_error, request,
-                                     _("Cannot look up service name %s/tcp. Please check your services file\n"),
-                                     service);
-          close (sock);
-          return (GFTP_EFATAL);
-        }
-
-      port = ntohs (serv_struct.s_port);
-
-      if (!request->use_proxy)
-        request->port = port;
-    }
-
-  remote_address.sin_port = htons (port);
-
-  request->logging_function (gftp_logging_misc, request,
-                             _("Looking up %s\n"), connect_host);
-
-  if (!(hostp = r_gethostbyname (connect_host, &host, NULL)))
-    {
-      request->logging_function (gftp_logging_error, request,
-                                 _("Cannot look up hostname %s: %s\n"),
-                                 connect_host, g_strerror (errno));
-      close (sock);
-      return (GFTP_ERETRYABLE);
-    }
-
-  disphost = NULL;
-  for (curhost = 0;
-       host.h_addr_list[curhost] != NULL;
-       curhost++)
-    {
-      disphost = host.h_name;
-      memcpy (&remote_address.sin_addr,
-              host.h_addr_list[curhost],
-              host.h_length);
-      request->logging_function (gftp_logging_misc, request,
-                                 _("Trying %s:%d\n"),
-                                 host.h_name, port);
-
-      if (connect (sock, (struct sockaddr *) &remote_address,
-                   sizeof (remote_address)) == -1)
-        {
-          request->logging_function (gftp_logging_error, request,
-                                     _("Cannot connect to %s: %s\n"),
-                                     connect_host, g_strerror (errno));
-        }
-      break;
-    }
-
-  if (host.h_addr_list[curhost] == NULL)
-    {
-      close (sock);
-      return (GFTP_ERETRYABLE);
-    }
-
-  return (sock);
-}
-
-
-int
-gftp_connect_server (gftp_request * request, char *service,
-                     char *proxy_hostname, unsigned int proxy_port)
-{
-  int sock;
 
+  /* FIXME - pass connect_data to these functions. This is to bypass a
+     second DNS lookup */
 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
-  sock = gftp_connect_server_with_getaddr (request, service, proxy_hostname,
-                                           proxy_port);
+  sock = gftp_connect_server_with_getaddrinfo (request, service, proxy_hostname,
+                                               proxy_port);
 #else
   sock = gftp_connect_server_legacy (request, service, proxy_hostname,
                                      proxy_port);

Modified: trunk/lib/sockutils.c
==============================================================================
--- trunk/lib/sockutils.c	(original)
+++ trunk/lib/sockutils.c	Fri Mar 28 11:44:36 2008
@@ -358,3 +358,30 @@
   return (0);
 }
 
+
+struct servent *
+r_getservbyname (const char *name, const char *proto,
+                 struct servent *result_buf, int *h_errnop)
+{
+  static GStaticMutex servfunclock = G_STATIC_MUTEX_INIT;
+  struct servent *sent;
+
+  if (g_thread_supported ())
+    g_static_mutex_lock (&servfunclock);
+
+  if ((sent = getservbyname (name, proto)) == NULL)
+    {
+      if (h_errnop)
+        *h_errnop = h_errno;
+    }
+  else
+    {
+      *result_buf = *sent;
+      sent = result_buf;
+    }
+
+  if (g_thread_supported ())
+    g_static_mutex_unlock (&servfunclock);
+  return (sent);
+}
+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]