summaryrefslogtreecommitdiff
path: root/usr.sbin/sendmail/src/err.c
diff options
context:
space:
mode:
authorsvn2git <svn2git@FreeBSD.org>1994-05-01 08:00:00 +0000
committersvn2git <svn2git@FreeBSD.org>1994-05-01 08:00:00 +0000
commita16f65c7d117419bd266c28a1901ef129a337569 (patch)
tree2626602f66dc3551e7a7c7bc9ad763c3bc7ab40a /usr.sbin/sendmail/src/err.c
parent8503f4f13f77abf7adc8f7e329c6f9c1d52b6a20 (diff)
Diffstat (limited to 'usr.sbin/sendmail/src/err.c')
-rw-r--r--usr.sbin/sendmail/src/err.c166
1 files changed, 121 insertions, 45 deletions
diff --git a/usr.sbin/sendmail/src/err.c b/usr.sbin/sendmail/src/err.c
index 9ee17becf456..fee36c4b42af 100644
--- a/usr.sbin/sendmail/src/err.c
+++ b/usr.sbin/sendmail/src/err.c
@@ -33,12 +33,13 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)err.c 8.2 (Berkeley) 7/11/93";
+static char sccsid[] = "@(#)err.c 8.26 (Berkeley) 3/11/94";
#endif /* not lint */
# include "sendmail.h"
# include <errno.h>
# include <netdb.h>
+# include <pwd.h>
/*
** SYSERR -- Print error message.
@@ -64,13 +65,13 @@ static char sccsid[] = "@(#)err.c 8.2 (Berkeley) 7/11/93";
** sets ExitStat.
*/
-# ifdef lint
-int sys_nerr;
-char *sys_errlist[];
-# endif lint
char MsgBuf[BUFSIZ*2]; /* text of most recent message */
-static void fmtmsg();
+static void fmtmsg();
+
+#if NAMED_BIND && !defined(NO_DATA)
+# define NO_DATA NO_ADDRESS
+#endif
void
/*VARARGS1*/
@@ -85,6 +86,11 @@ syserr(fmt, va_alist)
register char *p;
int olderrno = errno;
bool panic;
+#ifdef LOG
+ char *uname;
+ struct passwd *pw;
+ char ubuf[80];
+#endif
VA_LOCAL_DECL
panic = *fmt == '!';
@@ -108,14 +114,30 @@ syserr(fmt, va_alist)
ExitStat = EX_SOFTWARE;
else
ExitStat = EX_OSERR;
+ if (tTd(54, 1))
+ printf("syserr: ExitStat = %d\n", ExitStat);
}
# ifdef LOG
+ pw = getpwuid(getuid());
+ if (pw != NULL)
+ uname = pw->pw_name;
+ else
+ {
+ uname = ubuf;
+ sprintf(ubuf, "UID%d", getuid());
+ }
+
if (LogLevel > 0)
- syslog(panic ? LOG_ALERT : LOG_CRIT, "%s: SYSERR: %s",
+ syslog(panic ? LOG_ALERT : LOG_CRIT, "%s: SYSERR(%s): %s",
CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id,
- &MsgBuf[4]);
+ uname, &MsgBuf[4]);
# endif /* LOG */
+ if (olderrno == EMFILE)
+ {
+ printopenfds(TRUE);
+ mci_dump_all(TRUE);
+ }
if (panic)
{
#ifdef XLA
@@ -154,8 +176,6 @@ usrerr(fmt, va_alist)
#endif
{
VA_LOCAL_DECL
- extern char SuprErrs;
- extern int errno;
if (SuprErrs)
return;
@@ -265,29 +285,45 @@ putoutmsg(msg, holdmsg)
char *msg;
bool holdmsg;
{
+ /* display for debugging */
+ if (tTd(54, 8))
+ printf("--- %s%s\n", msg, holdmsg ? " (held)" : "");
+
/* output to transcript if serious */
- if (CurEnv->e_xfp != NULL && (msg[0] == '4' || msg[0] == '5'))
+ if (CurEnv->e_xfp != NULL && strchr("456", msg[0]) != NULL)
fprintf(CurEnv->e_xfp, "%s\n", msg);
/* output to channel if appropriate */
if (holdmsg || (!Verbose && msg[0] == '0'))
return;
+ /* map warnings to something SMTP can handle */
+ if (msg[0] == '6')
+ msg[0] = '5';
+
(void) fflush(stdout);
- if (OpMode == MD_SMTP)
+
+ /* 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", getpid(),
- OpMode == MD_SMTP ? msg : &msg[4]);
+ (OpMode == MD_SMTP || OpMode == MD_DAEMON) ? msg : &msg[4]);
if (msg[3] == ' ')
(void) fflush(OutChannel);
- if (!ferror(OutChannel))
+ if (!ferror(OutChannel) || DisConnected)
return;
- /* error on output -- if reporting lost channel, just ignore it */
- if (feof(InChannel) || ferror(InChannel))
+ /*
+ ** 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 (feof(InChannel) || ferror(InChannel) || strncmp(msg, "221", 3) == 0)
return;
/* can't call syserr, 'cause we are using MsgBuf */
@@ -295,9 +331,10 @@ putoutmsg(msg, holdmsg)
#ifdef LOG
if (LogLevel > 0)
syslog(LOG_CRIT,
- "%s: SYSERR: putoutmsg (%s): error on output channel sending \"%s\"",
+ "%s: SYSERR: putoutmsg (%s): error on output channel sending \"%s\": %m",
CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id,
- CurHostName, msg);
+ CurHostName == NULL ? "NO-HOST" : CurHostName,
+ msg);
#endif
}
/*
@@ -316,13 +353,23 @@ putoutmsg(msg, holdmsg)
puterrmsg(msg)
char *msg;
{
+ char msgcode = msg[0];
+
/* output the message as usual */
putoutmsg(msg, HoldErrs);
/* signal the error */
Errors++;
- if (msg[0] == '5')
+ 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.
@@ -377,7 +424,7 @@ fmtmsg(eb, to, num, eno, fmt, ap)
/* output the "to" person */
if (to != NULL && to[0] != '\0')
{
- (void) sprintf(eb, "%s... ", to);
+ (void) sprintf(eb, "%s... ", shortenstring(to, 203));
while (*eb != '\0')
*eb++ &= 0177;
}
@@ -396,46 +443,53 @@ fmtmsg(eb, to, num, eno, fmt, ap)
eb += strlen(eb);
}
- if (CurEnv->e_message == NULL && strchr("45", num[0]) != NULL)
+ if (num[0] == '5' || (CurEnv->e_message == NULL && num[0] == '4'))
+ {
+ if (CurEnv->e_message != NULL)
+ free(CurEnv->e_message);
CurEnv->e_message = newstr(meb);
+ }
}
/*
** ERRSTRING -- return string description of error code
**
** Parameters:
-** errno -- the error number to translate
+** errnum -- the error number to translate
**
** Returns:
-** A string description of errno.
+** A string description of errnum.
**
** Side Effects:
** none.
*/
const char *
-errstring(errno)
- int errno;
+errstring(errnum)
+ int errnum;
{
- extern const char *const sys_errlist[];
- extern int sys_nerr;
+ char *dnsmsg;
static char buf[MAXLINE];
+# ifndef ERRLIST_PREDEFINED
+ extern char *sys_errlist[];
+ extern int sys_nerr;
+# endif
# ifdef SMTP
extern char *SmtpPhase;
# endif /* SMTP */
-# ifdef DAEMON
-# ifdef ETIMEDOUT
/*
** Handle special network error codes.
**
** These are 4.2/4.3bsd specific; they should be in daemon.c.
*/
- switch (errno)
+ dnsmsg = NULL;
+ switch (errnum)
{
+# if defined(DAEMON) && defined(ETIMEDOUT)
case ETIMEDOUT:
case ECONNRESET:
- (void) strcpy(buf, sys_errlist[errno]);
+ (void) strcpy(buf, sys_errlist[errnum]);
if (SmtpPhase != NULL)
{
(void) strcat(buf, " during ");
@@ -459,27 +513,49 @@ errstring(errno)
break;
(void) sprintf(buf, "Connection refused by %s", CurHostName);
return (buf);
+# endif
-# ifdef NAMED_BIND
- case HOST_NOT_FOUND + MAX_ERRNO:
- return ("Name server: host not found");
+ case EOPENTIMEOUT:
+ return "Timeout on file open";
- case TRY_AGAIN + MAX_ERRNO:
- return ("Name server: host name lookup failure");
+# if NAMED_BIND
+ case HOST_NOT_FOUND + E_DNSBASE:
+ dnsmsg = "host not found";
+ break;
- case NO_RECOVERY + MAX_ERRNO:
- return ("Name server: non-recoverable error");
+ case TRY_AGAIN + E_DNSBASE:
+ dnsmsg = "host name lookup failure";
+ break;
- case NO_DATA + MAX_ERRNO:
- return ("Name server: no data known for name");
+ 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";
+ }
+
+ if (dnsmsg != NULL)
+ {
+ (void) strcpy(buf, "Name server: ");
+ if (CurHostName != NULL)
+ {
+ (void) strcat(buf, CurHostName);
+ (void) strcat(buf, ": ");
+ }
+ (void) strcat(buf, dnsmsg);
+ return buf;
}
-# endif
-# endif
- if (errno > 0 && errno < sys_nerr)
- return (sys_errlist[errno]);
+ if (errnum > 0 && errnum < sys_nerr)
+ return (sys_errlist[errnum]);
- (void) sprintf(buf, "Error %d", errno);
+ (void) sprintf(buf, "Error %d", errnum);
return (buf);
}