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

📄 parseaddr.c

📁 < linux网络编程工具>>配套源码
💻 C
📖 第 1 页 / 共 5 页
字号:
				{
					usrerr("653 Unbalanced '\"'");
					c = '"';
				}
				else if (cmntcnt > 0)
				{
					usrerr("653 Unbalanced '('");
					c = ')';
				}
				else if (anglecnt > 0)
				{
					c = '>';
					usrerr("653 Unbalanced '<'");
				}
				else
					break;

				p--;
			}
			else if (c == delim && cmntcnt <= 0 && state != QST)
			{
				if (anglecnt <= 0)
					break;

				/* special case for better error management */
				if (delim == ',' && !route_syntax)
				{
					usrerr("653 Unbalanced '<'");
					c = '>';
					p--;
				}
			}

			if (tTd(22, 101))
				dprintf("c=%c, s=%d; ", c, state);

			/* chew up special characters */
			*q = '\0';
			if (bslashmode)
			{
				bslashmode = FALSE;

				/* kludge \! for naive users */
				if (cmntcnt > 0)
				{
					c = NOCHAR;
					continue;
				}
				else if (c != '!' || state == QST)
				{
					*q++ = '\\';
					continue;
				}
			}

			if (c == '\\')
			{
				bslashmode = TRUE;
			}
			else if (state == QST)
			{
				/* EMPTY */
				/* do nothing, just avoid next clauses */
			}
			else if (c == '(' && toktab['('] == SPC)
			{
				cmntcnt++;
				c = NOCHAR;
			}
			else if (c == ')' && toktab['('] == SPC)
			{
				if (cmntcnt <= 0)
				{
					usrerr("653 Unbalanced ')'");
					c = NOCHAR;
				}
				else
					cmntcnt--;
			}
			else if (cmntcnt > 0)
			{
				c = NOCHAR;
			}
			else if (c == '<')
			{
				char *ptr = p;

				anglecnt++;
				while (isascii(*ptr) && isspace(*ptr))
					ptr++;
				if (*ptr == '@')
					route_syntax = TRUE;
			}
			else if (c == '>')
			{
				if (anglecnt <= 0)
				{
					usrerr("653 Unbalanced '>'");
					c = NOCHAR;
				}
				else
					anglecnt--;
				route_syntax = FALSE;
			}
			else if (delim == ' ' && isascii(c) && isspace(c))
				c = ' ';

			if (c == NOCHAR)
				continue;

			/* see if this is end of input */
			if (c == delim && anglecnt <= 0 && state != QST)
				break;

			newstate = StateTab[state][toktab[c & 0xff]];
			if (tTd(22, 101))
				dprintf("ns=%02o\n", newstate);
			state = newstate & TYPE;
			if (state == ILL)
			{
				if (isascii(c) && isprint(c))
					usrerr("653 Illegal character %c", c);
				else
					usrerr("653 Illegal character 0x%02x", c);
			}
			if (bitset(M, newstate))
				c = NOCHAR;
			if (bitset(B, newstate))
				break;
		}

		/* new token */
		if (tok != q)
		{
			*q++ = '\0';
			if (tTd(22, 36))
			{
				dprintf("tok=");
				xputs(tok);
				dprintf("\n");
			}
			if (avp >= &av[MAXATOM])
			{
				usrerr("553 5.1.0 prescan: too many tokens");
				goto returnnull;
			}
			if (q - tok > MAXNAME)
			{
				usrerr("553 5.1.0 prescan: token too long");
				goto returnnull;
			}
			*avp++ = tok;
		}
	} while (c != '\0' && (c != delim || anglecnt > 0));
	*avp = NULL;
	p--;
	if (delimptr != NULL)
		*delimptr = p;
	if (tTd(22, 12))
	{
		dprintf("prescan==>");
		printav(av);
	}
	CurEnv->e_to = saveto;
	if (av[0] == NULL)
	{
		if (tTd(22, 1))
			dprintf("prescan: null leading token\n");
		return NULL;
	}
	return av;
}
/*
**  REWRITE -- apply rewrite rules to token vector.
**
**	This routine is an ordered production system.  Each rewrite
**	rule has a LHS (called the pattern) and a RHS (called the
**	rewrite); 'rwr' points the the current rewrite rule.
**
**	For each rewrite rule, 'avp' points the address vector we
**	are trying to match against, and 'pvp' points to the pattern.
**	If pvp points to a special match value (MATCHZANY, MATCHANY,
**	MATCHONE, MATCHCLASS, MATCHNCLASS) then the address in avp
**	matched is saved away in the match vector (pointed to by 'mvp').
**
**	When a match between avp & pvp does not match, we try to
**	back out.  If we back up over MATCHONE, MATCHCLASS, or MATCHNCLASS
**	we must also back out the match in mvp.  If we reach a
**	MATCHANY or MATCHZANY we just extend the match and start
**	over again.
**
**	When we finally match, we rewrite the address vector
**	and try over again.
**
**	Parameters:
**		pvp -- pointer to token vector.
**		ruleset -- the ruleset to use for rewriting.
**		reclevel -- recursion level (to catch loops).
**		e -- the current envelope.
**
**	Returns:
**		A status code.  If EX_TEMPFAIL, higher level code should
**			attempt recovery.
**
**	Side Effects:
**		pvp is modified.
*/

