Deleted Added
full compact
stab.c (302408) stab.c (38032)
1/*
1/*
2 * Copyright (c) 1998-2001, 2003 Proofpoint, Inc. and its suppliers.
3 * All rights reserved.
2 * Copyright (c) 1998 Sendmail, Inc. 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
3 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
4 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * By using this file, you agree to the terms and conditions set
8 * forth in the LICENSE file which can be found at the top level of
9 * the sendmail distribution.
10 *
11 */
12
14#include <sendmail.h>
13#ifndef lint
14static char sccsid[] = "@(#)stab.c 8.19 (Berkeley) 5/19/98";
15#endif /* not lint */
15
16
16SM_RCSID("@(#)$Id: stab.c,v 8.92 2013-11-22 20:51:56 ca Exp $")
17# include "sendmail.h"
17
18/*
19** STAB -- manage the symbol table
20**
21** Parameters:
22** name -- the name to be looked up or inserted.
23** type -- the type of symbol.
24** op -- what to do:
18
19/*
20** STAB -- manage the symbol table
21**
22** Parameters:
23** name -- the name to be looked up or inserted.
24** type -- the type of symbol.
25** op -- what to do:
25** ST_ENTER -- enter the name if not already present.
26** ST_ENTER -- enter the name if not
27** already present.
26** ST_FIND -- find it only.
27**
28** Returns:
29** pointer to a STAB entry for this name.
30** NULL if not found and not entered.
31**
32** Side Effects:
33** can update the symbol table.
34*/
35
28** ST_FIND -- find it only.
29**
30** Returns:
31** pointer to a STAB entry for this name.
32** NULL if not found and not entered.
33**
34** Side Effects:
35** can update the symbol table.
36*/
37
36#define STABSIZE 2003
37#define SM_LOWER(c) ((isascii(c) && isupper(c)) ? tolower(c) : (c))
38# define STABSIZE 2003
38
39static STAB *SymTab[STABSIZE];
40
41STAB *
42stab(name, type, op)
43 char *name;
44 int type;
45 int op;
46{
47 register STAB *s;
48 register STAB **ps;
49 register int hfunc;
50 register char *p;
51 int len;
39
40static STAB *SymTab[STABSIZE];
41
42STAB *
43stab(name, type, op)
44 char *name;
45 int type;
46 int op;
47{
48 register STAB *s;
49 register STAB **ps;
50 register int hfunc;
51 register char *p;
52 int len;
53 extern char lower __P((char));
52
53 if (tTd(36, 5))
54
55 if (tTd(36, 5))
54 sm_dprintf("STAB: %s %d ", name, type);
56 printf("STAB: %s %d ", name, type);
55
56 /*
57 ** Compute the hashing function
58 */
59
60 hfunc = type;
61 for (p = name; *p != '\0'; p++)
57
58 /*
59 ** Compute the hashing function
60 */
61
62 hfunc = type;
63 for (p = name; *p != '\0'; p++)
62 hfunc = ((hfunc << 1) ^ (SM_LOWER(*p) & 0377)) % STABSIZE;
64 hfunc = ((hfunc << 1) ^ (lower(*p) & 0377)) % STABSIZE;
63
64 if (tTd(36, 9))
65
66 if (tTd(36, 9))
65 sm_dprintf("(hfunc=%d) ", hfunc);
67 printf("(hfunc=%d) ", hfunc);
66
67 ps = &SymTab[hfunc];
68
69 ps = &SymTab[hfunc];
68 if (type == ST_MACRO || type == ST_RULESET || type == ST_NAMECANON)
70 if (type == ST_MACRO || type == ST_RULESET)
69 {
70 while ((s = *ps) != NULL &&
71 {
72 while ((s = *ps) != NULL &&
71 (s->s_symtype != type || strcmp(name, s->s_name)))
73 (s->s_type != type || strcmp(name, s->s_name)))
72 ps = &s->s_next;
73 }
74 else
75 {
76 while ((s = *ps) != NULL &&
74 ps = &s->s_next;
75 }
76 else
77 {
78 while ((s = *ps) != NULL &&
77 (s->s_symtype != type || sm_strcasecmp(name, s->s_name)))
79 (s->s_type != type || strcasecmp(name, s->s_name)))
78 ps = &s->s_next;
79 }
80
81 /*
82 ** Dispose of the entry.
83 */
84
85 if (s != NULL || op == ST_FIND)
86 {
87 if (tTd(36, 5))
88 {
89 if (s == NULL)
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)
90 sm_dprintf("not found\n");
92 printf("not found\n");
91 else
92 {
93 long *lp = (long *) s->s_class;
94
93 else
94 {
95 long *lp = (long *) s->s_class;
96
95 sm_dprintf("type %d val %lx %lx %lx %lx\n",
96 s->s_symtype, lp[0], lp[1], lp[2], lp[3]);
97 printf("type %d val %lx %lx %lx %lx\n",
98 s->s_type, lp[0], lp[1], lp[2], lp[3]);
97 }
98 }
99 }
100 }
99 return s;
101 return (s);
100 }
101
102 /*
103 ** Make a new entry and link it in.
104 */
105
106 if (tTd(36, 5))
102 }
103
104 /*
105 ** Make a new entry and link it in.
106 */
107
108 if (tTd(36, 5))
107 sm_dprintf("entered\n");
109 printf("entered\n");
108
109 /* determine size of new entry */
110
111 /* determine size of new entry */
112#if _FFR_MEMORY_MISER
110 switch (type)
111 {
112 case ST_CLASS:
113 switch (type)
114 {
115 case ST_CLASS:
113 len = sizeof(s->s_class);
116 len = sizeof s->s_class;
114 break;
115
117 break;
118
116 case ST_MAILER:
117 len = sizeof(s->s_mailer);
119 case ST_ADDRESS:
120 len = sizeof s->s_address;
118 break;
119
121 break;
122
123 case ST_MAILER:
124 len = sizeof s->s_mailer;
125
120 case ST_ALIAS:
126 case ST_ALIAS:
121 len = sizeof(s->s_alias);
127 len = sizeof s->s_alias;
122 break;
123
124 case ST_MAPCLASS:
128 break;
129
130 case ST_MAPCLASS:
125 len = sizeof(s->s_mapclass);
131 len = sizeof s->s_mapclass;
126 break;
127
128 case ST_MAP:
132 break;
133
134 case ST_MAP:
129 len = sizeof(s->s_map);
135 len = sizeof s->s_map;
130 break;
131
132 case ST_HOSTSIG:
136 break;
137
138 case ST_HOSTSIG:
133 len = sizeof(s->s_hostsig);
139 len = sizeof s->s_hostsig;
134 break;
135
136 case ST_NAMECANON:
140 break;
141
142 case ST_NAMECANON:
137 len = sizeof(s->s_namecanon);
143 len = sizeof s->s_namecanon;
138 break;
139
140 case ST_MACRO:
144 break;
145
146 case ST_MACRO:
141 len = sizeof(s->s_macro);
147 len = sizeof s->s_macro;
142 break;
143
144 case ST_RULESET:
148 break;
149
150 case ST_RULESET:
145 len = sizeof(s->s_ruleset);
151 len = sizeof s->s_ruleset;
146 break;
147
152 break;
153
148 case ST_HEADER:
149 len = sizeof(s->s_header);
150 break;
151
152 case ST_SERVICE:
154 case ST_SERVICE:
153 len = sizeof(s->s_service);
155 len = sizeof s->s_service;
154 break;
155
156 break;
157
156#if LDAPMAP
157 case ST_LMAP:
158 len = sizeof(s->s_lmap);
158 case ST_HEADER:
159 len = sizeof s->s_header;
159 break;
160 break;
160#endif /* LDAPMAP */
161
161
162#if MILTER
163 case ST_MILTER:
164 len = sizeof(s->s_milter);
165 break;
166#endif /* MILTER */
167
168 case ST_QUEUE:
169 len = sizeof(s->s_quegrp);
170 break;
171
172#if SOCKETMAP
173 case ST_SOCKETMAP:
174 len = sizeof(s->s_socketmap);
175 break;
176#endif /* SOCKETMAP */
177
178 default:
162 default:
179 /*
180 ** Each mailer has its own MCI stab entry:
181 **
182 ** s = stab(host, ST_MCI + m->m_mno, ST_ENTER);
183 **
184 ** Therefore, anything ST_MCI or larger is an s_mci.
185 */
186
187 if (type >= ST_MCI)
163 if (type >= ST_MCI)
188 len = sizeof(s->s_mci);
164 len = sizeof s->s_mci;
189 else
190 {
191 syserr("stab: unknown symbol type %d", type);
165 else
166 {
167 syserr("stab: unknown symbol type %d", type);
192 len = sizeof(s->s_value);
168 len = sizeof s->s_value;
193 }
194 break;
195 }
169 }
170 break;
171 }
196 len += sizeof(*s) - sizeof(s->s_value);
172 len += sizeof *s - sizeof s->s_value;
173#else
174 len = sizeof *s;
175#endif
197
176
198 if (tTd(36, 15))
199 sm_dprintf("size of stab entry: %d\n", len);
200
201 /* make new entry */
177 /* make new entry */
202 s = (STAB *) sm_pmalloc_x(len);
203 memset((char *) s, '\0', len);
204 s->s_name = sm_pstrdup_x(name);
205 s->s_symtype = type;
178 s = (STAB *) xalloc(len);
179 bzero((char *) s, len);
180 s->s_name = newstr(name);
181 s->s_type = type;
182 s->s_len = len;
206
207 /* link it in */
208 *ps = s;
209
183
184 /* link it in */
185 *ps = s;
186
210 /* set a default value for rulesets */
211 if (type == ST_RULESET)
212 s->s_ruleset = -1;
213
214 return s;
187 return (s);
215}
188}
216/*
189 /*
217** STABAPPLY -- apply function to all stab entries
218**
219** Parameters:
190** STABAPPLY -- apply function to all stab entries
191**
192** Parameters:
220** func -- the function to apply. It will be given two
221** parameters (the stab entry and the arg).
193** func -- the function to apply. It will be given one
194** parameter (the stab entry).
222** arg -- an arbitrary argument, passed to func.
223**
224** Returns:
225** none.
226*/
227
228void
229stabapply(func, arg)
230 void (*func)__P((STAB *, int));
231 int arg;
232{
233 register STAB **shead;
234 register STAB *s;
235
236 for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++)
237 {
238 for (s = *shead; s != NULL; s = s->s_next)
239 {
240 if (tTd(36, 90))
195** arg -- an arbitrary argument, passed to func.
196**
197** Returns:
198** none.
199*/
200
201void
202stabapply(func, arg)
203 void (*func)__P((STAB *, int));
204 int arg;
205{
206 register STAB **shead;
207 register STAB *s;
208
209 for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++)
210 {
211 for (s = *shead; s != NULL; s = s->s_next)
212 {
213 if (tTd(36, 90))
241 sm_dprintf("stabapply: trying %d/%s\n",
242 s->s_symtype, s->s_name);
214 printf("stabapply: trying %d/%s\n",
215 s->s_type, s->s_name);
243 func(s, arg);
244 }
245 }
246}
216 func(s, arg);
217 }
218 }
219}
247/*
248** QUEUEUP_MACROS -- queueup the macros in a class
249**
250** Write the macros listed in the specified class into the
251** file referenced by qfp.
252**
253** Parameters:
254** class -- class ID.
255** qfp -- file pointer to the queue file.
256** e -- the envelope.
257**
258** Returns:
259** none.
260*/
261
262void
263queueup_macros(class, qfp, e)
264 int class;
265 SM_FILE_T *qfp;
266 ENVELOPE *e;
267{
268 register STAB **shead;
269 register STAB *s;
270
271 if (e == NULL)
272 return;
273
274 class = bitidx(class);
275 for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++)
276 {
277 for (s = *shead; s != NULL; s = s->s_next)
278 {
279 int m;
280 char *p;
281
282 if (s->s_symtype == ST_CLASS &&
283 bitnset(bitidx(class), s->s_class) &&
284 (m = macid(s->s_name)) != 0 &&
285 (p = macvalue(m, e)) != NULL)
286 {
287 (void) sm_io_fprintf(qfp, SM_TIME_DEFAULT,
288 "$%s%s\n",
289 s->s_name,
290 denlstring(p, true,
291 false));
292 }
293 }
294 }
295}
296/*
297** COPY_CLASS -- copy class members from one class to another
298**
299** Parameters:
300** src -- source class.
301** dst -- destination class.
302**
303** Returns:
304** none.
305*/
306
307void
308copy_class(src, dst)
309 int src;
310 int dst;
311{
312 register STAB **shead;
313 register STAB *s;
314
315 src = bitidx(src);
316 dst = bitidx(dst);
317 for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++)
318 {
319 for (s = *shead; s != NULL; s = s->s_next)
320 {
321 if (s->s_symtype == ST_CLASS &&
322 bitnset(src, s->s_class))
323 setbitn(dst, s->s_class);
324 }
325 }
326}
327
328/*
329** RMEXPSTAB -- remove expired entries from SymTab.
330**
331** These entries need to be removed in long-running processes,
332** e.g., persistent queue runners, to avoid consuming memory.
333**
334** XXX It might be useful to restrict the maximum TTL to avoid
335** caching data very long.
336**
337** Parameters:
338** none.
339**
340** Returns:
341** none.
342**
343** Side Effects:
344** can remove entries from the symbol table.
345*/
346
347#define SM_STAB_FREE(x) \
348 do \
349 { \
350 char *o = (x); \
351 (x) = NULL; \
352 if (o != NULL) \
353 sm_free(o); \
354 } while (0)
355
356void
357rmexpstab()
358{
359 int i;
360 STAB *s, *p, *f;
361 time_t now;
362
363 now = curtime();
364 for (i = 0; i < STABSIZE; i++)
365 {
366 p = NULL;
367 s = SymTab[i];
368 while (s != NULL)
369 {
370 switch (s->s_symtype)
371 {
372 case ST_HOSTSIG:
373 if (s->s_hostsig.hs_exp >= now)
374 goto next; /* not expired */
375 SM_STAB_FREE(s->s_hostsig.hs_sig); /* XXX */
376 break;
377
378 case ST_NAMECANON:
379 if (s->s_namecanon.nc_exp >= now)
380 goto next; /* not expired */
381 SM_STAB_FREE(s->s_namecanon.nc_cname); /* XXX */
382 break;
383
384 default:
385 if (s->s_symtype >= ST_MCI)
386 {
387 /* call mci_uncache? */
388 SM_STAB_FREE(s->s_mci.mci_status);
389 SM_STAB_FREE(s->s_mci.mci_rstatus);
390 SM_STAB_FREE(s->s_mci.mci_heloname);
391#if 0
392 /* not dynamically allocated */
393 SM_STAB_FREE(s->s_mci.mci_host);
394 SM_STAB_FREE(s->s_mci.mci_tolist);
395#endif /* 0 */
396#if SASL
397 /* should always by NULL */
398 SM_STAB_FREE(s->s_mci.mci_sasl_string);
399#endif /* SASL */
400 if (s->s_mci.mci_rpool != NULL)
401 {
402 sm_rpool_free(s->s_mci.mci_rpool);
403 s->s_mci.mci_macro.mac_rpool = NULL;
404 s->s_mci.mci_rpool = NULL;
405 }
406 break;
407 }
408 next:
409 p = s;
410 s = s->s_next;
411 continue;
412 }
413
414 /* remove entry */
415 SM_STAB_FREE(s->s_name); /* XXX */
416 f = s;
417 s = s->s_next;
418 sm_free(f); /* XXX */
419 if (p == NULL)
420 SymTab[i] = s;
421 else
422 p->s_next = s;
423 }
424 }
425}
426
427#if SM_HEAP_CHECK
428/*
429** DUMPSTAB -- dump symbol table.
430**
431** For debugging.
432*/
433
434#define MAXSTTYPES (ST_MCI + 1)
435
436void
437dumpstab()
438{
439 int i, t, total, types[MAXSTTYPES];
440 STAB *s;
441 static int prevt[MAXSTTYPES], prev = 0;
442
443 total = 0;
444 for (i = 0; i < MAXSTTYPES; i++)
445 types[i] = 0;
446 for (i = 0; i < STABSIZE; i++)
447 {
448 s = SymTab[i];
449 while (s != NULL)
450 {
451 ++total;
452 t = s->s_symtype;
453 if (t > MAXSTTYPES - 1)
454 t = MAXSTTYPES - 1;
455 types[t]++;
456 s = s->s_next;
457 }
458 }
459 sm_syslog(LOG_INFO, NOQID, "stab: total=%d (%d)", total, total - prev);
460 prev = total;
461 for (i = 0; i < MAXSTTYPES; i++)
462 {
463 if (types[i] != 0)
464 {
465 sm_syslog(LOG_INFO, NOQID, "stab: type[%2d]=%2d (%d)",
466 i, types[i], types[i] - prevt[i]);
467 }
468 prevt[i] = types[i];
469 }
470}
471#endif /* SM_HEAP_CHECK */