⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 host.c

📁 wget (command line browser) source code
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Host name resolution and matching.   Copyright (C) 1995, 1996, 1997, 2000, 2001 Free Software Foundation, Inc.This file is part of GNU Wget.GNU Wget is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.GNU Wget is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with Wget; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.In addition, as a special exception, the Free Software Foundationgives permission to link the code of its release of Wget with theOpenSSL project's "OpenSSL" library (or with modified versions of itthat use the same license as the "OpenSSL" library), and distributethe linked executables.  You must obey the GNU General Public Licensein all respects for all of the code used other than "OpenSSL".  If youmodify this file, you may extend this exception to your version of thefile, but you are not obligated to do so.  If you do not wish to doso, delete this exception statement from your version.  */#include <config.h>#ifndef WINDOWS#include <netdb.h>#endif#include <stdio.h>#include <stdlib.h>#ifdef HAVE_STRING_H# include <string.h>#else# include <strings.h>#endif#include <assert.h>#include <sys/types.h>#ifdef WINDOWS# include <winsock.h># define SET_H_ERRNO(err) WSASetLastError(err)#else# include <sys/socket.h># include <netinet/in.h># ifndef __BEOS__#  include <arpa/inet.h># endif# include <netdb.h># define SET_H_ERRNO(err) ((void)(h_errno = (err)))#endif /* WINDOWS */#ifndef NO_ADDRESS#define NO_ADDRESS NO_DATA#endif#ifdef HAVE_SYS_UTSNAME_H# include <sys/utsname.h>#endif#include <errno.h>#include "wget.h"#include "utils.h"#include "host.h"#include "url.h"#include "hash.h"#ifndef errnoextern int errno;#endif#ifndef h_errno# ifndef __CYGWIN__extern int h_errno;# endif#endif#ifdef ENABLE_IPV6int     ip_default_family = AF_INET6;#elseint     ip_default_family = AF_INET;#endif/* Mapping between known hosts and to lists of their addresses. */static struct hash_table *host_name_addresses_map;/* Lists of addresses.  This should eventually be extended to handle   IPv6.  */struct address_list {  int count;			/* number of adrresses */  ip_address *addresses;	/* pointer to the string of addresses */  int faulty;			/* number of addresses known not to work. */  int refcount;			/* so we know whether to free it or not. */};/* Get the bounds of the address list.  */voidaddress_list_get_bounds (struct address_list *al, int *start, int *end){  *start = al->faulty;  *end   = al->count;}/* Copy address number INDEX to IP_STORE.  */voidaddress_list_copy_one (struct address_list *al, int index, ip_address *ip_store){  assert (index >= al->faulty && index < al->count);  memcpy (ip_store, al->addresses + index, sizeof (ip_address));}/* Check whether two address lists have all their IPs in common.  */intaddress_list_match_all (struct address_list *al1, struct address_list *al2){  if (al1 == al2)    return 1;  if (al1->count != al2->count)    return 0;  return 0 == memcmp (al1->addresses, al2->addresses,		      al1->count * sizeof (ip_address));}/* Mark the INDEXth element of AL as faulty, so that the next time   this address list is used, the faulty element will be skipped.  */voidaddress_list_set_faulty (struct address_list *al, int index){  /* We assume that the address list is traversed in order, so that a     "faulty" attempt is always preceded with all-faulty addresses,     and this is how Wget uses it.  */  assert (index == al->faulty);  ++al->faulty;  if (al->faulty >= al->count)    /* All addresses have been proven faulty.  Since there's not much       sense in returning the user an empty address list the next       time, we'll rather make them all clean, so that they can be       retried anew.  */    al->faulty = 0;}#ifdef HAVE_GETADDRINFO/**  * address_list_from_addrinfo  *  * This function transform an addrinfo links list in and address_list.  *  * Input:  * addrinfo*		Linkt list of addrinfo  *  * Output:  * address_list*	New allocated address_list  */static struct address_list *address_list_from_addrinfo (struct addrinfo *ai){  struct address_list *al;  struct addrinfo *ai_head = ai;  int cnt = 0;  int i;  for (ai = ai_head; ai; ai = ai->ai_next)    if (ai->ai_family == AF_INET || ai->ai_family == AF_INET6)      ++cnt;  if (cnt == 0)    return NULL;  al = xmalloc (sizeof (struct address_list));  al->addresses = xmalloc (cnt * sizeof (ip_address));  al->count     = cnt;  al->faulty    = 0;  al->refcount  = 1;  for (i = 0, ai = ai_head; ai; ai = ai->ai_next)    if (ai->ai_family == AF_INET6)       {	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ai->ai_addr;	memcpy (al->addresses + i, &sin6->sin6_addr, 16);	++i;      }     else if (ai->ai_family == AF_INET)      {	struct sockaddr_in *sin = (struct sockaddr_in *)ai->ai_addr;        map_ipv4_to_ip ((ip4_address *)&sin->sin_addr, al->addresses + i);	++i;      }  assert (i == cnt);  return al;}#else/* Create an address_list out of a NULL-terminated vector of   addresses, as returned by gethostbyname.  */static struct address_list *address_list_from_vector (char **h_addr_list){  int count = 0, i;  struct address_list *al = xmalloc (sizeof (struct address_list));  while (h_addr_list[count])    ++count;  assert (count > 0);  al->count     = count;  al->faulty    = 0;  al->addresses = xmalloc (count * sizeof (ip_address));  al->refcount  = 1;  for (i = 0; i < count; i++)    map_ipv4_to_ip ((ip4_address *)h_addr_list[i], al->addresses + i);  return al;}#endif/* Like address_list_from_vector, but initialized with a single   address. */static struct address_list *address_list_from_single (ip_address *addr){  struct address_list *al = xmalloc (sizeof (struct address_list));  al->count     = 1;  al->faulty    = 0;  al->addresses = xmalloc (sizeof (ip_address));  al->refcount  = 1;  memcpy (al->addresses, addr, sizeof (ip_address));  return al;}static voidaddress_list_delete (struct address_list *al){  xfree (al->addresses);  xfree (al);}voidaddress_list_release (struct address_list *al){  --al->refcount;  DEBUGP (("Releasing %p (new refcount %d).\n", al, al->refcount));  if (al->refcount <= 0)    {      DEBUGP (("Deleting unused %p.\n", al));      address_list_delete (al);    }}/**  * wget_sockaddr_set_address  *  * This function takes an wget_sockaddr and fill in the protocol type,  * the port number and the address, there NULL in address means wildcard.  * Unsuported adress family will abort the whole programm.  *  * Input:  * wget_sockaddr*	The space to be filled  * int			The wished protocol  * unsigned short	The port  * const ip_address	The Binary IP adress  *  * Return:  * -			Only modify 1. param  */voidwget_sockaddr_set_address (wget_sockaddr *sa, 			   int ip_family, unsigned short port, ip_address *addr){  if (ip_family == AF_INET)     {      sa->sin.sin_family = ip_family;      sa->sin.sin_port = htons (port);      if (addr == NULL) 	memset (&sa->sin.sin_addr, 0,      sizeof(ip4_address));      else	{	  ip4_address addr4;	  if (!map_ip_to_ipv4 (addr, &addr4))	    /* should the callers have prevented this? */	    abort ();	  memcpy (&sa->sin.sin_addr, &addr4, sizeof(ip4_address));	}      return;    }#ifdef ENABLE_IPV6  if (ip_family == AF_INET6)     {      sa->sin6.sin6_family = ip_family;      sa->sin6.sin6_port = htons (port);      if (addr == NULL) 	memset (&sa->sin6.sin6_addr, 0   , 16);      else	     	memcpy (&sa->sin6.sin6_addr, addr, 16);      return;    }#endif    abort();}/**  * wget_sockaddr_set_port  *  * This funtion only fill the port of the socket information.  * If the protocol is not supported nothing is done.  * Unsuported adress family will abort the whole programm.  *   * Require:  * that the IP-Protocol already is set.  *  * Input:  * wget_sockaddr*	The space there port should be entered  * unsigned int	The port that should be entered in host order  *  * Return:  * -			Only modify 1. param  */void wget_sockaddr_set_port (wget_sockaddr *sa, unsigned short port){  if (sa->sa.sa_family == AF_INET)    {      sa->sin.sin_port = htons (port);      return;    }  #ifdef ENABLE_IPV6  if (sa->sa.sa_family == AF_INET6)    {      sa->sin6.sin6_port = htons (port);      return;    }#endif  abort();}/**  * wget_sockaddr_get_addr  *  * This function return the adress from an sockaddr as byte string.  * Unsuported adress family will abort the whole programm.  *   * Require:  * that the IP-Protocol already is set.  *  * Input:  * wget_sockaddr*	Socket Information  *  * Output:  * unsigned char *	IP address as byte string.  */void *wget_sockaddr_get_addr (wget_sockaddr *sa){   if (sa->sa.sa_family == AF_INET)    return &sa->sin.sin_addr;#ifdef ENABLE_IPV6  if (sa->sa.sa_family == AF_INET6)    return &sa->sin6.sin6_addr;#endif  abort();  /* unreached */  return NULL;}/**  * wget_sockaddr_get_port  *  * This function only return the port from the input structure  * Unsuported adress family will abort the whole programm.  *   * Require:  * that the IP-Protocol already is set.  *  * Input:  * wget_sockaddr*	Information where to get the port  *  * Output:  * unsigned short	Port Number in host order.  */unsigned short wget_sockaddr_get_port (const wget_sockaddr *sa){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -