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