diff options
Diffstat (limited to 'usr.sbin/sendmail/src/parseaddr.c')
-rw-r--r-- | usr.sbin/sendmail/src/parseaddr.c | 543 |
1 files changed, 175 insertions, 368 deletions
diff --git a/usr.sbin/sendmail/src/parseaddr.c b/usr.sbin/sendmail/src/parseaddr.c index e8bda9c..2683728 100644 --- a/usr.sbin/sendmail/src/parseaddr.c +++ b/usr.sbin/sendmail/src/parseaddr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1983 Eric P. Allman * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)parseaddr.c 8.86 (Berkeley) 9/28/95"; +static char sccsid[] = "@(#)parseaddr.c 8.31 (Berkeley) 4/15/94"; #endif /* not lint */ # include "sendmail.h" @@ -91,7 +91,6 @@ parseaddr(addr, a, flags, delim, delimptr, e) char pvpbuf[PSBUFSIZE]; extern ADDRESS *buildaddr(); extern bool invalidaddr(); - extern void allocaddr __P((ADDRESS *, int, char *)); /* ** Initialize and prescan address. @@ -104,7 +103,7 @@ parseaddr(addr, a, flags, delim, delimptr, e) if (delimptr == NULL) delimptr = &delimptrbuf; - pvp = prescan(addr, delim, pvpbuf, sizeof pvpbuf, delimptr, NULL); + pvp = prescan(addr, delim, pvpbuf, sizeof pvpbuf, delimptr); if (pvp == NULL) { if (tTd(20, 1)) @@ -173,15 +172,12 @@ parseaddr(addr, a, flags, delim, delimptr, e) { char *msg = "Transient parse error -- message queued for future delivery"; - if (e->e_sendmode == SM_DEFER) - msg = "Deferring message until queue run"; if (tTd(20, 1)) printf("parseaddr: queuing message\n"); message(msg); - if (e->e_message == NULL && e->e_sendmode != SM_DEFER) + if (e->e_message == NULL) e->e_message = newstr(msg); a->q_flags |= QQUEUEUP; - a->q_status = "4.4.3"; } /* @@ -212,7 +208,7 @@ invalidaddr(addr, delimptr) register char *addr; char *delimptr; { - char savedelim = '\0'; + char savedelim; if (delimptr != NULL) { @@ -235,14 +231,14 @@ invalidaddr(addr, delimptr) } if (*addr == '\0') { - if (delimptr != NULL && savedelim != '\0') + if (savedelim != '\0' && delimptr != NULL) *delimptr = savedelim; return FALSE; } setstat(EX_USAGE); usrerr("553 Address contained invalid control characters"); addrfailure: - if (delimptr != NULL && savedelim != '\0') + if (savedelim != '\0' && delimptr != NULL) *delimptr = savedelim; return TRUE; } @@ -264,14 +260,13 @@ invalidaddr(addr, delimptr) ** Copies portions of a into local buffers as requested. */ -void allocaddr(a, flags, paddr) register ADDRESS *a; int flags; char *paddr; { if (tTd(24, 4)) - printf("allocaddr(flags=%x, paddr=%s)\n", flags, paddr); + printf("allocaddr(flags=%o, paddr=%s)\n", flags, paddr); a->q_paddr = paddr; @@ -316,8 +311,6 @@ allocaddr(a, flags, paddr) ** pvpbsize -- size of pvpbuf. ** delimptr -- if non-NULL, set to the location of the ** terminating delimiter. -** toktab -- if set, a token table to use for parsing. -** If NULL, use the default table. ** ** Returns: ** A pointer to a vector of tokens. @@ -330,9 +323,8 @@ allocaddr(a, flags, paddr) # define QST 2 /* in quoted string */ # define SPC 3 /* chewing up spaces */ # define ONE 4 /* pick up one character */ -# define ILL 5 /* illegal character */ -# define NSTATES 6 /* number of states */ +# define NSTATES 5 /* number of states */ # define TYPE 017 /* mask to select state type */ /* meta bits for table */ @@ -342,102 +334,46 @@ allocaddr(a, flags, paddr) static short StateTab[NSTATES][NSTATES] = { - /* oldst chtype> OPR ATM QST SPC ONE ILL */ - /*OPR*/ OPR|B, ATM|B, QST|B, SPC|MB, ONE|B, ILL|MB, - /*ATM*/ OPR|B, ATM, QST|B, SPC|MB, ONE|B, ILL|MB, - /*QST*/ QST, QST, OPR, QST, QST, QST, - /*SPC*/ OPR, ATM, QST, SPC|M, ONE, ILL|MB, - /*ONE*/ OPR, OPR, OPR, OPR, OPR, ILL|MB, - /*ILL*/ OPR|B, ATM|B, QST|B, SPC|MB, ONE|B, ILL|M, + /* oldst chtype> OPR ATM QST SPC ONE */ + /*OPR*/ OPR|B, ATM|B, QST|B, SPC|MB, ONE|B, + /*ATM*/ OPR|B, ATM, QST|B, SPC|MB, ONE|B, + /*QST*/ QST, QST, OPR, QST, QST, + /*SPC*/ OPR, ATM, QST, SPC|M, ONE, + /*ONE*/ OPR, OPR, OPR, OPR, OPR, }; /* token type table -- it gets modified with $o characters */ -static u_char TokTypeTab[256] = +static TokTypeTab[256] = { - /* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */ - ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,SPC,SPC,SPC,SPC,SPC,ATM,ATM, - /* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */ - ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, - /* sp ! " # $ % & ' ( ) * + , - . / */ - SPC,ATM,QST,ATM,ATM,ATM,ATM,ATM, ATM,SPC,ATM,ATM,ATM,ATM,ATM,ATM, - /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ - ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, - /* @ A B C D E F G H I J K L M N O */ - ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, - /* P Q R S T U V W X Y Z [ \ ] ^ _ */ - ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, - /* ` a b c d e f g h i j k l m n o */ - ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, - /* p q r s t u v w x y z { | } ~ del */ - ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, - - /* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */ - OPR,OPR,ONE,OPR,OPR,OPR,OPR,OPR, OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR, - /* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */ - OPR,OPR,OPR,ONE,ONE,ONE,OPR,OPR, OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR, - /* sp ! " # $ % & ' ( ) * + , - . / */ - ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, - /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ - ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, - /* @ A B C D E F G H I J K L M N O */ - ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, - /* P Q R S T U V W X Y Z [ \ ] ^ _ */ - ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, - /* ` a b c d e f g h i j k l m n o */ - ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, - /* p q r s t u v w x y z { | } ~ del */ - ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,SPC,SPC,SPC,SPC,SPC,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + SPC,ATM,QST,ATM,ATM,ATM,ATM,ATM,ATM,SPC,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + OPR,OPR,ONE,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR, + OPR,OPR,OPR,ONE,ONE,ONE,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, + ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, }; -/* token type table for MIME parsing */ -u_char MimeTokenTab[256] = -{ - /* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */ - ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,SPC,SPC,SPC,SPC,SPC,ILL,ILL, - /* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */ - ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, - /* sp ! " # $ % & ' ( ) * + , - . / */ - SPC,ATM,QST,ATM,ATM,ATM,ATM,ATM, ATM,SPC,ATM,ATM,OPR,ATM,ATM,OPR, - /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ - ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,OPR,OPR,OPR,OPR,OPR,OPR, - /* @ A B C D E F G H I J K L M N O */ - OPR,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, - /* P Q R S T U V W X Y Z [ \ ] ^ _ */ - ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,OPR,OPR,OPR,ATM,ATM, - /* ` a b c d e f g h i j k l m n o */ - ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, - /* p q r s t u v w x y z { | } ~ del */ - ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, - - /* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */ - ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, - /* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */ - ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, - /* sp ! " # $ % & ' ( ) * + , - . / */ - ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, - /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ - ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, - /* @ A B C D E F G H I J K L M N O */ - ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, - /* P Q R S T U V W X Y Z [ \ ] ^ _ */ - ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, - /* ` a b c d e f g h i j k l m n o */ - ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, - /* p q r s t u v w x y z { | } ~ del */ - ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, ILL,ILL,ILL,ILL,ILL,ILL,ILL,ILL, -}; +#define toktype(c) ((int) TokTypeTab[(c) & 0xff]) # define NOCHAR -1 /* signal nothing in lookahead token */ char ** -prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab) +prescan(addr, delim, pvpbuf, pvpbsize, delimptr) char *addr; - int delim; + char delim; char pvpbuf[]; - int pvpbsize; char **delimptr; - u_char *toktab; { register char *p; register char *q; @@ -460,14 +396,7 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab) char obuf[50]; firsttime = FALSE; - if (OperatorChars == NULL) - { - if (ConfigLevel < 7) - OperatorChars = macvalue('o', CurEnv); - if (OperatorChars == NULL) - OperatorChars = ".:@[]"; - } - expand(OperatorChars, obuf, sizeof obuf - sizeof DELIMCHARS, CurEnv); + expand("\201o", obuf, &obuf[sizeof obuf - sizeof DELIMCHARS], CurEnv); strcat(obuf, DELIMCHARS); for (p = obuf; *p != '\0'; p++) { @@ -475,8 +404,6 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab) TokTypeTab[*p & 0xff] = OPR; } } - if (toktab == NULL) - toktab = TokTypeTab; /* make sure error messages don't have garbage on them */ errno = 0; @@ -510,8 +437,6 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab) if (q >= &pvpbuf[pvpbsize - 5]) { usrerr("553 Address too long"); - if (strlen(addr) > MAXNAME) - addr[MAXNAME] = '\0'; returnnull: if (delimptr != NULL) *delimptr = p; @@ -621,17 +546,10 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab) if (c == delim && anglecnt <= 0 && state != QST) break; - newstate = StateTab[state][toktab[c & 0xff]]; + newstate = StateTab[state][toktype(c)]; if (tTd(22, 101)) printf("ns=%02o\n", newstate); state = newstate & TYPE; - if (state == ILL) - { - if (isascii(c) && isprint(c)) - usrerr("653 Illegal character %c", c); - else - usrerr("653 Illegal character 0x%02x", c); - } if (bitset(M, newstate)) c = NOCHAR; if (bitset(B, newstate)) @@ -724,6 +642,10 @@ struct match # define MAXMATCH 9 /* max params per rewrite */ +# ifndef MAXRULERECURSION +# define MAXRULERECURSION 50 /* max recursion depth */ +# endif + int rewrite(pvp, ruleset, reclevel, e) @@ -744,7 +666,7 @@ rewrite(pvp, ruleset, reclevel, e) struct match mlist[MAXMATCH]; /* stores match on LHS */ char *npvp[MAXATOM+1]; /* temporary space for rebuild */ - if (OpMode == MD_TEST || tTd(21, 1)) + if (OpMode == MD_TEST || tTd(21, 2)) { printf("rewrite: ruleset %2d input:", ruleset); printav(pvp); @@ -754,10 +676,9 @@ rewrite(pvp, ruleset, reclevel, e) syserr("554 rewrite: illegal ruleset number %d", ruleset); return EX_CONFIG; } - if (reclevel++ > MaxRuleRecursion) + if (reclevel++ > MAXRULERECURSION) { - syserr("rewrite: excessive recursion (max %d), ruleset %d", - MaxRuleRecursion, ruleset); + syserr("rewrite: infinite recursion, ruleset %d", ruleset); return EX_CONFIG; } if (pvp == NULL) @@ -819,6 +740,7 @@ rewrite(pvp, ruleset, reclevel, e) switch (*rp & 0377) { + register STAB *s; char buf[MAXLINE]; case MATCHCLASS: @@ -831,7 +753,8 @@ rewrite(pvp, ruleset, reclevel, e) goto backup; mlp->last = avp++; cataddr(mlp->first, mlp->last, buf, sizeof buf, '\0'); - if (!wordinclass(buf, rp[1])) + s = stab(buf, ST_CLASS, ST_FIND); + if (s == NULL || !bitnset(rp[1], s->s_class)) { if (tTd(21, 36)) { @@ -850,7 +773,8 @@ rewrite(pvp, ruleset, reclevel, e) case MATCHNCLASS: /* match any token not in a class */ - if (wordinclass(ap, rp[1])) + s = stab(ap, ST_CLASS, ST_FIND); + if (s != NULL && bitnset(rp[1], s->s_class)) goto backup; /* fall through */ @@ -1160,7 +1084,7 @@ rewrite(pvp, ruleset, reclevel, e) if (xpvp != NULL) { cataddr(xpvp, NULL, replac, - &pvpbuf[sizeof pvpbuf] - replac, + &pvpbuf[sizeof pvpbuf] - replac, '\0'); *++arg_rvp = replac; } @@ -1173,22 +1097,10 @@ rewrite(pvp, ruleset, reclevel, e) /* look it up */ cataddr(key_rvp, NULL, buf, sizeof buf, '\0'); argvect[0] = buf; - if (e->e_sendmode == SM_DEFER) - { - /* don't do any map lookups */ - if (tTd(60, 1)) - printf("map_lookup(%s, %s) => DEFERRED\n", - mapname, buf); - replac = NULL; - rstat = EX_TEMPFAIL; - } - else if (map != NULL && bitset(MF_OPEN, map->s_map.map_mflags)) + if (map != NULL && bitset(MF_OPEN, map->s_map.map_mflags)) { auto int stat = EX_OK; - if (!bitset(MF_KEEPQUOTES, map->s_map.map_mflags)) - stripquotes(buf); - /* XXX should try to auto-open the map here */ if (tTd(60, 1)) @@ -1203,21 +1115,7 @@ rewrite(pvp, ruleset, reclevel, e) /* should recover if stat == EX_TEMPFAIL */ if (stat == EX_TEMPFAIL) - { - rstat = EX_TEMPFAIL; - if (tTd(60, 1)) - printf("map_lookup(%s, %s) tempfail: errno=%d\n", - mapname, buf, errno); - if (e->e_message == NULL) - { - char mbuf[300]; - - sprintf(mbuf, "%.80s map: lookup (%s): deferred", - mapname, - shortenstring(buf, 203)); - e->e_message = newstr(mbuf); - } - } + rstat = stat; } else replac = NULL; @@ -1244,7 +1142,7 @@ rewrite(pvp, ruleset, reclevel, e) { /* scan the new replacement */ xpvp = prescan(replac, '\0', pvpbuf, - sizeof pvpbuf, NULL, NULL); + sizeof pvpbuf, NULL); if (xpvp == NULL) { /* prescan already printed error */ @@ -1284,15 +1182,11 @@ rewrite(pvp, ruleset, reclevel, e) } else { - int ruleset; - STAB *s; - bcopy((char *) &npvp[2], (char *) pvp, (int) (avp - npvp - 2) * sizeof *avp); if (tTd(21, 3)) printf("-----callsubr %s\n", npvp[1]); - ruleset = strtorwset(npvp[1], NULL, ST_FIND); - stat = rewrite(pvp, ruleset, reclevel, e); + stat = rewrite(pvp, atoi(npvp[1]), reclevel, e); if (rstat == EX_OK || stat == EX_TEMPFAIL) rstat = stat; if (*pvp != NULL && (**pvp & 0377) == CANONNET) @@ -1311,7 +1205,7 @@ rewrite(pvp, ruleset, reclevel, e) } } - if (OpMode == MD_TEST || tTd(21, 1)) + if (OpMode == MD_TEST || tTd(21, 2)) { printf("rewrite: ruleset %2d returns:", ruleset); printav(pvp); @@ -1366,17 +1260,15 @@ buildaddr(tv, a, flags, e) { struct mailer **mp; register struct mailer *m; - register char *p; - char *mname; - char **hostp; - char hbuf[MAXNAME + 1]; + char *bp; + int spaceleft; static MAILER errormailer; static char *errorargv[] = { "ERROR", NULL }; - static char ubuf[MAXNAME + 1]; + static char buf[MAXNAME]; if (tTd(24, 5)) { - printf("buildaddr, flags=%x, tv=", flags); + printf("buildaddr, flags=%o, tv=", flags); printav(tv); } @@ -1384,13 +1276,10 @@ buildaddr(tv, a, flags, e) a = (ADDRESS *) xalloc(sizeof *a); bzero((char *) a, sizeof *a); - /* set up default error return flags */ - a->q_flags |= QPINGONFAILURE|QPINGONDELAY; - /* figure out what net/mailer to use */ if (*tv == NULL || (**tv & 0377) != CANONNET) { - syserr("554 buildaddr: no mailer in parsed address"); + syserr("554 buildaddr: no net"); badaddr: a->q_flags |= QBADADDR; a->q_mailer = &errormailer; @@ -1403,97 +1292,91 @@ badaddr: } return a; } - 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) + tv++; + if (strcasecmp(*tv, "error") == 0) { - syserr("554 buildaddr: no user"); - goto badaddr; - } - if (tv == hostp) - hostp = NULL; - else if (hostp != NULL) - cataddr(hostp, tv - 1, hbuf, sizeof hbuf, '\0'); - cataddr(++tv, NULL, ubuf, sizeof ubuf, ' '); - - /* save away the host name */ - if (strcasecmp(mname, "error") == 0) - { - if (hostp != NULL) + if ((**++tv & 0377) == CANONHOST) { register struct errcodes *ep; - if (strchr(hbuf, '.') != NULL) - { - a->q_status = newstr(hbuf); - setstat(dsntoexitstat(hbuf)); - } - else if (isascii(hbuf[0]) && isdigit(hbuf[0])) + if (isascii(**++tv) && isdigit(**tv)) { - setstat(atoi(hbuf)); + setstat(atoi(*tv)); } else { for (ep = ErrorCodes; ep->ec_name != NULL; ep++) - if (strcasecmp(ep->ec_name, hbuf) == 0) + if (strcasecmp(ep->ec_name, *tv) == 0) break; setstat(ep->ec_code); } + tv++; } else setstat(EX_UNAVAILABLE); - stripquotes(ubuf); - if (isascii(ubuf[0]) && isdigit(ubuf[0]) && - isascii(ubuf[1]) && isdigit(ubuf[1]) && - isascii(ubuf[2]) && isdigit(ubuf[2]) && - ubuf[3] == ' ') + if ((**tv & 0377) != CANONUSER) + syserr("554 buildaddr: error: no user"); + cataddr(++tv, NULL, buf, sizeof buf, ' '); + stripquotes(buf); + if (isascii(buf[0]) && isdigit(buf[0]) && + isascii(buf[1]) && isdigit(buf[1]) && + isascii(buf[2]) && isdigit(buf[2]) && + buf[3] == ' ') { char fmt[10]; - strncpy(fmt, ubuf, 3); + strncpy(fmt, buf, 3); strcpy(&fmt[3], " %s"); - usrerr(fmt, ubuf + 4); - - /* - ** If this is a 4xx code and we aren't running - ** SMTP on our input, bounce this message; - ** otherwise it disappears without a trace. - */ - - if (fmt[0] == '4' && OpMode != MD_SMTP && - OpMode != MD_DAEMON) - { - e->e_flags |= EF_FATALERRS; - } + usrerr(fmt, buf + 4); } else { - usrerr("553 %s", ubuf); + usrerr("553 %s", buf); } goto badaddr; } for (mp = Mailer; (m = *mp++) != NULL; ) { - if (strcasecmp(m->m_name, mname) == 0) + if (strcasecmp(m->m_name, *tv) == 0) break; } if (m == NULL) { - syserr("554 buildaddr: unknown mailer %s", mname); + syserr("554 buildaddr: unknown mailer %s", *tv); goto badaddr; } a->q_mailer = m; /* figure out what host (if any) */ - if (hostp == NULL) + tv++; + if ((**tv & 0377) == CANONHOST) + { + bp = buf; + spaceleft = sizeof buf - 1; + while (*++tv != NULL && (**tv & 0377) != CANONUSER) + { + int i = strlen(*tv); + + if (i > spaceleft) + { + /* out of space for this address */ + if (spaceleft >= 0) + syserr("554 buildaddr: host too long (%.40s...)", + buf); + i = spaceleft; + spaceleft = 0; + } + if (i <= 0) + continue; + bcopy(*tv, bp, i); + bp += i; + spaceleft -= i; + } + *bp = '\0'; + a->q_host = newstr(buf); + } + else { if (!bitnset(M_LOCALMAILER, m->m_flags)) { @@ -1502,38 +1385,47 @@ badaddr: } a->q_host = NULL; } - else - a->q_host = newstr(hbuf); /* figure out the user */ - p = ubuf; - if (bitnset(M_CHECKUDB, m->m_flags) && *p == '@') + if (*tv == NULL || (**tv & 0377) != CANONUSER) { - p++; - tv++; - a->q_flags |= QNOTREMOTE; + syserr("554 buildaddr: no user"); + goto badaddr; } + tv++; /* do special mapping for local mailer */ - 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)) + if (m == LocalMailer && *tv != NULL) { - /* may be :include: */ - stripquotes(ubuf); - if (strncasecmp(ubuf, ":include:", 9) == 0) + register char *p = *tv; + + if (*p == '"') + p++; + if (*p == '|') + a->q_mailer = m = ProgMailer; + else if (*p == '/') + a->q_mailer = m = FileMailer; + else if (*p == ':') { - /* if :include:, don't need further rewriting */ - a->q_mailer = m = InclMailer; - a->q_user = newstr(&ubuf[9]); - return a; + /* 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 (m == LocalMailer && *tv != NULL && strcmp(*tv, "@") == 0) + { + tv++; + a->q_flags |= QNOTREMOTE; + } + /* rewrite according recipient mailer rewriting rules */ define('h', a->q_host, e); if (!bitset(RF_SENDERADDR|RF_HEADERADDR, flags)) @@ -1546,8 +1438,8 @@ badaddr: (void) rewrite(tv, 4, 0, e); /* save the result for the command line/RCPT argument */ - cataddr(tv, NULL, ubuf, sizeof ubuf, '\0'); - a->q_user = ubuf; + cataddr(tv, NULL, buf, sizeof buf, '\0'); + a->q_user = buf; /* ** Do mapping to lower case as requested by mailer @@ -1558,12 +1450,7 @@ badaddr: if (!bitnset(M_USR_UPPER, m->m_flags)) makelower(a->q_user); - if (tTd(24, 6)) - { - printf("buildaddr => "); - printaddr(a, FALSE); - } - return a; + return (a); } /* ** CATADDR -- concatenate pieces of addresses (putting in <LWSP> subs) @@ -1584,13 +1471,12 @@ badaddr: ** Destroys buf. */ -void cataddr(pvp, evp, buf, sz, spacesub) char **pvp; char **evp; char *buf; register int sz; - int spacesub; + char spacesub; { bool oatomtok = FALSE; bool natomtok = FALSE; @@ -1609,7 +1495,7 @@ cataddr(pvp, evp, buf, sz, spacesub) sz -= 2; while (*pvp != NULL && (i = strlen(*pvp)) < sz) { - natomtok = (TokTypeTab[**pvp & 0xff] == ATM); + natomtok = (toktype(**pvp) == ATM); if (oatomtok && natomtok) *p++ = spacesub; (void) strcpy(p, *pvp); @@ -1694,55 +1580,17 @@ sameaddr(a, b) ** none. */ -struct qflags -{ - char *qf_name; - u_long qf_bit; -}; - -struct qflags AddressFlags[] = -{ - "QDONTSEND", QDONTSEND, - "QBADADDR", QBADADDR, - "QGOODUID", QGOODUID, - "QPRIMARY", QPRIMARY, - "QQUEUEUP", QQUEUEUP, - "QSENT", QSENT, - "QNOTREMOTE", QNOTREMOTE, - "QSELFREF", QSELFREF, - "QVERIFIED", QVERIFIED, - "QBOGUSSHELL", QBOGUSSHELL, - "QUNSAFEADDR", QUNSAFEADDR, - "QPINGONSUCCESS", QPINGONSUCCESS, - "QPINGONFAILURE", QPINGONFAILURE, - "QPINGONDELAY", QPINGONDELAY, - "QHASNOTIFY", QHASNOTIFY, - "QRELAYED", QRELAYED, - "QEXPANDED", QEXPANDED, - "QDELIVERED", QDELIVERED, - "QDELAYED", QDELAYED, - "QTHISPASS", QTHISPASS, - NULL -}; - -void printaddr(a, follow) register ADDRESS *a; bool follow; { + bool first = TRUE; register MAILER *m; MAILER pseudomailer; - register struct qflags *qfp; - bool firstone; - - if (a == NULL) - { - printf("[NULL]\n"); - return; - } while (a != NULL) { + first = FALSE; printf("%x=", a); (void) fflush(stdout); @@ -1755,60 +1603,25 @@ printaddr(a, follow) m->m_name = "NULL"; } - printf("%s:\n\tmailer %d (%s), host `%s'\n", - a->q_paddr == NULL ? "<null>" : a->q_paddr, - m->m_mno, m->m_name, - a->q_host == NULL ? "<null>" : a->q_host); - printf("\tuser `%s', ruser `%s'\n", - a->q_user, - a->q_ruser == NULL ? "<null>" : a->q_ruser); - printf("\tnext=%x, alias %x, uid %d, gid %d\n", - a->q_next, a->q_alias, a->q_uid, a->q_gid); - printf("\tflags=%lx<", a->q_flags); - firstone = TRUE; - for (qfp = AddressFlags; qfp->qf_name != NULL; qfp++) - { - if (!bitset(qfp->qf_bit, a->q_flags)) - continue; - if (!firstone) - printf(","); - firstone = FALSE; - printf("%s", qfp->qf_name); - } - printf(">\n"); + printf("%s:\n\tmailer %d (%s), host `%s', user `%s', ruser `%s'\n", + a->q_paddr, m->m_mno, m->m_name, + a->q_host, a->q_user, + a->q_ruser ? a->q_ruser : "<null>"); + printf("\tnext=%x, flags=%o, alias %x, uid %d, gid %d\n", + a->q_next, a->q_flags, a->q_alias, a->q_uid, a->q_gid); printf("\towner=%s, home=\"%s\", fullname=\"%s\"\n", a->q_owner == NULL ? "(none)" : a->q_owner, a->q_home == NULL ? "(none)" : a->q_home, a->q_fullname == NULL ? "(none)" : a->q_fullname); - printf("\torcpt=\"%s\", statmta=%s, rstatus=%s\n", - a->q_orcpt == NULL ? "(none)" : a->q_orcpt, - a->q_statmta == NULL ? "(none)" : a->q_statmta, - a->q_rstatus == NULL ? "(none)" : a->q_rstatus); if (!follow) return; a = a->q_next; } + if (first) + printf("[NULL]\n"); } -/* -** EMPTYADDR -- return TRUE if this address is empty (``<>'') -** -** Parameters: -** a -- pointer to the address -** -** Returns: -** TRUE -- if this address is "empty" (i.e., no one should -** ever generate replies to it. -** FALSE -- if it is a "regular" (read: replyable) address. -*/ -bool -emptyaddr(a) - register ADDRESS *a; -{ - return a->q_paddr == NULL || strcmp(a->q_paddr, "<>") == 0 || - a->q_user == NULL || strcmp(a->q_user, "<>") == 0; -} /* ** REMOTENAME -- return the name relative to the current mailer ** @@ -1844,8 +1657,8 @@ remotename(name, m, flags, pstat, e) char *fancy; char *oldg = macvalue('g', e); int rwset; - static char buf[MAXNAME + 1]; - char lbuf[MAXNAME + 1]; + static char buf[MAXNAME]; + char lbuf[MAXNAME]; char pvpbuf[PSBUFSIZE]; extern char *crackaddr(); @@ -1880,7 +1693,7 @@ remotename(name, m, flags, pstat, e) ** domain will be appended. */ - pvp = prescan(name, '\0', pvpbuf, sizeof pvpbuf, NULL, NULL); + pvp = prescan(name, '\0', pvpbuf, sizeof pvpbuf, NULL); if (pvp == NULL) return (name); if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL) @@ -1947,9 +1760,9 @@ remotename(name, m, flags, pstat, e) /* need to make sure route-addrs have <angle brackets> */ if (bitset(RF_CANONICAL, flags) && lbuf[0] == '@') - expand("<\201g>", buf, sizeof buf, e); + expand("<\201g>", buf, &buf[sizeof buf - 1], e); else - expand(fancy, buf, sizeof buf, e); + expand(fancy, buf, &buf[sizeof buf - 1], e); define('g', oldg, e); @@ -1964,18 +1777,14 @@ remotename(name, m, flags, pstat, e) ** a -- the address to map (but just the user name part). ** sendq -- the sendq in which to install any replacement ** addresses. -** aliaslevel -- the alias nesting depth. -** e -- the envelope. ** ** Returns: ** none. */ -void -maplocaluser(a, sendq, aliaslevel, e) +maplocaluser(a, sendq, e) register ADDRESS *a; ADDRESS **sendq; - int aliaslevel; ENVELOPE *e; { register char **pvp; @@ -1988,7 +1797,7 @@ maplocaluser(a, sendq, aliaslevel, e) printf("maplocaluser: "); printaddr(a, FALSE); } - pvp = prescan(a->q_user, '\0', pvpbuf, sizeof pvpbuf, &delimptr, NULL); + pvp = prescan(a->q_user, '\0', pvpbuf, sizeof pvpbuf, &delimptr); if (pvp == NULL) return; @@ -2009,8 +1818,8 @@ maplocaluser(a, sendq, aliaslevel, e) printaddr(a, FALSE); } a1->q_alias = a; - allocaddr(a1, RF_COPYALL, a->q_paddr); - (void) recipient(a1, sendq, aliaslevel, e); + allocaddr(a1, RF_COPYALL, NULL); + (void) recipient(a1, sendq, e); } /* ** DEQUOTE_INIT -- initialize dequote map @@ -2032,7 +1841,6 @@ dequote_init(map, args) { register char *p = args; - map->map_mflags |= MF_KEEPQUOTES; for (;;) { while (isascii(*p) && isspace(*p)) @@ -2044,10 +1852,6 @@ dequote_init(map, args) case 'a': map->map_app = ++p; break; - - case 's': - map->map_coldelim = *++p; - break; } while (*p != '\0' && !(isascii(*p) && isspace(*p))) p++; @@ -2084,13 +1888,19 @@ dequote_map(map, name, av, statp) register char *p; register char *q; register char c; - int anglecnt = 0; - int cmntcnt = 0; - int quotecnt = 0; - int spacecnt = 0; - bool quotemode = FALSE; - bool bslashmode = FALSE; - char spacesub = map->map_coldelim; + int anglecnt; + int cmntcnt; + int quotecnt; + int spacecnt; + bool quotemode; + bool bslashmode; + + anglecnt = 0; + cmntcnt = 0; + quotecnt = 0; + spacecnt = 0; + quotemode = FALSE; + bslashmode = FALSE; for (p = q = name; (c = *p++) != '\0'; ) { @@ -2101,9 +1911,6 @@ dequote_map(map, name, av, statp) continue; } - if (c == ' ' && spacesub != '\0') - c = spacesub; - switch (c) { case '\\': |