13379Seric # include "useful.h"
23379Seric 
3*4454Seric static char SccsId[] = "@(#)macro.c	3.5	10/02/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:
184319Seric **		End of interpolated output.
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 *bp;
314319Seric 	bool skipping;		/* set if conditionally skipping output */
323379Seric 
333379Seric # ifdef DEBUG
344073Seric 	if (Debug > 3)
353379Seric 		printf("expand(%s)\n", s);
363379Seric # endif DEBUG
373379Seric 
383387Seric 	skipping = FALSE;
393379Seric 	for (bp = buf; *s != '\0'; s++)
403379Seric 	{
414319Seric 		register char *q;
424319Seric 
434319Seric 		/*
444319Seric 		**  Check for non-ordinary (special?) character --
454319Seric 		**  always escaped with dollar sign.
464319Seric 		**	'q' will be the interpolated quantity.
474319Seric 		*/
484319Seric 
493379Seric 		q = NULL;
503379Seric 		if (*s == '$')
513387Seric 		{
523387Seric 			char c;
533379Seric 
543387Seric 			c = *++s;
553387Seric 			switch (c)
563387Seric 			{
573387Seric 			  case '?':	/* see if var set */
583387Seric 				c = *++s;
593387Seric 				skipping = Macro[c] == NULL;
603387Seric 				break;
613387Seric 
623387Seric 			  case ':':	/* else */
633387Seric 				skipping = !skipping;
643387Seric 				break;
653387Seric 
663387Seric 			  case '.':	/* end if */
673387Seric 				skipping = FALSE;
683387Seric 				break;
693387Seric 
703387Seric 			  default:
713387Seric 				q = Macro[c & 0177];
723387Seric 				break;
733387Seric 			}
744172Seric 			if (q == NULL && c != '$')
753387Seric 				continue;
763387Seric 		}
773387Seric 
783379Seric 		/*
793379Seric 		**  Interpolate q or output one character
803379Seric 		*/
813379Seric 
823387Seric 		if (skipping)
833387Seric 			continue;
843379Seric 		if (q != NULL)
853379Seric 			bp = expand(q, bp, buflim);
863379Seric 		else if (bp < buflim - 1)
873379Seric 			*bp++ = *s;
883379Seric 	}
893379Seric 	*bp = '\0';
903379Seric 
913379Seric # ifdef DEBUG
924073Seric 	if (Debug > 3)
933379Seric 		printf("expand ==> '%s'\n", buf);
943379Seric # endif DEBUG
953379Seric 
963379Seric 	return (bp);
973379Seric }
983379Seric /*
993379Seric **  DEFINE -- define a macro.
1003379Seric **
1013379Seric **	this would be better done using a #define macro.
1023379Seric **
1033379Seric **	Parameters:
1043379Seric **		n -- the macro name.
1053379Seric **		v -- the macro value.
1063379Seric **
1073379Seric **	Returns:
1083379Seric **		none.
1093379Seric **
1103379Seric **	Side Effects:
1113379Seric **		Macro[n] is defined.
1124092Seric **
1134092Seric **	Notes:
1144092Seric **		There is one macro for each ASCII character,
1154092Seric **		although they are not all used.  The currently
1164092Seric **		defined macros are:
1174092Seric **
1184202Seric **		$a   date in ARPANET format (preferring the Date: line
1194202Seric **		     of the message)
1204202Seric **		$b   the current date (as opposed to the date as found
1214202Seric **		     the message) in ARPANET format
1224092Seric **		$c   hop count
1234202Seric **		$d   (current) date in UNIX (ctime) format
1244092Seric **		$f   raw from address
1254092Seric **		$g   translated from address
1264092Seric **		$h   to host
1274092Seric **		$l   UNIX-style from line+
1284092Seric **		$n   name of sendmail ("MAILER-DAEMON" on local
1294092Seric **		     net typically)+
1304092Seric **		$o   delimiters ("operators") for address tokens+
1314092Seric **		$p   my process id in decimal
1324092Seric **		$t   the current time in seconds since 1/1/1970
1334092Seric **		$u   to user
1344092Seric **		$v   version number of sendmail
1354092Seric **		$x   signature (full name) of from person
1364202Seric **		$y   the tty id of our terminal
1374092Seric **		$z   home directory of to person
1384092Seric **
1394092Seric **		Macros marked with + must be defined in the
1404092Seric **		configuration file and are used internally, but
1414092Seric **		are not set.
1424092Seric **
1434092Seric **		There are also some macros that can be used
1444092Seric **		arbitrarily to make the configuration file
1454092Seric **		cleaner.  In general all upper-case letters
1464092Seric **		are available.
1473379Seric */
1483379Seric 
1493379Seric define(n, v)
1503379Seric 	char n;
1513379Seric 	char *v;
1523379Seric {
1533379Seric # ifdef DEBUG
1544073Seric 	if (Debug > 3)
1553379Seric 		printf("define(%c as %s)\n", n, v);
1563379Seric # endif DEBUG
1573379Seric 	Macro[n & 0177] = v;
1583379Seric }
159*4454Seric /*
160*4454Seric **  MACVALUE -- return uninterpreted value of a macro.
161*4454Seric **
162*4454Seric **	Parameters:
163*4454Seric **		n -- the name of the macro.
164*4454Seric **
165*4454Seric **	Returns:
166*4454Seric **		The value of n.
167*4454Seric **
168*4454Seric **	Side Effects:
169*4454Seric **		none.
170*4454Seric */
171*4454Seric 
172*4454Seric char *
173*4454Seric macvalue(n)
174*4454Seric 	char n;
175*4454Seric {
176*4454Seric 	return (Macro[n & 0177]);
177*4454Seric }
178