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

📄 err.c

📁 < linux网络编程工具>>配套源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
 *	All rights reserved.
 * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
 * Copyright (c) 1988, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 *
 */

#ifndef lint
static char id[] = "@(#)$Id: err.c,v 8.120.4.1 2000/05/25 18:56:15 gshapiro Exp $";
#endif /* ! lint */

#include <sendmail.h>
#ifdef LDAPMAP
# include <lber.h>
# include <ldap.h>			/* for LDAP error codes */
#endif /* LDAPMAP */


static void	putoutmsg __P((char *, bool, bool));
static void	puterrmsg __P((char *));
static char	*fmtmsg __P((char *, const char *, const char *, const char *,
			     int, const char *, va_list));

/*
**  SYSERR -- Print error message.
**
**	Prints an error message via printf to the diagnostic output.
**
**	If the first character of the syserr message is `!' it will
**	log this as an ALERT message and exit immediately.  This can
**	leave queue files in an indeterminate state, so it should not
**	be used lightly.
**
**	Parameters:
**		fmt -- the format string.  If it does not begin with
**			a three-digit SMTP reply code, either 554 or
**			451 is assumed depending on whether errno
**			is set.
**		(others) -- parameters
**
**	Returns:
**		none
**		Through TopFrame if QuickAbort is set.
**
**	Side Effects:
**		increments Errors.
**		sets ExitStat.
*/

char		MsgBuf[BUFSIZ*2];	/* text of most recent message */
static char	HeldMessageBuf[sizeof MsgBuf];	/* for held messages */

#if NAMED_BIND && !defined(NO_DATA)
# define NO_DATA	NO_ADDRESS
#endif /* NAMED_BIND && !defined(NO_DATA) */

void
/*VARARGS1*/
#ifdef __STDC__
syserr(const char *fmt, ...)
#else /* __STDC__ */
syserr(fmt, va_alist)
	const char *fmt;
	va_dcl
#endif /* __STDC__ */
{
	register char *p;
	int save_errno = errno;
	bool panic;
	char *user;
	char *enhsc;
	char *errtxt;
	struct passwd *pw;
	char ubuf[80];
	VA_LOCAL_DECL

	panic = *fmt == '!';
	if (panic)
	{
		fmt++;
		HoldErrs = FALSE;
	}

	/* format and output the error message */
	if (save_errno == 0)
	{
		p = "554";
		enhsc = "5.0.0";
	}
	else
	{
		p = "451";
		enhsc = "4.0.0";
	}
	VA_START(fmt);
	errtxt = fmtmsg(MsgBuf, (char *) NULL, p, enhsc, save_errno, fmt, ap);
	VA_END;
	puterrmsg(MsgBuf);

	/* save this message for mailq printing */
	if (!panic && CurEnv != NULL)
	{
		if (CurEnv->e_message != NULL)
			free(CurEnv->e_message);
		CurEnv->e_message = newstr(errtxt);
	}

	/* determine exit status if not already set */
	if (ExitStat == EX_OK)
	{
		if (save_errno == 0)
			ExitStat = EX_SOFTWARE;
		else
			ExitStat = EX_OSERR;
		if (tTd(54, 1))
			dprintf("syserr: ExitStat = %d\n", ExitStat);
	}

	pw = sm_getpwuid(getuid());
	if (pw != NULL)
		user = pw->pw_name;
	else
	{
		user = ubuf;
		snprintf(ubuf, sizeof ubuf, "UID%d", (int) getuid());
	}

	if (LogLevel > 0)
		sm_syslog(panic ? LOG_ALERT : LOG_CRIT,
			  CurEnv == NULL ? NOQID : CurEnv->e_id,
			  "SYSERR(%s): %.900s",
			  user, errtxt);
	switch (save_errno)
	{
	  case EBADF:
	  case ENFILE:
	  case EMFILE:
	  case ENOTTY:
#ifdef EFBIG
	  case EFBIG:
#endif /* EFBIG */
#ifdef ESPIPE
	  case ESPIPE:
#endif /* ESPIPE */
#ifdef EPIPE
	  case EPIPE:
#endif /* EPIPE */
#ifdef ENOBUFS
	  case ENOBUFS:
#endif /* ENOBUFS */
#ifdef ESTALE
	  case ESTALE:
#endif /* ESTALE */


		printopenfds(TRUE);
		mci_dump_all(TRUE);
		break;
	}
	if (panic)
	{
#ifdef XLA
		xla_all_end();
#endif /* XLA */
		sync_queue_time();
		if (tTd(0, 1))
			abort();
		exit(EX_OSERR);
	}
	errno = 0;
	if (QuickAbort)
		longjmp(TopFrame, 2);
}
/*
**  USRERR -- Signal user error.
**
**	This is much like syserr except it is for user errors.
**
**	Parameters:
**		fmt -- the format string.  If it does not begin with
**			a three-digit SMTP reply code, 501 is assumed.
**		(others) -- printf strings
**
**	Returns:
**		none
**		Through TopFrame if QuickAbort is set.
**
**	Side Effects:
**		increments Errors.
*/

