16056Seric # include "sendmail.h" 23379Seric 3*9382Seric SCCSID(@(#)macro.c 3.18 11/28/82); 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: 16*9382Seric ** none. 173379Seric ** 183379Seric ** Side Effects: 193379Seric ** none. 20*9382Seric ** 21*9382Seric ** Bugs: 22*9382Seric ** The handling of $$ (to get one dollar) is rather bizarre, 23*9382Seric ** especially if there should be another macro 24*9382Seric ** expansion in the same string. 253379Seric */ 263379Seric 276980Seric expand(s, buf, buflim, e) 286980Seric register char *s; 296980Seric register char *buf; 306980Seric char *buflim; 316980Seric register ENVELOPE *e; 326980Seric { 336056Seric register char *q; 34*9382Seric bool skipping; /* set if conditionally skipping output */ 35*9382Seric bool gotone = FALSE; /* set if any expansion done */ 366056Seric char xbuf[BUFSIZ]; 376056Seric register char *xp = xbuf; 388182Seric extern char *macvalue(); 393379Seric 403379Seric # ifdef DEBUG 417677Seric if (tTd(35, 4)) 426056Seric { 436056Seric printf("expand("); 446056Seric xputs(s); 456056Seric printf(")\n"); 466056Seric } 473379Seric # endif DEBUG 483379Seric 493387Seric skipping = FALSE; 508064Seric if (s == NULL) 518064Seric s = ""; 526056Seric for (; *s != '\0'; s++) 533379Seric { 546056Seric char c; 554319Seric 564319Seric /* 576056Seric ** Check for non-ordinary (special?) character. 584319Seric ** 'q' will be the interpolated quantity. 594319Seric */ 604319Seric 613379Seric q = NULL; 626056Seric c = *s; 636056Seric switch (c) 643387Seric { 656056Seric case CONDIF: /* see if var set */ 663387Seric c = *++s; 678182Seric skipping = macvalue(c, e) == NULL; 686056Seric continue; 693387Seric 706056Seric case CONDELSE: /* change state of skipping */ 716056Seric skipping = !skipping; 726056Seric continue; 733387Seric 746056Seric case CONDFI: /* stop skipping */ 756056Seric skipping = FALSE; 766056Seric continue; 773387Seric 786056Seric case '$': /* macro interpolation */ 796056Seric c = *++s; 80*9382Seric if (c == '$') 81*9382Seric break; 828182Seric q = macvalue(c & 0177, e); 83*9382Seric if (q == NULL) 843387Seric continue; 856056Seric gotone = TRUE; 866056Seric break; 873387Seric } 883387Seric 893379Seric /* 903379Seric ** Interpolate q or output one character 913379Seric */ 923379Seric 933387Seric if (skipping) 943387Seric continue; 956056Seric while (xp < &xbuf[sizeof xbuf]) 966056Seric { 976056Seric if (q == NULL) 986056Seric { 996056Seric *xp++ = c; 1006056Seric break; 1016056Seric } 102*9382Seric if (*q == '\0') 1036056Seric break; 1046056Seric *xp++ = *q++; 1056056Seric } 1063379Seric } 1076056Seric *xp = '\0'; 1083379Seric 1093379Seric # ifdef DEBUG 1107677Seric if (tTd(35, 4)) 1116056Seric { 1128064Seric printf("expand ==> "); 1136056Seric xputs(xbuf); 1148064Seric printf("\n"); 1156056Seric } 1163379Seric # endif DEBUG 1173379Seric 1186056Seric /* recurse as appropriate */ 1196056Seric if (gotone) 120*9382Seric { 121*9382Seric expand(xbuf, buf, buflim, e); 122*9382Seric return; 123*9382Seric } 1246056Seric 1256056Seric /* copy results out */ 1266056Seric for (q = buf, xp = xbuf; xp != '\0' && q < buflim-1; ) 1276056Seric *q++ = *xp++; 1286056Seric *q = '\0'; 1293379Seric } 1303379Seric /* 1313379Seric ** DEFINE -- define a macro. 1323379Seric ** 1333379Seric ** this would be better done using a #define macro. 1343379Seric ** 1353379Seric ** Parameters: 1363379Seric ** n -- the macro name. 1373379Seric ** v -- the macro value. 138*9382Seric ** e -- the envelope to store the definition in. 1393379Seric ** 1403379Seric ** Returns: 1413379Seric ** none. 1423379Seric ** 1433379Seric ** Side Effects: 144*9382Seric ** e->e_macro[n] is defined. 1454092Seric ** 1464092Seric ** Notes: 1474092Seric ** There is one macro for each ASCII character, 1484092Seric ** although they are not all used. The currently 1494092Seric ** defined macros are: 1504092Seric ** 1514202Seric ** $a date in ARPANET format (preferring the Date: line 1524202Seric ** of the message) 1534202Seric ** $b the current date (as opposed to the date as found 1544202Seric ** the message) in ARPANET format 1554092Seric ** $c hop count 1564202Seric ** $d (current) date in UNIX (ctime) format 1574092Seric ** $f raw from address 1584092Seric ** $g translated from address 1594092Seric ** $h to host 1607851Seric ** $i queue id 1617851Seric ** $j official SMTP hostname, used in messages+ 1624092Seric ** $l UNIX-style from line+ 1634092Seric ** $n name of sendmail ("MAILER-DAEMON" on local 1644092Seric ** net typically)+ 1654092Seric ** $o delimiters ("operators") for address tokens+ 1664092Seric ** $p my process id in decimal 1675919Seric ** $q the string that becomes an address -- this is 1685919Seric ** normally used to combine $g & $x. 1695187Seric ** $r protocol used to talk to sender 1705187Seric ** $s sender's host name 1714092Seric ** $t the current time in seconds since 1/1/1970 1724092Seric ** $u to user 1734092Seric ** $v version number of sendmail 1744092Seric ** $x signature (full name) of from person 1754202Seric ** $y the tty id of our terminal 1764092Seric ** $z home directory of to person 1774092Seric ** 1784092Seric ** Macros marked with + must be defined in the 1794092Seric ** configuration file and are used internally, but 1804092Seric ** are not set. 1814092Seric ** 1824092Seric ** There are also some macros that can be used 1834092Seric ** arbitrarily to make the configuration file 1844092Seric ** cleaner. In general all upper-case letters 1854092Seric ** are available. 1863379Seric */ 1873379Seric 188*9382Seric define(n, v, e) 1893379Seric char n; 1903379Seric char *v; 191*9382Seric register ENVELOPE *e; 1923379Seric { 1933379Seric # ifdef DEBUG 1947677Seric if (tTd(35, 3)) 1956056Seric { 1966056Seric printf("define(%c as ", n); 1976056Seric xputs(v); 1986056Seric printf(")\n"); 1996056Seric } 2003379Seric # endif DEBUG 201*9382Seric e->e_macro[n & 0177] = v; 2023379Seric } 2034454Seric /* 2044454Seric ** MACVALUE -- return uninterpreted value of a macro. 2054454Seric ** 2064454Seric ** Parameters: 2074454Seric ** n -- the name of the macro. 2084454Seric ** 2094454Seric ** Returns: 2104454Seric ** The value of n. 2114454Seric ** 2124454Seric ** Side Effects: 2134454Seric ** none. 2144454Seric */ 2154454Seric 2164454Seric char * 2178182Seric macvalue(n, e) 2184454Seric char n; 2198182Seric register ENVELOPE *e; 2204454Seric { 2218182Seric n &= 0177; 2228182Seric while (e != NULL) 2238182Seric { 2248182Seric register char *p = e->e_macro[n]; 2258182Seric 2268182Seric if (p != NULL) 2278182Seric return (p); 2288182Seric e = e->e_parent; 2298182Seric } 2308182Seric return (NULL); 2314454Seric } 232