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