16056Seric # include "sendmail.h" 23379Seric 3*16146Seric SCCSID(@(#)macro.c 4.2 03/11/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 { 286056Seric register char *q; 299382Seric bool skipping; /* set if conditionally skipping output */ 309382Seric bool gotone = FALSE; /* set if any expansion done */ 316056Seric char xbuf[BUFSIZ]; 326056Seric register char *xp = xbuf; 338182Seric extern char *macvalue(); 343379Seric 353379Seric # ifdef DEBUG 367677Seric if (tTd(35, 4)) 376056Seric { 386056Seric printf("expand("); 396056Seric xputs(s); 406056Seric printf(")\n"); 416056Seric } 423379Seric # endif DEBUG 433379Seric 443387Seric skipping = FALSE; 458064Seric if (s == NULL) 468064Seric s = ""; 476056Seric for (; *s != '\0'; s++) 483379Seric { 496056Seric char c; 504319Seric 514319Seric /* 526056Seric ** Check for non-ordinary (special?) character. 534319Seric ** 'q' will be the interpolated quantity. 544319Seric */ 554319Seric 563379Seric q = NULL; 576056Seric c = *s; 586056Seric switch (c) 593387Seric { 606056Seric case CONDIF: /* see if var set */ 613387Seric c = *++s; 628182Seric skipping = macvalue(c, e) == NULL; 636056Seric continue; 643387Seric 656056Seric case CONDELSE: /* change state of skipping */ 666056Seric skipping = !skipping; 676056Seric continue; 683387Seric 696056Seric case CONDFI: /* stop skipping */ 706056Seric skipping = FALSE; 716056Seric continue; 723387Seric 73*16146Seric case '\001': /* macro interpolation */ 746056Seric c = *++s; 758182Seric q = macvalue(c & 0177, e); 769382Seric if (q == NULL) 773387Seric continue; 786056Seric gotone = TRUE; 796056Seric break; 803387Seric } 813387Seric 823379Seric /* 833379Seric ** Interpolate q or output one character 843379Seric */ 853379Seric 863387Seric if (skipping) 873387Seric continue; 886056Seric while (xp < &xbuf[sizeof xbuf]) 896056Seric { 906056Seric if (q == NULL) 916056Seric { 926056Seric *xp++ = c; 936056Seric break; 946056Seric } 959382Seric if (*q == '\0') 966056Seric break; 976056Seric *xp++ = *q++; 986056Seric } 993379Seric } 1006056Seric *xp = '\0'; 1013379Seric 1023379Seric # ifdef DEBUG 1037677Seric if (tTd(35, 4)) 1046056Seric { 1058064Seric printf("expand ==> "); 1066056Seric xputs(xbuf); 1078064Seric printf("\n"); 1086056Seric } 1093379Seric # endif DEBUG 1103379Seric 1116056Seric /* recurse as appropriate */ 1126056Seric if (gotone) 1139382Seric { 1149382Seric expand(xbuf, buf, buflim, e); 1159382Seric return; 1169382Seric } 1176056Seric 1186056Seric /* copy results out */ 1196056Seric for (q = buf, xp = xbuf; xp != '\0' && q < buflim-1; ) 1206056Seric *q++ = *xp++; 1216056Seric *q = '\0'; 1223379Seric } 1233379Seric /* 1243379Seric ** DEFINE -- define a macro. 1253379Seric ** 1263379Seric ** this would be better done using a #define macro. 1273379Seric ** 1283379Seric ** Parameters: 1293379Seric ** n -- the macro name. 1303379Seric ** v -- the macro value. 1319382Seric ** e -- the envelope to store the definition in. 1323379Seric ** 1333379Seric ** Returns: 1343379Seric ** none. 1353379Seric ** 1363379Seric ** Side Effects: 1379382Seric ** e->e_macro[n] is defined. 1384092Seric ** 1394092Seric ** Notes: 1404092Seric ** There is one macro for each ASCII character, 1414092Seric ** although they are not all used. The currently 1424092Seric ** defined macros are: 1434092Seric ** 1444202Seric ** $a date in ARPANET format (preferring the Date: line 1454202Seric ** of the message) 1464202Seric ** $b the current date (as opposed to the date as found 1474202Seric ** the message) in ARPANET format 1484092Seric ** $c hop count 1494202Seric ** $d (current) date in UNIX (ctime) format 15010710Seric ** $e the SMTP entry message+ 1514092Seric ** $f raw from address 1524092Seric ** $g translated from address 1534092Seric ** $h to host 1547851Seric ** $i queue id 1557851Seric ** $j official SMTP hostname, used in messages+ 1564092Seric ** $l UNIX-style from line+ 1574092Seric ** $n name of sendmail ("MAILER-DAEMON" on local 1584092Seric ** net typically)+ 1594092Seric ** $o delimiters ("operators") for address tokens+ 1604092Seric ** $p my process id in decimal 1615919Seric ** $q the string that becomes an address -- this is 1625919Seric ** normally used to combine $g & $x. 1635187Seric ** $r protocol used to talk to sender 1645187Seric ** $s sender's host name 1654092Seric ** $t the current time in seconds since 1/1/1970 1664092Seric ** $u to user 1674092Seric ** $v version number of sendmail 16810407Seric ** $w our host name (if it can be determined) 1694092Seric ** $x signature (full name) of from person 1704202Seric ** $y the tty id of our terminal 1714092Seric ** $z home directory of to person 1724092Seric ** 1734092Seric ** Macros marked with + must be defined in the 1744092Seric ** configuration file and are used internally, but 1754092Seric ** are not set. 1764092Seric ** 1774092Seric ** There are also some macros that can be used 1784092Seric ** arbitrarily to make the configuration file 1794092Seric ** cleaner. In general all upper-case letters 1804092Seric ** are available. 1813379Seric */ 1823379Seric 1839382Seric define(n, v, e) 1843379Seric char n; 1853379Seric char *v; 1869382Seric register ENVELOPE *e; 1873379Seric { 1883379Seric # ifdef DEBUG 1897677Seric if (tTd(35, 3)) 1906056Seric { 1916056Seric printf("define(%c as ", n); 1926056Seric xputs(v); 1936056Seric printf(")\n"); 1946056Seric } 1953379Seric # endif DEBUG 1969382Seric e->e_macro[n & 0177] = v; 1973379Seric } 1984454Seric /* 1994454Seric ** MACVALUE -- return uninterpreted value of a macro. 2004454Seric ** 2014454Seric ** Parameters: 2024454Seric ** n -- the name of the macro. 2034454Seric ** 2044454Seric ** Returns: 2054454Seric ** The value of n. 2064454Seric ** 2074454Seric ** Side Effects: 2084454Seric ** none. 2094454Seric */ 2104454Seric 2114454Seric char * 2128182Seric macvalue(n, e) 2134454Seric char n; 2148182Seric register ENVELOPE *e; 2154454Seric { 2168182Seric n &= 0177; 2178182Seric while (e != NULL) 2188182Seric { 2198182Seric register char *p = e->e_macro[n]; 2208182Seric 2218182Seric if (p != NULL) 2228182Seric return (p); 2238182Seric e = e->e_parent; 2248182Seric } 2258182Seric return (NULL); 2264454Seric } 227