|
|
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.