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