struct match
{
	char	**match_first;		/* first token matched */
	char	**match_last;		/* last token matched */
	char	**match_pattern;	/* pointer to pattern */
};

#define MAXMATCH	9	/* max params per rewrite */


int
rewrite(pvp, ruleset, reclevel, e)
	char **pvp;
	int ruleset;
	int reclevel;
	register ENVELOPE *e;
{
	register char *ap;		/* address pointer */
	register char *rp;		/* rewrite pointer */
	register char *rulename;	/* ruleset name */
	register char *prefix;
	register char **avp;		/* address vector pointer */
	register char **rvp;		/* rewrite vector pointer */
	register struct match *mlp;	/* cur ptr into mlist */
	register struct rewrite *rwr;	/* pointer to current rewrite rule */
	int ruleno;			/* current rule number */
	int rstat = EX_OK;		/* return status */
	int loopcount;
	struct match mlist[MAXMATCH];	/* stores match on LHS */
	char *npvp[MAXATOM + 1];	/* temporary space for rebuild */
	char buf[MAXLINE];
	char name[6];

	if (ruleset < 0 || ruleset >= MAXRWSETS)
	{
		syserr("554 5.3.5 rewrite: illegal ruleset number %d", ruleset);
		return EX_CONFIG;
	}
	rulename = RuleSetNames[ruleset];
	if (rulename == NULL)
	{
		snprintf(name, sizeof name, "%d", ruleset);
		rulename = name;
	}
	if (OpMode == MD_TEST)
		prefix = "";
	else
		prefix = "rewrite: ruleset ";
	if (OpMode == MD_TEST)
	{
		printf("%s%-16.16s   input:", prefix, rulename);
		printav(pvp);
	}
	else if (tTd(21, 1))
	{
		dprintf("%s%-16.16s   input:", prefix, rulename);
		printav(pvp);
	}
	if (reclevel++ > MaxRuleRecursion)
	{
		syserr("rewrite: excessive recursion (max %d), ruleset %s",
			MaxRuleRecursion, rulename);
		return EX_CONFIG;
	}
	if (pvp == NULL)
		return EX_USAGE;

	/*
	**  Run through the list of rewrite rules, applying
	**	any that match.
	*/

	ruleno = 1;
	loopcount = 0;
	for (rwr = RewriteRules[ruleset]; rwr != NULL; )
	{
		int status;

		/* if already canonical, quit now */
		if (pvp[0] != NULL && (pvp[0][0] & 0377) == CANONNET)
			break;

		if (tTd(21, 12))
		{
			if (tTd(21, 15))
				dprintf("-----trying rule (line %d):",
				       rwr->r_line);
			else
				dprintf("-----trying rule:");
			printav(rwr->r_lhs);
		}

		/* try to match on this rule */
		mlp = mlist;
		rvp = rwr->r_lhs;
		avp = pvp;
		if (++loopcount > 100)
		{
			syserr("554 5.3.5 Infinite loop in ruleset %s, rule %d",
				rulename, ruleno);
			if (tTd(21, 1))
			{
				dprintf("workspace: ");
				printav(pvp);
			}
			break;
		}

		while ((ap = *avp) != NULL || *rvp != NULL)
		{
			rp = *rvp;
			if (tTd(21, 35))
			{
				dprintf("ADVANCE rp=");
				xputs(rp);
				dprintf(", ap=");
				xputs(ap);
				dprintf("\n");
			}
			if (rp == NULL)
			{
				/* end-of-pattern before end-of-address */
				goto backup;
			}
			if (ap == NULL && (*rp & 0377) != MATCHZANY &&
			    (*rp & 0377) != MATCHZERO)
			{
				/* end-of-input with patterns left */
				goto backup;
			}

			switch (*rp & 0377)
			{
			  case MATCHCLASS:
				/* match any phrase in a class */
				mlp->match_pattern = rvp;
				mlp->match_first = avp;
	extendclass:
				ap = *avp;
				if (ap == NULL)
					goto backup;
				mlp->match_last = avp++;
				cataddr(mlp->match_first, mlp->match_last,
					buf, sizeof buf, '\0');
				if (!wordinclass(buf, rp[1]))
				{
					if (tTd(21, 36))
					{
						dprintf("EXTEND  rp=");
						xputs(rp);
						dprintf(", ap=");
						xputs(ap);
						dprintf("\n");
					}
					goto extendclass;
				}
				if (tTd(21, 36))
					dprintf("CLMATCH\n");
				mlp++;
				break;

			  case MATCHNCLASS:
				/* match any token not in a class */
				if (wordinclass(ap, rp[1]))
					goto backup;

				/* FALLTHROUGH */

			  case MATCHONE:
			  case MATCHANY:
				/* match exactly one token */
				mlp->match_pattern = rvp;
				mlp->match_first = avp;
				mlp->match_last = avp++;
				mlp++;
				break;

			  case MATCHZANY:
				/* match zero or more tokens */
				mlp->match_pattern = rvp;
				mlp->match_first = avp;
				mlp->match_last = avp - 1;
				mlp++;
				break;

			  case MATCHZERO:
				/* match zero tokens */
				break;

			  case MACRODEXPAND:
				/*
				**  Match against run-time macro.
				**  This algorithm is broken for the
				**  general case (no recursive macros,
				**  improper tokenization) but should
				**  work for the usual cases.
				*/

				ap = macvalue(rp[1], e);
				mlp->match_first = avp;
				if (tTd(21, 2))
					dprintf("rewrite: LHS $&%s => \"%s\"\n",
						macname(rp[1]),
						ap == NULL ? "(NULL)" : ap);

				if (ap == NULL)
					break;
				while (*ap != '\0')
				{
					if (*avp == NULL ||
					    strncasecmp(ap, *avp, strlen(*avp)) != 0)
					{
						/* no match */
						avp = mlp->match_first;
						goto backup;
					}
					ap += strlen(*avp++);
				}

				/* match */
				break;

			  default:
				/* must have exact match */
				if (sm_strcasecmp(rp, ap))
					goto backup;
				avp++;
				break;
			}

			/* successful match on this token */
			rvp++;
			continue;

	  backup:
			/* match failed -- back up */
			while (--mlp >= mlist)
			{
				rvp = mlp->match_pattern;
				rp = *rvp;
				avp = mlp->match_last + 1;
				ap = *avp;

				if (tTd(21, 36))
				{
					dprintf("BACKUP  rp=");
					xputs(rp);
					dprintf(", ap=");
					xputs(ap);
					dprintf("\n");
				}

				if (ap == NULL)
				{
					/* run off the end -- back up again */
					continue;
				}
				if ((*rp & 0377) == MATCHANY ||
				    (*rp & 0377) == MATCHZANY)
				{
					/* extend binding and continue */
					mlp->match_last = avp++;
					rvp++;
					mlp++;
					break;
				}
				if ((*rp & 0377) == MATCHCLASS)
				{
					/* extend binding and try again */
					mlp->match_last = avp;
					goto extendclass;
				}
			}

			if (mlp < mlist)
			{
				/* total failure to match */
				break;
			}
		}

		/*
		**  See if we successfully matched
		*/

		if (mlp < mlist || *rvp != NULL)
		{
			if (tTd(21, 10))
				dprintf("----- rule fails\n");
			rwr = rwr->r_next;
			ruleno++;
			loopcount = 0;
			continue;
		}

		rvp = rwr->r_rhs;
		if (tTd(21, 12))
		{
			dprintf("-----rule matches:");
			printav(rvp);
		}

		rp = *rvp;
		if (rp != NULL)
		{
			if ((*rp & 0377) == CANONUSER)
			{
				rvp++;
				rwr = rwr->r_next;
				ruleno++;
				loopcount = 0;
			}
			else if ((*rp & 0377) == CANONHOST)
			{
				rvp++;
				rwr = NULL;
			}
		}

		/* substitute */
		for (avp = npvp; *rvp != NULL; rvp++)
		{
			register struct match *m;
			register char **pp;

			rp = *rvp;
			if ((*rp & 0377) == MATCHREPL)
			{
				/* substitute from LHS */
				m = &mlist[rp[1] - '1'];
				if (m < mlist || m >= mlp)
				{
					syserr("554 5.3.5 rewrite: ruleset %s: replacement $%c out of bounds",
						rulename, rp[1]);
					return EX_CONFIG;
				}
				if (tTd(21, 15))
				{
					dprintf("$%c:", rp[1]);
					pp = m->match_first;
					while (pp <= m->match_last)
					{
						dprintf(" %lx=\"",
							(u_long) *pp);
						(void) dflush();
						dprintf("%s\"", *pp++);

⌨️ 快捷键说明

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