static char sccsid
[] = "@(#)db_update.c 4.3 (Berkeley) 5/30/86";
* Copyright (c) 1986 Regents of the University of California
#include <arpa/nameser.h>
* Update data base. Flags control the action.
* Inverse query tables modified.
db_update(name
, odp
, newdp
, flags
)
struct databuf
*odp
, *newdp
;
register struct namebuf
*np
;
register struct databuf
*dp
, *pdp
;
struct hashbuf
*htp
= hashtab
;
fprintf(ddt
,"db_update( %s )\n",name
);
np
= nlookup(name
, &htp
, &fname
, newdp
!= NULL
);
if (np
== NULL
|| fname
!= name
)
for (dp
= np
->n_data
; dp
!= NULL
; pdp
= dp
, dp
= dp
->d_next
) {
if (!match(dp
, odp
->d_class
, odp
->d_type
))
fprintf(ddt
,"f = %#x, size = %d, %d (%d)\n",
flags
, odp
->d_size
, dp
->d_size
,
if ((flags
& DB_NODATA
) &&
/* refresh ttl if cache entry */
if (dp
->d_ttl
< tt
.tv_sec
) {
if (dp
->d_ttl
< odp
->d_ttl
)
if ((flags
& DB_MEXIST
) && db_cmp(dp
, odp
))
pdp
->d_next
= dp
->d_next
;
addinv(np
, newdp
); /* modify inverse query tables */
/* Add to end of list, generally preserving order */
if ((dp
= np
->n_data
) == NULL
) {
while (dp
->d_next
!= NULL
) {
/* NEEDS: check for duplicate WKS records and flag error */
struct invbuf
*invtab
[INVHASHSZ
]; /* Inverse query hash table */
* Add data 'dp' to inverse query tables for name 'np'.
register struct invbuf
*ip
;
hval
= dhash(dp
->d_data
, dp
->d_size
);
for (ip
= invtab
[hval
]; ip
!= NULL
; ip
= ip
->i_next
)
for (i
= 0; i
< INVBLKSZ
; i
++)
if (ip
->i_dname
[i
] == NULL
) {
ip
->i_next
= invtab
[hval
];
* Remove data 'odp' from inverse query table.
register struct invbuf
*ip
;
register struct databuf
*dp
;
for (ip
= invtab
[dhash(odp
->d_data
, odp
->d_size
)]; ip
!= NULL
;
for (i
= 0; i
< INVBLKSZ
; i
++) {
if ((np
= ip
->i_dname
[i
]) == NULL
)
for (dp
= np
->n_data
; dp
!= NULL
; dp
= dp
->d_next
) {
if (!match(dp
, odp
->d_class
, odp
->d_type
))
ip
->i_dname
[i
] = ip
->i_dname
[i
+1];
* Compute hash value from data.
for (cp
= dp
; --n
>= 0; ) {
return (hval
% INVHASHSZ
);
* Compare data sections from databufs for equivalence. Must be case
* insensitive for some domain names. We assume that they are the
* same type when they are passed. Return 0 if equivalent, nonzero
register struct databuf
*dp1
, *dp2
;
register char *cp1
, *cp2
;
if (dp1
->d_size
!= dp2
->d_size
)
return(bcmp(dp1
->d_data
, dp2
->d_data
, dp1
->d_size
));
return(cistrcmp(dp1
->d_data
, dp2
->d_data
));
if (cistrncmp(++cp1
, ++cp2
, len
))
return(cistrncmp(++cp1
, ++cp2
, len
));
if (cistrcmp(dp1
->d_data
, dp2
->d_data
))
cp1
= dp1
->d_data
+ strlen(dp1
->d_data
) + 1;
cp2
= dp2
->d_data
+ strlen(dp2
->d_data
) + 1;
if (dp1
->d_type
!= T_SOA
)
return(cistrcmp(cp1
, cp2
));
return(bcmp(cp1
, cp2
, sizeof(u_long
) * 5));
if (*cp1
++ != *cp2
++ || *cp1
++ != *cp2
++) /* cmp prio */
return(cistrcmp(cp1
, cp2
));