X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=src%2Fconnect.c;h=1e4a44bae3d8d98e12b6efaffc195feb7e650ac0;hp=0188353cfa812ee7393f76c9a13717aca08a06e7;hb=HEAD;hpb=df8b19a28eee02f23178584737080001ce8873d1 diff --git a/src/connect.c b/src/connect.c index 0188353c..1e4a44ba 100644 --- a/src/connect.c +++ b/src/connect.c @@ -1,5 +1,7 @@ /* Establishing and handling network connections. - Copyright (C) 1996-2006 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, + 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software + Foundation, Inc. This file is part of GNU Wget. @@ -16,28 +18,33 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Wget. If not, see . -In addition, as a special exception, the Free Software Foundation -gives permission to link the code of its release of Wget with the -OpenSSL project's "OpenSSL" library (or with modified versions of it -that use the same license as the "OpenSSL" library), and distribute -the linked executables. You must obey the GNU General Public License -in all respects for all of the code used other than "OpenSSL". If you -modify this file, you may extend this exception to your version of the -file, but you are not obligated to do so. If you do not wish to do -so, delete this exception statement from your version. */ +Additional permission under GNU GPL version 3 section 7 -#include +If you modify this program, or any covered work, by linking or +combining it with the OpenSSL project's OpenSSL library (or a +modified version of that library), containing parts covered by the +terms of the OpenSSL or SSLeay licenses, the Free Software Foundation +grants you additional permission to convey the resulting work. +Corresponding Source for a non-source form of such a combination +shall include the source code for the parts of OpenSSL used as well +as that of the covered work. */ + +#include "wget.h" #include #include -#ifdef HAVE_UNISTD_H -# include -#endif +#include #include +#include +#include + #ifndef WINDOWS -# include -# include +# ifdef __VMS +# include "vms_ip.h" +# else /* def __VMS */ +# include +# endif /* def __VMS [else] */ # include # ifndef __BEOS__ # include @@ -46,16 +53,17 @@ so, delete this exception statement from your version. */ #include #include -#ifdef HAVE_SYS_SELECT_H -# include -#endif /* HAVE_SYS_SELECT_H */ - -#include "wget.h" +#include #include "utils.h" #include "host.h" #include "connect.h" #include "hash.h" +/* Apparently needed for Interix: */ +#ifdef HAVE_STDINT_H +# include +#endif + /* Define sockaddr_storage where unavailable (presumably on IPv4-only hosts). */ @@ -192,8 +200,8 @@ resolve_bind_address (struct sockaddr *sa) { /* #### We should be able to print the error message here. */ logprintf (LOG_NOTQUIET, - _("%s: unable to resolve bind address `%s'; disabling bind.\n"), - exec_name, opt.bind_address); + _("%s: unable to resolve bind address %s; disabling bind.\n"), + exec_name, quote (opt.bind_address)); should_bind = false; return false; } @@ -263,11 +271,34 @@ connect_to_ip (const ip_address *ip, int port, const char *print) if (print) { const char *txt_addr = print_address (ip); - if (print && 0 != strcmp (print, txt_addr)) - logprintf (LOG_VERBOSE, _("Connecting to %s|%s|:%d... "), - escnonprint (print), txt_addr, port); + if (0 != strcmp (print, txt_addr)) + { + char *str = NULL, *name; + + if (opt.enable_iri && (name = idn_decode ((char *) print)) != NULL) + { + int len = strlen (print) + strlen (name) + 4; + str = xmalloc (len); + snprintf (str, len, "%s (%s)", name, print); + str[len-1] = '\0'; + xfree (name); + } + + logprintf (LOG_VERBOSE, _("Connecting to %s|%s|:%d... "), + str ? str : escnonprint_uri (print), txt_addr, port); + + if (str) + xfree (str); + } else - logprintf (LOG_VERBOSE, _("Connecting to %s:%d... "), txt_addr, port); + { + if (ip->family == AF_INET) + logprintf (LOG_VERBOSE, _("Connecting to %s:%d... "), txt_addr, port); +#ifdef ENABLE_IPV6 + else if (ip->family == AF_INET6) + logprintf (LOG_VERBOSE, _("Connecting to [%s]:%d... "), txt_addr, port); +#endif + } } /* Store the sockaddr info to SA. */ @@ -284,7 +315,7 @@ connect_to_ip (const ip_address *ip, int port, const char *print) /* In case of error, we will go on anyway... */ int err = setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)); IF_DEBUG - if (err < 0) + if (err < 0) DEBUGP (("Failed setting IPV6_V6ONLY: %s", strerror (errno))); } #endif @@ -361,7 +392,12 @@ connect_to_host (const char *host, int port) retry: if (!al) - return E_HOST; + { + logprintf (LOG_NOTQUIET, + _("%s: unable to resolve host address %s\n"), + exec_name, quote (host)); + return E_HOST; + } address_list_get_bounds (al, &start, &end); for (i = start; i < end; i++) @@ -509,10 +545,11 @@ bool socket_ip_address (int sock, ip_address *ip, int endpoint) { struct sockaddr_storage storage; - struct sockaddr *sockaddr = (struct sockaddr *)&storage; + struct sockaddr *sockaddr = (struct sockaddr *) &storage; socklen_t addrlen = sizeof (storage); int ret; + memset (sockaddr, 0, addrlen); if (endpoint == ENDPOINT_LOCAL) ret = getsockname (sock, sockaddr, &addrlen); else if (endpoint == ENDPOINT_PEER) @@ -522,6 +559,7 @@ socket_ip_address (int sock, ip_address *ip, int endpoint) if (ret < 0) return false; + memset(ip, 0, sizeof(ip_address)); ip->family = sockaddr->sa_family; switch (sockaddr->sa_family) { @@ -549,6 +587,36 @@ socket_ip_address (int sock, ip_address *ip, int endpoint) } } +/* Get the socket family of connection on FD and store + Return family type on success, -1 otherwise. + + If ENDPOINT is ENDPOINT_LOCAL, it returns the sock family of the local + (client) side of the socket. Else if ENDPOINT is ENDPOINT_PEER, it + returns the sock family of the remote (peer's) side of the socket. */ + +int +socket_family (int sock, int endpoint) +{ + struct sockaddr_storage storage; + struct sockaddr *sockaddr = (struct sockaddr *) &storage; + socklen_t addrlen = sizeof (storage); + int ret; + + memset (sockaddr, 0, addrlen); + + if (endpoint == ENDPOINT_LOCAL) + ret = getsockname (sock, sockaddr, &addrlen); + else if (endpoint == ENDPOINT_PEER) + ret = getpeername (sock, sockaddr, &addrlen); + else + abort (); + + if (ret < 0) + return -1; + + return sockaddr->sa_family; +} + /* Return true if the error from the connect code can be considered retryable. Wget normally retries after errors, but the exception are the "unsupported protocol" type errors (possible on IPv4/IPv6 @@ -624,7 +692,14 @@ select_fd (int fd, double maxtime, int wait_for) tmout.tv_usec = 1000000 * (maxtime - (long) maxtime); do + { result = select (fd + 1, rd, wr, NULL, &tmout); +#ifdef WINDOWS + /* gnulib select() converts blocking sockets to nonblocking in windows. + wget uses blocking sockets so we must convert them back to blocking. */ + set_windows_fd_as_blocking_socket (fd); +#endif + } while (result < 0 && errno == EINTR); return result; @@ -646,6 +721,7 @@ test_socket_open (int sock) { fd_set check_set; struct timeval to; + int ret = 0; /* Check if we still have a valid (non-EOF) connection. From Andrew * Maholski's code in the Unix Socket FAQ. */ @@ -657,7 +733,15 @@ test_socket_open (int sock) to.tv_sec = 0; to.tv_usec = 1; - if (select (sock + 1, &check_set, NULL, NULL, &to) == 0) + ret = select (sock + 1, &check_set, NULL, NULL, &to); +#ifdef WINDOWS +/* gnulib select() converts blocking sockets to nonblocking in windows. +wget uses blocking sockets so we must convert them back to blocking +*/ + set_windows_fd_as_blocking_socket ( sock ); +#endif + + if ( !ret ) /* We got a timeout, it means we're still connected. */ return true; else @@ -668,17 +752,6 @@ test_socket_open (int sock) /* Basic socket operations, mostly EINTR wrappers. */ -#if defined(WINDOWS) || defined(MSDOS) -# define read(fd, buf, cnt) recv (fd, buf, cnt, 0) -# define write(fd, buf, cnt) send (fd, buf, cnt, 0) -# define close(fd) closesocket (fd) -#endif - -#ifdef __BEOS__ -# define read(fd, buf, cnt) recv (fd, buf, cnt, 0) -# define write(fd, buf, cnt) send (fd, buf, cnt, 0) -#endif - static int sock_read (int fd, char *buf, int bufsize) {