1: /* 2: * Copyright (c) 1986 Regents of the University of California. 3: * All rights reserved. 4: * 5: * Redistribution and use in source and binary forms are permitted 6: * provided that this notice is preserved and that due credit is given 7: * to the University of California at Berkeley. The name of the University 8: * may not be used to endorse or promote products derived from this 9: * software without specific prior written permission. This software 10: * is provided ``as is'' without express or implied warranty. 11: */ 12: 13: #if defined(DOSCCS) && !defined(lint) 14: static char sccsid[] = "@(#)db_lookup.c 4.14.1 (2.11BSD GTE) 1/1/94"; 15: #endif 16: 17: /* 18: * Table lookup routines. 19: */ 20: 21: #include <sys/types.h> 22: #include <stdio.h> 23: #include <arpa/nameser.h> 24: #include "db.h" 25: 26: struct hashbuf *hashtab; /* root hash table */ 27: struct hashbuf *fcachetab; /* hash table of cache read from file */ 28: 29: #ifdef DEBUG 30: extern int debug; 31: extern FILE *ddt; 32: #endif 33: 34: /* 35: * Lookup 'name' and return a pointer to the namebuf; 36: * NULL otherwise. If 'insert', insert name into tables. 37: * Wildcard lookups are handled. 38: */ 39: struct namebuf * 40: nlookup(name, htpp, fname, insert) 41: char *name; 42: struct hashbuf **htpp; 43: char **fname; 44: int insert; 45: { 46: register struct namebuf *np; 47: register char *cp; 48: register int c; 49: register unsigned hval; 50: register struct hashbuf *htp; 51: struct namebuf *parent = NULL; 52: 53: htp = *htpp; 54: hval = 0; 55: *fname = "???"; 56: for (cp = name; c = *cp++; ) { 57: if (c == '.') { 58: parent = np = nlookup(cp, htpp, fname, insert); 59: if (np == NULL) 60: return (NULL); 61: if (*fname != cp) 62: return (np); 63: if ((htp = np->n_hash) == NULL) { 64: if (!insert) { 65: if (np->n_dname[0] == '*' && 66: np->n_dname[1] == '\0') 67: *fname = name; 68: return (np); 69: } 70: htp = savehash((struct hashbuf *)NULL); 71: np->n_hash = htp; 72: } 73: *htpp = htp; 74: break; 75: } 76: hval <<= HASHSHIFT; 77: hval += c & HASHMASK; 78: } 79: c = *--cp; 80: *cp = '\0'; 81: /* 82: * Lookup this label in current hash table. 83: */ 84: for (np = htp->h_tab[hval % htp->h_size]; np != NULL; np = np->n_next) { 85: 86: #ifdef ALLOW_UPDATES 87: /* Note: at this point, if np->n_data is NULL, we could be in 88: one of two situations: Either we have come across a name 89: for which all the RRs have been (dynamically) deleted, or 90: else we have come across a name which has no RRs 91: associated with it because it is just a place holder 92: (e.g., EDU). In the former case, we would like to delete 93: the namebuf, since it is no longer of use, but in the 94: latter case we need to hold on to it, so future lookups 95: that depend on it don't fail. The only way I can see of 96: doing this is to always leave the namebufs around 97: (although then the memory usage continues to grow whenever 98: names are added, and can never shrink back down completely 99: when all their associated RRs are deleted). */ 100: #endif ALLOW_UPDATES 101: 102: if (np->n_hashval == hval && 103: strcasecmp(name, np->n_dname) == 0) { 104: *cp = c; 105: *fname = name; 106: return (np); 107: } 108: } 109: if (!insert) { 110: /* 111: * look for wildcard in this hash table 112: */ 113: hval = ('*' & HASHMASK) % htp->h_size; 114: for (np = htp->h_tab[hval]; np != NULL; np = np->n_next) { 115: if (np->n_dname[0] == '*' && np->n_dname[1] == '\0') { 116: *cp = c; 117: *fname = name; 118: return (np); 119: } 120: } 121: *cp = c; 122: return (parent); 123: } 124: np = savename(name); 125: np->n_parent = parent; 126: np->n_hashval = hval; 127: hval %= htp->h_size; 128: np->n_next = htp->h_tab[hval]; 129: htp->h_tab[hval] = np; 130: /* increase hash table size */ 131: if (++htp->h_cnt > htp->h_size * 2) { 132: *htpp = savehash(htp); 133: if (parent == NULL) { 134: if (htp == hashtab) 135: hashtab = *htpp; 136: else 137: fcachetab = *htpp; 138: } 139: else 140: parent->n_hash = *htpp; 141: htp = *htpp; 142: } 143: *cp = c; 144: *fname = name; 145: return (np); 146: } 147: 148: /* 149: * Does the data record match the class and type? 150: */ 151: match(dp, class, type) 152: register struct databuf *dp; 153: register int class, type; 154: { 155: #ifdef DEBUG 156: if (debug >= 5) 157: fprintf(ddt,"match(0x%x, %d, %d) %d, %d\n", dp, class, type, 158: dp->d_class, dp->d_type); 159: #endif 160: if (dp->d_class != class && class != C_ANY) 161: return (0); 162: if (dp->d_type != type && type != T_ANY) 163: return (0); 164: return (1); 165: }