summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/src/err.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/src/err.c')
-rw-r--r--contrib/sendmail/src/err.c1158
1 files changed, 0 insertions, 1158 deletions
diff --git a/contrib/sendmail/src/err.c b/contrib/sendmail/src/err.c
deleted file mode 100644
index 5825666..0000000
--- a/contrib/sendmail/src/err.c
+++ /dev/null
@@ -1,1158 +0,0 @@
-/*
- * Copyright (c) 1998-2003 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.
- *
- */
-
-#include <sendmail.h>
-
-SM_RCSID("@(#)$Id: err.c,v 8.196 2006/11/10 23:14:08 ca Exp $")
-
-#if 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));
-
-/*
-** FATAL_ERROR -- handle a fatal exception
-**
-** This function is installed as the default exception handler
-** in the main sendmail process, and in all child processes
-** that we create. Its job is to handle exceptions that are not
-** handled at a lower level.
-**
-** The theory is that unhandled exceptions will be 'fatal' class
-** exceptions (with an "F:" prefix), such as the out-of-memory
-** exception "F:sm.heap". As such, they are handled by exiting
-** the process in exactly the same way that xalloc() in Sendmail 8.10
-** exits the process when it fails due to lack of memory:
-** we call syserr with a message beginning with "!".
-**
-** Parameters:
-** exc -- exception which is terminating this process
-**
-** Returns:
-** none
-*/
-
-void
-fatal_error(exc)
- SM_EXC_T *exc;
-{
- static char buf[256];
- SM_FILE_T f;
-
- /*
- ** This function may be called when the heap is exhausted.
- ** The following code writes the message for 'exc' into our
- ** static buffer without allocating memory or raising exceptions.
- */
-
- sm_strio_init(&f, buf, sizeof(buf));
- sm_exc_write(exc, &f);
- (void) sm_io_flush(&f, SM_TIME_DEFAULT);
-
- /*
- ** Terminate the process after logging an error and cleaning up.
- ** Problems:
- ** - syserr decides what class of error this is by looking at errno.
- ** That's no good; we should look at the exc structure.
- ** - The cleanup code should be moved out of syserr
- ** and into individual exception handlers
- ** that are part of the module they clean up after.
- */
-
- errno = ENOMEM;
- syserr("!%s", buf);
-}
-
-/*
-** SYSERR -- Print error message.
-**
-** Prints an error message via sm_io_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.
-**
-** If the first character of the syserr message is '!' or '@'
-** then syserr knows that the process is about to be terminated,
-** so the SMTP reply code defaults to 421. Otherwise, the
-** reply code defaults to 451 or 554, depending on errno.
-**
-** Parameters:
-** fmt -- the format string. An optional '!' or '@',
-** followed by an optional three-digit SMTP
-** reply code, followed by message text.
-** (others) -- parameters
-**
-** Returns:
-** none
-** Raises E:mta.quickabort 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;
- bool exiting;
- char *user;
- char *enhsc;
- char *errtxt;
- struct passwd *pw;
- char ubuf[80];
- SM_VA_LOCAL_DECL
-
- switch (*fmt)
- {
- case '!':
- ++fmt;
- panic = true;
- exiting = true;
- break;
- case '@':
- ++fmt;
- panic = false;
- exiting = true;
- break;
- default:
- panic = false;
- exiting = false;
- break;
- }
-
- /* format and output the error message */
- if (exiting)
- {
- /*
- ** Since we are terminating the process,
- ** we are aborting the entire SMTP session,
- ** rather than just the current transaction.
- */
-
- p = "421";
- enhsc = "4.0.0";
- }
- else if (save_errno == 0)
- {
- p = "554";
- enhsc = "5.0.0";
- }
- else
- {
- p = "451";
- enhsc = "4.0.0";
- }
- SM_VA_START(ap, fmt);
- errtxt = fmtmsg(MsgBuf, (char *) NULL, p, enhsc, save_errno, fmt, ap);
- SM_VA_END(ap);
- puterrmsg(MsgBuf);
-
- /* save this message for mailq printing */
- if (!panic && CurEnv != NULL)
- {
- char *nmsg = sm_rpool_strdup_x(CurEnv->e_rpool, errtxt);
-
- if (CurEnv->e_rpool == NULL && CurEnv->e_message != NULL)
- sm_free(CurEnv->e_message);
- CurEnv->e_message = nmsg;
- }
-
- /* 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))
- sm_dprintf("syserr: ExitStat = %d\n", ExitStat);
- }
-
- pw = sm_getpwuid(RealUid);
- if (pw != NULL)
- user = pw->pw_name;
- else
- {
- user = ubuf;
- (void) sm_snprintf(ubuf, sizeof(ubuf), "UID%d", (int) RealUid);
- }
-
- 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(smioout, true);
- break;
- }
- if (panic)
- {
-#if XLA
- xla_all_end();
-#endif /* XLA */
- sync_queue_time();
- if (tTd(0, 1))
- abort();
- exit(EX_OSERR);
- }
- errno = 0;
- if (QuickAbort)
- sm_exc_raisenew_x(&EtypeQuickAbort, 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, 550 is assumed.
-** (others) -- sm_io_printf strings
-**
-** Returns:
-** none
-** Raises E:mta.quickabort 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;
- SM_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;
- SM_VA_START(ap, fmt);
- errtxt = fmtmsg(MsgBuf, CurEnv->e_to, "550", enhsc, 0, fmt, ap);
- SM_VA_END(ap);
-
- 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_rpool == NULL && CurEnv->e_message != NULL)
- sm_free(CurEnv->e_message);
- if (MsgBuf[0] == '6')
- {
- char buf[MAXLINE];
-
- (void) sm_snprintf(buf, sizeof(buf),
- "Postmaster warning: %.*s",
- (int) sizeof(buf) - 22, errtxt);
- CurEnv->e_message =
- sm_rpool_strdup_x(CurEnv->e_rpool, buf);
- }
- else
- {
- CurEnv->e_message =
- sm_rpool_strdup_x(CurEnv->e_rpool, errtxt);
- }
- break;
- }
-
- puterrmsg(MsgBuf);
- if (LogLevel > 3 && LogUsrErrs)
- sm_syslog(LOG_NOTICE, CurEnv->e_id, "%.900s", errtxt);
- if (QuickAbort)
- sm_exc_raisenew_x(&EtypeQuickAbort, 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, 550 is assumed.
-** (others) -- sm_io_printf strings
-**
-** Returns:
-** none
-** Raises E:mta.quickabort 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;
- SM_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";
- }
- SM_VA_START(ap, fmt);
- errtxt = fmtmsg(MsgBuf, CurEnv->e_to, "550", enhsc, 0, fmt, ap);
- SM_VA_END(ap);
-
- 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_rpool == NULL && CurEnv->e_message != NULL)
- sm_free(CurEnv->e_message);
- if (MsgBuf[0] == '6')
- {
- char buf[MAXLINE];
-
- (void) sm_snprintf(buf, sizeof(buf),
- "Postmaster warning: %.*s",
- (int) sizeof(buf) - 22, errtxt);
- CurEnv->e_message =
- sm_rpool_strdup_x(CurEnv->e_rpool, buf);
- }
- else
- {
- CurEnv->e_message =
- sm_rpool_strdup_x(CurEnv->e_rpool, errtxt);
- }
- break;
- }
-
- puterrmsg(MsgBuf);
- if (LogLevel > 3 && LogUsrErrs)
- sm_syslog(LOG_NOTICE, CurEnv->e_id, "%.900s", errtxt);
- if (QuickAbort)
- sm_exc_raisenew_x(&EtypeQuickAbort, 1);
-}
-/*
-** MESSAGE -- print message (not necessarily an error)
-**
-** Parameters:
-** msg -- the message (sm_io_printf fmt) -- it can begin with
-** an SMTP reply code. If not, 050 is assumed.
-** (others) -- sm_io_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;
- SM_VA_LOCAL_DECL
-
- errno = 0;
- SM_VA_START(ap, msg);
- errtxt = fmtmsg(MsgBuf, CurEnv->e_to, "050", (char *) NULL, 0, msg, ap);
- SM_VA_END(ap);
- 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_rpool == NULL && CurEnv->e_message != NULL)
- sm_free(CurEnv->e_message);
- CurEnv->e_message =
- sm_rpool_strdup_x(CurEnv->e_rpool, errtxt);
- break;
- }
-}
-/*
-** NMESSAGE -- print message (not necessarily an error)
-**
-** Just like "message" except it never puts the to... tag on.
-**
-** Parameters:
-** msg -- the message (sm_io_printf fmt) -- if it begins
-** with a three digit SMTP reply code, that is used,
-** otherwise 050 is assumed.
-** (others) -- sm_io_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;
- SM_VA_LOCAL_DECL
-
- errno = 0;
- SM_VA_START(ap, msg);
- errtxt = fmtmsg(MsgBuf, (char *) NULL, "050",
- (char *) NULL, 0, msg, ap);
- SM_VA_END(ap);
- 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_rpool == NULL && CurEnv->e_message != NULL)
- sm_free(CurEnv->e_message);
- CurEnv->e_message = sm_rpool_strdup_x(CurEnv->e_rpool, 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 msgcode = msg[0];
- char *errtxt = msg;
- char *id;
-
- /* display for debugging */
- if (tTd(54, 8))
- sm_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';
- id = (CurEnv != NULL) ? CurEnv->e_id : NULL;
-
- /* output to transcript if serious */
- if (!heldmsg && CurEnv != NULL && CurEnv->e_xfp != NULL &&
- strchr("45", msg[0]) != NULL)
- (void) sm_io_fprintf(CurEnv->e_xfp, SM_TIME_DEFAULT, "%s\n",
- msg);
-
- if (LogLevel > 14 && (OpMode == MD_SMTP || OpMode == MD_DAEMON))
- sm_syslog(LOG_INFO, id,
- "--- %s%s%s", msg, holdmsg ? " (hold)" : "",
- heldmsg ? " (held)" : "");
-
- if (msgcode == '8')
- msg[0] = '0';
-
- /* output to channel if appropriate */
- if (!Verbose && msg[0] == '0')
- return;
- if (holdmsg)
- {
- /* save for possible future display */
- msg[0] = msgcode;
- if (HeldMessageBuf[0] == '5' && msgcode == '4')
- return;
- (void) sm_strlcpy(HeldMessageBuf, msg, sizeof(HeldMessageBuf));
- return;
- }
-
- (void) sm_io_flush(smioout, SM_TIME_DEFAULT);
-
- if (OutChannel == NULL)
- return;
-
- /* find actual text of error (after SMTP status codes) */
- if (ISSMTPREPLY(errtxt))
- {
- int l;
-
- errtxt += 4;
- l = isenhsc(errtxt, ' ');
- if (l <= 0)
- l = isenhsc(errtxt, '\0');
- if (l > 0)
- errtxt += l + 1;
- }
-
- /* if DisConnected, OutChannel now points to the transcript */
- if (!DisConnected &&
- (OpMode == MD_SMTP || OpMode == MD_DAEMON || OpMode == MD_ARPAFTP))
- (void) sm_io_fprintf(OutChannel, SM_TIME_DEFAULT, "%s\r\n",
- msg);
- else
- (void) sm_io_fprintf(OutChannel, SM_TIME_DEFAULT, "%s\n",
- errtxt);
- if (TrafficLogFile != NULL)
- (void) sm_io_fprintf(TrafficLogFile, SM_TIME_DEFAULT,
- "%05d >>> %s\n", (int) CurrentPid,
- (OpMode == MD_SMTP || OpMode == MD_DAEMON)
- ? msg : errtxt);
-#if !PIPELINING
- /* XXX can't flush here for SMTP pipelining */
- if (msg[3] == ' ')
- (void) sm_io_flush(OutChannel, SM_TIME_DEFAULT);
- if (!sm_io_error(OutChannel) || DisConnected)
- return;
-
- /*
- ** Error on output -- if reporting lost channel, just ignore it.
- ** Also, ignore errors from QUIT response (221 message) -- some
- ** rude servers don't read result.
- */
-
- if (InChannel == NULL || sm_io_eof(InChannel) ||
- sm_io_error(InChannel) || strncmp(msg, "221", 3) == 0)
- return;
-
- /* can't call syserr, 'cause we are using MsgBuf */
- HoldErrs = true;
- if (LogLevel > 0)
- sm_syslog(LOG_CRIT, id,
- "SYSERR: putoutmsg (%s): error on output channel sending \"%s\": %s",
- CURHOSTNAME,
- shortenstring(msg, MAXSHORTSTR), sm_errstring(errno));
-#endif /* !PIPELINING */
-}
-/*
-** PUTERRMSG -- like putoutmsg, but does special processing for error messages
-**
-** Parameters:
-** msg -- the message to output.
-**
-** Returns:
-** none.
-**
-** Side Effects:
-** Sets the fatal error bit in the envelope as appropriate.
-*/
-
-static void
-puterrmsg(msg)
- char *msg;
-{
- char msgcode = msg[0];
-
- /* output the message as usual */
- putoutmsg(msg, HoldErrs, false);
-
- /* be careful about multiple error messages */
- if (OnlyOneError)
- HoldErrs = true;
-
- /* signal the error */
- Errors++;
-
- if (CurEnv == NULL)
- return;
-
- if (msgcode == '6')
- {
- /* notify the postmaster */
- CurEnv->e_flags |= EF_PM_NOTIFY;
- }
- else if (msgcode == '5' && bitset(EF_GLOBALERRS, CurEnv->e_flags))
- {
- /* mark long-term fatal errors */
- CurEnv->e_flags |= EF_FATALERRS;
- }
-}
-/*
-** ISENHSC -- check whether a string contains an enhanced status code
-**
-** Parameters:
-** s -- string with possible enhanced status code.
-** delim -- delim for enhanced status code.
-**
-** Returns:
-** 0 -- no enhanced status code.
-** >4 -- length of enhanced status code.
-**
-** Side Effects:
-** none.
-*/
-int
-isenhsc(s, delim)
- const char *s;
- int delim;
-{
- int l, h;
-
- if (s == NULL)
- return 0;
- if (!((*s == '2' || *s == '4' || *s == '5') && s[1] == '.'))
- return 0;
- h = 0;
- l = 2;
- while (h < 3 && isascii(s[l + h]) && isdigit(s[l + h]))
- ++h;
- if (h == 0 || s[l + h] != '.')
- return 0;
- l += h + 1;
- h = 0;
- while (h < 3 && isascii(s[l + h]) && isdigit(s[l + h]))
- ++h;
- if (h == 0 || s[l + h] != delim)
- return 0;
- return l + h;
-}
-/*
-** EXTENHSC -- check and extract an enhanced status code
-**
-** Parameters:
-** s -- string with possible enhanced status code.
-** delim -- delim for enhanced status code.
-** e -- pointer to storage for enhanced status code.
-** must be != NULL and have space for at least
-** 10 characters ([245].[0-9]{1,3}.[0-9]{1,3})
-**
-** Returns:
-** 0 -- no enhanced status code.
-** >4 -- length of enhanced status code.
-**
-** Side Effects:
-** fills e with enhanced status code.
-*/
-
-int
-extenhsc(s, delim, e)
- const char *s;
- int delim;
- char *e;
-{
- int l, h;
-
- if (s == NULL)
- return 0;
- if (!((*s == '2' || *s == '4' || *s == '5') && s[1] == '.'))
- return 0;
- h = 0;
- l = 2;
- e[0] = s[0];
- e[1] = '.';
- while (h < 3 && isascii(s[l + h]) && isdigit(s[l + h]))
- {
- e[l + h] = s[l + h];
- ++h;
- }
- if (h == 0 || s[l + h] != '.')
- return 0;
- e[l + h] = '.';
- l += h + 1;
- h = 0;
- while (h < 3 && isascii(s[l + h]) && isdigit(s[l + h]))
- {
- e[l + h] = s[l + h];
- ++h;
- }
- if (h == 0 || s[l + h] != delim)
- return 0;
- e[l + h] = '\0';
- return l + h;
-}
-/*
-** FMTMSG -- format a message into buffer.
-**
-** Parameters:
-** eb -- error buffer to get result -- MUST BE MsgBuf.
-** to -- the recipient tag for this message.
-** num -- default three digit SMTP reply code.
-** enhsc -- enhanced status code.
-** en -- the error number to display.
-** fmt -- format of string.
-** ap -- arguments for fmt.
-**
-** Returns:
-** pointer to error text beyond status codes.
-**
-** Side Effects:
-** none.
-*/
-
-static char *
-fmtmsg(eb, to, num, enhsc, eno, fmt, ap)
- register char *eb;
- const char *to;
- const char *num;
- const char *enhsc;
- int eno;
- const char *fmt;
- SM_VA_LOCAL_DECL
-{
- char del;
- int l;
- int spaceleft = sizeof(MsgBuf);
- char *errtxt;
-
- /* output the reply code */
- if (ISSMTPCODE(fmt))
- {
- num = fmt;
- fmt += 4;
- }
- if (num[3] == '-')
- del = '-';
- else
- del = ' ';
- if (SoftBounce && num[0] == '5')
- {
- /* replace 5 by 4 */
- (void) sm_snprintf(eb, spaceleft, "4%2.2s%c", num + 1, del);
- }
- else
- (void) sm_snprintf(eb, spaceleft, "%3.3s%c", num, del);
- eb += 4;
- spaceleft -= 4;
-
- if ((l = isenhsc(fmt, ' ' )) > 0 && l < spaceleft - 4)
- {
- /* copy enh.status code including trailing blank */
- l++;
- (void) sm_strlcpy(eb, fmt, l + 1);
- eb += l;
- spaceleft -= l;
- fmt += l;
- }
- else if ((l = isenhsc(enhsc, '\0')) > 0 && l < spaceleft - 4)
- {
- /* copy enh.status code */
- (void) sm_strlcpy(eb, enhsc, l + 1);
- eb[l] = ' ';
- eb[++l] = '\0';
- eb += l;
- spaceleft -= l;
- }
- if (SoftBounce && eb[-l] == '5')
- {
- /* replace 5 by 4 */
- eb[-l] = '4';
- }
- errtxt = eb;
-
- /* output the file name and line number */
- if (FileName != NULL)
- {
- (void) sm_snprintf(eb, spaceleft, "%s: line %d: ",
- shortenstring(FileName, 83), LineNumber);
- eb += (l = strlen(eb));
- spaceleft -= l;
- }
-
- /*
- ** output the "to" address only if it is defined and one of the
- ** following codes is used:
- ** 050 internal notices, e.g., alias expansion
- ** 250 Ok
- ** 252 Cannot VRFY user, but will accept message and attempt delivery
- ** 450 Requested mail action not taken: mailbox unavailable
- ** 550 Requested action not taken: mailbox unavailable
- ** 553 Requested action not taken: mailbox name not allowed
- **
- ** Notice: this still isn't "the right thing", this code shouldn't
- ** (indirectly) depend on CurEnv->e_to.
- */
-
- if (to != NULL && to[0] != '\0' &&
- (strncmp(num, "050", 3) == 0 ||
- strncmp(num, "250", 3) == 0 ||
- strncmp(num, "252", 3) == 0 ||
- strncmp(num, "450", 3) == 0 ||
- strncmp(num, "550", 3) == 0 ||
- strncmp(num, "553", 3) == 0))
- {
- (void) sm_strlcpyn(eb, spaceleft, 2,
- shortenstring(to, MAXSHORTSTR), "... ");
- spaceleft -= strlen(eb);
- while (*eb != '\0')
- *eb++ &= 0177;
- }
-
- /* output the message */
- (void) sm_vsnprintf(eb, spaceleft, fmt, ap);
- spaceleft -= strlen(eb);
- while (*eb != '\0')
- *eb++ &= 0177;
-
- /* output the error code, if any */
- if (eno != 0)
- (void) sm_strlcpyn(eb, spaceleft, 2, ": ", sm_errstring(eno));
-
- return errtxt;
-}
-/*
-** BUFFER_ERRORS -- arrange to buffer future error messages
-**
-** Parameters:
-** none
-**
-** Returns:
-** none.
-*/
-
-void
-buffer_errors()
-{
- HeldMessageBuf[0] = '\0';
- HoldErrs = true;
-}
-/*
-** FLUSH_ERRORS -- flush the held error message buffer
-**
-** Parameters:
-** print -- if set, print the message, otherwise just
-** delete it.
-**
-** Returns:
-** none.
-*/
-
-void
-flush_errors(print)
- bool print;
-{
- if (print && HeldMessageBuf[0] != '\0')
- putoutmsg(HeldMessageBuf, false, true);
- HeldMessageBuf[0] = '\0';
- HoldErrs = false;
-}
-/*
-** SM_ERRSTRING -- return string description of error code
-**
-** Parameters:
-** errnum -- the error number to translate
-**
-** Returns:
-** A string description of errnum.
-**
-** Side Effects:
-** none.
-*/
-
-const char *
-sm_errstring(errnum)
- int errnum;
-{
- char *dnsmsg;
- char *bp;
- static char buf[MAXLINE];
-#if HASSTRERROR
- char *err;
- char errbuf[30];
-#endif /* HASSTRERROR */
-#if !HASSTRERROR && !defined(ERRLIST_PREDEFINED)
- extern char *sys_errlist[];
- extern int sys_nerr;
-#endif /* !HASSTRERROR && !defined(ERRLIST_PREDEFINED) */
-
- /*
- ** Handle special network error codes.
- **
- ** These are 4.2/4.3bsd specific; they should be in daemon.c.
- */
-
- dnsmsg = NULL;
- switch (errnum)
- {
- case ETIMEDOUT:
- case ECONNRESET:
- bp = buf;
-#if HASSTRERROR
- err = strerror(errnum);
- if (err == NULL)
- {
- (void) sm_snprintf(errbuf, sizeof(errbuf),
- "Error %d", errnum);
- err = errbuf;
- }
- (void) sm_strlcpy(bp, err, SPACELEFT(buf, bp));
-#else /* HASSTRERROR */
- if (errnum >= 0 && errnum < sys_nerr)
- (void) sm_strlcpy(bp, sys_errlist[errnum],
- SPACELEFT(buf, bp));
- else
- (void) sm_snprintf(bp, SPACELEFT(buf, bp),
- "Error %d", errnum);
-#endif /* HASSTRERROR */
- bp += strlen(bp);
- if (CurHostName != NULL)
- {
- if (errnum == ETIMEDOUT)
- {
- (void) sm_snprintf(bp, SPACELEFT(buf, bp),
- " with ");
- bp += strlen(bp);
- }
- else
- {
- bp = buf;
- (void) sm_snprintf(bp, SPACELEFT(buf, bp),
- "Connection reset by ");
- bp += strlen(bp);
- }
- (void) sm_strlcpy(bp,
- shortenstring(CurHostName, MAXSHORTSTR),
- SPACELEFT(buf, bp));
- bp += strlen(buf);
- }
- if (SmtpPhase != NULL)
- {
- (void) sm_snprintf(bp, SPACELEFT(buf, bp),
- " during %s", SmtpPhase);
- }
- return buf;
-
- case EHOSTDOWN:
- if (CurHostName == NULL)
- break;
- (void) sm_snprintf(buf, sizeof(buf), "Host %s is down",
- shortenstring(CurHostName, MAXSHORTSTR));
- return buf;
-
- case ECONNREFUSED:
- if (CurHostName == NULL)
- break;
- (void) sm_strlcpyn(buf, sizeof(buf), 2, "Connection refused by ",
- shortenstring(CurHostName, MAXSHORTSTR));
- return buf;
-
-#if NAMED_BIND
- case HOST_NOT_FOUND + E_DNSBASE:
- dnsmsg = "host not found";
- break;
-
- case TRY_AGAIN + E_DNSBASE:
- dnsmsg = "host name lookup failure";
- break;
-
- case NO_RECOVERY + E_DNSBASE:
- dnsmsg = "non-recoverable error";
- break;
-
- case NO_DATA + E_DNSBASE:
- dnsmsg = "no data known";
- break;
-#endif /* NAMED_BIND */
-
- case EPERM:
- /* SunOS gives "Not owner" -- this is the POSIX message */
- return "Operation not permitted";
-
- /*
- ** Error messages used internally in sendmail.
- */
-
- case E_SM_OPENTIMEOUT:
- return "Timeout on file open";
-
- case E_SM_NOSLINK:
- return "Symbolic links not allowed";
-
- case E_SM_NOHLINK:
- return "Hard links not allowed";
-
- case E_SM_REGONLY:
- return "Regular files only";
-
- case E_SM_ISEXEC:
- return "Executable files not allowed";
-
- case E_SM_WWDIR:
- return "World writable directory";
-
- case E_SM_GWDIR:
- return "Group writable directory";
-
- case E_SM_FILECHANGE:
- return "File changed after open";
-
- case E_SM_WWFILE:
- return "World writable file";
-
- case E_SM_GWFILE:
- return "Group writable file";
-
- case E_SM_GRFILE:
- return "Group readable file";
-
- case E_SM_WRFILE:
- return "World readable file";
- }
-
- if (dnsmsg != NULL)
- {
- bp = buf;
- bp += sm_strlcpy(bp, "Name server: ", sizeof(buf));
- if (CurHostName != NULL)
- {
- (void) sm_strlcpyn(bp, SPACELEFT(buf, bp), 2,
- shortenstring(CurHostName, MAXSHORTSTR), ": ");
- bp += strlen(bp);
- }
- (void) sm_strlcpy(bp, dnsmsg, SPACELEFT(buf, bp));
- return buf;
- }
-
-#if LDAPMAP
- if (errnum >= E_LDAPBASE)
- return ldap_err2string(errnum - E_LDAPBASE);
-#endif /* LDAPMAP */
-
-#if HASSTRERROR
- err = strerror(errnum);
- if (err == NULL)
- {
- (void) sm_snprintf(buf, sizeof(buf), "Error %d", errnum);
- return buf;
- }
- return err;
-#else /* HASSTRERROR */
- if (errnum > 0 && errnum < sys_nerr)
- return sys_errlist[errnum];
-
- (void) sm_snprintf(buf, sizeof(buf), "Error %d", errnum);
- return buf;
-#endif /* HASSTRERROR */
-}
OpenPOWER on IntegriCloud