/*VARARGS1*/
void
#ifdef __STDC__
usrerr(const char *fmt, ...)
#else /* __STDC__ */
usrerr(fmt, va_alist)
	const char *fmt;
	va_dcl
#endif /* __STDC__ */
{
	char *enhsc;
	char *errtxt;
	VA_LOCAL_DECL

	if (fmt[0] == '5' || fmt[0] == '6')
		enhsc = "5.0.0";
	else if (fmt[0] == '4' || fmt[0] == '8')
		enhsc = "4.0.0";
	else if (fmt[0] == '2')
		enhsc = "2.0.0";
	else
		enhsc = NULL;
	VA_START(fmt);
	errtxt = fmtmsg(MsgBuf, CurEnv->e_to, "501", enhsc, 0, fmt, ap);
	VA_END;

	if (SuprErrs)
		return;

	/* save this message for mailq printing */
	switch (MsgBuf[0])
	{
	  case '4':
	  case '8':
		if (CurEnv->e_message != NULL)
			break;

		/* FALLTHROUGH */

	  case '5':
	  case '6':
		if (CurEnv->e_message != NULL)
			free(CurEnv->e_message);
		if (MsgBuf[0] == '6')
		{
			char buf[MAXLINE];

			snprintf(buf, sizeof buf, "Postmaster warning: %.*s",
				(int) sizeof buf - 22, errtxt);
			CurEnv->e_message = newstr(buf);
		}
		else
		{
			CurEnv->e_message = newstr(errtxt);
		}
		break;
	}

	puterrmsg(MsgBuf);

	if (LogLevel > 3 && LogUsrErrs)
		sm_syslog(LOG_NOTICE, CurEnv->e_id, "%.900s", errtxt);

	if (QuickAbort)
		longjmp(TopFrame, 1);
}
/*
**  USRERRENH -- Signal user error.
**
**	Same as usrerr but with enhanced status code.
**
**	Parameters:
**		enhsc -- the enhanced status code.
**		fmt -- the format string.  If it does not begin with
**			a three-digit SMTP reply code, 501 is assumed.
**		(others) -- printf strings
**
**	Returns:
**		none
**		Through TopFrame if QuickAbort is set.
**
**	Side Effects:
**		increments Errors.
*/

/*VARARGS1*/
void
#ifdef __STDC__
usrerrenh(char *enhsc, const char *fmt, ...)
#else /* __STDC__ */
usrerrenh(enhsc, fmt, va_alist)
	char *enhsc;
	const char *fmt;
	va_dcl
#endif /* __STDC__ */
{
	char *errtxt;
	VA_LOCAL_DECL

	if (enhsc == NULL || *enhsc == '\0')
	{
		if (fmt[0] == '5' || fmt[0] == '6')
			enhsc = "5.0.0";
		else if (fmt[0] == '4' || fmt[0] == '8')
			enhsc = "4.0.0";
		else if (fmt[0] == '2')
			enhsc = "2.0.0";
	}
	VA_START(fmt);
	errtxt = fmtmsg(MsgBuf, CurEnv->e_to, "501", enhsc, 0, fmt, ap);
	VA_END;

	if (SuprErrs)
		return;

	/* save this message for mailq printing */
	switch (MsgBuf[0])
	{
	  case '4':
	  case '8':
		if (CurEnv->e_message != NULL)
			break;

		/* FALLTHROUGH */

	  case '5':
	  case '6':
		if (CurEnv->e_message != NULL)
			free(CurEnv->e_message);
		if (MsgBuf[0] == '6')
		{
			char buf[MAXLINE];

			snprintf(buf, sizeof buf, "Postmaster warning: %.*s",
				(int) sizeof buf - 22, errtxt);
			CurEnv->e_message = newstr(buf);
		}
		else
		{
			CurEnv->e_message = newstr(errtxt);
		}
		break;
	}

	puterrmsg(MsgBuf);

	if (LogLevel > 3 && LogUsrErrs)
		sm_syslog(LOG_NOTICE, CurEnv->e_id, "%.900s", errtxt);

	if (QuickAbort)
		longjmp(TopFrame, 1);
}
/*
**  MESSAGE -- print message (not necessarily an error)
**
**	Parameters:
**		msg -- the message (printf fmt) -- it can begin with
**			an SMTP reply code.  If not, 050 is assumed.
**		(others) -- printf arguments
**
**	Returns:
**		none
**
**	Side Effects:
**		none.
*/

