diff options
Diffstat (limited to 'contrib/sendmail/src/err.c')
-rw-r--r-- | contrib/sendmail/src/err.c | 438 |
1 files changed, 93 insertions, 345 deletions
diff --git a/contrib/sendmail/src/err.c b/contrib/sendmail/src/err.c index 78b5c5d..38a3576 100644 --- a/contrib/sendmail/src/err.c +++ b/contrib/sendmail/src/err.c @@ -1,6 +1,5 @@ /* - * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers. - * All rights reserved. + * 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. @@ -12,20 +11,11 @@ */ #ifndef lint -static char id[] = "@(#)$Id: err.c,v 8.120.4.1 2000/05/25 18:56:15 gshapiro Exp $"; -#endif /* ! lint */ +static char sccsid[] = "@(#)err.c 8.74 (Berkeley) 6/4/1998"; +#endif /* not 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)); +# include "sendmail.h" +# include <errno.h> /* ** SYSERR -- Print error message. @@ -53,29 +43,31 @@ static char *fmtmsg __P((char *, const char *, const char *, const char *, ** sets ExitStat. */ -char MsgBuf[BUFSIZ*2]; /* text of most recent message */ -static char HeldMessageBuf[sizeof MsgBuf]; /* for held messages */ +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 /* NAMED_BIND && !defined(NO_DATA) */ +#endif void /*VARARGS1*/ #ifdef __STDC__ syserr(const char *fmt, ...) -#else /* __STDC__ */ +#else syserr(fmt, va_alist) const char *fmt; va_dcl -#endif /* __STDC__ */ +#endif { register char *p; - int save_errno = errno; + int olderrno = errno; bool panic; - char *user; - char *enhsc; - char *errtxt; + char *uname; struct passwd *pw; char ubuf[80]; VA_LOCAL_DECL @@ -88,18 +80,12 @@ syserr(fmt, va_alist) } /* format and output the error message */ - if (save_errno == 0) - { + if (olderrno == 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); + fmtmsg(MsgBuf, (char *) NULL, p, olderrno, fmt, ap); VA_END; puterrmsg(MsgBuf); @@ -108,35 +94,35 @@ syserr(fmt, va_alist) { if (CurEnv->e_message != NULL) free(CurEnv->e_message); - CurEnv->e_message = newstr(errtxt); + CurEnv->e_message = newstr(MsgBuf + 4); } /* determine exit status if not already set */ if (ExitStat == EX_OK) { - if (save_errno == 0) + if (olderrno == 0) ExitStat = EX_SOFTWARE; else ExitStat = EX_OSERR; if (tTd(54, 1)) - dprintf("syserr: ExitStat = %d\n", ExitStat); + printf("syserr: ExitStat = %d\n", ExitStat); } pw = sm_getpwuid(getuid()); if (pw != NULL) - user = pw->pw_name; + uname = pw->pw_name; else { - user = ubuf; - snprintf(ubuf, sizeof ubuf, "UID%d", (int) getuid()); + 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", - user, errtxt); - switch (save_errno) + uname, &MsgBuf[4]); + switch (olderrno) { case EBADF: case ENFILE: @@ -144,21 +130,19 @@ syserr(fmt, va_alist) case ENOTTY: #ifdef EFBIG case EFBIG: -#endif /* EFBIG */ +#endif #ifdef ESPIPE case ESPIPE: -#endif /* ESPIPE */ +#endif #ifdef EPIPE case EPIPE: -#endif /* EPIPE */ +#endif #ifdef ENOBUFS case ENOBUFS: -#endif /* ENOBUFS */ +#endif #ifdef ESTALE case ESTALE: -#endif /* ESTALE */ - - +#endif printopenfds(TRUE); mci_dump_all(TRUE); break; @@ -167,8 +151,7 @@ syserr(fmt, va_alist) { #ifdef XLA xla_all_end(); -#endif /* XLA */ - sync_queue_time(); +#endif if (tTd(0, 1)) abort(); exit(EX_OSERR); @@ -199,117 +182,21 @@ syserr(fmt, va_alist) void #ifdef __STDC__ usrerr(const char *fmt, ...) -#else /* __STDC__ */ +#else usrerr(fmt, va_alist) const char *fmt; va_dcl -#endif /* __STDC__ */ +#endif { - 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); + fmtmsg(MsgBuf, CurEnv->e_to, "501", 0, fmt, ap); VA_END; - if (SuprErrs) - return; - /* save this message for mailq printing */ switch (MsgBuf[0]) { @@ -318,7 +205,7 @@ usrerrenh(enhsc, fmt, va_alist) if (CurEnv->e_message != NULL) break; - /* FALLTHROUGH */ + /* fall through.... */ case '5': case '6': @@ -329,12 +216,12 @@ usrerrenh(enhsc, fmt, va_alist) char buf[MAXLINE]; snprintf(buf, sizeof buf, "Postmaster warning: %.*s", - (int) sizeof buf - 22, errtxt); + (int)sizeof buf - 22, MsgBuf + 4); CurEnv->e_message = newstr(buf); } else { - CurEnv->e_message = newstr(errtxt); + CurEnv->e_message = newstr(MsgBuf + 4); } break; } @@ -342,7 +229,9 @@ usrerrenh(enhsc, fmt, va_alist) puterrmsg(MsgBuf); if (LogLevel > 3 && LogUsrErrs) - sm_syslog(LOG_NOTICE, CurEnv->e_id, "%.900s", errtxt); + sm_syslog(LOG_NOTICE, CurEnv->e_id, + "%.900s", + &MsgBuf[4]); if (QuickAbort) longjmp(TopFrame, 1); @@ -366,18 +255,17 @@ usrerrenh(enhsc, fmt, va_alist) void #ifdef __STDC__ message(const char *msg, ...) -#else /* __STDC__ */ +#else message(msg, va_alist) const char *msg; va_dcl -#endif /* __STDC__ */ +#endif { - char *errtxt; VA_LOCAL_DECL errno = 0; VA_START(msg); - errtxt = fmtmsg(MsgBuf, CurEnv->e_to, "050", (char *) NULL, 0, msg, ap); + fmtmsg(MsgBuf, CurEnv->e_to, "050", 0, msg, ap); VA_END; putoutmsg(MsgBuf, FALSE, FALSE); @@ -388,12 +276,12 @@ message(msg, va_alist) case '8': if (CurEnv->e_message != NULL) break; - /* FALLTHROUGH */ + /* fall through.... */ case '5': if (CurEnv->e_message != NULL) free(CurEnv->e_message); - CurEnv->e_message = newstr(errtxt); + CurEnv->e_message = newstr(MsgBuf + 4); break; } } @@ -419,19 +307,17 @@ message(msg, va_alist) void #ifdef __STDC__ nmessage(const char *msg, ...) -#else /* __STDC__ */ +#else nmessage(msg, va_alist) const char *msg; va_dcl -#endif /* __STDC__ */ +#endif { - char *errtxt; VA_LOCAL_DECL errno = 0; VA_START(msg); - errtxt = fmtmsg(MsgBuf, (char *) NULL, "050", - (char *) NULL, 0, msg, ap); + fmtmsg(MsgBuf, (char *) NULL, "050", 0, msg, ap); VA_END; putoutmsg(MsgBuf, FALSE, FALSE); @@ -442,12 +328,12 @@ nmessage(msg, va_alist) case '8': if (CurEnv->e_message != NULL) break; - /* FALLTHROUGH */ + /* fall through.... */ case '5': if (CurEnv->e_message != NULL) free(CurEnv->e_message); - CurEnv->e_message = newstr(errtxt); + CurEnv->e_message = newstr(MsgBuf + 4); break; } } @@ -470,18 +356,17 @@ nmessage(msg, va_alist) ** Deletes SMTP reply code number as appropriate. */ -static void +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)" : "", + printf("--- %s%s%s\n", msg, holdmsg ? " (hold)" : "", heldmsg ? " (held)" : ""); /* map warnings to something SMTP can handle */ @@ -497,8 +382,8 @@ putoutmsg(msg, holdmsg, heldmsg) if (LogLevel >= 15 && (OpMode == MD_SMTP || OpMode == MD_DAEMON)) sm_syslog(LOG_INFO, CurEnv->e_id, - "--> %s%s", - msg, holdmsg ? " (held)" : ""); + "--> %s%s", + msg, holdmsg ? " (held)" : ""); if (msgcode == '8') msg[0] = '0'; @@ -510,8 +395,6 @@ putoutmsg(msg, holdmsg, heldmsg) { /* save for possible future display */ msg[0] = msgcode; - if (HeldMessageBuf[0] == '5' && msgcode == '4') - return; snprintf(HeldMessageBuf, sizeof HeldMessageBuf, "%s", msg); return; } @@ -520,29 +403,16 @@ putoutmsg(msg, holdmsg, heldmsg) 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)) fprintf(OutChannel, "%s\r\n", msg); else - fprintf(OutChannel, "%s\n", errtxt); + fprintf(OutChannel, "%s\n", &msg[4]); if (TrafficLogFile != NULL) fprintf(TrafficLogFile, "%05d >>> %s\n", (int) getpid(), - (OpMode == MD_SMTP || OpMode == MD_DAEMON) ? msg : errtxt); + (OpMode == MD_SMTP || OpMode == MD_DAEMON) ? msg : &msg[4]); if (msg[3] == ' ') (void) fflush(OutChannel); if (!ferror(OutChannel) || DisConnected) @@ -562,9 +432,9 @@ putoutmsg(msg, holdmsg, heldmsg) 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)); + "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 @@ -579,7 +449,7 @@ putoutmsg(msg, holdmsg, heldmsg) ** Sets the fatal error bit in the envelope as appropriate. */ -static void +void puterrmsg(msg) char *msg; { @@ -597,7 +467,7 @@ puterrmsg(msg) if (CurEnv == NULL) return; - + if (msgcode == '6') { /* notify the postmaster */ @@ -610,122 +480,28 @@ puterrmsg(msg) } } /* -** 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. +** eb -- error buffer to get result. ** to -- the recipient tag for this message. -** num -- default three digit SMTP reply code. -** enhsc -- enhanced status code. +** num -- arpanet error number. ** en -- the error number to display. ** fmt -- format of string. -** ap -- arguments for fmt. +** a, b, c, d, e -- arguments. ** ** Returns: -** pointer to error text beyond status codes. +** none. ** ** Side Effects: ** none. */ -static char * -fmtmsg(eb, to, num, enhsc, eno, fmt, ap) +static void +fmtmsg(eb, to, num, eno, fmt, ap) register char *eb; const char *to; const char *num; - const char *enhsc; int eno; const char *fmt; va_list ap; @@ -733,10 +509,11 @@ fmtmsg(eb, to, num, enhsc, eno, fmt, ap) char del; int l; int spaceleft = sizeof MsgBuf; - char *errtxt; /* output the reply code */ - if (ISSMTPCODE(fmt)) + if (isascii(fmt[0]) && isdigit(fmt[0]) && + isascii(fmt[1]) && isdigit(fmt[1]) && + isascii(fmt[2]) && isdigit(fmt[2])) { num = fmt; fmt += 4; @@ -749,26 +526,6 @@ fmtmsg(eb, to, num, enhsc, eno, fmt, ap) eb += 4; spaceleft -= 4; - if ((l = isenhsc(fmt, ' ' )) > 0 && l < spaceleft - 4) - { - /* copy enh.status code including trailing blank */ - l++; - (void) 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) strlcpy(eb, enhsc, l + 1); - eb[l] = ' '; - eb[++l] = '\0'; - eb += l; - spaceleft -= l; - } - errtxt = eb; - /* output the file name and line number */ if (FileName != NULL) { @@ -799,8 +556,6 @@ fmtmsg(eb, to, num, enhsc, eno, fmt, ap) /* output the error code, if any */ if (eno != 0) (void) snprintf(eb, spaceleft, ": %s", errstring(eno)); - - return errtxt; } /* ** BUFFER_ERRORS -- arrange to buffer future error messages @@ -858,10 +613,13 @@ errstring(errnum) char *dnsmsg; char *bp; static char buf[MAXLINE]; -#if !HASSTRERROR && !defined(ERRLIST_PREDEFINED) +# if !HASSTRERROR && !defined(ERRLIST_PREDEFINED) extern char *sys_errlist[]; extern int sys_nerr; -#endif /* !HASSTRERROR && !defined(ERRLIST_PREDEFINED) */ +# endif +# if SMTP + extern char *SmtpPhase; +# endif /* SMTP */ /* ** Handle special network error codes. @@ -872,18 +630,18 @@ errstring(errnum) dnsmsg = NULL; switch (errnum) { -#if defined(DAEMON) && defined(ETIMEDOUT) +# if defined(DAEMON) && defined(ETIMEDOUT) case ETIMEDOUT: case ECONNRESET: bp = buf; -# if HASSTRERROR +#if HASSTRERROR snprintf(bp, SPACELEFT(buf, bp), "%s", strerror(errnum)); -# else /* HASSTRERROR */ +#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 /* HASSTRERROR */ +#endif bp += strlen(bp); if (CurHostName != NULL) { @@ -908,24 +666,24 @@ errstring(errnum) snprintf(bp, SPACELEFT(buf, bp), " during %s", SmtpPhase); } - return buf; + return (buf); case EHOSTDOWN: if (CurHostName == NULL) break; (void) snprintf(buf, sizeof buf, "Host %s is down", shortenstring(CurHostName, MAXSHORTSTR)); - return buf; + return (buf); case ECONNREFUSED: if (CurHostName == NULL) break; (void) snprintf(buf, sizeof buf, "Connection refused by %s", shortenstring(CurHostName, MAXSHORTSTR)); - return buf; -#endif /* defined(DAEMON) && defined(ETIMEDOUT) */ + return (buf); +# endif -#if NAMED_BIND +# if NAMED_BIND case HOST_NOT_FOUND + E_DNSBASE: dnsmsg = "host not found"; break; @@ -941,7 +699,7 @@ errstring(errnum) case NO_DATA + E_DNSBASE: dnsmsg = "no data known"; break; -#endif /* NAMED_BIND */ +# endif case EPERM: /* SunOS gives "Not owner" -- this is the POSIX message */ @@ -980,18 +738,13 @@ errstring(errnum) 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 += strlcpy(bp, "Name server: ", sizeof buf); + strcpy(bp, "Name server: "); + bp += strlen(bp); if (CurHostName != NULL) { snprintf(bp, SPACELEFT(buf, bp), "%s: ", @@ -1002,18 +755,13 @@ errstring(errnum) return buf; } -#ifdef LDAPMAP - if (errnum >= E_LDAPBASE) - return ldap_err2string(errnum - E_LDAPBASE); -#endif /* LDAPMAP */ - #if HASSTRERROR return strerror(errnum); -#else /* HASSTRERROR */ +#else if (errnum > 0 && errnum < sys_nerr) - return sys_errlist[errnum]; + return (sys_errlist[errnum]); (void) snprintf(buf, sizeof buf, "Error %d", errnum); - return buf; -#endif /* HASSTRERROR */ + return (buf); +#endif } |