use SpaceSub option value for space replacement in dequote map
[unix-history] / usr / src / usr.sbin / sendmail / src / parseaddr.c
index ea2e11e..ddbb114 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)parseaddr.c        8.23 (Berkeley) %G%";
+static char sccsid[] = "@(#)parseaddr.c        8.36 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "sendmail.h"
 #endif /* not lint */
 
 #include "sendmail.h"
@@ -132,7 +132,7 @@ parseaddr(addr, a, flags, delim, delimptr, e)
 
                if (savec != '\0')
                        **delimptr = '\0';
 
                if (savec != '\0')
                        **delimptr = '\0';
-               addr = newstr(addr);
+               e->e_to = addr = newstr(addr);
                if (savec != '\0')
                        **delimptr = savec;
        }
                if (savec != '\0')
                        **delimptr = savec;
        }
@@ -266,7 +266,7 @@ allocaddr(a, flags, paddr)
        char *paddr;
 {
        if (tTd(24, 4))
        char *paddr;
 {
        if (tTd(24, 4))
-               printf("allocaddr(flags=%o, paddr=%s)\n", flags, paddr);
+               printf("allocaddr(flags=%x, paddr=%s)\n", flags, paddr);
 
        a->q_paddr = paddr;
 
 
        a->q_paddr = paddr;
 
@@ -381,6 +381,30 @@ static short StateTab[NSTATES][NSTATES] =
        /*ONE*/         OPR,    OPR,    OPR,    OPR,    OPR,
 };
 
        /*ONE*/         OPR,    OPR,    OPR,    OPR,    OPR,
 };
 
+/* token type table -- it gets modified with $o characters */
+static TokTypeTab[256] =
+{
+       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,
+};
+
+#define toktype(c)     ((int) TokTypeTab[(c) & 0xff])
+
+
 # define NOCHAR                -1      /* signal nothing in lookahead token */
 
 char **
 # define NOCHAR                -1      /* signal nothing in lookahead token */
 
 char **
@@ -402,6 +426,22 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr)
        int newstate;
        char *saveto = CurEnv->e_to;
        static char *av[MAXATOM+1];
        int newstate;
        char *saveto = CurEnv->e_to;
        static char *av[MAXATOM+1];
+       static char firsttime = TRUE;
+
+       if (firsttime)
+       {
+               /* initialize the token type table */
+               char obuf[50];
+
+               firsttime = FALSE;
+               expand("\201o", obuf, &obuf[sizeof obuf - sizeof DELIMCHARS], CurEnv);
+               strcat(obuf, DELIMCHARS);
+               for (p = obuf; *p != '\0'; p++)
+               {
+                       if (TokTypeTab[*p & 0xff] == ATM)
+                               TokTypeTab[*p & 0xff] = OPR;
+               }
+       }
 
        /* make sure error messages don't have garbage on them */
        errno = 0;
 
        /* make sure error messages don't have garbage on them */
        errno = 0;
@@ -610,53 +650,6 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr)
        return (av);
 }
 \f/*
        return (av);
 }
 \f/*
-**  TOKTYPE -- return token type
-**
-**     Parameters:
-**             c -- the character in question.
-**
-**     Returns:
-**             Its type.
-**
-**     Side Effects:
-**             none.
-*/
-
-static int
-toktype(c)
-       register int c;
-{
-       static char buf[50];
-       static bool firstime = TRUE;
-
-       if (firstime)
-       {
-               firstime = FALSE;
-               expand("\201o", buf, &buf[sizeof buf - 1], CurEnv);
-               (void) strcat(buf, DELIMCHARS);
-       }
-       c &= 0377;
-       if (c == MATCHCLASS || c == MATCHREPL || c == MATCHNCLASS)
-               return (ONE);
-       if (c == MACRODEXPAND)
-               return (ONE);
-#ifdef MACVALUE
-       if (c == MACVALUE)
-               return (ONE);
-#endif /* MACVALUE */
-       if (c == '"')
-               return (QST);
-       if ((c & 0340) == 0200)
-               return (OPR);
-       if (!isascii(c))
-               return (ATM);
-       if (isspace(c) || c == ')')
-               return (SPC);
-       if (strchr(buf, c) != NULL)
-               return (OPR);
-       return (ATM);
-}
-\f/*
 **  REWRITE -- apply rewrite rules to token vector.
 **
 **     This routine is an ordered production system.  Each rewrite
 **  REWRITE -- apply rewrite rules to token vector.
 **
 **     This routine is an ordered production system.  Each rewrite
@@ -709,8 +702,12 @@ struct match
 # define MAXMATCH      9       /* max params per rewrite */
 # define MAX_CONTROL ' '
 
 # define MAXMATCH      9       /* max params per rewrite */
 # define MAX_CONTROL ' '
 
