make years in $t be four digits; do case folding for DBM databases
[unix-history] / usr / src / usr.sbin / sendmail / src / macro.c
CommitLineData
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 10static 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
33expand(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 193define(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
219char *
857afefe 220macvalue(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}