stab.c revision 71345
138032Speter/*
271345Sgshapiro * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
364562Sgshapiro *	All rights reserved.
438032Speter * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
538032Speter * Copyright (c) 1988, 1993
638032Speter *	The Regents of the University of California.  All rights reserved.
738032Speter *
838032Speter * By using this file, you agree to the terms and conditions set
938032Speter * forth in the LICENSE file which can be found at the top level of
1038032Speter * the sendmail distribution.
1138032Speter *
1238032Speter */
1338032Speter
1438032Speter#ifndef lint
1571345Sgshapirostatic char id[] = "@(#)$Id: stab.c,v 8.40.16.3 2000/10/09 02:46:12 gshapiro Exp $";
1664562Sgshapiro#endif /* ! lint */
1738032Speter
1864562Sgshapiro#include <sendmail.h>
1938032Speter
2038032Speter/*
2138032Speter**  STAB -- manage the symbol table
2238032Speter**
2338032Speter**	Parameters:
2438032Speter**		name -- the name to be looked up or inserted.
2538032Speter**		type -- the type of symbol.
2638032Speter**		op -- what to do:
2738032Speter**			ST_ENTER -- enter the name if not
2838032Speter**				already present.
2938032Speter**			ST_FIND -- find it only.
3038032Speter**
3138032Speter**	Returns:
3238032Speter**		pointer to a STAB entry for this name.
3338032Speter**		NULL if not found and not entered.
3438032Speter**
3538032Speter**	Side Effects:
3638032Speter**		can update the symbol table.
3738032Speter*/
3838032Speter
3964562Sgshapiro#define STABSIZE	2003
4038032Speter
4138032Speterstatic STAB	*SymTab[STABSIZE];
4238032Speter
4338032SpeterSTAB *
4438032Speterstab(name, type, op)
4538032Speter	char *name;
4638032Speter	int type;
4738032Speter	int op;
4838032Speter{
4938032Speter	register STAB *s;
5038032Speter	register STAB **ps;
5138032Speter	register int hfunc;
5238032Speter	register char *p;
5338032Speter	int len;
5438032Speter
5538032Speter	if (tTd(36, 5))
5664562Sgshapiro		dprintf("STAB: %s %d ", name, type);
5738032Speter
5838032Speter	/*
5938032Speter	**  Compute the hashing function
6038032Speter	*/
6138032Speter
6238032Speter	hfunc = type;
6338032Speter	for (p = name; *p != '\0'; p++)
6438032Speter		hfunc = ((hfunc << 1) ^ (lower(*p) & 0377)) % STABSIZE;
6538032Speter
6638032Speter	if (tTd(36, 9))
6764562Sgshapiro		dprintf("(hfunc=%d) ", hfunc);
6838032Speter
6938032Speter	ps = &SymTab[hfunc];
7038032Speter	if (type == ST_MACRO || type == ST_RULESET)
7138032Speter	{
7238032Speter		while ((s = *ps) != NULL &&
7338032Speter		       (s->s_type != type || strcmp(name, s->s_name)))
7438032Speter			ps = &s->s_next;
7538032Speter	}
7638032Speter	else
7738032Speter	{
7838032Speter		while ((s = *ps) != NULL &&
7938032Speter		       (s->s_type != type || strcasecmp(name, s->s_name)))
8038032Speter			ps = &s->s_next;
8138032Speter	}
8238032Speter
8338032Speter	/*
8438032Speter	**  Dispose of the entry.
8538032Speter	*/
8638032Speter
8738032Speter	if (s != NULL || op == ST_FIND)
8838032Speter	{
8938032Speter		if (tTd(36, 5))
9038032Speter		{
9138032Speter			if (s == NULL)
9264562Sgshapiro				dprintf("not found\n");
9338032Speter			else
9438032Speter			{
9538032Speter				long *lp = (long *) s->s_class;
9638032Speter
9764562Sgshapiro				dprintf("type %d val %lx %lx %lx %lx\n",
9838032Speter					s->s_type, lp[0], lp[1], lp[2], lp[3]);
9938032Speter			}
10038032Speter		}
10164562Sgshapiro		return s;
10238032Speter	}
10338032Speter
10438032Speter	/*
10538032Speter	**  Make a new entry and link it in.
10638032Speter	*/
10738032Speter
10838032Speter	if (tTd(36, 5))
10964562Sgshapiro		dprintf("entered\n");
11038032Speter
11138032Speter	/* determine size of new entry */
11238032Speter	switch (type)
11338032Speter	{
11438032Speter	  case ST_CLASS:
11538032Speter		len = sizeof s->s_class;
11638032Speter		break;
11738032Speter
11838032Speter	  case ST_ADDRESS:
11938032Speter		len = sizeof s->s_address;
12038032Speter		break;
12138032Speter
12238032Speter	  case ST_MAILER:
12338032Speter		len = sizeof s->s_mailer;
12464562Sgshapiro		break;
12538032Speter
12638032Speter	  case ST_ALIAS:
12738032Speter		len = sizeof s->s_alias;
12838032Speter		break;
12938032Speter
13038032Speter	  case ST_MAPCLASS:
13138032Speter		len = sizeof s->s_mapclass;
13238032Speter		break;
13338032Speter
13438032Speter	  case ST_MAP:
13538032Speter		len = sizeof s->s_map;
13638032Speter		break;
13738032Speter
13838032Speter	  case ST_HOSTSIG:
13938032Speter		len = sizeof s->s_hostsig;
14038032Speter		break;
14138032Speter
14238032Speter	  case ST_NAMECANON:
14338032Speter		len = sizeof s->s_namecanon;
14438032Speter		break;
14538032Speter
14638032Speter	  case ST_MACRO:
14738032Speter		len = sizeof s->s_macro;
14838032Speter		break;
14938032Speter
15038032Speter	  case ST_RULESET:
15138032Speter		len = sizeof s->s_ruleset;
15238032Speter		break;
15338032Speter
15464562Sgshapiro	  case ST_HEADER:
15564562Sgshapiro		len = sizeof s->s_header;
15664562Sgshapiro		break;
15764562Sgshapiro
15838032Speter	  case ST_SERVICE:
15938032Speter		len = sizeof s->s_service;
16038032Speter		break;
16138032Speter
16264562Sgshapiro#ifdef LDAPMAP
16364562Sgshapiro	  case ST_LDAP:
16464562Sgshapiro		len = sizeof s->s_ldap;
16538032Speter		break;
16664562Sgshapiro#endif /* LDAPMAP */
16738032Speter
16864562Sgshapiro#if _FFR_MILTER
16964562Sgshapiro	  case ST_MILTER:
17064562Sgshapiro		len = sizeof s->s_milter;
17164562Sgshapiro		break;
17264562Sgshapiro#endif /* _FFR_MILTER */
17364562Sgshapiro
17438032Speter	  default:
17564562Sgshapiro		/*
17664562Sgshapiro		**  Each mailer has it's own MCI stab entry:
17764562Sgshapiro		**
17864562Sgshapiro		**  s = stab(host, ST_MCI + m->m_mno, ST_ENTER);
17964562Sgshapiro		**
18064562Sgshapiro		**  Therefore, anything ST_MCI or larger is an s_mci.
18164562Sgshapiro		*/
18264562Sgshapiro
18338032Speter		if (type >= ST_MCI)
18438032Speter			len = sizeof s->s_mci;
18538032Speter		else
18638032Speter		{
18738032Speter			syserr("stab: unknown symbol type %d", type);
18838032Speter			len = sizeof s->s_value;
18938032Speter		}
19038032Speter		break;
19138032Speter	}
19238032Speter	len += sizeof *s - sizeof s->s_value;
19338032Speter
19464562Sgshapiro	if (tTd(36, 15))
19564562Sgshapiro		dprintf("size of stab entry: %d\n", len);
19664562Sgshapiro
19738032Speter	/* make new entry */
19838032Speter	s = (STAB *) xalloc(len);
19964562Sgshapiro	memset((char *) s, '\0', len);
20038032Speter	s->s_name = newstr(name);
20138032Speter	s->s_type = type;
20238032Speter	s->s_len = len;
20338032Speter
20438032Speter	/* link it in */
20538032Speter	*ps = s;
20638032Speter
20764562Sgshapiro	/* set a default value for rulesets */
20864562Sgshapiro	if (type == ST_RULESET)
20964562Sgshapiro		s->s_ruleset = -1;
21064562Sgshapiro
21164562Sgshapiro	return s;
21238032Speter}
21338032Speter/*
21438032Speter**  STABAPPLY -- apply function to all stab entries
21538032Speter**
21638032Speter**	Parameters:
21738032Speter**		func -- the function to apply.  It will be given one
21838032Speter**			parameter (the stab entry).
21938032Speter**		arg -- an arbitrary argument, passed to func.
22038032Speter**
22138032Speter**	Returns:
22238032Speter**		none.
22338032Speter*/
22438032Speter
22538032Spetervoid
22638032Speterstabapply(func, arg)
22738032Speter	void (*func)__P((STAB *, int));
22838032Speter	int arg;
22938032Speter{
23038032Speter	register STAB **shead;
23138032Speter	register STAB *s;
23238032Speter
23338032Speter	for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++)
23438032Speter	{
23538032Speter		for (s = *shead; s != NULL; s = s->s_next)
23638032Speter		{
23738032Speter			if (tTd(36, 90))
23864562Sgshapiro				dprintf("stabapply: trying %d/%s\n",
23938032Speter					s->s_type, s->s_name);
24038032Speter			func(s, arg);
24138032Speter		}
24238032Speter	}
24338032Speter}
24464562Sgshapiro/*
24564562Sgshapiro**  QUEUEUP_MACROS -- queueup the macros in a class
24664562Sgshapiro**
24764562Sgshapiro**	Write the macros listed in the specified class into the
24864562Sgshapiro**	file referenced by qfp.
24964562Sgshapiro**
25064562Sgshapiro**	Parameters:
25164562Sgshapiro**		class -- class ID.
25264562Sgshapiro**		qfp -- file pointer to the qf file.
25364562Sgshapiro**		e -- the envelope.
25464562Sgshapiro**
25564562Sgshapiro**	Returns:
25664562Sgshapiro**		none.
25764562Sgshapiro*/
25864562Sgshapiro
25964562Sgshapirovoid
26064562Sgshapiroqueueup_macros(class, qfp, e)
26164562Sgshapiro	int class;
26264562Sgshapiro	FILE *qfp;
26364562Sgshapiro	ENVELOPE *e;
26464562Sgshapiro{
26564562Sgshapiro	register STAB **shead;
26664562Sgshapiro	register STAB *s;
26764562Sgshapiro
26864562Sgshapiro	if (e == NULL)
26964562Sgshapiro		return;
27064562Sgshapiro
27171345Sgshapiro	class = bitidx(class);
27264562Sgshapiro	for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++)
27364562Sgshapiro	{
27464562Sgshapiro		for (s = *shead; s != NULL; s = s->s_next)
27564562Sgshapiro		{
27664562Sgshapiro			int m;
27764562Sgshapiro			char *p;
27864562Sgshapiro
27964562Sgshapiro			if (s->s_type == ST_CLASS &&
28071345Sgshapiro			    bitnset(class, s->s_class) &&
28164562Sgshapiro			    (m = macid(s->s_name, NULL)) != '\0' &&
28264562Sgshapiro			    (p = macvalue(m, e)) != NULL)
28364562Sgshapiro			{
28464562Sgshapiro				/*
28564562Sgshapiro				**  HACK ALERT: Unfortunately, 8.10 and
28664562Sgshapiro				**  8.11 reused the ${if_addr} and
28764562Sgshapiro				**  ${if_family} macros for both the incoming
28864562Sgshapiro				**  interface address/family (getrequests())
28964562Sgshapiro				**  and the outgoing interface address/family
29064562Sgshapiro				**  (makeconnection()).  In order for D_BINDIF
29164562Sgshapiro				**  to work properly, have to preserve the
29264562Sgshapiro				**  incoming information in the queue file for
29364562Sgshapiro				**  later delivery attempts.  The original
29464562Sgshapiro				**  information is stored in the envelope
29564562Sgshapiro				**  in readqf() so it can be stored in
29664562Sgshapiro				**  queueup_macros().  This should be fixed
29764562Sgshapiro				**  in 8.12.
29864562Sgshapiro				*/
29964562Sgshapiro
30064562Sgshapiro				if (e->e_if_macros[EIF_ADDR] != NULL &&
30164562Sgshapiro				    strcmp(s->s_name, "{if_addr}") == 0)
30264562Sgshapiro					p = e->e_if_macros[EIF_ADDR];
30364562Sgshapiro
30464562Sgshapiro				fprintf(qfp, "$%s%s\n",
30564562Sgshapiro					s->s_name,
30664562Sgshapiro					denlstring(p, TRUE, FALSE));
30764562Sgshapiro			}
30864562Sgshapiro		}
30964562Sgshapiro	}
31064562Sgshapiro}
31164562Sgshapiro/*
31264562Sgshapiro**  COPY_CLASS -- copy class members from one class to another
31364562Sgshapiro**
31464562Sgshapiro**	Parameters:
31564562Sgshapiro**		src -- source class.
31664562Sgshapiro**		dst -- destination class.
31764562Sgshapiro**
31864562Sgshapiro**	Returns:
31964562Sgshapiro**		none.
32064562Sgshapiro*/
32164562Sgshapiro
32264562Sgshapirovoid
32364562Sgshapirocopy_class(src, dst)
32464562Sgshapiro	int src;
32564562Sgshapiro	int dst;
32664562Sgshapiro{
32764562Sgshapiro	register STAB **shead;
32864562Sgshapiro	register STAB *s;
32964562Sgshapiro
33071345Sgshapiro	src = bitidx(src);
33171345Sgshapiro	dst = bitidx(dst);
33264562Sgshapiro	for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++)
33364562Sgshapiro	{
33464562Sgshapiro		for (s = *shead; s != NULL; s = s->s_next)
33564562Sgshapiro		{
33664562Sgshapiro			if (s->s_type == ST_CLASS &&
33771345Sgshapiro			    bitnset(src, s->s_class))
33864562Sgshapiro				setbitn(dst, s->s_class);
33964562Sgshapiro		}
34064562Sgshapiro	}
34164562Sgshapiro}
342