/*VARARGS1*/
void
#ifdef __STDC__
message(const char *msg, ...)
#else /* __STDC__ */
message(msg, va_alist)
	const char *msg;
	va_dcl
#endif /* __STDC__ */
{
	char *errtxt;
	VA_LOCAL_DECL

	errno = 0;
	VA_START(msg);
	errtxt = fmtmsg(MsgBuf, CurEnv->e_to, "050", (char *) NULL, 0, msg, ap);
	VA_END;
	putoutmsg(MsgBuf, FALSE, FALSE);

	/* save this message for mailq printing */
	switch (MsgBuf[0])
	{
	  case '4':
	  case '8':
		if (CurEnv->e_message != NULL)
			break;
		/* FALLTHROUGH */

	  case '5':
		if (CurEnv->e_message != NULL)
			free(CurEnv->e_message);
		CurEnv->e_message = newstr(errtxt);
		break;
	}
}
/*
**  NMESSAGE -- print message (not necessarily an error)
**
**	Just like "message" except it never puts the to... tag on.
**
**	Parameters:
**		msg -- the message (printf fmt) -- if it begins
**			with a three digit SMTP reply code, that is used,
**			otherwise 050 is assumed.
**		(others) -- printf arguments
**
**	Returns:
**		none
**
**	Side Effects:
**		none.
*/

/*VARARGS1*/
void
#ifdef __STDC__
nmessage(const char *msg, ...)
#else /* __STDC__ */
nmessage(msg, va_alist)
	const char *msg;
	va_dcl
#endif /* __STDC__ */
{
	char *errtxt;
	VA_LOCAL_DECL

	errno = 0;
	VA_START(msg);
	errtxt = fmtmsg(MsgBuf, (char *) NULL, "050",
			(char *) NULL, 0, msg, ap);
	VA_END;
	putoutmsg(MsgBuf, FALSE, FALSE);

	/* save this message for mailq printing */
	switch (MsgBuf[0])
	{
	  case '4':
	  case '8':
		if (CurEnv->e_message != NULL)
			break;
		/* FALLTHROUGH */

	  case '5':
		if (CurEnv->e_message != NULL)
			free(CurEnv->e_message);
		CurEnv->e_message = newstr(errtxt);
		break;
	}
}
/*
**  PUTOUTMSG -- output error message to transcript and channel
**
**	Parameters:
**		msg -- message to output (in SMTP format).
**		holdmsg -- if TRUE, don't output a copy of the message to
**			our output channel.
**		heldmsg -- if TRUE, this is a previously held message;
**			don't log it to the transcript file.
**
**	Returns:
**		none.
**
**	Side Effects:
**		Outputs msg to the transcript.
**		If appropriate, outputs it to the channel.
**		Deletes SMTP reply code number as appropriate.
*/

static void
putoutmsg(msg, holdmsg, heldmsg)
	char *msg;
	bool holdmsg;
	bool heldmsg;
{
	char *errtxt = msg;
	char msgcode = msg[0];

	/* display for debugging */
	if (tTd(54, 8))
		dprintf("--- %s%s%s\n", msg, holdmsg ? " (hold)" : "",
			heldmsg ? " (held)" : "");

	/* map warnings to something SMTP can handle */
	if (msgcode == '6')
		msg[0] = '5';
	else if (msgcode == '8')
		msg[0] = '4';

	/* output to transcript if serious */
	if (!heldmsg && CurEnv != NULL && CurEnv->e_xfp != NULL &&
	    strchr("45", msg[0]) != NULL)
		fprintf(CurEnv->e_xfp, "%s\n", msg);

	if (LogLevel >= 15 && (OpMode == MD_SMTP || OpMode == MD_DAEMON))
		sm_syslog(LOG_INFO, CurEnv->e_id,
			  "--> %s%s",
			  msg, holdmsg ? " (held)" : "");

	if (msgcode == '8')
		msg[0] = '0';

	/* output to channel if appropriate */
	if (!Verbose && msg[0] == '0')
		return;
	if (holdmsg)
	{

⌨️ 快捷键说明

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