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

📄 headers.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 <errno.h># include "sendmail.h"SCCSID(@(#)headers.c 1.1 92/07/30); /* from UCB 5.9 9/21/88 *//***  CHOMPHEADER -- process and save a header line.****	Called by collect and by readcf to deal with header lines.****	Parameters:**		line -- header as a text line.**		def -- if set, this is a default value.****	Returns:**		flags for this header.****	Side Effects:**		The header is saved on the header list.**		Contents of 'line' are destroyed.*/chompheader(line, def)	char *line;	bool def;{	register char *p;	register HDR *h;	HDR **hp;	char *fname;	char *fvalue;	struct hdrinfo *hi;	bool cond = FALSE;	BITMAP mopts;	extern char *crackaddr();# ifdef DEBUG	if (tTd(31, 6))		printf("chompheader: %s\n", line);# endif DEBUG	/* strip off options */	clrbitmap(mopts);	p = line;	if (*p == '?')	{		/* have some */		register char *q = index(p + 1, *p);				if (q != NULL)		{			*q++ = '\0';			while (*++p != '\0')				setbitn(*p, mopts);			p = q;		}		else			syserr("chompheader: syntax error, line \"%s\"", line);		cond = TRUE;	}	/* find canonical name */	fname = p;	p = index(p, ':');	if (p == NULL)	{		syserr("chompheader: syntax error, line \"%s\"", line);		return (0);	}	fvalue = &p[1];	while (isspace(*--p))		continue;	*++p = '\0';	makelower(fname);	/* strip field value on front */	if (*fvalue == ' ')		fvalue++;	/* see if it is a known type */	for (hi = HdrInfo; hi->hi_field != NULL; hi++)	{		if (strcmp(hi->hi_field, fname) == 0)			break;	}	/* see if this is a resent message */	if (!def && bitset(H_RESENT, hi->hi_flags))		CurEnv->e_flags |= EF_RESENT;	/* if this means "end of header" quit now */	if (bitset(H_EOH, hi->hi_flags))		return (hi->hi_flags);	/* drop explicit From: if same as what we would generate -- for MH */	p = "resent-from";	if (!bitset(EF_RESENT, CurEnv->e_flags))		p += 7;	if (!def && !QueueRun && strcmp(fname, p) == 0)	{		if (CurEnv->e_from.q_paddr != NULL &&		    strcmp(fvalue, CurEnv->e_from.q_paddr) == 0)			return (hi->hi_flags);	}	/* delete default value for this header */	for (hp = &CurEnv->e_header; (h = *hp) != NULL; hp = &h->h_link)	{		if (strcmp(fname, h->h_field) == 0 &&		    bitset(H_DEFAULT, h->h_flags) &&		    !bitset(H_FORCE, h->h_flags))			h->h_value = NULL;	}	/* create a new node */	h = (HDR *) xalloc(sizeof *h);	h->h_field = newstr(fname);	h->h_value = NULL;	h->h_link = NULL;	bcopy((char *) mopts, (char *) h->h_mflags, sizeof mopts);	*hp = h;	h->h_flags = hi->hi_flags;	if (def)		h->h_flags |= H_DEFAULT;	if (cond)		h->h_flags |= H_CHECK;	if (h->h_value != NULL)		free((char *) h->h_value);	h->h_value = newstr(fvalue);	/* hack to see if this is a new format message */	if (!def && bitset(H_RCPT|H_FROM, h->h_flags) &&	    (index(fvalue, ',') != NULL || index(fvalue, '(') != NULL ||	     index(fvalue, '<') != NULL || index(fvalue, ';') != NULL))	{		CurEnv->e_flags &= ~EF_OLDSTYLE;	}	return (h->h_flags);}/***  ADDHEADER -- add a header entry to the end of the queue.****	This bypasses the special checking of chompheader.****	Parameters:**		field -- the name of the header field.**		value -- the value of the field.  It must be lower-cased.**		e -- the envelope to add them to.****	Returns:**		none.****	Side Effects:**		adds the field on the list of headers for this envelope.*/addheader(field, value, e)	char *field;	char *value;	ENVELOPE *e;{	register HDR *h;	register struct hdrinfo *hi;	HDR **hp;	/* find info struct */	for (hi = HdrInfo; hi->hi_field != NULL; hi++)	{		if (strcmp(field, hi->hi_field) == 0)			break;	}	/* find current place in list -- keep back pointer? */	for (hp = &e->e_header; (h = *hp) != NULL; hp = &h->h_link)	{		if (strcmp(field, h->h_field) == 0)			break;	}	/* allocate space for new header */	h = (HDR *) xalloc(sizeof *h);	h->h_field = field;	h->h_value = newstr(value);	h->h_link = *hp;	h->h_flags = hi->hi_flags | H_DEFAULT;	clrbitmap(h->h_mflags);	*hp = h;}/***  HVALUE -- return value of a header.****	Only "real" fields (i.e., ones that have not been supplied**	as a default) are used.****	Parameters:**		field -- the field name.****	Returns:**		pointer to the value part.**		NULL if not found.****	Side Effects:**		none.*/char *hvalue(field)	char *field;{	register HDR *h;	for (h = CurEnv->e_header; h != NULL; h = h->h_link)	{		if (!bitset(H_DEFAULT, h->h_flags) && strcmp(h->h_field, field) == 0)			return (h->h_value);	}	return (NULL);}/***  ISHEADER -- predicate telling if argument is a header.****	A line is a header if it has a single word followed by**	optional white space followed by a colon.****	Parameters:**		s -- string to check for possible headerness.****	Returns:**		TRUE if s is a header.**		FALSE otherwise.****	Side Effects:**		none.*/boolisheader(s)	register char *s;{	while (*s > ' ' && *s != ':' && *s != '\0')		s++;	/* following technically violates RFC822 */	while (isspace(*s))		s++;	return (*s == ':');}/***  EATHEADER -- run through the stored header and extract info.****	Parameters:**		e -- the envelope to process.****	Returns:**		none.****	Side Effects:**		Sets a bunch of global variables from information**			in the collected header.**		Aborts the message if the hop count is exceeded.*/eatheader(e)	register ENVELOPE *e;{	register HDR *h;	register char *p;	int hopcnt = 0;#ifdef DEBUG	if (tTd(32, 1))		printf("----- collected header -----\n");#endif DEBUG	for (h = e->e_header; h != NULL; h = h->h_link)	{#ifdef DEBUG		extern char *capitalize();		if (tTd(32, 1))			printf("%s: %s\n", capitalize(h->h_field), h->h_value);#endif DEBUG		/* count the number of times it has been processed */		if (bitset(H_TRACE, h->h_flags))			hopcnt++;		/* send to this person if we so desire */		if (GrabTo && bitset(H_RCPT, h->h_flags) &&		    !bitset(H_DEFAULT, h->h_flags) &&		    (!bitset(EF_RESENT, CurEnv->e_flags) || bitset(H_RESENT, h->h_flags)))		{			sendtolist(h->h_value, (ADDRESS *) NULL, &CurEnv->e_sendqueue);		}		/* log the message-id */#ifdef LOG		if (!QueueRun && LogLevel > 8 && h->h_value != NULL &&		    strcmp(h->h_field, "message-id") == 0)		{			char buf[MAXNAME];			p = h->h_value;			if (bitset(H_DEFAULT, h->h_flags))			{				expand(p, buf, &buf[sizeof buf], e);				p = buf;			}			syslog(LOG_INFO, "%s: message-id=%s", e->e_id, p);		}#endif LOG	}#ifdef DEBUG	if (tTd(32, 1))		printf("----------------------------\n");#endif DEBUG	/* store hop count */	if (hopcnt > e->e_hopcount)		e->e_hopcount = hopcnt;	/* message priority */	p = hvalue("precedence");	if (p != NULL)		e->e_class = priencode(p);	if (!QueueRun)		e->e_msgpriority = e->e_msgsize				 - e->e_class * WkClassFact				 + e->e_nrcpts * WkRecipFact;	/* return receipt to */	p = hvalue("return-receipt-to");	if (p != NULL)		e->e_receiptto = p;	/* errors to */	p = hvalue("errors-to");	if (p != NULL)		sendtolist(p, (ADDRESS *) NULL, &e->e_errorqueue);	/* from person */	if (OpMode == MD_ARPAFTP)	{		register struct hdrinfo *hi = HdrInfo;		for (p = NULL; p == NULL && hi->hi_field != NULL; hi++)		{			if (bitset(H_FROM, hi->hi_flags))				p = hvalue(hi->hi_field);		}		if (p != NULL)			setsender(p);	}	/* full name of from person */	p = hvalue("full-name");	if (p != NULL)		define('x', p, e);	/* date message originated */	p = hvalue("posted-date");	if (p == NULL)		p = hvalue("date");	if (p != NULL)	{		define('a', p, e);		/* we don't have a good way to do canonical conversion ....		define('d', newstr(arpatounix(p)), e);		.... so we will ignore the problem for the time being */	}	/*	**  Log collection information.	*/# ifdef LOG	if (!QueueRun && LogLevel > 1)	{		syslog(LOG_INFO, "%s: from=%s, size=%ld, class=%d\n",		       CurEnv->e_id, CurEnv->e_from.q_paddr, CurEnv->e_msgsize,		       CurEnv->e_class);	}# endif LOG}/***  PRIENCODE -- encode external priority names into internal values.****	Parameters:**		p -- priority in ascii.****	Returns:**		priority as a numeric level.****	Side Effects:**		none.*/priencode(p)	char *p;{	register int i;	for (i = 0; i < NumPriorities; i++)	{		if (!strcasecmp(p, Priorities[i].pri_name))			return (Priorities[i].pri_val);	}	/* unknown priority */	return (0);}/***  CRACKADDR -- parse an address and turn it into a macro****	This doesn't actually parse the address -- it just extracts**	it and replaces it with "$g".  The parse is totally ad hoc**	and isn't even guaranteed to leave something syntactically**	identical to what it started with.  However, it does leave**	something semantically identical.****	The process is kind of strange.  There are a number of**	interesting cases:**		1.  comment <address> comment	==> comment <$g> comment**		2.  address			==> address**		3.  address (comment)		==> $g (comment)**		4.  (comment) address		==> (comment) $g**	And then there are the hard cases....**		5.  add (comment) ress		==> $g (comment)

⌨️ 快捷键说明

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