+# ifndef MAXRULERECURSION
+#  define MAXRULERECURSION     50      /* max recursion depth */
+# endif
 static char control_opts[MAX_CONTROL];
 
 static char control_opts[MAX_CONTROL];
 
+
 int
 static char control_init_data[] = { 
        MATCHZANY,      OP_VARLEN,
 int
 static char control_init_data[] = { 
        MATCHZANY,      OP_VARLEN,
@@ -760,7 +757,7 @@ _rewrite(pvp, ruleset)
        struct match *old_mlp;          /* to save our place */
        bool extend_match;      /* extend existing match during backup */
 
        struct match *old_mlp;          /* to save our place */
        bool extend_match;      /* extend existing match during backup */
 
-       if (OpMode == MD_TEST || tTd(21, 2))
+       if (OpMode == MD_TEST || tTd(21, 1))
        {
                printf("rewrite: ruleset %2d   input:", ruleset);
                printcav(pvp);
        {
                printf("rewrite: ruleset %2d   input:", ruleset);
                printcav(pvp);
@@ -770,7 +767,7 @@ _rewrite(pvp, ruleset)
                syserr("554 rewrite: illegal ruleset number %d", ruleset);
                return EX_CONFIG;
        }
                syserr("554 rewrite: illegal ruleset number %d", ruleset);
                return EX_CONFIG;
        }
-       if (reclevel++ > 50)
+       if (reclevel++ > MAXRULERECURSION)
        {
                syserr("rewrite: infinite recursion, ruleset %d", ruleset);
                return EX_CONFIG;
        {
                syserr("rewrite: infinite recursion, ruleset %d", ruleset);
                return EX_CONFIG;
@@ -1474,7 +1471,7 @@ backup:
                }
        }
 
                }
        }
 
-       if (OpMode == MD_TEST || tTd(21, 2))
+       if (OpMode == MD_TEST || tTd(21, 1))
        {
                printf("rewrite: ruleset %2d returns:", ruleset);
                printcav(pvp);
        {
                printf("rewrite: ruleset %2d returns:", ruleset);
                printcav(pvp);
@@ -1585,7 +1582,7 @@ buildaddr(tv, a, flags, e)
 
        if (tTd(24, 5))
        {
 
        if (tTd(24, 5))
        {
-               printf("buildaddr, flags=%o, tv=", flags);
+               printf("buildaddr, flags=%x, tv=", flags);
                printav(tv);
        }
 
                printav(tv);
        }
 
@@ -1660,7 +1657,7 @@ badaddr:
                }
                else
                {
                }
                else
                {
-                       usrerr("%s", buf);
+                       usrerr("553 %s", buf);
                }
                goto badaddr;
        }
                }
                goto badaddr;
        }
@@ -1703,17 +1700,17 @@ badaddr:
        tv++;
 
        /* do special mapping for local mailer */
        tv++;
 
        /* do special mapping for local mailer */
