xref: /freebsd/contrib/sendmail/src/stab.c (revision 8774250cea278e6e89c2edc49f341828de307fb4)
1c2aa98e2SPeter Wemm /*
28774250cSGregory Neil Shapiro  * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
306f25ae9SGregory Neil Shapiro  *	All rights reserved.
4c2aa98e2SPeter Wemm  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
5c2aa98e2SPeter Wemm  * Copyright (c) 1988, 1993
6c2aa98e2SPeter Wemm  *	The Regents of the University of California.  All rights reserved.
7c2aa98e2SPeter Wemm  *
8c2aa98e2SPeter Wemm  * By using this file, you agree to the terms and conditions set
9c2aa98e2SPeter Wemm  * forth in the LICENSE file which can be found at the top level of
10c2aa98e2SPeter Wemm  * the sendmail distribution.
11c2aa98e2SPeter Wemm  *
12c2aa98e2SPeter Wemm  */
13c2aa98e2SPeter Wemm 
14c2aa98e2SPeter Wemm #ifndef lint
158774250cSGregory Neil Shapiro static char id[] = "@(#)$Id: stab.c,v 8.40.16.7 2001/05/07 22:06:41 gshapiro Exp $";
1606f25ae9SGregory Neil Shapiro #endif /* ! lint */
17c2aa98e2SPeter Wemm 
1806f25ae9SGregory Neil Shapiro #include <sendmail.h>
19c2aa98e2SPeter Wemm 
20c2aa98e2SPeter Wemm /*
21c2aa98e2SPeter Wemm **  STAB -- manage the symbol table
22c2aa98e2SPeter Wemm **
23c2aa98e2SPeter Wemm **	Parameters:
24c2aa98e2SPeter Wemm **		name -- the name to be looked up or inserted.
25c2aa98e2SPeter Wemm **		type -- the type of symbol.
26c2aa98e2SPeter Wemm **		op -- what to do:
27c2aa98e2SPeter Wemm **			ST_ENTER -- enter the name if not
28c2aa98e2SPeter Wemm **				already present.
29c2aa98e2SPeter Wemm **			ST_FIND -- find it only.
30c2aa98e2SPeter Wemm **
31c2aa98e2SPeter Wemm **	Returns:
32c2aa98e2SPeter Wemm **		pointer to a STAB entry for this name.
33c2aa98e2SPeter Wemm **		NULL if not found and not entered.
34c2aa98e2SPeter Wemm **
35c2aa98e2SPeter Wemm **	Side Effects:
36c2aa98e2SPeter Wemm **		can update the symbol table.
37c2aa98e2SPeter Wemm */
38c2aa98e2SPeter Wemm 
39c2aa98e2SPeter Wemm #define STABSIZE	2003
40c2aa98e2SPeter Wemm 
41c2aa98e2SPeter Wemm static STAB	*SymTab[STABSIZE];
42c2aa98e2SPeter Wemm 
43c2aa98e2SPeter Wemm STAB *
44c2aa98e2SPeter Wemm stab(name, type, op)
45c2aa98e2SPeter Wemm 	char *name;
46c2aa98e2SPeter Wemm 	int type;
47c2aa98e2SPeter Wemm 	int op;
48c2aa98e2SPeter Wemm {
49c2aa98e2SPeter Wemm 	register STAB *s;
50c2aa98e2SPeter Wemm 	register STAB **ps;
51c2aa98e2SPeter Wemm 	register int hfunc;
52c2aa98e2SPeter Wemm 	register char *p;
53c2aa98e2SPeter Wemm 	int len;
54c2aa98e2SPeter Wemm 
55c2aa98e2SPeter Wemm 	if (tTd(36, 5))
5606f25ae9SGregory Neil Shapiro 		dprintf("STAB: %s %d ", name, type);
57c2aa98e2SPeter Wemm 
58c2aa98e2SPeter Wemm 	/*
59c2aa98e2SPeter Wemm 	**  Compute the hashing function
60c2aa98e2SPeter Wemm 	*/
61c2aa98e2SPeter Wemm 
62c2aa98e2SPeter Wemm 	hfunc = type;
63c2aa98e2SPeter Wemm 	for (p = name; *p != '\0'; p++)
64c2aa98e2SPeter Wemm 		hfunc = ((hfunc << 1) ^ (lower(*p) & 0377)) % STABSIZE;
65c2aa98e2SPeter Wemm 
66c2aa98e2SPeter Wemm 	if (tTd(36, 9))
6706f25ae9SGregory Neil Shapiro 		dprintf("(hfunc=%d) ", hfunc);
68c2aa98e2SPeter Wemm 
69c2aa98e2SPeter Wemm 	ps = &SymTab[hfunc];
70c2aa98e2SPeter Wemm 	if (type == ST_MACRO || type == ST_RULESET)
71c2aa98e2SPeter Wemm 	{
72c2aa98e2SPeter Wemm 		while ((s = *ps) != NULL &&
73c2aa98e2SPeter Wemm 		       (s->s_type != type || strcmp(name, s->s_name)))
74c2aa98e2SPeter Wemm 			ps = &s->s_next;
75c2aa98e2SPeter Wemm 	}
76c2aa98e2SPeter Wemm 	else
77c2aa98e2SPeter Wemm 	{
78c2aa98e2SPeter Wemm 		while ((s = *ps) != NULL &&
79c2aa98e2SPeter Wemm 		       (s->s_type != type || strcasecmp(name, s->s_name)))
80c2aa98e2SPeter Wemm 			ps = &s->s_next;
81c2aa98e2SPeter Wemm 	}
82c2aa98e2SPeter Wemm 
83c2aa98e2SPeter Wemm 	/*
84c2aa98e2SPeter Wemm 	**  Dispose of the entry.
85c2aa98e2SPeter Wemm 	*/
86c2aa98e2SPeter Wemm 
87c2aa98e2SPeter Wemm 	if (s != NULL || op == ST_FIND)
88c2aa98e2SPeter Wemm 	{
89c2aa98e2SPeter Wemm 		if (tTd(36, 5))
90c2aa98e2SPeter Wemm 		{
91c2aa98e2SPeter Wemm 			if (s == NULL)
9206f25ae9SGregory Neil Shapiro 				dprintf("not found\n");
93c2aa98e2SPeter Wemm 			else
94c2aa98e2SPeter Wemm 			{
95c2aa98e2SPeter Wemm 				long *lp = (long *) s->s_class;
96c2aa98e2SPeter Wemm 
9706f25ae9SGregory Neil Shapiro 				dprintf("type %d val %lx %lx %lx %lx\n",
98c2aa98e2SPeter Wemm 					s->s_type, lp[0], lp[1], lp[2], lp[3]);
99c2aa98e2SPeter Wemm 			}
100c2aa98e2SPeter Wemm 		}
10106f25ae9SGregory Neil Shapiro 		return s;
102c2aa98e2SPeter Wemm 	}
103c2aa98e2SPeter Wemm 
104c2aa98e2SPeter Wemm 	/*
105c2aa98e2SPeter Wemm 	**  Make a new entry and link it in.
106c2aa98e2SPeter Wemm 	*/
107c2aa98e2SPeter Wemm 
108c2aa98e2SPeter Wemm 	if (tTd(36, 5))
10906f25ae9SGregory Neil Shapiro 		dprintf("entered\n");
110c2aa98e2SPeter Wemm 
111c2aa98e2SPeter Wemm 	/* determine size of new entry */
112c2aa98e2SPeter Wemm 	switch (type)
113c2aa98e2SPeter Wemm 	{
114c2aa98e2SPeter Wemm 	  case ST_CLASS:
115c2aa98e2SPeter Wemm 		len = sizeof s->s_class;
116c2aa98e2SPeter Wemm 		break;
117c2aa98e2SPeter Wemm 
118c2aa98e2SPeter Wemm 	  case ST_ADDRESS:
119c2aa98e2SPeter Wemm 		len = sizeof s->s_address;
120c2aa98e2SPeter Wemm 		break;
121c2aa98e2SPeter Wemm 
122c2aa98e2SPeter Wemm 	  case ST_MAILER:
123c2aa98e2SPeter Wemm 		len = sizeof s->s_mailer;
12406f25ae9SGregory Neil Shapiro 		break;
125c2aa98e2SPeter Wemm 
126c2aa98e2SPeter Wemm 	  case ST_ALIAS:
127c2aa98e2SPeter Wemm 		len = sizeof s->s_alias;
128c2aa98e2SPeter Wemm 		break;
129c2aa98e2SPeter Wemm 
130c2aa98e2SPeter Wemm 	  case ST_MAPCLASS:
131c2aa98e2SPeter Wemm 		len = sizeof s->s_mapclass;
132c2aa98e2SPeter Wemm 		break;
133c2aa98e2SPeter Wemm 
134c2aa98e2SPeter Wemm 	  case ST_MAP:
135c2aa98e2SPeter Wemm 		len = sizeof s->s_map;
136c2aa98e2SPeter Wemm 		break;
137c2aa98e2SPeter Wemm 
138c2aa98e2SPeter Wemm 	  case ST_HOSTSIG:
139c2aa98e2SPeter Wemm 		len = sizeof s->s_hostsig;
140c2aa98e2SPeter Wemm 		break;
141c2aa98e2SPeter Wemm 
142c2aa98e2SPeter Wemm 	  case ST_NAMECANON:
143c2aa98e2SPeter Wemm 		len = sizeof s->s_namecanon;
144c2aa98e2SPeter Wemm 		break;
145c2aa98e2SPeter Wemm 
146c2aa98e2SPeter Wemm 	  case ST_MACRO:
147c2aa98e2SPeter Wemm 		len = sizeof s->s_macro;
148c2aa98e2SPeter Wemm 		break;
149c2aa98e2SPeter Wemm 
150c2aa98e2SPeter Wemm 	  case ST_RULESET:
151c2aa98e2SPeter Wemm 		len = sizeof s->s_ruleset;
152c2aa98e2SPeter Wemm 		break;
153c2aa98e2SPeter Wemm 
154c2aa98e2SPeter Wemm 	  case ST_HEADER:
155c2aa98e2SPeter Wemm 		len = sizeof s->s_header;
156c2aa98e2SPeter Wemm 		break;
157c2aa98e2SPeter Wemm 
15806f25ae9SGregory Neil Shapiro 	  case ST_SERVICE:
15906f25ae9SGregory Neil Shapiro 		len = sizeof s->s_service;
16006f25ae9SGregory Neil Shapiro 		break;
16106f25ae9SGregory Neil Shapiro 
16206f25ae9SGregory Neil Shapiro #ifdef LDAPMAP
1638774250cSGregory Neil Shapiro 	  case ST_LMAP:
1648774250cSGregory Neil Shapiro 		len = sizeof s->s_lmap;
16506f25ae9SGregory Neil Shapiro 		break;
16606f25ae9SGregory Neil Shapiro #endif /* LDAPMAP */
16706f25ae9SGregory Neil Shapiro 
16806f25ae9SGregory Neil Shapiro #if _FFR_MILTER
16906f25ae9SGregory Neil Shapiro 	  case ST_MILTER:
17006f25ae9SGregory Neil Shapiro 		len = sizeof s->s_milter;
17106f25ae9SGregory Neil Shapiro 		break;
17206f25ae9SGregory Neil Shapiro #endif /* _FFR_MILTER */
17306f25ae9SGregory Neil Shapiro 
174c2aa98e2SPeter Wemm 	  default:
17506f25ae9SGregory Neil Shapiro 		/*
17606f25ae9SGregory Neil Shapiro 		**  Each mailer has it's own MCI stab entry:
17706f25ae9SGregory Neil Shapiro 		**
17806f25ae9SGregory Neil Shapiro 		**  s = stab(host, ST_MCI + m->m_mno, ST_ENTER);
17906f25ae9SGregory Neil Shapiro 		**
18006f25ae9SGregory Neil Shapiro 		**  Therefore, anything ST_MCI or larger is an s_mci.
18106f25ae9SGregory Neil Shapiro 		*/
18206f25ae9SGregory Neil Shapiro 
183c2aa98e2SPeter Wemm 		if (type >= ST_MCI)
184c2aa98e2SPeter Wemm 			len = sizeof s->s_mci;
185c2aa98e2SPeter Wemm 		else
186c2aa98e2SPeter Wemm 		{
187c2aa98e2SPeter Wemm 			syserr("stab: unknown symbol type %d", type);
188c2aa98e2SPeter Wemm 			len = sizeof s->s_value;
189c2aa98e2SPeter Wemm 		}
190c2aa98e2SPeter Wemm 		break;
191c2aa98e2SPeter Wemm 	}
192c2aa98e2SPeter Wemm 	len += sizeof *s - sizeof s->s_value;
19306f25ae9SGregory Neil Shapiro 
19406f25ae9SGregory Neil Shapiro 	if (tTd(36, 15))
19506f25ae9SGregory Neil Shapiro 		dprintf("size of stab entry: %d\n", len);
196c2aa98e2SPeter Wemm 
197c2aa98e2SPeter Wemm 	/* make new entry */
198c2aa98e2SPeter Wemm 	s = (STAB *) xalloc(len);
19906f25ae9SGregory Neil Shapiro 	memset((char *) s, '\0', len);
200c2aa98e2SPeter Wemm 	s->s_name = newstr(name);
201c2aa98e2SPeter Wemm 	s->s_type = type;
202c2aa98e2SPeter Wemm 	s->s_len = len;
203c2aa98e2SPeter Wemm 
204c2aa98e2SPeter Wemm 	/* link it in */
205c2aa98e2SPeter Wemm 	*ps = s;
206c2aa98e2SPeter Wemm 
20706f25ae9SGregory Neil Shapiro 	/* set a default value for rulesets */
20806f25ae9SGregory Neil Shapiro 	if (type == ST_RULESET)
20906f25ae9SGregory Neil Shapiro 		s->s_ruleset = -1;
21006f25ae9SGregory Neil Shapiro 
21106f25ae9SGregory Neil Shapiro 	return s;
212c2aa98e2SPeter Wemm }
213c2aa98e2SPeter Wemm /*
214c2aa98e2SPeter Wemm **  STABAPPLY -- apply function to all stab entries
215c2aa98e2SPeter Wemm **
216c2aa98e2SPeter Wemm **	Parameters:
217c2aa98e2SPeter Wemm **		func -- the function to apply.  It will be given one
218c2aa98e2SPeter Wemm **			parameter (the stab entry).
219c2aa98e2SPeter Wemm **		arg -- an arbitrary argument, passed to func.
220c2aa98e2SPeter Wemm **
221c2aa98e2SPeter Wemm **	Returns:
222c2aa98e2SPeter Wemm **		none.
223c2aa98e2SPeter Wemm */
224c2aa98e2SPeter Wemm 
225c2aa98e2SPeter Wemm void
226c2aa98e2SPeter Wemm stabapply(func, arg)
227c2aa98e2SPeter Wemm 	void (*func)__P((STAB *, int));
228c2aa98e2SPeter Wemm 	int arg;
229c2aa98e2SPeter Wemm {
230c2aa98e2SPeter Wemm 	register STAB **shead;
231c2aa98e2SPeter Wemm 	register STAB *s;
232c2aa98e2SPeter Wemm 
233c2aa98e2SPeter Wemm 	for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++)
234c2aa98e2SPeter Wemm 	{
235c2aa98e2SPeter Wemm 		for (s = *shead; s != NULL; s = s->s_next)
236c2aa98e2SPeter Wemm 		{
237c2aa98e2SPeter Wemm 			if (tTd(36, 90))
23806f25ae9SGregory Neil Shapiro 				dprintf("stabapply: trying %d/%s\n",
239c2aa98e2SPeter Wemm 					s->s_type, s->s_name);
240c2aa98e2SPeter Wemm 			func(s, arg);
241c2aa98e2SPeter Wemm 		}
242c2aa98e2SPeter Wemm 	}
243c2aa98e2SPeter Wemm }
24406f25ae9SGregory Neil Shapiro /*
24506f25ae9SGregory Neil Shapiro **  QUEUEUP_MACROS -- queueup the macros in a class
24606f25ae9SGregory Neil Shapiro **
24706f25ae9SGregory Neil Shapiro **	Write the macros listed in the specified class into the
24806f25ae9SGregory Neil Shapiro **	file referenced by qfp.
24906f25ae9SGregory Neil Shapiro **
25006f25ae9SGregory Neil Shapiro **	Parameters:
25106f25ae9SGregory Neil Shapiro **		class -- class ID.
25206f25ae9SGregory Neil Shapiro **		qfp -- file pointer to the qf file.
25306f25ae9SGregory Neil Shapiro **		e -- the envelope.
25406f25ae9SGregory Neil Shapiro **
25506f25ae9SGregory Neil Shapiro **	Returns:
25606f25ae9SGregory Neil Shapiro **		none.
25706f25ae9SGregory Neil Shapiro */
25806f25ae9SGregory Neil Shapiro 
25906f25ae9SGregory Neil Shapiro void
26006f25ae9SGregory Neil Shapiro queueup_macros(class, qfp, e)
26106f25ae9SGregory Neil Shapiro 	int class;
26206f25ae9SGregory Neil Shapiro 	FILE *qfp;
26306f25ae9SGregory Neil Shapiro 	ENVELOPE *e;
26406f25ae9SGregory Neil Shapiro {
26506f25ae9SGregory Neil Shapiro 	register STAB **shead;
26606f25ae9SGregory Neil Shapiro 	register STAB *s;
26706f25ae9SGregory Neil Shapiro 
26806f25ae9SGregory Neil Shapiro 	if (e == NULL)
26906f25ae9SGregory Neil Shapiro 		return;
27006f25ae9SGregory Neil Shapiro 
271193538b7SGregory Neil Shapiro 	class = bitidx(class);
27206f25ae9SGregory Neil Shapiro 	for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++)
27306f25ae9SGregory Neil Shapiro 	{
27406f25ae9SGregory Neil Shapiro 		for (s = *shead; s != NULL; s = s->s_next)
27506f25ae9SGregory Neil Shapiro 		{
27606f25ae9SGregory Neil Shapiro 			int m;
27706f25ae9SGregory Neil Shapiro 			char *p;
27806f25ae9SGregory Neil Shapiro 
27906f25ae9SGregory Neil Shapiro 			if (s->s_type == ST_CLASS &&
280193538b7SGregory Neil Shapiro 			    bitnset(class, s->s_class) &&
28106f25ae9SGregory Neil Shapiro 			    (m = macid(s->s_name, NULL)) != '\0' &&
28206f25ae9SGregory Neil Shapiro 			    (p = macvalue(m, e)) != NULL)
28306f25ae9SGregory Neil Shapiro 			{
28406f25ae9SGregory Neil Shapiro 				/*
28506f25ae9SGregory Neil Shapiro 				**  HACK ALERT: Unfortunately, 8.10 and
28606f25ae9SGregory Neil Shapiro 				**  8.11 reused the ${if_addr} and
28706f25ae9SGregory Neil Shapiro 				**  ${if_family} macros for both the incoming
28806f25ae9SGregory Neil Shapiro 				**  interface address/family (getrequests())
28906f25ae9SGregory Neil Shapiro 				**  and the outgoing interface address/family
29006f25ae9SGregory Neil Shapiro 				**  (makeconnection()).  In order for D_BINDIF
29106f25ae9SGregory Neil Shapiro 				**  to work properly, have to preserve the
29206f25ae9SGregory Neil Shapiro 				**  incoming information in the queue file for
29306f25ae9SGregory Neil Shapiro 				**  later delivery attempts.  The original
29406f25ae9SGregory Neil Shapiro 				**  information is stored in the envelope
29506f25ae9SGregory Neil Shapiro 				**  in readqf() so it can be stored in
29606f25ae9SGregory Neil Shapiro 				**  queueup_macros().  This should be fixed
29706f25ae9SGregory Neil Shapiro 				**  in 8.12.
29806f25ae9SGregory Neil Shapiro 				*/
29906f25ae9SGregory Neil Shapiro 
30006f25ae9SGregory Neil Shapiro 				if (e->e_if_macros[EIF_ADDR] != NULL &&
30106f25ae9SGregory Neil Shapiro 				    strcmp(s->s_name, "{if_addr}") == 0)
30206f25ae9SGregory Neil Shapiro 					p = e->e_if_macros[EIF_ADDR];
30306f25ae9SGregory Neil Shapiro 
30406f25ae9SGregory Neil Shapiro 				fprintf(qfp, "$%s%s\n",
30506f25ae9SGregory Neil Shapiro 					s->s_name,
30606f25ae9SGregory Neil Shapiro 					denlstring(p, TRUE, FALSE));
30706f25ae9SGregory Neil Shapiro 			}
30806f25ae9SGregory Neil Shapiro 		}
30906f25ae9SGregory Neil Shapiro 	}
31006f25ae9SGregory Neil Shapiro }
31106f25ae9SGregory Neil Shapiro /*
31206f25ae9SGregory Neil Shapiro **  COPY_CLASS -- copy class members from one class to another
31306f25ae9SGregory Neil Shapiro **
31406f25ae9SGregory Neil Shapiro **	Parameters:
31506f25ae9SGregory Neil Shapiro **		src -- source class.
31606f25ae9SGregory Neil Shapiro **		dst -- destination class.
31706f25ae9SGregory Neil Shapiro **
31806f25ae9SGregory Neil Shapiro **	Returns:
31906f25ae9SGregory Neil Shapiro **		none.
32006f25ae9SGregory Neil Shapiro */
32106f25ae9SGregory Neil Shapiro 
32206f25ae9SGregory Neil Shapiro void
32306f25ae9SGregory Neil Shapiro copy_class(src, dst)
32406f25ae9SGregory Neil Shapiro 	int src;
32506f25ae9SGregory Neil Shapiro 	int dst;
32606f25ae9SGregory Neil Shapiro {
32706f25ae9SGregory Neil Shapiro 	register STAB **shead;
32806f25ae9SGregory Neil Shapiro 	register STAB *s;
32906f25ae9SGregory Neil Shapiro 
330193538b7SGregory Neil Shapiro 	src = bitidx(src);
331193538b7SGregory Neil Shapiro 	dst = bitidx(dst);
33206f25ae9SGregory Neil Shapiro 	for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++)
33306f25ae9SGregory Neil Shapiro 	{
33406f25ae9SGregory Neil Shapiro 		for (s = *shead; s != NULL; s = s->s_next)
33506f25ae9SGregory Neil Shapiro 		{
33606f25ae9SGregory Neil Shapiro 			if (s->s_type == ST_CLASS &&
337193538b7SGregory Neil Shapiro 			    bitnset(src, s->s_class))
33806f25ae9SGregory Neil Shapiro 				setbitn(dst, s->s_class);
33906f25ae9SGregory Neil Shapiro 		}
34006f25ae9SGregory Neil Shapiro 	}
34106f25ae9SGregory Neil Shapiro }
342