1: # include "sendmail.h"
   2: 
   3: SCCSID(@(#)macro.c	4.1		7/25/83);
   4: 
   5: /*
   6: **  EXPAND -- macro expand a string using $x escapes.
   7: **
   8: **	Parameters:
   9: **		s -- the string to expand.
  10: **		buf -- the place to put the expansion.
  11: **		buflim -- the buffer limit, i.e., the address
  12: **			of the last usable position in buf.
  13: **		e -- envelope in which to work.
  14: **
  15: **	Returns:
  16: **		none.
  17: **
  18: **	Side Effects:
  19: **		none.
  20: **
  21: **	Bugs:
  22: **		The handling of $$ (to get one dollar) is rather bizarre,
  23: **			especially if there should be another macro
  24: **			expansion in the same string.
  25: */
  26: 
  27: expand(s, buf, buflim, e)
  28:     register char *s;
  29:     register char *buf;
  30:     char *buflim;
  31:     register ENVELOPE *e;
  32: {
  33:     register char *q;
  34:     bool skipping;      /* set if conditionally skipping output */
  35:     bool gotone = FALSE;    /* set if any expansion done */
  36:     char xbuf[BUFSIZ];
  37:     register char *xp = xbuf;
  38:     extern char *macvalue();
  39: 
  40: # ifdef DEBUG
  41:     if (tTd(35, 4))
  42:     {
  43:         printf("expand(");
  44:         xputs(s);
  45:         printf(")\n");
  46:     }
  47: # endif DEBUG
  48: 
  49:     skipping = FALSE;
  50:     if (s == NULL)
  51:         s = "";
  52:     for (; *s != '\0'; s++)
  53:     {
  54:         char c;
  55: 
  56:         /*
  57: 		**  Check for non-ordinary (special?) character.
  58: 		**	'q' will be the interpolated quantity.
  59: 		*/
  60: 
  61:         q = NULL;
  62:         c = *s;
  63:         switch (c)
  64:         {
  65:           case CONDIF:      /* see if var set */
  66:             c = *++s;
  67:             skipping = macvalue(c, e) == NULL;
  68:             continue;
  69: 
  70:           case CONDELSE:    /* change state of skipping */
  71:             skipping = !skipping;
  72:             continue;
  73: 
  74:           case CONDFI:      /* stop skipping */
  75:             skipping = FALSE;
  76:             continue;
  77: 
  78:           case '$':     /* macro interpolation */
  79:             c = *++s;
  80:             if (c == '$')
  81:                 break;
  82:             q = macvalue(c & 0177, e);
  83:             if (q == NULL)
  84:                 continue;
  85:             gotone = TRUE;
  86:             break;
  87:         }
  88: 
  89:         /*
  90: 		**  Interpolate q or output one character
  91: 		*/
  92: 
  93:         if (skipping)
  94:             continue;
  95:         while (xp < &xbuf[sizeof xbuf])
  96:         {
  97:             if (q == NULL)
  98:             {
  99:                 *xp++ = c;
 100:                 break;
 101:             }
 102:             if (*q == '\0')
 103:                 break;
 104:             *xp++ = *q++;
 105:         }
 106:     }
 107:     *xp = '\0';
 108: 
 109: # ifdef DEBUG
 110:     if (tTd(35, 4))
 111:     {
 112:         printf("expand ==> ");
 113:         xputs(xbuf);
 114:         printf("\n");
 115:     }
 116: # endif DEBUG
 117: 
 118:     /* recurse as appropriate */
 119:     if (gotone)
 120:     {
 121:         expand(xbuf, buf, buflim, e);
 122:         return;
 123:     }
 124: 
 125:     /* copy results out */
 126:     for (q = buf, xp = xbuf; xp != '\0' && q < buflim-1; )
 127:         *q++ = *xp++;
 128:     *q = '\0';
 129: }
 130: /*
 131: **  DEFINE -- define a macro.
 132: **
 133: **	this would be better done using a #define macro.
 134: **
 135: **	Parameters:
 136: **		n -- the macro name.
 137: **		v -- the macro value.
 138: **		e -- the envelope to store the definition in.
 139: **
 140: **	Returns:
 141: **		none.
 142: **
 143: **	Side Effects:
 144: **		e->e_macro[n] is defined.
 145: **
 146: **	Notes:
 147: **		There is one macro for each ASCII character,
 148: **		although they are not all used.  The currently
 149: **		defined macros are:
 150: **
 151: **		$a   date in ARPANET format (preferring the Date: line
 152: **		     of the message)
 153: **		$b   the current date (as opposed to the date as found
 154: **		     the message) in ARPANET format
 155: **		$c   hop count
 156: **		$d   (current) date in UNIX (ctime) format
 157: **		$e   the SMTP entry message+
 158: **		$f   raw from address
 159: **		$g   translated from address
 160: **		$h   to host
 161: **		$i   queue id
 162: **		$j   official SMTP hostname, used in messages+
 163: **		$l   UNIX-style from line+
 164: **		$n   name of sendmail ("MAILER-DAEMON" on local
 165: **		     net typically)+
 166: **		$o   delimiters ("operators") for address tokens+
 167: **		$p   my process id in decimal
 168: **		$q   the string that becomes an address -- this is
 169: **		     normally used to combine $g & $x.
 170: **		$r   protocol used to talk to sender
 171: **		$s   sender's host name
 172: **		$t   the current time in seconds since 1/1/1970
 173: **		$u   to user
 174: **		$v   version number of sendmail
 175: **		$w   our host name (if it can be determined)
 176: **		$x   signature (full name) of from person
 177: **		$y   the tty id of our terminal
 178: **		$z   home directory of to person
 179: **
 180: **		Macros marked with + must be defined in the
 181: **		configuration file and are used internally, but
 182: **		are not set.
 183: **
 184: **		There are also some macros that can be used
 185: **		arbitrarily to make the configuration file
 186: **		cleaner.  In general all upper-case letters
 187: **		are available.
 188: */
 189: 
 190: define(n, v, e)
 191:     char n;
 192:     char *v;
 193:     register ENVELOPE *e;
 194: {
 195: # ifdef DEBUG
 196:     if (tTd(35, 3))
 197:     {
 198:         printf("define(%c as ", n);
 199:         xputs(v);
 200:         printf(")\n");
 201:     }
 202: # endif DEBUG
 203:     e->e_macro[n & 0177] = v;
 204: }
 205: /*
 206: **  MACVALUE -- return uninterpreted value of a macro.
 207: **
 208: **	Parameters:
 209: **		n -- the name of the macro.
 210: **
 211: **	Returns:
 212: **		The value of n.
 213: **
 214: **	Side Effects:
 215: **		none.
 216: */
 217: 
 218: char *
 219: macvalue(n, e)
 220:     char n;
 221:     register ENVELOPE *e;
 222: {
 223:     n &= 0177;
 224:     while (e != NULL)
 225:     {
 226:         register char *p = e->e_macro[n];
 227: 
 228:         if (p != NULL)
 229:             return (p);
 230:         e = e->e_parent;
 231:     }
 232:     return (NULL);
 233: }

Defined functions

Last modified: 1983-12-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 813
Valid CSS Valid XHTML 1.0 Strict