]> sjero.net Git - wget/blobdiff - src/host.c
[svn] Change u_int32_t to uint32_t.
[wget] / src / host.c
index 5f41ace699a382b36036691e3aad978aac300d6a..5297d0f34347bc5b926d3d35192bf958f48e60c9 100644 (file)
@@ -15,7 +15,17 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with Wget; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+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.  */
 
 #include <config.h>
 
@@ -71,7 +81,7 @@ extern int h_errno;
 # endif
 #endif
 
-#ifdef INET6
+#ifdef ENABLE_IPV6
 int     ip_default_family = AF_INET6;
 #else
 int     ip_default_family = AF_INET;
@@ -143,7 +153,7 @@ address_list_set_faulty (struct address_list *al, int index)
     al->faulty = 0;
 }
 
-#ifdef INET6
+#ifdef HAVE_GETADDRINFO
 /**
   * address_list_from_addrinfo
   *
@@ -192,10 +202,10 @@ address_list_from_addrinfo (struct addrinfo *ai)
   return al;
 }
 #else
-/* Create an address_list out of a NULL-terminated list of addresses,
-   as returned by gethostbyname.  */
+/* Create an address_list out of a NULL-terminated vector of
+   addresses, as returned by gethostbyname.  */
 static struct address_list *
-address_list_new (char **h_addr_list)
+address_list_from_vector (char **h_addr_list)
 {
   int count = 0, i;
 
@@ -216,10 +226,11 @@ address_list_new (char **h_addr_list)
 }
 #endif
 
-/* Like address_list_new, but initialized with only one address. */
+/* Like address_list_from_vector, but initialized with a single
+   address. */
 
 static struct address_list *
-address_list_new_one (ip_address *addr)
+address_list_from_single (ip_address *addr)
 {
   struct address_list *al = xmalloc (sizeof (struct address_list));
   al->count     = 1;
@@ -286,7 +297,7 @@ wget_sockaddr_set_address (wget_sockaddr *sa,
        }
       return;
     }
-#ifdef INET6
+#ifdef ENABLE_IPV6
   if (ip_family == AF_INET6) 
     {
       sa->sin6.sin6_family = ip_family;
@@ -326,7 +337,7 @@ wget_sockaddr_set_port (wget_sockaddr *sa, unsigned short port)
       sa->sin.sin_port = htons (port);
       return;
     }  
