readcf.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 983 行 · 第 1/2 页

C
983
字号
#ifndef lintstatic	char	*sccsid = "@(#)readcf.c	4.1	(ULTRIX)	7/2/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1987 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************/# include "sendmail.h"/***  READCF -- read control file.****	This routine reads the control file and builds the internal**	form.****	The file is formatted as a sequence of lines, each taken**	atomically.  The first character of each line describes how**	the line is to be interpreted.  The lines are:**		Dxval		Define macro x to have value val.**		Cxword		Put word into class x.**		Fxfile [fmt]	Read file for lines to put into**				class x.  Use scanf string 'fmt'**				or "%s" if not present.  Fmt should**				only produce one string-valued result.**		Hname: value	Define header with field-name 'name'**				and value as specified; this will be**				macro expanded immediately before**				use.**		Sn		Use rewriting set n.**		Rlhs rhs	Rewrite addresses that match lhs to**				be rhs.**		Mn arg=val...	Define mailer.  n is the internal name.**				Args specify mailer parameters.**		Oxvalue		Set option x to value.**		Pname=value	Set precedence name to value.****	Parameters:**		cfname -- control file name.****	Returns:**		none.****	Side Effects:**		Builds several internal tables.*/readcf(cfname)	char *cfname;{	FILE *cf;	int ruleset = 0;	char *q;	char **pv;	struct rewrite *rwp = NULL;	char buf[MAXLINE];	register char *p;	extern char **prescan();	extern char **copyplist();	char exbuf[MAXLINE];	char pvpbuf[PSBUFSIZE];	extern char *fgetfolded();	extern char *munchstring();	cf = fopen(cfname, "r");	if (cf == NULL)	{		syserr("cannot open %s", cfname);		exit(EX_OSFILE);	}	FileName = cfname;	LineNumber = 0;	while (fgetfolded(buf, sizeof buf, cf) != NULL)	{		/* map $ into \001 (ASCII SOH) for macro expansion */		for (p = buf; *p != '\0'; p++)		{			if (*p != '$')				continue;			if (p[1] == '$')			{				/* actual dollar sign.... */				(void) strcpy(p, p + 1);				continue;			}			/* convert to macro expansion character */			*p = '\001';		}		/* interpret this line */		switch (buf[0])		{		  case '\0':		  case '#':		/* comment */			break;		  case 'R':		/* rewriting rule */			for (p = &buf[1]; *p != '\0' && *p != '\t'; p++)				continue;			if (*p == '\0')			{				syserr("invalid rewrite line \"%s\"", buf);				break;			}			/* allocate space for the rule header */			if (rwp == NULL)			{				RewriteRules[ruleset] = rwp =					(struct rewrite *) xalloc(sizeof *rwp);			}			else			{				rwp->r_next = (struct rewrite *) xalloc(sizeof *rwp);				rwp = rwp->r_next;			}			rwp->r_next = NULL;			/* expand and save the LHS */			*p = '\0';			expand(&buf[1], exbuf, &exbuf[sizeof exbuf], CurEnv);			rwp->r_lhs = prescan(exbuf, '\t', pvpbuf);			if (rwp->r_lhs != NULL)				rwp->r_lhs = copyplist(rwp->r_lhs, TRUE);			/* expand and save the RHS */			while (*++p == '\t')				continue;			q = p;			while (*p != '\0' && *p != '\t')				p++;			*p = '\0';			expand(q, exbuf, &exbuf[sizeof exbuf], CurEnv);			rwp->r_rhs = prescan(exbuf, '\t', pvpbuf);			if (rwp->r_rhs != NULL)				rwp->r_rhs = copyplist(rwp->r_rhs, TRUE);			break;		  case 'S':		/* select rewriting set */			ruleset = atoi(&buf[1]);			if (ruleset >= MAXRWSETS || ruleset < 0)			{				syserr("bad ruleset %d (%d max)", ruleset, MAXRWSETS);				ruleset = 0;			}			rwp = NULL;			break;		  case 'D':		/* macro definition */			define(buf[1], newstr(munchstring(&buf[2])), CurEnv);			break;		  case 'H':		/* required header line */			(void) chompheader(&buf[1], TRUE);			break;		  case 'C':		/* word class */		  case 'F':		/* word class from file */			/* read list of words from argument or file */			if (buf[0] == 'F')			{				/* read from file */				for (p = &buf[2]; *p != '\0' && !isspace(*p); p++)					continue;				if (*p == '\0')					p = "%s";				else				{					*p = '\0';					while (isspace(*++p))						continue;				}				fileclass(buf[1], &buf[2], p);				break;			}			/* scan the list of words and set class for all */			for (p = &buf[2]; *p != '\0'; )			{				register char *wd;				char delim;				while (*p != '\0' && isspace(*p))					p++;				wd = p;				while (*p != '\0' && !isspace(*p))					p++;				delim = *p;				*p = '\0';				if (wd[0] != '\0')					setclass(buf[1], wd);				*p = delim;			}			break;		  case 'M':		/* define mailer */			makemailer(&buf[1]);			break;		  case 'O':		/* set option */			setoption(buf[1], &buf[2], TRUE, FALSE);			break;		  case 'P':		/* set precedence */			if (NumPriorities >= MAXPRIORITIES)			{				toomany('P', MAXPRIORITIES);				break;			}			for (p = &buf[1]; *p != '\0' && *p != '=' && *p != '\t'; p++)				continue;			if (*p == '\0')				goto badline;			*p = '\0';			Priorities[NumPriorities].pri_name = newstr(&buf[1]);			Priorities[NumPriorities].pri_val = atoi(++p);			NumPriorities++;			break;		  case 'T':		/* trusted user(s) */			p = &buf[1];			while (*p != '\0')			{				while (isspace(*p))					p++;				q = p;				while (*p != '\0' && !isspace(*p))					p++;				if (*p != '\0')					*p++ = '\0';				if (*q == '\0')					continue;				for (pv = TrustedUsers; *pv != NULL; pv++)					continue;				if (pv >= &TrustedUsers[MAXTRUST])				{					toomany('T', MAXTRUST);					break;				}				*pv = newstr(q);			}			break;		  default:		  badline:			syserr("unknown control line \"%s\"", buf);		}	}	FileName = NULL;}/***  TOOMANY -- signal too many of some option****	Parameters:**		id -- the id of the error line**		maxcnt -- the maximum possible values****	Returns:**		none.****	Side Effects:**		gives a syserr.*/toomany(id, maxcnt)	char id;	int maxcnt;{	syserr("too many %c lines, %d max", id, maxcnt);}/***  FILECLASS -- read members of a class from a file****	Parameters:**		class -- class to define.**		filename -- name of file to read.**		fmt -- scanf string to use for match.****	Returns:**		none****	Side Effects:****		puts all lines in filename that match a scanf into**			the named class.*/fileclass(class, filename, fmt)	int class;	char *filename;	char *fmt;{	FILE *f;	char buf[MAXLINE];	f = fopen(filename, "r");	if (f == NULL)	{		syserr("cannot open %s", filename);		return;	}	while (fgets(buf, sizeof buf, f) != NULL)	{		register STAB *s;		register char *p;/* In support of Yellow Pages, we need to use the sscanf logic. Define * the flag. Why is this set up this way I wonder ? */# define SCANF 1# ifdef SCANF		char wordbuf[MAXNAME+1];		/* /etc/passwd file entries for Yellow Pages users		 * of the form  +name:::::/home/dir:		 * must have the  +  stripped, else the user name		 * won't get into the class.		 */		if (buf[0] == '+') {			if (sscanf(&buf[1], fmt, wordbuf) != 1)				continue;		}		else {			if (sscanf(buf, fmt, wordbuf) != 1)				continue;		}		p = wordbuf;# else SCANF		p = buf;# endif SCANF		/*		**  Break up the match into words.		*/		while (*p != '\0')		{			register char *q;			/* strip leading spaces */			while (isspace(*p))				p++;			if (*p == '\0')				break;			/* find the end of the word */			q = p;			while (*p != '\0' && !isspace(*p))				p++;			if (*p != '\0')				*p++ = '\0';			/* enter the word in the symbol table */			s = stab(q, ST_CLASS, ST_ENTER);			setbitn(class, s->s_class);		}	}	(void) fclose(f);}/***  MAKEMAILER -- define a new mailer.****	Parameters:**		line -- description of mailer.  This is in labeled**			fields.  The fields are:**			   P -- the path to the mailer**			   F -- the flags associated with the mailer**			   A -- the argv for this mailer**			   S -- the sender rewriting set**			   R -- the recipient rewriting set**			   E -- the eol string**			The first word is the canonical name of the mailer.****	Returns:**		none.****	Side Effects:**		enters the mailer into the mailer table.*/makemailer(line)	char *line;{	register char *p;	register struct mailer *m;	register STAB *s;	int i;	char fcode;	extern int NextMailer;	extern char **makeargv();	extern char *munchstring();	extern char *DelimChar;	extern long atol();	/* allocate a mailer and set up defaults */	m = (struct mailer *) xalloc(sizeof *m);	bzero((char *) m, sizeof *m);	m->m_mno = NextMailer;	m->m_eol = "\n";	/* collect the mailer name */	for (p = line; *p != '\0' && *p != ',' && !isspace(*p); p++)		continue;	if (*p != '\0')		*p++ = '\0';	m->m_name = newstr(line);	/* now scan through and assign info from the fields */	while (*p != '\0')	{		while (*p != '\0' && (*p == ',' || isspace(*p)))			p++;		/* p now points to field code */		fcode = *p;		while (*p != '\0' && *p != '=' && *p != ',')			p++;		if (*p++ != '=')		{			syserr("`=' expected");			return;		}		while (isspace(*p))			p++;		/* p now points to the field body */		p = munchstring(p);		/* install the field into the mailer struct */		switch (fcode)		{		  case 'P':		/* pathname */			m->m_mailer = newstr(p);			break;		  case 'F':		/* flags */			for (; *p != '\0'; p++)				setbitn(*p, m->m_flags);			break;		  case 'S':		/* sender rewriting ruleset */		  case 'R':		/* recipient rewriting ruleset */			i = atoi(p);			if (i < 0 || i >= MAXRWSETS)			{				syserr("invalid rewrite set, %d max", MAXRWSETS);				return;			}			if (fcode == 'S')				m->m_s_rwset = i;			else				m->m_r_rwset = i;			break;		  case 'E':		/* end of line string */			m->m_eol = newstr(p);			break;		  case 'A':		/* argument vector */			m->m_argv = makeargv(p);

⌨️ 快捷键说明

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