xref: /csrg-svn/usr.sbin/sendmail/src/macro.c (revision 17349)
16056Seric # include "sendmail.h"
23379Seric 
3*17349Seric SCCSID(@(#)macro.c	4.3		11/13/84);
43379Seric 
53379Seric /*
63379Seric **  EXPAND -- macro expand a string using $x escapes.
73379Seric **
83379Seric **	Parameters:
93379Seric **		s -- the string to expand.
103379Seric **		buf -- the place to put the expansion.
113379Seric **		buflim -- the buffer limit, i.e., the address
123379Seric **			of the last usable position in buf.
136980Seric **		e -- envelope in which to work.
143379Seric **
153379Seric **	Returns:
169382Seric **		none.
173379Seric **
183379Seric **	Side Effects:
193379Seric **		none.
203379Seric */
213379Seric 
226980Seric expand(s, buf, buflim, e)
236980Seric 	register char *s;
246980Seric 	register char *buf;
256980Seric 	char *buflim;
266980Seric 	register ENVELOPE *e;
276980Seric {
28*17349Seric 	register char *xp;
296056Seric 	register char *q;
309382Seric 	bool skipping;		/* set if conditionally skipping output */
31*17349Seric 	bool recurse = FALSE;	/* set if recursion required */
32*17349Seric 	int i;
336056Seric 	char xbuf[BUFSIZ];
348182Seric 	extern char *macvalue();
353379Seric 
363379Seric # ifdef DEBUG
377677Seric 	if (tTd(35, 4))
386056Seric 	{
396056Seric 		printf("expand(");
406056Seric 		xputs(s);
416056Seric 		printf(")\n");
426056Seric 	}
433379Seric # endif DEBUG
443379Seric 
453387Seric 	skipping = FALSE;
468064Seric 	if (s == NULL)
478064Seric 		s = "";
48*17349Seric 	for (xp = xbuf; *s != '\0'; s++)
493379Seric 	{
506056Seric 		char c;
514319Seric 
524319Seric 		/*
536056Seric 		**  Check for non-ordinary (special?) character.
544319Seric 		**	'q' will be the interpolated quantity.
554319Seric 		*/
564319Seric 
573379Seric 		q = NULL;
586056Seric 		c = *s;
596056Seric 		switch (c)
603387Seric 		{
616056Seric 		  case CONDIF:		/* see if var set */
623387Seric 			c = *++s;
638182Seric 			skipping = macvalue(c, e) == NULL;
646056Seric 			continue;
653387Seric 
666056Seric 		  case CONDELSE:	/* change state of skipping */
676056Seric 			skipping = !skipping;
686056Seric 			continue;
693387Seric 
706056Seric 		  case CONDFI:		/* stop skipping */
716056Seric 			skipping = FALSE;
726056Seric 			continue;
733387Seric 
7416146Seric 		  case '\001':		/* macro interpolation */
756056Seric 			c = *++s;
768182Seric 			q = macvalue(c & 0177, e);
779382Seric 			if (q == NULL)
783387Seric 				continue;
796056Seric 			break;
803387Seric 		}
813387Seric 
823379Seric 		/*
833379Seric 		**  Interpolate q or output one character
843379Seric 		*/
853379Seric 
86*17349Seric 		if (skipping || xp >= &xbuf[sizeof xbuf])
873387Seric 			continue;
88*17349Seric 		if (q == NULL)
89*17349Seric 			*xp++ = c;
90*17349Seric 		else
916056Seric 		{
92*17349Seric 			/* copy to end of q or max space remaining in buf */
93*17349Seric 			while ((c = *q++) != '\0' && xp < &xbuf[sizeof xbuf - 1])
946056Seric 			{
95*17349Seric 				if (iscntrl(c) && !isspace(c))
96*17349Seric 					recurse = TRUE;
976056Seric 				*xp++ = c;
986056Seric 			}
996056Seric 		}
1003379Seric 	}
1016056Seric 	*xp = '\0';
1023379Seric 
1033379Seric # ifdef DEBUG
1047677Seric 	if (tTd(35, 4))
1056056Seric 	{
1068064Seric 		printf("expand ==> ");
1076056Seric 		xputs(xbuf);
1088064Seric 		printf("\n");
1096056Seric 	}
1103379Seric # endif DEBUG
1113379Seric 
1126056Seric 	/* recurse as appropriate */
113*17349Seric 	if (recurse)
1149382Seric 	{
1159382Seric 		expand(xbuf, buf, buflim, e);
1169382Seric 		return;
1179382Seric 	}
1186056Seric 
1196056Seric 	/* copy results out */
120*17349Seric 	i = buflim - buf - 1;
121*17349Seric 	if (i > xp - xbuf)
122*17349Seric 		i = xp - xbuf;
123*17349Seric 	bcopy(xbuf, buf, i);
124*17349Seric 	buf[i] = '\0';
1253379Seric }
1263379Seric /*
1273379Seric **  DEFINE -- define a macro.
1283379Seric **
1293379Seric **	this would be better done using a #define macro.
1303379Seric **
1313379Seric **	Parameters:
1323379Seric **		n -- the macro name.
1333379Seric **		v -- the macro value.
1349382Seric **		e -- the envelope to store the definition in.
1353379Seric **
1363379Seric **	Returns:
1373379Seric **		none.
1383379Seric **
1393379Seric **	Side Effects:
1409382Seric **		e->e_macro[n] is defined.
1414092Seric **
1424092Seric **	Notes:
1434092Seric **		There is one macro for each ASCII character,
1444092Seric **		although they are not all used.  The currently
1454092Seric **		defined macros are:
1464092Seric **
1474202Seric **		$a   date in ARPANET format (preferring the Date: line
1484202Seric **		     of the message)
1494202Seric **		$b   the current date (as opposed to the date as found
1504202Seric **		     the message) in ARPANET format
1514092Seric **		$c   hop count
1524202Seric **		$d   (current) date in UNIX (ctime) format
15310710Seric **		$e   the SMTP entry message+
1544092Seric **		$f   raw from address
1554092Seric **		$g   translated from address
1564092Seric **		$h   to host
1577851Seric **		$i   queue id
1587851Seric **		$j   official SMTP hostname, used in messages+
1594092Seric **		$l   UNIX-style from line+
1604092Seric **		$n   name of sendmail ("MAILER-DAEMON" on local
1614092Seric **		     net typically)+
1624092Seric **		$o   delimiters ("operators") for address tokens+
1634092Seric **		$p   my process id in decimal
1645919Seric **		$q   the string that becomes an address -- this is
1655919Seric **		     normally used to combine $g & $x.
1665187Seric **		$r   protocol used to talk to sender
1675187Seric **		$s   sender's host name
1684092Seric **		$t   the current time in seconds since 1/1/1970
1694092Seric **		$u   to user
1704092Seric **		$v   version number of sendmail
17110407Seric **		$w   our host name (if it can be determined)
1724092Seric **		$x   signature (full name) of from person
1734202Seric **		$y   the tty id of our terminal
1744092Seric **		$z   home directory of to person
1754092Seric **
1764092Seric **		Macros marked with + must be defined in the
1774092Seric **		configuration file and are used internally, but
1784092Seric **		are not set.
1794092Seric **
1804092Seric **		There are also some macros that can be used
1814092Seric **		arbitrarily to make the configuration file
1824092Seric **		cleaner.  In general all upper-case letters
1834092Seric **		are available.
1843379Seric */
1853379Seric 
1869382Seric define(n, v, e)
1873379Seric 	char n;
1883379Seric 	char *v;
1899382Seric 	register ENVELOPE *e;
1903379Seric {
1913379Seric # ifdef DEBUG
1927677Seric 	if (tTd(35, 3))
1936056Seric 	{
1946056Seric 		printf("define(%c as ", n);
1956056Seric 		xputs(v);
1966056Seric 		printf(")\n");
1976056Seric 	}
1983379Seric # endif DEBUG
1999382Seric 	e->e_macro[n & 0177] = v;
2003379Seric }
2014454Seric /*
2024454Seric **  MACVALUE -- return uninterpreted value of a macro.
2034454Seric **
2044454Seric **	Parameters:
2054454Seric **		n -- the name of the macro.
2064454Seric **
2074454Seric **	Returns:
2084454Seric **		The value of n.
2094454Seric **
2104454Seric **	Side Effects:
2114454Seric **		none.
2124454Seric */
2134454Seric 
2144454Seric char *
2158182Seric macvalue(n, e)
2164454Seric 	char n;
2178182Seric 	register ENVELOPE *e;
2184454Seric {
2198182Seric 	n &= 0177;
2208182Seric 	while (e != NULL)
2218182Seric 	{
2228182Seric 		register char *p = e->e_macro[n];
2238182Seric 
2248182Seric 		if (p != NULL)
2258182Seric 			return (p);
2268182Seric 		e = e->e_parent;
2278182Seric 	}
2288182Seric 	return (NULL);
2294454Seric }
230