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

📄 envelope.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1983 Eric P. Allman * Copyright (c) 1988, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)envelope.c	8.34 (Berkeley) 4/14/94";#endif /* not lint */#include "sendmail.h"#include <pwd.h>/***  NEWENVELOPE -- allocate a new envelope****	Supports inheritance.****	Parameters:**		e -- the new envelope to fill in.**		parent -- the envelope to be the parent of e.****	Returns:**		e.****	Side Effects:**		none.*/ENVELOPE *newenvelope(e, parent)	register ENVELOPE *e;	register ENVELOPE *parent;{	extern putheader(), putbody();	extern ENVELOPE BlankEnvelope;	if (e == parent && e->e_parent != NULL)		parent = e->e_parent;	clearenvelope(e, TRUE);	if (e == CurEnv)		bcopy((char *) &NullAddress, (char *) &e->e_from, sizeof e->e_from);	else		bcopy((char *) &CurEnv->e_from, (char *) &e->e_from, sizeof e->e_from);	e->e_parent = parent;	e->e_ctime = curtime();	if (parent != NULL)		e->e_msgpriority = parent->e_msgsize;	e->e_puthdr = putheader;	e->e_putbody = putbody;	if (CurEnv->e_xfp != NULL)		(void) fflush(CurEnv->e_xfp);	return (e);}/***  DROPENVELOPE -- deallocate an envelope.****	Parameters:**		e -- the envelope to deallocate.****	Returns:**		none.****	Side Effects:**		housekeeping necessary to dispose of an envelope.**		Unlocks this queue file.*/voiddropenvelope(e)	register ENVELOPE *e;{	bool queueit = FALSE;	bool saveit = bitset(EF_FATALERRS, e->e_flags);	register ADDRESS *q;	char *id = e->e_id;	char buf[MAXLINE];	if (tTd(50, 1))	{		printf("dropenvelope %x: id=", e);		xputs(e->e_id);		printf(", flags=0x%x\n", e->e_flags);		if (tTd(50, 10))		{			printf("sendq=");			printaddr(e->e_sendqueue, TRUE);		}	}	/* we must have an id to remove disk files */	if (id == NULL)		return;#ifdef LOG	if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))		logsender(e, NULL);	if (LogLevel > 84)		syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=0x%x, pid=%d",				  id, e->e_flags, getpid());#endif /* LOG */	e->e_flags &= ~EF_LOGSENDER;	/* post statistics */	poststats(StatFile);	/*	**  Extract state information from dregs of send list.	*/	e->e_flags &= ~EF_QUEUERUN;	for (q = e->e_sendqueue; q != NULL; q = q->q_next)	{		if (bitset(QQUEUEUP, q->q_flags))			queueit = TRUE;		if (!bitset(QDONTSEND, q->q_flags) &&		    bitset(QBADADDR, q->q_flags))		{			if (q->q_owner == NULL &&			    strcmp(e->e_from.q_paddr, "<>") != 0)				(void) sendtolist(e->e_from.q_paddr, NULL,						  &e->e_errorqueue, e);		}	}	/*	**  See if the message timed out.	*/	if (!queueit)		/* nothing to do */ ;	else if (curtime() > e->e_ctime + TimeOuts.to_q_return)	{		(void) sprintf(buf, "Cannot send message for %s",			pintvl(TimeOuts.to_q_return, FALSE));		if (e->e_message != NULL)			free(e->e_message);		e->e_message = newstr(buf);		message(buf);		e->e_flags |= EF_CLRQUEUE;		saveit = TRUE;		fprintf(e->e_xfp, "Message could not be delivered for %s\n",			pintvl(TimeOuts.to_q_return, FALSE));		fprintf(e->e_xfp, "Message will be deleted from queue\n");		for (q = e->e_sendqueue; q != NULL; q = q->q_next)		{			if (bitset(QQUEUEUP, q->q_flags))				q->q_flags |= QBADADDR;		}	}	else if (TimeOuts.to_q_warning > 0 &&	    curtime() > e->e_ctime + TimeOuts.to_q_warning)	{		if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) &&		    e->e_class >= 0 &&		    strcmp(e->e_from.q_paddr, "<>") != 0)		{			(void) sprintf(buf,				"warning: cannot send message for %s",				pintvl(TimeOuts.to_q_warning, FALSE));			if (e->e_message != NULL)				free(e->e_message);			e->e_message = newstr(buf);			message(buf);			e->e_flags |= EF_WARNING;			saveit = TRUE;		}		fprintf(e->e_xfp,			"Warning: message still undelivered after %s\n",			pintvl(TimeOuts.to_q_warning, FALSE));		fprintf(e->e_xfp, "Will keep trying until message is %s old\n",			pintvl(TimeOuts.to_q_return, FALSE));		for (q = e->e_sendqueue; q != NULL; q = q->q_next)		{			if (bitset(QQUEUEUP, q->q_flags))				q->q_flags |= QREPORT;		}	}	/*	**  Send back return receipts as requested.	*/	if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags)	    && !bitset(PRIV_NORECEIPTS, PrivacyFlags))	{		auto ADDRESS *rlist = NULL;		(void) sendtolist(e->e_receiptto, NULLADDR, &rlist, e);		(void) returntosender("Return receipt", rlist, FALSE, e);		e->e_flags &= ~EF_SENDRECEIPT;	}	/*	**  Arrange to send error messages if there are fatal errors.	*/	if (saveit && e->e_errormode != EM_QUIET)		savemail(e);	/*	**  Arrange to send warning messages to postmaster as requested.	*/	if (bitset(EF_PM_NOTIFY, e->e_flags) && PostMasterCopy != NULL &&	    !bitset(EF_RESPONSE, e->e_flags) && e->e_class >= 0)	{		auto ADDRESS *rlist = NULL;		(void) sendtolist(PostMasterCopy, NULLADDR, &rlist, e);		(void) returntosender(e->e_message, rlist, FALSE, e);	}	/*	**  Instantiate or deinstantiate the queue.	*/	if ((!queueit && !bitset(EF_KEEPQUEUE, e->e_flags)) ||	    bitset(EF_CLRQUEUE, e->e_flags))	{		if (tTd(50, 1))			printf("\n===== Dropping [dq]f%s =====\n\n", e->e_id);		if (e->e_df != NULL)			xunlink(e->e_df);		xunlink(queuename(e, 'q'));#ifdef LOG		if (LogLevel > 10)			syslog(LOG_INFO, "%s: done", id);#endif	}	else if (queueit || !bitset(EF_INQUEUE, e->e_flags))	{#ifdef QUEUE		queueup(e, bitset(EF_KEEPQUEUE, e->e_flags), FALSE);#else /* QUEUE */		syserr("554 dropenvelope: queueup");#endif /* QUEUE */	}	/* now unlock the job */	closexscript(e);	unlockqueue(e);	/* make sure that this envelope is marked unused */	if (e->e_dfp != NULL)		(void) xfclose(e->e_dfp, "dropenvelope", e->e_df);	e->e_dfp = NULL;	e->e_id = e->e_df = NULL;}/***  CLEARENVELOPE -- clear an envelope without unlocking****	This is normally used by a child process to get a clean**	envelope without disturbing the parent.****	Parameters:**		e -- the envelope to clear.**		fullclear - if set, the current envelope is total**			garbage and should be ignored; otherwise,**			release any resources it may indicate.****	Returns:**		none.****	Side Effects:**		Closes files associated with the envelope.**		Marks the envelope as unallocated.*/voidclearenvelope(e, fullclear)	register ENVELOPE *e;	bool fullclear;{	register HDR *bh;	register HDR **nhp;	extern ENVELOPE BlankEnvelope;	if (!fullclear)	{		/* clear out any file information */		if (e->e_xfp != NULL)			(void) xfclose(e->e_xfp, "clearenvelope xfp", e->e_id);		if (e->e_dfp != NULL)			(void) xfclose(e->e_dfp, "clearenvelope dfp", e->e_df);		e->e_xfp = e->e_dfp = NULL;	}	/* now clear out the data */	STRUCTCOPY(BlankEnvelope, *e);	if (Verbose)		e->e_sendmode = SM_DELIVER;	bh = BlankEnvelope.e_header;	nhp = &e->e_header;	while (bh != NULL)	{		*nhp = (HDR *) xalloc(sizeof *bh);		bcopy((char *) bh, (char *) *nhp, sizeof *bh);		bh = bh->h_link;		nhp = &(*nhp)->h_link;	}}/***  INITSYS -- initialize instantiation of system****	In Daemon mode, this is done in the child.****	Parameters:**		none.****	Returns:**		none.****	Side Effects:**		Initializes the system macros, some global variables,**		etc.  In particular, the current time in various**		forms is set.*/voidinitsys(e)	register ENVELOPE *e;{	char cbuf[5];				/* holds hop count */	char pbuf[10];				/* holds pid */#ifdef TTYNAME	static char ybuf[60];			/* holds tty id */	register char *p;#endif /* TTYNAME */	extern char *ttyname();	extern void settime();	extern char Version[];	/*	**  Give this envelope a reality.	**	I.e., an id, a transcript, and a creation time.	*/	openxscript(e);	e->e_ctime = curtime();	/*	**  Set OutChannel to something useful if stdout isn't it.	**	This arranges that any extra stuff the mailer produces	**	gets sent back to the user on error (because it is	**	tucked away in the transcript).	*/	if (OpMode == MD_DAEMON && bitset(EF_QUEUERUN, e->e_flags) &&	    e->e_xfp != NULL)		OutChannel = e->e_xfp;	/*	**  Set up some basic system macros.	*/	/* process id */	(void) sprintf(pbuf, "%d", getpid());	define('p', newstr(pbuf), e);

⌨️ 快捷键说明

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