X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=src%2Fhost.c;h=11de5944352d91d6b805b8bc00ad832ee8097ca3;hp=fccc0d6dc19f704a7fa3cd337cfe2bbb7e2cf326;hb=4d7c5e087b2bc82c9f503dff003916d1047903ce;hpb=976cc5bfca3c360921bdb4cce38a225ce5a1bd46 diff --git a/src/host.c b/src/host.c index fccc0d6d..11de5944 100644 --- a/src/host.c +++ b/src/host.c @@ -1,11 +1,11 @@ /* Host name resolution and matching. - Copyright (C) 1995, 1996, 1997, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1996-2006 Free Software Foundation, Inc. This file is part of GNU Wget. GNU Wget 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 +the Free Software Foundation; either version 3 of the License, or (at your option) any later version. GNU Wget is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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 Wget; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +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 @@ -29,10 +28,6 @@ so, delete this exception statement from your version. */ #include -#ifndef WINDOWS -#include -#endif - #include #include #include @@ -57,7 +52,6 @@ so, delete this exception statement from your version. */ #include "host.h" #include "url.h" #include "hash.h" -#include "connect.h" /* for socket_has_inet6 */ #ifndef NO_ADDRESS # define NO_ADDRESS NO_DATA @@ -71,7 +65,7 @@ struct address_list { ip_address *addresses; /* pointer to the string of addresses */ int faulty; /* number of addresses known not to work. */ - int connected; /* whether we were able to connect to + bool connected; /* whether we were able to connect to one of the addresses in the list, at least once. */ @@ -97,39 +91,36 @@ address_list_address_at (const struct address_list *al, int pos) return al->addresses + pos; } -/* Return non-zero if AL contains IP, zero otherwise. */ +/* Return true if AL contains IP, false otherwise. */ -int +bool address_list_contains (const struct address_list *al, const ip_address *ip) { int i; - switch (ip->type) + switch (ip->family) { - case IPV4_ADDRESS: + case AF_INET: for (i = 0; i < al->count; i++) { ip_address *cur = al->addresses + i; - if (cur->type == IPV4_ADDRESS - && (ADDRESS_IPV4_IN_ADDR (cur).s_addr - == - ADDRESS_IPV4_IN_ADDR (ip).s_addr)) - return 1; + if (cur->family == AF_INET + && (cur->data.d4.s_addr == ip->data.d4.s_addr)) + return true; } - return 0; + return false; #ifdef ENABLE_IPV6 - case IPV6_ADDRESS: + case AF_INET6: for (i = 0; i < al->count; i++) { ip_address *cur = al->addresses + i; - if (cur->type == IPV6_ADDRESS + if (cur->family == AF_INET6 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID - && ADDRESS_IPV6_SCOPE (cur) == ADDRESS_IPV6_SCOPE (ip) + && cur->ipv6_scope == ip->ipv6_scope #endif - && IN6_ARE_ADDR_EQUAL (&ADDRESS_IPV6_IN6_ADDR (cur), - &ADDRESS_IPV6_IN6_ADDR (ip))) - return 1; + && IN6_ARE_ADDR_EQUAL (&cur->data.d6, &ip->data.d6)) + return true; } - return 0; + return false; #endif /* ENABLE_IPV6 */ default: abort (); @@ -162,12 +153,12 @@ address_list_set_faulty (struct address_list *al, int index) void address_list_set_connected (struct address_list *al) { - al->connected = 1; + al->connected = true; } /* Return the value of the "connected" flag. */ -int +bool address_list_connected_p (const struct address_list *al) { return al->connected; @@ -204,10 +195,10 @@ address_list_from_addrinfo (const struct addrinfo *ai) { const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)ptr->ai_addr; - ip->type = IPV6_ADDRESS; - ADDRESS_IPV6_IN6_ADDR (ip) = sin6->sin6_addr; + ip->family = AF_INET6; + ip->data.d6 = sin6->sin6_addr; #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID - ADDRESS_IPV6_SCOPE (ip) = sin6->sin6_scope_id; + ip->ipv6_scope = sin6->sin6_scope_id; #endif ++ip; } @@ -215,17 +206,17 @@ address_list_from_addrinfo (const struct addrinfo *ai) { const struct sockaddr_in *sin = (const struct sockaddr_in *)ptr->ai_addr; - ip->type = IPV4_ADDRESS; - ADDRESS_IPV4_IN_ADDR (ip) = sin->sin_addr; + ip->family = AF_INET; + ip->data.d4 = sin->sin_addr; ++ip; } assert (ip - al->addresses == cnt); return al; } -#define IS_IPV4(addr) (((const ip_address *) addr)->type == IPV4_ADDRESS) +#define IS_IPV4(addr) (((const ip_address *) addr)->family == AF_INET) -/* Compare two IP addresses by type, giving preference to the IPv4 +/* Compare two IP addresses by family, giving preference to the IPv4 address (sorting it first). In other words, return -1 if ADDR1 is IPv4 and ADDR2 is IPv6, +1 if ADDR1 is IPv6 and ADDR2 is IPv4, and 0 otherwise. @@ -239,7 +230,7 @@ cmp_prefer_ipv4 (const void *addr1, const void *addr2) return !IS_IPV4 (addr1) - !IS_IPV4 (addr2); } -#define IS_IPV6(addr) (((const ip_address *) addr)->type == IPV6_ADDRESS) +#define IS_IPV6(addr) (((const ip_address *) addr)->family == AF_INET6) /* Like the above, but give preference to the IPv6 address. */ @@ -272,8 +263,8 @@ address_list_from_ipv4_addresses (char **vec) for (i = 0; i < count; i++) { ip_address *ip = &al->addresses[i]; - ip->type = IPV4_ADDRESS; - memcpy (ADDRESS_IPV4_DATA (ip), vec[i], 4); + ip->family = AF_INET; + memcpy (IP_INADDR_DATA (ip), vec[i], 4); } return al; @@ -404,46 +395,30 @@ getaddrinfo_with_timeout (const char *node, const char *service, #endif /* ENABLE_IPV6 */ -/* 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 - address. */ +/* Return a textual representation of ADDR, i.e. the dotted quad for + IPv4 addresses, and the colon-separated list of hex words (with all + zeros omitted, etc.) for IPv6 addresses. */ const char * -pretty_print_address (const ip_address *addr) +print_address (const ip_address *addr) { - switch (addr->type) - { - case IPV4_ADDRESS: - return inet_ntoa (ADDRESS_IPV4_IN_ADDR (addr)); #ifdef ENABLE_IPV6 - case IPV6_ADDRESS: - { - static char buf[128]; - inet_ntop (AF_INET6, &ADDRESS_IPV6_IN6_ADDR (addr), buf, sizeof (buf)); -#if 0 -#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID - { - /* append "%SCOPE_ID" for all ?non-global? addresses */ - char *p = buf + strlen (buf); - *p++ = '%'; - number_to_string (p, ADDRESS_IPV6_SCOPE (addr)); - } -#endif + static char buf[64]; + if (!inet_ntop (addr->family, IP_INADDR_DATA (addr), buf, sizeof buf)) + snprintf (buf, sizeof buf, "", strerror (errno)); + return buf; +#else + return inet_ntoa (addr->data.d4); #endif - buf[sizeof (buf) - 1] = '\0'; - return buf; - } -#endif - } - abort (); } -/* The following two functions were adapted from glibc. */ +/* The following two functions were adapted from glibc's + implementation of inet_pton, written by Paul Vixie. */ -static int +static bool is_valid_ipv4_address (const char *str, const char *end) { - int saw_digit = 0; + bool saw_digit = false; int octets = 0; int val = 0; @@ -456,31 +431,31 @@ is_valid_ipv4_address (const char *str, const char *end) val = val * 10 + (ch - '0'); if (val > 255) - return 0; - if (saw_digit == 0) + return false; + if (!saw_digit) { if (++octets > 4) - return 0; - saw_digit = 1; + return false; + saw_digit = true; } } - else if (ch == '.' && saw_digit == 1) + else if (ch == '.' && saw_digit) { if (octets == 4) - return 0; + return false; val = 0; - saw_digit = 0; + saw_digit = false; } else - return 0; + return false; } if (octets < 4) - return 0; + return false; - return 1; + return true; } -int +bool is_valid_ipv6_address (const char *str, const char *end) { /* Use lower-case for these to avoid clash with system headers. */ @@ -493,25 +468,25 @@ is_valid_ipv6_address (const char *str, const char *end) const char *curtok; int tp; const char *colonp; - int saw_xdigit; + bool saw_xdigit; unsigned int val; tp = 0; colonp = NULL; if (str == end) - return 0; + return false; /* Leading :: requires some special handling. */ if (*str == ':') { ++str; if (str == end || *str != ':') - return 0; + return false; } curtok = str; - saw_xdigit = 0; + saw_xdigit = false; val = 0; while (str < end) @@ -524,8 +499,8 @@ is_valid_ipv6_address (const char *str, const char *end) val <<= 4; val |= XDIGIT_TO_NUM (ch); if (val > 0xffff) - return 0; - saw_xdigit = 1; + return false; + saw_xdigit = true; continue; } @@ -533,19 +508,19 @@ is_valid_ipv6_address (const char *str, const char *end) if (ch == ':') { curtok = str; - if (saw_xdigit == 0) + if (!saw_xdigit) { if (colonp != NULL) - return 0; + return false; colonp = str + tp; continue; } else if (str == end) - return 0; + return false; if (tp > ns_in6addrsz - ns_int16sz) - return 0; + return false; tp += ns_int16sz; - saw_xdigit = 0; + saw_xdigit = false; val = 0; continue; } @@ -555,31 +530,31 @@ is_valid_ipv6_address (const char *str, const char *end) && is_valid_ipv4_address (curtok, end) == 1) { tp += ns_inaddrsz; - saw_xdigit = 0; + saw_xdigit = false; break; } - return 0; + return false; } - if (saw_xdigit == 1) + if (saw_xdigit) { if (tp > ns_in6addrsz - ns_int16sz) - return 0; + return false; tp += ns_int16sz; } if (colonp != NULL) { if (tp == ns_in6addrsz) - return 0; + return false; tp = ns_in6addrsz; } if (tp != ns_in6addrsz) - return 0; + return false; - return 1; + return true; } /* Simple host cache, used by lookup_host to speed up resolving. The @@ -627,7 +602,7 @@ cache_store (const char *host, struct address_list *al) int i; debug_logprintf ("Caching %s =>", host); for (i = 0; i < al->count; i++) - debug_logprintf (" %s", pretty_print_address (al->addresses + i)); + debug_logprintf (" %s", print_address (al->addresses + i)); debug_logprintf ("\n"); } } @@ -675,9 +650,9 @@ struct address_list * lookup_host (const char *host, int flags) { struct address_list *al; - int silent = flags & LH_SILENT; - int use_cache; - int numeric_address = 0; + bool silent = !!(flags & LH_SILENT); + bool use_cache; + bool numeric_address = false; double timeout = opt.dns_timeout; #ifndef ENABLE_IPV6 @@ -706,7 +681,7 @@ lookup_host (const char *host, int flags) { const char *end = host + strlen (host); if (is_valid_ipv4_address (host, end) || is_valid_ipv6_address (host, end)) - numeric_address = 1; + numeric_address = true; } #endif @@ -715,7 +690,7 @@ lookup_host (const char *host, int flags) use_cache = opt.dns_cache; #ifdef ENABLE_IPV6 if ((flags & LH_BIND) || numeric_address) - use_cache = 0; + use_cache = false; #endif /* Try to find the host in the cache so we don't need to talk to the @@ -823,8 +798,7 @@ lookup_host (const char *host, int flags) int printmax = al->count <= 3 ? al->count : 3; for (i = 0; i < printmax; i++) { - logprintf (LOG_VERBOSE, "%s", - pretty_print_address (al->addresses + i)); + logputs (LOG_VERBOSE, print_address (al->addresses + i)); if (i < printmax - 1) logputs (LOG_VERBOSE, ", "); } @@ -842,21 +816,21 @@ lookup_host (const char *host, int flags) /* Determine whether a URL is acceptable to be followed, according to a list of domains to accept. */ -int +bool accept_domain (struct url *u) { assert (u->host != NULL); if (opt.domains) { if (!sufmatch ((const char **)opt.domains, u->host)) - return 0; + return false; } if (opt.exclude_domains) { if (sufmatch ((const char **)opt.exclude_domains, u->host)) - return 0; + return false; } - return 1; + return true; } /* Check whether WHAT is matched in LIST, each element of LIST being a @@ -864,7 +838,7 @@ accept_domain (struct url *u) match_backwards() in utils.c). If an element of LIST matched, 1 is returned, 0 otherwise. */ -int +bool sufmatch (const char **list, const char *what) { int i, j, k, lw; @@ -877,23 +851,9 @@ sufmatch (const char **list, const char *what) break; /* The domain must be first to reach to beginning. */ if (j == -1) - return 1; + return true; } - return 0; -} - -static int -host_cleanup_mapper (void *key, void *value, void *arg_ignored) -{ - struct address_list *al; - - xfree (key); /* host */ - - al = (struct address_list *)value; - assert (al->refcount == 1); - address_list_delete (al); - - return 0; + return false; } void @@ -901,7 +861,17 @@ host_cleanup (void) { if (host_name_addresses_map) { - hash_table_map (host_name_addresses_map, host_cleanup_mapper, NULL); + hash_table_iterator iter; + for (hash_table_iterate (host_name_addresses_map, &iter); + hash_table_iter_next (&iter); + ) + { + char *host = iter.key; + struct address_list *al = iter.value; + xfree (host); + assert (al->refcount == 1); + address_list_delete (al); + } hash_table_destroy (host_name_addresses_map); host_name_addresses_map = NULL; }