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

📄 savecopy.c

📁 这个源码是UNIX网络编程卷1一书中的事例源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include	"unp.h"#include	<ctype.h>		/* isxdigit(), etc. */#include	<arpa/nameser.h>#include	<resolv.h>		/* res_init, _res */		/* following internal flag cannot overlap with other AI_xxx flags */#define	AI_CLONE	     4	/* clone this entry for other socket types */struct search {  const char	*host;	/* hostname of address string */  int			family;	/* AF_xxx */};		/* function prototypes for our own internal functions */static int	ga_echeck(const char *, const char *, const struct addrinfo *);static int	ga_nsearch(const char *, const struct addrinfo *,					   struct search *);static int	ga_aistruct(struct addrinfo ***, const struct addrinfo *,						void *, int);static int	ga_serv(struct addrinfo *, const struct addrinfo *, const char *);static int	ga_port(struct addrinfo *, int , int);static int	ga_unix(const char *, struct addrinfo *, struct addrinfo **);static struct addrinfo	*ga_clone(struct addrinfo *);		/* globals for all functions in this file; these *must* be		   read-only if this function is to be reentrant */static struct addrinfo	hints_default;intgetaddrinfo(const char *hostname, const char *servname,			const struct addrinfo *hintsp, struct addrinfo **result){	int					rc, error, nsearch;	char				**ap;	struct hostent		*hptr;	struct search		search[3], *sptr;	struct addrinfo		hints, *ai, *aihead, **aipnext;	/*	 * If we encounter an error we want to free() any dynamic memory	 * that we've allocated.  This is our hack to simplify the code.	 */#define	error(e) { error = (e); goto bad; }	if (hintsp == NULL) {		hints = hints_default;	/* struct copy */		hints.ai_family = AF_UNSPEC;	} else		hints = *hintsp;		/* struct copy */		/* 4first some basic error checking */	if ( (rc = ga_echeck(hostname, servname, &hints)) != 0)		error(rc);#ifdef	UNIXDOMAIN	/*	 * Special case Unix domain first;	 * remainder of function for IPv4/IPv6.	 */	if (hostname != NULL && hostname[0] == '/' &&	    (servname == NULL || servname[0] == '\0'))		return(ga_unix(hostname, &hints, result));	if (servname != NULL && servname[0] == '/' &&	    (hostname == NULL || hostname[0] == '\0'))		return(ga_unix(servname, &hints, result));#endif	nsearch = ga_nsearch(hostname, &hints, &search[0]);	aihead = NULL;	aipnext = &aihead;	for (sptr = &search[0]; sptr < &search[nsearch]; sptr++) {#ifdef	IPV4			/* 4check for an IPv4 dotted-decimal string */		if (isdigit(sptr->host[0])) {			struct in_addr	inaddr;			if (inet_pton(AF_INET, sptr->host, &inaddr) == 1) {				rc = ga_aistruct(&aipnext, &hints, &inaddr, AF_INET);				if (rc != 0)					error(rc);				continue;			}		}#endif	#ifdef	IPV6			/* 4check for an IPv6 hex string */		if (isxdigit(sptr->host[0]) || sptr->host[0] == ':') {			struct in6_addr	in6addr;			if (inet_pton(AF_INET6, sptr->host, &in6addr) == 1) {				rc = ga_aistruct(&aipnext, &hints, &in6addr, AF_INET6);				if (rc != 0)					error(rc);				continue;			}		}#endif			/* 4look up hostname */		if ((_res.options & RES_INIT) == 0)			res_init();			/* need this to set _res.options */		if (nsearch == 2)			hptr = gethostbyname2(sptr->host, sptr->family);		else {#ifdef	IPV6			if (sptr->family == AF_INET6)				_res.options |= RES_USE_INET6;			else				_res.options &= ~RES_USE_INET6;#endif			hptr = gethostbyname(sptr->host);		}		if (hptr == NULL) {			switch (h_errno) {				case HOST_NOT_FOUND:	error(EAI_NONAME);				case TRY_AGAIN:			error(EAI_AGAIN);				case NO_RECOVERY:		error(EAI_FAIL);				case NO_DATA:			error(EAI_NODATA);				default:				error(EAI_NONAME);			}		}				/* 4check for address family mismatch if one specified */		if (hints.ai_family != AF_UNSPEC && hints.ai_family != hptr->h_addrtype)			error(EAI_ADDRFAMILY);				/* 4create one addrinfo{} for each returned address */		for (ap = hptr->h_addr_list; *ap != NULL; ap++) {			if ( (ai = calloc(1, sizeof(struct addrinfo))) == NULL)				error(EAI_MEMORY);			*aipnext = ai;			aipnext = &ai->ai_next;			rc = ga_aistruct(&aipnext, &hints, *ap, hptr->h_addrtype);			if (rc != 0)				error(rc);		}	}	/* "aihead" points to the first structure in the linked list */	if (hostname != NULL && hostname[0] != '\0' &&		hints.ai_flags & AI_CANONNAME) {		aihead->ai_canonname = strdup(hptr->h_name != NULL ?									  hptr->h_name : search[0].host);		if (aihead->ai_canonname == NULL)			error(EAI_MEMORY);	}		/* 4now process the service name */	if (servname != NULL && servname[0] != '\0') {		if ( (rc = ga_serv(aihead, &hints, servname)) != 0)			error(rc);	}	*result = aihead;	/* pointer to first structure in linked list */	return(0);bad:	freeaddrinfo(aihead);	/* free any alloc'ed memory */	return(error);}/* * Basic error checking at the beginning. */static intga_echeck(const char *hostname, const char *servname,		  const struct addrinfo *hintsp){	if (hintsp->ai_flags & ~(AI_PASSIVE | AI_CANONNAME))		return(EAI_BADFLAGS);	/* unknown flag bits */	if (hostname == NULL || hostname[0] == '\0') {		if (servname == NULL || servname[0] == '\0')			return(EAI_NONAME);	/* host or service must be specified */	}	switch(hintsp->ai_family) {		case AF_UNSPEC:			break;#ifdef	IPV4		case AF_INET:			if (hintsp->ai_socktype != 0 &&				(hintsp->ai_socktype != SOCK_STREAM &&				 hintsp->ai_socktype != SOCK_DGRAM &&				 hintsp->ai_socktype != SOCK_RAW))				return(EAI_SOCKTYPE);	/* invalid socket type */			break;#endif#ifdef	IPV6		case AF_INET6:			if (hintsp->ai_socktype != 0 &&				(hintsp->ai_socktype != SOCK_STREAM &&				 hintsp->ai_socktype != SOCK_DGRAM &&				 hintsp->ai_socktype != SOCK_RAW))				return(EAI_SOCKTYPE);	/* invalid socket type */			break;#endif#ifdef	UNIXDOMAIN		case AF_LOCAL:			if (hintsp->ai_socktype != 0 &&				(hintsp->ai_socktype != SOCK_STREAM &&				 hintsp->ai_socktype != SOCK_DGRAM))				return(EAI_SOCKTYPE);	/* invalid socket type */			break;#endif		default:			return(EAI_FAMILY);		/* unknown protocol family */	}	return(0);}/* * Set up the search[] array with the hostnames and address families * that we are to look up. */static intga_nsearch(const char *hostname, const struct addrinfo *hintsp,		   struct search *search){	int		nsearch = 0;	if (hostname == NULL || hostname[0] == '\0') {		if (hintsp->ai_flags & AI_PASSIVE) {				/* 4no hostname and AI_PASSIVE: implies wildcard bind */			switch (hintsp->ai_family) {#ifdef	IPV4			case AF_INET:				search[nsearch].host = "0.0.0.0";				search[nsearch].family = AF_INET;				nsearch++;				break;#endif#ifdef	IPV6			case AF_INET6:				search[nsearch].host = "0::0";				search[nsearch].family = AF_INET6;				nsearch++;				break;#endif			case AF_UNSPEC:#ifdef	IPV6				search[nsearch].host = "0::0";	/* IPv6 first, then IPv4 */				search[nsearch].family = AF_INET6;				nsearch++;#endif#ifdef	IPV4				search[nsearch].host = "0.0.0.0";				search[nsearch].family = AF_INET;				nsearch++;#endif				break;			}		} else {				/* 4no host and not AI_PASSIVE: connect to local host */			switch (hintsp->ai_family) {#ifdef	IPV4			case AF_INET:				search[nsearch].host = "localhost";	/* 127.0.0.1 */				search[nsearch].family = AF_INET;				nsearch++;				break;#endif#ifdef	IPV6			case AF_INET6:				search[nsearch].host = "0::1";				search[nsearch].family = AF_INET6;				nsearch++;				break;#endif			case AF_UNSPEC:#ifdef	IPV6				search[nsearch].host = "0::1";	/* IPv6 first, then IPv4 */				search[nsearch].family = AF_INET6;				nsearch++;#endif#ifdef	IPV4				search[nsearch].host = "localhost";				search[nsearch].family = AF_INET;				nsearch++;#endif				break;			}		}	} else {	/* host is specified */		switch (hintsp->ai_family) {#ifdef	IPV4		case AF_INET:

⌨️ 快捷键说明

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