📄 db_dump.c
字号:
#if !defined(lint) && !defined(SABER)static char sccsid[] = "@(#)db_dump.c 4.33 (Berkeley) 3/3/91";static char rcsid[] = "$Id: db_dump.c,v 4.9.1.2 1993/09/08 00:01:17 vixie Exp $";#endif /* not lint *//* * ++Copyright++ 1986, 1988, 1990 * - * Copyright (c) 1986, 1988, 1990 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * - * --Copyright-- */#include <sys/param.h>#include <sys/stat.h>#include <netinet/in.h>#include <arpa/nameser.h>#include <arpa/inet.h>#include <netdb.h>#include <stdio.h>#include <syslog.h>#include <resolv.h>#include <errno.h>#include "named.h"static int scan_root __P((struct hashbuf *));/* * Dump current cache in a format similar to RFC 883. * * We try to be careful and determine whether the operation succeeded * so that the new cache file can be installed. */voiddoachkpt(){ FILE *fp; char tmpcheckfile[256]; /* nowhere to checkpoint cache... */ if (cache_file == NULL) { dprintf(3, (ddt, "skipping doachkpt (cache_file == NULL)\n")); return; } dprintf(3, (ddt, "doachkpt()\n")); (void) sprintf(tmpcheckfile, "%s.chk", cache_file); if ((fp = fopen(tmpcheckfile, "w")) == NULL) { dprintf(3, (ddt, "doachkpt(can't open %s for write)\n", tmpcheckfile)); return; } (void) gettime(&tt); fprintf(fp, "; Dumped at %s", ctime(&tt.tv_sec)); fflush(fp); if (ferror(fp)) { dprintf(3, (ddt, "doachkpt(write to checkpoint file failed)\n")); return; } if (fcachetab != NULL) { int n = scan_root(hashtab); if (n < MINROOTS) { syslog(LOG_ERR, "%d root hints... (too low)", n); fprintf(fp, "; ---- Root hint cache dump ----\n"); (void) db_dump(fcachetab, fp, DB_Z_CACHE, ""); } } if (hashtab != NULL) { fprintf(fp, "; ---- Cache dump ----\n"); if (db_dump(hashtab, fp, DB_Z_CACHE, "") == NODBFILE) { dprintf(3, (ddt, "doachkpt(checkpoint failed)\n")); (void) my_fclose(fp); return; } } (void) fsync(fileno(fp)); if (my_fclose(fp) == EOF) { return; } if (rename(tmpcheckfile, cache_file)) { dprintf(3, (ddt, "doachkpt(install %s to %s failed, %d)\n", tmpcheckfile, cache_file, errno)); }}/* * What we do is scan the root hint cache to make sure there are at least * MINROOTS root pointers with non-0 TTL's so that the checkpoint will not * lose the root. Failing this, all pointers are written out w/ TTL ~0 * (root pointers timed out and prime_cache() not done or failed). */static intscan_root(htp) struct hashbuf *htp;{ register struct databuf *dp; register struct namebuf *np; struct timeval soon; int roots = 0; dprintf(1, (ddt, "scan_root(0x%x)\n", htp)); /* metric by which we determine whether a root NS pointer is still */ /* valid (will be written out if we do a dump). we also add some */ /* time buffer for safety... */ (void) gettime(&soon); soon.tv_sec += TIMBUF; for (np = htp->h_tab[0]; np != NULL; np = np->n_next) { if (np->n_dname[0] == '\0') { dp = np->n_data; while (dp != NULL) { if (dp->d_type == T_NS && dp->d_ttl > soon.tv_sec) { roots++; if (roots >= MINROOTS) return (roots); } dp = dp->d_next; } } } return (roots);}#ifdef notdefmark_cache(htp, ttl) struct hashbuf *htp; int ttl;{ register struct databuf *dp; register struct namebuf *np; struct namebuf **npp, **nppend; struct timeval soon; dprintf(1, (ddt, "mark_cache()\n")); (void) gettime(&soon); soon.tv_sec += TIMBUF; npp = htp->h_tab; nppend = npp + htp->h_size; while (npp < nppend) { for (np = *npp++; np != NULL; np = np->n_next) { if (np->n_data == NULL) continue; for (dp = np->n_data; dp != NULL; dp = dp->d_next) { if (dp->d_ttl < soon.tv_sec) dp->d_ttl = ttl; } } } npp = htp->h_tab; nppend = npp + htp->h_size; while (npp < nppend) { for (np = *npp++; np != NULL; np = np->n_next) { if (np->n_hash == NULL) continue; mark_cache(np->n_hash, ttl); } }}#endif /* notdef *//* * Dump current data base in a format similar to RFC 883. */voiddoadump(){ FILE *fp; dprintf(3, (ddt, "doadump()\n")); if ((fp = fopen(dumpfile, "w")) == NULL) return; gettime(&tt); fprintf(fp, "; Dumped at %s", ctime(&tt.tv_sec));#ifdef CRED fputs("; Note: Cr=(auth,answer,addtnl,cache) tag only shown for non-auth RR's\n", fp);#endif fputs("; Note: NT=milliseconds for any A RR which we've used as a nameserver\n", fp); fprintf(fp, "; --- Cache & Data ---\n"); if (hashtab != NULL) (void) db_dump(hashtab, fp, DB_Z_ALL, ""); fprintf(fp, "; --- Hints ---\n"); if (fcachetab != NULL) (void) db_dump(fcachetab, fp, DB_Z_ALL, ""); (void) my_fclose(fp);}#ifdef ALLOW_UPDATES/* Create a disk database to back up zones */voidzonedump(zp) register struct zoneinfo *zp;{ FILE *fp; char *fname; struct hashbuf *htp; char *op; struct stat st; /* Only dump zone if there is a cache specified */ if (zp->z_source && *(zp->z_source)) { dprintf(1, (ddt, "zonedump(%s)\n", zp->z_source)); if ((fp = fopen(zp->z_source, "w")) == NULL) return; if (op = strchr(zp->z_origin, '.')) op++; gettime(&tt); htp = hashtab; if (nlookup(zp->z_origin, &htp, &fname, 0) != NULL) { db_dump(htp, fp, zp-zones, (op == NULL ? "" : op)); zp->z_state &= ~Z_CHANGED; /* Checkpointed */ } (void) my_fclose(fp); if (stat(zp->z_source, &st) == 0) zp->z_ftime = st.st_mtime; } else { dprintf(1, (ddt, "zonedump: no zone to dump\n")); }}#endifintdb_dump(htp, fp, zone, origin) int zone; struct hashbuf *htp; FILE *fp; char *origin;{ register struct databuf *dp; register struct namebuf *np; struct namebuf **npp, **nppend; char dname[MAXDNAME]; u_int32_t n; u_int32_t addr; int j, i; register u_char *cp; u_char *end; char *proto, *sep; int found_data, tab, printed_origin = 0; npp = htp->h_tab; nppend = npp + htp->h_size; while (npp < nppend) { for (np = *npp++; np != NULL; np = np->n_next) { if (np->n_data == NULL) continue; /* Blecch - can't tell if there is data here for the * right zone, so can't print name yet */ found_data = 0; /* we want a snapshot in time... */ for (dp = np->n_data; dp != NULL; dp = dp->d_next) { /* Is the data for this zone? */ if (zone != DB_Z_ALL && dp->d_zone != zone) continue; if (dp->d_zone == DB_Z_CACHE && dp->d_ttl <= tt.tv_sec && (dp->d_flags & DB_F_HINT) == 0) continue; if (!printed_origin) { fprintf(fp, "$ORIGIN %s.\n", origin); printed_origin++; } tab = 0;#ifdef NCACHE if (dp->d_rcode == NXDOMAIN || dp->d_rcode == NOERROR_NODATA) { fputc(';', fp); }#endif /*NCACHE*/ if (!found_data) { if (np->n_dname[0] == 0) { if (origin[0] == 0) fprintf(fp, ".\t"); else fprintf(fp, ".%s.\t", origin); /* ??? */ } else fprintf(fp, "%s\t", np->n_dname); if (strlen(np->n_dname) < 8) tab = 1; found_data++; } else { (void) putc('\t', fp); tab = 1; } if (dp->d_zone == DB_Z_CACHE) { if (dp->d_flags & DB_F_HINT && (int32_t)(dp->d_ttl - tt.tv_sec) < DB_ROOT_TIMBUF) fprintf(fp, "%d\t", DB_ROOT_TIMBUF); else fprintf(fp, "%d\t", (int)(dp->d_ttl - tt.tv_sec)); } else if (dp->d_ttl != 0 && dp->d_ttl != zones[dp->d_zone].z_minimum) fprintf(fp, "%d\t", (int)dp->d_ttl); else if (tab) (void) putc('\t', fp); fprintf(fp, "%s\t%s\t", p_class(dp->d_class), p_type(dp->d_type)); cp = (u_char *)dp->d_data; sep = "\t;";#ifdef NCACHE if (dp->d_rcode == NXDOMAIN || dp->d_rcode == NOERROR_NODATA) { fprintf(fp, "%s%s-$", (dp->d_rcode == NXDOMAIN) ?"NXDOMAIN" :"NODATA", sep); goto eoln; }#endif /* * Print type specific data */ switch (dp->d_type) { case T_A: switch (dp->d_class) { case C_IN: case C_HS: GETLONG(n, cp); n = htonl(n); fprintf(fp, "%s", inet_ntoa(*(struct in_addr *)&n)); break; } if (dp->d_nstime) { fprintf(fp, "%sNT=%d", sep, dp->d_nstime); sep = " "; } break; case T_CNAME: case T_MB: case T_MG: case T_MR: case T_PTR: fprintf(fp, "%s.", cp); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -