add $* to match zero or more and $> to make a "subroutine" call; stick
authorEric Allman <eric@ucbvax.Berkeley.EDU>
Mon, 6 Sep 1982 02:48:27 +0000 (18:48 -0800)
committerEric Allman <eric@ucbvax.Berkeley.EDU>
Mon, 6 Sep 1982 02:48:27 +0000 (18:48 -0800)
in initial hooks for per-mailer rewriting; improve diagnostics in readcf,
including number lines; increase the number of rewriting sets.

SCCS-vsn: usr.sbin/sendmail/src/sendmail.h 3.85
SCCS-vsn: usr.sbin/sendmail/src/parseaddr.c 3.51
SCCS-vsn: usr.sbin/sendmail/src/version.c 3.185

usr/src/usr.sbin/sendmail/src/parseaddr.c
usr/src/usr.sbin/sendmail/src/sendmail.h
usr/src/usr.sbin/sendmail/src/version.c

index c1f5ba2..f8a424f 100644 (file)
@@ -1,6 +1,6 @@
 # include "sendmail.h"
 
 # include "sendmail.h"
 
-SCCSID(@(#)parseaddr.c 3.50            %G%);
+SCCSID(@(#)parseaddr.c 3.51            %G%);
 
 /*
 **  PARSE -- Parse an address
 
 /*
 **  PARSE -- Parse an address
@@ -379,14 +379,15 @@ toktype(c)
 **
 **     For each rewrite rule, 'avp' points the address vector we
 **     are trying to match against, and 'pvp' points to the pattern.
 **
 **     For each rewrite rule, 'avp' points the address vector we
 **     are trying to match against, and 'pvp' points to the pattern.
-**     If pvp points to a special match value (MATCHANY, MATCHONE,
-**     MATCHCLASS) then the address in avp matched is saved away
-**     in the match vector (pointed to by 'mvp').
+**     If pvp points to a special match value (MATCHZANY, MATCHANY,
+**     MATCHONE, MATCHCLASS) then the address in avp matched is
+**     saved away in the match vector (pointed to by 'mvp').
 **
 **     When a match between avp & pvp does not match, we try to
 **     back out.  If we back up over a MATCHONE or a MATCHCLASS
 **     we must also back out the match in mvp.  If we reach a
 **
 **     When a match between avp & pvp does not match, we try to
 **     back out.  If we back up over a MATCHONE or a MATCHCLASS
 **     we must also back out the match in mvp.  If we reach a
-**     MATCHANY we just extend the match and start over again.
+**     MATCHANY or MATCHZANY we just extend the match and start
+**     over again.
 **
 **     When we finally match, we rewrite the address vector
 **     and try over again.
 **
 **     When we finally match, we rewrite the address vector
 **     and try over again.
@@ -418,16 +419,16 @@ rewrite(pvp, ruleset)
        register char *rp;              /* rewrite pointer */
        register char **avp;            /* address vector pointer */
        register char **rvp;            /* rewrite vector pointer */
        register char *rp;              /* rewrite pointer */
        register char **avp;            /* address vector pointer */
        register char **rvp;            /* rewrite vector pointer */
-       struct rewrite *rwr;            /* pointer to current rewrite rule */
+       register struct match *mlp;     /* cur ptr into mlist */
+       register struct rewrite *rwr;   /* pointer to current rewrite rule */
        struct match mlist[MAXMATCH];   /* stores match on LHS */
        struct match mlist[MAXMATCH];   /* stores match on LHS */
-       struct match *mlp;              /* cur ptr into mlist */
        char *npvp[MAXATOM+1];          /* temporary space for rebuild */
        extern bool sameword();
 
 # ifdef DEBUG
        if (tTd(21, 9))
        {
        char *npvp[MAXATOM+1];          /* temporary space for rebuild */
        extern bool sameword();
 
 # ifdef DEBUG
        if (tTd(21, 9))
        {
-               printf("rewrite: original pvp:\n");
+               printf("rewrite: ruleset %d, original pvp:\n", ruleset);
                printav(pvp);
        }
 # endif DEBUG
                printav(pvp);
        }
 # endif DEBUG
@@ -449,15 +450,30 @@ rewrite(pvp, ruleset)
 
                /* try to match on this rule */
                mlp = mlist;
 
                /* try to match on this rule */
                mlp = mlist;
-               for (rvp = rwr->r_lhs, avp = pvp; *avp != NULL; )
+               rvp = rwr->r_lhs;
+               avp = pvp;
+               while ((ap = *avp) != NULL || *rvp != NULL)
                {
                {
-                       ap = *avp;
                        rp = *rvp;
                        rp = *rvp;
-
+# ifdef DEBUG
+                       if (tTd(21, 35))
+                       {
+                               printf("ap=\"");
+                               xputs(ap);
+                               printf("\", rp=\"");
+                               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 */
-                               goto fail;
+                               goto backup;
+                       }
+                       if (ap == NULL && *rp != MATCHZANY)
+                       {
+                               /* end-of-input */
+                               break;
                        }
 
                        switch (*rp)
                        }
 
                        switch (*rp)
@@ -469,28 +485,36 @@ rewrite(pvp, ruleset)
                                /* match any token in a class */
                                class = rp[1];
                                if (!isalpha(class))
                                /* match any token in a class */
                                class = rp[1];
                                if (!isalpha(class))
-                                       goto fail;
+                                       goto backup;
                                if (isupper(class))
                                        class -= 'A';
                                else
                                        class -= 'a';
                                s = stab(ap, ST_CLASS, ST_FIND);
                                if (s == NULL || (s->s_class & (1L << class)) == 0)
                                if (isupper(class))
                                        class -= 'A';
                                else
                                        class -= 'a';
                                s = stab(ap, ST_CLASS, ST_FIND);
                                if (s == NULL || (s->s_class & (1L << class)) == 0)
-                                       goto fail;
+                                       goto backup;
 
                                /* explicit fall-through */
 
                          case MATCHONE:
                          case MATCHANY:
                                /* match exactly one token */
 
                                /* explicit fall-through */
 
                          case MATCHONE:
                          case MATCHANY:
                                /* match exactly one token */
-                               mlp->first = mlp->last = avp++;
+                               mlp->first = avp;
+                               mlp->last = avp++;
+                               mlp++;
+                               break;
+
+                         case MATCHZANY:
+                               /* match zero or more tokens */
+                               mlp->first = avp;
+                               mlp->last = avp - 1;
                                mlp++;
                                break;
 
                          default:
                                /* must have exact match */
                                if (!sameword(rp, ap))
                                mlp++;
                                break;
 
                          default:
                                /* must have exact match */
                                if (!sameword(rp, ap))
-                                       goto fail;
+                                       goto backup;
                                avp++;
                                break;
                        }
                                avp++;
                                break;
                        }
@@ -499,15 +523,16 @@ rewrite(pvp, ruleset)
                        rvp++;
                        continue;
 
                        rvp++;
                        continue;
 
-                 fail:
+                 backup:
                        /* match failed -- back up */
                        while (--rvp >= rwr->r_lhs)
                        {
                                rp = *rvp;
                        /* match failed -- back up */
                        while (--rvp >= rwr->r_lhs)
                        {
                                rp = *rvp;
-                               if (*rp == MATCHANY)
+                               if (*rp == MATCHANY || *rp == MATCHZANY)
                                {
                                        /* extend binding and continue */
                                {
                                        /* extend binding and continue */
-                                       mlp[-1].last = avp++;
+                                       avp = ++mlp[-1].last;
+                                       avp++;
                                        rvp++;
                                        break;
                                }
                                        rvp++;
                                        break;
                                }
@@ -532,14 +557,29 @@ rewrite(pvp, ruleset)
 
                if (rvp >= rwr->r_lhs && *rvp == NULL)
                {
 
                if (rvp >= rwr->r_lhs && *rvp == NULL)
                {
+                       rvp = rwr->r_rhs;
 # ifdef DEBUG
                        if (tTd(21, 12))
                        {
                                printf("-----rule matches:\n");
 # ifdef DEBUG
                        if (tTd(21, 12))
                        {
                                printf("-----rule matches:\n");
-                               printav(rwr->r_rhs);
+                               printav(rvp);
                        }
 # endif DEBUG
 
                        }
 # endif DEBUG
 
+                       /* see if this is a "subroutine" call */
+                       rp = *rvp;
+                       if (*rp == CALLSUBR)
+                       {
+                               rp = *++rvp;
+# ifdef DEBUG
+                               if (tTd(21, 2))
+                                       printf("-----callsubr %s\n", rp);
+# endif DEBUG
+                               rewrite(pvp, atoi(rp));
+                               rwr = rwr->r_next;
+                               continue;
+                       }
+
                        /* substitute */
                        for (rvp = rwr->r_rhs, avp = npvp; *rvp != NULL; rvp++)
                        {
                        /* substitute */
                        for (rvp = rwr->r_rhs, avp = npvp; *rvp != NULL; rvp++)
                        {
@@ -555,25 +595,25 @@ rewrite(pvp, ruleset)
                                        {
                                                printf("$%c:", rp[1]);
                                                pp = m->first;
                                        {
                                                printf("$%c:", rp[1]);
                                                pp = m->first;
-                                               do
+                                               while (pp <= m->last)
                                                {
                                                        printf(" %x=\"", *pp);
                                                        (void) fflush(stdout);
                                                {
                                                        printf(" %x=\"", *pp);
                                                        (void) fflush(stdout);
-                                                       printf("%s\"", *pp);
-                                               } while (pp++ != m->last);
+                                                       printf("%s\"", *pp++);
+                                               }
                                                printf("\n");
                                        }
 # endif DEBUG
                                        pp = m->first;
                                                printf("\n");
                                        }
 # endif DEBUG
                                        pp = m->first;
-                                       do
+                                       while (pp <= m->last)
                                        {
                                                if (avp >= &npvp[MAXATOM])
                                                {
                                                        syserr("rewrite: expansion too long");
                                                        return;
                                                }
                                        {
                                                if (avp >= &npvp[MAXATOM])
                                                {
                                                        syserr("rewrite: expansion too long");
                                                        return;
                                                }
-                                               *avp++ = *pp;
-                                       } while (pp++ != m->last);
+                                               *avp++ = *pp++;
+                                       }
                                }
                                else
                                {
                                }
                                else
                                {
@@ -894,6 +934,11 @@ remotename(name, m, force)
        **  First put this address into canonical form.
        **      First turn it into a macro.
        **      Then run it through ruleset 4.
        **  First put this address into canonical form.
        **      First turn it into a macro.
        **      Then run it through ruleset 4.
+       **      If the mailer defines a rewriting set, run it through
+       **              there next.
+       **      The intent is that ruleset 4 puts the name into a
+       **              canonical form; the mailer's ruleset then
+       **              does any customization.
        */
 
        /* save away the extraneous pretty stuff */
        */
 
        /* save away the extraneous pretty stuff */
@@ -904,6 +949,8 @@ remotename(name, m, force)
        if (pvp == NULL)
                return (name);
        rewrite(pvp, 4);
        if (pvp == NULL)
                return (name);
        rewrite(pvp, 4);
+       if (m->m_rwset > 0)
+               rewrite(pvp, m->m_rwset);
 
        /*
        **  See if this mailer wants the name to be rewritten.  There are
 
        /*
        **  See if this mailer wants the name to be rewritten.  There are
index 10922b9..7e8eb05 100644 (file)
@@ -7,7 +7,7 @@
 # ifdef _DEFINE
 # define EXTERN
 # ifndef lint
 # ifdef _DEFINE
 # define EXTERN
 # ifndef lint
-static char SmailSccsId[] =    "@(#)sendmail.h 3.84            %G%";
+static char SmailSccsId[] =    "@(#)sendmail.h 3.85            %G%";
 # endif lint
 # else  _DEFINE
 # define EXTERN extern
 # endif lint
 # else  _DEFINE
 # define EXTERN extern
@@ -34,6 +34,7 @@ static char SmailSccsId[] =   "@(#)sendmail.h 3.84            %G%";
 # define MAXHOP                30              /* max value of HopCount */
 # define MAXATOM       100             /* max atoms per address */
 # define MAXMAILERS    25              /* maximum mailers known to system */
 # define MAXHOP                30              /* max value of HopCount */
 # define MAXATOM       100             /* max atoms per address */
 # define MAXMAILERS    25              /* maximum mailers known to system */
+# define MAXRWSETS     30              /* max # of sets of rewriting rules */
 # define SPACESUB      ('.'|0200)      /* substitution for <lwsp> */
 \f/*
 **  Address structure.
 # define SPACESUB      ('.'|0200)      /* substitution for <lwsp> */
 \f/*
 **  Address structure.
@@ -100,6 +101,7 @@ struct mailer
        short   m_mno;          /* mailer number internally */
        char    *m_from;        /* pattern for From: header */
        char    **m_argv;       /* template argument vector */
        short   m_mno;          /* mailer number internally */
        char    *m_from;        /* pattern for From: header */
        char    **m_argv;       /* template argument vector */
+       short   m_rwset;        /* apply this rewriting set to addresses */
 };
 
 typedef struct mailer  MAILER;
 };
 
 typedef struct mailer  MAILER;
@@ -262,20 +264,33 @@ struct rewrite
        struct rewrite  *r_next;/* next in chain */
 };
 
        struct rewrite  *r_next;/* next in chain */
 };
 
-extern struct rewrite  *RewriteRules[];
+EXTERN struct rewrite  *RewriteRules[MAXRWSETS];
 
 
-# define MATCHANY      '\020'  /* match one or more tokens */
-# define MATCHONE      '\021'  /* match exactly one token */
-# define MATCHCLASS    '\022'  /* match one token in a class */
-# define MATCHREPL     '\023'  /* replacement on RHS for above */
+/*
+**  Special characters in rewriting rules.
+**     These are used internally only.
+**     The COND* rules are actually used in macros rather than in
+**             rewriting rules, but are given here because they
+**             cannot conflict.
+*/
+
+/* left hand side items */
+# define MATCHZANY     '\020'  /* match zero or more tokens */
+# define MATCHANY      '\021'  /* match one or more tokens */
+# define MATCHONE      '\022'  /* match exactly one token */
+# define MATCHCLASS    '\023'  /* match one token in a class */
+# define MATCHREPL     '\024'  /* replacement on RHS for above */
 
 
+/* right hand side items */
 # define CANONNET      '\025'  /* canonical net, next token */
 # define CANONHOST     '\026'  /* canonical host, next token */
 # define CANONUSER     '\027'  /* canonical user, next N tokens */
 # define CANONNET      '\025'  /* canonical net, next token */
 # define CANONHOST     '\026'  /* canonical host, next token */
 # define CANONUSER     '\027'  /* canonical user, next N tokens */
+# define CALLSUBR      '\030'  /* call another rewriting set */
 
 
-# define CONDIF                '\030'  /* conditional if-then */
-# define CONDELSE      '\031'  /* conditional else */
-# define CONDFI                '\032'  /* conditional fi */
+/* conditionals in macros */
+# define CONDIF                '\031'  /* conditional if-then */
+# define CONDELSE      '\032'  /* conditional else */
+# define CONDFI                '\033'  /* conditional fi */
 \f/*
 **  Symbol table definitions
 */
 \f/*
 **  Symbol table definitions
 */
@@ -404,6 +419,7 @@ EXTERN int  ExitStat;       /* exit status code */
 EXTERN int     HopCount;       /* hop count */
 EXTERN int     AliasLevel;     /* depth of aliasing */
 EXTERN int     MotherPid;      /* proc id of parent process */
 EXTERN int     HopCount;       /* hop count */
 EXTERN int     AliasLevel;     /* depth of aliasing */
 EXTERN int     MotherPid;      /* proc id of parent process */
+EXTERN int     LineNumber;     /* line number in current input */
 EXTERN time_t  QueueIntvl;     /* intervals between running the queue */
 EXTERN char    *HostName;      /* name of this host for SMTP messages */
 EXTERN char    *Transcript;    /* the transcript file name */
 EXTERN time_t  QueueIntvl;     /* intervals between running the queue */
 EXTERN char    *HostName;      /* name of this host for SMTP messages */
 EXTERN char    *Transcript;    /* the transcript file name */
index f8aaf85..301a200 100644 (file)
@@ -1,5 +1,5 @@
 # ifndef lint
 # ifndef lint
-static char    SccsId[] = "@(#)SendMail version 3.184 of %G%";
+static char    SccsId[] = "@(#)SendMail version 3.185 of %G%";
 # endif lint
 
 # endif lint
 
-char   Version[] = "3.184 [%G%]";
+char   Version[] = "3.185 [%G%]";