macro.c revision 168515
1/*
2 * Copyright (c) 1998-2001, 2003, 2006 Sendmail, Inc. and its suppliers.
3 *	All rights reserved.
4 * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
5 * Copyright (c) 1988, 1993
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * By using this file, you agree to the terms and conditions set
9 * forth in the LICENSE file which can be found at the top level of
10 * the sendmail distribution.
11 *
12 */
13
14#include <sendmail.h>
15
16SM_RCSID("@(#)$Id: macro.c,v 8.102 2006/12/21 23:06:10 ca Exp $")
17
18#include <sm/sendmail.h>
19#if MAXMACROID != (BITMAPBITS - 1)
20	ERROR Read the comment in conf.h
21#endif /* MAXMACROID != (BITMAPBITS - 1) */
22
23static char	*MacroName[MAXMACROID + 1];	/* macro id to name table */
24int		NextMacroId = 0240;	/* codes for long named macros */
25/* see sendmail.h: Special characters in rewriting rules. */
26
27
28/*
29**  INITMACROS -- initialize the macro system
30**
31**	This just involves defining some macros that are actually
32**	used internally as metasymbols to be themselves.
33**
34**	Parameters:
35**		none.
36**
37**	Returns:
38**		none.
39**
40**	Side Effects:
41**		initializes several macros to be themselves.
42*/
43
44struct metamac	MetaMacros[] =
45{
46	/* LHS pattern matching characters */
47	{ '*', MATCHZANY },	{ '+', MATCHANY },	{ '-', MATCHONE },
48	{ '=', MATCHCLASS },	{ '~', MATCHNCLASS },
49
50	/* these are RHS metasymbols */
51	{ '#', CANONNET },	{ '@', CANONHOST },	{ ':', CANONUSER },
52	{ '>', CALLSUBR },
53
54	/* the conditional operations */
55	{ '?', CONDIF },	{ '|', CONDELSE },	{ '.', CONDFI },
56
57	/* the hostname lookup characters */
58	{ '[', HOSTBEGIN },	{ ']', HOSTEND },
59	{ '(', LOOKUPBEGIN },	{ ')', LOOKUPEND },
60
61	/* miscellaneous control characters */
62	{ '&', MACRODEXPAND },
63
64	{ '\0', '\0' }
65};
66
67#define MACBINDING(name, mid) \
68		stab(name, ST_MACRO, ST_ENTER)->s_macro = mid; \
69		MacroName[mid] = name;
70
71void
72initmacros(e)
73	ENVELOPE *e;
74{
75	struct metamac *m;
76	int c;
77	char buf[5];
78
79	for (m = MetaMacros; m->metaname != '\0'; m++)
80	{
81		buf[0] = m->metaval;
82		buf[1] = '\0';
83		macdefine(&e->e_macro, A_TEMP, m->metaname, buf);
84	}
85	buf[0] = MATCHREPL;
86	buf[2] = '\0';
87	for (c = '0'; c <= '9'; c++)
88	{
89		buf[1] = c;
90		macdefine(&e->e_macro, A_TEMP, c, buf);
91	}
92
93	/* set defaults for some macros sendmail will use later */
94	macdefine(&e->e_macro, A_PERM, 'n', "MAILER-DAEMON");
95
96	/* set up external names for some internal macros */
97	MACBINDING("opMode", MID_OPMODE);
98	/*XXX should probably add equivalents for all short macros here XXX*/
99}
100
101/*
102**  EXPAND/DOEXPAND -- macro expand a string using $x escapes.
103**
104**	After expansion, the expansion will be in external form (that is,
105**	there will be no sendmail metacharacters and METAQUOTEs will have
106**	been stripped out).
107**
108**	Parameters:
109**		s -- the string to expand.
110**		buf -- the place to put the expansion.
111**		bufsize -- the size of the buffer.
112**		explevel -- the depth of expansion (doexpand only)
113**		e -- envelope in which to work.
114**
115**	Returns:
116**		none.
117**
118**	Side Effects:
119**		none.
120*/
121
122static void doexpand __P(( char *, char *, size_t, int, ENVELOPE *));
123
124static void
125doexpand(s, buf, bufsize, explevel, e)
126	char *s;
127	char *buf;
128	size_t bufsize;
129	int explevel;
130	ENVELOPE *e;
131{
132	char *xp;
133	char *q;
134	bool skipping;		/* set if conditionally skipping output */
135	bool recurse;		/* set if recursion required */
136	size_t i;
137	int skiplev;		/* skipping nesting level */
138	int iflev;		/* if nesting level */
139	bool quotenext;		/* quote the following character */
140	char xbuf[MACBUFSIZE];
141
142	if (tTd(35, 24))
143	{
144		sm_dprintf("expand(");
145		xputs(sm_debug_file(), s);
146		sm_dprintf(")\n");
147	}
148
149	recurse = false;
150	skipping = false;
151	skiplev = 0;
152	iflev = 0;
153	quotenext = false;
154	if (s == NULL)
155		s = "";
156	for (xp = xbuf; *s != '\0'; s++)
157	{
158		int c;
159
160		/*
161		**  Check for non-ordinary (special?) character.
162		**	'q' will be the interpolated quantity.
163		*/
164
165		q = NULL;
166		c = *s & 0377;
167
168		if (quotenext)
169		{
170			quotenext = false;
171			goto simpleinterpolate;
172		}
173
174		switch (c)
175		{
176		  case CONDIF:		/* see if var set */
177			iflev++;
178			c = *++s & 0377;
179			if (skipping)
180				skiplev++;
181			else
182			{
183				char *mv;
184
185				mv = macvalue(c, e);
186				skipping = (mv == NULL || *mv == '\0');
187			}
188			continue;
189
190		  case CONDELSE:	/* change state of skipping */
191			if (iflev == 0)
192				break;	/* XXX: error */
193			if (skiplev == 0)
194				skipping = !skipping;
195			continue;
196
197		  case CONDFI:		/* stop skipping */
198			if (iflev == 0)
199				break;	/* XXX: error */
200			iflev--;
201			if (skiplev == 0)
202				skipping = false;
203			if (skipping)
204				skiplev--;
205			continue;
206
207		  case MACROEXPAND:	/* macro interpolation */
208			c = bitidx(*++s);
209			if (c != '\0')
210				q = macvalue(c, e);
211			else
212			{
213				s--;
214				q = NULL;
215			}
216			if (q == NULL)
217				continue;
218			break;
219
220		  case METAQUOTE:
221			/* next octet completely quoted */
222			quotenext = true;
223			break;
224		}
225
226		/*
227		**  Interpolate q or output one character
228		*/
229
230  simpleinterpolate:
231		if (skipping || xp >= &xbuf[sizeof(xbuf) - 1])
232			continue;
233		if (q == NULL)
234			*xp++ = c;
235		else
236		{
237			/* copy to end of q or max space remaining in buf */
238			bool hiderecurse = false;
239
240			while ((c = *q++) != '\0' &&
241				xp < &xbuf[sizeof(xbuf) - 1])
242			{
243				/* check for any sendmail metacharacters */
244				if (!hiderecurse && (c & 0340) == 0200)
245					recurse = true;
246				*xp++ = c;
247
248				/* give quoted characters a free ride */
249				hiderecurse = (c & 0377) == METAQUOTE;
250			}
251		}
252	}
253	*xp = '\0';
254
255	if (tTd(35, 28))
256	{
257		sm_dprintf("expand(%d) ==> ", explevel);
258		xputs(sm_debug_file(), xbuf);
259		sm_dprintf("\n");
260	}
261
262	/* recurse as appropriate */
263	if (recurse)
264	{
265		if (explevel < MaxMacroRecursion)
266		{
267			doexpand(xbuf, buf, bufsize, explevel + 1, e);
268			return;
269		}
270		syserr("expand: recursion too deep (%d max)",
271			MaxMacroRecursion);
272	}
273
274	/* copy results out */
275	if (explevel == 0)
276		(void) sm_strlcpy(buf, xbuf, bufsize);
277	else
278	{
279		/* leave in internal form */
280		i = xp - xbuf;
281		if (i >= bufsize)
282			i = bufsize - 1;
283		memmove(buf, xbuf, i);
284		buf[i] = '\0';
285	}
286
287	if (tTd(35, 24))
288	{
289		sm_dprintf("expand ==> ");
290		xputs(sm_debug_file(), buf);
291		sm_dprintf("\n");
292	}
293}
294
295void
296expand(s, buf, bufsize, e)
297	char *s;
298	char *buf;
299	size_t bufsize;
300	ENVELOPE *e;
301{
302	doexpand(s, buf, bufsize, 0, e);
303}
304
305/*
306**  MACDEFINE -- bind a macro name to a value
307**
308**	Set a macro to a value, with fancy storage management.
309**	macdefine will make a copy of the value, if required,
310**	and will ensure that the storage for the previous value
311**	is not leaked.
312**
313**	Parameters:
314**		mac -- Macro table.
315**		vclass -- storage class of 'value', ignored if value==NULL.
316**			A_HEAP	means that the value was allocated by
317**				malloc, and that macdefine owns the storage.
318**			A_TEMP	means that value points to temporary storage,
319**				and thus macdefine needs to make a copy.
320**			A_PERM	means that value points to storage that
321**				will remain allocated and unchanged for
322**				at least the lifetime of mac.  Use A_PERM if:
323**				-- value == NULL,
324**				-- value points to a string literal,
325**				-- value was allocated from mac->mac_rpool
326**				   or (in the case of an envelope macro)
327**				   from e->e_rpool,
328**				-- in the case of an envelope macro,
329**				   value is a string member of the envelope
330**				   such as e->e_sender.
331**		id -- Macro id.  This is a single character macro name
332**			such as 'g', or a value returned by macid().
333**		value -- Macro value: either NULL, or a string.
334*/
335
336void
337#if SM_HEAP_CHECK
338macdefine_tagged(mac, vclass, id, value, file, line, grp)
339#else /* SM_HEAP_CHECK */
340macdefine(mac, vclass, id, value)
341#endif /* SM_HEAP_CHECK */
342	MACROS_T *mac;
343	ARGCLASS_T vclass;
344	int id;
345	char *value;
346#if SM_HEAP_CHECK
347	char *file;
348	int line;
349	int grp;
350#endif /* SM_HEAP_CHECK */
351{
352	char *newvalue;
353
354	if (id < 0 || id > MAXMACROID)
355		return;
356
357	if (tTd(35, 9))
358	{
359		sm_dprintf("%sdefine(%s as ",
360			mac->mac_table[id] == NULL ? "" : "re", macname(id));
361		xputs(sm_debug_file(), value);
362		sm_dprintf(")\n");
363	}
364
365	if (mac->mac_rpool == NULL)
366	{
367		char *freeit = NULL;
368
369		if (mac->mac_table[id] != NULL &&
370		    bitnset(id, mac->mac_allocated))
371			freeit = mac->mac_table[id];
372
373		if (value == NULL || vclass == A_HEAP)
374		{
375			sm_heap_checkptr_tagged(value, file, line);
376			newvalue = value;
377			clrbitn(id, mac->mac_allocated);
378		}
379		else
380		{
381#if SM_HEAP_CHECK
382			newvalue = sm_strdup_tagged_x(value, file, line, 0);
383#else /* SM_HEAP_CHECK */
384			newvalue = sm_strdup_x(value);
385#endif /* SM_HEAP_CHECK */
386			setbitn(id, mac->mac_allocated);
387		}
388		mac->mac_table[id] = newvalue;
389		if (freeit != NULL)
390			sm_free(freeit);
391	}
392	else
393	{
394		if (value == NULL || vclass == A_PERM)
395			newvalue = value;
396		else
397			newvalue = sm_rpool_strdup_x(mac->mac_rpool, value);
398		mac->mac_table[id] = newvalue;
399		if (vclass == A_HEAP)
400			sm_free(value);
401	}
402
403#if _FFR_RESET_MACRO_GLOBALS
404	switch (id)
405	{
406	  case 'j':
407		PSTRSET(MyHostName, value);
408		break;
409	}
410#endif /* _FFR_RESET_MACRO_GLOBALS */
411}
412
413/*
414**  MACSET -- set a named macro to a value (low level)
415**
416**	No fancy storage management; the caller takes full responsibility.
417**	Often used with macget; see also macdefine.
418**
419**	Parameters:
420**		mac -- Macro table.
421**		i -- Macro name, specified as an integer offset.
422**		value -- Macro value: either NULL, or a string.
423*/
424
425void
426macset(mac, i, value)
427	MACROS_T *mac;
428	int i;
429	char *value;
430{
431	if (i < 0 || i > MAXMACROID)
432		return;
433
434	if (tTd(35, 9))
435	{
436		sm_dprintf("macset(%s as ", macname(i));
437		xputs(sm_debug_file(), value);
438		sm_dprintf(")\n");
439	}
440	mac->mac_table[i] = value;
441}
442
443/*
444**  MACVALUE -- return uninterpreted value of a macro.
445**
446**	Does fancy path searching.
447**	The low level counterpart is macget.
448**
449**	Parameters:
450**		n -- the name of the macro.
451**		e -- envelope in which to start looking for the macro.
452**
453**	Returns:
454**		The value of n.
455**
456**	Side Effects:
457**		none.
458*/
459
460char *
461macvalue(n, e)
462	int n;
463	ENVELOPE *e;
464{
465	n = bitidx(n);
466	if (e != NULL && e->e_mci != NULL)
467	{
468		char *p = e->e_mci->mci_macro.mac_table[n];
469
470		if (p != NULL)
471			return p;
472	}
473	while (e != NULL)
474	{
475		char *p = e->e_macro.mac_table[n];
476
477		if (p != NULL)
478			return p;
479		if (e == e->e_parent)
480			break;
481		e = e->e_parent;
482	}
483	return GlobalMacros.mac_table[n];
484}
485
486/*
487**  MACNAME -- return the name of a macro given its internal id
488**
489**	Parameter:
490**		n -- the id of the macro
491**
492**	Returns:
493**		The name of n.
494**
495**	Side Effects:
496**		none.
497**
498**	WARNING:
499**		Not thread-safe.
500*/
501
502char *
503macname(n)
504	int n;
505{
506	static char mbuf[2];
507
508	n = (int)(unsigned char)n;
509	if (n > MAXMACROID)
510		return "***OUT OF RANGE MACRO***";
511
512	/* if not ASCII printable, look up the name */
513	if (n <= 0x20 || n > 0x7f)
514	{
515		char *p = MacroName[n];
516
517		if (p != NULL)
518			return p;
519		return "***UNDEFINED MACRO***";
520	}
521
522	/* if in the ASCII graphic range, just return the id directly */
523	mbuf[0] = n;
524	mbuf[1] = '\0';
525	return mbuf;
526}
527
528/*
529**  MACID_PARSE -- return id of macro identified by its name
530**
531**	Parameters:
532**		p -- pointer to name string -- either a single
533**			character or {name}.
534**		ep -- filled in with the pointer to the byte
535**			after the name.
536**
537**	Returns:
538**		0 -- An error was detected.
539**		1..MAXMACROID -- The internal id code for this macro.
540**
541**	Side Effects:
542**		If this is a new macro name, a new id is allocated.
543**		On error, syserr is called.
544*/
545
546int
547macid_parse(p, ep)
548	char *p;
549	char **ep;
550{
551	int mid;
552	char *bp;
553	char mbuf[MAXMACNAMELEN + 1];
554
555	if (tTd(35, 14))
556	{
557		sm_dprintf("macid(");
558		xputs(sm_debug_file(), p);
559		sm_dprintf(") => ");
560	}
561
562	if (*p == '\0' || (p[0] == '{' && p[1] == '}'))
563	{
564		syserr("Name required for macro/class");
565		if (ep != NULL)
566			*ep = p;
567		if (tTd(35, 14))
568			sm_dprintf("NULL\n");
569		return 0;
570	}
571	if (*p != '{')
572	{
573		/* the macro is its own code */
574		if (ep != NULL)
575			*ep = p + 1;
576		if (tTd(35, 14))
577		{
578			char buf[2];
579
580			buf[0] = *p;
581			buf[1] = '\0';
582			xputs(sm_debug_file(), buf);
583			sm_dprintf("\n");
584		}
585		return bitidx(*p);
586	}
587	bp = mbuf;
588	while (*++p != '\0' && *p != '}' && bp < &mbuf[sizeof(mbuf) - 1])
589	{
590		if (isascii(*p) && (isalnum(*p) || *p == '_'))
591			*bp++ = *p;
592		else
593			syserr("Invalid macro/class character %c", *p);
594	}
595	*bp = '\0';
596	mid = -1;
597	if (*p == '\0')
598	{
599		syserr("Unbalanced { on %s", mbuf);	/* missing } */
600	}
601	else if (*p != '}')
602	{
603		syserr("Macro/class name ({%s}) too long (%d chars max)",
604			mbuf, (int) (sizeof(mbuf) - 1));
605	}
606	else if (mbuf[1] == '\0')
607	{
608		/* ${x} == $x */
609		mid = bitidx(mbuf[0]);
610		p++;
611	}
612	else
613	{
614		STAB *s;
615
616		s = stab(mbuf, ST_MACRO, ST_ENTER);
617		if (s->s_macro != 0)
618			mid = s->s_macro;
619		else
620		{
621			if (NextMacroId > MAXMACROID)
622			{
623				syserr("Macro/class {%s}: too many long names",
624					mbuf);
625				s->s_macro = -1;
626			}
627			else
628			{
629				MacroName[NextMacroId] = s->s_name;
630				s->s_macro = mid = NextMacroId++;
631			}
632		}
633		p++;
634	}
635	if (ep != NULL)
636		*ep = p;
637	if (mid < 0 || mid > MAXMACROID)
638	{
639		syserr("Unable to assign macro/class ID (mid = 0x%x)", mid);
640		if (tTd(35, 14))
641			sm_dprintf("NULL\n");
642		return 0;
643	}
644	if (tTd(35, 14))
645		sm_dprintf("0x%x\n", mid);
646	return mid;
647}
648
649/*
650**  WORDINCLASS -- tell if a word is in a specific class
651**
652**	Parameters:
653**		str -- the name of the word to look up.
654**		cl -- the class name.
655**
656**	Returns:
657**		true if str can be found in cl.
658**		false otherwise.
659*/
660
661bool
662wordinclass(str, cl)
663	char *str;
664	int cl;
665{
666	STAB *s;
667
668	s = stab(str, ST_CLASS, ST_FIND);
669	return s != NULL && bitnset(bitidx(cl), s->s_class);
670}
671