summaryrefslogtreecommitdiff
path: root/src/err.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/err.c')
-rw-r--r--src/err.c767
1 files changed, 0 insertions, 767 deletions
diff --git a/src/err.c b/src/err.c
deleted file mode 100644
index 1a875a2..0000000
--- a/src/err.c
+++ /dev/null
@@ -1,767 +0,0 @@
-/*
- * Copyright (c) 1998 Sendmail, Inc. 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 sccsid[] = "@(#)err.c 8.74 (Berkeley) 6/4/1998";
-#endif /* not lint */
-
-# include "sendmail.h"
-# include <errno.h>
-
-/*
-** 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 */
-char HeldMessageBuf[sizeof MsgBuf]; /* for held messages */
-
-extern void putoutmsg __P((char *, bool, bool));
-extern void puterrmsg __P((char *));
-static void fmtmsg __P((char *, const char *, const char *, int, const char *, va_list));
-
-#if NAMED_BIND && !defined(NO_DATA)
-# define NO_DATA NO_ADDRESS
-#endif
-
-void
-/*VARARGS1*/
-#ifdef __STDC__
-syserr(const char *fmt, ...)
-#else
-syserr(fmt, va_alist)
- const char *fmt;
- va_dcl
-#endif
-{
- register char *p;
- int olderrno = errno;
- bool panic;
- char *uname;
- struct passwd *pw;
- char ubuf[80];
- VA_LOCAL_DECL
-
- panic = *fmt == '!';
- if (panic)
- {
- fmt++;
- HoldErrs = FALSE;
- }
-
- /* format and output the error message */
- if (olderrno == 0)
- p = "554";
- else
- p = "451";
- VA_START(fmt);
- fmtmsg(MsgBuf, (char *) NULL, p, olderrno, 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(MsgBuf + 4);
- }
-
- /* determine exit status if not already set */
- if (ExitStat == EX_OK)
- {
- if (olderrno == 0)
- ExitStat = EX_SOFTWARE;
- else
- ExitStat = EX_OSERR;
- if (tTd(54, 1))
- printf("syserr: ExitStat = %d\n", ExitStat);
- }
-
- pw = sm_getpwuid(getuid());
- if (pw != NULL)
- uname = pw->pw_name;
- else
- {
- uname = ubuf;
- snprintf(ubuf, sizeof ubuf, "UID%d", getuid());
- }
-
- if (LogLevel > 0)
- sm_syslog(panic ? LOG_ALERT : LOG_CRIT,
- CurEnv == NULL ? NOQID : CurEnv->e_id,
- "SYSERR(%s): %.900s",
- uname, &MsgBuf[4]);
- switch (olderrno)
- {
- case EBADF:
- case ENFILE:
- case EMFILE:
- case ENOTTY:
-#ifdef EFBIG
- case EFBIG:
-#endif
-#ifdef ESPIPE
- case ESPIPE:
-#endif
-#ifdef EPIPE
- case EPIPE:
-#endif
-#ifdef ENOBUFS
- case ENOBUFS:
-#endif
-#ifdef ESTALE
- case ESTALE:
-#endif
- printopenfds(TRUE);
- mci_dump_all(TRUE);
- break;
- }
- if (panic)
- {
-#ifdef XLA
- xla_all_end();
-#endif
- 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
-usrerr(fmt, va_alist)
- const char *fmt;
- va_dcl
-#endif
-{
- VA_LOCAL_DECL
-
- if (SuprErrs)
- return;
-
- VA_START(fmt);
- fmtmsg(MsgBuf, CurEnv->e_to, "501", 0, fmt, ap);
- VA_END;
-
- /* save this message for mailq printing */
- switch (MsgBuf[0])
- {
- case '4':
- case '8':
- if (CurEnv->e_message != NULL)
- break;
-
- /* fall through.... */
-
- 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",
- sizeof buf - 22, MsgBuf + 4);
- CurEnv->e_message = newstr(buf);
- }
- else
- {
- CurEnv->e_message = newstr(MsgBuf + 4);
- }
- break;
- }
-
- puterrmsg(MsgBuf);
-
- if (LogLevel > 3 && LogUsrErrs)
- sm_syslog(LOG_NOTICE, CurEnv->e_id,
- "%.900s",
- &MsgBuf[4]);
-
- 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
-message(msg, va_alist)
- const char *msg;
- va_dcl
-#endif
-{
- VA_LOCAL_DECL
-
- errno = 0;
- VA_START(msg);
- fmtmsg(MsgBuf, CurEnv->e_to, "050", 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;
- /* fall through.... */
-
- case '5':
- if (CurEnv->e_message != NULL)
- free(CurEnv->e_message);
- CurEnv->e_message = newstr(MsgBuf + 4);
- 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
-nmessage(msg, va_alist)
- const char *msg;
- va_dcl
-#endif
-{
- VA_LOCAL_DECL
-
- errno = 0;
- VA_START(msg);
- fmtmsg(MsgBuf, (char *) NULL, "050", 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;
- /* fall through.... */
-
- case '5':
- if (CurEnv->e_message != NULL)
- free(CurEnv->e_message);
- CurEnv->e_message = newstr(MsgBuf + 4);
- 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.
-*/
-
-void
-putoutmsg(msg, holdmsg, heldmsg)
- char *msg;
- bool holdmsg;
- bool heldmsg;
-{
- char msgcode = msg[0];
-
- /* display for debugging */
- if (tTd(54, 8))
- printf("--- %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)
- {
- /* save for possible future display */
- msg[0] = msgcode;
- snprintf(HeldMessageBuf, sizeof HeldMessageBuf, "%s", msg);
- return;
- }
-
- (void) fflush(stdout);
-
- if (OutChannel == NULL)
- return;
-
- /* if DisConnected, OutChannel now points to the transcript */
- if (!DisConnected &&
- (OpMode == MD_SMTP || OpMode == MD_DAEMON || OpMode == MD_ARPAFTP))
- fprintf(OutChannel, "%s\r\n", msg);
- else
- fprintf(OutChannel, "%s\n", &msg[4]);
- if (TrafficLogFile != NULL)
- fprintf(TrafficLogFile, "%05d >>> %s\n", (int) getpid(),
- (OpMode == MD_SMTP || OpMode == MD_DAEMON) ? msg : &msg[4]);
- if (msg[3] == ' ')
- (void) fflush(OutChannel);
- if (!ferror(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 || feof(InChannel) || ferror(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, CurEnv->e_id,
- "SYSERR: putoutmsg (%s): error on output channel sending \"%s\": %s",
- CurHostName == NULL ? "NO-HOST" : CurHostName,
- shortenstring(msg, MAXSHORTSTR), errstring(errno));
-}
- /*
-** 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.
-*/
-
-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;
- }
-}
- /*
-** FMTMSG -- format a message into buffer.
-**
-** Parameters:
-** eb -- error buffer to get result.
-** to -- the recipient tag for this message.
-** num -- arpanet error number.
-** en -- the error number to display.
-** fmt -- format of string.
-** a, b, c, d, e -- arguments.
-**
-** Returns:
-** none.
-**
-** Side Effects:
-** none.
-*/
-
-static void
-fmtmsg(eb, to, num, eno, fmt, ap)
- register char *eb;
- const char *to;
- const char *num;
- int eno;
- const char *fmt;
- va_list ap;
-{
- char del;
- int l;
- int spaceleft = sizeof MsgBuf;
-
- /* output the reply code */
- if (isascii(fmt[0]) && isdigit(fmt[0]) &&
- isascii(fmt[1]) && isdigit(fmt[1]) &&
- isascii(fmt[2]) && isdigit(fmt[2]))
- {
- num = fmt;
- fmt += 4;
- }
- if (num[3] == '-')
- del = '-';
- else
- del = ' ';
- (void) snprintf(eb, spaceleft, "%3.3s%c", num, del);
- eb += 4;
- spaceleft -= 4;
-
- /* output the file name and line number */
- if (FileName != NULL)
- {
- (void) snprintf(eb, spaceleft, "%s: line %d: ",
- shortenstring(FileName, 83), LineNumber);
- eb += (l = strlen(eb));
- spaceleft -= l;
- }
-
- /* output the "to" person */
- if (to != NULL && to[0] != '\0' &&
- strncmp(num, "551", 3) != 0 &&
- strncmp(num, "251", 3) != 0)
- {
- (void) snprintf(eb, spaceleft, "%s... ",
- shortenstring(to, MAXSHORTSTR));
- spaceleft -= strlen(eb);
- while (*eb != '\0')
- *eb++ &= 0177;
- }
-
- /* output the message */
- (void) vsnprintf(eb, spaceleft, fmt, ap);
- spaceleft -= strlen(eb);
- while (*eb != '\0')
- *eb++ &= 0177;
-
- /* output the error code, if any */
- if (eno != 0)
- (void) snprintf(eb, spaceleft, ": %s", errstring(eno));
-}
- /*
-** 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;
-}
- /*
-** 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 *
-errstring(errnum)
- int errnum;
-{
- char *dnsmsg;
- char *bp;
- static char buf[MAXLINE];
-# if !HASSTRERROR && !defined(ERRLIST_PREDEFINED)
- extern char *sys_errlist[];
- extern int sys_nerr;
-# endif
-# if SMTP
- extern char *SmtpPhase;
-# endif /* SMTP */
-
- /*
- ** Handle special network error codes.
- **
- ** These are 4.2/4.3bsd specific; they should be in daemon.c.
- */
-
- dnsmsg = NULL;
- switch (errnum)
- {
-# if defined(DAEMON) && defined(ETIMEDOUT)
- case ETIMEDOUT:
- case ECONNRESET:
- bp = buf;
-#if HASSTRERROR
- snprintf(bp, SPACELEFT(buf, bp), "%s", strerror(errnum));
-#else
- if (errnum >= 0 && errnum < sys_nerr)
- snprintf(bp, SPACELEFT(buf, bp), "%s", sys_errlist[errnum]);
- else
- snprintf(bp, SPACELEFT(buf, bp), "Error %d", errnum);
-#endif
- bp += strlen(bp);
- if (CurHostName != NULL)
- {
- if (errnum == ETIMEDOUT)
- {
- snprintf(bp, SPACELEFT(buf, bp), " with ");
- bp += strlen(bp);
- }
- else
- {
- bp = buf;
- snprintf(bp, SPACELEFT(buf, bp),
- "Connection reset by ");
- bp += strlen(bp);
- }
- snprintf(bp, SPACELEFT(buf, bp), "%s",
- shortenstring(CurHostName, MAXSHORTSTR));
- bp += strlen(buf);
- }
- if (SmtpPhase != NULL)
- {
- snprintf(bp, SPACELEFT(buf, bp), " during %s",
- SmtpPhase);
- }
- return (buf);
-
- case EHOSTDOWN:
- if (CurHostName == NULL)
- break;
- (void) snprintf(buf, sizeof buf, "Host %s is down",
- shortenstring(CurHostName, MAXSHORTSTR));
- return (buf);
-
- case ECONNREFUSED:
- if (CurHostName == NULL)
- break;
- (void) snprintf(buf, sizeof buf, "Connection refused by %s",
- shortenstring(CurHostName, MAXSHORTSTR));
- return (buf);
-# endif
-
-# 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
-
- 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";
- }
-
- if (dnsmsg != NULL)
- {
- bp = buf;
- strcpy(bp, "Name server: ");
- bp += strlen(bp);
- if (CurHostName != NULL)
- {
- snprintf(bp, SPACELEFT(buf, bp), "%s: ",
- shortenstring(CurHostName, MAXSHORTSTR));
- bp += strlen(bp);
- }
- snprintf(bp, SPACELEFT(buf, bp), "%s", dnsmsg);
- return buf;
- }
-
-#if HASSTRERROR
- return strerror(errnum);
-#else
- if (errnum > 0 && errnum < sys_nerr)
- return (sys_errlist[errnum]);
-
- (void) snprintf(buf, sizeof buf, "Error %d", errnum);
- return (buf);
-#endif
-}