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