xref: /freebsd/contrib/sendmail/src/stab.c (revision 1b6c76a2fe091c74f08427e6c870851025a9cf67)
1 /*
2  * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
3  *	All rights reserved.
4  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
5  * Copyright (c) 1988, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * By using this file, you agree to the terms and conditions set
9  * forth in the LICENSE file which can be found at the top level of
10  * the sendmail distribution.
11  *
12  */
13 
14 #ifndef lint
15 static char id[] = "@(#)$Id: stab.c,v 8.40.16.7 2001/05/07 22:06:41 gshapiro Exp $";
16 #endif /* ! lint */
17 
18 #include <sendmail.h>
19 
20 /*
21 **  STAB -- manage the symbol table
22 **
23 **	Parameters:
24 **		name -- the name to be looked up or inserted.
25 **		type -- the type of symbol.
26 **		op -- what to do:
27 **			ST_ENTER -- enter the name if not
28 **				already present.
29 **			ST_FIND -- find it only.
30 **
31 **	Returns:
32 **		pointer to a STAB entry for this name.
33 **		NULL if not found and not entered.
34 **
35 **	Side Effects:
36 **		can update the symbol table.
37 */
38 
39 #define STABSIZE	2003
40 
41 static STAB	*SymTab[STABSIZE];
42 
43 STAB *
44 stab(name, type, op)
45 	char *name;
46 	int type;
47 	int op;
48 {
49 	register STAB *s;
50 	register STAB **ps;
51 	register int hfunc;
52 	register char *p;
53 	int len;
54 
55 	if (tTd(36, 5))
56 		dprintf("STAB: %s %d ", name, type);
57 
58 	/*
59 	**  Compute the hashing function
60 	*/
61 
62 	hfunc = type;
63 	for (p = name; *p != '\0'; p++)
64 		hfunc = ((hfunc << 1) ^ (lower(*p) & 0377)) % STABSIZE;
65 
66 	if (tTd(36, 9))
67 		dprintf("(hfunc=%d) ", hfunc);
68 
69 	ps = &SymTab[hfunc];
70 	if (type == ST_MACRO || type == ST_RULESET)
71 	{
72 		while ((s = *ps) != NULL &&
73 		       (s->s_type != type || strcmp(name, s->s_name)))
74 			ps = &s->s_next;
75 	}
76 	else
77 	{
78 		while ((s = *ps) != NULL &&
79 		       (s->s_type != type || strcasecmp(name, s->s_name)))
80 			ps = &s->s_next;
81 	}
82 
83 	/*
84 	**  Dispose of the entry.
85 	*/
86 
87 	if (s != NULL || op == ST_FIND)
88 	{
89 		if (tTd(36, 5))
90 		{
91 			if (s == NULL)
92 				dprintf("not found\n");
93 			else
94 			{
95 				long *lp = (long *) s->s_class;
96 
97 				dprintf("type %d val %lx %lx %lx %lx\n",
98 					s->s_type, lp[0], lp[1], lp[2], lp[3]);
99 			}
100 		}
101 		return s;
102 	}
103 
104 	/*
105 	**  Make a new entry and link it in.
106 	*/
107 
108 	if (tTd(36, 5))
109 		dprintf("entered\n");
110 
111 	/* determine size of new entry */
112 	switch (type)
113 	{
114 	  case ST_CLASS:
115 		len = sizeof s->s_class;
116 		break;
117 
118 	  case ST_ADDRESS:
119 		len = sizeof s->s_address;
120 		break;
121 
122 	  case ST_MAILER:
123 		len = sizeof s->s_mailer;
124 		break;
125 
126 	  case ST_ALIAS:
127 		len = sizeof s->s_alias;
128 		break;
129 
130 	  case ST_MAPCLASS:
131 		len = sizeof s->s_mapclass;
132 		break;
133 
134 	  case ST_MAP:
135 		len = sizeof s->s_map;
136 		break;
137 
138 	  case ST_HOSTSIG:
139 		len = sizeof s->s_hostsig;
140 		break;
141 
142 	  case ST_NAMECANON:
143 		len = sizeof s->s_namecanon;
144 		break;
145 
146 	  case ST_MACRO:
147 		len = sizeof s->s_macro;
148 		break;
149 
150 	  case ST_RULESET:
151 		len = sizeof s->s_ruleset;
152 		break;
153 
154 	  case ST_HEADER:
155 		len = sizeof s->s_header;
156 		break;
157 
158 	  case ST_SERVICE:
159 		len = sizeof s->s_service;
160 		break;
161 
162 #ifdef LDAPMAP
163 	  case ST_LMAP:
164 		len = sizeof s->s_lmap;
165 		break;
166 #endif /* LDAPMAP */
167 
168 #if _FFR_MILTER
169 	  case ST_MILTER:
170 		len = sizeof s->s_milter;
171 		break;
172 #endif /* _FFR_MILTER */
173 
174 	  default:
175 		/*
176 		**  Each mailer has it's own MCI stab entry:
177 		**
178 		**  s = stab(host, ST_MCI + m->m_mno, ST_ENTER);
179 		**
180 		**  Therefore, anything ST_MCI or larger is an s_mci.
181 		*/
182 
183 		if (type >= ST_MCI)
184 			len = sizeof s->s_mci;
185 		else
186 		{
187 			syserr("stab: unknown symbol type %d", type);
188 			len = sizeof s->s_value;
189 		}
190 		break;
191 	}
192 	len += sizeof *s - sizeof s->s_value;
193 
194 	if (tTd(36, 15))
195 		dprintf("size of stab entry: %d\n", len);
196 
197 	/* make new entry */
198 	s = (STAB *) xalloc(len);
199 	memset((char *) s, '\0', len);
200 	s->s_name = newstr(name);
201 	s->s_type = type;
202 	s->s_len = len;
203 
204 	/* link it in */
205 	*ps = s;
206 
207 	/* set a default value for rulesets */
208 	if (type == ST_RULESET)
209 		s->s_ruleset = -1;
210 
211 	return s;
212 }
213 /*
214 **  STABAPPLY -- apply function to all stab entries
215 **
216 **	Parameters:
217 **		func -- the function to apply.  It will be given one
218 **			parameter (the stab entry).
219 **		arg -- an arbitrary argument, passed to func.
220 **
221 **	Returns:
222 **		none.
223 */
224 
225 void
226 stabapply(func, arg)
227 	void (*func)__P((STAB *, int));
228 	int arg;
229 {
230 	register STAB **shead;
231 	register STAB *s;
232 
233 	for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++)
234 	{
235 		for (s = *shead; s != NULL; s = s->s_next)
236 		{
237 			if (tTd(36, 90))
238 				dprintf("stabapply: trying %d/%s\n",
239 					s->s_type, s->s_name);
240 			func(s, arg);
241 		}
242 	}
243 }
244 /*
245 **  QUEUEUP_MACROS -- queueup the macros in a class
246 **
247 **	Write the macros listed in the specified class into the
248 **	file referenced by qfp.
249 **
250 **	Parameters:
251 **		class -- class ID.
252 **		qfp -- file pointer to the qf file.
253 **		e -- the envelope.
254 **
255 **	Returns:
256 **		none.
257 */
258 
259 void
260 queueup_macros(class, qfp, e)
261 	int class;
262 	FILE *qfp;
263 	ENVELOPE *e;
264 {
265 	register STAB **shead;
266 	register STAB *s;
267 
268 	if (e == NULL)
269 		return;
270 
271 	class = bitidx(class);
272 	for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++)
273 	{
274 		for (s = *shead; s != NULL; s = s->s_next)
275 		{
276 			int m;
277 			char *p;
278 
279 			if (s->s_type == ST_CLASS &&
280 			    bitnset(class, s->s_class) &&
281 			    (m = macid(s->s_name, NULL)) != '\0' &&
282 			    (p = macvalue(m, e)) != NULL)
283 			{
284 				/*
285 				**  HACK ALERT: Unfortunately, 8.10 and
286 				**  8.11 reused the ${if_addr} and
287 				**  ${if_family} macros for both the incoming
288 				**  interface address/family (getrequests())
289 				**  and the outgoing interface address/family
290 				**  (makeconnection()).  In order for D_BINDIF
291 				**  to work properly, have to preserve the
292 				**  incoming information in the queue file for
293 				**  later delivery attempts.  The original
294 				**  information is stored in the envelope
295 				**  in readqf() so it can be stored in
296 				**  queueup_macros().  This should be fixed
297 				**  in 8.12.
298 				*/
299 
300 				if (e->e_if_macros[EIF_ADDR] != NULL &&
301 				    strcmp(s->s_name, "{if_addr}") == 0)
302 					p = e->e_if_macros[EIF_ADDR];
303 
304 				fprintf(qfp, "$%s%s\n",
305 					s->s_name,
306 					denlstring(p, TRUE, FALSE));
307 			}
308 		}
309 	}
310 }
311 /*
312 **  COPY_CLASS -- copy class members from one class to another
313 **
314 **	Parameters:
315 **		src -- source class.
316 **		dst -- destination class.
317 **
318 **	Returns:
319 **		none.
320 */
321 
322 void
323 copy_class(src, dst)
324 	int src;
325 	int dst;
326 {
327 	register STAB **shead;
328 	register STAB *s;
329 
330 	src = bitidx(src);
331 	dst = bitidx(dst);
332 	for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++)
333 	{
334 		for (s = *shead; s != NULL; s = s->s_next)
335 		{
336 			if (s->s_type == ST_CLASS &&
337 			    bitnset(src, s->s_class))
338 				setbitn(dst, s->s_class);
339 		}
340 	}
341 }
342