1 # include "sendmail.h" 2 3 SCCSID(@(#)macro.c 3.11 03/06/82); 4 5 char *Macro[128]; 6 7 /* 8 ** EXPAND -- macro expand a string using $x escapes. 9 ** 10 ** Parameters: 11 ** s -- the string to expand. 12 ** buf -- the place to put the expansion. 13 ** buflim -- the buffer limit, i.e., the address 14 ** of the last usable position in buf. 15 ** 16 ** Returns: 17 ** End of interpolated output. 18 ** 19 ** Side Effects: 20 ** none. 21 */ 22 23 char * 24 expand(s, buf, buflim) 25 register char *s; 26 register char *buf; 27 char *buflim; 28 { 29 register char *q; 30 char xbuf[BUFSIZ]; 31 register char *xp = xbuf; 32 bool skipping; /* set if conditionally skipping output */ 33 bool gotone = FALSE; /* set if any expansion done */ 34 35 # ifdef DEBUG 36 if (Debug > 3) 37 { 38 printf("expand("); 39 xputs(s); 40 printf(")\n"); 41 } 42 # endif DEBUG 43 44 skipping = FALSE; 45 for (; *s != '\0'; s++) 46 { 47 char c; 48 49 /* 50 ** Check for non-ordinary (special?) character. 51 ** 'q' will be the interpolated quantity. 52 */ 53 54 q = NULL; 55 c = *s; 56 switch (c) 57 { 58 case CONDIF: /* see if var set */ 59 c = *++s; 60 skipping = Macro[c] == NULL; 61 continue; 62 63 case CONDELSE: /* change state of skipping */ 64 skipping = !skipping; 65 continue; 66 67 case CONDFI: /* stop skipping */ 68 skipping = FALSE; 69 continue; 70 71 case '$': /* macro interpolation */ 72 c = *++s; 73 q = Macro[c & 0177]; 74 if (q == NULL && c != '$') 75 continue; 76 gotone = TRUE; 77 break; 78 } 79 80 /* 81 ** Interpolate q or output one character 82 */ 83 84 if (skipping) 85 continue; 86 while (xp < &xbuf[sizeof xbuf]) 87 { 88 if (q == NULL) 89 { 90 *xp++ = c; 91 break; 92 } 93 if (*q == NULL) 94 break; 95 *xp++ = *q++; 96 } 97 } 98 *xp = '\0'; 99 100 # ifdef DEBUG 101 if (Debug > 3) 102 { 103 printf("expand ==> '"); 104 xputs(xbuf); 105 printf("'\n"); 106 } 107 # endif DEBUG 108 109 /* recurse as appropriate */ 110 if (gotone) 111 return (expand(xbuf, buf, buflim)); 112 113 /* copy results out */ 114 for (q = buf, xp = xbuf; xp != '\0' && q < buflim-1; ) 115 *q++ = *xp++; 116 *q = '\0'; 117 118 return (q); 119 } 120 /* 121 ** DEFINE -- define a macro. 122 ** 123 ** this would be better done using a #define macro. 124 ** 125 ** Parameters: 126 ** n -- the macro name. 127 ** v -- the macro value. 128 ** 129 ** Returns: 130 ** none. 131 ** 132 ** Side Effects: 133 ** Macro[n] is defined. 134 ** 135 ** Notes: 136 ** There is one macro for each ASCII character, 137 ** although they are not all used. The currently 138 ** defined macros are: 139 ** 140 ** $a date in ARPANET format (preferring the Date: line 141 ** of the message) 142 ** $b the current date (as opposed to the date as found 143 ** the message) in ARPANET format 144 ** $c hop count 145 ** $d (current) date in UNIX (ctime) format 146 ** $f raw from address 147 ** $g translated from address 148 ** $h to host 149 ** $i official SMTP hostname, used in messages+ 150 ** $l UNIX-style from line+ 151 ** $n name of sendmail ("MAILER-DAEMON" on local 152 ** net typically)+ 153 ** $o delimiters ("operators") for address tokens+ 154 ** $p my process id in decimal 155 ** $q the string that becomes an address -- this is 156 ** normally used to combine $g & $x. 157 ** $r protocol used to talk to sender 158 ** $s sender's host name 159 ** $t the current time in seconds since 1/1/1970 160 ** $u to user 161 ** $v version number of sendmail 162 ** $x signature (full name) of from person 163 ** $y the tty id of our terminal 164 ** $z home directory of to person 165 ** 166 ** Macros marked with + must be defined in the 167 ** configuration file and are used internally, but 168 ** are not set. 169 ** 170 ** There are also some macros that can be used 171 ** arbitrarily to make the configuration file 172 ** cleaner. In general all upper-case letters 173 ** are available. 174 */ 175 176 define(n, v) 177 char n; 178 char *v; 179 { 180 # ifdef DEBUG 181 if (Debug > 3) 182 { 183 printf("define(%c as ", n); 184 xputs(v); 185 printf(")\n"); 186 } 187 # endif DEBUG 188 Macro[n & 0177] = v; 189 } 190 /* 191 ** MACVALUE -- return uninterpreted value of a macro. 192 ** 193 ** Parameters: 194 ** n -- the name of the macro. 195 ** 196 ** Returns: 197 ** The value of n. 198 ** 199 ** Side Effects: 200 ** none. 201 */ 202 203 char * 204 macvalue(n) 205 char n; 206 { 207 return (Macro[n & 0177]); 208 } 209