diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 07:24:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 07:24:22 +0000 |
commit | 45d6379135504814ab723b57f0eb8be23393a51d (patch) | |
tree | d4f2ec4acca824a8446387a758b0ce4238a4dffa /bin/tests/optional/db_test.c | |
parent | Initial commit. (diff) | |
download | bind9-upstream.tar.xz bind9-upstream.zip |
Adding upstream version 1:9.16.44.upstream/1%9.16.44upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'bin/tests/optional/db_test.c')
-rw-r--r-- | bin/tests/optional/db_test.c | 983 |
1 files changed, 983 insertions, 0 deletions
diff --git a/bin/tests/optional/db_test.c b/bin/tests/optional/db_test.c new file mode 100644 index 0000000..05bd748 --- /dev/null +++ b/bin/tests/optional/db_test.c @@ -0,0 +1,983 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/*! \file + */ + +#include <inttypes.h> +#include <stdbool.h> +#include <stdlib.h> + +#include <isc/commandline.h> +#include <isc/log.h> +#include <isc/mem.h> +#include <isc/print.h> +#include <isc/string.h> +#include <isc/time.h> +#include <isc/util.h> + +#include <dns/db.h> +#include <dns/dbiterator.h> +#include <dns/dbtable.h> +#include <dns/fixedname.h> +#include <dns/log.h> +#include <dns/rdataset.h> +#include <dns/rdatasetiter.h> +#include <dns/result.h> + +#define MAXHOLD 100 +#define MAXVERSIONS 100 + +typedef struct dbinfo { + dns_db_t *db; + dns_dbversion_t *version; + dns_dbversion_t *wversion; + dns_dbversion_t *rversions[MAXVERSIONS]; + int rcount; + dns_dbnode_t *hold_nodes[MAXHOLD]; + int hold_count; + dns_dbiterator_t *dbiterator; + dns_dbversion_t *iversion; + int pause_every; + bool ascending; + ISC_LINK(struct dbinfo) link; +} dbinfo; + +static isc_mem_t *mctx = NULL; +static char dbtype[128]; +static dns_dbtable_t *dbtable; +static ISC_LIST(dbinfo) dbs; +static dbinfo *cache_dbi = NULL; +static int pause_every = 0; +static bool ascending = true; + +static void +print_result(const char *message, isc_result_t result) { + if (message == NULL) { + message = ""; + } + printf("%s%sresult %08x: %s\n", message, (*message == '\0') ? "" : " ", + result, isc_result_totext(result)); +} + +static void +print_rdataset(dns_name_t *name, dns_rdataset_t *rdataset) { + isc_buffer_t text; + char t[1000]; + isc_result_t result; + isc_region_t r; + + isc_buffer_init(&text, t, sizeof(t)); + result = dns_rdataset_totext(rdataset, name, false, false, &text); + isc_buffer_usedregion(&text, &r); + if (result == ISC_R_SUCCESS) { + printf("%.*s", (int)r.length, (char *)r.base); + } else { + print_result("", result); + } +} + +static void +print_rdatasets(dns_name_t *name, dns_rdatasetiter_t *rdsiter) { + isc_result_t result; + dns_rdataset_t rdataset; + + dns_rdataset_init(&rdataset); + result = dns_rdatasetiter_first(rdsiter); + while (result == ISC_R_SUCCESS) { + dns_rdatasetiter_current(rdsiter, &rdataset); + print_rdataset(name, &rdataset); + dns_rdataset_disassociate(&rdataset); + result = dns_rdatasetiter_next(rdsiter); + } + if (result != ISC_R_NOMORE) { + print_result("", result); + } +} + +static dbinfo * +select_db(char *origintext) { + dns_fixedname_t forigin; + dns_name_t *origin; + isc_buffer_t source; + size_t len; + dbinfo *dbi; + isc_result_t result; + + if (strcasecmp(origintext, "cache") == 0) { + if (cache_dbi == NULL) { + printf("the cache does not exist\n"); + } + return (cache_dbi); + } + len = strlen(origintext); + isc_buffer_init(&source, origintext, len); + isc_buffer_add(&source, len); + origin = dns_fixedname_initname(&forigin); + result = dns_name_fromtext(origin, &source, dns_rootname, 0, NULL); + if (result != ISC_R_SUCCESS) { + print_result("bad name", result); + return (NULL); + } + + for (dbi = ISC_LIST_HEAD(dbs); dbi != NULL; + dbi = ISC_LIST_NEXT(dbi, link)) + { + if (dns_name_compare(dns_db_origin(dbi->db), origin) == 0) { + break; + } + } + + return (dbi); +} + +static void +list(dbinfo *dbi, char *seektext) { + dns_fixedname_t fname; + dns_name_t *name; + dns_dbnode_t *node; + dns_rdatasetiter_t *rdsiter; + isc_result_t result; + int i; + size_t len; + dns_fixedname_t fseekname; + dns_name_t *seekname; + isc_buffer_t source; + + name = dns_fixedname_initname(&fname); + + if (dbi->dbiterator == NULL) { + INSIST(dbi->iversion == NULL); + if (dns_db_iszone(dbi->db)) { + if (dbi->version != NULL) { + dns_db_attachversion(dbi->db, dbi->version, + &dbi->iversion); + } else { + dns_db_currentversion(dbi->db, &dbi->iversion); + } + } + + result = dns_db_createiterator(dbi->db, 0, &dbi->dbiterator); + if (result == ISC_R_SUCCESS) { + if (seektext != NULL) { + len = strlen(seektext); + isc_buffer_init(&source, seektext, len); + isc_buffer_add(&source, len); + seekname = dns_fixedname_initname(&fseekname); + result = dns_name_fromtext( + seekname, &source, + dns_db_origin(dbi->db), 0, NULL); + if (result == ISC_R_SUCCESS) { + result = dns_dbiterator_seek( + dbi->dbiterator, seekname); + } + } else if (dbi->ascending) { + result = dns_dbiterator_first(dbi->dbiterator); + } else { + result = dns_dbiterator_last(dbi->dbiterator); + } + } + } else { + result = ISC_R_SUCCESS; + } + + node = NULL; + rdsiter = NULL; + i = 0; + while (result == ISC_R_SUCCESS) { + result = dns_dbiterator_current(dbi->dbiterator, &node, name); + if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { + break; + } + result = dns_db_allrdatasets(dbi->db, node, dbi->iversion, 0, 0, + &rdsiter); + if (result != ISC_R_SUCCESS) { + dns_db_detachnode(dbi->db, &node); + break; + } + print_rdatasets(name, rdsiter); + dns_rdatasetiter_destroy(&rdsiter); + dns_db_detachnode(dbi->db, &node); + if (dbi->ascending) { + result = dns_dbiterator_next(dbi->dbiterator); + } else { + result = dns_dbiterator_prev(dbi->dbiterator); + } + i++; + if (result == ISC_R_SUCCESS && i == dbi->pause_every) { + printf("[more...]\n"); + result = dns_dbiterator_pause(dbi->dbiterator); + if (result == ISC_R_SUCCESS) { + return; + } + } + } + if (result != ISC_R_NOMORE) { + print_result("", result); + } + + dns_dbiterator_destroy(&dbi->dbiterator); + if (dbi->iversion != NULL) { + dns_db_closeversion(dbi->db, &dbi->iversion, false); + } +} + +static isc_result_t +load(const char *filename, const char *origintext, bool cache) { + dns_fixedname_t forigin; + dns_name_t *origin; + isc_result_t result; + isc_buffer_t source; + size_t len; + dbinfo *dbi; + unsigned int i; + + dbi = isc_mem_get(mctx, sizeof(*dbi)); + + dbi->db = NULL; + dbi->version = NULL; + dbi->wversion = NULL; + for (i = 0; i < MAXVERSIONS; i++) { + dbi->rversions[i] = NULL; + } + dbi->hold_count = 0; + for (i = 0; i < MAXHOLD; i++) { + dbi->hold_nodes[i] = NULL; + } + dbi->dbiterator = NULL; + dbi->iversion = NULL; + dbi->pause_every = pause_every; + dbi->ascending = ascending; + ISC_LINK_INIT(dbi, link); + + len = strlen(origintext); + isc_buffer_constinit(&source, origintext, len); + isc_buffer_add(&source, len); + origin = dns_fixedname_initname(&forigin); + result = dns_name_fromtext(origin, &source, dns_rootname, 0, NULL); + if (result != ISC_R_SUCCESS) { + isc_mem_put(mctx, dbi, sizeof(*dbi)); + return (result); + } + + result = dns_db_create(mctx, dbtype, origin, + cache ? dns_dbtype_cache : dns_dbtype_zone, + dns_rdataclass_in, 0, NULL, &dbi->db); + if (result != ISC_R_SUCCESS) { + isc_mem_put(mctx, dbi, sizeof(*dbi)); + return (result); + } + + printf("loading %s (%s)\n", filename, origintext); + result = dns_db_load(dbi->db, filename, dns_masterformat_text, 0); + if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) { + dns_db_detach(&dbi->db); + isc_mem_put(mctx, dbi, sizeof(*dbi)); + return (result); + } + printf("loaded\n"); + + if (cache) { + INSIST(cache_dbi == NULL); + dns_dbtable_adddefault(dbtable, dbi->db); + cache_dbi = dbi; + } else { + result = dns_dbtable_add(dbtable, dbi->db); + if (result != ISC_R_SUCCESS) { + dns_db_detach(&dbi->db); + isc_mem_put(mctx, dbi, sizeof(*dbi)); + return (result); + } + } + ISC_LIST_APPEND(dbs, dbi, link); + + return (ISC_R_SUCCESS); +} + +static void +unload_all(void) { + dbinfo *dbi, *dbi_next; + + for (dbi = ISC_LIST_HEAD(dbs); dbi != NULL; dbi = dbi_next) { + dbi_next = ISC_LIST_NEXT(dbi, link); + if (dns_db_iszone(dbi->db)) { + dns_dbtable_remove(dbtable, dbi->db); + } else { + INSIST(dbi == cache_dbi); + dns_dbtable_removedefault(dbtable); + cache_dbi = NULL; + } + dns_db_detach(&dbi->db); + ISC_LIST_UNLINK(dbs, dbi, link); + isc_mem_put(mctx, dbi, sizeof(*dbi)); + } +} + +#define DBI_CHECK(dbi) \ + if ((dbi) == NULL) { \ + printf("You must first select a database with !DB\n"); \ + continue; \ + } + +int +main(int argc, char *argv[]) { + dns_db_t *db; + dns_dbnode_t *node; + isc_result_t result; + dns_name_t name; + dns_offsets_t offsets; + size_t len; + isc_buffer_t source, target; + char s[1000]; + char b[255]; + dns_rdataset_t rdataset, sigrdataset; + int ch; + dns_rdatatype_t type = 1; + bool printnode = false; + bool addmode = false; + bool delmode = false; + bool holdmode = false; + bool verbose = false; + bool done = false; + bool quiet = false; + bool time_lookups = false; + bool found_as; + bool find_zonecut = false; + bool noexact_zonecut = false; + int i, v; + dns_rdatasetiter_t *rdsiter; + char t1[256]; + char t2[256]; + isc_buffer_t tb1, tb2; + isc_region_t r1, r2; + dns_fixedname_t foundname; + dns_name_t *fname; + unsigned int options = 0, zcoptions; + isc_time_t start, finish; + const char *origintext; + dbinfo *dbi; + dns_dbversion_t *version; + const dns_name_t *origin; + dns_trust_t trust = 0; + unsigned int addopts; + isc_log_t *lctx = NULL; + size_t n; + + dns_result_register(); + + isc_mem_create(&mctx); + RUNTIME_CHECK(dns_dbtable_create(mctx, dns_rdataclass_in, &dbtable) == + ISC_R_SUCCESS); + + snprintf(dbtype, sizeof(dbtype), "rbt"); + while ((ch = isc_commandline_parse(argc, argv, "c:d:t:z:P:Q:glpqvT")) != + -1) + { + switch (ch) { + case 'c': + result = load(isc_commandline_argument, ".", true); + if (result != ISC_R_SUCCESS) { + printf("cache load(%s) %08x: %s\n", + isc_commandline_argument, result, + isc_result_totext(result)); + } + break; + case 'd': + n = strlcpy(dbtype, isc_commandline_argument, + sizeof(dbtype)); + if (n >= sizeof(dbtype)) { + fprintf(stderr, "bad db type '%s'\n", + isc_commandline_argument); + exit(1); + } + break; + case 'g': + options |= (DNS_DBFIND_GLUEOK | + DNS_DBFIND_VALIDATEGLUE); + break; + case 'l': + isc_log_create(mctx, &lctx, NULL); + isc_log_setcontext(lctx); + dns_log_init(lctx); + dns_log_setcontext(lctx); + break; + case 'q': + quiet = true; + verbose = false; + break; + case 'p': + printnode = true; + break; + case 'P': + pause_every = atoi(isc_commandline_argument); + break; + case 't': + type = atoi(isc_commandline_argument); + break; + case 'T': + time_lookups = true; + break; + case 'v': + verbose = true; + break; + case 'z': + origintext = strrchr(isc_commandline_argument, '/'); + if (origintext == NULL) { + origintext = isc_commandline_argument; + } else { + origintext++; /* Skip '/'. */ + } + result = load(isc_commandline_argument, origintext, + false); + if (result != ISC_R_SUCCESS) { + printf("zone load(%s) %08x: %s\n", + isc_commandline_argument, result, + isc_result_totext(result)); + } + break; + } + } + + argc -= isc_commandline_index; + argv += isc_commandline_index; + POST(argv); + + if (argc != 0) { + printf("ignoring trailing arguments\n"); + } + + /* + * Some final initialization... + */ + fname = dns_fixedname_initname(&foundname); + dbi = NULL; + origin = dns_rootname; + version = NULL; + + if (time_lookups) { + TIME_NOW(&start); + } + + while (!done) { + if (!quiet) { + printf("\n"); + } + if (fgets(s, sizeof(s), stdin) == NULL) { + done = true; + continue; + } + len = strlen(s); + if (len > 0U && s[len - 1] == '\n') { + s[len - 1] = '\0'; + len--; + } + if (verbose && dbi != NULL) { + if (dbi->wversion != NULL) { + printf("future version (%p)\n", dbi->wversion); + } + for (i = 0; i < dbi->rcount; i++) { + if (dbi->rversions[i] != NULL) { + printf("open version %d (%p)\n", i, + dbi->rversions[i]); + } + } + } + dns_name_init(&name, offsets); + if (strcmp(s, "!R") == 0) { + DBI_CHECK(dbi); + if (dbi->rcount == MAXVERSIONS) { + printf("too many open versions\n"); + continue; + } + dns_db_currentversion(dbi->db, + &dbi->rversions[dbi->rcount]); + printf("opened version %d\n", dbi->rcount); + dbi->version = dbi->rversions[dbi->rcount]; + version = dbi->version; + dbi->rcount++; + continue; + } else if (strcmp(s, "!W") == 0) { + DBI_CHECK(dbi); + if (dbi->wversion != NULL) { + printf("using existing future version\n"); + dbi->version = dbi->wversion; + version = dbi->version; + continue; + } + result = dns_db_newversion(dbi->db, &dbi->wversion); + if (result != ISC_R_SUCCESS) { + print_result("", result); + } else { + printf("newversion\n"); + } + dbi->version = dbi->wversion; + version = dbi->version; + continue; + } else if (strcmp(s, "!C") == 0) { + DBI_CHECK(dbi); + addmode = false; + delmode = false; + if (dbi->version == NULL) { + continue; + } + if (dbi->version == dbi->wversion) { + printf("closing future version\n"); + dbi->wversion = NULL; + } else { + for (i = 0; i < dbi->rcount; i++) { + if (dbi->version == dbi->rversions[i]) { + dbi->rversions[i] = NULL; + printf("closing open version " + "%d\n", + i); + break; + } + } + } + dns_db_closeversion(dbi->db, &dbi->version, true); + version = NULL; + continue; + } else if (strcmp(s, "!X") == 0) { + DBI_CHECK(dbi); + addmode = false; + delmode = false; + if (dbi->version == NULL) { + continue; + } + if (dbi->version == dbi->wversion) { + printf("aborting future version\n"); + dbi->wversion = NULL; + } else { + for (i = 0; i < dbi->rcount; i++) { + if (dbi->version == dbi->rversions[i]) { + dbi->rversions[i] = NULL; + printf("closing open version " + "%d\n", + i); + break; + } + } + } + dns_db_closeversion(dbi->db, &dbi->version, false); + version = NULL; + continue; + } else if (strcmp(s, "!A") == 0) { + DBI_CHECK(dbi); + delmode = false; + if (addmode) { + addmode = false; + } else { + addmode = true; + } + printf("addmode = %s\n", addmode ? "TRUE" : "FALSE"); + continue; + } else if (strcmp(s, "!D") == 0) { + DBI_CHECK(dbi); + addmode = false; + if (delmode) { + delmode = false; + } else { + delmode = true; + } + printf("delmode = %s\n", delmode ? "TRUE" : "FALSE"); + continue; + } else if (strcmp(s, "!H") == 0) { + DBI_CHECK(dbi); + if (holdmode) { + holdmode = false; + } else { + holdmode = true; + } + printf("holdmode = %s\n", holdmode ? "TRUE" : "FALSE"); + continue; + } else if (strcmp(s, "!HR") == 0) { + DBI_CHECK(dbi); + for (i = 0; i < dbi->hold_count; i++) { + dns_db_detachnode(dbi->db, &dbi->hold_nodes[i]); + } + dbi->hold_count = 0; + holdmode = false; + printf("held nodes have been detached\n"); + continue; + } else if (strcmp(s, "!VC") == 0) { + DBI_CHECK(dbi); + printf("switching to current version\n"); + dbi->version = NULL; + version = NULL; + continue; + } else if (strstr(s, "!V") == s) { + DBI_CHECK(dbi); + v = atoi(&s[2]); + if (v >= dbi->rcount || v < 0) { + printf("unknown open version %d\n", v); + continue; + } + if (dbi->rversions[v] == NULL) { + printf("version %d is not open\n", v); + continue; + } + printf("switching to open version %d\n", v); + dbi->version = dbi->rversions[v]; + version = dbi->version; + continue; + } else if (strstr(s, "!TR") == s) { + trust = (unsigned int)atoi(&s[3]); + printf("trust level is now %u\n", (unsigned int)trust); + continue; + } else if (strstr(s, "!T") == s) { + type = (unsigned int)atoi(&s[2]); + printf("now searching for type %u\n", type); + continue; + } else if (strcmp(s, "!G") == 0) { + if ((options & DNS_DBFIND_GLUEOK) != 0) { + options &= ~DNS_DBFIND_GLUEOK; + } else { + options |= DNS_DBFIND_GLUEOK; + } + printf("glue ok = %s\n", + ((options & DNS_DBFIND_GLUEOK) != 0) ? "TRUE" + : "FALSE"); + continue; + } else if (strcmp(s, "!GV") == 0) { + if ((options & DNS_DBFIND_VALIDATEGLUE) != 0) { + options &= ~DNS_DBFIND_VALIDATEGLUE; + } else { + options |= DNS_DBFIND_VALIDATEGLUE; + } + printf("validate glue = %s\n", + ((options & DNS_DBFIND_VALIDATEGLUE) != 0) + ? "TRUE" + : "FALSE"); + continue; + } else if (strcmp(s, "!WC") == 0) { + if ((options & DNS_DBFIND_NOWILD) != 0) { + options &= ~DNS_DBFIND_NOWILD; + } else { + options |= DNS_DBFIND_NOWILD; + } + printf("wildcard matching = %s\n", + ((options & DNS_DBFIND_NOWILD) == 0) ? "TRUE" + : "FALSE"); + continue; + } else if (strstr(s, "!LS ") == s) { + DBI_CHECK(dbi); + list(dbi, &s[4]); + continue; + } else if (strcmp(s, "!LS") == 0) { + DBI_CHECK(dbi); + list(dbi, NULL); + continue; + } else if (strstr(s, "!DU ") == s) { + DBI_CHECK(dbi); + result = dns_db_dump(dbi->db, dbi->version, s + 4); + if (result != ISC_R_SUCCESS) { + printf("\n"); + print_result("", result); + } + continue; + } else if (strcmp(s, "!PN") == 0) { + if (printnode) { + printnode = false; + } else { + printnode = true; + } + printf("printnode = %s\n", + printnode ? "TRUE" : "FALSE"); + continue; + } else if (strstr(s, "!P") == s) { + DBI_CHECK(dbi); + v = atoi(&s[2]); + dbi->pause_every = v; + continue; + } else if (strcmp(s, "!+") == 0) { + DBI_CHECK(dbi); + dbi->ascending = true; + continue; + } else if (strcmp(s, "!-") == 0) { + DBI_CHECK(dbi); + dbi->ascending = false; + continue; + } else if (strcmp(s, "!DB") == 0) { + dbi = NULL; + origin = dns_rootname; + version = NULL; + printf("now searching all databases\n"); + continue; + } else if (strncmp(s, "!DB ", 4) == 0) { + dbi = select_db(s + 4); + if (dbi != NULL) { + db = dbi->db; + origin = dns_db_origin(dbi->db); + version = dbi->version; + addmode = false; + delmode = false; + holdmode = false; + } else { + db = NULL; + version = NULL; + origin = dns_rootname; + printf("database not found; " + "now searching all databases\n"); + } + continue; + } else if (strcmp(s, "!ZC") == 0) { + if (find_zonecut) { + find_zonecut = false; + } else { + find_zonecut = true; + } + printf("find_zonecut = %s\n", + find_zonecut ? "TRUE" : "FALSE"); + continue; + } else if (strcmp(s, "!NZ") == 0) { + if (noexact_zonecut) { + noexact_zonecut = false; + } else { + noexact_zonecut = true; + } + printf("noexact_zonecut = %s\n", + noexact_zonecut ? "TRUE" : "FALSE"); + continue; + } + + isc_buffer_init(&source, s, len); + isc_buffer_add(&source, len); + isc_buffer_init(&target, b, sizeof(b)); + result = dns_name_fromtext(&name, &source, origin, 0, &target); + if (result != ISC_R_SUCCESS) { + print_result("bad name: ", result); + continue; + } + + if (dbi == NULL) { + zcoptions = 0; + if (noexact_zonecut) { + zcoptions |= DNS_DBTABLEFIND_NOEXACT; + } + db = NULL; + result = dns_dbtable_find(dbtable, &name, zcoptions, + &db); + if (result != ISC_R_SUCCESS && + result != DNS_R_PARTIALMATCH) + { + if (!quiet) { + printf("\n"); + print_result("", result); + } + continue; + } + isc_buffer_init(&tb1, t1, sizeof(t1)); + result = dns_name_totext(dns_db_origin(db), false, + &tb1); + if (result != ISC_R_SUCCESS) { + printf("\n"); + print_result("", result); + dns_db_detach(&db); + continue; + } + isc_buffer_usedregion(&tb1, &r1); + printf("\ndatabase = %.*s (%s)\n", (int)r1.length, + r1.base, (dns_db_iszone(db)) ? "zone" : "cache"); + } + node = NULL; + dns_rdataset_init(&rdataset); + dns_rdataset_init(&sigrdataset); + + if (find_zonecut && dns_db_iscache(db)) { + zcoptions = options; + if (noexact_zonecut) { + zcoptions |= DNS_DBFIND_NOEXACT; + } + result = dns_db_findzonecut(db, &name, zcoptions, 0, + &node, fname, NULL, + &rdataset, &sigrdataset); + } else { + result = dns_db_find(db, &name, version, type, options, + 0, &node, fname, &rdataset, + &sigrdataset); + } + + if (!quiet) { + if (dbi != NULL) { + printf("\n"); + } + print_result("", result); + } + + found_as = false; + switch (result) { + case ISC_R_SUCCESS: + case DNS_R_GLUE: + case DNS_R_CNAME: + case DNS_R_ZONECUT: + break; + case DNS_R_DNAME: + case DNS_R_DELEGATION: + found_as = true; + break; + case DNS_R_NXRRSET: + if (dns_rdataset_isassociated(&rdataset)) { + break; + } + if (dbi != NULL) { + if (holdmode) { + RUNTIME_CHECK(dbi->hold_count < + MAXHOLD); + dbi->hold_nodes[dbi->hold_count++] = + node; + node = NULL; + } else { + dns_db_detachnode(db, &node); + } + } else { + dns_db_detachnode(db, &node); + dns_db_detach(&db); + } + continue; + case DNS_R_NXDOMAIN: + if (dns_rdataset_isassociated(&rdataset)) { + break; + } + FALLTHROUGH; + default: + if (dbi == NULL) { + dns_db_detach(&db); + } + if (quiet) { + print_result("", result); + } + continue; + } + if (found_as && !quiet) { + isc_buffer_init(&tb1, t1, sizeof(t1)); + isc_buffer_init(&tb2, t2, sizeof(t2)); + result = dns_name_totext(&name, false, &tb1); + if (result != ISC_R_SUCCESS) { + print_result("", result); + dns_db_detachnode(db, &node); + if (dbi == NULL) { + dns_db_detach(&db); + } + continue; + } + result = dns_name_totext(fname, false, &tb2); + if (result != ISC_R_SUCCESS) { + print_result("", result); + dns_db_detachnode(db, &node); + if (dbi == NULL) { + dns_db_detach(&db); + } + continue; + } + isc_buffer_usedregion(&tb1, &r1); + isc_buffer_usedregion(&tb2, &r2); + printf("found %.*s as %.*s\n", (int)r1.length, r1.base, + (int)r2.length, r2.base); + } + + if (printnode) { + dns_db_printnode(db, node, stdout); + } + + if (!found_as && type == dns_rdatatype_any) { + rdsiter = NULL; + result = dns_db_allrdatasets(db, node, version, 0, 0, + &rdsiter); + if (result == ISC_R_SUCCESS) { + if (!quiet) { + print_rdatasets(fname, rdsiter); + } + dns_rdatasetiter_destroy(&rdsiter); + } else { + print_result("", result); + } + } else { + if (!quiet) { + print_rdataset(fname, &rdataset); + } + if (dns_rdataset_isassociated(&sigrdataset)) { + if (!quiet) { + print_rdataset(fname, &sigrdataset); + } + dns_rdataset_disassociate(&sigrdataset); + } + if (dbi != NULL && addmode && !found_as) { + rdataset.ttl++; + rdataset.trust = trust; + if (dns_db_iszone(db)) { + addopts = DNS_DBADD_MERGE; + } else { + addopts = 0; + } + result = dns_db_addrdataset(db, node, version, + 0, &rdataset, + addopts, NULL); + if (result != ISC_R_SUCCESS) { + print_result("", result); + } + if (printnode) { + dns_db_printnode(db, node, stdout); + } + } else if (dbi != NULL && delmode && !found_as) { + result = dns_db_deleterdataset( + db, node, version, type, 0); + if (result != ISC_R_SUCCESS) { + print_result("", result); + } + if (printnode) { + dns_db_printnode(db, node, stdout); + } + } + dns_rdataset_disassociate(&rdataset); + } + + if (dbi != NULL) { + if (holdmode) { + RUNTIME_CHECK(dbi->hold_count < MAXHOLD); + dbi->hold_nodes[dbi->hold_count++] = node; + node = NULL; + } else { + dns_db_detachnode(db, &node); + } + } else { + dns_db_detachnode(db, &node); + dns_db_detach(&db); + } + } + + if (time_lookups) { + uint64_t usec; + + TIME_NOW(&finish); + + usec = isc_time_microdiff(&finish, &start); + + printf("elapsed time: %lu.%06lu seconds\n", + (unsigned long)(usec / 1000000), + (unsigned long)(usec % 1000000)); + } + + unload_all(); + + dns_dbtable_detach(&dbtable); + + if (lctx != NULL) { + isc_log_destroy(&lctx); + } + + if (!quiet) { + isc_mem_stats(mctx, stdout); + } + + return (0); +} |