BSD 4_3_Net_2 release
[unix-history] / usr / src / usr.sbin / sendmail / src / macro.c
index e3fe0c9..da35b46 100644 (file)
@@ -1,9 +1,42 @@
-# include "sendmail.h"
-# include "conf.h"
+/*
+ * 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.
+ */
 
 
-SCCSID(@(#)macro.c     3.11            %G%);
+#ifndef lint
+static char sccsid[] = "@(#)macro.c    5.7 (Berkeley) 6/1/90";
+#endif /* not lint */
 
 
-char   *Macro[128];
+# include "sendmail.h"
 
 /*
 **  EXPAND -- macro expand a string using $x escapes.
 
 /*
 **  EXPAND -- macro expand a string using $x escapes.
@@ -13,37 +46,40 @@ char        *Macro[128];
 **             buf -- the place to put the expansion.
 **             buflim -- the buffer limit, i.e., the address
 **                     of the last usable position in buf.
 **             buf -- the place to put the expansion.
 **             buflim -- the buffer limit, i.e., the address
 **                     of the last usable position in buf.
+**             e -- envelope in which to work.
 **
 **     Returns:
 **
 **     Returns:
-**             End of interpolated output.
+**             none.
 **
 **     Side Effects:
 **             none.
 */
 
 **
 **     Side Effects:
 **             none.
 */
 
-char *
-expand(s, buf, buflim)
+expand(s, buf, buflim, e)
        register char *s;
        register char *buf;
        char *buflim;
        register char *s;
        register char *buf;
        char *buflim;
+       register ENVELOPE *e;
 {
 {
+       register char *xp;
        register char *q;
        register char *q;
-       char xbuf[BUFSIZ];
-       register char *xp = xbuf;
        bool skipping;          /* set if conditionally skipping output */
        bool skipping;          /* set if conditionally skipping output */
-       bool gotone = FALSE;    /* set if any expansion done */
+       bool recurse = FALSE;   /* set if recursion required */
+       int i;
+       char xbuf[BUFSIZ];
+       extern char *macvalue();
 
 
-# ifdef DEBUG
-       if (Debug > 3)
+       if (tTd(35, 24))
        {
                printf("expand(");
                xputs(s);
                printf(")\n");
        }
        {
                printf("expand(");
                xputs(s);
                printf(")\n");
        }
-# endif DEBUG
 
        skipping = FALSE;
 
        skipping = FALSE;
-       for (; *s != '\0'; s++)
+       if (s == NULL)
+               s = "";
+       for (xp = xbuf; *s != '\0'; s++)
        {
                char c;
 
        {
                char c;
 
@@ -58,7 +94,7 @@ expand(s, buf, buflim)
                {
                  case CONDIF:          /* see if var set */
                        c = *++s;
                {
                  case CONDIF:          /* see if var set */
                        c = *++s;
-                       skipping = Macro[c] == NULL;
+                       skipping = macvalue(c, e) == NULL;
                        continue;
 
                  case CONDELSE:        /* change state of skipping */
                        continue;
 
                  case CONDELSE:        /* change state of skipping */
@@ -69,12 +105,11 @@ expand(s, buf, buflim)
                        skipping = FALSE;
                        continue;
 
                        skipping = FALSE;
                        continue;
 
-                 case '$':             /* macro interpolation */
+                 case '\001':          /* macro interpolation */
                        c = *++s;
                        c = *++s;
-                       q = Macro[c & 0177];
-                       if (q == NULL && c != '$')
+                       q = macvalue(c & 0177, e);
+                       if (q == NULL)
                                continue;
                                continue;
-                       gotone = TRUE;
                        break;
                }
 
                        break;
                }
 
@@ -82,41 +117,43 @@ expand(s, buf, buflim)
                **  Interpolate q or output one character
                */
 
                **  Interpolate q or output one character
                */
 
-               if (skipping)
+               if (skipping || xp >= &xbuf[sizeof xbuf])
                        continue;
                        continue;
-               while (xp < &xbuf[sizeof xbuf])
+               if (q == NULL)
+                       *xp++ = c;
+               else
                {
                {
-                       if (q == NULL)
+                       /* copy to end of q or max space remaining in buf */
+                       while ((c = *q++) != '\0' && xp < &xbuf[sizeof xbuf - 1])
                        {
                        {
+                               if (iscntrl(c) && !isspace(c))
+                                       recurse = TRUE;
                                *xp++ = c;
                                *xp++ = c;
-                               break;
                        }
                        }
-                       if (*q == NULL)
-                               break;
-                       *xp++ = *q++;
                }
        }
        *xp = '\0';
 
                }
        }
        *xp = '\0';
 
-# ifdef DEBUG
-       if (Debug > 3)
+       if (tTd(35, 24))
        {
        {
-               printf("expand ==> '");
+               printf("expand ==> ");
                xputs(xbuf);
                xputs(xbuf);
-               printf("'\n");
+               printf("\n");
        }
        }
-# endif DEBUG
 
        /* recurse as appropriate */
 
        /* recurse as appropriate */
-       if (gotone)
-               return (expand(xbuf, buf, buflim));
+       if (recurse)
+       {
+               expand(xbuf, buf, buflim, e);
+               return;
+       }
 
        /* copy results out */
 
        /* copy results out */
-       for (q = buf, xp = xbuf; xp != '\0' && q < buflim-1; )
-               *q++ = *xp++;
-       *q = '\0';
-
-       return (q);
+       i = buflim - buf - 1;
+       if (i > xp - xbuf)
+               i = xp - xbuf;
+       bcopy(xbuf, buf, i);
+       buf[i] = '\0';
 }
 \f/*
 **  DEFINE -- define a macro.
 }
 \f/*
 **  DEFINE -- define a macro.
@@ -126,12 +163,13 @@ expand(s, buf, buflim)
 **     Parameters:
 **             n -- the macro name.
 **             v -- the macro value.
 **     Parameters:
 **             n -- the macro name.
 **             v -- the macro value.
+**             e -- the envelope to store the definition in.
 **
 **     Returns:
 **             none.
 **
 **     Side Effects:
 **
 **     Returns:
 **             none.
 **
 **     Side Effects:
-**             Macro[n] is defined.
+**             e->e_macro[n] is defined.
 **
 **     Notes:
 **             There is one macro for each ASCII character,
 **
 **     Notes:
 **             There is one macro for each ASCII character,
@@ -144,10 +182,12 @@ expand(s, buf, buflim)
 **                  the message) in ARPANET format
 **             $c   hop count
 **             $d   (current) date in UNIX (ctime) format
 **                  the message) in ARPANET format
 **             $c   hop count
 **             $d   (current) date in UNIX (ctime) format
+**             $e   the SMTP entry message+
 **             $f   raw from address
 **             $g   translated from address
 **             $h   to host
 **             $f   raw from address
 **             $g   translated from address
 **             $h   to host
-**             $i   official SMTP hostname, used in messages+
+**             $i   queue id
+**             $j   official SMTP hostname, used in messages+
 **             $l   UNIX-style from line+
 **             $n   name of sendmail ("MAILER-DAEMON" on local
 **                  net typically)+
 **             $l   UNIX-style from line+
 **             $n   name of sendmail ("MAILER-DAEMON" on local
 **                  net typically)+
@@ -160,6 +200,7 @@ expand(s, buf, buflim)
 **             $t   the current time in seconds since 1/1/1970
 **             $u   to user
 **             $v   version number of sendmail
 **             $t   the current time in seconds since 1/1/1970
 **             $u   to user
 **             $v   version number of sendmail
+**             $w   our host name (if it can be determined)
 **             $x   signature (full name) of from person
 **             $y   the tty id of our terminal
 **             $z   home directory of to person
 **             $x   signature (full name) of from person
 **             $y   the tty id of our terminal
 **             $z   home directory of to person
@@ -174,19 +215,18 @@ expand(s, buf, buflim)
 **             are available.
 */
 
 **             are available.
 */
 
-define(n, v)
+define(n, v, e)
        char n;
        char *v;
        char n;
        char *v;
+       register ENVELOPE *e;
 {
 {
-# ifdef DEBUG
-       if (Debug > 3)
+       if (tTd(35, 9))
        {
                printf("define(%c as ", n);
                xputs(v);
                printf(")\n");
        }
        {
                printf("define(%c as ", n);
                xputs(v);
                printf(")\n");
        }
-# endif DEBUG
-       Macro[n & 0177] = v;
+       e->e_macro[n & 0177] = v;
 }
 \f/*
 **  MACVALUE -- return uninterpreted value of a macro.
 }
 \f/*
 **  MACVALUE -- return uninterpreted value of a macro.
@@ -202,8 +242,18 @@ define(n, v)
 */
 
 char *
 */
 
 char *
-macvalue(n)
+macvalue(n, e)
        char n;
        char n;
+       register ENVELOPE *e;
 {
 {
-       return (Macro[n & 0177]);
+       n &= 0177;
+       while (e != NULL)
+       {
+               register char *p = e->e_macro[n];
+
+               if (p != NULL)
+                       return (p);
+               e = e->e_parent;
+       }
+       return (NULL);
 }
 }