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