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