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 */
| |
| |