static void lookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event) { isc_result_t result; isc_boolean_t want_restart; isc_boolean_t send_event; dns_name_t *name, *fname, *prefix; dns_fixedname_t foundname, fixed; dns_rdata_t rdata = DNS_RDATA_INIT; unsigned int nlabels; int order; dns_namereln_t namereln; dns_rdata_cname_t cname; dns_rdata_dname_t dname; REQUIRE(VALID_LOOKUP(lookup)); LOCK(&lookup->lock); result = ISC_R_SUCCESS; name = dns_fixedname_name(&lookup->name); do { lookup->restarts++; want_restart = ISC_FALSE; send_event = ISC_TRUE; if (event == NULL && !lookup->canceled) { dns_fixedname_init(&foundname); fname = dns_fixedname_name(&foundname); INSIST(!dns_rdataset_isassociated(&lookup->rdataset)); INSIST(!dns_rdataset_isassociated (&lookup->sigrdataset)); /* * If we have restarted then clear the old node. */ if (lookup->event->node != NULL) { INSIST(lookup->event->db != NULL); dns_db_detachnode(lookup->event->db, &lookup->event->node); } if (lookup->event->db != NULL) dns_db_detach(&lookup->event->db); result = view_find(lookup, fname); if (result == ISC_R_NOTFOUND) { /* * We don't know anything about the name. * Launch a fetch. */ if (lookup->event->node != NULL) { INSIST(lookup->event->db != NULL); dns_db_detachnode(lookup->event->db, &lookup->event->node); } if (lookup->event->db != NULL) dns_db_detach(&lookup->event->db); result = start_fetch(lookup); if (result == ISC_R_SUCCESS) send_event = ISC_FALSE; goto done; } } else if (event != NULL) { result = event->result; fname = dns_fixedname_name(&event->foundname); dns_resolver_destroyfetch(&lookup->fetch); INSIST(event->rdataset == &lookup->rdataset); INSIST(event->sigrdataset == &lookup->sigrdataset); } else fname = NULL; /* Silence compiler warning. */ /* * If we've been canceled, forget about the result. */ if (lookup->canceled) result = ISC_R_CANCELED; switch (result) { case ISC_R_SUCCESS: result = build_event(lookup); if (event == NULL) break; if (event->db != NULL) dns_db_attach(event->db, &lookup->event->db); if (event->node != NULL) dns_db_attachnode(lookup->event->db, event->node, &lookup->event->node); break; case DNS_R_CNAME: /* * Copy the CNAME's target into the lookup's * query name and start over. */ result = dns_rdataset_first(&lookup->rdataset); if (result != ISC_R_SUCCESS) break; dns_rdataset_current(&lookup->rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &cname, NULL); dns_rdata_reset(&rdata); if (result != ISC_R_SUCCESS) break; result = dns_name_copy(&cname.cname, name, NULL); dns_rdata_freestruct(&cname); if (result == ISC_R_SUCCESS) { want_restart = ISC_TRUE; send_event = ISC_FALSE; } break; case DNS_R_DNAME: namereln = dns_name_fullcompare(name, fname, &order, &nlabels); INSIST(namereln == dns_namereln_subdomain); /* * Get the target name of the DNAME. */ result = dns_rdataset_first(&lookup->rdataset); if (result != ISC_R_SUCCESS) break; dns_rdataset_current(&lookup->rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &dname, NULL); dns_rdata_reset(&rdata); if (result != ISC_R_SUCCESS) break; /* * Construct the new query name and start over. */ dns_fixedname_init(&fixed); prefix = dns_fixedname_name(&fixed); dns_name_split(name, nlabels, prefix, NULL); result = dns_name_concatenate(prefix, &dname.dname, name, NULL); dns_rdata_freestruct(&dname); if (result == ISC_R_SUCCESS) { want_restart = ISC_TRUE; send_event = ISC_FALSE; } break; default: send_event = ISC_TRUE; } if (dns_rdataset_isassociated(&lookup->rdataset)) dns_rdataset_disassociate(&lookup->rdataset); if (dns_rdataset_isassociated(&lookup->sigrdataset)) dns_rdataset_disassociate(&lookup->sigrdataset); done: if (event != NULL) { if (event->node != NULL) dns_db_detachnode(event->db, &event->node); if (event->db != NULL) dns_db_detach(&event->db); isc_event_free(ISC_EVENT_PTR(&event)); } /* * Limit the number of restarts. */ if (want_restart && lookup->restarts == MAX_RESTARTS) { want_restart = ISC_FALSE; result = ISC_R_QUOTA; send_event = ISC_TRUE; } } while (want_restart); if (send_event) { lookup->event->result = result; lookup->event->ev_sender = lookup; isc_task_sendanddetach(&lookup->task, (isc_event_t **)(void *)&lookup->event); dns_view_detach(&lookup->view); } UNLOCK(&lookup->lock); }
static isc_result_t diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver, isc_boolean_t warn) { dns_difftuple_t *t; dns_dbnode_t *node = NULL; isc_result_t result; char namebuf[DNS_NAME_FORMATSIZE]; char typebuf[DNS_RDATATYPE_FORMATSIZE]; char classbuf[DNS_RDATACLASS_FORMATSIZE]; REQUIRE(DNS_DIFF_VALID(diff)); REQUIRE(DNS_DB_VALID(db)); t = ISC_LIST_HEAD(diff->tuples); while (t != NULL) { dns_name_t *name; INSIST(node == NULL); name = &t->name; /* * Find the node. * We create the node if it does not exist. * This will cause an empty node to be created if the diff * contains a deletion of an RR at a nonexistent name, * but such diffs should never be created in the first * place. */ while (t != NULL && dns_name_equal(&t->name, name)) { dns_rdatatype_t type, covers; dns_diffop_t op; dns_rdatalist_t rdl; dns_rdataset_t rds; dns_rdataset_t ardataset; dns_rdataset_t *modified = NULL; op = t->op; type = t->rdata.type; covers = rdata_covers(&t->rdata); /* * Collect a contiguous set of updates with * the same operation (add/delete) and RR type * into a single rdatalist so that the * database rrset merging/subtraction code * can work more efficiently than if each * RR were merged into / subtracted from * the database separately. * * This is done by linking rdata structures from the * diff into "rdatalist". This uses the rdata link * field, not the diff link field, so the structure * of the diff itself is not affected. */ rdl.type = type; rdl.covers = covers; rdl.rdclass = t->rdata.rdclass; rdl.ttl = t->ttl; ISC_LIST_INIT(rdl.rdata); ISC_LINK_INIT(&rdl, link); node = NULL; if (type != dns_rdatatype_nsec3 && covers != dns_rdatatype_nsec3) CHECK(dns_db_findnode(db, name, ISC_TRUE, &node)); else CHECK(dns_db_findnsec3node(db, name, ISC_TRUE, &node)); while (t != NULL && dns_name_equal(&t->name, name) && t->op == op && t->rdata.type == type && rdata_covers(&t->rdata) == covers) { dns_name_format(name, namebuf, sizeof(namebuf)); dns_rdatatype_format(t->rdata.type, typebuf, sizeof(typebuf)); dns_rdataclass_format(t->rdata.rdclass, classbuf, sizeof(classbuf)); if (t->ttl != rdl.ttl && warn) isc_log_write(DIFF_COMMON_LOGARGS, ISC_LOG_WARNING, "'%s/%s/%s': TTL differs in " "rdataset, adjusting " "%lu -> %lu", namebuf, typebuf, classbuf, (unsigned long) t->ttl, (unsigned long) rdl.ttl); ISC_LIST_APPEND(rdl.rdata, &t->rdata, link); t = ISC_LIST_NEXT(t, link); } /* * Convert the rdatalist into a rdataset. */ dns_rdataset_init(&rds); CHECK(dns_rdatalist_tordataset(&rdl, &rds)); if (rds.type == dns_rdatatype_rrsig) switch (op) { case DNS_DIFFOP_ADDRESIGN: case DNS_DIFFOP_DELRESIGN: modified = &ardataset; dns_rdataset_init(modified); break; default: break; } rds.trust = dns_trust_ultimate; /* * Merge the rdataset into the database. */ switch (op) { case DNS_DIFFOP_ADD: case DNS_DIFFOP_ADDRESIGN: result = dns_db_addrdataset(db, node, ver, 0, &rds, DNS_DBADD_MERGE| DNS_DBADD_EXACT| DNS_DBADD_EXACTTTL, modified); break; case DNS_DIFFOP_DEL: case DNS_DIFFOP_DELRESIGN: result = dns_db_subtractrdataset(db, node, ver, &rds, DNS_DBSUB_EXACT, modified); break; default: INSIST(0); } if (result == ISC_R_SUCCESS) { if (modified != NULL) { isc_stdtime_t resign; resign = setresign(modified, diff->resign); dns_db_setsigningtime(db, modified, resign); if (diff->resign == 0 && (op == DNS_DIFFOP_ADDRESIGN || op == DNS_DIFFOP_DELRESIGN)) isc_log_write( DIFF_COMMON_LOGARGS, ISC_LOG_WARNING, "resign requested " "with 0 resign " "interval"); } } else if (result == DNS_R_UNCHANGED) { /* * This will not happen when executing a * dynamic update, because that code will * generate strictly minimal diffs. * It may happen when receiving an IXFR * from a server that is not as careful. * Issue a warning and continue. */ if (warn) { char classbuf[DNS_RDATATYPE_FORMATSIZE]; char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(dns_db_origin(db), namebuf, sizeof(namebuf)); dns_rdataclass_format(dns_db_class(db), classbuf, sizeof(classbuf)); isc_log_write(DIFF_COMMON_LOGARGS, ISC_LOG_WARNING, "%s/%s: dns_diff_apply: " "update with no effect", namebuf, classbuf); } } else if (result == DNS_R_NXRRSET) { /* * OK. */ } else { if (modified != NULL && dns_rdataset_isassociated(modified)) dns_rdataset_disassociate(modified); CHECK(result); } dns_db_detachnode(db, &node); if (modified != NULL && dns_rdataset_isassociated(modified)) dns_rdataset_disassociate(modified); } } return (ISC_R_SUCCESS); failure: if (node != NULL) dns_db_detachnode(db, &node); return (result); }
int main(int argc, char *argv[]) { char *sql; int res; char *errmsg = NULL; char *porigin, *zonefile; dns_fixedname_t forigin, fname; dns_name_t *origin, *name; dns_db_t *db = NULL; dns_dbiterator_t *dbiter; dns_dbnode_t *node; dns_rdatasetiter_t *rdsiter; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; isc_mem_t *mctx = NULL; isc_entropy_t *ectx = NULL; isc_buffer_t b; isc_result_t result; if (argc != 5) { printf("usage: %s <zone> <zonefile> <dbfile> <dbtable>\n", argv[0]); exit(1); } porigin = argv[1]; zonefile = argv[2]; dbi.filename = argv[3]; dbi.table = argv[4]; dns_result_register(); result = isc_mem_create(0, 0, &mctx); check_result(result, "isc_mem_create"); result = isc_entropy_create(mctx, &ectx); check_result(result, "isc_entropy_create"); result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); check_result(result, "isc_hash_create"); isc_buffer_init(&b, porigin, strlen(porigin)); isc_buffer_add(&b, strlen(porigin)); dns_fixedname_init(&forigin); origin = dns_fixedname_name(&forigin); result = dns_name_fromtext(origin, &b, dns_rootname, 0, NULL); check_result(result, "dns_name_fromtext"); db = NULL; result = dns_db_create(mctx, "rbt", origin, dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &db); check_result(result, "dns_db_create"); result = dns_db_load(db, zonefile); if (result == DNS_R_SEENINCLUDE) result = ISC_R_SUCCESS; check_result(result, "dns_db_load"); printf("Connecting to '%s'\n", dbi.filename); if ((result = db_connect(&dbi)) != ISC_R_SUCCESS) { fprintf(stderr, "Connection to database '%s' failed\n", dbi.filename); closeandexit(1); } sql = sqlite3_mprintf("DROP TABLE %Q ", dbi.table); printf("%s\n", sql); res = sqlite3_exec(dbi.db, sql, NULL, NULL, &errmsg); sqlite3_free(sql); #if 0 if (res != SQLITE_OK) { fprintf(stderr, "DROP TABLE %s failed: %s\n", dbi.table, errmsg); } #endif #if 0 sql = sqlite3_mprintf(sql, "BEGIN TRANSACTION"); printf("%s\n", sql); res = sqlite3_exec(dbi.db, sql, NULL, NULL, &errmsg); sqlite3_free(sql); if (res != SQLITE_OK) { fprintf(stderr, "BEGIN TRANSACTION failed: %s\n", errmsg); closeandexit(1); } #endif sql = sqlite3_mprintf( "CREATE TABLE %Q " "(NAME TEXT, TTL INTEGER, RDTYPE TEXT, RDATA TEXT) ", dbi.table); printf("%s\n", sql); res = sqlite3_exec(dbi.db, sql, NULL, NULL, &errmsg); sqlite3_free(sql); if (res != SQLITE_OK) { fprintf(stderr, "CREATE TABLE %s failed: %s\n", dbi.table, errmsg); closeandexit(1); } dbiter = NULL; result = dns_db_createiterator(db, 0, &dbiter); check_result(result, "dns_db_createiterator()"); result = dns_dbiterator_first(dbiter); check_result(result, "dns_dbiterator_first"); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_rdataset_init(&rdataset); dns_rdata_init(&rdata); while (result == ISC_R_SUCCESS) { node = NULL; result = dns_dbiterator_current(dbiter, &node, name); if (result == ISC_R_NOMORE) break; check_result(result, "dns_dbiterator_current"); rdsiter = NULL; result = dns_db_allrdatasets(db, node, NULL, 0, &rdsiter); check_result(result, "dns_db_allrdatasets"); result = dns_rdatasetiter_first(rdsiter); while (result == ISC_R_SUCCESS) { dns_rdatasetiter_current(rdsiter, &rdataset); result = dns_rdataset_first(&rdataset); check_result(result, "dns_rdataset_first"); while (result == ISC_R_SUCCESS) { dns_rdataset_current(&rdataset, &rdata); addrdata(name, rdataset.ttl, &rdata); dns_rdata_reset(&rdata); result = dns_rdataset_next(&rdataset); } dns_rdataset_disassociate(&rdataset); result = dns_rdatasetiter_next(rdsiter); } dns_rdatasetiter_destroy(&rdsiter); dns_db_detachnode(db, &node); result = dns_dbiterator_next(dbiter); } #if 0 sql = sqlite3_mprintf(sql, "COMMIT TRANSACTION "); printf("%s\n", sql); res = sqlite3_exec(dbi.db, sql, NULL, NULL, &errmsg); sqlite3_free(sql); if (res != SQLITE_OK) { fprintf(stderr, "COMMIT TRANSACTION failed: %s\n", errmsg); closeandexit(1); } #endif dns_dbiterator_destroy(&dbiter); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); closeandexit(0); exit(0); }
int main(int argc, char *argv[]) { isc_mem_t *mctx = NULL; isc_buffer_t b; int n; dns_fixedname_t origin, name; dns_db_t *db = NULL; dns_dbiterator_t *dbiter = NULL; isc_result_t res; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_rdatasetiter_t *rdatasetiter = NULL; dns_rdata_t rdata; DB *bdb; if (argc != 4) usage(*argv); REQUIRE(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); n = strlen(argv[1]); isc_buffer_init(&b, argv[1], n); isc_buffer_add(&b, n); dns_fixedname_init(&origin); REQUIRE(dns_name_fromtext(dns_fixedname_name(&origin), &b, dns_rootname, 0, NULL) == ISC_R_SUCCESS); REQUIRE(dns_db_create(mctx, "rbt", dns_fixedname_name(&origin), dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &db) == ISC_R_SUCCESS); REQUIRE(dns_db_load(db, argv[2]) == ISC_R_SUCCESS); REQUIRE(dns_db_createiterator(db, 0, &dbiter) == ISC_R_SUCCESS); dns_rdataset_init(&rdataset); dns_rdata_init(&rdata); dns_fixedname_init(&name); bdb = bdb_init(argv[3]); for (res = dns_dbiterator_first(dbiter); res == ISC_R_SUCCESS; res = dns_dbiterator_next(dbiter)) { dns_dbiterator_current(dbiter, &node, dns_fixedname_name(&name)); REQUIRE(dns_db_allrdatasets(db, node, NULL, 0, &rdatasetiter) == ISC_R_SUCCESS); for (res = dns_rdatasetiter_first(rdatasetiter); res == ISC_R_SUCCESS; res = dns_rdatasetiter_next(rdatasetiter)) { dns_rdatasetiter_current(rdatasetiter, &rdataset); res = dns_rdataset_first(&rdataset); while (res == ISC_R_SUCCESS) { dns_rdataset_current(&rdataset, &rdata); REQUIRE(bdb_putrdata(bdb, dns_fixedname_name(&name), rdataset.ttl, &rdata) == ISC_R_SUCCESS); dns_rdata_reset(&rdata); res = dns_rdataset_next(&rdataset); } dns_rdataset_disassociate(&rdataset); } dns_rdatasetiter_destroy(&rdatasetiter); dns_db_detachnode(db, &node); } dns_dbiterator_destroy(&dbiter); REQUIRE(bdb_destroy(bdb) == ISC_R_SUCCESS); return 0; }
static void resigned(isc_assertioncallback_t callback) { isc_result_t result; dns_rdataset_t rdataset, added; dns_dbnode_t *node = NULL; dns_rdatalist_t rdatalist; dns_rdata_rrsig_t rrsig; dns_rdata_t rdata = DNS_RDATA_INIT; isc_buffer_t b; unsigned char buf[1024]; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); setup_db(); /* * Create a dummy RRSIG record and set a resigning time. */ dns_rdataset_init(&added); dns_rdataset_init(&rdataset); dns_rdatalist_init(&rdatalist); isc_buffer_init(&b, buf, sizeof(buf)); DNS_RDATACOMMON_INIT(&rrsig, dns_rdatatype_rrsig, dns_rdataclass_in); rrsig.covered = dns_rdatatype_a; rrsig.algorithm = 100; rrsig.labels = 0; rrsig.originalttl = 0; rrsig.timeexpire = 3600; rrsig.timesigned = 0; rrsig.keyid = 0; dns_name_init(&rrsig.signer, NULL); dns_name_clone(dns_rootname, &rrsig.signer); rrsig.siglen = 0; rrsig.signature = NULL; result = dns_rdata_fromstruct(&rdata, dns_rdataclass_in, dns_rdatatype_rrsig, &rrsig, &b); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); rdatalist.rdclass = dns_rdataclass_in; rdatalist.type = dns_rdatatype_rrsig; ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); result = dns_rdatalist_tordataset(&rdatalist, &rdataset); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); rdataset.attributes |= DNS_RDATASETATTR_RESIGN; rdataset.resign = 7200; result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_addrdataset(db1, node, v1, 0, &rdataset, 0, &added); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_db_detachnode(db1, &node); ATF_REQUIRE_EQ(node, NULL); isc_assertion_setcallback(callback); dns_db_resigned(db1, &added, VERSION(callback)); if (callback != NULL) atf_tc_fail("dns_db_resigned did not assert"); dns_rdataset_disassociate(&added); close_db(); dns_test_end(); }
/*% scan the zone for oversize TTLs */ static isc_result_t check_ttls(dns_zone_t *zone, dns_ttl_t maxttl) { isc_result_t result; dns_db_t *db = NULL; dns_dbversion_t *version = NULL; dns_dbnode_t *node = NULL; dns_dbiterator_t *dbiter = NULL; dns_rdatasetiter_t *rdsiter = NULL; dns_rdataset_t rdataset; dns_fixedname_t fname; dns_name_t *name; dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_rdataset_init(&rdataset); CHECK(dns_zone_getdb(zone, &db)); INSIST(db != NULL); CHECK(dns_db_newversion(db, &version)); CHECK(dns_db_createiterator(db, 0, &dbiter)); for (result = dns_dbiterator_first(dbiter); result == ISC_R_SUCCESS; result = dns_dbiterator_next(dbiter)) { result = dns_dbiterator_current(dbiter, &node, name); if (result == DNS_R_NEWORIGIN) result = ISC_R_SUCCESS; CHECK(result); CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsiter)); for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter)) { dns_rdatasetiter_current(rdsiter, &rdataset); if (rdataset.ttl > maxttl) { char nbuf[DNS_NAME_FORMATSIZE]; char tbuf[255]; isc_buffer_t b; isc_region_t r; dns_name_format(name, nbuf, sizeof(nbuf)); isc_buffer_init(&b, tbuf, sizeof(tbuf) - 1); CHECK(dns_rdatatype_totext(rdataset.type, &b)); isc_buffer_usedregion(&b, &r); r.base[r.length] = 0; dns_zone_log(zone, ISC_LOG_ERROR, "%s/%s TTL %d exceeds " "maximum TTL %d", nbuf, tbuf, rdataset.ttl, maxttl); dns_rdataset_disassociate(&rdataset); CHECK(ISC_R_RANGE); } dns_rdataset_disassociate(&rdataset); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; CHECK(result); dns_rdatasetiter_destroy(&rdsiter); dns_db_detachnode(db, &node); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; cleanup: if (node != NULL) dns_db_detachnode(db, &node); if (rdsiter != NULL) dns_rdatasetiter_destroy(&rdsiter); if (dbiter != NULL) dns_dbiterator_destroy(&dbiter); if (version != NULL) dns_db_closeversion(db, &version, ISC_FALSE); if (db != NULL) dns_db_detach(&db); return (result); }
static void nsecify(char *filename) { isc_result_t result; dns_db_t *db; dns_dbversion_t *wversion; dns_dbnode_t *node, *nextnode; char *origintext; dns_fixedname_t fname, fnextname; dns_name_t *name, *nextname, *target; isc_buffer_t b; size_t len; dns_dbiterator_t *dbiter; char newfilename[1024]; dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_fixedname_init(&fnextname); nextname = dns_fixedname_name(&fnextname); origintext = strrchr(filename, '/'); if (origintext == NULL) origintext = filename; else origintext++; /* Skip '/'. */ len = strlen(origintext); isc_buffer_init(&b, origintext, len); isc_buffer_add(&b, len); result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); check_result(result, "dns_name_fromtext()"); db = NULL; result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &db); check_result(result, "dns_db_create()"); result = dns_db_load(db, filename); if (result == DNS_R_SEENINCLUDE) result = ISC_R_SUCCESS; check_result(result, "dns_db_load()"); wversion = NULL; result = dns_db_newversion(db, &wversion); check_result(result, "dns_db_newversion()"); dbiter = NULL; result = dns_db_createiterator(db, 0, &dbiter); check_result(result, "dns_db_createiterator()"); result = dns_dbiterator_first(dbiter); check_result(result, "dns_dbiterator_first()"); node = NULL; result = next_active(db, wversion, dbiter, name, &node); while (result == ISC_R_SUCCESS) { nextnode = NULL; result = dns_dbiterator_next(dbiter); if (result == ISC_R_SUCCESS) result = next_active(db, wversion, dbiter, nextname, &nextnode); if (result == ISC_R_SUCCESS) target = nextname; else if (result == ISC_R_NOMORE) target = dns_db_origin(db); else { target = NULL; /* Make compiler happy. */ fatal("db iteration failed"); } dns_nsec_build(db, wversion, node, target, 3600); /* XXX BEW */ dns_db_detachnode(db, &node); node = nextnode; } if (result != ISC_R_NOMORE) fatal("db iteration failed"); dns_dbiterator_destroy(&dbiter); /* * XXXRTH For now, we don't increment the SOA serial. */ dns_db_closeversion(db, &wversion, ISC_TRUE); len = strlen(filename); if (len + 4 + 1 > sizeof(newfilename)) fatal("filename too long"); sprintf(newfilename, "%s.new", filename); result = dns_db_dump(db, NULL, newfilename); check_result(result, "dns_db_dump"); dns_db_detach(&db); }
static isc_result_t diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver, isc_boolean_t warn) { dns_difftuple_t *t; dns_dbnode_t *node = NULL; isc_result_t result; REQUIRE(DNS_DIFF_VALID(diff)); REQUIRE(DNS_DB_VALID(db)); t = ISC_LIST_HEAD(diff->tuples); while (t != NULL) { dns_name_t *name; INSIST(node == NULL); name = &t->name; /* * Find the node. * We create the node if it does not exist. * This will cause an empty node to be created if the diff * contains a deletion of an RR at a nonexistent name, * but such diffs should never be created in the first * place. */ node = NULL; CHECK(dns_db_findnode(db, name, ISC_TRUE, &node)); while (t != NULL && dns_name_equal(&t->name, name)) { dns_rdatatype_t type, covers; dns_diffop_t op; dns_rdatalist_t rdl; dns_rdataset_t rds; op = t->op; type = t->rdata.type; covers = rdata_covers(&t->rdata); /* * Collect a contiguous set of updates with * the same operation (add/delete) and RR type * into a single rdatalist so that the * database rrset merging/subtraction code * can work more efficiently than if each * RR were merged into / subtracted from * the database separately. * * This is done by linking rdata structures from the * diff into "rdatalist". This uses the rdata link * field, not the diff link field, so the structure * of the diff itself is not affected. */ rdl.type = type; rdl.covers = covers; rdl.rdclass = t->rdata.rdclass; rdl.ttl = t->ttl; ISC_LIST_INIT(rdl.rdata); ISC_LINK_INIT(&rdl, link); while (t != NULL && dns_name_equal(&t->name, name) && t->op == op && t->rdata.type == type && rdata_covers(&t->rdata) == covers) { if (t->ttl != rdl.ttl && warn) isc_log_write(DIFF_COMMON_LOGARGS, ISC_LOG_WARNING, "TTL differs in rdataset, " "adjusting %lu -> %lu", (unsigned long) t->ttl, (unsigned long) rdl.ttl); ISC_LIST_APPEND(rdl.rdata, &t->rdata, link); t = ISC_LIST_NEXT(t, link); } /* * Convert the rdatalist into a rdataset. */ dns_rdataset_init(&rds); CHECK(dns_rdatalist_tordataset(&rdl, &rds)); rds.trust = dns_trust_ultimate; /* * Merge the rdataset into the database. */ if (op == DNS_DIFFOP_ADD) { result = dns_db_addrdataset(db, node, ver, 0, &rds, DNS_DBADD_MERGE| DNS_DBADD_EXACT| DNS_DBADD_EXACTTTL, NULL); } else if (op == DNS_DIFFOP_DEL) { result = dns_db_subtractrdataset(db, node, ver, &rds, DNS_DBSUB_EXACT, NULL); } else { INSIST(0); } if (result == DNS_R_UNCHANGED) { /* * This will not happen when executing a * dynamic update, because that code will * generate strictly minimal diffs. * It may happen when receiving an IXFR * from a server that is not as careful. * Issue a warning and continue. */ if (warn) isc_log_write(DIFF_COMMON_LOGARGS, ISC_LOG_WARNING, "update with no effect"); } else if (result == ISC_R_SUCCESS || result == DNS_R_NXRRSET) { /* * OK. */ } else { CHECK(result); } } dns_db_detachnode(db, &node); } return (ISC_R_SUCCESS); failure: if (node != NULL) dns_db_detachnode(db, &node); return (result); }
int main(int argc, char **argv) { char *porigin, *zonefile; dns_fixedname_t forigin, fname; dns_name_t *origin, *name; dns_db_t *db = NULL; dns_dbiterator_t *dbiter; dns_dbnode_t *node; dns_rdatasetiter_t *rdsiter; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; isc_mem_t *mctx = NULL; isc_entropy_t *ectx = NULL; isc_buffer_t b; isc_result_t result; PGresult *res; if (argc != 5) { printf("usage: %s origin file dbname dbtable\n", argv[0]); printf("Note that dbname must be an existing database.\n"); exit(1); } porigin = argv[1]; zonefile = argv[2]; dbname = argv[3]; dbtable = argv[4]; dns_result_register(); mctx = NULL; result = isc_mem_create(0, 0, &mctx); check_result(result, "isc_mem_create"); result = isc_entropy_create(mctx, &ectx); check_result(result, "isc_entropy_create"); result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); check_result(result, "isc_hash_create"); isc_buffer_init(&b, porigin, strlen(porigin)); isc_buffer_add(&b, strlen(porigin)); dns_fixedname_init(&forigin); origin = dns_fixedname_name(&forigin); result = dns_name_fromtext(origin, &b, dns_rootname, 0, NULL); check_result(result, "dns_name_fromtext"); db = NULL; result = dns_db_create(mctx, "rbt", origin, dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &db); check_result(result, "dns_db_create"); result = dns_db_load(db, zonefile); if (result == DNS_R_SEENINCLUDE) result = ISC_R_SUCCESS; check_result(result, "dns_db_load"); printf("Connecting to '%s'\n", dbname); conn = PQsetdb(NULL, NULL, NULL, NULL, dbname); if (PQstatus(conn) == CONNECTION_BAD) { fprintf(stderr, "Connection to database '%s' failed: %s\n", dbname, PQerrorMessage(conn)); closeandexit(1); } snprintf(str, sizeof(str), "DROP TABLE %s", dbtable); printf("%s\n", str); res = PQexec(conn, str); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) fprintf(stderr, "DROP TABLE command failed: %s\n", PQresultErrorMessage(res)); PQclear(res); snprintf(str, sizeof(str), "BEGIN"); printf("%s\n", str); res = PQexec(conn, str); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "BEGIN command failed: %s\n", PQresultErrorMessage(res)); PQclear(res); closeandexit(1); } PQclear(res); snprintf(str, sizeof(str), "CREATE TABLE %s " "(NAME TEXT, TTL INTEGER, RDTYPE TEXT, RDATA TEXT)", dbtable); printf("%s\n", str); res = PQexec(conn, str); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "CREATE TABLE command failed: %s\n", PQresultErrorMessage(res)); PQclear(res); closeandexit(1); } PQclear(res); dbiter = NULL; result = dns_db_createiterator(db, 0, &dbiter); check_result(result, "dns_db_createiterator()"); result = dns_dbiterator_first(dbiter); check_result(result, "dns_dbiterator_first"); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_rdataset_init(&rdataset); dns_rdata_init(&rdata); while (result == ISC_R_SUCCESS) { node = NULL; result = dns_dbiterator_current(dbiter, &node, name); if (result == ISC_R_NOMORE) break; check_result(result, "dns_dbiterator_current"); rdsiter = NULL; result = dns_db_allrdatasets(db, node, NULL, 0, &rdsiter); check_result(result, "dns_db_allrdatasets"); result = dns_rdatasetiter_first(rdsiter); while (result == ISC_R_SUCCESS) { dns_rdatasetiter_current(rdsiter, &rdataset); result = dns_rdataset_first(&rdataset); check_result(result, "dns_rdataset_first"); while (result == ISC_R_SUCCESS) { dns_rdataset_current(&rdataset, &rdata); addrdata(name, rdataset.ttl, &rdata); dns_rdata_reset(&rdata); result = dns_rdataset_next(&rdataset); } dns_rdataset_disassociate(&rdataset); result = dns_rdatasetiter_next(rdsiter); } dns_rdatasetiter_destroy(&rdsiter); dns_db_detachnode(db, &node); result = dns_dbiterator_next(dbiter); } snprintf(str, sizeof(str), "COMMIT TRANSACTION"); printf("%s\n", str); res = PQexec(conn, str); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "COMMIT command failed: %s\n", PQresultErrorMessage(res)); PQclear(res); closeandexit(1); } PQclear(res); dns_dbiterator_destroy(&dbiter); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); closeandexit(0); exit(0); }
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; isc_boolean_t printnode = ISC_FALSE; isc_boolean_t addmode = ISC_FALSE; isc_boolean_t delmode = ISC_FALSE; isc_boolean_t holdmode = ISC_FALSE; isc_boolean_t verbose = ISC_FALSE; isc_boolean_t done = ISC_FALSE; isc_boolean_t quiet = ISC_FALSE; isc_boolean_t time_lookups = ISC_FALSE; isc_boolean_t found_as; isc_boolean_t find_zonecut = ISC_FALSE; isc_boolean_t noexact_zonecut = ISC_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; dns_name_t *origin; size_t memory_quota = 0; dns_trust_t trust = 0; unsigned int addopts; isc_log_t *lctx = NULL; size_t n; dns_result_register(); RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); RUNTIME_CHECK(dns_dbtable_create(mctx, dns_rdataclass_in, &dbtable) == ISC_R_SUCCESS); strcpy(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, ".", ISC_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': RUNTIME_CHECK(isc_log_create(mctx, &lctx, NULL) == ISC_R_SUCCESS); isc_log_setcontext(lctx); dns_log_init(lctx); dns_log_setcontext(lctx); break; case 'q': quiet = ISC_TRUE; verbose = ISC_FALSE; break; case 'p': printnode = ISC_TRUE; break; case 'P': pause_every = atoi(isc_commandline_argument); break; case 'Q': memory_quota = atoi(isc_commandline_argument); isc_mem_setquota(mctx, memory_quota); break; case 't': type = atoi(isc_commandline_argument); break; case 'T': time_lookups = ISC_TRUE; break; case 'v': verbose = ISC_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, ISC_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... */ dns_fixedname_init(&foundname); fname = dns_fixedname_name(&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 = ISC_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 = ISC_FALSE; delmode = ISC_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, ISC_TRUE); version = NULL; continue; } else if (strcmp(s, "!X") == 0) { DBI_CHECK(dbi); addmode = ISC_FALSE; delmode = ISC_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, ISC_FALSE); version = NULL; continue; } else if (strcmp(s, "!A") == 0) { DBI_CHECK(dbi); delmode = ISC_FALSE; if (addmode) addmode = ISC_FALSE; else addmode = ISC_TRUE; printf("addmode = %s\n", addmode ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!D") == 0) { DBI_CHECK(dbi); addmode = ISC_FALSE; if (delmode) delmode = ISC_FALSE; else delmode = ISC_TRUE; printf("delmode = %s\n", delmode ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!H") == 0) { DBI_CHECK(dbi); if (holdmode) holdmode = ISC_FALSE; else holdmode = ISC_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 = ISC_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 = ISC_FALSE; else printnode = ISC_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 = ISC_TRUE; continue; } else if (strcmp(s, "!-") == 0) { DBI_CHECK(dbi); dbi->ascending = ISC_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 = ISC_FALSE; delmode = ISC_FALSE; holdmode = ISC_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 = ISC_FALSE; else find_zonecut = ISC_TRUE; printf("find_zonecut = %s\n", find_zonecut ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!NZ") == 0) { if (noexact_zonecut) noexact_zonecut = ISC_FALSE; else noexact_zonecut = ISC_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), ISC_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, &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 = ISC_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 = ISC_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, ISC_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, ISC_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, &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) { isc_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); }
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; dns_fixedname_init(&fname); name = dns_fixedname_name(&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); dns_fixedname_init(&fseekname); seekname = dns_fixedname_name(&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, &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, ISC_FALSE); }