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