BSD 4_3_Net_2 release
[unix-history] / usr / src / usr.sbin / sendmail / src / parseaddr.c
index 17968be..2ee24e0 100644 (file)
@@ -1,16 +1,40 @@
 /*
 /*
-**  Sendmail
-**  Copyright (c) 1983  Eric P. Allman
-**  Berkeley, California
-**
-**  Copyright (c) 1983 Regents of the University of California.
-**  All rights reserved.  The Berkeley software License Agreement
-**  specifies the terms and conditions for redistribution.
-*/
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
 
 #ifndef lint
 
 #ifndef lint
-static char    SccsId[] = "@(#)parseaddr.c     5.5 (Berkeley) %G%";
-#endif not lint
+static char sccsid[] = "@(#)parseaddr.c        5.13 (Berkeley) 6/1/90";
+#endif /* not lint */
 
 # include "sendmail.h"
 
 
 # include "sendmail.h"
 
@@ -73,10 +97,8 @@ parseaddr(addr, a, copyf, delim)
        */
 
        CurEnv->e_to = addr;
        */
 
        CurEnv->e_to = addr;
-# ifdef DEBUG
        if (tTd(20, 1))
                printf("\n--parseaddr(%s)\n", addr);
        if (tTd(20, 1))
                printf("\n--parseaddr(%s)\n", addr);
-# endif DEBUG
 
        pvp = prescan(addr, delim, pvpbuf);
        if (pvp == NULL)
 
        pvp = prescan(addr, delim, pvpbuf);
        if (pvp == NULL)
@@ -151,13 +173,11 @@ parseaddr(addr, a, copyf, delim)
        **  Compute return value.
        */
 
        **  Compute return value.
        */
 
-# ifdef DEBUG
        if (tTd(20, 1))
        {
                printf("parseaddr-->");
                printaddr(a, FALSE);
        }
        if (tTd(20, 1))
        {
                printf("parseaddr-->");
                printaddr(a, FALSE);
        }
-# endif DEBUG
 
        return (a);
 }
 
        return (a);
 }
@@ -273,14 +293,12 @@ prescan(addr, delim, pvpbuf)
        state = OPR;
        c = NOCHAR;
        p = addr;
        state = OPR;
        c = NOCHAR;
        p = addr;
-# ifdef DEBUG
        if (tTd(22, 45))
        {
                printf("prescan: ");
                xputs(p);
                (void) putchar('\n');
        }
        if (tTd(22, 45))
        {
                printf("prescan: ");
                xputs(p);
                (void) putchar('\n');
        }
-# endif DEBUG
 
        do
        {
 
        do
        {
@@ -309,10 +327,8 @@ prescan(addr, delim, pvpbuf)
                                break;
                        c &= ~0200;
 
                                break;
                        c &= ~0200;
 
-# ifdef DEBUG
                        if (tTd(22, 101))
                                printf("c=%c, s=%d; ", c, state);
                        if (tTd(22, 101))
                                printf("c=%c, s=%d; ", c, state);
-# endif DEBUG
 
                        /* chew up special characters */
                        *q = '\0';
 
                        /* chew up special characters */
                        *q = '\0';
@@ -364,17 +380,6 @@ prescan(addr, delim, pvpbuf)
                        }
                        else if (delim == ' ' && isspace(c))
                                c = ' ';
                        }
                        else if (delim == ' ' && isspace(c))
                                c = ' ';
-                       else if (c == ':' && !CurEnv->e_oldstyle)
-                       {
-                               /* consume characters until a semicolon */
-                               while (*p != '\0' && *p != ';')
-                                       p++;
-                               if (*p == '\0')
-                                       usrerr("Unbalanced ':...;' group spec");
-                               else
-                                       p++;
-                               c = ' ';
-                       }
 
                        if (c == NOCHAR)
                                continue;
 
                        if (c == NOCHAR)
                                continue;
@@ -384,10 +389,8 @@ prescan(addr, delim, pvpbuf)
                                break;
 
                        newstate = StateTab[state][toktype(c)];
                                break;
 
                        newstate = StateTab[state][toktype(c)];
