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