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