Import sendmail 8.13.4 into a new contrib directory as the first step
[dragonfly.git] / contrib / sendmail-8.13.4 / sendmail / macro.c
blobaf8f6d5b19456b73ac7b782204bbafc4b8530f4f
1 /*
2 * Copyright (c) 1998-2001, 2003 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.
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.
14 #include <sendmail.h>
16 SM_RCSID("@(#)$Id: macro.c,v 8.88 2003/09/05 23:11:18 ca Exp $")
18 #if MAXMACROID != (BITMAPBITS - 1)
19 ERROR Read the comment in conf.h
20 #endif /* MAXMACROID != (BITMAPBITS - 1) */
22 static char *MacroName[MAXMACROID + 1]; /* macro id to name table */
23 int NextMacroId = 0240; /* codes for long named macros */
26 ** INITMACROS -- initialize the macro system
28 ** This just involves defining some macros that are actually
29 ** used internally as metasymbols to be themselves.
31 ** Parameters:
32 ** none.
34 ** Returns:
35 ** none.
37 ** Side Effects:
38 ** initializes several macros to be themselves.
41 struct metamac MetaMacros[] =
43 /* LHS pattern matching characters */
44 { '*', MATCHZANY }, { '+', MATCHANY }, { '-', MATCHONE },
45 { '=', MATCHCLASS }, { '~', MATCHNCLASS },
47 /* these are RHS metasymbols */
48 { '#', CANONNET }, { '@', CANONHOST }, { ':', CANONUSER },
49 { '>', CALLSUBR },
51 /* the conditional operations */
52 { '?', CONDIF }, { '|', CONDELSE }, { '.', CONDFI },
54 /* the hostname lookup characters */
55 { '[', HOSTBEGIN }, { ']', HOSTEND },
56 { '(', LOOKUPBEGIN }, { ')', LOOKUPEND },
58 /* miscellaneous control characters */
59 { '&', MACRODEXPAND },
61 { '\0', '\0' }
64 #define MACBINDING(name, mid) \
65 stab(name, ST_MACRO, ST_ENTER)->s_macro = mid; \
66 MacroName[mid] = name;
68 void
69 initmacros(e)
70 register ENVELOPE *e;
72 register struct metamac *m;
73 register int c;
74 char buf[5];
76 for (m = MetaMacros; m->metaname != '\0'; m++)
78 buf[0] = m->metaval;
79 buf[1] = '\0';
80 macdefine(&e->e_macro, A_TEMP, m->metaname, buf);
82 buf[0] = MATCHREPL;
83 buf[2] = '\0';
84 for (c = '0'; c <= '9'; c++)
86 buf[1] = c;
87 macdefine(&e->e_macro, A_TEMP, c, buf);
90 /* set defaults for some macros sendmail will use later */
91 macdefine(&e->e_macro, A_PERM, 'n', "MAILER-DAEMON");
93 /* set up external names for some internal macros */
94 MACBINDING("opMode", MID_OPMODE);
95 /*XXX should probably add equivalents for all short macros here XXX*/
98 ** EXPAND -- macro expand a string using $x escapes.
100 ** Parameters:
101 ** s -- the string to expand.
102 ** buf -- the place to put the expansion.
103 ** bufsize -- the size of the buffer.
104 ** e -- envelope in which to work.
106 ** Returns:
107 ** none.
109 ** Side Effects:
110 ** none.
113 void
114 expand(s, buf, bufsize, e)
115 register char *s;
116 register char *buf;
117 size_t bufsize;
118 register ENVELOPE *e;
120 register char *xp;
121 register char *q;
122 bool skipping; /* set if conditionally skipping output */
123 bool recurse; /* set if recursion required */
124 size_t i;
125 int skiplev; /* skipping nesting level */
126 int iflev; /* if nesting level */
127 char xbuf[MACBUFSIZE];
128 static int explevel = 0;
130 if (tTd(35, 24))
132 sm_dprintf("expand(");
133 xputs(sm_debug_file(), s);
134 sm_dprintf(")\n");
137 recurse = false;
138 skipping = false;
139 skiplev = 0;
140 iflev = 0;
141 if (s == NULL)
142 s = "";
143 for (xp = xbuf; *s != '\0'; s++)
145 int c;
148 ** Check for non-ordinary (special?) character.
149 ** 'q' will be the interpolated quantity.
152 q = NULL;
153 c = *s;
154 switch (c & 0377)
156 case CONDIF: /* see if var set */
157 iflev++;
158 c = *++s;
159 if (skipping)
160 skiplev++;
161 else
163 char *mv;
165 mv = macvalue(c, e);
166 skipping = (mv == NULL || *mv == '\0');
168 continue;
170 case CONDELSE: /* change state of skipping */
171 if (iflev == 0)
172 break; /* XXX: error */
173 if (skiplev == 0)
174 skipping = !skipping;
175 continue;
177 case CONDFI: /* stop skipping */
178 if (iflev == 0)
179 break; /* XXX: error */
180 iflev--;
181 if (skiplev == 0)
182 skipping = false;
183 if (skipping)
184 skiplev--;
185 continue;
187 case MACROEXPAND: /* macro interpolation */
188 c = bitidx(*++s);
189 if (c != '\0')
190 q = macvalue(c, e);
191 else
193 s--;
194 q = NULL;
196 if (q == NULL)
197 continue;
198 break;
202 ** Interpolate q or output one character
205 if (skipping || xp >= &xbuf[sizeof xbuf - 1])
206 continue;
207 if (q == NULL)
208 *xp++ = c;
209 else
211 /* copy to end of q or max space remaining in buf */
212 while ((c = *q++) != '\0' && xp < &xbuf[sizeof xbuf - 1])
214 /* check for any sendmail metacharacters */
215 if ((c & 0340) == 0200)
216 recurse = true;
217 *xp++ = c;
221 *xp = '\0';
223 if (tTd(35, 24))
225 sm_dprintf("expand ==> ");
226 xputs(sm_debug_file(), xbuf);
227 sm_dprintf("\n");
230 /* recurse as appropriate */
231 if (recurse)
233 if (explevel < MaxMacroRecursion)
235 explevel++;
236 expand(xbuf, buf, bufsize, e);
237 explevel--;
238 return;
240 syserr("expand: recursion too deep (%d max)",
241 MaxMacroRecursion);
244 /* copy results out */
245 i = xp - xbuf;
246 if (i >= bufsize)
247 i = bufsize - 1;
248 memmove(buf, xbuf, i);
249 buf[i] = '\0';
253 ** MACDEFINE -- bind a macro name to a value
255 ** Set a macro to a value, with fancy storage management.
256 ** macdefine will make a copy of the value, if required,
257 ** and will ensure that the storage for the previous value
258 ** is not leaked.
260 ** Parameters:
261 ** mac -- Macro table.
262 ** vclass -- storage class of 'value', ignored if value==NULL.
263 ** A_HEAP means that the value was allocated by
264 ** malloc, and that macdefine owns the storage.
265 ** A_TEMP means that value points to temporary storage,
266 ** and thus macdefine needs to make a copy.
267 ** A_PERM means that value points to storage that
268 ** will remain allocated and unchanged for
269 ** at least the lifetime of mac. Use A_PERM if:
270 ** -- value == NULL,
271 ** -- value points to a string literal,
272 ** -- value was allocated from mac->mac_rpool
273 ** or (in the case of an envelope macro)
274 ** from e->e_rpool,
275 ** -- in the case of an envelope macro,
276 ** value is a string member of the envelope
277 ** such as e->e_sender.
278 ** id -- Macro id. This is a single character macro name
279 ** such as 'g', or a value returned by macid().
280 ** value -- Macro value: either NULL, or a string.
283 void
284 #if SM_HEAP_CHECK
285 macdefine_tagged(mac, vclass, id, value, file, line, grp)
286 #else /* SM_HEAP_CHECK */
287 macdefine(mac, vclass, id, value)
288 #endif /* SM_HEAP_CHECK */
289 MACROS_T *mac;
290 ARGCLASS_T vclass;
291 int id;
292 char *value;
293 #if SM_HEAP_CHECK
294 char *file;
295 int line;
296 int grp;
297 #endif /* SM_HEAP_CHECK */
299 char *newvalue;
301 if (id < 0 || id > MAXMACROID)
302 return;
304 if (tTd(35, 9))
306 sm_dprintf("%sdefine(%s as ",
307 mac->mac_table[id] == NULL ? "" : "re", macname(id));
308 xputs(sm_debug_file(), value);
309 sm_dprintf(")\n");
312 if (mac->mac_rpool == NULL)
314 char *freeit = NULL;
316 if (mac->mac_table[id] != NULL &&
317 bitnset(id, mac->mac_allocated))
318 freeit = mac->mac_table[id];
320 if (value == NULL || vclass == A_HEAP)
322 sm_heap_checkptr_tagged(value, file, line);
323 newvalue = value;
324 clrbitn(id, mac->mac_allocated);
326 else
328 #if SM_HEAP_CHECK
329 newvalue = sm_strdup_tagged_x(value, file, line, 0);
330 #else /* SM_HEAP_CHECK */
331 newvalue = sm_strdup_x(value);
332 #endif /* SM_HEAP_CHECK */
333 setbitn(id, mac->mac_allocated);
335 mac->mac_table[id] = newvalue;
336 if (freeit != NULL)
337 sm_free(freeit);
339 else
341 if (value == NULL || vclass == A_PERM)
342 newvalue = value;
343 else
344 newvalue = sm_rpool_strdup_x(mac->mac_rpool, value);
345 mac->mac_table[id] = newvalue;
346 if (vclass == A_HEAP)
347 sm_free(value);
350 #if _FFR_RESET_MACRO_GLOBALS
351 switch (id)
353 case 'j':
354 PSTRSET(MyHostName, value);
355 break;
357 #endif /* _FFR_RESET_MACRO_GLOBALS */
361 ** MACSET -- set a named macro to a value (low level)
363 ** No fancy storage management; the caller takes full responsibility.
364 ** Often used with macget; see also macdefine.
366 ** Parameters:
367 ** mac -- Macro table.
368 ** i -- Macro name, specified as an integer offset.
369 ** value -- Macro value: either NULL, or a string.
372 void
373 macset(mac, i, value)
374 MACROS_T *mac;
375 int i;
376 char *value;
378 if (i < 0 || i > MAXMACROID)
379 return;
381 if (tTd(35, 9))
383 sm_dprintf("macset(%s as ", macname(i));
384 xputs(sm_debug_file(), value);
385 sm_dprintf(")\n");
387 mac->mac_table[i] = value;
391 ** MACVALUE -- return uninterpreted value of a macro.
393 ** Does fancy path searching.
394 ** The low level counterpart is macget.
396 ** Parameters:
397 ** n -- the name of the macro.
398 ** e -- envelope in which to start looking for the macro.
400 ** Returns:
401 ** The value of n.
403 ** Side Effects:
404 ** none.
407 char *
408 macvalue(n, e)
409 int n;
410 register ENVELOPE *e;
412 n = bitidx(n);
413 if (e != NULL && e->e_mci != NULL)
415 register char *p = e->e_mci->mci_macro.mac_table[n];
417 if (p != NULL)
418 return p;
420 while (e != NULL)
422 register char *p = e->e_macro.mac_table[n];
424 if (p != NULL)
425 return p;
426 if (e == e->e_parent)
427 break;
428 e = e->e_parent;
430 return GlobalMacros.mac_table[n];
433 ** MACNAME -- return the name of a macro given its internal id
435 ** Parameter:
436 ** n -- the id of the macro
438 ** Returns:
439 ** The name of n.
441 ** Side Effects:
442 ** none.
445 char *
446 macname(n)
447 int n;
449 static char mbuf[2];
451 n = bitidx(n);
452 if (bitset(0200, n))
454 char *p = MacroName[n];
456 if (p != NULL)
457 return p;
458 return "***UNDEFINED MACRO***";
460 mbuf[0] = n;
461 mbuf[1] = '\0';
462 return mbuf;
465 ** MACID_PARSE -- return id of macro identified by its name
467 ** Parameters:
468 ** p -- pointer to name string -- either a single
469 ** character or {name}.
470 ** ep -- filled in with the pointer to the byte
471 ** after the name.
473 ** Returns:
474 ** 0 -- An error was detected.
475 ** 1..255 -- The internal id code for this macro.
477 ** Side Effects:
478 ** If this is a new macro name, a new id is allocated.
479 ** On error, syserr is called.
483 macid_parse(p, ep)
484 register char *p;
485 char **ep;
487 int mid;
488 register char *bp;
489 char mbuf[MAXMACNAMELEN + 1];
491 if (tTd(35, 14))
493 sm_dprintf("macid(");
494 xputs(sm_debug_file(), p);
495 sm_dprintf(") => ");
498 if (*p == '\0' || (p[0] == '{' && p[1] == '}'))
500 syserr("Name required for macro/class");
501 if (ep != NULL)
502 *ep = p;
503 if (tTd(35, 14))
504 sm_dprintf("NULL\n");
505 return 0;
507 if (*p != '{')
509 /* the macro is its own code */
510 if (ep != NULL)
511 *ep = p + 1;
512 if (tTd(35, 14))
513 sm_dprintf("%c\n", bitidx(*p));
514 return bitidx(*p);
516 bp = mbuf;
517 while (*++p != '\0' && *p != '}' && bp < &mbuf[sizeof mbuf - 1])
519 if (isascii(*p) && (isalnum(*p) || *p == '_'))
520 *bp++ = *p;
521 else
522 syserr("Invalid macro/class character %c", *p);
524 *bp = '\0';
525 mid = -1;
526 if (*p == '\0')
528 syserr("Unbalanced { on %s", mbuf); /* missing } */
530 else if (*p != '}')
532 syserr("Macro/class name ({%s}) too long (%d chars max)",
533 mbuf, (int) (sizeof mbuf - 1));
535 else if (mbuf[1] == '\0')
537 /* ${x} == $x */
538 mid = bitidx(mbuf[0]);
539 p++;
541 else
543 register STAB *s;
545 s = stab(mbuf, ST_MACRO, ST_ENTER);
546 if (s->s_macro != 0)
547 mid = s->s_macro;
548 else
550 if (NextMacroId > MAXMACROID)
552 syserr("Macro/class {%s}: too many long names",
553 mbuf);
554 s->s_macro = -1;
556 else
558 MacroName[NextMacroId] = s->s_name;
559 s->s_macro = mid = NextMacroId++;
562 p++;
564 if (ep != NULL)
565 *ep = p;
566 if (mid < 0 || mid > MAXMACROID)
568 syserr("Unable to assign macro/class ID (mid = 0x%x)", mid);
569 if (tTd(35, 14))
570 sm_dprintf("NULL\n");
571 return 0;
573 if (tTd(35, 14))
574 sm_dprintf("0x%x\n", mid);
575 return mid;
578 ** WORDINCLASS -- tell if a word is in a specific class
580 ** Parameters:
581 ** str -- the name of the word to look up.
582 ** cl -- the class name.
584 ** Returns:
585 ** true if str can be found in cl.
586 ** false otherwise.
589 bool
590 wordinclass(str, cl)
591 char *str;
592 int cl;
594 register STAB *s;
596 s = stab(str, ST_CLASS, ST_FIND);
597 return s != NULL && bitnset(bitidx(cl), s->s_class);