macro.c revision 71345
1/* 2 * Copyright (c) 1998-2000 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#ifndef lint 15static char id[] = "@(#)$Id: macro.c,v 8.40.16.7 2000/10/09 15:49:06 gshapiro Exp $"; 16#endif /* ! lint */ 17 18#include <sendmail.h> 19 20#if MAXMACROID != (BITMAPBITS - 1) 21 ERROR Read the comment in conf.h 22#endif /* MAXMACROID != (BITMAPBITS - 1) */ 23 24char *MacroName[MAXMACROID + 1]; /* macro id to name table */ 25int NextMacroId = 0240; /* codes for long named macros */ 26 27/* 28** EXPAND -- macro expand a string using $x escapes. 29** 30** Parameters: 31** s -- the string to expand. 32** buf -- the place to put the expansion. 33** bufsize -- the size of the buffer. 34** e -- envelope in which to work. 35** 36** Returns: 37** none. 38** 39** Side Effects: 40** none. 41*/ 42 43void 44expand(s, buf, bufsize, e) 45 register char *s; 46 register char *buf; 47 size_t bufsize; 48 register ENVELOPE *e; 49{ 50 register char *xp; 51 register char *q; 52 bool skipping; /* set if conditionally skipping output */ 53 bool recurse = FALSE; /* set if recursion required */ 54 int i; 55 int skiplev; /* skipping nesting level */ 56 int iflev; /* if nesting level */ 57 char xbuf[MACBUFSIZE]; 58 static int explevel = 0; 59 60 if (tTd(35, 24)) 61 { 62 dprintf("expand("); 63 xputs(s); 64 dprintf(")\n"); 65 } 66 67 skipping = FALSE; 68 skiplev = 0; 69 iflev = 0; 70 if (s == NULL) 71 s = ""; 72 for (xp = xbuf; *s != '\0'; s++) 73 { 74 int c; 75 76 /* 77 ** Check for non-ordinary (special?) character. 78 ** 'q' will be the interpolated quantity. 79 */ 80 81 q = NULL; 82 c = *s; 83 switch (c & 0377) 84 { 85 case CONDIF: /* see if var set */ 86 iflev++; 87 c = *++s; 88 if (skipping) 89 skiplev++; 90 else 91 { 92 char *mv; 93 94 mv = macvalue(c, e); 95 skipping = (mv == NULL || *mv == '\0'); 96 } 97 continue; 98 99 case CONDELSE: /* change state of skipping */ 100 if (iflev == 0) 101 break; 102 if (skiplev == 0) 103 skipping = !skipping; 104 continue; 105 106 case CONDFI: /* stop skipping */ 107 if (iflev == 0) 108 break; 109 iflev--; 110 if (skiplev == 0) 111 skipping = FALSE; 112 if (skipping) 113 skiplev--; 114 continue; 115 116 case MACROEXPAND: /* macro interpolation */ 117 c = bitidx(*++s); 118 if (c != '\0') 119 q = macvalue(c, e); 120 else 121 { 122 s--; 123 q = NULL; 124 } 125 if (q == NULL) 126 continue; 127 break; 128 } 129 130 /* 131 ** Interpolate q or output one character 132 */ 133 134 if (skipping || xp >= &xbuf[sizeof xbuf - 1]) 135 continue; 136 if (q == NULL) 137 *xp++ = c; 138 else 139 { 140 /* copy to end of q or max space remaining in buf */ 141 while ((c = *q++) != '\0' && xp < &xbuf[sizeof xbuf - 1]) 142 { 143 /* check for any sendmail metacharacters */ 144 if ((c & 0340) == 0200) 145 recurse = TRUE; 146 *xp++ = c; 147 } 148 } 149 } 150 *xp = '\0'; 151 152 if (tTd(35, 24)) 153 { 154 dprintf("expand ==> "); 155 xputs(xbuf); 156 dprintf("\n"); 157 } 158 159 /* recurse as appropriate */ 160 if (recurse) 161 { 162 if (explevel < MaxMacroRecursion) 163 { 164 explevel++; 165 expand(xbuf, buf, bufsize, e); 166 explevel--; 167 return; 168 } 169 syserr("expand: recursion too deep (%d max)", 170 MaxMacroRecursion); 171 } 172 173 /* copy results out */ 174 i = xp - xbuf; 175 if ((size_t)i >= bufsize) 176 i = bufsize - 1; 177 memmove(buf, xbuf, i); 178 buf[i] = '\0'; 179} 180/* 181** DEFINE -- define a macro. 182** 183** this would be better done using a #define macro. 184** 185** Parameters: 186** n -- the macro name. 187** v -- the macro value. 188** e -- the envelope to store the definition in. 189** 190** Returns: 191** none. 192** 193** Side Effects: 194** e->e_macro[n] is defined. 195** 196** Notes: 197** There is one macro for each ASCII character, 198** although they are not all used. The currently 199** defined macros are: 200** 201** $a date in ARPANET format (preferring the Date: line 202** of the message) 203** $b the current date (as opposed to the date as found 204** the message) in ARPANET format 205** $c hop count 206** $d (current) date in UNIX (ctime) format 207** $e the SMTP entry message+ 208** $f raw from address 209** $g translated from address 210** $h to host 211** $i queue id 212** $j official SMTP hostname, used in messages+ 213** $k UUCP node name 214** $l UNIX-style from line+ 215** $m The domain part of our full name. 216** $n name of sendmail ("MAILER-DAEMON" on local 217** net typically)+ 218** $o delimiters ("operators") for address tokens+ 219** (set via OperatorChars option in V6 or later 220** sendmail.cf files) 221** $p my process id in decimal 222** $q the string that becomes an address -- this is 223** normally used to combine $g & $x. 224** $r protocol used to talk to sender 225** $s sender's host name 226** $t the current time in seconds since 1/1/1970 227** $u to user 228** $v version number of sendmail 229** $w our host name (if it can be determined) 230** $x signature (full name) of from person 231** $y the tty id of our terminal 232** $z home directory of to person 233** $_ RFC1413 authenticated sender address 234** 235** Macros marked with + must be defined in the 236** configuration file and are used internally, but 237** are not set. 238** 239** There are also some macros that can be used 240** arbitrarily to make the configuration file 241** cleaner. In general all upper-case letters 242** are available. 243*/ 244 245void 246define(n, v, e) 247 int n; 248 char *v; 249 register ENVELOPE *e; 250{ 251 int m; 252 253 m = bitidx(n); 254 if (tTd(35, 9)) 255 { 256 dprintf("%sdefine(%s as ", 257 (e->e_macro[m] == NULL) ? "" 258 : "re", macname(n)); 259 xputs(v); 260 dprintf(")\n"); 261 } 262 e->e_macro[m] = v; 263 264#if _FFR_RESET_MACRO_GLOBALS 265 switch (m) 266 { 267 case 'j': 268 MyHostName = v; 269 break; 270 } 271#endif /* _FFR_RESET_MACRO_GLOBALS */ 272} 273/* 274** MACVALUE -- return uninterpreted value of a macro. 275** 276** Parameters: 277** n -- the name of the macro. 278** 279** Returns: 280** The value of n. 281** 282** Side Effects: 283** none. 284*/ 285 286char * 287macvalue(n, e) 288 int n; 289 register ENVELOPE *e; 290{ 291 n = bitidx(n); 292 while (e != NULL) 293 { 294 register char *p = e->e_macro[n]; 295 296 if (p != NULL) 297 return p; 298 e = e->e_parent; 299 } 300 return NULL; 301} 302/* 303** MACNAME -- return the name of a macro given its internal id 304** 305** Parameter: 306** n -- the id of the macro 307** 308** Returns: 309** The name of n. 310** 311** Side Effects: 312** none. 313*/ 314 315char * 316macname(n) 317 int n; 318{ 319 static char mbuf[2]; 320 321 n = bitidx(n); 322 if (bitset(0200, n)) 323 { 324 char *p = MacroName[n]; 325 326 if (p != NULL) 327 return p; 328 return "***UNDEFINED MACRO***"; 329 } 330 mbuf[0] = n; 331 mbuf[1] = '\0'; 332 return mbuf; 333} 334/* 335** MACID -- return id of macro identified by its name 336** 337** Parameters: 338** p -- pointer to name string -- either a single 339** character or {name}. 340** ep -- filled in with the pointer to the byte 341** after the name. 342** 343** Returns: 344** The internal id code for this macro. This will 345** fit into a single byte. 346** 347** Side Effects: 348** If this is a new macro name, a new id is allocated. 349*/ 350 351int 352macid(p, ep) 353 register char *p; 354 char **ep; 355{ 356 int mid; 357 register char *bp; 358 char mbuf[MAXMACNAMELEN + 1]; 359 360 if (tTd(35, 14)) 361 { 362 dprintf("macid("); 363 xputs(p); 364 dprintf(") => "); 365 } 366 367 if (*p == '\0' || (p[0] == '{' && p[1] == '}')) 368 { 369 syserr("Name required for macro/class"); 370 if (ep != NULL) 371 *ep = p; 372 if (tTd(35, 14)) 373 dprintf("NULL\n"); 374 return 0; 375 } 376 if (*p != '{') 377 { 378 /* the macro is its own code */ 379 if (ep != NULL) 380 *ep = p + 1; 381 if (tTd(35, 14)) 382 dprintf("%c\n", bitidx(*p)); 383 return bitidx(*p); 384 } 385 bp = mbuf; 386 while (*++p != '\0' && *p != '}' && bp < &mbuf[sizeof mbuf - 1]) 387 { 388 if (isascii(*p) && (isalnum(*p) || *p == '_')) 389 *bp++ = *p; 390 else 391 syserr("Invalid macro/class character %c", *p); 392 } 393 *bp = '\0'; 394 mid = -1; 395 if (*p == '\0') 396 { 397 syserr("Unbalanced { on %s", mbuf); /* missing } */ 398 } 399 else if (*p != '}') 400 { 401 syserr("Macro/class name ({%s}) too long (%d chars max)", 402 mbuf, sizeof mbuf - 1); 403 } 404 else if (mbuf[1] == '\0') 405 { 406 /* ${x} == $x */ 407 mid = bitidx(mbuf[0]); 408 p++; 409 } 410 else 411 { 412 register STAB *s; 413 414 s = stab(mbuf, ST_MACRO, ST_ENTER); 415 if (s->s_macro != 0) 416 mid = s->s_macro; 417 else 418 { 419 if (NextMacroId > MAXMACROID) 420 { 421 syserr("Macro/class {%s}: too many long names", mbuf); 422 s->s_macro = -1; 423 } 424 else 425 { 426 MacroName[NextMacroId] = s->s_name; 427 s->s_macro = mid = NextMacroId++; 428 } 429 } 430 p++; 431 } 432 if (ep != NULL) 433 *ep = p; 434 if (mid < 0 || mid > MAXMACROID) 435 { 436 syserr("Unable to assign macro/class ID (mid = 0x%x)", mid); 437 if (tTd(35, 14)) 438 dprintf("NULL\n"); 439 return 0; 440 } 441 if (tTd(35, 14)) 442 dprintf("0x%x\n", mid); 443 return mid; 444} 445/* 446** WORDINCLASS -- tell if a word is in a specific class 447** 448** Parameters: 449** str -- the name of the word to look up. 450** cl -- the class name. 451** 452** Returns: 453** TRUE if str can be found in cl. 454** FALSE otherwise. 455*/ 456 457bool 458wordinclass(str, cl) 459 char *str; 460 int cl; 461{ 462 register STAB *s; 463 464 s = stab(str, ST_CLASS, ST_FIND); 465 return s != NULL && bitnset(bitidx(cl), s->s_class); 466} 467