xref: /csrg-svn/usr.sbin/sendmail/src/macro.c (revision 34921)
122707Sdist /*
2*34921Sbostic  * Copyright (c) 1983 Eric P. Allman
333729Sbostic  * Copyright (c) 1988 Regents of the University of California.
433729Sbostic  * All rights reserved.
533729Sbostic  *
633729Sbostic  * Redistribution and use in source and binary forms are permitted
7*34921Sbostic  * provided that the above copyright notice and this paragraph are
8*34921Sbostic  * duplicated in all such forms and that any documentation,
9*34921Sbostic  * advertising materials, and other materials related to such
10*34921Sbostic  * distribution and use acknowledge that the software was developed
11*34921Sbostic  * by the University of California, Berkeley.  The name of the
12*34921Sbostic  * University may not be used to endorse or promote products derived
13*34921Sbostic  * from this software without specific prior written permission.
14*34921Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15*34921Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16*34921Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1733729Sbostic  */
1822707Sdist 
1922707Sdist #ifndef lint
20*34921Sbostic static char sccsid[] = "@(#)macro.c	5.5 (Berkeley) 06/30/88";
2133729Sbostic #endif /* not lint */
2222707Sdist 
236056Seric # include "sendmail.h"
243379Seric 
253379Seric /*
263379Seric **  EXPAND -- macro expand a string using $x escapes.
273379Seric **
283379Seric **	Parameters:
293379Seric **		s -- the string to expand.
303379Seric **		buf -- the place to put the expansion.
313379Seric **		buflim -- the buffer limit, i.e., the address
323379Seric **			of the last usable position in buf.
336980Seric **		e -- envelope in which to work.
343379Seric **
353379Seric **	Returns:
369382Seric **		none.
373379Seric **
383379Seric **	Side Effects:
393379Seric **		none.
403379Seric */
413379Seric 
426980Seric expand(s, buf, buflim, e)
436980Seric 	register char *s;
446980Seric 	register char *buf;
456980Seric 	char *buflim;
466980Seric 	register ENVELOPE *e;
476980Seric {
4817349Seric 	register char *xp;
496056Seric 	register char *q;
509382Seric 	bool skipping;		/* set if conditionally skipping output */
5117349Seric 	bool recurse = FALSE;	/* set if recursion required */
5217349Seric 	int i;
536056Seric 	char xbuf[BUFSIZ];
548182Seric 	extern char *macvalue();
553379Seric 
563379Seric # ifdef DEBUG
5724941Seric 	if (tTd(35, 24))
586056Seric 	{
596056Seric 		printf("expand(");
606056Seric 		xputs(s);
616056Seric 		printf(")\n");
626056Seric 	}
633379Seric # endif DEBUG
643379Seric 
653387Seric 	skipping = FALSE;
668064Seric 	if (s == NULL)
678064Seric 		s = "";
6817349Seric 	for (xp = xbuf; *s != '\0'; s++)
693379Seric 	{
706056Seric 		char c;
714319Seric 
724319Seric 		/*
736056Seric 		**  Check for non-ordinary (special?) character.
744319Seric 		**	'q' will be the interpolated quantity.
754319Seric 		*/
764319Seric 
773379Seric 		q = NULL;
786056Seric 		c = *s;
796056Seric 		switch (c)
803387Seric 		{
816056Seric 		  case CONDIF:		/* see if var set */
823387Seric 			c = *++s;
838182Seric 			skipping = macvalue(c, e) == NULL;
846056Seric 			continue;
853387Seric 
866056Seric 		  case CONDELSE:	/* change state of skipping */
876056Seric 			skipping = !skipping;
886056Seric 			continue;
893387Seric 
906056Seric 		  case CONDFI:		/* stop skipping */
916056Seric 			skipping = FALSE;
926056Seric 			continue;
933387Seric 
9416146Seric 		  case '\001':		/* macro interpolation */
956056Seric 			c = *++s;
968182Seric 			q = macvalue(c & 0177, e);
979382Seric 			if (q == NULL)
983387Seric 				continue;
996056Seric 			break;
1003387Seric 		}
1013387Seric 
1023379Seric 		/*
1033379Seric 		**  Interpolate q or output one character
1043379Seric 		*/
1053379Seric 
10617349Seric 		if (skipping || xp >= &xbuf[sizeof xbuf])
1073387Seric 			continue;
10817349Seric 		if (q == NULL)
10917349Seric 			*xp++ = c;
11017349Seric 		else
1116056Seric 		{
11217349Seric 			/* copy to end of q or max space remaining in buf */
11317349Seric 			while ((c = *q++) != '\0' && xp < &xbuf[sizeof xbuf - 1])
1146056Seric 			{
11517349Seric 				if (iscntrl(c) && !isspace(c))
11617349Seric 					recurse = TRUE;
1176056Seric 				*xp++ = c;
1186056Seric 			}
1196056Seric 		}
1203379Seric 	}
1216056Seric 	*xp = '\0';
1223379Seric 
1233379Seric # ifdef DEBUG
12424941Seric 	if (tTd(35, 24))
1256056Seric 	{
1268064Seric 		printf("expand ==> ");
1276056Seric 		xputs(xbuf);
1288064Seric 		printf("\n");
1296056Seric 	}
1303379Seric # endif DEBUG
1313379Seric 
1326056Seric 	/* recurse as appropriate */
13317349Seric 	if (recurse)
1349382Seric 	{
1359382Seric 		expand(xbuf, buf, buflim, e);
1369382Seric 		return;
1379382Seric 	}
1386056Seric 
1396056Seric 	/* copy results out */
14017349Seric 	i = buflim - buf - 1;
14117349Seric 	if (i > xp - xbuf)
14217349Seric 		i = xp - xbuf;
14317349Seric 	bcopy(xbuf, buf, i);
14417349Seric 	buf[i] = '\0';
1453379Seric }
1463379Seric /*
1473379Seric **  DEFINE -- define a macro.
1483379Seric **
1493379Seric **	this would be better done using a #define macro.
1503379Seric **
1513379Seric **	Parameters:
1523379Seric **		n -- the macro name.
1533379Seric **		v -- the macro value.
1549382Seric **		e -- the envelope to store the definition in.
1553379Seric **
1563379Seric **	Returns:
1573379Seric **		none.
1583379Seric **
1593379Seric **	Side Effects:
1609382Seric **		e->e_macro[n] is defined.
1614092Seric **
1624092Seric **	Notes:
1634092Seric **		There is one macro for each ASCII character,
1644092Seric **		although they are not all used.  The currently
1654092Seric **		defined macros are:
1664092Seric **
1674202Seric **		$a   date in ARPANET format (preferring the Date: line
1684202Seric **		     of the message)
1694202Seric **		$b   the current date (as opposed to the date as found
1704202Seric **		     the message) in ARPANET format
1714092Seric **		$c   hop count
1724202Seric **		$d   (current) date in UNIX (ctime) format
17310710Seric **		$e   the SMTP entry message+
1744092Seric **		$f   raw from address
1754092Seric **		$g   translated from address
1764092Seric **		$h   to host
1777851Seric **		$i   queue id
1787851Seric **		$j   official SMTP hostname, used in messages+
1794092Seric **		$l   UNIX-style from line+
1804092Seric **		$n   name of sendmail ("MAILER-DAEMON" on local
1814092Seric **		     net typically)+
1824092Seric **		$o   delimiters ("operators") for address tokens+
1834092Seric **		$p   my process id in decimal
1845919Seric **		$q   the string that becomes an address -- this is
1855919Seric **		     normally used to combine $g & $x.
1865187Seric **		$r   protocol used to talk to sender
1875187Seric **		$s   sender's host name
1884092Seric **		$t   the current time in seconds since 1/1/1970
1894092Seric **		$u   to user
1904092Seric **		$v   version number of sendmail
19110407Seric **		$w   our host name (if it can be determined)
1924092Seric **		$x   signature (full name) of from person
1934202Seric **		$y   the tty id of our terminal
1944092Seric **		$z   home directory of to person
1954092Seric **
1964092Seric **		Macros marked with + must be defined in the
1974092Seric **		configuration file and are used internally, but
1984092Seric **		are not set.
1994092Seric **
2004092Seric **		There are also some macros that can be used
2014092Seric **		arbitrarily to make the configuration file
2024092Seric **		cleaner.  In general all upper-case letters
2034092Seric **		are available.
2043379Seric */
2053379Seric 
2069382Seric define(n, v, e)
2073379Seric 	char n;
2083379Seric 	char *v;
2099382Seric 	register ENVELOPE *e;
2103379Seric {
2113379Seric # ifdef DEBUG
21224941Seric 	if (tTd(35, 9))
2136056Seric 	{
2146056Seric 		printf("define(%c as ", n);
2156056Seric 		xputs(v);
2166056Seric 		printf(")\n");
2176056Seric 	}
2183379Seric # endif DEBUG
2199382Seric 	e->e_macro[n & 0177] = v;
2203379Seric }
2214454Seric /*
2224454Seric **  MACVALUE -- return uninterpreted value of a macro.
2234454Seric **
2244454Seric **	Parameters:
2254454Seric **		n -- the name of the macro.
2264454Seric **
2274454Seric **	Returns:
2284454Seric **		The value of n.
2294454Seric **
2304454Seric **	Side Effects:
2314454Seric **		none.
2324454Seric */
2334454Seric 
2344454Seric char *
2358182Seric macvalue(n, e)
2364454Seric 	char n;
2378182Seric 	register ENVELOPE *e;
2384454Seric {
2398182Seric 	n &= 0177;
2408182Seric 	while (e != NULL)
2418182Seric 	{
2428182Seric 		register char *p = e->e_macro[n];
2438182Seric 
2448182Seric 		if (p != NULL)
2458182Seric 			return (p);
2468182Seric 		e = e->e_parent;
2478182Seric 	}
2488182Seric 	return (NULL);
2494454Seric }
250