122707Sdist /* 2*34921Sbostic * Copyright (c) 1983 Eric P. Allman 333729Sbostic * Copyright (c) 1988 Regents of the University of California. 433729Sbostic * All rights reserved. 533729Sbostic * 633729Sbostic * Redistribution and use in source and binary forms are permitted 7*34921Sbostic * provided that the above copyright notice and this paragraph are 8*34921Sbostic * duplicated in all such forms and that any documentation, 9*34921Sbostic * advertising materials, and other materials related to such 10*34921Sbostic * distribution and use acknowledge that the software was developed 11*34921Sbostic * by the University of California, Berkeley. The name of the 12*34921Sbostic * University may not be used to endorse or promote products derived 13*34921Sbostic * from this software without specific prior written permission. 14*34921Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 15*34921Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 16*34921Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1733729Sbostic */ 1822707Sdist 1922707Sdist #ifndef lint 20*34921Sbostic static char sccsid[] = "@(#)macro.c 5.5 (Berkeley) 06/30/88"; 2133729Sbostic #endif /* not lint */ 2222707Sdist 236056Seric # include "sendmail.h" 243379Seric 253379Seric /* 263379Seric ** EXPAND -- macro expand a string using $x escapes. 273379Seric ** 283379Seric ** Parameters: 293379Seric ** s -- the string to expand. 303379Seric ** buf -- the place to put the expansion. 313379Seric ** buflim -- the buffer limit, i.e., the address 323379Seric ** of the last usable position in buf. 336980Seric ** e -- envelope in which to work. 343379Seric ** 353379Seric ** Returns: 369382Seric ** none. 373379Seric ** 383379Seric ** Side Effects: 393379Seric ** none. 403379Seric */ 413379Seric 426980Seric expand(s, buf, buflim, e) 436980Seric register char *s; 446980Seric register char *buf; 456980Seric char *buflim; 466980Seric register ENVELOPE *e; 476980Seric { 4817349Seric register char *xp; 496056Seric register char *q; 509382Seric bool skipping; /* set if conditionally skipping output */ 5117349Seric bool recurse = FALSE; /* set if recursion required */ 5217349Seric int i; 536056Seric char xbuf[BUFSIZ]; 548182Seric extern char *macvalue(); 553379Seric 563379Seric # ifdef DEBUG 5724941Seric if (tTd(35, 24)) 586056Seric { 596056Seric printf("expand("); 606056Seric xputs(s); 616056Seric printf(")\n"); 626056Seric } 633379Seric # endif DEBUG 643379Seric 653387Seric skipping = FALSE; 668064Seric if (s == NULL) 678064Seric s = ""; 6817349Seric for (xp = xbuf; *s != '\0'; s++) 693379Seric { 706056Seric char c; 714319Seric 724319Seric /* 736056Seric ** Check for non-ordinary (special?) character. 744319Seric ** 'q' will be the interpolated quantity. 754319Seric */ 764319Seric 773379Seric q = NULL; 786056Seric c = *s; 796056Seric switch (c) 803387Seric { 816056Seric case CONDIF: /* see if var set */ 823387Seric c = *++s; 838182Seric skipping = macvalue(c, e) == NULL; 846056Seric continue; 853387Seric 866056Seric case CONDELSE: /* change state of skipping */ 876056Seric skipping = !skipping; 886056Seric continue; 893387Seric 906056Seric case CONDFI: /* stop skipping */ 916056Seric skipping = FALSE; 926056Seric continue; 933387Seric 9416146Seric case '\001': /* macro interpolation */ 956056Seric c = *++s; 968182Seric q = macvalue(c & 0177, e); 979382Seric if (q == NULL) 983387Seric continue; 996056Seric break; 1003387Seric } 1013387Seric 1023379Seric /* 1033379Seric ** Interpolate q or output one character 1043379Seric */ 1053379Seric 10617349Seric if (skipping || xp >= &xbuf[sizeof xbuf]) 1073387Seric continue; 10817349Seric if (q == NULL) 10917349Seric *xp++ = c; 11017349Seric else 1116056Seric { 11217349Seric /* copy to end of q or max space remaining in buf */ 11317349Seric while ((c = *q++) != '\0' && xp < &xbuf[sizeof xbuf - 1]) 1146056Seric { 11517349Seric if (iscntrl(c) && !isspace(c)) 11617349Seric recurse = TRUE; 1176056Seric *xp++ = c; 1186056Seric } 1196056Seric } 1203379Seric } 1216056Seric *xp = '\0'; 1223379Seric 1233379Seric # ifdef DEBUG 12424941Seric if (tTd(35, 24)) 1256056Seric { 1268064Seric printf("expand ==> "); 1276056Seric xputs(xbuf); 1288064Seric printf("\n"); 1296056Seric } 1303379Seric # endif DEBUG 1313379Seric 1326056Seric /* recurse as appropriate */ 13317349Seric if (recurse) 1349382Seric { 1359382Seric expand(xbuf, buf, buflim, e); 1369382Seric return; 1379382Seric } 1386056Seric 1396056Seric /* copy results out */ 14017349Seric i = buflim - buf - 1; 14117349Seric if (i > xp - xbuf) 14217349Seric i = xp - xbuf; 14317349Seric bcopy(xbuf, buf, i); 14417349Seric buf[i] = '\0'; 1453379Seric } 1463379Seric /* 1473379Seric ** DEFINE -- define a macro. 1483379Seric ** 1493379Seric ** this would be better done using a #define macro. 1503379Seric ** 1513379Seric ** Parameters: 1523379Seric ** n -- the macro name. 1533379Seric ** v -- the macro value. 1549382Seric ** e -- the envelope to store the definition in. 1553379Seric ** 1563379Seric ** Returns: 1573379Seric ** none. 1583379Seric ** 1593379Seric ** Side Effects: 1609382Seric ** e->e_macro[n] is defined. 1614092Seric ** 1624092Seric ** Notes: 1634092Seric ** There is one macro for each ASCII character, 1644092Seric ** although they are not all used. The currently 1654092Seric ** defined macros are: 1664092Seric ** 1674202Seric ** $a date in ARPANET format (preferring the Date: line 1684202Seric ** of the message) 1694202Seric ** $b the current date (as opposed to the date as found 1704202Seric ** the message) in ARPANET format 1714092Seric ** $c hop count 1724202Seric ** $d (current) date in UNIX (ctime) format 17310710Seric ** $e the SMTP entry message+ 1744092Seric ** $f raw from address 1754092Seric ** $g translated from address 1764092Seric ** $h to host 1777851Seric ** $i queue id 1787851Seric ** $j official SMTP hostname, used in messages+ 1794092Seric ** $l UNIX-style from line+ 1804092Seric ** $n name of sendmail ("MAILER-DAEMON" on local 1814092Seric ** net typically)+ 1824092Seric ** $o delimiters ("operators") for address tokens+ 1834092Seric ** $p my process id in decimal 1845919Seric ** $q the string that becomes an address -- this is 1855919Seric ** normally used to combine $g & $x. 1865187Seric ** $r protocol used to talk to sender 1875187Seric ** $s sender's host name 1884092Seric ** $t the current time in seconds since 1/1/1970 1894092Seric ** $u to user 1904092Seric ** $v version number of sendmail 19110407Seric ** $w our host name (if it can be determined) 1924092Seric ** $x signature (full name) of from person 1934202Seric ** $y the tty id of our terminal 1944092Seric ** $z home directory of to person 1954092Seric ** 1964092Seric ** Macros marked with + must be defined in the 1974092Seric ** configuration file and are used internally, but 1984092Seric ** are not set. 1994092Seric ** 2004092Seric ** There are also some macros that can be used 2014092Seric ** arbitrarily to make the configuration file 2024092Seric ** cleaner. In general all upper-case letters 2034092Seric ** are available. 2043379Seric */ 2053379Seric 2069382Seric define(n, v, e) 2073379Seric char n; 2083379Seric char *v; 2099382Seric register ENVELOPE *e; 2103379Seric { 2113379Seric # ifdef DEBUG 21224941Seric if (tTd(35, 9)) 2136056Seric { 2146056Seric printf("define(%c as ", n); 2156056Seric xputs(v); 2166056Seric printf(")\n"); 2176056Seric } 2183379Seric # endif DEBUG 2199382Seric e->e_macro[n & 0177] = v; 2203379Seric } 2214454Seric /* 2224454Seric ** MACVALUE -- return uninterpreted value of a macro. 2234454Seric ** 2244454Seric ** Parameters: 2254454Seric ** n -- the name of the macro. 2264454Seric ** 2274454Seric ** Returns: 2284454Seric ** The value of n. 2294454Seric ** 2304454Seric ** Side Effects: 2314454Seric ** none. 2324454Seric */ 2334454Seric 2344454Seric char * 2358182Seric macvalue(n, e) 2364454Seric char n; 2378182Seric register ENVELOPE *e; 2384454Seric { 2398182Seric n &= 0177; 2408182Seric while (e != NULL) 2418182Seric { 2428182Seric register char *p = e->e_macro[n]; 2438182Seric 2448182Seric if (p != NULL) 2458182Seric return (p); 2468182Seric e = e->e_parent; 2478182Seric } 2488182Seric return (NULL); 2494454Seric } 250