13379Seric # include "useful.h" 23379Seric 3*5187Seric static char SccsId[] = "@(#)macro.c 3.7 12/05/81"; 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 623387Seric 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*5187Seric ** $r protocol used to talk to sender 134*5187Seric ** $s sender's host name 1354092Seric ** $t the current time in seconds since 1/1/1970 1364092Seric ** $u to user 1374092Seric ** $v version number of sendmail 1384092Seric ** $x signature (full name) of from person 1394202Seric ** $y the tty id of our terminal 1404092Seric ** $z home directory of to person 1414092Seric ** 1424092Seric ** Macros marked with + must be defined in the 1434092Seric ** configuration file and are used internally, but 1444092Seric ** are not set. 1454092Seric ** 1464092Seric ** There are also some macros that can be used 1474092Seric ** arbitrarily to make the configuration file 1484092Seric ** cleaner. In general all upper-case letters 1494092Seric ** are available. 1503379Seric */ 1513379Seric 1523379Seric define(n, v) 1533379Seric char n; 1543379Seric char *v; 1553379Seric { 1563379Seric # ifdef DEBUG 1574073Seric if (Debug > 3) 1583379Seric printf("define(%c as %s)\n", n, v); 1593379Seric # endif DEBUG 1603379Seric Macro[n & 0177] = v; 1613379Seric } 1624454Seric /* 1634454Seric ** MACVALUE -- return uninterpreted value of a macro. 1644454Seric ** 1654454Seric ** Parameters: 1664454Seric ** n -- the name of the macro. 1674454Seric ** 1684454Seric ** Returns: 1694454Seric ** The value of n. 1704454Seric ** 1714454Seric ** Side Effects: 1724454Seric ** none. 1734454Seric */ 1744454Seric 1754454Seric char * 1764454Seric macvalue(n) 1774454Seric char n; 1784454Seric { 1794454Seric return (Macro[n & 0177]); 1804454Seric } 181