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