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

📄 domain.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1986 Eric P. Allman * Copyright (c) 1988, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include "sendmail.h"#ifndef lint#if NAMED_BINDstatic char sccsid[] = "@(#)domain.c	8.19 (Berkeley) 3/11/94 (with name server)";#elsestatic char sccsid[] = "@(#)domain.c	8.19 (Berkeley) 3/11/94 (without name server)";#endif#endif /* not lint */#if NAMED_BIND#include <errno.h>#include <arpa/nameser.h>#include <resolv.h>#include <netdb.h>typedef union{	HEADER	qb1;	char	qb2[PACKETSZ];} querybuf;static char	MXHostBuf[MAXMXHOSTS*PACKETSZ];#ifndef MAXDNSRCH#define MAXDNSRCH	6	/* number of possible domains to search */#endif#ifndef MAX#define MAX(a, b)	((a) > (b) ? (a) : (b))#endif#ifndef NO_DATA# define NO_DATA	NO_ADDRESS#endif#ifndef HEADERSZ# define HEADERSZ	sizeof(HEADER)#endif/* don't use sizeof because sizeof(long) is different on 64-bit machines */#define SHORTSIZE	2	/* size of a short (really, must be 2) */#define LONGSIZE	4	/* size of a long (really, must be 4) */#define MAXCNAMEDEPTH	10	/* maximum depth of CNAME recursion *//***  GETMXRR -- get MX resource records for a domain****	Parameters:**		host -- the name of the host to MX.**		mxhosts -- a pointer to a return buffer of MX records.**		droplocalhost -- If TRUE, all MX records less preferred**			than the local host (as determined by $=w) will**			be discarded.**		rcode -- a pointer to an EX_ status code.****	Returns:**		The number of MX records found.**		-1 if there is an internal failure.**		If no MX records are found, mxhosts[0] is set to host**			and 1 is returned.*/getmxrr(host, mxhosts, droplocalhost, rcode)	char *host;	char **mxhosts;	bool droplocalhost;	int *rcode;{	extern int h_errno;	register u_char *eom, *cp;	register int i, j, n;	int nmx = 0;	register char *bp;	HEADER *hp;	querybuf answer;	int ancount, qdcount, buflen;	bool seenlocal = FALSE;	u_short pref, localpref, type;	char *fallbackMX = FallBackMX;	static bool firsttime = TRUE;	STAB *st;	bool trycanon = FALSE;	u_short prefer[MAXMXHOSTS];	int weight[MAXMXHOSTS];	extern bool getcanonname();	if (tTd(8, 2))		printf("getmxrr(%s, droplocalhost=%d)\n", host, droplocalhost);	if (fallbackMX != NULL)	{		if (firsttime && res_query(FallBackMX, C_IN, T_A,					   (char *) &answer, sizeof answer) < 0)		{			/* this entry is bogus */			fallbackMX = FallBackMX = NULL;		}		else if (droplocalhost &&			 (st = stab(fallbackMX, ST_CLASS, ST_FIND)) != NULL &&			 bitnset('w', st->s_class))		{			/* don't use fallback for this pass */			fallbackMX = NULL;		}		firsttime = FALSE;	}	/* efficiency hack -- numeric or non-MX lookups */	if (host[0] == '[')		goto punt;	errno = 0;	n = res_search(host, C_IN, T_MX, (char *)&answer, sizeof(answer));	if (n < 0)	{		if (tTd(8, 1))			printf("getmxrr: res_search(%s) failed (errno=%d, h_errno=%d)\n",			    (host == NULL) ? "<NULL>" : host, errno, h_errno);		switch (h_errno)		{		  case NO_DATA:			trycanon = TRUE;			/* fall through */		  case NO_RECOVERY:			/* no MX data on this host */			goto punt;		  case HOST_NOT_FOUND:#ifdef BROKEN_RES_SEARCH			/* Ultrix resolver returns failure w/ h_errno=0 */		  case 0:#endif			/* the host just doesn't exist */			*rcode = EX_NOHOST;			if (!UseNameServer)			{				/* might exist in /etc/hosts */				goto punt;			}			break;		  case TRY_AGAIN:			/* couldn't connect to the name server */			if (!UseNameServer && errno == ECONNREFUSED)				goto punt;			/* it might come up later; better queue it up */			*rcode = EX_TEMPFAIL;			break;		  default:			syserr("getmxrr: res_search (%s) failed with impossible h_errno (%d)\n",				host, h_errno);			*rcode = EX_OSERR;			break;		}		/* irreconcilable differences */		return (-1);	}	/* find first satisfactory answer */	hp = (HEADER *)&answer;	cp = (u_char *)&answer + HEADERSZ;	eom = (u_char *)&answer + n;	for (qdcount = ntohs(hp->qdcount); qdcount--; cp += n + QFIXEDSZ)		if ((n = dn_skipname(cp, eom)) < 0)			goto punt;	buflen = sizeof(MXHostBuf) - 1;	bp = MXHostBuf;	ancount = ntohs(hp->ancount);	while (--ancount >= 0 && cp < eom && nmx < MAXMXHOSTS - 1)	{		if ((n = dn_expand((u_char *)&answer,		    eom, cp, (u_char *)bp, buflen)) < 0)			break;		cp += n;		GETSHORT(type, cp); 		cp += SHORTSIZE + LONGSIZE;		GETSHORT(n, cp);		if (type != T_MX)		{			if (tTd(8, 8) || _res.options & RES_DEBUG)				printf("unexpected answer type %d, size %d\n",				    type, n);			cp += n;			continue;		}		GETSHORT(pref, cp);		if ((n = dn_expand((u_char *)&answer, eom, cp,				   (u_char *)bp, buflen)) < 0)			break;		cp += n;		if (droplocalhost &&		    (st = stab(bp, ST_CLASS, ST_FIND)) != NULL &&		    bitnset('w', st->s_class))		{			if (tTd(8, 3))				printf("found localhost (%s) in MX list, pref=%d\n",					bp, pref);			if (!seenlocal || pref < localpref)				localpref = pref;			seenlocal = TRUE;			continue;		}		weight[nmx] = mxrand(bp);		prefer[nmx] = pref;		mxhosts[nmx++] = bp;		n = strlen(bp);		bp += n;		if (bp[-1] != '.')		{			*bp++ = '.';			n++;		}		*bp++ = '\0';		buflen -= n + 1;	}	/* sort the records */	for (i = 0; i < nmx; i++)	{		for (j = i + 1; j < nmx; j++)		{			if (prefer[i] > prefer[j] ||			    (prefer[i] == prefer[j] && weight[i] > weight[j]))			{				register int temp;				register char *temp1;				temp = prefer[i];				prefer[i] = prefer[j];				prefer[j] = temp;				temp1 = mxhosts[i];				mxhosts[i] = mxhosts[j];				mxhosts[j] = temp1;				temp = weight[i];				weight[i] = weight[j];				weight[j] = temp;			}		}		if (seenlocal && prefer[i] >= localpref)		{			/* truncate higher preference part of list */			nmx = i;		}	}	if (nmx == 0)	{punt:		if (seenlocal &&		    (!TryNullMXList || gethostbyname(host) == NULL))		{			/*			**  If we have deleted all MX entries, this is			**  an error -- we should NEVER send to a host that			**  has an MX, and this should have been caught			**  earlier in the config file.			**			**  Some sites prefer to go ahead and try the			**  A record anyway; that case is handled by			**  setting TryNullMXList.  I believe this is a			**  bad idea, but it's up to you....			*/			*rcode = EX_CONFIG;			syserr("MX list for %s points back to %s",				host, MyHostName);			return -1;		}		strcpy(MXHostBuf, host);		mxhosts[0] = MXHostBuf;		if (host[0] == '[')		{			register char *p;			/* this may be an MX suppression-style address */			p = strchr(MXHostBuf, ']');			if (p != NULL)			{				*p = '\0';				if (inet_addr(&MXHostBuf[1]) != -1)					*p = ']';				else				{					trycanon = TRUE;					mxhosts[0]++;				}			}		}		if (trycanon &&		    getcanonname(mxhosts[0], sizeof MXHostBuf - 2, FALSE))		{			bp = &MXHostBuf[strlen(MXHostBuf)];			if (bp[-1] != '.')			{				*bp++ = '.';				*bp = '\0';			}		}		nmx = 1;	}	/* if we have a default lowest preference, include that */	if (fallbackMX != NULL && !seenlocal)		mxhosts[nmx++] = fallbackMX;	return (nmx);}/***  MXRAND -- create a randomizer for equal MX preferences****	If two MX hosts have equal preferences we want to randomize**	the selection.  But in order for signatures to be the same,**	we need to randomize the same way each time.  This function**	computes a pseudo-random hash function from the host name.****	Parameters:**		host -- the name of the host.****	Returns:**		A random but repeatable value based on the host name.****	Side Effects:**		none.*/mxrand(host)	register char *host;{	int hfunc;	static unsigned int seed;	if (seed == 0)	{		seed = (int) curtime() & 0xffff;		if (seed == 0)			seed++;	}	if (tTd(17, 9))		printf("mxrand(%s)", host);	hfunc = seed;	while (*host != '\0')	{

⌨️ 快捷键说明

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