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

📄 gethostent.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
#if !defined(lint) && defined(SCCSIDS)static  char sccsid[] = "@(#)gethostent.c 1.1 92/07/30 Copyr 1990 Sun Micro";#endif/*  * Copyright (c) 1990 by Sun Microsystems, Inc. */#include <stdio.h>#include <ctype.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <rpcsvc/ypclnt.h>struct hostent *_gethostent();/* * Internet version. */static struct hostdata {	FILE	*hostf;	char	*current;	int	currentlen;	int	stayopen;#define	MAXALIASES	20	char	*host_aliases[MAXALIASES];#define MAXADDRS	10#define	HOSTADDRSIZE	4	/* assumed == sizeof u_long */	char	hostaddr[MAXADDRS][HOSTADDRSIZE];	char	*addr_list[MAXADDRS+1];	char	line[BUFSIZ+1];	struct	hostent host;	char	*domain;	char	*map;	int 	notusingyellow;} *hostdata, *_hostdata();static	struct hostent *interpret();struct	hostent *gethostent();char	*inet_ntoa();char	*strpbrk();static	char *HOSTDB = "/etc/hosts";/* * Internal routine to allocate hostdata on heap, instead of * putting lots of stuff into the data segment. */static struct hostdata *_hostdata(){	register struct hostdata *d = hostdata;	if (d == 0) {		d = (struct hostdata *)calloc(1, sizeof (struct hostdata));		hostdata = d;		(void) yp_get_default_domain(&d->domain);	}	return (d);}/* * NIS use strategy: * gethostbyaddr() and gethostbyname() always try NIS first. * gethostent() tries NIS first, if it fails with an indication * that NIS is not running it sets a flag so that subsequent * calls will not try NIS.  If sethostent() is called  * the next gethostent() will try NIS first. An intervening * gethostbyaddr() or gethostbyname() will also   * clear the flag so that gethostent() will go back to trying NIS */struct hostent *gethostbyaddr(addr, len, type)	char *addr;	register int len, type;{	register struct hostdata *d = _hostdata();	register struct hostent *p;	char *adrstr, *val = NULL;	int vallen;	int stat;	h_errno = NO_RECOVERY;	if (d == 0)		return ((struct hostent*)NULL);	d->map = "hosts.byaddr";	sethostent(0);	if (d->domain ) {		/*try to yp_match it*/		adrstr = inet_ntoa(*(struct in_addr *)addr);		stat = yp_match(d->domain, d->map, adrstr, strlen(adrstr), 					&val, &vallen);		switch (stat) {		    case 0:			p = interpret(val, vallen);			free(val);			h_errno = 0;			return(p);		    case YPERR_KEY: 			h_errno = HOST_NOT_FOUND;				return(NULL);		    case YPERR_NOMORE:			h_errno = TRY_AGAIN;				return(NULL);		}	}	h_errno = HOST_NOT_FOUND;	_sethostent(0);	while (p = _gethostent()) {		if (p->h_addrtype != type || p->h_length != len)			continue;		if (bcmp(p->h_addr_list[0], addr, len) == 0) {				h_errno = 0;			break;		}	}	endhostent();	return (p);}struct hostent *gethostbyname(name)	register char *name;{	register struct hostdata *d = _hostdata();	register struct hostent *p;	register char **cp;	register char *name2;	char *val = NULL;	int vallen,stat;	h_errno = NO_RECOVERY;	if (d == 0)		return ((struct hostent*)NULL);	d->map = "hosts.byname";	sethostent(0);	if (d->domain ) {		  /*		   * try to yp_match it first		   */		name2 = name;		for (val=d->line; *name2; name2++)			*val++ = isupper((unsigned char)*name2) ? tolower(*name2) : *name2;		*val = '\0';		stat = yp_match(d->domain, d->map,			    d->line, val - d->line, &val, &vallen);		switch (stat) {		    case 0:			h_errno = 0;			p = interpret(val, vallen);			free(val);			return(p);		    case YPERR_KEY: 			h_errno = HOST_NOT_FOUND;				return(NULL);		    case YPERR_NOMORE:			h_errno = TRY_AGAIN;				return(NULL);		}		}	/* yp_match said NIS isn't running or domain is null */	h_errno = HOST_NOT_FOUND;	_sethostent(0);	while (p = _gethostent()) {		if (strcasecmp(p->h_name, name) == 0) {			h_errno = 0;			break;		}		for (cp = p->h_aliases; *cp != 0; cp++)			if (strcasecmp(*cp, name) == 0)	{				h_errno = 0;				goto found;			}	}found:	endhostent();	return (p);}sethostent(f)int f;{/*Doesn't open file if not needed*//*f!=0 -> makes it open file     */	register struct hostdata *d = _hostdata();	if (d == 0)		return;	d->notusingyellow = 0; /*try yellow again if off*/	if (f) {		_sethostent(f);		return; 	}	if (d->hostf) 		rewind(d->hostf); /*if its open rewind it*/	if (d->current)		free(d->current);	d->current = NULL;}static _sethostent(f)	int f;{	register struct hostdata *d = _hostdata();	if (d == 0)		return;	if (d->hostf == NULL)		d->hostf = fopen(HOSTDB, "r");	else		rewind(d->hostf);	if (d->current)		free(d->current);	d->current = NULL;	d->stayopen |= f;}endhostent(){	register struct hostdata *d = _hostdata();	if (d == 0)		return;	if (d->current && !d->stayopen) {		free(d->current);		d->current = NULL;	}	if (d->hostf && !d->stayopen) {		(void) fclose(d->hostf);		d->hostf = NULL;	}}struct hostent *gethostent(){	register struct hostdata *d = _hostdata();	struct hostent *hp;	char *key = NULL, *val = NULL;	int keylen, vallen, stat;	if (d == 0)		return ((struct hostent*)NULL);	d->map = "hosts.byaddr";	if (d->domain && !(d->notusingyellow)) {		if (d->current == NULL) {			stat = yp_first(d->domain, d->map, &key, &keylen, 					&val, &vallen);		} else {			stat = yp_next(d->domain, d->map,			    d->current, d->currentlen, &key, &keylen, 			    		&val, &vallen);		}		switch (stat) {		    case YPERR_NOMORE:			return(NULL);		    case YPERR_KEY:		    	return(NULL); /* first might return this*/		    case 0:			if (d->current)			free(d->current);			d->current = key;			d->currentlen = keylen;			hp = interpret(val, vallen);			free(val);			return (hp);		}		/*All other cases mean no NIS!*/		d->notusingyellow = 1;	}	return(_gethostent()); /*The hard way*/}static struct hostent *_gethostent(){	register struct hostdata *d = _hostdata();	if (d->hostf == NULL && (d->hostf = fopen(HOSTDB, "r")) == NULL)		return (NULL);        if (fgets(d->line, BUFSIZ, d->hostf) == NULL)		return (NULL);	return (interpret(d->line, strlen(d->line)));}/* * Take the line read from /etc/hosts or from the NIS map, and parse it * into a hostent structure.  Multiple lines are used to encode multiple * addresses for the same name.  This should only happen when NIS talks to * the Domain Name Service, but it should not hurt to put it here. */static struct hostent *interpret(val, len)char	*val;int	len;{	register struct hostdata *d = _hostdata();	char *p, *z;	register char *cp, **q;	int i;	if (d == 0)		return (0);	(void) strncpy(d->line, val, len);	p = d->line;	d->line[len] = '\n';	d->line[len+1] = '\0';	/*	 * Note that these are recursive calls, and thus should only	 * happen when reading /etc/hosts.	 */	if ((*p == '#') || (*p == '\n')) /* Check for special cases */		return (gethostent());	cp = strpbrk(p, "#\n");	if (cp == NULL)		return (gethostent());	z = cp;	if (*z == '#')		z = strpbrk(cp, "\n");	*cp = '\0';	/* 	 * This is what causes the blank line bug, we find the \n but no	 * whitespace after it and return NULL. fixed by special casing the	 * blank lines above.	 */	cp = strpbrk(p, " \t");	if (cp == NULL)		return (NULL);	*cp++ = '\0';	/* THIS STUFF IS INTERNET SPECIFIC */	d->addr_list[0] = d->hostaddr[0];	d->addr_list[1] = NULL;	d->host.h_addr_list = d->addr_list;	*((u_long *)d->hostaddr[0]) = inet_addr(p);	d->host.h_length = HOSTADDRSIZE;	d->host.h_addrtype = AF_INET;	while (*cp == ' ' || *cp == '\t')		cp++;	d->host.h_name = cp;	q = d->host.h_aliases = d->host_aliases;	cp = strpbrk(cp, " \t");	if (cp != NULL) 		*cp++ = '\0';	while (cp && *cp) {		if (*cp == ' ' || *cp == '\t') {			cp++;			continue;		}		if (q < &(d->host_aliases[MAXALIASES - 1]))			*q++ = cp;		cp = strpbrk(cp, " \t");		if (cp != NULL)			*cp++ = '\0';	}	*q = NULL;		/*	 * Reached end of the line -- see if there are any more lines.	 * At this point, z points to the END of the first line (\n character),	 * i is the index of addr_list[]. (We only look at the addresses)	 */	i = 1;	while (z) {		cp = z+1;		if (*cp == '\0')			break;		while (*cp == '\n' || *cp == ' ' || *cp == '\t')			cp++;		p = cp;		cp = strpbrk(cp, " \t\n");		if (cp == NULL)			break;		z = cp;		if (*cp != '\n')			z = strpbrk(cp, "\n");		*cp = '\0';		/*		 * At this point p points to the start of the address,		 * past any white space, cp points to the end, and		 * z points to the end of the current line.		 */		d->addr_list[i] = d->hostaddr[i];		*((u_long *)d->hostaddr[i]) = inet_addr(p);		i++;		d->addr_list[i] = NULL;	}	return (&d->host);}

⌨️ 快捷键说明

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