122707Sdist /* 2*33729Sbostic * Copyright (c) 1988 Regents of the University of California. 3*33729Sbostic * All rights reserved. 4*33729Sbostic * 5*33729Sbostic * Redistribution and use in source and binary forms are permitted 6*33729Sbostic * provided that this notice is preserved and that due credit is given 7*33729Sbostic * to the University of California at Berkeley. The name of the University 8*33729Sbostic * may not be used to endorse or promote products derived from this 9*33729Sbostic * software without specific prior written permission. This software 10*33729Sbostic * is provided ``as is'' without express or implied warranty. 11*33729Sbostic * 12*33729Sbostic * Sendmail 13*33729Sbostic * Copyright (c) 1983 Eric P. Allman 14*33729Sbostic * Berkeley, California 15*33729Sbostic */ 1622707Sdist 1722707Sdist #ifndef lint 18*33729Sbostic static char sccsid[] = "@(#)macro.c 5.4 (Berkeley) 03/13/88"; 19*33729Sbostic #endif /* not lint */ 2022707Sdist 216056Seric # include "sendmail.h" 223379Seric 233379Seric /* 243379Seric ** EXPAND -- macro expand a string using $x escapes. 253379Seric ** 263379Seric ** Parameters: 273379Seric ** s -- the string to expand. 283379Seric ** buf -- the place to put the expansion. 293379Seric ** buflim -- the buffer limit, i.e., the address 303379Seric ** of the last usable position in buf. 316980Seric ** e -- envelope in which to work. 323379Seric ** 333379Seric ** Returns: 349382Seric ** none. 353379Seric ** 363379Seric ** Side Effects: 373379Seric ** none. 383379Seric */ 393379Seric 406980Seric expand(s, buf, buflim, e) 416980Seric register char *s; 426980Seric register char *buf; 436980Seric char *buflim; 446980Seric register ENVELOPE *e; 456980Seric { 4617349Seric register char *xp; 476056Seric register char *q; 489382Seric bool skipping; /* set if conditionally skipping output */ 4917349Seric bool recurse = FALSE; /* set if recursion required */ 5017349Seric int i; 516056Seric char xbuf[BUFSIZ]; 528182Seric extern char *macvalue(); 533379Seric 543379Seric # ifdef DEBUG 5524941Seric if (tTd(35, 24)) 566056Seric { 576056Seric printf("expand("); 586056Seric xputs(s); 596056Seric printf(")\n"); 606056Seric } 613379Seric # endif DEBUG 623379Seric 633387Seric skipping = FALSE; 648064Seric if (s == NULL) 658064Seric s = ""; 6617349Seric for (xp = xbuf; *s != '\0'; s++) 673379Seric { 686056Seric char c; 694319Seric 704319Seric /* 716056Seric ** Check for non-ordinary (special?) character. 724319Seric ** 'q' will be the interpolated quantity. 734319Seric */ 744319Seric 753379Seric q = NULL; 766056Seric c = *s; 776056Seric switch (c) 783387Seric { 796056Seric case CONDIF: /* see if var set */ 803387Seric c = *++s; 818182Seric skipping = macvalue(c, e) == NULL; 826056Seric continue; 833387Seric 846056Seric case CONDELSE: /* change state of skipping */ 856056Seric skipping = !skipping; 866056Seric continue; 873387Seric 886056Seric case CONDFI: /* stop skipping */ 896056Seric skipping = FALSE; 906056Seric continue; 913387Seric 9216146Seric case '\001': /* macro interpolation */ 936056Seric c = *++s; 948182Seric q = macvalue(c & 0177, e); 959382Seric if (q == NULL) 963387Seric continue; 976056Seric break; 983387Seric } 993387Seric 1003379Seric /* 1013379Seric ** Interpolate q or output one character 1023379Seric */ 1033379Seric 10417349Seric if (skipping || xp >= &xbuf[sizeof xbuf]) 1053387Seric continue; 10617349Seric if (q == NULL) 10717349Seric *xp++ = c; 10817349Seric else 1096056Seric { 11017349Seric /* copy to end of q or max space remaining in buf */ 11117349Seric while ((c = *q++) != '\0' && xp < &xbuf[sizeof xbuf - 1]) 1126056Seric { 11317349Seric if (iscntrl(c) && !isspace(c)) 11417349Seric recurse = TRUE; 1156056Seric *xp++ = c; 1166056Seric } 1176056Seric } 1183379Seric } 1196056Seric *xp = '\0'; 1203379Seric 1213379Seric # ifdef DEBUG 12224941Seric if (tTd(35, 24)) 1236056Seric { 1248064Seric printf("expand ==> "); 1256056Seric xputs(xbuf); 1268064Seric printf("\n"); 1276056Seric } 1283379Seric # endif DEBUG 1293379Seric 1306056Seric /* recurse as appropriate */ 13117349Seric if (recurse) 1329382Seric { 1339382Seric expand(xbuf, buf, buflim, e); 1349382Seric return; 1359382Seric } 1366056Seric 1376056Seric /* copy results out */ 13817349Seric i = buflim - buf - 1; 13917349Seric if (i > xp - xbuf) 14017349Seric i = xp - xbuf; 14117349Seric bcopy(xbuf, buf, i); 14217349Seric buf[i] = '\0'; 1433379Seric } 1443379Seric /* 1453379Seric ** DEFINE -- define a macro. 1463379Seric ** 1473379Seric ** this would be better done using a #define macro. 1483379Seric ** 1493379Seric ** Parameters: 1503379Seric ** n -- the macro name. 1513379Seric ** v -- the macro value. 1529382Seric ** e -- the envelope to store the definition in. 1533379Seric ** 1543379Seric ** Returns: 1553379Seric ** none. 1563379Seric ** 1573379Seric ** Side Effects: 1589382Seric ** e->e_macro[n] is defined. 1594092Seric ** 1604092Seric ** Notes: 1614092Seric ** There is one macro for each ASCII character, 1624092Seric ** although they are not all used. The currently 1634092Seric ** defined macros are: 1644092Seric ** 1654202Seric ** $a date in ARPANET format (preferring the Date: line 1664202Seric ** of the message) 1674202Seric ** $b the current date (as opposed to the date as found 1684202Seric ** the message) in ARPANET format 1694092Seric ** $c hop count 1704202Seric ** $d (current) date in UNIX (ctime) format 17110710Seric ** $e the SMTP entry message+ 1724092Seric ** $f raw from address 1734092Seric ** $g translated from address 1744092Seric ** $h to host 1757851Seric ** $i queue id 1767851Seric ** $j official SMTP hostname, used in messages+ 1774092Seric ** $l UNIX-style from line+ 1784092Seric ** $n name of sendmail ("MAILER-DAEMON" on local 1794092Seric ** net typically)+ 1804092Seric ** $o delimiters ("operators") for address tokens+ 1814092Seric ** $p my process id in decimal 1825919Seric ** $q the string that becomes an address -- this is 1835919Seric ** normally used to combine $g & $x. 1845187Seric ** $r protocol used to talk to sender 1855187Seric ** $s sender's host name 1864092Seric ** $t the current time in seconds since 1/1/1970 1874092Seric ** $u to user 1884092Seric ** $v version number of sendmail 18910407Seric ** $w our host name (if it can be determined) 1904092Seric ** $x signature (full name) of from person 1914202Seric ** $y the tty id of our terminal 1924092Seric ** $z home directory of to person 1934092Seric ** 1944092Seric ** Macros marked with + must be defined in the 1954092Seric ** configuration file and are used internally, but 1964092Seric ** are not set. 1974092Seric ** 1984092Seric ** There are also some macros that can be used 1994092Seric ** arbitrarily to make the configuration file 2004092Seric ** cleaner. In general all upper-case letters 2014092Seric ** are available. 2023379Seric */ 2033379Seric 2049382Seric define(n, v, e) 2053379Seric char n; 2063379Seric char *v; 2079382Seric register ENVELOPE *e; 2083379Seric { 2093379Seric # ifdef DEBUG 21024941Seric if (tTd(35, 9)) 2116056Seric { 2126056Seric printf("define(%c as ", n); 2136056Seric xputs(v); 2146056Seric printf(")\n"); 2156056Seric } 2163379Seric # endif DEBUG 2179382Seric e->e_macro[n & 0177] = v; 2183379Seric } 2194454Seric /* 2204454Seric ** MACVALUE -- return uninterpreted value of a macro. 2214454Seric ** 2224454Seric ** Parameters: 2234454Seric ** n -- the name of the macro. 2244454Seric ** 2254454Seric ** Returns: 2264454Seric ** The value of n. 2274454Seric ** 2284454Seric ** Side Effects: 2294454Seric ** none. 2304454Seric */ 2314454Seric 2324454Seric char * 2338182Seric macvalue(n, e) 2344454Seric char n; 2358182Seric register ENVELOPE *e; 2364454Seric { 2378182Seric n &= 0177; 2388182Seric while (e != NULL) 2398182Seric { 2408182Seric register char *p = e->e_macro[n]; 2418182Seric 2428182Seric if (p != NULL) 2438182Seric return (p); 2448182Seric e = e->e_parent; 2458182Seric } 2468182Seric return (NULL); 2474454Seric } 248