16056Seric # include "sendmail.h" 23379Seric 3*17349Seric SCCSID(@(#)macro.c 4.3 11/13/84); 43379Seric 53379Seric /* 63379Seric ** EXPAND -- macro expand a string using $x escapes. 73379Seric ** 83379Seric ** Parameters: 93379Seric ** s -- the string to expand. 103379Seric ** buf -- the place to put the expansion. 113379Seric ** buflim -- the buffer limit, i.e., the address 123379Seric ** of the last usable position in buf. 136980Seric ** e -- envelope in which to work. 143379Seric ** 153379Seric ** Returns: 169382Seric ** none. 173379Seric ** 183379Seric ** Side Effects: 193379Seric ** none. 203379Seric */ 213379Seric 226980Seric expand(s, buf, buflim, e) 236980Seric register char *s; 246980Seric register char *buf; 256980Seric char *buflim; 266980Seric register ENVELOPE *e; 276980Seric { 28*17349Seric register char *xp; 296056Seric register char *q; 309382Seric bool skipping; /* set if conditionally skipping output */ 31*17349Seric bool recurse = FALSE; /* set if recursion required */ 32*17349Seric int i; 336056Seric char xbuf[BUFSIZ]; 348182Seric extern char *macvalue(); 353379Seric 363379Seric # ifdef DEBUG 377677Seric if (tTd(35, 4)) 386056Seric { 396056Seric printf("expand("); 406056Seric xputs(s); 416056Seric printf(")\n"); 426056Seric } 433379Seric # endif DEBUG 443379Seric 453387Seric skipping = FALSE; 468064Seric if (s == NULL) 478064Seric s = ""; 48*17349Seric for (xp = xbuf; *s != '\0'; s++) 493379Seric { 506056Seric char c; 514319Seric 524319Seric /* 536056Seric ** Check for non-ordinary (special?) character. 544319Seric ** 'q' will be the interpolated quantity. 554319Seric */ 564319Seric 573379Seric q = NULL; 586056Seric c = *s; 596056Seric switch (c) 603387Seric { 616056Seric case CONDIF: /* see if var set */ 623387Seric c = *++s; 638182Seric skipping = macvalue(c, e) == NULL; 646056Seric continue; 653387Seric 666056Seric case CONDELSE: /* change state of skipping */ 676056Seric skipping = !skipping; 686056Seric continue; 693387Seric 706056Seric case CONDFI: /* stop skipping */ 716056Seric skipping = FALSE; 726056Seric continue; 733387Seric 7416146Seric case '\001': /* macro interpolation */ 756056Seric c = *++s; 768182Seric q = macvalue(c & 0177, e); 779382Seric if (q == NULL) 783387Seric continue; 796056Seric break; 803387Seric } 813387Seric 823379Seric /* 833379Seric ** Interpolate q or output one character 843379Seric */ 853379Seric 86*17349Seric if (skipping || xp >= &xbuf[sizeof xbuf]) 873387Seric continue; 88*17349Seric if (q == NULL) 89*17349Seric *xp++ = c; 90*17349Seric else 916056Seric { 92*17349Seric /* copy to end of q or max space remaining in buf */ 93*17349Seric while ((c = *q++) != '\0' && xp < &xbuf[sizeof xbuf - 1]) 946056Seric { 95*17349Seric if (iscntrl(c) && !isspace(c)) 96*17349Seric recurse = TRUE; 976056Seric *xp++ = c; 986056Seric } 996056Seric } 1003379Seric } 1016056Seric *xp = '\0'; 1023379Seric 1033379Seric # ifdef DEBUG 1047677Seric if (tTd(35, 4)) 1056056Seric { 1068064Seric printf("expand ==> "); 1076056Seric xputs(xbuf); 1088064Seric printf("\n"); 1096056Seric } 1103379Seric # endif DEBUG 1113379Seric 1126056Seric /* recurse as appropriate */ 113*17349Seric if (recurse) 1149382Seric { 1159382Seric expand(xbuf, buf, buflim, e); 1169382Seric return; 1179382Seric } 1186056Seric 1196056Seric /* copy results out */ 120*17349Seric i = buflim - buf - 1; 121*17349Seric if (i > xp - xbuf) 122*17349Seric i = xp - xbuf; 123*17349Seric bcopy(xbuf, buf, i); 124*17349Seric buf[i] = '\0'; 1253379Seric } 1263379Seric /* 1273379Seric ** DEFINE -- define a macro. 1283379Seric ** 1293379Seric ** this would be better done using a #define macro. 1303379Seric ** 1313379Seric ** Parameters: 1323379Seric ** n -- the macro name. 1333379Seric ** v -- the macro value. 1349382Seric ** e -- the envelope to store the definition in. 1353379Seric ** 1363379Seric ** Returns: 1373379Seric ** none. 1383379Seric ** 1393379Seric ** Side Effects: 1409382Seric ** e->e_macro[n] is defined. 1414092Seric ** 1424092Seric ** Notes: 1434092Seric ** There is one macro for each ASCII character, 1444092Seric ** although they are not all used. The currently 1454092Seric ** defined macros are: 1464092Seric ** 1474202Seric ** $a date in ARPANET format (preferring the Date: line 1484202Seric ** of the message) 1494202Seric ** $b the current date (as opposed to the date as found 1504202Seric ** the message) in ARPANET format 1514092Seric ** $c hop count 1524202Seric ** $d (current) date in UNIX (ctime) format 15310710Seric ** $e the SMTP entry message+ 1544092Seric ** $f raw from address 1554092Seric ** $g translated from address 1564092Seric ** $h to host 1577851Seric ** $i queue id 1587851Seric ** $j official SMTP hostname, used in messages+ 1594092Seric ** $l UNIX-style from line+ 1604092Seric ** $n name of sendmail ("MAILER-DAEMON" on local 1614092Seric ** net typically)+ 1624092Seric ** $o delimiters ("operators") for address tokens+ 1634092Seric ** $p my process id in decimal 1645919Seric ** $q the string that becomes an address -- this is 1655919Seric ** normally used to combine $g & $x. 1665187Seric ** $r protocol used to talk to sender 1675187Seric ** $s sender's host name 1684092Seric ** $t the current time in seconds since 1/1/1970 1694092Seric ** $u to user 1704092Seric ** $v version number of sendmail 17110407Seric ** $w our host name (if it can be determined) 1724092Seric ** $x signature (full name) of from person 1734202Seric ** $y the tty id of our terminal 1744092Seric ** $z home directory of to person 1754092Seric ** 1764092Seric ** Macros marked with + must be defined in the 1774092Seric ** configuration file and are used internally, but 1784092Seric ** are not set. 1794092Seric ** 1804092Seric ** There are also some macros that can be used 1814092Seric ** arbitrarily to make the configuration file 1824092Seric ** cleaner. In general all upper-case letters 1834092Seric ** are available. 1843379Seric */ 1853379Seric 1869382Seric define(n, v, e) 1873379Seric char n; 1883379Seric char *v; 1899382Seric register ENVELOPE *e; 1903379Seric { 1913379Seric # ifdef DEBUG 1927677Seric if (tTd(35, 3)) 1936056Seric { 1946056Seric printf("define(%c as ", n); 1956056Seric xputs(v); 1966056Seric printf(")\n"); 1976056Seric } 1983379Seric # endif DEBUG 1999382Seric e->e_macro[n & 0177] = v; 2003379Seric } 2014454Seric /* 2024454Seric ** MACVALUE -- return uninterpreted value of a macro. 2034454Seric ** 2044454Seric ** Parameters: 2054454Seric ** n -- the name of the macro. 2064454Seric ** 2074454Seric ** Returns: 2084454Seric ** The value of n. 2094454Seric ** 2104454Seric ** Side Effects: 2114454Seric ** none. 2124454Seric */ 2134454Seric 2144454Seric char * 2158182Seric macvalue(n, e) 2164454Seric char n; 2178182Seric register ENVELOPE *e; 2184454Seric { 2198182Seric n &= 0177; 2208182Seric while (e != NULL) 2218182Seric { 2228182Seric register char *p = e->e_macro[n]; 2238182Seric 2248182Seric if (p != NULL) 2258182Seric return (p); 2268182Seric e = e->e_parent; 2278182Seric } 2288182Seric return (NULL); 2294454Seric } 230