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

📄 deliver.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
logdelivery(m, mci, stat, ctladdr, e)	MAILER *m;	register MCI *mci;	char *stat;	ADDRESS *ctladdr;	register ENVELOPE *e;{# ifdef LOG	register char *bp;	register char *p;	int l;	char buf[512];#  if (SYSLOG_BUFSIZE) >= 256	bp = buf;	if (ctladdr != NULL)	{		strcpy(bp, ", ctladdr=");		strcat(bp, shortenstring(ctladdr->q_paddr, 83));		bp += strlen(bp);		if (bitset(QGOODUID, ctladdr->q_flags))		{			(void) sprintf(bp, " (%d/%d)",					ctladdr->q_uid, ctladdr->q_gid);			bp += strlen(bp);		}	}	(void) sprintf(bp, ", delay=%s", pintvl(curtime() - e->e_ctime, TRUE));	bp += strlen(bp);	if (m != NULL)	{		(void) strcpy(bp, ", mailer=");		(void) strcat(bp, m->m_name);		bp += strlen(bp);	}	if (mci != NULL && mci->mci_host != NULL)	{# ifdef DAEMON		extern SOCKADDR CurHostAddr;# endif		(void) strcpy(bp, ", relay=");		(void) strcat(bp, mci->mci_host);# ifdef DAEMON		(void) strcat(bp, " [");		(void) strcat(bp, anynet_ntoa(&CurHostAddr));		(void) strcat(bp, "]");# endif	}	else if (strcmp(stat, "queued") != 0)	{		char *p = macvalue('h', e);		if (p != NULL && p[0] != '\0')		{			(void) strcpy(bp, ", relay=");			(void) strcat(bp, p);		}	}	bp += strlen(bp);#define STATLEN		(((SYSLOG_BUFSIZE) - 100) / 4)#if (STATLEN) < 63# undef STATLEN# define STATLEN	63#endif#if (STATLEN) > 203# undef STATLEN# define STATLEN	203#endif	if ((bp - buf) > (sizeof buf - ((STATLEN) + 20)))	{		/* desperation move -- truncate data */		bp = buf + sizeof buf - ((STATLEN) + 17);		strcpy(bp, "...");		bp += 3;	}	(void) strcpy(bp, ", stat=");	bp += strlen(bp);	(void) strcpy(bp, shortenstring(stat, (STATLEN)));			l = SYSLOG_BUFSIZE - 100 - strlen(buf);	p = e->e_to;	while (strlen(p) >= l)	{		register char *q = strchr(p + l, ',');		if (q == NULL)			break;		syslog(LOG_INFO, "%s: to=%.*s [more]%s",			e->e_id, ++q - p, p, buf);		p = q;	}	syslog(LOG_INFO, "%s: to=%s%s", e->e_id, p, buf);#  else		/* we have a very short log buffer size */	l = SYSLOG_BUFSIZE - 85;	p = e->e_to;	while (strlen(p) >= l)	{		register char *q = strchr(p + l, ',');		if (q == NULL)			break;		syslog(LOG_INFO, "%s: to=%.*s [more]",			e->e_id, ++q - p, p);		p = q;	}	syslog(LOG_INFO, "%s: to=%s", e->e_id, p);	if (ctladdr != NULL)	{		bp = buf;		strcpy(buf, "ctladdr=");		bp += strlen(buf);		strcpy(bp, shortenstring(ctladdr->q_paddr, 83));		bp += strlen(buf);		if (bitset(QGOODUID, ctladdr->q_flags))		{			(void) sprintf(bp, " (%d/%d)",					ctladdr->q_uid, ctladdr->q_gid);			bp += strlen(bp);		}		syslog(LOG_INFO, "%s: %s", e->e_id, buf);	}	bp = buf;	sprintf(bp, "delay=%s", pintvl(curtime() - e->e_ctime, TRUE));	bp += strlen(bp);	if (m != NULL)	{		sprintf(bp, ", mailer=%s", m->m_name);		bp += strlen(bp);	}	syslog(LOG_INFO, "%s: %s", e->e_id, buf);	buf[0] = '\0';	if (mci != NULL && mci->mci_host != NULL)	{# ifdef DAEMON		extern SOCKADDR CurHostAddr;# endif		sprintf(buf, "relay=%s", mci->mci_host);# ifdef DAEMON		(void) strcat(buf, " [");		(void) strcat(buf, anynet_ntoa(&CurHostAddr));		(void) strcat(buf, "]");# endif	}	else if (strcmp(stat, "queued") != 0)	{		char *p = macvalue('h', e);		if (p != NULL && p[0] != '\0')			sprintf(buf, "relay=%s", p);	}	if (buf[0] != '\0')		syslog(LOG_INFO, "%s: %s", e->e_id, buf);	syslog(LOG_INFO, "%s: stat=%s", e->e_id, shortenstring(stat, 63));#  endif /* short log buffer */# endif /* LOG */}/***  PUTFROMLINE -- output a UNIX-style from line (or whatever)****	This can be made an arbitrary message separator by changing $l****	One of the ugliest hacks seen by human eyes is contained herein:**	UUCP wants those stupid "remote from <host>" lines.  Why oh why**	does a well-meaning programmer such as myself have to deal with**	this kind of antique garbage????****	Parameters:**		mci -- the connection information.**		e -- the envelope.****	Returns:**		none****	Side Effects:**		outputs some text to fp.*/putfromline(mci, e)	register MCI *mci;	ENVELOPE *e;{	char *template = "\201l\n";	char buf[MAXLINE];	if (bitnset(M_NHDR, mci->mci_mailer->m_flags))		return;# ifdef UGLYUUCP	if (bitnset(M_UGLYUUCP, mci->mci_mailer->m_flags))	{		char *bang;		char xbuf[MAXLINE];		expand("\201g", buf, &buf[sizeof buf - 1], e);		bang = strchr(buf, '!');		if (bang == NULL)		{			errno = 0;			syserr("554 No ! in UUCP From address! (%s given)", buf);		}		else		{			*bang++ = '\0';			(void) sprintf(xbuf, "From %s  \201d remote from %s\n", bang, buf);			template = xbuf;		}	}# endif /* UGLYUUCP */	expand(template, buf, &buf[sizeof buf - 1], e);	putline(buf, mci);}/***  PUTBODY -- put the body of a message.****	Parameters:**		mci -- the connection information.**		e -- the envelope to put out.**		separator -- if non-NULL, a message separator that must**			not be permitted in the resulting message.****	Returns:**		none.****	Side Effects:**		The message is written onto fp.*/putbody(mci, e, separator)	register MCI *mci;	register ENVELOPE *e;	char *separator;{	char buf[MAXLINE];	/*	**  Output the body of the message	*/	if (e->e_dfp == NULL)	{		if (e->e_df != NULL)		{			e->e_dfp = fopen(e->e_df, "r");			if (e->e_dfp == NULL)				syserr("putbody: Cannot open %s for %s from %s",				e->e_df, e->e_to, e->e_from.q_paddr);		}		else			putline("<<< No Message Collected >>>", mci);	}	if (e->e_dfp != NULL)	{		rewind(e->e_dfp);		while (!ferror(mci->mci_out) && fgets(buf, sizeof buf, e->e_dfp) != NULL)		{			if (buf[0] == 'F' &&			    bitnset(M_ESCFROM, mci->mci_mailer->m_flags) &&			    strncmp(buf, "From ", 5) == 0)				(void) putc('>', mci->mci_out);			if (buf[0] == '-' && buf[1] == '-' && separator != NULL)			{				/* possible separator */				int sl = strlen(separator);				if (strncmp(&buf[2], separator, sl) == 0)					(void) putc(' ', mci->mci_out);			}			putline(buf, mci);		}		if (ferror(e->e_dfp))		{			syserr("putbody: %s: read error", e->e_df);			ExitStat = EX_IOERR;		}	}	/* some mailers want extra blank line at end of message */	if (bitnset(M_BLANKEND, mci->mci_mailer->m_flags) &&	    buf[0] != '\0' && buf[0] != '\n')		putline("", mci);	(void) fflush(mci->mci_out);	if (ferror(mci->mci_out) && errno != EPIPE)	{		syserr("putbody: write error");		ExitStat = EX_IOERR;	}	errno = 0;}/***  MAILFILE -- Send a message to a file.****	If the file has the setuid/setgid bits set, but NO execute**	bits, sendmail will try to become the owner of that file**	rather than the real user.  Obviously, this only works if**	sendmail runs as root.****	This could be done as a subordinate mailer, except that it**	is used implicitly to save messages in ~/dead.letter.  We**	view this as being sufficiently important as to include it**	here.  For example, if the system is dying, we shouldn't have**	to create another process plus some pipes to save the message.****	Parameters:**		filename -- the name of the file to send to.**		ctladdr -- the controlling address header -- includes**			the userid/groupid to be when sending.****	Returns:**		The exit code associated with the operation.****	Side Effects:**		none.*/mailfile(filename, ctladdr, e)	char *filename;	ADDRESS *ctladdr;	register ENVELOPE *e;{	register FILE *f;	register int pid;	int mode;	if (tTd(11, 1))	{		printf("mailfile %s\n  ctladdr=", filename);		printaddr(ctladdr, FALSE);	}	if (e->e_xfp != NULL)		fflush(e->e_xfp);	/*	**  Fork so we can change permissions here.	**	Note that we MUST use fork, not vfork, because of	**	the complications of calling subroutines, etc.	*/	DOFORK(fork);	if (pid < 0)		return (EX_OSERR);	else if (pid == 0)	{		/* child -- actually write to file */		struct stat stb;		MCI mcibuf;		(void) setsignal(SIGINT, SIG_DFL);		(void) setsignal(SIGHUP, SIG_DFL);		(void) setsignal(SIGTERM, SIG_DFL);		(void) umask(OldUmask);		if (stat(filename, &stb) < 0)			stb.st_mode = FileMode;		mode = stb.st_mode;		/* limit the errors to those actually caused in the child */		errno = 0;		ExitStat = EX_OK;		if (bitset(0111, stb.st_mode))			exit(EX_CANTCREAT);		if (ctladdr != NULL)		{			/* ignore setuid and setgid bits */			mode &= ~(S_ISGID|S_ISUID);		}		/* we have to open the dfile BEFORE setuid */		if (e->e_dfp == NULL && e->e_df != NULL)		{			e->e_dfp = fopen(e->e_df, "r");			if (e->e_dfp == NULL)			{				syserr("mailfile: Cannot open %s for %s from %s",					e->e_df, e->e_to, e->e_from.q_paddr);			}		}		if (!bitset(S_ISGID, mode) || setgid(stb.st_gid) < 0)		{			if (ctladdr == NULL || ctladdr->q_uid == 0)			{				(void) initgroups(DefUser, DefGid);			}			else			{				(void) initgroups(ctladdr->q_ruser ?					ctladdr->q_ruser : ctladdr->q_user,					ctladdr->q_gid);			}		}		if (!bitset(S_ISUID, mode) || setuid(stb.st_uid) < 0)		{			if (ctladdr == NULL || ctladdr->q_uid == 0)				(void) setuid(DefUid);			else				(void) setuid(ctladdr->q_uid);		}		FileName = filename;		LineNumber = 0;		f = dfopen(filename, O_WRONLY|O_CREAT|O_APPEND, FileMode);		if (f == NULL)		{			message("554 cannot open: %s", errstring(errno));			exit(EX_CANTCREAT);		}		bzero(&mcibuf, sizeof mcibuf);		mcibuf.mci_mailer = FileMailer;		mcibuf.mci_out = f;		if (bitnset(M_7BITS, FileMailer->m_flags))			mcibuf.mci_flags |= MCIF_7BIT;		putfromline(&mcibuf, e);		(*e->e_puthdr)(&mcibuf, e);		putline("\n", &mcibuf);		(*e->e_putbody)(&mcibuf, e, NULL);		putline("\n", &mcibuf);		if (ferror(f))		{			message("451 I/O error: %s", errstring(errno));			setstat(EX_IOERR);		}		(void) xfclose(f, "mailfile", filename);		(void) fflush(stdout);		/* reset ISUID & ISGID bits for paranoid systems */		(void) chmod(filename, (int) stb.st_mode);		exit(ExitStat);		/*NOTREACHED*/	}	else	{		/* parent -- wait for exit status */		int st;		st = waitfor(pid);		if (WIFEXITED(st))			return (WEXITSTATUS(st));		else		{			syserr("child died on signal %d", st);			return (EX_UNAVAILABLE);		}		/*NOTREACHED*/	}}/***  HOSTSIGNATURE -- return the "signature" for a host.****	The signature describes how we are going to send this -- it**	can be just the hostname (for non-Internet hosts) or can be**	an ordered list of MX hosts.****	Parameters:**		m -- the mailer describing this host.**		host -- the host name.**		e -- the current envelope.****	Returns:**		The signature for this host.****	Side Effects:**		Can tweak the symbol table.*/char *hostsignature(m, host, e)	register MAILER *m;	char *host;	ENVELOPE *e;{	register char *p;	register STAB *s;	int i;	int len;#if NAMED_BIND	int nmx;	auto int rcode;	char *hp;	char *endp;	int oldoptions;	char *mxhosts[MAXMXHOSTS + 1];#endif	/*	**  Check to see if this uses IPC -- if not, it can't have MX records.	*/	p = m->m_mailer;	if (strcmp(p, "[IPC]") != 0 && strcmp(p, "[TCP]") != 0)	{		/* just an ordinary mailer */		return host;	}	/*	**  Look it up in the symbol table.	*/	s = stab(host, ST_HOSTSIG, ST_ENTER);	if (s->s_hostsig != NULL)		return s->s_hostsig;	/*	**  Not already there -- create a signature.	*/#if NAMED_BIND	if (ConfigLevel < 2)	{		oldoptions = _res.options;		_res.options &= ~(RES_DEFNAMES | RES_DNSRCH);	/* XXX */	}	for (hp = host; hp != NULL; hp = endp)	{		endp = strchr(hp, ':');		if (endp != NULL)			*endp = '\0';		nmx = getmxrr(hp, mxhosts, TRUE, &rcode);		if (nmx <= 0)		{			register MCI *mci;			/* update the connection info for this host */			mci = mci_get(hp, m);			mci->mci_exitstat = rcode;			mci->mci_errno = errno;#if NAMED_BIND			mci->mci_herrno = h_errno;#endif			/* and return the original host name as the signature */			nmx = 1;			mxhosts[0] = hp;		}		len = 0;		for (i = 0; i < nmx; i++)		{			len += strlen(mxhosts[i]) + 1;		}		if (s->s_hostsig != NULL)			len += strlen(s->s_hostsig) + 1;		p = xalloc(len);		if (s->s_hostsig != NULL)		{			(void) strcpy(p, s->s_hostsig);			free(s->s_hostsig);			s->s_hostsig = p;			p += strlen(p);			*p++ = ':';		}		else			s->s_hostsig = p;		for (i = 0; i < nmx; i++)		{			if (i != 0)				*p++ = ':';			strcpy(p, mxhosts[i]);			p += strlen(p);		}		if (endp != NULL)			*endp++ = ':';	}	makelower(s->s_hostsig);	if (ConfigLevel < 2)		_res.options = oldoptions;#else	/* not using BIND -- the signature is just the host name */	s->s_hostsig = host;#endif	if (tTd(17, 1))		printf("hostsignature(%s) = %s\n", host, s->s_hostsig);	return s->s_hostsig;}

⌨️ 快捷键说明

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