1 # include "useful.h"
2 
3 static char SccsId[] = "@(#)macro.c	3.1	08/09/81";
4 
5 char	*Macro[128];
6 extern int	Debug;
7 
8 /*
9 **  EXPAND -- macro expand a string using $x escapes.
10 **
11 **	Parameters:
12 **		s -- the string to expand.
13 **		buf -- the place to put the expansion.
14 **		buflim -- the buffer limit, i.e., the address
15 **			of the last usable position in buf.
16 **
17 **	Returns:
18 **		buf.
19 **
20 **	Side Effects:
21 **		none.
22 */
23 
24 char *
25 expand(s, buf, buflim)
26 	register char *s;
27 	register char *buf;
28 	char *buflim;
29 {
30 	register char *q;
31 	register char *bp;
32 	bool skipping;
33 
34 # ifdef DEBUG
35 	if (Debug > 3)
36 		printf("expand(%s)\n", s);
37 # endif DEBUG
38 
39 	skipping = FALSE;
40 	for (bp = buf; *s != '\0'; s++)
41 	{
42 		/* q will be the interpolated quantity */
43 		q = NULL;
44 		if (*s == '$')
45 		{
46 			char c;
47 
48 			c = *++s;
49 			switch (c)
50 			{
51 			  case '?':	/* see if var set */
52 				c = *++s;
53 				skipping = Macro[c] == NULL;
54 				break;
55 
56 			  case ':':	/* else */
57 				skipping = !skipping;
58 				break;
59 
60 			  case '.':	/* end if */
61 				skipping = FALSE;
62 				break;
63 
64 			  default:
65 				q = Macro[c & 0177];
66 				break;
67 			}
68 			if (q == NULL)
69 				continue;
70 		}
71 
72 		/*
73 		**  Interpolate q or output one character
74 		*/
75 
76 		if (skipping)
77 			continue;
78 		if (q != NULL)
79 			bp = expand(q, bp, buflim);
80 		else if (bp < buflim - 1)
81 			*bp++ = *s;
82 	}
83 	*bp = '\0';
84 
85 # ifdef DEBUG
86 	if (Debug > 3)
87 		printf("expand ==> '%s'\n", buf);
88 # endif DEBUG
89 
90 	return (bp);
91 }
92 /*
93 **  DEFINE -- define a macro.
94 **
95 **	this would be better done using a #define macro.
96 **
97 **	Parameters:
98 **		n -- the macro name.
99 **		v -- the macro value.
100 **
101 **	Returns:
102 **		none.
103 **
104 **	Side Effects:
105 **		Macro[n] is defined.
106 **
107 **	Notes:
108 **		There is one macro for each ASCII character,
109 **		although they are not all used.  The currently
110 **		defined macros are:
111 **
112 **		$a   date in arpa format
113 **		$c   hop count
114 **		$d   date in ctime format
115 **		$f   raw from address
116 **		$g   translated from address
117 **		$h   to host
118 **		$l   UNIX-style from line+
119 **		$n   name of sendmail ("MAILER-DAEMON" on local
120 **		     net typically)+
121 **		$o   delimiters ("operators") for address tokens+
122 **		$p   my process id in decimal
123 **		$t   the current time in seconds since 1/1/1970
124 **		$u   to user
125 **		$v   version number of sendmail
126 **		$x   signature (full name) of from person
127 **		$z   home directory of to person
128 **
129 **		Macros marked with + must be defined in the
130 **		configuration file and are used internally, but
131 **		are not set.
132 **
133 **		There are also some macros that can be used
134 **		arbitrarily to make the configuration file
135 **		cleaner.  In general all upper-case letters
136 **		are available.
137 */
138 
139 define(n, v)
140 	char n;
141 	char *v;
142 {
143 # ifdef DEBUG
144 	if (Debug > 3)
145 		printf("define(%c as %s)\n", n, v);
146 # endif DEBUG
147 	Macro[n & 0177] = v;
148 }
149