# HG changeset patch # User masneyb # Date 1206704676 0 # Node ID a490d94a5b8e383e473dcc061da63ac6ca1a26e3 # Parent 99f8858bbf022c16dc2a9a7a9f71cf5ac4ab3045 2008-03-28 Brian Masney * 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. diff -r 99f8858bbf02 -r a490d94a5b8e ChangeLog --- a/ChangeLog Sat Mar 08 11:36:14 2008 +0000 +++ b/ChangeLog Fri Mar 28 11:44:36 2008 +0000 @@ -1,3 +1,10 @@ +2008-03-28 Brian Masney + * 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. + 2008-03-04 Brian Masney * lib/gftp.h lib/socket-connect.c lib/sockutils.c lib/protocols.c lib/Makefile.am lib/charset-conv.c lib/parse-dir-listing.c - split diff -r 99f8858bbf02 -r a490d94a5b8e lib/Makefile.am --- a/lib/Makefile.am Sat Mar 08 11:36:14 2008 +0000 +++ b/lib/Makefile.am Fri Mar 28 11:44:36 2008 +0000 @@ -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 diff -r 99f8858bbf02 -r a490d94a5b8e lib/gftp.h --- a/lib/gftp.h Sat Mar 08 11:36:14 2008 +0000 +++ b/lib/gftp.h Fri Mar 28 11:44:36 2008 +0000 @@ -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 ); + diff -r 99f8858bbf02 -r a490d94a5b8e lib/misc.c --- a/lib/misc.c Sat Mar 08 11:36:14 2008 +0000 +++ b/lib/misc.c Fri Mar 28 11:44:36 2008 +0000 @@ -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) { diff -r 99f8858bbf02 -r a490d94a5b8e lib/socket-connect-getaddrinfo.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/socket-connect-getaddrinfo.c Fri Mar 28 11:44:36 2008 +0000 @@ -0,0 +1,158 @@ +/*****************************************************************************/ +/* socket-connect-getaddrinfo.c - uses getaddrinfo for connections */ +/* Copyright (C) 1998-2008 Brian Masney */ +/* */ +/* 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 diff -r 99f8858bbf02 -r a490d94a5b8e lib/socket-connect-gethostbyname.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/socket-connect-gethostbyname.c Fri Mar 28 11:44:36 2008 +0000 @@ -0,0 +1,165 @@ +/*****************************************************************************/ +/* socket-connect.c - contains functions for connecting to a server */ +/* Copyright (C) 1998-2008 Brian Masney */ +/* */ +/* 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 diff -r 99f8858bbf02 -r a490d94a5b8e lib/socket-connect.c --- a/lib/socket-connect.c Sat Mar 08 11:36:14 2008 +0000 +++ b/lib/socket-connect.c Fri Mar 28 11:44:36 2008 +0000 @@ -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) -{ - struct sockaddr_in remote_address; - char *connect_host, *disphost; - struct hostent host, *hostp; - struct servent serv_struct; - int ret, sock, curhost; - unsigned int port; - - if ((ret = gftp_need_proxy (request, service, proxy_hostname, - proxy_port)) < 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; + void *connect_data; + int sock, ret; + if ((ret = gftp_need_proxy (request, service, proxy_hostname, + proxy_port, &connect_data)) < 0) + return (ret); + request->use_proxy = ret; + + /* 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); diff -r 99f8858bbf02 -r a490d94a5b8e lib/sockutils.c --- a/lib/sockutils.c Sat Mar 08 11:36:14 2008 +0000 +++ b/lib/sockutils.c Fri Mar 28 11:44:36 2008 +0000 @@ -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); +} +