stab.c revision 261363
11590Srgrimes/* 21590Srgrimes * Copyright (c) 1998-2001, 2003 Proofpoint, Inc. and its suppliers. 31590Srgrimes * All rights reserved. 41590Srgrimes * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 51590Srgrimes * Copyright (c) 1988, 1993 61590Srgrimes * The Regents of the University of California. All rights reserved. 71590Srgrimes * 81590Srgrimes * By using this file, you agree to the terms and conditions set 91590Srgrimes * forth in the LICENSE file which can be found at the top level of 101590Srgrimes * the sendmail distribution. 111590Srgrimes * 121590Srgrimes */ 131590Srgrimes 141590Srgrimes#include <sendmail.h> 151590Srgrimes 161590SrgrimesSM_RCSID("@(#)$Id: stab.c,v 8.92 2013/11/22 20:51:56 ca Exp $") 171590Srgrimes 181590Srgrimes/* 191590Srgrimes** STAB -- manage the symbol table 201590Srgrimes** 211590Srgrimes** Parameters: 221590Srgrimes** name -- the name to be looked up or inserted. 231590Srgrimes** type -- the type of symbol. 241590Srgrimes** op -- what to do: 251590Srgrimes** ST_ENTER -- enter the name if not already present. 261590Srgrimes** ST_FIND -- find it only. 271590Srgrimes** 281590Srgrimes** Returns: 291590Srgrimes** pointer to a STAB entry for this name. 301590Srgrimes** NULL if not found and not entered. 3191792Smike** 321590Srgrimes** Side Effects: 331590Srgrimes** can update the symbol table. 3491481Smike*/ 351590Srgrimes 3691792Smike#define STABSIZE 2003 371590Srgrimes#define SM_LOWER(c) ((isascii(c) && isupper(c)) ? tolower(c) : (c)) 3891481Smike 3991481Smikestatic STAB *SymTab[STABSIZE]; 4015233Sbde 411590SrgrimesSTAB * 4291481Smikestab(name, type, op) 4391481Smike char *name; 4491481Smike int type; 451590Srgrimes int op; 461590Srgrimes{ 4715233Sbde register STAB *s; 4815233Sbde register STAB **ps; 4915233Sbde register int hfunc; 5098165Stjr register char *p; 511590Srgrimes int len; 5213380Sache 5391481Smike if (tTd(36, 5)) 541590Srgrimes sm_dprintf("STAB: %s %d ", name, type); 551590Srgrimes 561590Srgrimes /* 5715233Sbde ** Compute the hashing function 58128049Stjr */ 59101670Stjr 601590Srgrimes hfunc = type; 61227201Sed for (p = name; *p != '\0'; p++) 62227201Sed hfunc = ((hfunc << 1) ^ (SM_LOWER(*p) & 0377)) % STABSIZE; 63208210Spjd 641590Srgrimes if (tTd(36, 9)) 65208170Spjd sm_dprintf("(hfunc=%d) ", hfunc); 66208170Spjd 6792922Simp ps = &SymTab[hfunc]; 6892922Simp if (type == ST_MACRO || type == ST_RULESET || type == ST_NAMECANON) 691590Srgrimes { 70208170Spjd while ((s = *ps) != NULL && 71208170Spjd (s->s_symtype != type || strcmp(name, s->s_name))) 72208170Spjd ps = &s->s_next; 73208170Spjd } 74208170Spjd else 75208170Spjd { 76208170Spjd while ((s = *ps) != NULL && 77282278Sbdrewery (s->s_symtype != type || sm_strcasecmp(name, s->s_name))) 78282278Sbdrewery ps = &s->s_next; 79282278Sbdrewery } 80282278Sbdrewery 81282278Sbdrewery /* 82282278Sbdrewery ** Dispose of the entry. 83282278Sbdrewery */ 84282278Sbdrewery 851590Srgrimes if (s != NULL || op == ST_FIND) 86139364Sjosef { 871590Srgrimes if (tTd(36, 5)) 8849685Ssheldonh { 891590Srgrimes if (s == NULL) 9013380Sache sm_dprintf("not found\n"); 9113380Sache else 92185714Skeramida { 931590Srgrimes long *lp = (long *) s->s_class; 941590Srgrimes 951590Srgrimes sm_dprintf("type %d val %lx %lx %lx %lx\n", 961590Srgrimes s->s_symtype, lp[0], lp[1], lp[2], lp[3]); 971590Srgrimes } 981590Srgrimes } 991590Srgrimes return s; 1001590Srgrimes } 1011590Srgrimes 10298165Stjr /* 1031590Srgrimes ** Make a new entry and link it in. 104185714Skeramida */ 105185714Skeramida 106185714Skeramida if (tTd(36, 5)) 10798165Stjr sm_dprintf("entered\n"); 10898165Stjr 10998165Stjr /* determine size of new entry */ 11098165Stjr switch (type) 1111590Srgrimes { 1121590Srgrimes case ST_CLASS: 1131590Srgrimes len = sizeof(s->s_class); 1141590Srgrimes break; 1151590Srgrimes 1161590Srgrimes case ST_MAILER: 1171590Srgrimes len = sizeof(s->s_mailer); 118208170Spjd break; 119208170Spjd 1201590Srgrimes case ST_ALIAS: 121185714Skeramida len = sizeof(s->s_alias); 1221590Srgrimes break; 1231590Srgrimes 12415233Sbde case ST_MAPCLASS: 1251590Srgrimes len = sizeof(s->s_mapclass); 1261590Srgrimes break; 12715233Sbde 12815233Sbde case ST_MAP: 129208170Spjd len = sizeof(s->s_map); 130208170Spjd break; 131208170Spjd 132208170Spjd case ST_HOSTSIG: 133208170Spjd len = sizeof(s->s_hostsig); 134208170Spjd break; 1351590Srgrimes 1361590Srgrimes case ST_NAMECANON: 137208170Spjd len = sizeof(s->s_namecanon); 138208170Spjd break; 13915233Sbde 1401590Srgrimes case ST_MACRO: 1411590Srgrimes len = sizeof(s->s_macro); 142208170Spjd break; 143208170Spjd 144208170Spjd case ST_RULESET: 145208170Spjd len = sizeof(s->s_ruleset); 146208170Spjd break; 147208170Spjd 148208170Spjd case ST_HEADER: 149208170Spjd len = sizeof(s->s_header); 150208170Spjd break; 151208170Spjd 152208170Spjd case ST_SERVICE: 153208170Spjd len = sizeof(s->s_service); 154208170Spjd break; 155208170Spjd 156208170Spjd#if LDAPMAP 157208170Spjd case ST_LMAP: 158208170Spjd len = sizeof(s->s_lmap); 159208170Spjd break; 160208170Spjd#endif /* LDAPMAP */ 161208170Spjd 162208170Spjd#if MILTER 163208170Spjd case ST_MILTER: 164208170Spjd len = sizeof(s->s_milter); 165208170Spjd break; 166208170Spjd#endif /* MILTER */ 167208170Spjd 168208170Spjd case ST_QUEUE: 16991481Smike len = sizeof(s->s_quegrp); 170139364Sjosef break; 1711590Srgrimes 17249685Ssheldonh#if SOCKETMAP 173185714Skeramida case ST_SOCKETMAP: 174128049Stjr len = sizeof(s->s_socketmap); 175128049Stjr break; 17649461Ssheldonh#endif /* SOCKETMAP */ 17749685Ssheldonh 17898291Stjr default: 17998165Stjr /* 180128049Stjr ** Each mailer has its own MCI stab entry: 1811590Srgrimes ** 182185714Skeramida ** s = stab(host, ST_MCI + m->m_mno, ST_ENTER); 183208170Spjd ** 18415233Sbde ** Therefore, anything ST_MCI or larger is an s_mci. 185208170Spjd */ 18615179Swosch 18715233Sbde if (type >= ST_MCI) 18815233Sbde len = sizeof(s->s_mci); 18915179Swosch else 19098165Stjr { 1911590Srgrimes syserr("stab: unknown symbol type %d", type); 1921590Srgrimes len = sizeof(s->s_value); 1931590Srgrimes } 1941590Srgrimes break; 1951590Srgrimes } 1961590Srgrimes len += sizeof(*s) - sizeof(s->s_value); 1971590Srgrimes 19828696Scharnier if (tTd(36, 15)) 19915233Sbde sm_dprintf("size of stab entry: %d\n", len); 20015233Sbde 20115233Sbde /* make new entry */ 20215233Sbde s = (STAB *) sm_pmalloc_x(len); 20315233Sbde memset((char *) s, '\0', len); 204208170Spjd s->s_name = sm_pstrdup_x(name); 205208170Spjd s->s_symtype = type; 206208170Spjd 207208170Spjd /* link it in */ 2081590Srgrimes *ps = s; 2091590Srgrimes 210185714Skeramida /* set a default value for rulesets */ 211185714Skeramida if (type == ST_RULESET) 212185714Skeramida s->s_ruleset = -1; 213185714Skeramida 2141590Srgrimes return s; 215185714Skeramida} 216185714Skeramida/* 2171590Srgrimes** STABAPPLY -- apply function to all stab entries 218282278Sbdrewery** 2191590Srgrimes** Parameters: 220208170Spjd** func -- the function to apply. It will be given two 2211590Srgrimes** parameters (the stab entry and the arg). 222185714Skeramida** arg -- an arbitrary argument, passed to func. 223185714Skeramida** 224185714Skeramida** Returns: 225185714Skeramida** none. 226208170Spjd*/ 2271590Srgrimes 22815233Sbdevoid 2291590Srgrimesstabapply(func, arg) 2301590Srgrimes void (*func)__P((STAB *, int)); 2311590Srgrimes int arg; 23298245Stjr{ 2331590Srgrimes register STAB **shead; 23498165Stjr register STAB *s; 23515233Sbde 23615233Sbde for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++) 23715233Sbde { 23815233Sbde for (s = *shead; s != NULL; s = s->s_next) 23915233Sbde { 24098245Stjr if (tTd(36, 90)) 241282278Sbdrewery sm_dprintf("stabapply: trying %d/%s\n", 242208170Spjd s->s_symtype, s->s_name); 243208170Spjd func(s, arg); 244208170Spjd } 2451590Srgrimes } 24615233Sbde} 2471590Srgrimes/* 2481590Srgrimes** QUEUEUP_MACROS -- queueup the macros in a class 2491590Srgrimes** 2501590Srgrimes** Write the macros listed in the specified class into the 2511590Srgrimes** file referenced by qfp. 25298165Stjr** 25398165Stjr** Parameters: 254128049Stjr** class -- class ID. 255128049Stjr** qfp -- file pointer to the queue file. 256128049Stjr** e -- the envelope. 257208170Spjd** 25815233Sbde** Returns: 25915233Sbde** none. 26015233Sbde*/ 26198165Stjr 26298165Stjrvoid 263208170Spjdqueueup_macros(class, qfp, e) 264208170Spjd int class; 26598165Stjr SM_FILE_T *qfp; 26698165Stjr ENVELOPE *e; 26798165Stjr{ 268128049Stjr register STAB **shead; 269128049Stjr register STAB *s; 270128049Stjr 271128049Stjr if (e == NULL) 272208170Spjd return; 273208170Spjd 274128049Stjr class = bitidx(class); 27598165Stjr for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++) 276128049Stjr { 277128049Stjr for (s = *shead; s != NULL; s = s->s_next) 278128049Stjr { 279128049Stjr int m; 280128049Stjr char *p; 281128049Stjr 282128049Stjr if (s->s_symtype == ST_CLASS && 28398165Stjr bitnset(bitidx(class), s->s_class) && 284185714Skeramida (m = macid(s->s_name)) != 0 && 285185714Skeramida (p = macvalue(m, e)) != NULL) 28698165Stjr { 28798165Stjr (void) sm_io_fprintf(qfp, SM_TIME_DEFAULT, 288185714Skeramida "$%s%s\n", 289185714Skeramida s->s_name, 290185714Skeramida denlstring(p, true, 291185714Skeramida false)); 2921590Srgrimes } 293185714Skeramida } 294101670Stjr } 2951590Srgrimes} 2961590Srgrimes/* 2971590Srgrimes** COPY_CLASS -- copy class members from one class to another 2981590Srgrimes** 2991590Srgrimes** Parameters: 3001590Srgrimes** src -- source class. 3011590Srgrimes** dst -- destination class. 302282278Sbdrewery** 303128049Stjr** Returns: 304128049Stjr** none. 305208170Spjd*/ 306208170Spjd 3071590Srgrimesvoid 308208170Spjdcopy_class(src, dst) 3091590Srgrimes int src; 310208170Spjd int dst; 3111590Srgrimes{ 312185714Skeramida register STAB **shead; 313185714Skeramida register STAB *s; 314185714Skeramida 315185714Skeramida src = bitidx(src); 316208170Spjd dst = bitidx(dst); 3171590Srgrimes for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++) 31815233Sbde { 3191590Srgrimes for (s = *shead; s != NULL; s = s->s_next) 3201590Srgrimes { 32191481Smike if (s->s_symtype == ST_CLASS && 322201181Sed bitnset(src, s->s_class)) 3231590Srgrimes setbitn(dst, s->s_class); 324185714Skeramida } 3251590Srgrimes } 3261590Srgrimes} 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 */ 472