122707Sdist /* 234921Sbostic * Copyright (c) 1983 Eric P. Allman 333729Sbostic * Copyright (c) 1988 Regents of the University of California. 433729Sbostic * All rights reserved. 533729Sbostic * 6*42826Sbostic * %sccs.include.redist.c% 733729Sbostic */ 822707Sdist 922707Sdist #ifndef lint 10*42826Sbostic static char sccsid[] = "@(#)macro.c 5.7 (Berkeley) 06/01/90"; 1133729Sbostic #endif /* not lint */ 1222707Sdist 136056Seric # include "sendmail.h" 143379Seric 153379Seric /* 163379Seric ** EXPAND -- macro expand a string using $x escapes. 173379Seric ** 183379Seric ** Parameters: 193379Seric ** s -- the string to expand. 203379Seric ** buf -- the place to put the expansion. 213379Seric ** buflim -- the buffer limit, i.e., the address 223379Seric ** of the last usable position in buf. 236980Seric ** e -- envelope in which to work. 243379Seric ** 253379Seric ** Returns: 269382Seric ** none. 273379Seric ** 283379Seric ** Side Effects: 293379Seric ** none. 303379Seric */ 313379Seric 326980Seric expand(s, buf, buflim, e) 336980Seric register char *s; 346980Seric register char *buf; 356980Seric char *buflim; 366980Seric register ENVELOPE *e; 376980Seric { 3817349Seric register char *xp; 396056Seric register char *q; 409382Seric bool skipping; /* set if conditionally skipping output */ 4117349Seric bool recurse = FALSE; /* set if recursion required */ 4217349Seric int i; 436056Seric char xbuf[BUFSIZ]; 448182Seric extern char *macvalue(); 453379Seric 4624941Seric if (tTd(35, 24)) 476056Seric { 486056Seric printf("expand("); 496056Seric xputs(s); 506056Seric printf(")\n"); 516056Seric } 523379Seric 533387Seric skipping = FALSE; 548064Seric if (s == NULL) 558064Seric s = ""; 5617349Seric for (xp = xbuf; *s != '\0'; s++) 573379Seric { 586056Seric char c; 594319Seric 604319Seric /* 616056Seric ** Check for non-ordinary (special?) character. 624319Seric ** 'q' will be the interpolated quantity. 634319Seric */ 644319Seric 653379Seric q = NULL; 666056Seric c = *s; 676056Seric switch (c) 683387Seric { 696056Seric case CONDIF: /* see if var set */ 703387Seric c = *++s; 718182Seric skipping = macvalue(c, e) == NULL; 726056Seric continue; 733387Seric 746056Seric case CONDELSE: /* change state of skipping */ 756056Seric skipping = !skipping; 766056Seric continue; 773387Seric 786056Seric case CONDFI: /* stop skipping */ 796056Seric skipping = FALSE; 806056Seric continue; 813387Seric 8216146Seric case '\001': /* macro interpolation */ 836056Seric c = *++s; 848182Seric q = macvalue(c & 0177, e); 859382Seric if (q == NULL) 863387Seric continue; 876056Seric break; 883387Seric } 893387Seric 903379Seric /* 913379Seric ** Interpolate q or output one character 923379Seric */ 933379Seric 9417349Seric if (skipping || xp >= &xbuf[sizeof xbuf]) 953387Seric continue; 9617349Seric if (q == NULL) 9717349Seric *xp++ = c; 9817349Seric else 996056Seric { 10017349Seric /* copy to end of q or max space remaining in buf */ 10117349Seric while ((c = *q++) != '\0' && xp < &xbuf[sizeof xbuf - 1]) 1026056Seric { 10317349Seric if (iscntrl(c) && !isspace(c)) 10417349Seric recurse = TRUE; 1056056Seric *xp++ = c; 1066056Seric } 1076056Seric } 1083379Seric } 1096056Seric *xp = '\0'; 1103379Seric 11124941Seric if (tTd(35, 24)) 1126056Seric { 1138064Seric printf("expand ==> "); 1146056Seric xputs(xbuf); 1158064Seric printf("\n"); 1166056Seric } 1173379Seric 1186056Seric /* recurse as appropriate */ 11917349Seric if (recurse) 1209382Seric { 1219382Seric expand(xbuf, buf, buflim, e); 1229382Seric return; 1239382Seric } 1246056Seric 1256056Seric /* copy results out */ 12617349Seric i = buflim - buf - 1; 12717349Seric if (i > xp - xbuf) 12817349Seric i = xp - xbuf; 12917349Seric bcopy(xbuf, buf, i); 13017349Seric buf[i] = '\0'; 1313379Seric } 1323379Seric /* 1333379Seric ** DEFINE -- define a macro. 1343379Seric ** 1353379Seric ** this would be better done using a #define macro. 1363379Seric ** 1373379Seric ** Parameters: 1383379Seric ** n -- the macro name. 1393379Seric ** v -- the macro value. 1409382Seric ** e -- the envelope to store the definition in. 1413379Seric ** 1423379Seric ** Returns: 1433379Seric ** none. 1443379Seric ** 1453379Seric ** Side Effects: 1469382Seric ** e->e_macro[n] is defined. 1474092Seric ** 1484092Seric ** Notes: 1494092Seric ** There is one macro for each ASCII character, 1504092Seric ** although they are not all used. The currently 1514092Seric ** defined macros are: 1524092Seric ** 1534202Seric ** $a date in ARPANET format (preferring the Date: line 1544202Seric ** of the message) 1554202Seric ** $b the current date (as opposed to the date as found 1564202Seric ** the message) in ARPANET format 1574092Seric ** $c hop count 1584202Seric ** $d (current) date in UNIX (ctime) format 15910710Seric ** $e the SMTP entry message+ 1604092Seric ** $f raw from address 1614092Seric ** $g translated from address 1624092Seric ** $h to host 1637851Seric ** $i queue id 1647851Seric ** $j official SMTP hostname, used in messages+ 1654092Seric ** $l UNIX-style from line+ 1664092Seric ** $n name of sendmail ("MAILER-DAEMON" on local 1674092Seric ** net typically)+ 1684092Seric ** $o delimiters ("operators") for address tokens+ 1694092Seric ** $p my process id in decimal 1705919Seric ** $q the string that becomes an address -- this is 1715919Seric ** normally used to combine $g & $x. 1725187Seric ** $r protocol used to talk to sender 1735187Seric ** $s sender's host name 1744092Seric ** $t the current time in seconds since 1/1/1970 1754092Seric ** $u to user 1764092Seric ** $v version number of sendmail 17710407Seric ** $w our host name (if it can be determined) 1784092Seric ** $x signature (full name) of from person 1794202Seric ** $y the tty id of our terminal 1804092Seric ** $z home directory of to person 1814092Seric ** 1824092Seric ** Macros marked with + must be defined in the 1834092Seric ** configuration file and are used internally, but 1844092Seric ** are not set. 1854092Seric ** 1864092Seric ** There are also some macros that can be used 1874092Seric ** arbitrarily to make the configuration file 1884092Seric ** cleaner. In general all upper-case letters 1894092Seric ** are available. 1903379Seric */ 1913379Seric 1929382Seric define(n, v, e) 1933379Seric char n; 1943379Seric char *v; 1959382Seric register ENVELOPE *e; 1963379Seric { 19724941Seric if (tTd(35, 9)) 1986056Seric { 1996056Seric printf("define(%c as ", n); 2006056Seric xputs(v); 2016056Seric printf(")\n"); 2026056Seric } 2039382Seric e->e_macro[n & 0177] = v; 2043379Seric } 2054454Seric /* 2064454Seric ** MACVALUE -- return uninterpreted value of a macro. 2074454Seric ** 2084454Seric ** Parameters: 2094454Seric ** n -- the name of the macro. 2104454Seric ** 2114454Seric ** Returns: 2124454Seric ** The value of n. 2134454Seric ** 2144454Seric ** Side Effects: 2154454Seric ** none. 2164454Seric */ 2174454Seric 2184454Seric char * 2198182Seric macvalue(n, e) 2204454Seric char n; 2218182Seric register ENVELOPE *e; 2224454Seric { 2238182Seric n &= 0177; 2248182Seric while (e != NULL) 2258182Seric { 2268182Seric register char *p = e->e_macro[n]; 2278182Seric 2288182Seric if (p != NULL) 2298182Seric return (p); 2308182Seric e = e->e_parent; 2318182Seric } 2328182Seric return (NULL); 2334454Seric } 234