13379Seric # include "useful.h" 23379Seric 3*5919Seric SCCSID(@(#)macro.c 3.10 02/20/82); 43379Seric 53379Seric char *Macro[128]; 64073Seric extern int Debug; 73379Seric 83379Seric /* 93379Seric ** EXPAND -- macro expand a string using $x escapes. 103379Seric ** 113379Seric ** Parameters: 123379Seric ** s -- the string to expand. 133379Seric ** buf -- the place to put the expansion. 143379Seric ** buflim -- the buffer limit, i.e., the address 153379Seric ** of the last usable position in buf. 163379Seric ** 173379Seric ** Returns: 184319Seric ** End of interpolated output. 193379Seric ** 203379Seric ** Side Effects: 213379Seric ** none. 223379Seric */ 233379Seric 243379Seric char * 253379Seric expand(s, buf, buflim) 263379Seric register char *s; 273379Seric register char *buf; 283379Seric char *buflim; 293379Seric { 303379Seric register char *bp; 314319Seric bool skipping; /* set if conditionally skipping output */ 323379Seric 333379Seric # ifdef DEBUG 344073Seric if (Debug > 3) 353379Seric printf("expand(%s)\n", s); 363379Seric # endif DEBUG 373379Seric 383387Seric skipping = FALSE; 393379Seric for (bp = buf; *s != '\0'; s++) 403379Seric { 414319Seric register char *q; 424319Seric 434319Seric /* 444319Seric ** Check for non-ordinary (special?) character -- 454319Seric ** always escaped with dollar sign. 464319Seric ** 'q' will be the interpolated quantity. 474319Seric */ 484319Seric 493379Seric q = NULL; 503379Seric if (*s == '$') 513387Seric { 523387Seric char c; 533379Seric 543387Seric c = *++s; 553387Seric switch (c) 563387Seric { 573387Seric case '?': /* see if var set */ 583387Seric c = *++s; 593387Seric skipping = Macro[c] == NULL; 603387Seric break; 613387Seric 625910Seric case '|': /* else */ 633387Seric skipping = !skipping; 643387Seric break; 653387Seric 663387Seric case '.': /* end if */ 673387Seric skipping = FALSE; 683387Seric break; 693387Seric 703387Seric default: 713387Seric q = Macro[c & 0177]; 723387Seric break; 733387Seric } 744172Seric if (q == NULL && c != '$') 753387Seric continue; 763387Seric } 773387Seric 783379Seric /* 793379Seric ** Interpolate q or output one character 803379Seric */ 813379Seric 823387Seric if (skipping) 833387Seric continue; 843379Seric if (q != NULL) 853379Seric bp = expand(q, bp, buflim); 863379Seric else if (bp < buflim - 1) 873379Seric *bp++ = *s; 883379Seric } 893379Seric *bp = '\0'; 903379Seric 913379Seric # ifdef DEBUG 924073Seric if (Debug > 3) 933379Seric printf("expand ==> '%s'\n", buf); 943379Seric # endif DEBUG 953379Seric 963379Seric return (bp); 973379Seric } 983379Seric /* 993379Seric ** DEFINE -- define a macro. 1003379Seric ** 1013379Seric ** this would be better done using a #define macro. 1023379Seric ** 1033379Seric ** Parameters: 1043379Seric ** n -- the macro name. 1053379Seric ** v -- the macro value. 1063379Seric ** 1073379Seric ** Returns: 1083379Seric ** none. 1093379Seric ** 1103379Seric ** Side Effects: 1113379Seric ** Macro[n] is defined. 1124092Seric ** 1134092Seric ** Notes: 1144092Seric ** There is one macro for each ASCII character, 1154092Seric ** although they are not all used. The currently 1164092Seric ** defined macros are: 1174092Seric ** 1184202Seric ** $a date in ARPANET format (preferring the Date: line 1194202Seric ** of the message) 1204202Seric ** $b the current date (as opposed to the date as found 1214202Seric ** the message) in ARPANET format 1224092Seric ** $c hop count 1234202Seric ** $d (current) date in UNIX (ctime) format 1244092Seric ** $f raw from address 1254092Seric ** $g translated from address 1264092Seric ** $h to host 1274558Seric ** $i official SMTP hostname, used in messages+ 1284092Seric ** $l UNIX-style from line+ 1294092Seric ** $n name of sendmail ("MAILER-DAEMON" on local 1304092Seric ** net typically)+ 1314092Seric ** $o delimiters ("operators") for address tokens+ 1324092Seric ** $p my process id in decimal 133*5919Seric ** $q the string that becomes an address -- this is 134*5919Seric ** normally used to combine $g & $x. 1355187Seric ** $r protocol used to talk to sender 1365187Seric ** $s sender's host name 1374092Seric ** $t the current time in seconds since 1/1/1970 1384092Seric ** $u to user 1394092Seric ** $v version number of sendmail 1404092Seric ** $x signature (full name) of from person 1414202Seric ** $y the tty id of our terminal 1424092Seric ** $z home directory of to person 1434092Seric ** 1444092Seric ** Macros marked with + must be defined in the 1454092Seric ** configuration file and are used internally, but 1464092Seric ** are not set. 1474092Seric ** 1484092Seric ** There are also some macros that can be used 1494092Seric ** arbitrarily to make the configuration file 1504092Seric ** cleaner. In general all upper-case letters 1514092Seric ** are available. 1523379Seric */ 1533379Seric 1543379Seric define(n, v) 1553379Seric char n; 1563379Seric char *v; 1573379Seric { 1583379Seric # ifdef DEBUG 1594073Seric if (Debug > 3) 1603379Seric printf("define(%c as %s)\n", n, v); 1613379Seric # endif DEBUG 1623379Seric Macro[n & 0177] = v; 1633379Seric } 1644454Seric /* 1654454Seric ** MACVALUE -- return uninterpreted value of a macro. 1664454Seric ** 1674454Seric ** Parameters: 1684454Seric ** n -- the name of the macro. 1694454Seric ** 1704454Seric ** Returns: 1714454Seric ** The value of n. 1724454Seric ** 1734454Seric ** Side Effects: 1744454Seric ** none. 1754454Seric */ 1764454Seric 1774454Seric char * 1784454Seric macvalue(n) 1794454Seric char n; 1804454Seric { 1814454Seric return (Macro[n & 0177]); 1824454Seric } 183