source: trunk/third/sendmail/sendmail/stab.c @ 19204

Revision 19204, 8.4 KB checked in by zacheiss, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19203, which included commits to RCS files with non-trunk default branches.
Line 
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#include <sendmail.h>
15
16SM_RCSID("@(#)$Id: stab.c,v 1.1.1.1 2003-04-08 15:06:41 zacheiss Exp $")
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:
25**                      ST_ENTER -- enter the name if not 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
36#define STABSIZE        2003
37#define SM_LOWER(c)     ((isascii(c) && isupper(c)) ? tolower(c) : (c))
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;
52
53        if (tTd(36, 5))
54                sm_dprintf("STAB: %s %d ", name, type);
55
56        /*
57        **  Compute the hashing function
58        */
59
60        hfunc = type;
61        for (p = name; *p != '\0'; p++)
62                hfunc = ((hfunc << 1) ^ (SM_LOWER(*p) & 0377)) % STABSIZE;
63
64        if (tTd(36, 9))
65                sm_dprintf("(hfunc=%d) ", hfunc);
66
67        ps = &SymTab[hfunc];
68        if (type == ST_MACRO || type == ST_RULESET)
69        {
70                while ((s = *ps) != NULL &&
71                       (s->s_symtype != type || strcmp(name, s->s_name)))
72                        ps = &s->s_next;
73        }
74        else
75        {
76                while ((s = *ps) != NULL &&
77                       (s->s_symtype != type || sm_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)
90                                sm_dprintf("not found\n");
91                        else
92                        {
93                                long *lp = (long *) s->s_class;
94
95                                sm_dprintf("type %d val %lx %lx %lx %lx\n",
96                                        s->s_symtype, lp[0], lp[1], lp[2], lp[3]);
97                        }
98                }
99                return s;
100        }
101
102        /*
103        **  Make a new entry and link it in.
104        */
105
106        if (tTd(36, 5))
107                sm_dprintf("entered\n");
108
109        /* determine size of new entry */
110        switch (type)
111        {
112          case ST_CLASS:
113                len = sizeof s->s_class;
114                break;
115
116          case ST_ADDRESS:
117                len = sizeof s->s_address;
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 /* LDAPMAP */
165
166#if MILTER
167          case ST_MILTER:
168                len = sizeof s->s_milter;
169                break;
170#endif /* MILTER */
171
172          case ST_QUEUE:
173                len = sizeof s->s_quegrp;
174                break;
175
176          default:
177                /*
178                **  Each mailer has its own MCI stab entry:
179                **
180                **  s = stab(host, ST_MCI + m->m_mno, ST_ENTER);
181                **
182                **  Therefore, anything ST_MCI or larger is an s_mci.
183                */
184
185                if (type >= ST_MCI)
186                        len = sizeof s->s_mci;
187                else
188                {
189                        syserr("stab: unknown symbol type %d", type);
190                        len = sizeof s->s_value;
191                }
192                break;
193        }
194        len += sizeof *s - sizeof s->s_value;
195
196        if (tTd(36, 15))
197                sm_dprintf("size of stab entry: %d\n", len);
198
199        /* make new entry */
200        s = (STAB *) sm_pmalloc_x(len);
201        memset((char *) s, '\0', len);
202        s->s_name = sm_pstrdup_x(name);
203        s->s_symtype = type;
204
205        /* link it in */
206        *ps = s;
207
208        /* set a default value for rulesets */
209        if (type == ST_RULESET)
210                s->s_ruleset = -1;
211
212        return s;
213}
214/*
215**  STABAPPLY -- apply function to all stab entries
216**
217**      Parameters:
218**              func -- the function to apply.  It will be given two
219**                      parameters (the stab entry and the arg).
220**              arg -- an arbitrary argument, passed to func.
221**
222**      Returns:
223**              none.
224*/
225
226void
227stabapply(func, arg)
228        void (*func)__P((STAB *, int));
229        int arg;
230{
231        register STAB **shead;
232        register STAB *s;
233
234        for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++)
235        {
236                for (s = *shead; s != NULL; s = s->s_next)
237                {
238                        if (tTd(36, 90))
239                                sm_dprintf("stabapply: trying %d/%s\n",
240                                        s->s_symtype, s->s_name);
241                        func(s, arg);
242                }
243        }
244}
245/*
246**  QUEUEUP_MACROS -- queueup the macros in a class
247**
248**      Write the macros listed in the specified class into the
249**      file referenced by qfp.
250**
251**      Parameters:
252**              class -- class ID.
253**              qfp -- file pointer to the queue file.
254**              e -- the envelope.
255**
256**      Returns:
257**              none.
258*/
259
260void
261queueup_macros(class, qfp, e)
262        int class;
263        SM_FILE_T *qfp;
264        ENVELOPE *e;
265{
266        register STAB **shead;
267        register STAB *s;
268
269        if (e == NULL)
270                return;
271
272        class = bitidx(class);
273        for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++)
274        {
275                for (s = *shead; s != NULL; s = s->s_next)
276                {
277                        int m;
278                        char *p;
279
280                        if (s->s_symtype == ST_CLASS &&
281                            bitnset(bitidx(class), s->s_class) &&
282                            (m = macid(s->s_name)) != '\0' &&
283                            (p = macvalue(m, e)) != NULL)
284                        {
285                                (void) sm_io_fprintf(qfp, SM_TIME_DEFAULT,
286                                                      "$%s%s\n",
287                                                      s->s_name,
288                                                      denlstring(p, true,
289                                                                 false));
290                        }
291                }
292        }
293}
294/*
295**  COPY_CLASS -- copy class members from one class to another
296**
297**      Parameters:
298**              src -- source class.
299**              dst -- destination class.
300**
301**      Returns:
302**              none.
303*/
304
305void
306copy_class(src, dst)
307        int src;
308        int dst;
309{
310        register STAB **shead;
311        register STAB *s;
312
313        src = bitidx(src);
314        dst = bitidx(dst);
315        for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++)
316        {
317                for (s = *shead; s != NULL; s = s->s_next)
318                {
319                        if (s->s_symtype == ST_CLASS &&
320                            bitnset(src, s->s_class))
321                                setbitn(dst, s->s_class);
322                }
323        }
324}
325
326/*
327**  RMEXPSTAB -- remove expired entries from SymTab.
328**
329**      These entries need to be removed in long-running processes,
330**      e.g., persistent queue runners, to avoid consuming memory.
331**
332**      XXX It might be useful to restrict the maximum TTL to avoid
333**              caching data very long.
334**
335**      Parameters:
336**              none.
337**
338**      Returns:
339**              none.
340**
341**      Side Effects:
342**              can remove entries from the symbol table.
343*/
344
345#define SM_STAB_FREE(x) \
346        do \
347        { \
348                char *o = (x); \
349                (x) = NULL; \
350                if (o != NULL) \
351                        sm_free(o); \
352        } while (0)
353
354void
355rmexpstab()
356{
357        int i;
358        STAB *s, *p, *f;
359        time_t now;
360
361        now = curtime();
362        for (i = 0; i < STABSIZE; i++)
363        {
364                p = NULL;
365                s = SymTab[i];
366                while (s != NULL)
367                {
368                        switch (s->s_symtype)
369                        {
370                          case ST_HOSTSIG:
371                                if (s->s_hostsig.hs_exp >= now)
372                                        goto next;      /* not expired */
373                                SM_STAB_FREE(s->s_hostsig.hs_sig); /* XXX */
374                                break;
375
376                          case ST_NAMECANON:
377                                if (s->s_namecanon.nc_exp >= now)
378                                        goto next;      /* not expired */
379                                SM_STAB_FREE(s->s_namecanon.nc_cname); /* XXX */
380                                break;
381
382                          default:
383                                if (s->s_symtype >= ST_MCI)
384                                {
385                                        /* call mci_uncache? */
386                                        SM_STAB_FREE(s->s_mci.mci_status);
387                                        SM_STAB_FREE(s->s_mci.mci_rstatus);
388                                        SM_STAB_FREE(s->s_mci.mci_heloname);
389#if 0
390                                        /* not dynamically allocated */
391                                        SM_STAB_FREE(s->s_mci.mci_host);
392                                        SM_STAB_FREE(s->s_mci.mci_tolist);
393#endif /* 0 */
394#if SASL
395                                        /* should always by NULL */
396                                        SM_STAB_FREE(s->s_mci.mci_sasl_string);
397#endif /* SASL */
398                                        if (s->s_mci.mci_rpool != NULL)
399                                        {
400                                                sm_rpool_free(s->s_mci.mci_rpool);
401                                                s->s_mci.mci_macro.mac_rpool = NULL;
402                                                s->s_mci.mci_rpool = NULL;
403                                        }
404                                        break;
405                                }
406  next:
407                                p = s;
408                                s = s->s_next;
409                                continue;
410                        }
411
412                        /* remove entry */
413                        SM_STAB_FREE(s->s_name); /* XXX */
414                        f = s;
415                        s = s->s_next;
416                        sm_free(f);     /* XXX */
417                        if (p == NULL)
418                                SymTab[i] = s;
419                        else
420                                p->s_next = s;
421                }
422        }
423}
424
425#if SM_HEAP_CHECK
426/*
427**  DUMPSTAB -- dump symbol table.
428**
429**      For debugging.
430*/
431
432#define MAXSTTYPES      (ST_MCI + 1)
433
434void
435dumpstab()
436{
437        int i, t, total, types[MAXSTTYPES];
438        STAB *s;
439        static int prevt[MAXSTTYPES], prev = 0;
440
441        total = 0;
442        for (i = 0; i < MAXSTTYPES; i++)
443                types[i] = 0;
444        for (i = 0; i < STABSIZE; i++)
445        {
446                s = SymTab[i];
447                while (s != NULL)
448                {
449                        ++total;
450                        t = s->s_symtype;
451                        if (t > MAXSTTYPES - 1)
452                                t = MAXSTTYPES - 1;
453                        types[t]++;
454                        s = s->s_next;
455                }
456        }
457        sm_syslog(LOG_INFO, NOQID, "stab: total=%d (%d)", total, total - prev);
458        prev = total;
459        for (i = 0; i < MAXSTTYPES; i++)
460        {
461                if (types[i] != 0)
462                {
463                        sm_syslog(LOG_INFO, NOQID, "stab: type[%2d]=%2d (%d)",
464                                i, types[i], types[i] - prevt[i]);
465                }
466                prevt[i] = types[i];
467        }
468}
469#endif /* SM_HEAP_CHECK */
Note: See TracBrowser for help on using the repository browser.