-# ifdef DEBUG
                        if (tTd(22, 101))
                                printf("ns=%02o\n", newstate);
                        if (tTd(22, 101))
                                printf("ns=%02o\n", newstate);
-# endif DEBUG
                        state = newstate & TYPE;
                        if (bitset(M, newstate))
                                c = NOCHAR;
                        state = newstate & TYPE;
                        if (bitset(M, newstate))
                                c = NOCHAR;
@@ -399,14 +402,12 @@ prescan(addr, delim, pvpbuf)
                if (tok != q)
                {
                        *q++ = '\0';
                if (tok != q)
                {
                        *q++ = '\0';
-# ifdef DEBUG
                        if (tTd(22, 36))
                        {
                                printf("tok=");
                                xputs(tok);
                                (void) putchar('\n');
                        }
                        if (tTd(22, 36))
                        {
                                printf("tok=");
                                xputs(tok);
                                (void) putchar('\n');
                        }
-# endif DEBUG
                        if (avp >= &av[MAXATOM])
                        {
                                syserr("prescan: too many tokens");
                        if (avp >= &av[MAXATOM])
                        {
                                syserr("prescan: too many tokens");
@@ -516,11 +517,8 @@ rewrite(pvp, ruleset)
        register char **rvp;            /* rewrite vector pointer */
        register struct match *mlp;     /* cur ptr into mlist */
        register struct rewrite *rwr;   /* pointer to current rewrite rule */
        register char **rvp;            /* rewrite vector pointer */
        register struct match *mlp;     /* cur ptr into mlist */
        register struct rewrite *rwr;   /* pointer to current rewrite rule */
-       int subr;                       /* subroutine number if >= 0 */
-       bool dolookup;                  /* do host aliasing */
        struct match mlist[MAXMATCH];   /* stores match on LHS */
        char *npvp[MAXATOM+1];          /* temporary space for rebuild */
        struct match mlist[MAXMATCH];   /* stores match on LHS */
        char *npvp[MAXATOM+1];          /* temporary space for rebuild */
-       extern bool sameword();
 
        if (OpMode == MD_TEST || tTd(21, 2))
        {
 
        if (OpMode == MD_TEST || tTd(21, 2))
        {
@@ -537,13 +535,11 @@ rewrite(pvp, ruleset)
 
        for (rwr = RewriteRules[ruleset]; rwr != NULL; )
        {
 
        for (rwr = RewriteRules[ruleset]; rwr != NULL; )
        {
-# ifdef DEBUG
                if (tTd(21, 12))
                {
                        printf("-----trying rule:");
                        printav(rwr->r_lhs);
                }
                if (tTd(21, 12))
                {
                        printf("-----trying rule:");
                        printav(rwr->r_lhs);
                }
-# endif DEBUG
 
                /* try to match on this rule */
                mlp = mlist;
 
                /* try to match on this rule */
                mlp = mlist;
@@ -552,7 +548,6 @@ rewrite(pvp, ruleset)
                while ((ap = *avp) != NULL || *rvp != NULL)
                {
                        rp = *rvp;
                while ((ap = *avp) != NULL || *rvp != NULL)
                {
                        rp = *rvp;
-# ifdef DEBUG
                        if (tTd(21, 35))
                        {
                                printf("ap=");
                        if (tTd(21, 35))
                        {
                                printf("ap=");
@@ -561,7 +556,6 @@ rewrite(pvp, ruleset)
                                xputs(rp);
                                printf("\n");
                        }
                                xputs(rp);
                                printf("\n");
                        }
-# endif DEBUG
                        if (rp == NULL)
                        {
                                /* end-of-pattern before end-of-address */
                        if (rp == NULL)
                        {
                                /* end-of-pattern before end-of-address */
@@ -608,7 +602,7 @@ rewrite(pvp, ruleset)
 
                          default:
                                /* must have exact match */
 
                          default:
                                /* must have exact match */
-                               if (!sameword(rp, ap))
+                               if (strcasecmp(rp, ap))
                                        goto backup;
                                avp++;
                                break;
                                        goto backup;
                                avp++;
                                break;
@@ -653,22 +647,18 @@ rewrite(pvp, ruleset)
 
                if (rvp < rwr->r_lhs || *rvp != NULL)
                {
 
                if (rvp < rwr->r_lhs || *rvp != NULL)
                {
-# ifdef DEBUG
                        if (tTd(21, 10))
                                printf("----- rule fails\n");
                        if (tTd(21, 10))
                                printf("----- rule fails\n");
-# endif DEBUG
                        rwr = rwr->r_next;
                        continue;
                }
 
                rvp = rwr->r_rhs;
                        rwr = rwr->r_next;
                        continue;
                }
 
                rvp = rwr->r_rhs;
-# ifdef DEBUG
                if (tTd(21, 12))
                {
                        printf("-----rule matches:");
                        printav(rvp);
                }
                if (tTd(21, 12))
                {
                        printf("-----rule matches:");
                        printav(rvp);
                }
-# endif DEBUG
 
                rp = *rvp;
                if (*rp == CANONUSER)
 
                rp = *rvp;
                if (*rp == CANONUSER)
@@ -685,30 +675,21 @@ rewrite(pvp, ruleset)
                        rwr = NULL;
 
                /* substitute */
                        rwr = NULL;
 
                /* substitute */
-               dolookup = FALSE;
                for (avp = npvp; *rvp != NULL; rvp++)
                {
                        register struct match *m;
                        register char **pp;
 
                        rp = *rvp;
                for (avp = npvp; *rvp != NULL; rvp++)
                {
                        register struct match *m;
                        register char **pp;
 
                        rp = *rvp;
-
-                       /* check to see if we should do a lookup */
-                       if (*rp == MATCHLOOKUP)
-                               dolookup = TRUE;
-
-                       /* see if there is substitution here */
                        if (*rp == MATCHREPL)
                        {
                                /* substitute from LHS */
                                m = &mlist[rp[1] - '1'];
                                if (m >= mlp)
                                {
                        if (*rp == MATCHREPL)
                        {
                                /* substitute from LHS */
                                m = &mlist[rp[1] - '1'];
                                if (m >= mlp)
                                {
-                                 toolong:
                                        syserr("rewrite: ruleset %d: replacement out of bounds", ruleset);
                                        return;
                                }
                                        syserr("rewrite: ruleset %d: replacement out of bounds", ruleset);
                                        return;
                                }
-# ifdef DEBUG
                                if (tTd(21, 15))
                                {
                                        printf("$%c:", rp[1]);
                                if (tTd(21, 15))
                                {
                                        printf("$%c:", rp[1]);
@@ -721,7 +702,6 @@ rewrite(pvp, ruleset)
                                        }
                                        printf("\n");
                                }
                                        }
                                        printf("\n");
                                }
-# endif DEBUG
                                pp = m->first;
                                while (pp <= m->last)
                                {
                                pp = m->first;
                                while (pp <= m->last)
                                {
@@ -737,7 +717,11 @@ rewrite(pvp, ruleset)
                        {
                                /* vanilla replacement */
                                if (avp >= &npvp[MAXATOM])
                        {
                                /* vanilla replacement */
                                if (avp >= &npvp[MAXATOM])
-                                       goto toolong;
+                               {
+       toolong:
+                                       syserr("rewrite: expansion too long");
+                                       return;
+                               }
                                *avp++ = rp;
                        }
                }
                                *avp++ = rp;
                        }
                }
@@ -813,64 +797,24 @@ rewrite(pvp, ruleset)
                **  Check for subroutine calls.
                */
 
                **  Check for subroutine calls.
                */
 
-
-               /*
-               **  Do hostname lookup if requested.
-               */
-
-               if (dolookup)
+               if (*npvp != NULL && **npvp == CALLSUBR)
                {
                {
-                       extern char **maphost();
-
-                       rvp = maphost(npvp);
-               }
-               else
-                       rvp = npvp;
-
-               /*
-               **  See if this is a subroutine call.
-               */
-
-               if (**rvp == CALLSUBR)
-               {
-                       subr = atoi(*++rvp);
-                       rvp++;
+                       bcopy((char *) &npvp[2], (char *) pvp,
+                               (int) (avp - npvp - 2) * sizeof *avp);
+                       if (tTd(21, 3))
+                               printf("-----callsubr %s\n", npvp[1]);
+                       rewrite(pvp, atoi(npvp[1]));
                }
                else
                }
                else
-                       subr = -1;
-
-               /*
-               **  Copy result back to original string.
-               */
-
-               for (avp = pvp; *rvp != NULL; rvp++)
-                       *avp++ = *rvp;
-               *avp = NULL;
-
-               /*
-               **  If this specified a subroutine, call it.
-               */
-
-               if (subr >= 0)
                {
                {
-# ifdef DEBUG
-                       if (tTd(21, 3))
-                               printf("-----callsubr %s\n", subr);
-# endif DEBUG
-                       rewrite(pvp, subr);
+                       bcopy((char *) npvp, (char *) pvp,
+                               (int) (avp - npvp) * sizeof *avp);
                }
                }
-
-               /*
-               **  Done with rewriting this pass.
-               */
-
-# ifdef DEBUG
                if (tTd(21, 4))
                {
                        printf("rewritten as:");
                        printav(pvp);
                }
                if (tTd(21, 4))
                {
                        printf("rewritten as:");
                        printav(pvp);
                }
-# endif DEBUG
        }
 
        if (OpMode == MD_TEST || tTd(21, 2))
        }
 
        if (OpMode == MD_TEST || tTd(21, 2))
@@ -903,11 +847,10 @@ buildaddr(tv, a)
        static char buf[MAXNAME];
        struct mailer **mp;
        register struct mailer *m;
        static char buf[MAXNAME];
        struct mailer **mp;
        register struct mailer *m;
-       extern bool sameword();
 
        if (a == NULL)
                a = (ADDRESS *) xalloc(sizeof *a);
 
        if (a == NULL)
                a = (ADDRESS *) xalloc(sizeof *a);
-       clear((char *) a, sizeof *a);
+       bzero((char *) a, sizeof *a);
 
        /* figure out what net/mailer to use */
        if (**tv != CANONNET)
 
        /* figure out what net/mailer to use */
        if (**tv != CANONNET)
@@ -916,7 +859,7 @@ buildaddr(tv, a)
                return (NULL);
        }
        tv++;
                return (NULL);
        }
        tv++;
-       if (sameword(*tv, "error"))
+       if (!strcasecmp(*tv, "error"))
        {
                if (**++tv == CANONHOST)
                {
        {
                if (**++tv == CANONHOST)
                {
@@ -937,7 +880,7 @@ buildaddr(tv, a)
        }
        for (mp = Mailer; (m = *mp++) != NULL; )
        {
        }
        for (mp = Mailer; (m = *mp++) != NULL; )
        {
-               if (sameword(m->m_name, *tv))
+               if (!strcasecmp(m->m_name, *tv))
                        break;
        }
        if (m == NULL)
                        break;
        }
        if (m == NULL)
@@ -965,7 +908,7 @@ buildaddr(tv, a)
                a->q_host = NULL;
 
        /* figure out the user */
                a->q_host = NULL;
 
        /* figure out the user */
-       if (**tv != CANONUSER)
+       if (*tv == NULL || **tv != CANONUSER)
        {
                syserr("buildaddr: no user");
                return (NULL);
        {
                syserr("buildaddr: no user");
                return (NULL);
@@ -1058,11 +1001,6 @@ sameaddr(a, b)
        if (strcmp(a->q_user, b->q_user) != 0)
                return (FALSE);
 
        if (strcmp(a->q_user, b->q_user) != 0)
                return (FALSE);
 
-       /* if receiving uid's don't match, these are "different" */
-       if (bitset(QGOODUID, a->q_flags) && bitset(QGOODUID, b->q_flags) &&
-           (a->q_uid != b->q_uid || a->q_gid != b->q_gid))
-               return (FALSE);
-
        /* if the mailer ignores hosts, we have succeeded! */
        if (bitnset(M_LOCAL, a->q_mailer->m_flags))
                return (TRUE);
        /* if the mailer ignores hosts, we have succeeded! */
        if (bitnset(M_LOCAL, a->q_mailer->m_flags))
                return (TRUE);
@@ -1089,45 +1027,33 @@ sameaddr(a, b)
 **             none.
 */
 
 **             none.
 */
 
-# ifdef DEBUG
-
 printaddr(a, follow)
        register ADDRESS *a;
        bool follow;
 {
        bool first = TRUE;
 
 printaddr(a, follow)
        register ADDRESS *a;
        bool follow;
 {
        bool first = TRUE;
 
-       static int indent;
-       register int i;
-
        while (a != NULL)
        {
                first = FALSE;
        while (a != NULL)
        {
                first = FALSE;
-               for (i = indent; i > 0; i--)
-                       printf("\t");
                printf("%x=", a);
                (void) fflush(stdout);
                printf("%x=", a);
                (void) fflush(stdout);
-               printf("%s: mailer %d (%s), host `%s', user `%s'\n", a->q_paddr,
-               for (i = indent; i > 0; i--)
-                       printf("\t");
-               printf("\tnext=%x, flags=%o, rmailer %d, alias=%x, sibling=%x, child=%x\n",
-                      a->q_next, a->q_flags, a->q_rmailer, a->q_alias,
-                      a->q_sibling, a->q_child);
-               
-               /* follow the chain if appropriate */
+               printf("%s: mailer %d (%s), host `%s', user `%s', ruser `%s'\n",
+                      a->q_paddr, a->q_mailer->m_mno, a->q_mailer->m_name,
+                      a->q_host, a->q_user, a->q_ruser? a->q_ruser: "<null>");
+               printf("\tnext=%x, flags=%o, alias %x\n", a->q_next, a->q_flags,
+                      a->q_alias);
+               printf("\thome=\"%s\", fullname=\"%s\"\n", a->q_home,
+                      a->q_fullname);
+
                if (!follow)
                        return;
                if (!follow)
                        return;
-               
-               indent++;
-               printaddr(a->q_child, TRUE);
-               indent--;
-               a = a->q_sibling;
+               a = a->q_next;
        }
        if (first)
                printf("[NULL]\n");
 }
 
        }
        if (first)
                printf("[NULL]\n");
 }
 
-# endif DEBUG
 \f/*
 **  REMOTENAME -- return the name relative to the current mailer
 **
 \f/*
 **  REMOTENAME -- return the name relative to the current mailer
 **
@@ -1169,10 +1095,8 @@ remotename(name, m, senderaddress, canonical)
        extern char **prescan();
        extern char *crackaddr();
 
        extern char **prescan();
        extern char *crackaddr();
 
-# ifdef DEBUG
        if (tTd(12, 1))
                printf("remotename(%s)\n", name);
        if (tTd(12, 1))
                printf("remotename(%s)\n", name);
-# endif DEBUG
 
        /* don't do anything if we are tagging it as special */
        if ((senderaddress ? m->m_s_rwset : m->m_r_rwset) < 0)
 
        /* don't do anything if we are tagging it as special */
        if ((senderaddress ? m->m_s_rwset : m->m_r_rwset) < 0)
@@ -1257,9 +1181,7 @@ remotename(name, m, senderaddress, canonical)
        expand(fancy, buf, &buf[sizeof buf - 1], CurEnv);
        define('g', oldg, CurEnv);
 
        expand(fancy, buf, &buf[sizeof buf - 1], CurEnv);
        define('g', oldg, CurEnv);
 
-# ifdef DEBUG
        if (tTd(12, 1))
                printf("remotename => `%s'\n", buf);
        if (tTd(12, 1))
                printf("remotename => `%s'\n", buf);
-# endif DEBUG
        return (buf);
 }
        return (buf);
 }