16056Seric # include "sendmail.h" 23379Seric 3*8064Seric SCCSID(@(#)macro.c 3.16 09/05/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: 164319Seric ** End of interpolated output. 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 { 286980Seric extern char *expand2(); 296980Seric 306980Seric (void) expand2(s, buf, buflim, e); 316980Seric } 326980Seric 336980Seric 343379Seric char * 356980Seric expand2(s, buf, buflim, e) 363379Seric register char *s; 373379Seric register char *buf; 383379Seric char *buflim; 396980Seric register ENVELOPE *e; 403379Seric { 416056Seric register char *q; 426056Seric char xbuf[BUFSIZ]; 436056Seric register char *xp = xbuf; 444319Seric bool skipping; /* set if conditionally skipping output */ 456056Seric bool gotone = FALSE; /* set if any expansion done */ 463379Seric 473379Seric # ifdef DEBUG 487677Seric if (tTd(35, 4)) 496056Seric { 506056Seric printf("expand("); 516056Seric xputs(s); 526056Seric printf(")\n"); 536056Seric } 543379Seric # endif DEBUG 553379Seric 563387Seric skipping = FALSE; 57*8064Seric if (s == NULL) 58*8064Seric s = ""; 596056Seric for (; *s != '\0'; s++) 603379Seric { 616056Seric char c; 624319Seric 634319Seric /* 646056Seric ** Check for non-ordinary (special?) character. 654319Seric ** 'q' will be the interpolated quantity. 664319Seric */ 674319Seric 683379Seric q = NULL; 696056Seric c = *s; 706056Seric switch (c) 713387Seric { 726056Seric case CONDIF: /* see if var set */ 733387Seric c = *++s; 746980Seric skipping = e->e_macro[c] == NULL; 756056Seric continue; 763387Seric 776056Seric case CONDELSE: /* change state of skipping */ 786056Seric skipping = !skipping; 796056Seric continue; 803387Seric 816056Seric case CONDFI: /* stop skipping */ 826056Seric skipping = FALSE; 836056Seric continue; 843387Seric 856056Seric case '$': /* macro interpolation */ 866056Seric c = *++s; 876980Seric q = e->e_macro[c & 0177]; 884172Seric if (q == NULL && c != '$') 893387Seric continue; 906056Seric gotone = TRUE; 916056Seric break; 923387Seric } 933387Seric 943379Seric /* 953379Seric ** Interpolate q or output one character 963379Seric */ 973379Seric 983387Seric if (skipping) 993387Seric continue; 1006056Seric while (xp < &xbuf[sizeof xbuf]) 1016056Seric { 1026056Seric if (q == NULL) 1036056Seric { 1046056Seric *xp++ = c; 1056056Seric break; 1066056Seric } 1076056Seric if (*q == NULL) 1086056Seric break; 1096056Seric *xp++ = *q++; 1106056Seric } 1113379Seric } 1126056Seric *xp = '\0'; 1133379Seric 1143379Seric # ifdef DEBUG 1157677Seric if (tTd(35, 4)) 1166056Seric { 117*8064Seric printf("expand ==> "); 1186056Seric xputs(xbuf); 119*8064Seric printf("\n"); 1206056Seric } 1213379Seric # endif DEBUG 1223379Seric 1236056Seric /* recurse as appropriate */ 1246056Seric if (gotone) 1256980Seric return (expand2(xbuf, buf, buflim, e)); 1266056Seric 1276056Seric /* copy results out */ 1286056Seric for (q = buf, xp = xbuf; xp != '\0' && q < buflim-1; ) 1296056Seric *q++ = *xp++; 1306056Seric *q = '\0'; 1316056Seric 1326056Seric return (q); 1333379Seric } 1343379Seric /* 1353379Seric ** DEFINE -- define a macro. 1363379Seric ** 1373379Seric ** this would be better done using a #define macro. 1383379Seric ** 1393379Seric ** Parameters: 1403379Seric ** n -- the macro name. 1413379Seric ** v -- the macro value. 1423379Seric ** 1433379Seric ** Returns: 1443379Seric ** none. 1453379Seric ** 1463379Seric ** Side Effects: 1476980Seric ** CurEnv->e_macro[n] is defined. 1484092Seric ** 1494092Seric ** Notes: 1504092Seric ** There is one macro for each ASCII character, 1514092Seric ** although they are not all used. The currently 1524092Seric ** defined macros are: 1534092Seric ** 1544202Seric ** $a date in ARPANET format (preferring the Date: line 1554202Seric ** of the message) 1564202Seric ** $b the current date (as opposed to the date as found 1574202Seric ** the message) in ARPANET format 1584092Seric ** $c hop count 1594202Seric ** $d (current) date in UNIX (ctime) format 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 1774092Seric ** $x signature (full name) of from person 1784202Seric ** $y the tty id of our terminal 1794092Seric ** $z home directory of to person 1804092Seric ** 1814092Seric ** Macros marked with + must be defined in the 1824092Seric ** configuration file and are used internally, but 1834092Seric ** are not set. 1844092Seric ** 1854092Seric ** There are also some macros that can be used 1864092Seric ** arbitrarily to make the configuration file 1874092Seric ** cleaner. In general all upper-case letters 1884092Seric ** are available. 1893379Seric */ 1903379Seric 1913379Seric define(n, v) 1923379Seric char n; 1933379Seric char *v; 1943379Seric { 1953379Seric # ifdef DEBUG 1967677Seric if (tTd(35, 3)) 1976056Seric { 1986056Seric printf("define(%c as ", n); 1996056Seric xputs(v); 2006056Seric printf(")\n"); 2016056Seric } 2023379Seric # endif DEBUG 2036980Seric CurEnv->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 * 2194454Seric macvalue(n) 2204454Seric char n; 2214454Seric { 2226980Seric return (CurEnv->e_macro[n & 0177]); 2234454Seric } 224