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

📄 parseaddr.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
				setstat(ep->ec_code);			}			tv++;		}		else			setstat(EX_UNAVAILABLE);		if ((**tv & 0377) != CANONUSER)			syserr("554 buildaddr: error: no user");		cataddr(++tv, NULL, buf, sizeof buf, ' ');		stripquotes(buf);		if (isascii(buf[0]) && isdigit(buf[0]) &&		    isascii(buf[1]) && isdigit(buf[1]) &&		    isascii(buf[2]) && isdigit(buf[2]) &&		    buf[3] == ' ')		{			char fmt[10];			strncpy(fmt, buf, 3);			strcpy(&fmt[3], " %s");			usrerr(fmt, buf + 4);		}		else		{			usrerr("553 %s", buf);		}		goto badaddr;	}	for (mp = Mailer; (m = *mp++) != NULL; )	{		if (strcasecmp(m->m_name, *tv) == 0)			break;	}	if (m == NULL)	{		syserr("554 buildaddr: unknown mailer %s", *tv);		goto badaddr;	}	a->q_mailer = m;	/* figure out what host (if any) */	tv++;	if ((**tv & 0377) == CANONHOST)	{		bp = buf;		spaceleft = sizeof buf - 1;		while (*++tv != NULL && (**tv & 0377) != CANONUSER)		{			int i = strlen(*tv);			if (i > spaceleft)			{				/* out of space for this address */				if (spaceleft >= 0)					syserr("554 buildaddr: host too long (%.40s...)",						buf);				i = spaceleft;				spaceleft = 0;			}			if (i <= 0)				continue;			bcopy(*tv, bp, i);			bp += i;			spaceleft -= i;		}		*bp = '\0';		a->q_host = newstr(buf);	}	else	{		if (!bitnset(M_LOCALMAILER, m->m_flags))		{			syserr("554 buildaddr: no host");			goto badaddr;		}		a->q_host = NULL;	}	/* figure out the user */	if (*tv == NULL || (**tv & 0377) != CANONUSER)	{		syserr("554 buildaddr: no user");		goto badaddr;	}	tv++;	/* do special mapping for local mailer */	if (m == LocalMailer && *tv != NULL)	{		register char *p = *tv;		if (*p == '"')			p++;		if (*p == '|')			a->q_mailer = m = ProgMailer;		else if (*p == '/')			a->q_mailer = m = FileMailer;		else if (*p == ':')		{			/* may be :include: */			cataddr(tv, NULL, buf, sizeof buf, '\0');			stripquotes(buf);			if (strncasecmp(buf, ":include:", 9) == 0)			{				/* if :include:, don't need further rewriting */				a->q_mailer = m = InclMailer;				a->q_user = &buf[9];				return (a);			}		}	}	if (m == LocalMailer && *tv != NULL && strcmp(*tv, "@") == 0)	{		tv++;		a->q_flags |= QNOTREMOTE;	}	/* rewrite according recipient mailer rewriting rules */	define('h', a->q_host, e);	if (!bitset(RF_SENDERADDR|RF_HEADERADDR, flags))	{		/* sender addresses done later */		(void) rewrite(tv, 2, 0, e);		if (m->m_re_rwset > 0)		       (void) rewrite(tv, m->m_re_rwset, 0, e);	}	(void) rewrite(tv, 4, 0, e);	/* save the result for the command line/RCPT argument */	cataddr(tv, NULL, buf, sizeof buf, '\0');	a->q_user = buf;	/*	**  Do mapping to lower case as requested by mailer	*/	if (a->q_host != NULL && !bitnset(M_HST_UPPER, m->m_flags))		makelower(a->q_host);	if (!bitnset(M_USR_UPPER, m->m_flags))		makelower(a->q_user);	return (a);}/***  CATADDR -- concatenate pieces of addresses (putting in <LWSP> subs)****	Parameters:**		pvp -- parameter vector to rebuild.**		evp -- last parameter to include.  Can be NULL to**			use entire pvp.**		buf -- buffer to build the string into.**		sz -- size of buf.**		spacesub -- the space separator character; if null,**			use SpaceSub.****	Returns:**		none.****	Side Effects:**		Destroys buf.*/cataddr(pvp, evp, buf, sz, spacesub)	char **pvp;	char **evp;	char *buf;	register int sz;	char spacesub;{	bool oatomtok = FALSE;	bool natomtok = FALSE;	register int i;	register char *p;	if (spacesub == '\0')		spacesub = SpaceSub;	if (pvp == NULL)	{		(void) strcpy(buf, "");		return;	}	p = buf;	sz -= 2;	while (*pvp != NULL && (i = strlen(*pvp)) < sz)	{		natomtok = (toktype(**pvp) == ATM);		if (oatomtok && natomtok)			*p++ = spacesub;		(void) strcpy(p, *pvp);		oatomtok = natomtok;		p += i;		sz -= i + 1;		if (pvp++ == evp)			break;	}	*p = '\0';}/***  SAMEADDR -- Determine if two addresses are the same****	This is not just a straight comparison -- if the mailer doesn't**	care about the host we just ignore it, etc.****	Parameters:**		a, b -- pointers to the internal forms to compare.****	Returns:**		TRUE -- they represent the same mailbox.**		FALSE -- they don't.****	Side Effects:**		none.*/boolsameaddr(a, b)	register ADDRESS *a;	register ADDRESS *b;{	register ADDRESS *ca, *cb;	/* if they don't have the same mailer, forget it */	if (a->q_mailer != b->q_mailer)		return (FALSE);	/* if the user isn't the same, we can drop out */	if (strcmp(a->q_user, b->q_user) != 0)		return (FALSE);	/* if we have good uids for both but they differ, these are different */	if (a->q_mailer == ProgMailer)	{		ca = getctladdr(a);		cb = getctladdr(b);		if (ca != NULL && cb != NULL &&		    bitset(QGOODUID, ca->q_flags & cb->q_flags) &&		    ca->q_uid != cb->q_uid)			return (FALSE);	}	/* otherwise compare hosts (but be careful for NULL ptrs) */	if (a->q_host == b->q_host)	{		/* probably both null pointers */		return (TRUE);	}	if (a->q_host == NULL || b->q_host == NULL)	{		/* only one is a null pointer */		return (FALSE);	}	if (strcmp(a->q_host, b->q_host) != 0)		return (FALSE);	return (TRUE);}/***  PRINTADDR -- print address (for debugging)****	Parameters:**		a -- the address to print**		follow -- follow the q_next chain.****	Returns:**		none.****	Side Effects:**		none.*/printaddr(a, follow)	register ADDRESS *a;	bool follow;{	bool first = TRUE;	register MAILER *m;	MAILER pseudomailer;	while (a != NULL)	{		first = FALSE;		printf("%x=", a);		(void) fflush(stdout);		/* find the mailer -- carefully */		m = a->q_mailer;		if (m == NULL)		{			m = &pseudomailer;			m->m_mno = -1;			m->m_name = "NULL";		}		printf("%s:\n\tmailer %d (%s), host `%s', user `%s', ruser `%s'\n",		       a->q_paddr, m->m_mno, m->m_name,		       a->q_host, a->q_user,		       a->q_ruser ? a->q_ruser : "<null>");		printf("\tnext=%x, flags=%o, alias %x, uid %d, gid %d\n",		       a->q_next, a->q_flags, a->q_alias, a->q_uid, a->q_gid);		printf("\towner=%s, home=\"%s\", fullname=\"%s\"\n",		       a->q_owner == NULL ? "(none)" : a->q_owner,		       a->q_home == NULL ? "(none)" : a->q_home,		       a->q_fullname == NULL ? "(none)" : a->q_fullname);		if (!follow)			return;		a = a->q_next;	}	if (first)		printf("[NULL]\n");}/***  REMOTENAME -- return the name relative to the current mailer****	Parameters:**		name -- the name to translate.**		m -- the mailer that we want to do rewriting relative**			to.**		flags -- fine tune operations.**		pstat -- pointer to status word.**		e -- the current envelope.****	Returns:**		the text string representing this address relative to**			the receiving mailer.****	Side Effects:**		none.****	Warnings:**		The text string returned is tucked away locally;**			copy it if you intend to save it.*/char *remotename(name, m, flags, pstat, e)	char *name;	struct mailer *m;	int flags;	int *pstat;	register ENVELOPE *e;{	register char **pvp;	char *fancy;	char *oldg = macvalue('g', e);	int rwset;	static char buf[MAXNAME];	char lbuf[MAXNAME];	char pvpbuf[PSBUFSIZE];	extern char *crackaddr();	if (tTd(12, 1))		printf("remotename(%s)\n", name);	/* don't do anything if we are tagging it as special */	if (bitset(RF_SENDERADDR, flags))		rwset = bitset(RF_HEADERADDR, flags) ? m->m_sh_rwset						     : m->m_se_rwset;	else		rwset = bitset(RF_HEADERADDR, flags) ? m->m_rh_rwset						     : m->m_re_rwset;	if (rwset < 0)		return (name);	/*	**  Do a heuristic crack of this name to extract any comment info.	**	This will leave the name as a comment and a $g macro.	*/	if (bitset(RF_CANONICAL, flags) || bitnset(M_NOCOMMENT, m->m_flags))		fancy = "\201g";	else		fancy = crackaddr(name);	/*	**  Turn the name into canonical form.	**	Normally this will be RFC 822 style, i.e., "user@domain".	**	If this only resolves to "user", and the "C" flag is	**	specified in the sending mailer, then the sender's	**	domain will be appended.	*/	pvp = prescan(name, '\0', pvpbuf, sizeof pvpbuf, NULL);	if (pvp == NULL)		return (name);	if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL)		*pstat = EX_TEMPFAIL;	if (bitset(RF_ADDDOMAIN, flags) && e->e_fromdomain != NULL)	{		/* append from domain to this address */		register char **pxp = pvp;		/* see if there is an "@domain" in the current name */		while (*pxp != NULL && strcmp(*pxp, "@") != 0)			pxp++;		if (*pxp == NULL)		{			/* no.... append the "@domain" from the sender */			register char **qxq = e->e_fromdomain;			while ((*pxp++ = *qxq++) != NULL)				continue;			if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL)				*pstat = EX_TEMPFAIL;		}	}	/*	**  Do more specific rewriting.	**	Rewrite using ruleset 1 or 2 depending on whether this is	**		a sender address or not.	**	Then run it through any receiving-mailer-specific rulesets.	*/	if (bitset(RF_SENDERADDR, flags))	{		if (rewrite(pvp, 1, 0, e) == EX_TEMPFAIL)			*pstat = EX_TEMPFAIL;	}	else	{		if (rewrite(pvp, 2, 0, e) == EX_TEMPFAIL)			*pstat = EX_TEMPFAIL;	}	if (rwset > 0)	{		if (rewrite(pvp, rwset, 0, e) == EX_TEMPFAIL)			*pstat = EX_TEMPFAIL;	}	/*	**  Do any final sanitation the address may require.	**	This will normally be used to turn internal forms	**	(e.g., user@host.LOCAL) into external form.  This	**	may be used as a default to the above rules.	*/	if (rewrite(pvp, 4, 0, e) == EX_TEMPFAIL)		*pstat = EX_TEMPFAIL;	/*	**  Now restore the comment information we had at the beginning.	*/	cataddr(pvp, NULL, lbuf, sizeof lbuf, '\0');	define('g', lbuf, e);	/* need to make sure route-addrs have <angle brackets> */	if (bitset(RF_CANONICAL, flags) && lbuf[0] == '@')		expand("<\201g>", buf, &buf[sizeof buf - 1], e);	else		expand(fancy, buf, &buf[sizeof buf - 1], e);	define('g', oldg, e);	if (tTd(12, 1))		printf("remotename => `%s'\n", buf);	return (buf);}/***  MAPLOCALUSER -- run local username through ruleset 5 for final redirection****	Parameters:**		a -- the address to map (but just the user name part).**		sendq -- the sendq in which to install any replacement**			addresses.****	Returns:**		none.*/maplocaluser(a, sendq, e)	register ADDRESS *a;	ADDRESS **sendq;	ENVELOPE *e;{	register char **pvp;	register ADDRESS *a1 = NULL;	auto char *delimptr;	char pvpbuf[PSBUFSIZE];	if (tTd(29, 1))	{		printf("maplocaluser: ");		printaddr(a, FALSE);	}	pvp = prescan(a->q_user, '\0', pvpbuf, sizeof pvpbuf, &delimptr);	if (pvp == NULL)		return;	(void) rewrite(pvp, 5, 0, e);	if (pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET)		return;	/* if non-null, mailer destination specified -- has it changed? */	a1 = buildaddr(pvp, NULL, 0, e);	if (a1 == NULL || sameaddr(a, a1))		return;	/* mark old address as dead; insert new address */	a->q_flags |= QDONTSEND;	if (tTd(29, 5))	{		printf("maplocaluser: QDONTSEND ");		printaddr(a, FALSE);	}	a1->q_alias = a;	allocaddr(a1, RF_COPYALL, NULL);	(void) recipient(a1, sendq, e);}/***  DEQUOTE_INIT -- initialize dequote map****	This is a no-op.****	Parameters:**		map -- the internal map structure.**		args -- arguments.****	Returns:**		TRUE.*/booldequote_init(map, args)	MAP *map;	char *args;{	register char *p = args;	for (;;)	{		while (isascii(*p) && isspace(*p))			p++;		if (*p != '-')			break;		switch (*++p)		{		  case 'a':			map->map_app = ++p;			break;		}		while (*p != '\0' && !(isascii(*p) && isspace(*p)))			p++;		if (*p != '\0')			*p = '\0';	}	if (map->map_app != NULL)		map->map_app = newstr(map->map_app);	return TRUE;}/***  DEQUOTE_MAP -- unquote an address****	Parameters:**		map -- the internal map structure (ignored).**		name -- the name to dequote.**		av -- arguments (ignored).**		statp -- pointer to status out-parameter.****	Returns:**		NULL -- if there were no quotes, or if the resulting**			unquoted buffer would not be acceptable to prescan.**		else -- The dequoted buffer.*/char *dequote_map(map, name, av, statp)	MAP *map;	char *name;	char **av;	int *statp;{	register char *p;	register char *q;	register char c;	int anglecnt;	int cmntcnt;	int quotecnt;	int spacecnt;	bool quotemode;	bool bslashmode;	anglecnt = 0;	cmntcnt = 0;	quotecnt = 0;	spacecnt = 0;	quotemode = FALSE;	bslashmode = FALSE;	for (p = q = name; (c = *p++) != '\0'; )	{		if (bslashmode)		{			bslashmode = FALSE;			*q++ = c;			continue;		}		switch (c)		{		  case '\\':			bslashmode = TRUE;			break;		  case '(':			cmntcnt++;			break;		  case ')':			if (cmntcnt-- <= 0)				return NULL;			break;		  case ' ':			spacecnt++;			break;		}		if (cmntcnt > 0)		{			*q++ = c;			continue;		}		switch (c)		{		  case '"':			quotemode = !quotemode;			quotecnt++;			continue;		  case '<':			anglecnt++;			break;		  case '>':			if (anglecnt-- <= 0)				return NULL;			break;		}		*q++ = c;	}	if (anglecnt != 0 || cmntcnt != 0 || bslashmode ||	    quotemode || quotecnt <= 0 || spacecnt != 0)		return NULL;	*q++ = '\0';	return name;}

⌨️ 快捷键说明

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