1 # include "useful.h" 2 # include "conf.h" 3 4 static char SccsId[] = "@(#)macro.c 3.4.1.1 09/23/81"; 5 6 char *Macro[128]; 7 extern int Debug; 8 9 /* 10 ** EXPAND -- macro expand a string using $x escapes. 11 ** 12 ** Parameters: 13 ** s -- the string to expand. 14 ** buf -- the place to put the expansion. 15 ** buflim -- the buffer limit, i.e., the address 16 ** of the last usable position in buf. 17 ** 18 ** Returns: 19 ** End of interpolated output. 20 ** 21 ** Side Effects: 22 ** none. 23 */ 24 25 char * 26 expand(s, buf, buflim) 27 register char *s; 28 register char *buf; 29 char *buflim; 30 { 31 register char *bp; 32 bool skipping; /* set if conditionally skipping output */ 33 34 # ifdef DEBUG 35 if (Debug > 3) 36 printf("expand(%s)\n", s); 37 # endif DEBUG 38 39 skipping = FALSE; 40 for (bp = buf; *s != '\0'; s++) 41 { 42 register char *q; 43 44 /* 45 ** Check for non-ordinary (special?) character -- 46 ** always escaped with dollar sign. 47 ** 'q' will be the interpolated quantity. 48 */ 49 50 q = NULL; 51 if (*s == '$') 52 { 53 char c; 54 55 c = *++s; 56 switch (c) 57 { 58 case '?': /* see if var set */ 59 c = *++s; 60 skipping = Macro[c] == NULL; 61 break; 62 63 case ':': /* else */ 64 skipping = !skipping; 65 break; 66 67 case '.': /* end if */ 68 skipping = FALSE; 69 break; 70 71 default: 72 q = Macro[c & 0177]; 73 break; 74 } 75 if (q == NULL && c != '$') 76 continue; 77 } 78 79 /* 80 ** Interpolate q or output one character 81 */ 82 83 if (skipping) 84 continue; 85 if (q != NULL) 86 bp = expand(q, bp, buflim); 87 else if (bp < buflim - 1) 88 *bp++ = *s; 89 } 90 *bp = '\0'; 91 92 # ifdef DEBUG 93 if (Debug > 3) 94 printf("expand ==> '%s'\n", buf); 95 # endif DEBUG 96 97 return (bp); 98 } 99 /* 100 ** DEFINE -- define a macro. 101 ** 102 ** this would be better done using a #define macro. 103 ** 104 ** Parameters: 105 ** n -- the macro name. 106 ** v -- the macro value. 107 ** 108 ** Returns: 109 ** none. 110 ** 111 ** Side Effects: 112 ** Macro[n] is defined. 113 ** 114 ** Notes: 115 ** There is one macro for each ASCII character, 116 ** although they are not all used. The currently 117 ** defined macros are: 118 ** 119 ** $a date in ARPANET format (preferring the Date: line 120 ** of the message) 121 ** $b the current date (as opposed to the date as found 122 ** the message) in ARPANET format 123 ** $c hop count 124 ** $d (current) date in UNIX (ctime) format 125 ** $f raw from address 126 ** $g translated from address 127 ** $h to host 128 ** $l UNIX-style from line+ 129 ** $n name of sendmail ("MAILER-DAEMON" on local 130 ** net typically)+ 131 ** $o delimiters ("operators") for address tokens+ 132 ** $p my process id in decimal 133 ** $t the current time in seconds since 1/1/1970 134 ** $u to user 135 ** $v version number of sendmail 136 ** $x signature (full name) of from person 137 ** $y the tty id of our terminal 138 ** $z home directory of to person 139 ** 140 ** Macros marked with + must be defined in the 141 ** configuration file and are used internally, but 142 ** are not set. 143 ** 144 ** There are also some macros that can be used 145 ** arbitrarily to make the configuration file 146 ** cleaner. In general all upper-case letters 147 ** are available. 148 */ 149 150 define(n, v) 151 char n; 152 char *v; 153 { 154 # ifdef DEBUG 155 if (Debug > 3) 156 printf("define(%c as %s)\n", n, v); 157 # endif DEBUG 158 Macro[n & 0177] = v; 159 } 160