From 5c5d2382183e0d6d728c2f0bd2b4a190bf47cc8e Mon Sep 17 00:00:00 2001 From: Eric Allman Date: Sat, 22 Apr 1995 18:07:06 -0800 Subject: [PATCH] allow error mailer to take DSN status code SCCS-vsn: usr.sbin/sendmail/src/sysexits.c 8.3 SCCS-vsn: usr.sbin/sendmail/src/parseaddr.c 8.66 --- usr/src/usr.sbin/sendmail/src/parseaddr.c | 129 +++++++++++----------- usr/src/usr.sbin/sendmail/src/sysexits.c | 117 +++++++++++++++++++- 2 files changed, 181 insertions(+), 65 deletions(-) diff --git a/usr/src/usr.sbin/sendmail/src/parseaddr.c b/usr/src/usr.sbin/sendmail/src/parseaddr.c index 8fd2b5a040..f8943db714 100644 --- a/usr/src/usr.sbin/sendmail/src/parseaddr.c +++ b/usr/src/usr.sbin/sendmail/src/parseaddr.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)parseaddr.c 8.65 (Berkeley) %G%"; +static char sccsid[] = "@(#)parseaddr.c 8.66 (Berkeley) %G%"; #endif /* not lint */ #include "sendmail.h" @@ -1705,11 +1705,14 @@ buildaddr(tv, a, flags, e) { struct mailer **mp; register struct mailer *m; + register char *p; char *bp; - int spaceleft; + char *mname; + char **hostp; + char hbuf[MAXNAME + 1]; static MAILER errormailer; static char *errorargv[] = { "ERROR", NULL }; - static char buf[MAXNAME + 1]; + static char ubuf[MAXNAME + 1]; if (tTd(24, 5)) { @@ -1740,25 +1743,47 @@ badaddr: } return a; } - tv++; - if (strcasecmp(*tv, "error") == 0) + mname = *++tv; + + /* extract host and user portions */ + if ((**++tv & 0377) == CANONHOST) + hostp = ++tv; + else + hostp = NULL; + while (*tv != NULL && (**tv & 0377) != CANONUSER) + tv++; + if (*tv == NULL) + { + syserr("554 buildaddr: no user"); + goto badaddr; + } + if (hostp != NULL) + cataddr(hostp, tv - 1, hbuf, sizeof hbuf, '\0'); + cataddr(++tv, NULL, ubuf, sizeof ubuf, '\0'); + + /* save away the host name */ + if (strcasecmp(mname, "error") == 0) { - if ((**++tv & 0377) == CANONHOST) + if (hostp != NULL) { register struct errcodes *ep; - if (isascii(**++tv) && isdigit(**tv)) + if (strchr(hbuf, '.') != NULL) + { + a->q_status = newstr(hbuf); + setstat(dsntoexitstat(hbuf)); + } + else if (isascii(hbuf[0]) && isdigit(hbuf[0])) { - setstat(atoi(*tv)); + setstat(atoi(hbuf)); } else { for (ep = ErrorCodes; ep->ec_name != NULL; ep++) - if (strcasecmp(ep->ec_name, *tv) == 0) + if (strcasecmp(ep->ec_name, hbuf) == 0) break; setstat(ep->ec_code); } - tv++; } else setstat(EX_UNAVAILABLE); @@ -1769,25 +1794,17 @@ badaddr: (void) strcat(buf, " "); (void) strcat(buf, *tv); } - if ((**tv & 0377) != CANONUSER) - syserr("554 buildaddr: error: no user"); - cataddr(++tv, NULL, buf, sizeof buf, ' '); - stripquotes(buf); -#ifdef LOG - if (LogLevel > 8) - syslog (LOG_DEBUG, "%s: Trace: $#ERROR $: %s", - CurEnv->e_id, buf); -#endif /* LOG */ - if (isascii(buf[0]) && isdigit(buf[0]) && - isascii(buf[1]) && isdigit(buf[1]) && - isascii(buf[2]) && isdigit(buf[2]) && - buf[3] == ' ') + stripquotes(ubuf); + if (isascii(ubuf[0]) && isdigit(ubuf[0]) && + isascii(ubuf[1]) && isdigit(ubuf[1]) && + isascii(ubuf[2]) && isdigit(ubuf[2]) && + ubuf[3] == ' ') { char fmt[10]; - strncpy(fmt, buf, 3); + strncpy(fmt, ubuf, 3); strcpy(&fmt[3], " %s"); - usrerr(fmt, buf + 4); + usrerr(fmt, ubuf + 4); /* ** If this is a 4xx code and we aren't running @@ -1803,19 +1820,19 @@ badaddr: } else { - usrerr("553 %s", buf); + usrerr("553 %s", ubuf); } goto badaddr; } for (mp = Mailer; (m = *mp++) != NULL; ) { - if (strcasecmp(m->m_name, *tv) == 0) + if (strcasecmp(m->m_name, mname) == 0) break; } if (m == NULL) { - syserr("554 buildaddr: unknown mailer %s", *tv); + syserr("554 buildaddr: unknown mailer %s", mname); goto badaddr; } a->q_mailer = m; @@ -1832,49 +1849,33 @@ badaddr: } else { - while (*++tv != NULL && **tv != CANONUSER) - (void) strcat(buf, *tv); - a->q_host = newstr(buf); - } /* figure out the user */ - if (*tv == NULL || (**tv & 0377) != CANONUSER) - { - syserr("554 buildaddr: no user"); - goto badaddr; - } - tv++; - - if (bitnset(M_CHECKUDB, m->m_flags) && *tv != NULL && - strcmp(*tv, "@") == 0) + p = ubuf; + if (bitnset(M_CHECKUDB, m->m_flags) && *p == '@') { + p++; tv++; a->q_flags |= QNOTREMOTE; } /* do special mapping for local mailer */ - if (*tv != NULL) + if (*p == '"') + p++; + if (*p == '|' && bitnset(M_CHECKPROG, m->m_flags)) + a->q_mailer = m = ProgMailer; + else if (*p == '/' && bitnset(M_CHECKFILE, m->m_flags)) + a->q_mailer = m = FileMailer; + else if (*p == ':' && bitnset(M_CHECKINCLUDE, m->m_flags)) { - register char *p = *tv; - - if (*p == '"') - p++; - if (*p == '|' && bitnset(M_CHECKPROG, m->m_flags)) - a->q_mailer = m = ProgMailer; - else if (*p == '/' && bitnset(M_CHECKFILE, m->m_flags)) - a->q_mailer = m = FileMailer; - else if (*p == ':' && bitnset(M_CHECKINCLUDE, m->m_flags)) + /* may be :include: */ + stripquotes(ubuf); + if (strncasecmp(ubuf, ":include:", 9) == 0) { - /* may be :include: */ - cataddr(tv, NULL, buf, sizeof buf, '\0'); - stripquotes(buf); - if (strncasecmp(buf, ":include:", 9) == 0) - { - /* if :include:, don't need further rewriting */ - a->q_mailer = m = InclMailer; - a->q_user = &buf[9]; - return (a); - } + /* if :include:, don't need further rewriting */ + a->q_mailer = m = InclMailer; + a->q_user = newstr(&ubuf[9]); + return a; } } @@ -1883,8 +1884,8 @@ badaddr: (void) rewrite(tv, 4, 0, e); /* save the result for the command line/RCPT argument */ - cataddr(tv, NULL, buf, sizeof buf, '\0'); - a->q_user = buf; + cataddr(tv, NULL, ubuf, sizeof ubuf, '\0'); + a->q_user = ubuf; /* ** Do mapping to lower case as requested by mailer @@ -1895,7 +1896,7 @@ badaddr: if (!bitnset(M_USR_UPPER, m->m_flags)) makelower(a->q_user); - return (a); + return a; } /* ** CATADDR -- concatenate pieces of addresses (putting in subs) diff --git a/usr/src/usr.sbin/sendmail/src/sysexits.c b/usr/src/usr.sbin/sendmail/src/sysexits.c index bec4a3a18a..3cd0123e58 100644 --- a/usr/src/usr.sbin/sendmail/src/sysexits.c +++ b/usr/src/usr.sbin/sendmail/src/sysexits.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)sysexits.c 8.2 (Berkeley) %G%"; +static char sccsid[] = "@(#)sysexits.c 8.3 (Berkeley) %G%"; #endif /* not lint */ #include @@ -39,3 +39,118 @@ char *SysExMsg[] = }; int N_SysEx = sizeof(SysExMsg) / sizeof(SysExMsg[0]); + /* +** DSNTOEXITSTAT -- convert DSN-style error code to EX_ style. +** +** Parameters: +** dsncode -- the text of the DSN-style code. +** +** Returns: +** The corresponding exit status. +*/ + +int +dsntoexitstat(dsncode) + char *dsncode; +{ + int code2, code3; + + /* first the easy cases.... */ + if (*dsncode == '2') + return EX_OK; + if (*dsncode == '4') + return EX_TEMPFAIL; + + /* now decode the other two field parts */ + if (*++dsncode == '.') + dsncode++; + code2 = atoi(dsncode); + while (*dsncode != '\0' && *dsncode != '.') + dsncode++; + if (*dsncode != '\0') + dsncode++; + code3 = atoi(dsncode); + + /* and do a nested switch to work them out */ + switch (code2) + { + case 0: /* Other or Undefined status */ + return EX_UNAVAILABLE; + + case 1: /* Address Status */ + switch (code3) + { + case 0: /* Other Address Status */ + return EX_DATAERR; + + case 1: /* Bad mailbox address */ + case 6: /* Mailbox has moved, No forwarding address */ + return EX_NOUSER; + + case 2: /* Bad system address */ + return EX_NOHOST; + + case 3: /* Bad mailbox address syntax */ + return EX_USAGE; + + case 4: /* Mailbox address ambiguous */ + return EX_UNAVAILABLE; + + case 5: /* Address valid */ + return EX_OK; + } + break; + + case 2: /* Mailbox Status */ + switch (code3) + { + case 0: /* Other or Undefined mailbox status */ + case 1: /* Mailbox disabled, not acccepting messages */ + case 2: /* Mailbox full */ + case 4: /* Mailing list expansion problem */ + return EX_UNAVAILABLE; + + case 3: /* Message length exceeds administrative lim */ + return EX_DATAERR; + } + break; + + case 3: /* System Status */ + return EX_OSERR; + + case 4: /* Network and Routing Status */ + switch (code3) + { + case 0: /* Other or undefined network or routing stat */ + return EX_IOERR; + + case 1: /* No answer from host */ + case 3: /* Routing server failure */ + case 5: /* Network congestion */ + return EX_TEMPFAIL; + + case 2: /* Bad connection */ + return EX_IOERR; + + case 4: /* Unable to route */ + return EX_PROTOCOL; + + case 6: /* Routing loop detected */ + return EX_CONFIG; + + case 7: /* Delivery time expired */ + return EX_UNAVAILABLE; + } + break; + + case 5: /* Protocol Status */ + return EX_PROTOCOL; + + case 6: /* Message Content or Media Status */ + return EX_UNAVAILABLE; + + case 7: /* Security Status */ + return EX_DATAERR; + } + return EX_CONFIG; +} -- 2.20.1