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

📄 domain.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		int c = *host++;		if (isascii(c) && isupper(c))			c = tolower(c);		hfunc = ((hfunc << 1) ^ c) % 2003;	}	hfunc &= 0xff;	if (tTd(17, 9))		printf(" = %d\n", hfunc);	return hfunc;}/***  GETCANONNAME -- get the canonical name for named host****	This algorithm tries to be smart about wildcard MX records.**	This is hard to do because DNS doesn't tell is if we matched**	against a wildcard or a specific MX.**	**	We always prefer A & CNAME records, since these are presumed**	to be specific.****	If we match an MX in one pass and lose it in the next, we use**	the old one.  For example, consider an MX matching *.FOO.BAR.COM.**	A hostname bletch.foo.bar.com will match against this MX, but**	will stop matching when we try bletch.bar.com -- so we know**	that bletch.foo.bar.com must have been right.  This fails if**	there was also an MX record matching *.BAR.COM, but there are**	some things that just can't be fixed.****	Parameters:**		host -- a buffer containing the name of the host.**			This is a value-result parameter.**		hbsize -- the size of the host buffer.**		trymx -- if set, try MX records as well as A and CNAME.****	Returns:**		TRUE -- if the host matched.**		FALSE -- otherwise.*/boolgetcanonname(host, hbsize, trymx)	char *host;	int hbsize;	bool trymx;{	extern int h_errno;	register u_char *eom, *ap;	register char *cp;	register int n; 	HEADER *hp;	querybuf answer;	int ancount, qdcount;	int ret;	char **domain;	int type;	char **dp;	char *mxmatch;	bool amatch;	bool gotmx;	int qtype;	int loopcnt;	char *xp;	char nbuf[MAX(PACKETSZ, MAXDNAME*2+2)];	char *searchlist[MAXDNSRCH+2];	extern char *gethostalias();	if (tTd(8, 2))		printf("getcanonname(%s)\n", host);	if ((_res.options & RES_INIT) == 0 && res_init() == -1)		return (FALSE);	/*	**  Initialize domain search list.  If there is at least one	**  dot in the name, search the unmodified name first so we	**  find "vse.CS" in Czechoslovakia instead of in the local	**  domain (e.g., vse.CS.Berkeley.EDU).	**	**  Older versions of the resolver could create this	**  list by tearing apart the host name.	*/	loopcnt = 0;cnameloop:	for (cp = host, n = 0; *cp; cp++)		if (*cp == '.')			n++;	if (n == 0 && (xp = gethostalias(host)) != NULL)	{		if (loopcnt++ > MAXCNAMEDEPTH)		{			syserr("loop in ${HOSTALIASES} file");		}		else		{			strncpy(host, xp, hbsize);			host[hbsize - 1] = '\0';			goto cnameloop;		}	}	dp = searchlist;	if (n > 0)		*dp++ = "";	if (n >= 0 && *--cp != '.' && bitset(RES_DNSRCH, _res.options))	{		for (domain = _res.dnsrch; *domain != NULL; )			*dp++ = *domain++;	}	else if (n == 0 && bitset(RES_DEFNAMES, _res.options))	{		*dp++ = _res.defdname;	}	else if (*cp == '.')	{		*cp = '\0';	}	*dp = NULL;	/*	**  Now run through the search list for the name in question.	*/	mxmatch = NULL;	qtype = T_ANY;	for (dp = searchlist; *dp != NULL; )	{		if (qtype == T_ANY)			gotmx = FALSE;		if (tTd(8, 5))			printf("getcanonname: trying %s.%s (%s)\n", host, *dp,				qtype == T_ANY ? "ANY" : qtype == T_A ? "A" :				qtype == T_MX ? "MX" : "???");		ret = res_querydomain(host, *dp, C_IN, qtype,				      &answer, sizeof(answer));		if (ret <= 0)		{			if (tTd(8, 7))				printf("\tNO: errno=%d, h_errno=%d\n",					errno, h_errno);			if (errno == ECONNREFUSED || h_errno == TRY_AGAIN)			{				/* the name server seems to be down */				h_errno = TRY_AGAIN;				return FALSE;			}			if (h_errno != HOST_NOT_FOUND)			{				/* might have another type of interest */				if (qtype == T_ANY)				{					qtype = T_A;					continue;				}				else if (qtype == T_A && !gotmx && trymx)				{					qtype = T_MX;					continue;				}			}			if (mxmatch != NULL)			{				/* we matched before -- use that one */				break;			}			/* otherwise, try the next name */			dp++;			qtype = T_ANY;			continue;		}		else if (tTd(8, 7))			printf("\tYES\n");		/*		**  This might be a bogus match.  Search for A or		**  CNAME records.  If we don't have a matching		**  wild card MX record, we will accept MX as well.		*/		hp = (HEADER *) &answer;		ap = (u_char *) &answer + HEADERSZ;		eom = (u_char *) &answer + ret;		/* skip question part of response -- we know what we asked */		for (qdcount = ntohs(hp->qdcount); qdcount--; ap += ret + QFIXEDSZ)		{			if ((ret = dn_skipname(ap, eom)) < 0)			{				if (tTd(8, 20))					printf("qdcount failure (%d)\n",						ntohs(hp->qdcount));				return FALSE;		/* ???XXX??? */			}		}		amatch = FALSE;		for (ancount = ntohs(hp->ancount); --ancount >= 0 && ap < eom; ap += n)		{			n = dn_expand((u_char *) &answer, eom, ap,				      (u_char *) nbuf, sizeof nbuf);			if (n < 0)				break;			ap += n;			GETSHORT(type, ap);			ap += SHORTSIZE + LONGSIZE;			GETSHORT(n, ap);			switch (type)			{			  case T_MX:				gotmx = TRUE;				if (**dp != '\0')				{					/* got a match -- save that info */					if (trymx && mxmatch == NULL)						mxmatch = *dp;					continue;				}				/* exact MX matches are as good as an A match */				/* fall through */			  case T_A:				/* good show */				amatch = TRUE;				/* continue in case a CNAME also exists */				continue;			  case T_CNAME:				if (loopcnt++ > MAXCNAMEDEPTH)				{					/*XXX should notify postmaster XXX*/					message("DNS failure: CNAME loop for %s",						host);					if (CurEnv->e_message == NULL)					{						char ebuf[MAXLINE];						sprintf(ebuf, "Deferred: DNS failure: CNAME loop for %s",							host);						CurEnv->e_message = newstr(ebuf);					}					h_errno = NO_RECOVERY;					return FALSE;				}				/* value points at name */				if ((ret = dn_expand((u_char *)&answer,				    eom, ap, (u_char *)nbuf, sizeof(nbuf))) < 0)					break;				(void)strncpy(host, nbuf, hbsize); /* XXX */				host[hbsize - 1] = '\0';				/*				**  RFC 1034 section 3.6 specifies that CNAME				**  should point at the canonical name -- but				**  urges software to try again anyway.				*/				goto cnameloop;			  default:				/* not a record of interest */				continue;			}		}		if (amatch)		{			/* got an A record and no CNAME */			mxmatch = *dp;			break;		}		/*		**  If this was a T_ANY query, we may have the info but		**  need an explicit query.  Try T_A, then T_MX.		*/		if (qtype == T_ANY)			qtype = T_A;		else if (qtype == T_A && !gotmx && trymx)			qtype = T_MX;		else		{			/* really nothing in this domain; try the next */			qtype = T_ANY;			dp++;		}	}	if (mxmatch == NULL)		return FALSE;	/* create matching name and return */	(void) sprintf(nbuf, "%.*s%s%.*s", MAXDNAME, host,			*mxmatch == '\0' ? "" : ".",			MAXDNAME, mxmatch);	strncpy(host, nbuf, hbsize);	host[hbsize - 1] = '\0';	return TRUE;}char *gethostalias(host)	char *host;{	char *fname;	FILE *fp;	register char *p;	char buf[MAXLINE];	static char hbuf[MAXDNAME];	fname = getenv("HOSTALIASES");	if (fname == NULL || (fp = fopen(fname, "r")) == NULL)		return NULL;	while (fgets(buf, sizeof buf, fp) != NULL)	{		for (p = buf; p != '\0' && !(isascii(*p) && isspace(*p)); p++)			continue;		if (*p == 0)		{			/* syntax error */			continue;		}		*p++ = '\0';		if (strcasecmp(buf, host) == 0)			break;	}	if (feof(fp))	{		/* no match */		fclose(fp);		return NULL;	}	/* got a match; extract the equivalent name */	while (*p != '\0' && isascii(*p) && isspace(*p))		p++;	host = p;	while (*p != '\0' && !(isascii(*p) && isspace(*p)))		p++;	*p = '\0';	strncpy(hbuf, host, sizeof hbuf - 1);	hbuf[sizeof hbuf - 1] = '\0';	return hbuf;}#else /* not NAMED_BIND */#include <netdb.h>boolgetcanonname(host, hbsize, trymx)	char *host;	int hbsize;	bool trymx;{	struct hostent *hp;	hp = gethostbyname(host);	if (hp == NULL)		return (FALSE);	if (strlen(hp->h_name) >= hbsize)		return (FALSE);	(void) strcpy(host, hp->h_name);	return (TRUE);}#endif /* not NAMED_BIND */

⌨️ 快捷键说明

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