]> sjero.net Git - wget/blobdiff - src/connect.c
Fix build when libpsl is not available
[wget] / src / connect.c
index e4ad453b1658806eb37df21c72c8ec4d7306db26..1e4a44bae3d8d98e12b6efaffc195feb7e650ac0 100644 (file)
@@ -1,6 +1,7 @@
 /* Establishing and handling network connections.
    Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+   2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+   Foundation, Inc.
 
 This file is part of GNU Wget.
 
@@ -32,14 +33,18 @@ as that of the covered work.  */
 
 #include <stdio.h>
 #include <stdlib.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
+#include <unistd.h>
 #include <assert.h>
 
+#include <sys/socket.h>
+#include <sys/select.h>
+
 #ifndef WINDOWS
-# include <sys/socket.h>
-# include <netdb.h>
+# ifdef __VMS
+#  include "vms_ip.h"
+# else /* def __VMS */
+#  include <netdb.h>
+# endif /* def __VMS [else] */
 # include <netinet/in.h>
 # ifndef __BEOS__
 #  include <arpa/inet.h>
@@ -48,14 +53,17 @@ as that of the covered work.  */
 
 #include <errno.h>
 #include <string.h>
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif /* HAVE_SYS_SELECT_H */
+#include <sys/time.h>
 #include "utils.h"
 #include "host.h"
 #include "connect.h"
 #include "hash.h"
 
+/* Apparently needed for Interix: */
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#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
@@ -363,8 +394,8 @@ connect_to_host (const char *host, int port)
   if (!al)
     {
       logprintf (LOG_NOTQUIET,
-                 _("%s: unable to resolve host address `%s'\n"),
-                 exec_name, host);
+                 _("%s: unable to resolve host address %s\n"),
+                 exec_name, quote (host));
       return E_HOST;
     }
 
@@ -514,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)
@@ -527,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)
     {
@@ -554,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
@@ -629,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;
@@ -651,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.  */
@@ -662,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
@@ -673,17 +752,6 @@ test_socket_open (int sock)
 \f
 /* 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)
 {