summaryrefslogtreecommitdiffstats
path: root/usr.sbin/sendmail/src/parseaddr.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/sendmail/src/parseaddr.c')
-rw-r--r--usr.sbin/sendmail/src/parseaddr.c543
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 '\\':
OpenPOWER on IntegriCloud