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

📄 readcf.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
**	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.**		safe -- if set, this is a safe read.**		optional -- if set, it is not an error for the file to**			not exist.****	Returns:**		none****	Side Effects:****		puts all lines in filename that match a scanf into**			the named class.*/fileclass(class, filename, fmt, safe, optional)	int class;	char *filename;	char *fmt;	bool safe;	bool optional;{	FILE *f;	struct stat stbuf;	char buf[MAXLINE];	if (tTd(37, 2))		printf("fileclass(%s, fmt=%s)\n", filename, fmt);	if (filename[0] == '|')	{		syserr("fileclass: pipes (F%c%s) not supported due to security problems",			class, filename);		return;	}	if (stat(filename, &stbuf) < 0)	{		if (tTd(37, 2))			printf("  cannot stat (%s)\n", errstring(errno));		if (!optional)			syserr("fileclass: cannot stat %s", filename);		return;	}	if (!S_ISREG(stbuf.st_mode))	{		syserr("fileclass: %s not a regular file", filename);		return;	}	if (!safe && access(filename, R_OK) < 0)	{		syserr("fileclass: access denied on %s", filename);		return;	}	f = fopen(filename, "r");	if (f == NULL)	{		syserr("fileclass: cannot open %s", filename);		return;	}	while (fgets(buf, sizeof buf, f) != NULL)	{		register STAB *s;		register char *p;# 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 (isascii(*p) && isspace(*p))				p++;			if (*p == '\0')				break;			/* find the end of the word */			q = p;			while (*p != '\0' && !(isascii(*p) && isspace(*p)))				p++;			if (*p != '\0')				*p++ = '\0';			/* enter the word in the symbol table */			setclass(class, q);		}	}	(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;	auto char *endp;	extern int NextMailer;	extern char **makeargv();	extern char *munchstring();	extern long atol();	/* allocate a mailer and set up defaults */	m = (struct mailer *) xalloc(sizeof *m);	bzero((char *) m, sizeof *m);	m->m_eol = "\n";	/* collect the mailer name */	for (p = line; *p != '\0' && *p != ',' && !(isascii(*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')	{		auto char *delimptr;		while (*p != '\0' && (*p == ',' || (isascii(*p) && isspace(*p))))			p++;		/* p now points to field code */		fcode = *p;		while (*p != '\0' && *p != '=' && *p != ',')			p++;		if (*p++ != '=')		{			syserr("mailer %s: `=' expected", m->m_name);			return;		}		while (isascii(*p) && isspace(*p))			p++;		/* p now points to the field body */		p = munchstring(p, &delimptr);		/* 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++)				if (!(isascii(*p) && isspace(*p)))					setbitn(*p, m->m_flags);			break;		  case 'S':		/* sender rewriting ruleset */		  case 'R':		/* recipient rewriting ruleset */			i = strtol(p, &endp, 10);			if (i < 0 || i >= MAXRWSETS)			{				syserr("invalid rewrite set, %d max", MAXRWSETS);				return;			}			if (fcode == 'S')				m->m_sh_rwset = m->m_se_rwset = i;			else				m->m_rh_rwset = m->m_re_rwset = i;			p = endp;			if (*p++ == '/')			{				i = strtol(p, NULL, 10);				if (i < 0 || i >= MAXRWSETS)				{					syserr("invalid rewrite set, %d max",						MAXRWSETS);					return;				}				if (fcode == 'S')					m->m_sh_rwset = i;				else					m->m_rh_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 line length */			m->m_linelimit = atoi(p);			break;		  case 'D':		/* working directory */			m->m_execdir = newstr(p);			break;		}		p = delimptr;	}	/* do some heuristic cleanup for back compatibility */	if (bitnset(M_LIMITS, m->m_flags))	{		if (m->m_linelimit == 0)			m->m_linelimit = SMTPLINELIM;		if (ConfigLevel < 2)			setbitn(M_7BITS, m->m_flags);	}	/* do some rationality checking */	if (m->m_argv == NULL)	{		syserr("M%s: A= argument required", m->m_name);		return;	}	if (m->m_mailer == NULL)	{		syserr("M%s: P= argument required", m->m_name);		return;	}	if (NextMailer >= MAXMAILERS)	{		syserr("too many mailers defined (%d max)", MAXMAILERS);		return;	}	s = stab(m->m_name, ST_MAILER, ST_ENTER);	if (s->s_mailer != NULL)	{		i = s->s_mailer->m_mno;		free(s->s_mailer);	}	else	{		i = NextMailer++;	}	Mailer[i] = s->s_mailer = m;	m->m_mno = i;}/***  MUNCHSTRING -- translate a string into internal form.****	Parameters:**		p -- the string to munch.**		delimptr -- if non-NULL, set to the pointer of the**			field delimiter character.****	Returns:**		the munched string.*/char *munchstring(p, delimptr)	register char *p;	char **delimptr;{	register char *q;	bool backslash = FALSE;	bool quotemode = FALSE;	static char buf[MAXLINE];	for (q = buf; *p != '\0'; p++)	{		if (backslash)		{			/* everything is roughly literal */			backslash = FALSE;			switch (*p)			{			  case 'r':		/* carriage return */				*q++ = '\r';				continue;			  case 'n':		/* newline */				*q++ = '\n';				continue;			  case 'f':		/* form feed */				*q++ = '\f';				continue;			  case 'b':		/* backspace */				*q++ = '\b';				continue;			}			*q++ = *p;		}		else		{			if (*p == '\\')				backslash = TRUE;			else if (*p == '"')				quotemode = !quotemode;			else if (quotemode || *p != ',')				*q++ = *p;			else				break;		}	}	if (delimptr != NULL)		*delimptr = p;	*q++ = '\0';	return (buf);}/***  MAKEARGV -- break up a string into words****	Parameters:**		p -- the string to break up.****	Returns:**		a char **argv (dynamically allocated)****	Side Effects:**		munges p.*/char **makeargv(p)	register char *p;{	char *q;	int i;	char **avp;	char *argv[MAXPV + 1];	/* take apart the words */	i = 0;	while (*p != '\0' && i < MAXPV)	{		q = p;		while (*p != '\0' && !(isascii(*p) && isspace(*p)))			p++;		while (isascii(*p) && isspace(*p))			*p++ = '\0';		argv[i++] = newstr(q);	}	argv[i++] = NULL;	/* now make a copy of the argv */	avp = (char **) xalloc(sizeof *avp * i);	bcopy((char *) argv, (char *) avp, sizeof *avp * i);	return (avp);}/***  PRINTRULES -- print rewrite rules (for debugging)****	Parameters:**		none.****	Returns:**		none.****	Side Effects:**		prints rewrite rules.*/printrules(){	register struct rewrite *rwp;	register int ruleset;	for (ruleset = 0; ruleset < 10; ruleset++)	{		if (RewriteRules[ruleset] == NULL)			continue;		printf("\n----Rule Set %d:", ruleset);		for (rwp = RewriteRules[ruleset]; rwp != NULL; rwp = rwp->r_next)		{			printf("\nLHS:");			printav(rwp->r_lhs);			printf("RHS:");			printav(rwp->r_rhs);		}	}}/***  SETOPTION -- set global processing option****	Parameters:**		opt -- option name.**		val -- option value (as a text string).**		safe -- set if this came from a configuration file.**			Some options (if set from the command line) will**			reset the user id to avoid security problems.**		sticky -- if set, don't let other setoptions override**			this value.**		e -- the main envelope.****	Returns:**		none.****	Side Effects:**		Sets options as implied by the arguments.*/static BITMAP	StickyOpt;		/* set if option is stuck */#if NAMED_BINDstruct resolverflags{	char	*rf_name;	/* name of the flag */	long	rf_bits;	/* bits to set/clear */} ResolverFlags[] ={	"debug",	RES_DEBUG,	"aaonly",	RES_AAONLY,	"usevc",	RES_USEVC,	"primary",	RES_PRIMARY,	"igntc",	RES_IGNTC,	"recurse",	RES_RECURSE,	"defnames",	RES_DEFNAMES,	"stayopen",	RES_STAYOPEN,	"dnsrch",	RES_DNSRCH,	"true",		0,		/* to avoid error on old syntax */	NULL,		0};#endifsetoption(opt, val, safe, sticky, e)	char opt;	char *val;	bool safe;	bool sticky;	register ENVELOPE *e;{	register char *p;	extern bool atobool();	extern time_t convtime();	extern int QueueLA;	extern int RefuseLA;	extern bool Warn_Q_option;	extern bool trusteduser();	if (tTd(37, 1))		printf("setoption %c=%s", opt, val);	/*	**  See if this option is preset for us.	*/	if (!sticky && bitnset(opt, StickyOpt))	{		if (tTd(37, 1))			printf(" (ignored)\n");		return;	}	/*	**  Check to see if this option can be specified by this user.	*/	if (!safe && RealUid == 0)		safe = TRUE;	if (!safe && strchr("bCdeijLmoprsvw7", opt) == NULL)	{		if (opt != 'M' || (val[0] != 'r' && val[0] != 's'))		{			if (tTd(37, 1))				printf(" (unsafe)");			if (RealUid != geteuid())			{				if (tTd(37, 1))					printf("(Resetting uid)");				(void) setgid(RealGid);				(void) setuid(RealUid);			}		}	}	if (tTd(37, 1))		printf("\n");	switch (opt)	{	  case '7':		/* force seven-bit input */		SevenBit = atobool(val);		break;	  case 'A':		/* set default alias file */		if (val[0] == '\0')			setalias("aliases");		else			setalias(val);		break;	  case 'a':		/* look N minutes for "@:@" in alias file */		if (val[0] == '\0')			SafeAlias = 5 * 60;		/* five minutes */		else			SafeAlias = convtime(val, 'm');		break;	  case 'B':		/* substitution for blank character */		SpaceSub = val[0];		if (SpaceSub == '\0')			SpaceSub = ' ';		break;	  case 'b':		/* min blocks free on queue fs/max msg size */

⌨️ 快捷键说明

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