-#ifdef INET6
+#ifdef ENABLE_IPV6
   if (sa->sa.sa_family == AF_INET6)
     {
       sa->sin6.sin6_port = htons (port);
@@ -356,7 +367,7 @@ wget_sockaddr_get_addr (wget_sockaddr *sa)
 { 
   if (sa->sa.sa_family == AF_INET)
     return &sa->sin.sin_addr;
-#ifdef INET6
+#ifdef ENABLE_IPV6
   if (sa->sa.sa_family == AF_INET6)
     return &sa->sin6.sin6_addr;
 #endif
@@ -385,7 +396,7 @@ wget_sockaddr_get_port (const wget_sockaddr *sa)
 {
   if (sa->sa.sa_family == AF_INET)
       return htons (sa->sin.sin_port);
-#ifdef INET6
+#ifdef ENABLE_IPV6
   if (sa->sa.sa_family == AF_INET6)
       return htons (sa->sin6.sin6_port);
 #endif
@@ -408,14 +419,14 @@ wget_sockaddr_get_port (const wget_sockaddr *sa)
   * -          Public IP-Family Information
   *
   * Output:
-  * int                structure length for socket options
+  * socklen_t  structure length for socket options
   */
-int 
+socklen_t
 sockaddr_len () 
 {
   if (ip_default_family == AF_INET) 
     return sizeof (struct sockaddr_in);
-#ifdef INET6
+#ifdef ENABLE_IPV6
   if (ip_default_family == AF_INET6) 
     return sizeof (struct sockaddr_in6);
 #endif
@@ -430,7 +441,7 @@ sockaddr_len ()
 void 
 map_ipv4_to_ip (ip4_address *ipv4, ip_address *ip) 
 {
-#ifdef INET6
+#ifdef ENABLE_IPV6
   static unsigned char ipv64[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff};
   memcpy ((char *)ip + 12, ipv4 , 4);
   memcpy ((char *)ip + 0, ipv64, 12);
@@ -448,7 +459,7 @@ map_ipv4_to_ip (ip4_address *ipv4, ip_address *ip)
 int 
 map_ip_to_ipv4 (ip_address *ip, ip4_address *ipv4) 
 {
-#ifdef INET6
+#ifdef ENABLE_IPV6
   static unsigned char ipv64[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff};
   if (0 != memcmp (ip, ipv64, 12))
     return 0;
@@ -463,7 +474,7 @@ map_ip_to_ipv4 (ip_address *ip, ip4_address *ipv4)
 \f
 /* Versions of gethostbyname and getaddrinfo that support timeout. */
 
-#ifndef INET6
+#ifndef ENABLE_IPV6
 
 struct ghbnwt_context {
   const char *host_name;
@@ -483,7 +494,7 @@ gethostbyname_with_timeout_callback (void *arg)
    other than timeout, errno is reset.  */
 
 static struct hostent *
-gethostbyname_with_timeout (const char *host_name, int timeout)
+gethostbyname_with_timeout (const char *host_name, double timeout)
 {
   struct ghbnwt_context ctx;
   ctx.host_name = host_name;
@@ -498,7 +509,7 @@ gethostbyname_with_timeout (const char *host_name, int timeout)
   return ctx.hptr;
 }
 
-#else  /* INET6 */
+#else  /* ENABLE_IPV6 */
 
 struct gaiwt_context {
   const char *node;
@@ -522,7 +533,7 @@ getaddrinfo_with_timeout_callback (void *arg)
 static int
 getaddrinfo_with_timeout (const char *node, const char *service,
                          const struct addrinfo *hints, struct addrinfo **res,
-                         int timeout)
+                         double timeout)
 {
   struct gaiwt_context ctx;
   ctx.node = node;
@@ -538,7 +549,7 @@ getaddrinfo_with_timeout (const char *node, const char *service,
   return ctx.exit_code;
 }
 
-#endif /* INET6 */
+#endif /* ENABLE_IPV6 */
 \f
 /* Pretty-print ADDR.  When compiled without IPv6, this is the same as
    inet_ntoa.  With IPv6, it either prints an IPv6 address or an IPv4
@@ -547,7 +558,7 @@ getaddrinfo_with_timeout (const char *node, const char *service,
 char *
 pretty_print_address (ip_address *addr)
 {
-#ifdef INET6
+#ifdef ENABLE_IPV6
   ip4_address addr4;
   static char buf[128];
 
@@ -574,7 +585,7 @@ cache_host_lookup (const char *host, struct address_list *al)
   ++al->refcount;
   hash_table_put (host_name_addresses_map, xstrdup_lower (host), al);
 
-#ifdef DEBUG
+#ifdef ENABLE_DEBUG
   if (opt.debug)
     {
       int i;
@@ -590,37 +601,29 @@ struct address_list *
 lookup_host (const char *host, int silent)
 {
   struct address_list *al = NULL;
-  unsigned long addr_ipv4;     /* #### use a 32-bit type here. */
+  uint32_t addr_ipv4;
   ip_address addr;
 
   /* First, try to check whether the address is already a numeric
      address.  */
 
-#ifdef INET6
+#ifdef ENABLE_IPV6
   if (inet_pton (AF_INET6, host, &addr) > 0)
-    return address_list_new_one (&addr);
+    return address_list_from_single (&addr);
 #endif
 
-  addr_ipv4 = (unsigned long)inet_addr (host);
-  if ((int)addr_ipv4 != -1)
+  addr_ipv4 = (uint32_t)inet_addr (host);
+  if (addr_ipv4 != (uint32_t)-1)
     {
       /* ADDR is defined to be in network byte order, which is what
-        this returns, so we can just copy it to STORE_IP.  However,
-        on big endian 64-bit architectures the value will be stored
-        in the *last*, not first four bytes.  OFFSET makes sure that
-        we copy the correct four bytes.  */
-      int offset = 0;
-#ifdef WORDS_BIGENDIAN
-      offset = sizeof (unsigned long) - sizeof (ip4_address);
-#endif
-      map_ipv4_to_ip ((ip4_address *)((char *)&addr_ipv4 + offset), &addr);
-      return address_list_new_one (&addr);
+        this returns, so we can just copy it to STORE_IP.  */
+      map_ipv4_to_ip ((ip4_address *)&addr_ipv4, &addr);
+      return address_list_from_single (&addr);
     }
 
   if (host_name_addresses_map)
     {
       al = hash_table_get (host_name_addresses_map, host);
-
       if (al)
        {
          DEBUGP (("Found %s in host_name_addresses_map (%p)\n", host, al));
@@ -634,7 +637,7 @@ lookup_host (const char *host, int silent)
 
   /* Host name lookup goes on below. */
 
-#ifdef INET6
+#ifdef HAVE_GETADDRINFO
   {
     struct addrinfo hints, *ai;
     int err;
@@ -645,7 +648,7 @@ lookup_host (const char *host, int silent)
     else
       hints.ai_family   = PF_UNSPEC;
     hints.ai_socktype = SOCK_STREAM;
-    err = getaddrinfo_with_timeout (host, NULL, &hints, &ai, opt.timeout);
+    err = getaddrinfo_with_timeout (host, NULL, &hints, &ai, opt.dns_timeout);
 
     if (err != 0 || ai == NULL)
       {
@@ -659,7 +662,8 @@ lookup_host (const char *host, int silent)
   }
 #else
   {
-    struct hostent *hptr = gethostbyname_with_timeout (host, opt.timeout);
+    struct hostent *hptr;
+    hptr = gethostbyname_with_timeout (host, opt.dns_timeout);
     if (!hptr)
       {
        if (!silent)
@@ -672,16 +676,32 @@ lookup_host (const char *host, int silent)
        return NULL;
       }
     /* Do all systems have h_addr_list, or is it a newer thing?  If
-       the latter, use address_list_new_one.  */
-    al = address_list_new (hptr->h_addr_list);
+       the latter, use address_list_from_single.  */
+    al = address_list_from_vector (hptr->h_addr_list);
   }
 #endif
 
+  /* Print the addresses determined by DNS lookup, but no more than
+     three.  */
   if (!silent)
-    logprintf (LOG_VERBOSE, _("done.\n"));
+    {
+      int i;
+      int printmax = al->count <= 3 ? al->count : 3;
+      for (i = 0; i < printmax; i++)
+       {
+         logprintf (LOG_VERBOSE, "%s",
+                    pretty_print_address (al->addresses + i));
+         if (i < printmax - 1)
+           logputs (LOG_VERBOSE, ", ");
+       }
+      if (printmax != al->count)
+       logputs (LOG_VERBOSE, ", ...");
+      logputs (LOG_VERBOSE, "\n");
+    }
 
   /* Cache the lookup information. */
-  cache_host_lookup (host, al);
+  if (opt.dns_cache)
+    cache_host_lookup (host, al);
 
   return al;
 }