|
|
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 provided
7: * that: (1) source distributions retain this entire copyright notice and
8: * comment, and (2) distributions including binaries display the following
9: * acknowledgement: ``This product includes software developed by the
10: * University of California, Berkeley and its contributors'' in the
11: * documentation or other materials provided with the distribution and in
12: * all advertising materials mentioning features or use of this software.
13: * Neither the name of the University nor the names of its contributors may
14: * be used to endorse or promote products derived from this software without
15: * specific prior written permission.
16: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
17: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
18: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19: */
20:
21: #ifndef lint
22: static char sccsid[] = "@(#)macro.c 5.7 (Berkeley) 6/1/90";
23: #endif /* not lint */
24:
25: # include "sendmail.h"
26:
27: /*
28: ** EXPAND -- macro expand a string using $x escapes.
29: **
30: ** Parameters:
31: ** s -- the string to expand.
32: ** buf -- the place to put the expansion.
33: ** buflim -- the buffer limit, i.e., the address
34: ** of the last usable position in buf.
35: ** e -- envelope in which to work.
36: **
37: ** Returns:
38: ** none.
39: **
40: ** Side Effects:
41: ** none.
42: */
43:
44: expand(s, buf, buflim, e)
45: register char *s;
46: register char *buf;
47: char *buflim;
48: register ENVELOPE *e;
49: {
50: register char *xp;
51: register char *q;
52: bool skipping; /* set if conditionally skipping output */
53: bool recurse = FALSE; /* set if recursion required */
54: int i;
55: char xbuf[BUFSIZ];
56: extern char *macvalue();
57:
58: if (tTd(35, 24))
59: {
60: printf("expand(");
61: xputs(s);
62: printf(")\n");
63: }
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: if (tTd(35, 24))
124: {
125: printf("expand ==> ");
126: xputs(xbuf);
127: printf("\n");
128: }
129:
130: /* recurse as appropriate */
131: if (recurse)
132: {
133: expand(xbuf, buf, buflim, e);
134: return;
135: }
136:
137: /* copy results out */
138: i = buflim - buf - 1;
139: if (i > xp - xbuf)
140: i = xp - xbuf;
141: bcopy(xbuf, buf, i);
142: buf[i] = '\0';
143: }
144: /*
145: ** DEFINE -- define a macro.
146: **
147: ** this would be better done using a #define macro.
148: **
149: ** Parameters:
150: ** n -- the macro name.
151: ** v -- the macro value.
152: ** e -- the envelope to store the definition in.
153: **
154: ** Returns:
155: ** none.
156: **
157: ** Side Effects:
158: ** e->e_macro[n] is defined.
159: **
160: ** Notes:
161: ** There is one macro for each ASCII character,
162: ** although they are not all used. The currently
163: ** defined macros are:
164: **
165: ** $a date in ARPANET format (preferring the Date: line
166: ** of the message)
167: ** $b the current date (as opposed to the date as found
168: ** the message) in ARPANET format
169: ** $c hop count
170: ** $d (current) date in UNIX (ctime) format
171: ** $e the SMTP entry message+
172: ** $f raw from address
173: ** $g translated from address
174: ** $h to host
175: ** $i queue id
176: ** $j official SMTP hostname, used in messages+
177: ** $l UNIX-style from line+
178: ** $n name of sendmail ("MAILER-DAEMON" on local
179: ** net typically)+
180: ** $o delimiters ("operators") for address tokens+
181: ** $p my process id in decimal
182: ** $q the string that becomes an address -- this is
183: ** normally used to combine $g & $x.
184: ** $r protocol used to talk to sender
185: ** $s sender's host name
186: ** $t the current time in seconds since 1/1/1970
187: ** $u to user
188: ** $v version number of sendmail
189: ** $w our host name (if it can be determined)
190: ** $x signature (full name) of from person
191: ** $y the tty id of our terminal
192: ** $z home directory of to person
193: **
194: ** Macros marked with + must be defined in the
195: ** configuration file and are used internally, but
196: ** are not set.
197: **
198: ** There are also some macros that can be used
199: ** arbitrarily to make the configuration file
200: ** cleaner. In general all upper-case letters
201: ** are available.
202: */
203:
204: define(n, v, e)
205: char n;
206: char *v;
207: register ENVELOPE *e;
208: {
209: if (tTd(35, 9))
210: {
211: printf("define(%c as ", n);
212: xputs(v);
213: printf(")\n");
214: }
215: e->e_macro[n & 0177] = v;
216: }
217: /*
218: ** MACVALUE -- return uninterpreted value of a macro.
219: **
220: ** Parameters:
221: ** n -- the name of the macro.
222: **
223: ** Returns:
224: ** The value of n.
225: **
226: ** Side Effects:
227: ** none.
228: */
229:
230: char *
231: macvalue(n, e)
232: char n;
233: register ENVELOPE *e;
234: {
235: n &= 0177;
236: while (e != NULL)
237: {
238: register char *p = e->e_macro[n];
239:
240: if (p != NULL)
241: return (p);
242: e = e->e_parent;
243: }
244: return (NULL);
245: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.