|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)db_update.c 4.3 (Berkeley) 5/30/86";
3: #endif
4:
5: /*
6: * Copyright (c) 1986 Regents of the University of California
7: * All Rights Reserved
8: */
9:
10: #include <sys/types.h>
11: #include <sys/time.h>
12: #include <stdio.h>
13: #include <syslog.h>
14: #include <arpa/nameser.h>
15: #include "db.h"
16:
17: struct timeval tt;
18: extern FILE *ddt;
19:
20: /*
21: * Update data base. Flags control the action.
22: * Inverse query tables modified.
23: */
24: db_update(name, odp, newdp, flags)
25: char name[];
26: struct databuf *odp, *newdp;
27: int flags;
28: {
29: register struct namebuf *np;
30: register struct databuf *dp, *pdp;
31: struct hashbuf *htp = hashtab;
32: char *fname;
33:
34: #ifdef DEBUG
35: extern int debug;
36:
37: if (debug >= 3)
38: fprintf(ddt,"db_update( %s )\n",name);
39: #endif
40: np = nlookup(name, &htp, &fname, newdp != NULL);
41: if (np == NULL || fname != name)
42: return (NONAME);
43: if (odp != NULL) {
44: pdp = NULL;
45: for (dp = np->n_data; dp != NULL; pdp = dp, dp = dp->d_next) {
46: if (!match(dp, odp->d_class, odp->d_type))
47: continue;
48: #ifdef DEBUG
49: if (debug >= 5)
50: fprintf(ddt,"f = %#x, size = %d, %d (%d)\n",
51: flags, odp->d_size, dp->d_size,
52: db_cmp(dp, odp));
53: #endif
54: if ((flags & DB_NODATA) &&
55: !db_cmp(dp, odp)) {
56: /* refresh ttl if cache entry */
57: if (dp->d_zone == 0) {
58: if (dp->d_ttl < tt.tv_sec ) {
59: dp->d_ttl = odp->d_ttl;
60: return (OK);
61: }
62: if (dp->d_ttl < odp->d_ttl)
63: dp->d_ttl = odp->d_ttl;
64: }
65: return (DATAEXISTS);
66: }
67: if ((flags & DB_MEXIST) && db_cmp(dp, odp))
68: return (NODATA);
69: if (flags & DB_DELETE) {
70: if (pdp == NULL)
71: np->n_data = dp->d_next;
72: else
73: pdp->d_next = dp->d_next;
74: rminv(dp);
75: (void) free((char *)dp);
76: }
77: }
78: }
79: if (newdp == NULL)
80: return (OK);
81: addinv(np, newdp); /* modify inverse query tables */
82:
83: /* Add to end of list, generally preserving order */
84: newdp->d_next = NULL;
85: if ((dp = np->n_data) == NULL) {
86: np->n_data = newdp;
87: return (OK);
88: }
89: while (dp->d_next != NULL) {
90: dp = dp->d_next;
91: /* NEEDS: check for duplicate WKS records and flag error */
92: }
93: dp->d_next = newdp;
94: return (OK);
95: }
96:
97: struct invbuf *invtab[INVHASHSZ]; /* Inverse query hash table */
98:
99: /*
100: * Add data 'dp' to inverse query tables for name 'np'.
101: */
102: addinv(np, dp)
103: struct namebuf *np;
104: struct databuf *dp;
105: {
106: register struct invbuf *ip;
107: register int hval, i;
108:
109: switch (dp->d_type) {
110: case T_A:
111: case T_UID:
112: case T_GID:
113: break;
114:
115: default:
116: return;
117: }
118:
119: hval = dhash(dp->d_data, dp->d_size);
120: for (ip = invtab[hval]; ip != NULL; ip = ip->i_next)
121: for (i = 0; i < INVBLKSZ; i++)
122: if (ip->i_dname[i] == NULL) {
123: ip->i_dname[i] = np;
124: return;
125: }
126: ip = saveinv();
127: ip->i_next = invtab[hval];
128: invtab[hval] = ip;
129: ip->i_dname[0] = np;
130: }
131:
132: /*
133: * Remove data 'odp' from inverse query table.
134: */
135: rminv(odp)
136: struct databuf *odp;
137: {
138: register struct invbuf *ip;
139: register struct databuf *dp;
140: struct namebuf *np;
141: register int i;
142:
143: for (ip = invtab[dhash(odp->d_data, odp->d_size)]; ip != NULL;
144: ip = ip->i_next) {
145: for (i = 0; i < INVBLKSZ; i++) {
146: if ((np = ip->i_dname[i]) == NULL)
147: break;
148: for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
149: if (!match(dp, odp->d_class, odp->d_type))
150: continue;
151: if (db_cmp(dp, odp))
152: continue;
153: while (i < INVBLKSZ-1) {
154: ip->i_dname[i] = ip->i_dname[i+1];
155: i++;
156: }
157: ip->i_dname[i] = NULL;
158: return;
159: }
160: }
161: }
162: }
163:
164: /*
165: * Compute hash value from data.
166: */
167: dhash(dp, dlen)
168: char *dp;
169: int dlen;
170: {
171: register char *cp;
172: register unsigned hval;
173: register int n;
174:
175: n = dlen;
176: if (n > 8)
177: n = 8;
178: hval = 0;
179: for (cp = dp; --n >= 0; ) {
180: hval <<= 1;
181: hval += *cp++;
182: }
183: return (hval % INVHASHSZ);
184: }
185:
186: /*
187: * Compare data sections from databufs for equivalence. Must be case
188: * insensitive for some domain names. We assume that they are the
189: * same type when they are passed. Return 0 if equivalent, nonzero
190: * otherwise.
191: */
192:
193: db_cmp(dp1, dp2)
194: register struct databuf *dp1, *dp2;
195:
196: {
197: register char *cp1, *cp2;
198: int len;
199:
200: if (dp1->d_size != dp2->d_size)
201: return(1);
202: switch (dp1->d_type) {
203:
204: case T_A:
205: case T_UID:
206: case T_GID:
207: case T_WKS:
208: case T_NULL:
209: return(bcmp(dp1->d_data, dp2->d_data, dp1->d_size));
210:
211: case T_NS:
212: case T_CNAME:
213: case T_PTR:
214: case T_MB:
215: case T_MG:
216: case T_MR:
217: case T_UINFO:
218: return(cistrcmp(dp1->d_data, dp2->d_data));
219:
220: case T_HINFO:
221: cp1 = dp1->d_data;
222: cp2 = dp2->d_data;
223: len = *cp1;
224: if (cistrncmp(++cp1, ++cp2, len))
225: return(1);
226: cp1 += len;
227: cp2 += len;
228: len = *cp1;
229: return(cistrncmp(++cp1, ++cp2, len));
230:
231: case T_SOA:
232: case T_MINFO:
233: if (cistrcmp(dp1->d_data, dp2->d_data))
234: return(1);
235: cp1 = dp1->d_data + strlen(dp1->d_data) + 1;
236: cp2 = dp2->d_data + strlen(dp2->d_data) + 1;
237: if (dp1->d_type != T_SOA)
238: return(cistrcmp(cp1, cp2));
239: if (cistrcmp(cp1, cp2))
240: return(1);
241: cp1 += strlen(cp1) + 1;
242: cp2 += strlen(cp2) + 1;
243: return(bcmp(cp1, cp2, sizeof(u_long) * 5));
244:
245: case T_MX:
246: cp1 = dp1->d_data;
247: cp2 = dp2->d_data;
248: if (*cp1++ != *cp2++ || *cp1++ != *cp2++) /* cmp prio */
249: return(1);
250: return(cistrcmp(cp1, cp2));
251:
252: default:
253: return (1);
254: }
255: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.