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

📄 readcf.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1988 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that this notice is preserved and that due credit is given * to the University of California at Berkeley. The name of the University * may not be used to endorse or promote products derived from this * software without specific prior written permission. This software * is provided ``as is'' without express or implied warranty. * *  Sendmail *  Copyright (c) 1983  Eric P. Allman *  Berkeley, California */# include "sendmail.h"SCCSID(@(#)readcf.c 1.1 92/07/30 SMI); /* from UCB 5.12 4/1/88 *//***  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:**		Cxword		Put word into class x.**		Dxval		Define macro x to have value val.**		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.**		Fx|cmd		Read standard output of cmd for lines**				to put into**				class x.  1st word on line goes in.**		Hname: value	Define header with field-name 'name'**				and value as specified; this will be**				macro expanded immediately before**				use.**		Sn		Define rewriting set n.**		Rlhs rhs	Rewrite addresses that match lhs to**				be rhs.**		Mname, arg=val,...	**				Define mailer.  name = internal name,**				rest are keyword arguments.**		Oxvalue		Set option x to value.**		Pname=value	Set precedence name to value.**		Tname		Declare trusted users**		****	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)	{		extern char *ConfFile2;		/*		 * For Sun's disk reorg, try the old file location if the new		 * file location is not found.		 */		cfname = ConfFile2;		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 'F':		/* word class from file */			/*			 * GNU replaced the "scanf string" feature with			 * a "read class from shell cmd" feature.			 * It might be more general, but we also			 * need backward compatibility,			 */			fileclass(buf[1], &buf[2]);			break;		  case 'C':		/* word class */			/* 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.  If it begins with**			    '|', a pipe from that command is read instead.****	Returns:**		none****	Side Effects:**		puts the first word of each line in file filename (or each**			line of output from program 'filename') into**			the named class.*/fileclass(class, filename)	int class;	char *filename;{	register FILE *f;	char *fmt;	register char *p;	char buf[MAXLINE];		  /*	   * remove leading and trailing spaces and tabs	   */	for ( p=filename; *p != '\0' && isspace(*p); p++)		continue;	for ( filename=p; *p != '\0'; p++)		continue;	for ( p--; isspace(*p) && p != filename; p--)		*p = '\0';	fmt = "%s";	if ('|' == filename[0]) {		  /*		   * if reading from a program, use entire line including		   * arguments as command, and always use default format.		   */		f = popen(&filename[1], "r");	} else {		  /*		   * reading from a file, treat the optional argument as		   * a scanf format string as in BSD.		   */		for ( p=filename; *p != '\0' && !isspace(*p); p++)			continue;		if (*p != '\0') {			*p = '\0';			while (isspace(*++p))				continue;			fmt = p;		}		f = fopen(filename, "r");	}	if (f == NULL)	{		syserr("cannot open %s", filename);		return;	}	while (fgets(buf, sizeof buf, f) != NULL)	{		register STAB *s;# ifdef SCANF		char wordbuf[MAXNAME+1];		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);			continue;		}	}	if ('|' == filename[0]) {		(void) pclose(f);	} else {		(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_argvsize = 10000;	/* 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);			break;		  case 'M':		/* maximum message size */			m->m_maxsize = atol(p);			break;		  case 'L':		/* maximum length of argv */			m->m_argvsize = atoi(p);

⌨️ 快捷键说明

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