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 #ifndef lint 15 static char id[] = "@(#)$Id: stab.c,v 8.40.16.7 2001/05/07 22:06:41 gshapiro Exp $"; 16 #endif /* ! lint */ 17 18 #include <sendmail.h> 19 20 /* 21 ** STAB -- manage the symbol table 22 ** 23 ** Parameters: 24 ** name -- the name to be looked up or inserted. 25 ** type -- the type of symbol. 26 ** op -- what to do: 27 ** ST_ENTER -- enter the name if not 28 ** already present. 29 ** ST_FIND -- find it only. 30 ** 31 ** Returns: 32 ** pointer to a STAB entry for this name. 33 ** NULL if not found and not entered. 34 ** 35 ** Side Effects: 36 ** can update the symbol table. 37 */ 38 39 #define STABSIZE 2003 40 41 static STAB *SymTab[STABSIZE]; 42 43 STAB * 44 stab(name, type, op) 45 char *name; 46 int type; 47 int op; 48 { 49 register STAB *s; 50 register STAB **ps; 51 register int hfunc; 52 register char *p; 53 int len; 54 55 if (tTd(36, 5)) 56 dprintf("STAB: %s %d ", name, type); 57 58 /* 59 ** Compute the hashing function 60 */ 61 62 hfunc = type; 63 for (p = name; *p != '\0'; p++) 64 hfunc = ((hfunc << 1) ^ (lower(*p) & 0377)) % STABSIZE; 65 66 if (tTd(36, 9)) 67 dprintf("(hfunc=%d) ", hfunc); 68 69 ps = &SymTab[hfunc]; 70 if (type == ST_MACRO || type == ST_RULESET) 71 { 72 while ((s = *ps) != NULL && 73 (s->s_type != type || strcmp(name, s->s_name))) 74 ps = &s->s_next; 75 } 76 else 77 { 78 while ((s = *ps) != NULL && 79 (s->s_type != type || strcasecmp(name, s->s_name))) 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) 92 dprintf("not found\n"); 93 else 94 { 95 long *lp = (long *) s->s_class; 96 97 dprintf("type %d val %lx %lx %lx %lx\n", 98 s->s_type, lp[0], lp[1], lp[2], lp[3]); 99 } 100 } 101 return s; 102 } 103 104 /* 105 ** Make a new entry and link it in. 106 */ 107 108 if (tTd(36, 5)) 109 dprintf("entered\n"); 110 111 /* determine size of new entry */ 112 switch (type) 113 { 114 case ST_CLASS: 115 len = sizeof s->s_class; 116 break; 117 118 case ST_ADDRESS: 119 len = sizeof s->s_address; 120 break; 121 122 case ST_MAILER: 123 len = sizeof s->s_mailer; 124 break; 125 126 case ST_ALIAS: 127 len = sizeof s->s_alias; 128 break; 129 130 case ST_MAPCLASS: 131 len = sizeof s->s_mapclass; 132 break; 133 134 case ST_MAP: 135 len = sizeof s->s_map; 136 break; 137 138 case ST_HOSTSIG: 139 len = sizeof s->s_hostsig; 140 break; 141 142 case ST_NAMECANON: 143 len = sizeof s->s_namecanon; 144 break; 145 146 case ST_MACRO: 147 len = sizeof s->s_macro; 148 break; 149 150 case ST_RULESET: 151 len = sizeof s->s_ruleset; 152 break; 153 154 case ST_HEADER: 155 len = sizeof s->s_header; 156 break; 157 158 case ST_SERVICE: 159 len = sizeof s->s_service; 160 break; 161 162 #ifdef LDAPMAP 163 case ST_LMAP: 164 len = sizeof s->s_lmap; 165 break; 166 #endif /* LDAPMAP */ 167 168 #if _FFR_MILTER 169 case ST_MILTER: 170 len = sizeof s->s_milter; 171 break; 172 #endif /* _FFR_MILTER */ 173 174 default: 175 /* 176 ** Each mailer has it's own MCI stab entry: 177 ** 178 ** s = stab(host, ST_MCI + m->m_mno, ST_ENTER); 179 ** 180 ** Therefore, anything ST_MCI or larger is an s_mci. 181 */ 182 183 if (type >= ST_MCI) 184 len = sizeof s->s_mci; 185 else 186 { 187 syserr("stab: unknown symbol type %d", type); 188 len = sizeof s->s_value; 189 } 190 break; 191 } 192 len += sizeof *s - sizeof s->s_value; 193 194 if (tTd(36, 15)) 195 dprintf("size of stab entry: %d\n", len); 196 197 /* make new entry */ 198 s = (STAB *) xalloc(len); 199 memset((char *) s, '\0', len); 200 s->s_name = newstr(name); 201 s->s_type = type; 202 s->s_len = len; 203 204 /* link it in */ 205 *ps = s; 206 207 /* set a default value for rulesets */ 208 if (type == ST_RULESET) 209 s->s_ruleset = -1; 210 211 return s; 212 } 213 /* 214 ** STABAPPLY -- apply function to all stab entries 215 ** 216 ** Parameters: 217 ** func -- the function to apply. It will be given one 218 ** parameter (the stab entry). 219 ** arg -- an arbitrary argument, passed to func. 220 ** 221 ** Returns: 222 ** none. 223 */ 224 225 void 226 stabapply(func, arg) 227 void (*func)__P((STAB *, int)); 228 int arg; 229 { 230 register STAB **shead; 231 register STAB *s; 232 233 for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++) 234 { 235 for (s = *shead; s != NULL; s = s->s_next) 236 { 237 if (tTd(36, 90)) 238 dprintf("stabapply: trying %d/%s\n", 239 s->s_type, s->s_name); 240 func(s, arg); 241 } 242 } 243 } 244 /* 245 ** QUEUEUP_MACROS -- queueup the macros in a class 246 ** 247 ** Write the macros listed in the specified class into the 248 ** file referenced by qfp. 249 ** 250 ** Parameters: 251 ** class -- class ID. 252 ** qfp -- file pointer to the qf file. 253 ** e -- the envelope. 254 ** 255 ** Returns: 256 ** none. 257 */ 258 259 void 260 queueup_macros(class, qfp, e) 261 int class; 262 FILE *qfp; 263 ENVELOPE *e; 264 { 265 register STAB **shead; 266 register STAB *s; 267 268 if (e == NULL) 269 return; 270 271 class = bitidx(class); 272 for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++) 273 { 274 for (s = *shead; s != NULL; s = s->s_next) 275 { 276 int m; 277 char *p; 278 279 if (s->s_type == ST_CLASS && 280 bitnset(class, s->s_class) && 281 (m = macid(s->s_name, NULL)) != '\0' && 282 (p = macvalue(m, e)) != NULL) 283 { 284 /* 285 ** HACK ALERT: Unfortunately, 8.10 and 286 ** 8.11 reused the ${if_addr} and 287 ** ${if_family} macros for both the incoming 288 ** interface address/family (getrequests()) 289 ** and the outgoing interface address/family 290 ** (makeconnection()). In order for D_BINDIF 291 ** to work properly, have to preserve the 292 ** incoming information in the queue file for 293 ** later delivery attempts. The original 294 ** information is stored in the envelope 295 ** in readqf() so it can be stored in 296 ** queueup_macros(). This should be fixed 297 ** in 8.12. 298 */ 299 300 if (e->e_if_macros[EIF_ADDR] != NULL && 301 strcmp(s->s_name, "{if_addr}") == 0) 302 p = e->e_if_macros[EIF_ADDR]; 303 304 fprintf(qfp, "$%s%s\n", 305 s->s_name, 306 denlstring(p, TRUE, FALSE)); 307 } 308 } 309 } 310 } 311 /* 312 ** COPY_CLASS -- copy class members from one class to another 313 ** 314 ** Parameters: 315 ** src -- source class. 316 ** dst -- destination class. 317 ** 318 ** Returns: 319 ** none. 320 */ 321 322 void 323 copy_class(src, dst) 324 int src; 325 int dst; 326 { 327 register STAB **shead; 328 register STAB *s; 329 330 src = bitidx(src); 331 dst = bitidx(dst); 332 for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++) 333 { 334 for (s = *shead; s != NULL; s = s->s_next) 335 { 336 if (s->s_type == ST_CLASS && 337 bitnset(src, s->s_class)) 338 setbitn(dst, s->s_class); 339 } 340 } 341 } 342