-       if (m == LocalMailer && *tv != NULL)
+       if (*tv != NULL)
        {
                register char *p = *tv;
 
                if (*p == '"')
                        p++;
        {
                register char *p = *tv;
 
                if (*p == '"')
                        p++;
-               if (*p == '|')
+               if (*p == '|' && bitnset(M_CHECKPROG, m->m_flags))
                        a->q_mailer = m = ProgMailer;
                        a->q_mailer = m = ProgMailer;
-               else if (*p == '/')
+               else if (*p == '/' && bitnset(M_CHECKFILE, m->m_flags))
                        a->q_mailer = m = FileMailer;
                        a->q_mailer = m = FileMailer;
-               else if (*p == ':')
+               else if (*p == ':' && bitnset(M_CHECKINCLUDE, m->m_flags))
                {
                        /* may be :include: */
                        cataddr(tv, NULL, buf, sizeof buf, '\0');
                {
                        /* may be :include: */
                        cataddr(tv, NULL, buf, sizeof buf, '\0');
@@ -1728,7 +1725,8 @@ badaddr:
                }
        }
 
                }
        }
 
-       if (m == LocalMailer && *tv != NULL && strcmp(*tv, "@") == 0)
+       if (bitnset(M_CHECKUDB, m->m_flags) && *tv != NULL &&
+           strcmp(*tv, "@") == 0)
        {
                tv++;
                a->q_flags |= QNOTREMOTE;
        {
                tv++;
                a->q_flags |= QNOTREMOTE;
@@ -1831,6 +1829,8 @@ sameaddr(a, b)
        register ADDRESS *a;
        register ADDRESS *b;
 {
        register ADDRESS *a;
        register ADDRESS *b;
 {
+       register ADDRESS *ca, *cb;
+
        /* if they don't have the same mailer, forget it */
        if (a->q_mailer != b->q_mailer)
                return (FALSE);
        /* if they don't have the same mailer, forget it */
        if (a->q_mailer != b->q_mailer)
                return (FALSE);
@@ -1839,9 +1839,16 @@ sameaddr(a, b)
        if (strcasecmp(a->q_user, b->q_user))
                return (FALSE);
 
        if (strcasecmp(a->q_user, b->q_user))
                return (FALSE);
 
-       /* if we have good uids for both but the differ, these are different */
-       if (bitset(QGOODUID, a->q_flags & b->q_flags) && a->q_uid != b->q_uid)
-               return (FALSE);
+       /* if we have good uids for both but they differ, these are different */
+       if (a->q_mailer == ProgMailer)
+       {
+               ca = getctladdr(a);
+               cb = getctladdr(b);
+               if (ca != NULL && cb != NULL &&
+                   bitset(QGOODUID, ca->q_flags & cb->q_flags) &&
+                   ca->q_uid != cb->q_uid)
+                       return (FALSE);
+       }
 
        /* otherwise compare hosts (but be careful for NULL ptrs) */
        if (a->q_host == b->q_host)
 
        /* otherwise compare hosts (but be careful for NULL ptrs) */
        if (a->q_host == b->q_host)
@@ -2042,7 +2049,13 @@ remotename(name, m, flags, pstat, e)
 
        cataddr(pvp, NULL, lbuf, sizeof lbuf, '\0');
        define('g', lbuf, e);
 
        cataddr(pvp, NULL, lbuf, sizeof lbuf, '\0');
        define('g', lbuf, e);
-       expand(fancy, buf, &buf[sizeof buf - 1], e);
+
+       /* need to make sure route-addrs have <angle brackets> */
+       if (bitset(RF_CANONICAL, flags) && lbuf[0] == '@')
+               expand("<\201g>", buf, &buf[sizeof buf - 1], e);
+       else
+               expand(fancy, buf, &buf[sizeof buf - 1], e);
+
        define('g', oldg, e);
 
        if (tTd(12, 1))
        define('g', oldg, e);
 
        if (tTd(12, 1))
@@ -2260,6 +2273,9 @@ dequote_map(map, name, av, statp)
                        continue;
                }
 
                        continue;
                }
 
+               if (c == ' ' && SpaceSub != '\0')
+                       c = SpaceSub;
+
                switch (c)
                {
                  case '\\':
                switch (c)
                {
                  case '\\':