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