13379Seric # include "useful.h"
23379Seric 
3*4172Seric static char SccsId[] = "@(#)macro.c	3.2	08/20/81";
43379Seric 
53379Seric char	*Macro[128];
64073Seric extern int	Debug;
73379Seric 
83379Seric /*
93379Seric **  EXPAND -- macro expand a string using $x escapes.
103379Seric **
113379Seric **	Parameters:
123379Seric **		s -- the string to expand.
133379Seric **		buf -- the place to put the expansion.
143379Seric **		buflim -- the buffer limit, i.e., the address
153379Seric **			of the last usable position in buf.
163379Seric **
173379Seric **	Returns:
183379Seric **		buf.
193379Seric **
203379Seric **	Side Effects:
213379Seric **		none.
223379Seric */
233379Seric 
243379Seric char *
253379Seric expand(s, buf, buflim)
263379Seric 	register char *s;
273379Seric 	register char *buf;
283379Seric 	char *buflim;
293379Seric {
303379Seric 	register char *q;
313379Seric 	register char *bp;
323387Seric 	bool skipping;
333379Seric 
343379Seric # ifdef DEBUG
354073Seric 	if (Debug > 3)
363379Seric 		printf("expand(%s)\n", s);
373379Seric # endif DEBUG
383379Seric 
393387Seric 	skipping = FALSE;
403379Seric 	for (bp = buf; *s != '\0'; s++)
413379Seric 	{
423379Seric 		/* q will be the interpolated quantity */
433379Seric 		q = NULL;
443379Seric 		if (*s == '$')
453387Seric 		{
463387Seric 			char c;
473379Seric 
483387Seric 			c = *++s;
493387Seric 			switch (c)
503387Seric 			{
513387Seric 			  case '?':	/* see if var set */
523387Seric 				c = *++s;
533387Seric 				skipping = Macro[c] == NULL;
543387Seric 				break;
553387Seric 
563387Seric 			  case ':':	/* else */
573387Seric 				skipping = !skipping;
583387Seric 				break;
593387Seric 
603387Seric 			  case '.':	/* end if */
613387Seric 				skipping = FALSE;
623387Seric 				break;
633387Seric 
643387Seric 			  default:
653387Seric 				q = Macro[c & 0177];
663387Seric 				break;
673387Seric 			}
68*4172Seric 			if (q == NULL && c != '$')
693387Seric 				continue;
703387Seric 		}
713387Seric 
723379Seric 		/*
733379Seric 		**  Interpolate q or output one character
743379Seric 		*/
753379Seric 
763387Seric 		if (skipping)
773387Seric 			continue;
783379Seric 		if (q != NULL)
793379Seric 			bp = expand(q, bp, buflim);
803379Seric 		else if (bp < buflim - 1)
813379Seric 			*bp++ = *s;
823379Seric 	}
833379Seric 	*bp = '\0';
843379Seric 
853379Seric # ifdef DEBUG
864073Seric 	if (Debug > 3)
873379Seric 		printf("expand ==> '%s'\n", buf);
883379Seric # endif DEBUG
893379Seric 
903379Seric 	return (bp);
913379Seric }
923379Seric /*
933379Seric **  DEFINE -- define a macro.
943379Seric **
953379Seric **	this would be better done using a #define macro.
963379Seric **
973379Seric **	Parameters:
983379Seric **		n -- the macro name.
993379Seric **		v -- the macro value.
1003379Seric **
1013379Seric **	Returns:
1023379Seric **		none.
1033379Seric **
1043379Seric **	Side Effects:
1053379Seric **		Macro[n] is defined.
1064092Seric **
1074092Seric **	Notes:
1084092Seric **		There is one macro for each ASCII character,
1094092Seric **		although they are not all used.  The currently
1104092Seric **		defined macros are:
1114092Seric **
1124092Seric **		$a   date in arpa format
1134092Seric **		$c   hop count
1144092Seric **		$d   date in ctime format
1154092Seric **		$f   raw from address
1164092Seric **		$g   translated from address
1174092Seric **		$h   to host
1184092Seric **		$l   UNIX-style from line+
1194092Seric **		$n   name of sendmail ("MAILER-DAEMON" on local
1204092Seric **		     net typically)+
1214092Seric **		$o   delimiters ("operators") for address tokens+
1224092Seric **		$p   my process id in decimal
1234092Seric **		$t   the current time in seconds since 1/1/1970
1244092Seric **		$u   to user
1254092Seric **		$v   version number of sendmail
1264092Seric **		$x   signature (full name) of from person
1274092Seric **		$z   home directory of to person
1284092Seric **
1294092Seric **		Macros marked with + must be defined in the
1304092Seric **		configuration file and are used internally, but
1314092Seric **		are not set.
1324092Seric **
1334092Seric **		There are also some macros that can be used
1344092Seric **		arbitrarily to make the configuration file
1354092Seric **		cleaner.  In general all upper-case letters
1364092Seric **		are available.
1373379Seric */
1383379Seric 
1393379Seric define(n, v)
1403379Seric 	char n;
1413379Seric 	char *v;
1423379Seric {
1433379Seric # ifdef DEBUG
1444073Seric 	if (Debug > 3)
1453379Seric 		printf("define(%c as %s)\n", n, v);
1463379Seric # endif DEBUG
1473379Seric 	Macro[n & 0177] = v;
1483379Seric }
149