2 * Copyright (c) 1998-2001, 2003, 2006, 2007 Proofpoint, Inc. and its suppliers.
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.
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.
16 SM_RCSID("@(#)$Id: macro.c,v 8.108 2013-11-22 20:51:55 ca Exp $")
18 #include <sm/sendmail.h>
19 #if MAXMACROID != (BITMAPBITS - 1)
20 ERROR Read the comment in conf.h
23 static char *MacroName[MAXMACROID + 1]; /* macro id to name table */
26 ** Codes for long named macros.
27 ** See also macname():
28 * if not ASCII printable, look up the name *
29 if (n <= 0x20 || n > 0x7f)
30 ** First use 1 to NEXTMACROID_L, then use NEXTMACROID_H to MAXMACROID.
33 #define NEXTMACROID_L 037
34 #define NEXTMACROID_H 0240
37 /* table for next id in non-printable ASCII range: disallow some value */
38 static int NextMIdTable[] =
75 #define NEXTMACROID(mid) ( \
76 (mid < NEXTMACROID_L) ? (NextMIdTable[mid]) : \
77 ((mid < NEXTMACROID_H) ? NEXTMACROID_H : (mid + 1)))
79 int NextMacroId = 1; /* codes for long named macros */
80 /* see sendmail.h: Special characters in rewriting rules. */
81 #else /* _FFR_MORE_MACROS */
82 int NextMacroId = 0240; /* codes for long named macros */
83 #define NEXTMACROID(mid) ((mid) + 1)
84 #endif /* _FFR_MORE_MACROS */
87 ** INITMACROS -- initialize the macro system
89 ** This just involves defining some macros that are actually
90 ** used internally as metasymbols to be themselves.
99 ** initializes several macros to be themselves.
102 struct metamac MetaMacros[] =
104 /* LHS pattern matching characters */
105 { '*', MATCHZANY }, { '+', MATCHANY }, { '-', MATCHONE },
106 { '=', MATCHCLASS }, { '~', MATCHNCLASS },
108 /* these are RHS metasymbols */
109 { '#', CANONNET }, { '@', CANONHOST }, { ':', CANONUSER },
112 /* the conditional operations */
113 { '?', CONDIF }, { '|', CONDELSE }, { '.', CONDFI },
115 /* the hostname lookup characters */
116 { '[', HOSTBEGIN }, { ']', HOSTEND },
117 { '(', LOOKUPBEGIN }, { ')', LOOKUPEND },
119 /* miscellaneous control characters */
120 { '&', MACRODEXPAND },
125 #define MACBINDING(name, mid) \
126 stab(name, ST_MACRO, ST_ENTER)->s_macro = mid; \
127 MacroName[mid] = name;
137 for (m = MetaMacros; m->metaname != '\0'; m++)
141 macdefine(&e->e_macro, A_TEMP, m->metaname, buf);
145 for (c = '0'; c <= '9'; c++)
148 macdefine(&e->e_macro, A_TEMP, c, buf);
151 /* set defaults for some macros sendmail will use later */
152 macdefine(&e->e_macro, A_PERM, 'n', "MAILER-DAEMON");
154 /* set up external names for some internal macros */
155 MACBINDING("opMode", MID_OPMODE);
156 /*XXX should probably add equivalents for all short macros here XXX*/
160 ** EXPAND/DOEXPAND -- macro expand a string using $x escapes.
161 ** (including conditionals, e.g., $?x Y $| N $.)
164 ** s -- the string to expand. [i]
165 ** buf -- the place to put the expansion. [i]
166 ** bufsize -- the size of the buffer.
167 ** explevel -- the depth of expansion (doexpand only)
168 ** e -- envelope in which to work.
174 static void doexpand __P(( char *, char *, size_t, int, ENVELOPE *));
177 doexpand(s, buf, bufsize, explevel, e)
186 bool skipping; /* set if conditionally skipping output */
187 bool recurse; /* set if recursion required */
189 int skiplev; /* skipping nesting level */
190 int iflev; /* if nesting level */
191 bool quotenext; /* quote the following character */
192 char xbuf[MACBUFSIZE];
196 sm_dprintf("expand(");
197 xputs(sm_debug_file(), s);
208 for (xp = xbuf; *s != '\0'; s++)
213 ** Check for non-ordinary (special?) character.
214 ** 'q' will be the interpolated quantity.
223 goto simpleinterpolate;
228 case CONDIF: /* see if var set */
238 skipping = (mv == NULL || *mv == '\0');
242 case CONDELSE: /* change state of skipping */
244 break; /* XXX: error */
246 skipping = !skipping;
249 case CONDFI: /* stop skipping */
251 break; /* XXX: error */
259 case MACROEXPAND: /* macro interpolation */
273 /* next octet completely quoted */
279 ** Interpolate q or output one character
283 if (skipping || xp >= &xbuf[sizeof(xbuf) - 1])
289 /* copy to end of q or max space remaining in buf */
290 bool hiderecurse = false;
292 while ((c = *q++) != '\0' &&
293 xp < &xbuf[sizeof(xbuf) - 1])
295 /* check for any sendmail metacharacters */
296 if (!hiderecurse && (c & 0340) == 0200)
300 /* give quoted characters a free ride */
301 hiderecurse = (c & 0377) == METAQUOTE;
309 sm_dprintf("expand(%d) ==> ", explevel);
310 xputs(sm_debug_file(), xbuf);
314 /* recurse as appropriate */
317 if (explevel < MaxMacroRecursion)
319 doexpand(xbuf, buf, bufsize, explevel + 1, e);
322 syserr("expand: recursion too deep (%d max)",
326 /* copy results out */
328 (void) sm_strlcpy(buf, xbuf, bufsize);
331 /* leave in internal form */
335 memmove(buf, xbuf, i);
341 sm_dprintf("expand ==> ");
342 xputs(sm_debug_file(), buf);
348 expand(s, buf, bufsize, e)
354 doexpand(s, buf, bufsize, 0, e);
358 ** MACTABCLEAR -- clear entire macro table
361 ** mac -- Macro table.
367 ** clears entire mac structure including rpool pointer!
376 if (mac->mac_rpool == NULL)
378 for (i = 0; i < MAXMACROID; i++)
379 SM_FREE(mac->mac_table[i]);
381 memset((char *) mac, '\0', sizeof(*mac));
385 ** MACDEFINE -- bind a macro name to a value
387 ** Set a macro to a value, with fancy storage management.
388 ** macdefine will make a copy of the value, if required,
389 ** and will ensure that the storage for the previous value
393 ** mac -- Macro table.
394 ** vclass -- storage class of 'value', ignored if value==NULL.
395 ** A_HEAP means that the value was allocated by
396 ** malloc, and that macdefine owns the storage.
397 ** A_TEMP means that value points to temporary storage,
398 ** and thus macdefine needs to make a copy.
399 ** A_PERM means that value points to storage that
400 ** will remain allocated and unchanged for
401 ** at least the lifetime of mac. Use A_PERM if:
403 ** -- value points to a string literal,
404 ** -- value was allocated from mac->mac_rpool
405 ** or (in the case of an envelope macro)
407 ** -- in the case of an envelope macro,
408 ** value is a string member of the envelope
409 ** such as e->e_sender.
410 ** id -- Macro id. This is a single character macro name
411 ** such as 'g', or a value returned by macid().
412 ** value -- Macro value: either NULL, or a string.
420 macdefine_tagged(mac, vclass, id, value, file, line, grp)
422 macdefine(mac, vclass, id, value)
436 if (id < 0 || id > MAXMACROID)
441 sm_dprintf("%sdefine(%s as ",
442 mac->mac_table[id] == NULL ? "" : "re", macname(id));
443 xputs(sm_debug_file(), value);
447 // if (('j' == id || 'm' == id) && !addr_is_ascii(value))
448 // return an error/warning to caller and let them handle it.
451 if (mac->mac_rpool == NULL)
455 if (mac->mac_table[id] != NULL &&
456 bitnset(id, mac->mac_allocated))
457 freeit = mac->mac_table[id];
459 if (value == NULL || vclass == A_HEAP)
461 sm_heap_checkptr_tagged(value, file, line);
463 clrbitn(id, mac->mac_allocated);
468 newvalue = sm_strdup_tagged_x(value, file, line, 0);
470 newvalue = sm_strdup_x(value);
472 setbitn(id, mac->mac_allocated);
474 mac->mac_table[id] = newvalue;
480 if (value == NULL || vclass == A_PERM)
483 newvalue = sm_rpool_strdup_x(mac->mac_rpool, value);
484 mac->mac_table[id] = newvalue;
485 if (vclass == A_HEAP)
489 #if _FFR_RESET_MACRO_GLOBALS
493 PSTRSET(MyHostName, value);
496 #endif /* _FFR_RESET_MACRO_GLOBALS */
500 ** MACSET -- set a named macro to a value (low level)
502 ** No fancy storage management; the caller takes full responsibility.
503 ** Often used with macget; see also macdefine.
506 ** mac -- Macro table.
507 ** i -- Macro name, specified as an integer offset.
508 ** value -- Macro value: either NULL, or a string.
515 macset(mac, i, value)
520 if (i < 0 || i > MAXMACROID)
525 sm_dprintf("macset(%s as ", macname(i));
526 xputs(sm_debug_file(), value);
529 mac->mac_table[i] = value;
533 ** MACVALUE -- return uninterpreted value of a macro.
535 ** Does fancy path searching.
536 ** The low level counterpart is macget.
539 ** n -- the name of the macro.
540 ** e -- envelope in which to start looking for the macro.
555 if (e != NULL && e->e_mci != NULL)
557 char *p = e->e_mci->mci_macro.mac_table[n];
564 char *p = e->e_macro.mac_table[n];
568 if (e == e->e_parent)
572 #if _FFR_BLANKENV_MACV
573 if (LOOKUP_MACRO_IN_BLANKENV && e != &BlankEnvelope)
575 char *p = BlankEnvelope.e_macro.mac_table[n];
581 return GlobalMacros.mac_table[n];
585 ** MACNAME -- return the name of a macro given its internal id
588 ** n -- the id of the macro
606 n = (int)(unsigned char)n;
608 return "***OUT OF RANGE MACRO***";
610 /* if not ASCII printable, look up the name */
611 if (n <= 0x20 || n > 0x7f)
613 char *p = MacroName[n];
617 return "***UNDEFINED MACRO***";
620 /* if in the ASCII graphic range, just return the id directly */
627 ** MACID_PARSE -- return id of macro identified by its name
630 ** p -- pointer to name string -- either a single
631 ** character or {name}.
632 ** ep -- filled in with the pointer to the byte
636 ** 0 -- An error was detected.
637 ** 1..MAXMACROID -- The internal id code for this macro.
640 ** If this is a new macro name, a new id is allocated.
641 ** On error, syserr is called.
651 char mbuf[MAXMACNAMELEN + 1];
655 sm_dprintf("macid(");
656 xputs(sm_debug_file(), p);
660 if (*p == '\0' || (p[0] == '{' && p[1] == '}'))
662 syserr("Name required for macro/class");
666 sm_dprintf("NULL\n");
671 /* the macro is its own code */
680 xputs(sm_debug_file(), buf);
686 while (*++p != '\0' && *p != '}' && bp < &mbuf[sizeof(mbuf) - 1])
688 if (isascii(*p) && (isalnum(*p) || *p == '_'))
691 syserr("Invalid macro/class character %c", *p);
697 syserr("Unbalanced { on %s", mbuf); /* missing } */
701 syserr("Macro/class name ({%s}) too long (%d chars max)",
702 mbuf, (int) (sizeof(mbuf) - 1));
704 else if (mbuf[1] == '\0' && mbuf[0] >= 0x20)
707 mid = bitidx(mbuf[0]);
714 s = stab(mbuf, ST_MACRO, ST_ENTER);
719 if (NextMacroId > MAXMACROID)
721 syserr("Macro/class {%s}: too many long names",
727 MacroName[NextMacroId] = s->s_name;
728 s->s_macro = mid = NextMacroId;
729 NextMacroId = NEXTMACROID(NextMacroId);
736 if (mid < 0 || mid > MAXMACROID)
738 syserr("Unable to assign macro/class ID (mid = 0x%x)", mid);
740 sm_dprintf("NULL\n");
744 sm_dprintf("0x%x\n", mid);
749 ** WORDINCLASS -- tell if a word is in a specific class
752 ** str -- the name of the word to look up.
753 ** cl -- the class name.
756 ** true if str can be found in cl.
773 s = stab(p, ST_DYNMAP, ST_FIND);
777 s = stab(str, ST_CLASS, ST_FIND);
778 return s != NULL && bitnset(bitidx(cl), s->s_class);
781 map = &s->s_dynclass;
782 SM_REQUIRE(NULL != map);
783 SM_REQUIRE(!SM_IS_EMPTY(str));
784 if (bitset(MF_OPENBOGUS, map->map_mflags))
786 /* need to set some error! */
791 if (!SM_IS_EMPTY(map->map_tag))
793 sm_strlcpy(key, map->map_tag, sizeof(key));
794 sm_strlcat(key, ":", sizeof(key));
796 sm_strlcat(key, str, sizeof(key));
798 p = (map->map_class->map_lookup)(map, key, NULL, &status);
801 if ((EX_OK == status && NULL == p) || EX_NOTFOUND == status)
804 sm_syslog(LOG_WARNING, CurEnv->e_id,
805 "dynamic class: A{%s}: map lookup failed: key=%s, status=%d",
806 map->map_mname, key, status);
808 /* Note: this error is shown to the client, so do not "leak" info */
809 usrerr("451 4.3.1 temporary error");