xref: /minix3/external/bsd/bind/dist/bin/tests/db_test.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: db_test.c,v 1.7 2014/12/10 04:37:53 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2004, 2005, 2007-2009, 2011-2013  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Copyright (C) 1999-2001  Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek  *
7*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek  *
11*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek  */
19*00b67f09SDavid van Moolenbroek 
20*00b67f09SDavid van Moolenbroek /* Id: db_test.c,v 1.70 2011/08/29 23:46:44 tbox Exp  */
21*00b67f09SDavid van Moolenbroek 
22*00b67f09SDavid van Moolenbroek /*! \file
23*00b67f09SDavid van Moolenbroek  * \author
24*00b67f09SDavid van Moolenbroek  * Principal Author: Bob Halley
25*00b67f09SDavid van Moolenbroek  */
26*00b67f09SDavid van Moolenbroek 
27*00b67f09SDavid van Moolenbroek #include <config.h>
28*00b67f09SDavid van Moolenbroek 
29*00b67f09SDavid van Moolenbroek #include <stdlib.h>
30*00b67f09SDavid van Moolenbroek 
31*00b67f09SDavid van Moolenbroek #include <isc/commandline.h>
32*00b67f09SDavid van Moolenbroek #include <isc/log.h>
33*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
34*00b67f09SDavid van Moolenbroek #include <isc/time.h>
35*00b67f09SDavid van Moolenbroek #include <isc/string.h>
36*00b67f09SDavid van Moolenbroek #include <isc/util.h>
37*00b67f09SDavid van Moolenbroek 
38*00b67f09SDavid van Moolenbroek #include <dns/db.h>
39*00b67f09SDavid van Moolenbroek #include <dns/dbiterator.h>
40*00b67f09SDavid van Moolenbroek #include <dns/dbtable.h>
41*00b67f09SDavid van Moolenbroek #include <dns/fixedname.h>
42*00b67f09SDavid van Moolenbroek #include <dns/log.h>
43*00b67f09SDavid van Moolenbroek #include <dns/rdataset.h>
44*00b67f09SDavid van Moolenbroek #include <dns/rdatasetiter.h>
45*00b67f09SDavid van Moolenbroek #include <dns/result.h>
46*00b67f09SDavid van Moolenbroek 
47*00b67f09SDavid van Moolenbroek #define MAXHOLD			100
48*00b67f09SDavid van Moolenbroek #define MAXVERSIONS		100
49*00b67f09SDavid van Moolenbroek 
50*00b67f09SDavid van Moolenbroek typedef struct dbinfo {
51*00b67f09SDavid van Moolenbroek 	dns_db_t *		db;
52*00b67f09SDavid van Moolenbroek 	dns_dbversion_t *	version;
53*00b67f09SDavid van Moolenbroek 	dns_dbversion_t *	wversion;
54*00b67f09SDavid van Moolenbroek 	dns_dbversion_t *	rversions[MAXVERSIONS];
55*00b67f09SDavid van Moolenbroek 	int			rcount;
56*00b67f09SDavid van Moolenbroek 	dns_dbnode_t *		hold_nodes[MAXHOLD];
57*00b67f09SDavid van Moolenbroek 	int			hold_count;
58*00b67f09SDavid van Moolenbroek 	dns_dbiterator_t *	dbiterator;
59*00b67f09SDavid van Moolenbroek 	dns_dbversion_t *	iversion;
60*00b67f09SDavid van Moolenbroek 	int			pause_every;
61*00b67f09SDavid van Moolenbroek 	isc_boolean_t		ascending;
62*00b67f09SDavid van Moolenbroek 	ISC_LINK(struct dbinfo)	link;
63*00b67f09SDavid van Moolenbroek } dbinfo;
64*00b67f09SDavid van Moolenbroek 
65*00b67f09SDavid van Moolenbroek static isc_mem_t *		mctx = NULL;
66*00b67f09SDavid van Moolenbroek static char			dbtype[128];
67*00b67f09SDavid van Moolenbroek static dns_dbtable_t *		dbtable;
68*00b67f09SDavid van Moolenbroek static ISC_LIST(dbinfo)		dbs;
69*00b67f09SDavid van Moolenbroek static dbinfo *			cache_dbi = NULL;
70*00b67f09SDavid van Moolenbroek static int			pause_every = 0;
71*00b67f09SDavid van Moolenbroek static isc_boolean_t		ascending = ISC_TRUE;
72*00b67f09SDavid van Moolenbroek 
73*00b67f09SDavid van Moolenbroek static void
print_result(const char * message,isc_result_t result)74*00b67f09SDavid van Moolenbroek print_result(const char *message, isc_result_t result) {
75*00b67f09SDavid van Moolenbroek 
76*00b67f09SDavid van Moolenbroek 	if (message == NULL)
77*00b67f09SDavid van Moolenbroek 		message = "";
78*00b67f09SDavid van Moolenbroek 	printf("%s%sresult %08x: %s\n", message, (*message == '\0') ? "" : " ",
79*00b67f09SDavid van Moolenbroek 	       result, isc_result_totext(result));
80*00b67f09SDavid van Moolenbroek }
81*00b67f09SDavid van Moolenbroek 
82*00b67f09SDavid van Moolenbroek static void
print_rdataset(dns_name_t * name,dns_rdataset_t * rdataset)83*00b67f09SDavid van Moolenbroek print_rdataset(dns_name_t *name, dns_rdataset_t *rdataset) {
84*00b67f09SDavid van Moolenbroek 	isc_buffer_t text;
85*00b67f09SDavid van Moolenbroek 	char t[1000];
86*00b67f09SDavid van Moolenbroek 	isc_result_t result;
87*00b67f09SDavid van Moolenbroek 	isc_region_t r;
88*00b67f09SDavid van Moolenbroek 
89*00b67f09SDavid van Moolenbroek 	isc_buffer_init(&text, t, sizeof(t));
90*00b67f09SDavid van Moolenbroek 	result = dns_rdataset_totext(rdataset, name, ISC_FALSE, ISC_FALSE,
91*00b67f09SDavid van Moolenbroek 				     &text);
92*00b67f09SDavid van Moolenbroek 	isc_buffer_usedregion(&text, &r);
93*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS)
94*00b67f09SDavid van Moolenbroek 		printf("%.*s", (int)r.length, (char *)r.base);
95*00b67f09SDavid van Moolenbroek 	else
96*00b67f09SDavid van Moolenbroek 		print_result("", result);
97*00b67f09SDavid van Moolenbroek }
98*00b67f09SDavid van Moolenbroek 
99*00b67f09SDavid van Moolenbroek static void
print_rdatasets(dns_name_t * name,dns_rdatasetiter_t * rdsiter)100*00b67f09SDavid van Moolenbroek print_rdatasets(dns_name_t *name, dns_rdatasetiter_t *rdsiter) {
101*00b67f09SDavid van Moolenbroek 	isc_result_t result;
102*00b67f09SDavid van Moolenbroek 	dns_rdataset_t rdataset;
103*00b67f09SDavid van Moolenbroek 
104*00b67f09SDavid van Moolenbroek 	dns_rdataset_init(&rdataset);
105*00b67f09SDavid van Moolenbroek 	result = dns_rdatasetiter_first(rdsiter);
106*00b67f09SDavid van Moolenbroek 	while (result == ISC_R_SUCCESS) {
107*00b67f09SDavid van Moolenbroek 		dns_rdatasetiter_current(rdsiter, &rdataset);
108*00b67f09SDavid van Moolenbroek 		print_rdataset(name, &rdataset);
109*00b67f09SDavid van Moolenbroek 		dns_rdataset_disassociate(&rdataset);
110*00b67f09SDavid van Moolenbroek 		result = dns_rdatasetiter_next(rdsiter);
111*00b67f09SDavid van Moolenbroek 	}
112*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_NOMORE)
113*00b67f09SDavid van Moolenbroek 		print_result("", result);
114*00b67f09SDavid van Moolenbroek }
115*00b67f09SDavid van Moolenbroek 
116*00b67f09SDavid van Moolenbroek static dbinfo *
select_db(char * origintext)117*00b67f09SDavid van Moolenbroek select_db(char *origintext) {
118*00b67f09SDavid van Moolenbroek 	dns_fixedname_t forigin;
119*00b67f09SDavid van Moolenbroek 	dns_name_t *origin;
120*00b67f09SDavid van Moolenbroek 	isc_buffer_t source;
121*00b67f09SDavid van Moolenbroek 	size_t len;
122*00b67f09SDavid van Moolenbroek 	dbinfo *dbi;
123*00b67f09SDavid van Moolenbroek 	isc_result_t result;
124*00b67f09SDavid van Moolenbroek 
125*00b67f09SDavid van Moolenbroek 	if (strcasecmp(origintext, "cache") == 0) {
126*00b67f09SDavid van Moolenbroek 		if (cache_dbi == NULL)
127*00b67f09SDavid van Moolenbroek 			printf("the cache does not exist\n");
128*00b67f09SDavid van Moolenbroek 		return (cache_dbi);
129*00b67f09SDavid van Moolenbroek 	}
130*00b67f09SDavid van Moolenbroek 	len = strlen(origintext);
131*00b67f09SDavid van Moolenbroek 	isc_buffer_init(&source, origintext, len);
132*00b67f09SDavid van Moolenbroek 	isc_buffer_add(&source, len);
133*00b67f09SDavid van Moolenbroek 	dns_fixedname_init(&forigin);
134*00b67f09SDavid van Moolenbroek 	origin = dns_fixedname_name(&forigin);
135*00b67f09SDavid van Moolenbroek 	result = dns_name_fromtext(origin, &source, dns_rootname, 0, NULL);
136*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) {
137*00b67f09SDavid van Moolenbroek 		print_result("bad name", result);
138*00b67f09SDavid van Moolenbroek 		return (NULL);
139*00b67f09SDavid van Moolenbroek 	}
140*00b67f09SDavid van Moolenbroek 
141*00b67f09SDavid van Moolenbroek 	for (dbi = ISC_LIST_HEAD(dbs);
142*00b67f09SDavid van Moolenbroek 	     dbi != NULL;
143*00b67f09SDavid van Moolenbroek 	     dbi = ISC_LIST_NEXT(dbi, link)) {
144*00b67f09SDavid van Moolenbroek 		if (dns_name_compare(dns_db_origin(dbi->db), origin) == 0)
145*00b67f09SDavid van Moolenbroek 			break;
146*00b67f09SDavid van Moolenbroek 	}
147*00b67f09SDavid van Moolenbroek 
148*00b67f09SDavid van Moolenbroek 	return (dbi);
149*00b67f09SDavid van Moolenbroek }
150*00b67f09SDavid van Moolenbroek 
151*00b67f09SDavid van Moolenbroek static void
list(dbinfo * dbi,char * seektext)152*00b67f09SDavid van Moolenbroek list(dbinfo *dbi, char *seektext) {
153*00b67f09SDavid van Moolenbroek 	dns_fixedname_t fname;
154*00b67f09SDavid van Moolenbroek 	dns_name_t *name;
155*00b67f09SDavid van Moolenbroek 	dns_dbnode_t *node;
156*00b67f09SDavid van Moolenbroek 	dns_rdatasetiter_t *rdsiter;
157*00b67f09SDavid van Moolenbroek 	isc_result_t result;
158*00b67f09SDavid van Moolenbroek 	int i;
159*00b67f09SDavid van Moolenbroek 	size_t len;
160*00b67f09SDavid van Moolenbroek 	dns_fixedname_t fseekname;
161*00b67f09SDavid van Moolenbroek 	dns_name_t *seekname;
162*00b67f09SDavid van Moolenbroek 	isc_buffer_t source;
163*00b67f09SDavid van Moolenbroek 
164*00b67f09SDavid van Moolenbroek 	dns_fixedname_init(&fname);
165*00b67f09SDavid van Moolenbroek 	name = dns_fixedname_name(&fname);
166*00b67f09SDavid van Moolenbroek 
167*00b67f09SDavid van Moolenbroek 	if (dbi->dbiterator == NULL) {
168*00b67f09SDavid van Moolenbroek 		INSIST(dbi->iversion == NULL);
169*00b67f09SDavid van Moolenbroek 		if (dns_db_iszone(dbi->db)) {
170*00b67f09SDavid van Moolenbroek 			if (dbi->version != NULL)
171*00b67f09SDavid van Moolenbroek 				dns_db_attachversion(dbi->db, dbi->version,
172*00b67f09SDavid van Moolenbroek 						     &dbi->iversion);
173*00b67f09SDavid van Moolenbroek 			else
174*00b67f09SDavid van Moolenbroek 				dns_db_currentversion(dbi->db, &dbi->iversion);
175*00b67f09SDavid van Moolenbroek 		}
176*00b67f09SDavid van Moolenbroek 
177*00b67f09SDavid van Moolenbroek 		result = dns_db_createiterator(dbi->db, 0, &dbi->dbiterator);
178*00b67f09SDavid van Moolenbroek 		if (result == ISC_R_SUCCESS) {
179*00b67f09SDavid van Moolenbroek 			if (seektext != NULL) {
180*00b67f09SDavid van Moolenbroek 				len = strlen(seektext);
181*00b67f09SDavid van Moolenbroek 				isc_buffer_init(&source, seektext, len);
182*00b67f09SDavid van Moolenbroek 				isc_buffer_add(&source, len);
183*00b67f09SDavid van Moolenbroek 				dns_fixedname_init(&fseekname);
184*00b67f09SDavid van Moolenbroek 				seekname = dns_fixedname_name(&fseekname);
185*00b67f09SDavid van Moolenbroek 				result = dns_name_fromtext(seekname, &source,
186*00b67f09SDavid van Moolenbroek 							   dns_db_origin(
187*00b67f09SDavid van Moolenbroek 								 dbi->db),
188*00b67f09SDavid van Moolenbroek 							   0, NULL);
189*00b67f09SDavid van Moolenbroek 				if (result == ISC_R_SUCCESS)
190*00b67f09SDavid van Moolenbroek 					result = dns_dbiterator_seek(
191*00b67f09SDavid van Moolenbroek 							     dbi->dbiterator,
192*00b67f09SDavid van Moolenbroek 							     seekname);
193*00b67f09SDavid van Moolenbroek 			} else if (dbi->ascending)
194*00b67f09SDavid van Moolenbroek 				result = dns_dbiterator_first(dbi->dbiterator);
195*00b67f09SDavid van Moolenbroek 			else
196*00b67f09SDavid van Moolenbroek 				result = dns_dbiterator_last(dbi->dbiterator);
197*00b67f09SDavid van Moolenbroek 		}
198*00b67f09SDavid van Moolenbroek 	} else
199*00b67f09SDavid van Moolenbroek 		result = ISC_R_SUCCESS;
200*00b67f09SDavid van Moolenbroek 
201*00b67f09SDavid van Moolenbroek 	node = NULL;
202*00b67f09SDavid van Moolenbroek 	rdsiter = NULL;
203*00b67f09SDavid van Moolenbroek 	i = 0;
204*00b67f09SDavid van Moolenbroek 	while (result == ISC_R_SUCCESS) {
205*00b67f09SDavid van Moolenbroek 		result = dns_dbiterator_current(dbi->dbiterator, &node, name);
206*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN)
207*00b67f09SDavid van Moolenbroek 			break;
208*00b67f09SDavid van Moolenbroek 		result = dns_db_allrdatasets(dbi->db, node, dbi->iversion, 0,
209*00b67f09SDavid van Moolenbroek 					     &rdsiter);
210*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS) {
211*00b67f09SDavid van Moolenbroek 			dns_db_detachnode(dbi->db, &node);
212*00b67f09SDavid van Moolenbroek 			break;
213*00b67f09SDavid van Moolenbroek 		}
214*00b67f09SDavid van Moolenbroek 		print_rdatasets(name, rdsiter);
215*00b67f09SDavid van Moolenbroek 		dns_rdatasetiter_destroy(&rdsiter);
216*00b67f09SDavid van Moolenbroek 		dns_db_detachnode(dbi->db, &node);
217*00b67f09SDavid van Moolenbroek 		if (dbi->ascending)
218*00b67f09SDavid van Moolenbroek 			result = dns_dbiterator_next(dbi->dbiterator);
219*00b67f09SDavid van Moolenbroek 		else
220*00b67f09SDavid van Moolenbroek 			result = dns_dbiterator_prev(dbi->dbiterator);
221*00b67f09SDavid van Moolenbroek 		i++;
222*00b67f09SDavid van Moolenbroek 		if (result == ISC_R_SUCCESS && i == dbi->pause_every) {
223*00b67f09SDavid van Moolenbroek 			printf("[more...]\n");
224*00b67f09SDavid van Moolenbroek 			result = dns_dbiterator_pause(dbi->dbiterator);
225*00b67f09SDavid van Moolenbroek 			if (result == ISC_R_SUCCESS)
226*00b67f09SDavid van Moolenbroek 				return;
227*00b67f09SDavid van Moolenbroek 		}
228*00b67f09SDavid van Moolenbroek 	}
229*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_NOMORE)
230*00b67f09SDavid van Moolenbroek 		print_result("", result);
231*00b67f09SDavid van Moolenbroek 
232*00b67f09SDavid van Moolenbroek 	dns_dbiterator_destroy(&dbi->dbiterator);
233*00b67f09SDavid van Moolenbroek 	if (dbi->iversion != NULL)
234*00b67f09SDavid van Moolenbroek 		dns_db_closeversion(dbi->db, &dbi->iversion, ISC_FALSE);
235*00b67f09SDavid van Moolenbroek }
236*00b67f09SDavid van Moolenbroek 
237*00b67f09SDavid van Moolenbroek static isc_result_t
load(const char * filename,const char * origintext,isc_boolean_t cache)238*00b67f09SDavid van Moolenbroek load(const char *filename, const char *origintext, isc_boolean_t cache) {
239*00b67f09SDavid van Moolenbroek 	dns_fixedname_t forigin;
240*00b67f09SDavid van Moolenbroek 	dns_name_t *origin;
241*00b67f09SDavid van Moolenbroek 	isc_result_t result;
242*00b67f09SDavid van Moolenbroek 	isc_buffer_t source;
243*00b67f09SDavid van Moolenbroek 	size_t len;
244*00b67f09SDavid van Moolenbroek 	dbinfo *dbi;
245*00b67f09SDavid van Moolenbroek 	unsigned int i;
246*00b67f09SDavid van Moolenbroek 
247*00b67f09SDavid van Moolenbroek 	dbi = isc_mem_get(mctx, sizeof(*dbi));
248*00b67f09SDavid van Moolenbroek 	if (dbi == NULL)
249*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
250*00b67f09SDavid van Moolenbroek 
251*00b67f09SDavid van Moolenbroek 	dbi->db = NULL;
252*00b67f09SDavid van Moolenbroek 	dbi->version = NULL;
253*00b67f09SDavid van Moolenbroek 	dbi->wversion = NULL;
254*00b67f09SDavid van Moolenbroek 	for (i = 0; i < MAXVERSIONS; i++)
255*00b67f09SDavid van Moolenbroek 		dbi->rversions[i] = NULL;
256*00b67f09SDavid van Moolenbroek 	dbi->hold_count = 0;
257*00b67f09SDavid van Moolenbroek 	for (i = 0; i < MAXHOLD; i++)
258*00b67f09SDavid van Moolenbroek 		dbi->hold_nodes[i] = NULL;
259*00b67f09SDavid van Moolenbroek 	dbi->dbiterator = NULL;
260*00b67f09SDavid van Moolenbroek 	dbi->iversion = NULL;
261*00b67f09SDavid van Moolenbroek 	dbi->pause_every = pause_every;
262*00b67f09SDavid van Moolenbroek 	dbi->ascending = ascending;
263*00b67f09SDavid van Moolenbroek 	ISC_LINK_INIT(dbi, link);
264*00b67f09SDavid van Moolenbroek 
265*00b67f09SDavid van Moolenbroek 	len = strlen(origintext);
266*00b67f09SDavid van Moolenbroek 	isc_buffer_constinit(&source, origintext, len);
267*00b67f09SDavid van Moolenbroek 	isc_buffer_add(&source, len);
268*00b67f09SDavid van Moolenbroek 	dns_fixedname_init(&forigin);
269*00b67f09SDavid van Moolenbroek 	origin = dns_fixedname_name(&forigin);
270*00b67f09SDavid van Moolenbroek 	result = dns_name_fromtext(origin, &source, dns_rootname, 0, NULL);
271*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
272*00b67f09SDavid van Moolenbroek 		return (result);
273*00b67f09SDavid van Moolenbroek 
274*00b67f09SDavid van Moolenbroek 	result = dns_db_create(mctx, dbtype, origin,
275*00b67f09SDavid van Moolenbroek 			       cache ? dns_dbtype_cache : dns_dbtype_zone,
276*00b67f09SDavid van Moolenbroek 			       dns_rdataclass_in,
277*00b67f09SDavid van Moolenbroek 			       0, NULL, &dbi->db);
278*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) {
279*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, dbi, sizeof(*dbi));
280*00b67f09SDavid van Moolenbroek 		return (result);
281*00b67f09SDavid van Moolenbroek 	}
282*00b67f09SDavid van Moolenbroek 
283*00b67f09SDavid van Moolenbroek 	printf("loading %s (%s)\n", filename, origintext);
284*00b67f09SDavid van Moolenbroek 	result = dns_db_load(dbi->db, filename);
285*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
286*00b67f09SDavid van Moolenbroek 		dns_db_detach(&dbi->db);
287*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, dbi, sizeof(*dbi));
288*00b67f09SDavid van Moolenbroek 		return (result);
289*00b67f09SDavid van Moolenbroek 	}
290*00b67f09SDavid van Moolenbroek 	printf("loaded\n");
291*00b67f09SDavid van Moolenbroek 
292*00b67f09SDavid van Moolenbroek 	if (cache) {
293*00b67f09SDavid van Moolenbroek 		INSIST(cache_dbi == NULL);
294*00b67f09SDavid van Moolenbroek 		dns_dbtable_adddefault(dbtable, dbi->db);
295*00b67f09SDavid van Moolenbroek 		cache_dbi = dbi;
296*00b67f09SDavid van Moolenbroek 	} else {
297*00b67f09SDavid van Moolenbroek 		if (dns_dbtable_add(dbtable, dbi->db) != ISC_R_SUCCESS) {
298*00b67f09SDavid van Moolenbroek 			dns_db_detach(&dbi->db);
299*00b67f09SDavid van Moolenbroek 			isc_mem_put(mctx, dbi, sizeof(*dbi));
300*00b67f09SDavid van Moolenbroek 			return (result);
301*00b67f09SDavid van Moolenbroek 		}
302*00b67f09SDavid van Moolenbroek 	}
303*00b67f09SDavid van Moolenbroek 	ISC_LIST_APPEND(dbs, dbi, link);
304*00b67f09SDavid van Moolenbroek 
305*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
306*00b67f09SDavid van Moolenbroek }
307*00b67f09SDavid van Moolenbroek 
308*00b67f09SDavid van Moolenbroek static void
unload_all(void)309*00b67f09SDavid van Moolenbroek unload_all(void) {
310*00b67f09SDavid van Moolenbroek 	dbinfo *dbi, *dbi_next;
311*00b67f09SDavid van Moolenbroek 
312*00b67f09SDavid van Moolenbroek 	for (dbi = ISC_LIST_HEAD(dbs); dbi != NULL; dbi = dbi_next) {
313*00b67f09SDavid van Moolenbroek 		dbi_next = ISC_LIST_NEXT(dbi, link);
314*00b67f09SDavid van Moolenbroek 		if (dns_db_iszone(dbi->db))
315*00b67f09SDavid van Moolenbroek 			dns_dbtable_remove(dbtable, dbi->db);
316*00b67f09SDavid van Moolenbroek 		else {
317*00b67f09SDavid van Moolenbroek 			INSIST(dbi == cache_dbi);
318*00b67f09SDavid van Moolenbroek 			dns_dbtable_removedefault(dbtable);
319*00b67f09SDavid van Moolenbroek 			cache_dbi = NULL;
320*00b67f09SDavid van Moolenbroek 		}
321*00b67f09SDavid van Moolenbroek 		dns_db_detach(&dbi->db);
322*00b67f09SDavid van Moolenbroek 		ISC_LIST_UNLINK(dbs, dbi, link);
323*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, dbi, sizeof(*dbi));
324*00b67f09SDavid van Moolenbroek 	}
325*00b67f09SDavid van Moolenbroek }
326*00b67f09SDavid van Moolenbroek 
327*00b67f09SDavid van Moolenbroek #define DBI_CHECK(dbi) \
328*00b67f09SDavid van Moolenbroek if ((dbi) == NULL) { \
329*00b67f09SDavid van Moolenbroek 	printf("You must first select a database with !DB\n"); \
330*00b67f09SDavid van Moolenbroek 	continue; \
331*00b67f09SDavid van Moolenbroek }
332*00b67f09SDavid van Moolenbroek 
333*00b67f09SDavid van Moolenbroek int
main(int argc,char * argv[])334*00b67f09SDavid van Moolenbroek main(int argc, char *argv[]) {
335*00b67f09SDavid van Moolenbroek 	dns_db_t *db;
336*00b67f09SDavid van Moolenbroek 	dns_dbnode_t *node;
337*00b67f09SDavid van Moolenbroek 	isc_result_t result;
338*00b67f09SDavid van Moolenbroek 	dns_name_t name;
339*00b67f09SDavid van Moolenbroek 	dns_offsets_t offsets;
340*00b67f09SDavid van Moolenbroek 	size_t len;
341*00b67f09SDavid van Moolenbroek 	isc_buffer_t source, target;
342*00b67f09SDavid van Moolenbroek 	char s[1000];
343*00b67f09SDavid van Moolenbroek 	char b[255];
344*00b67f09SDavid van Moolenbroek 	dns_rdataset_t rdataset, sigrdataset;
345*00b67f09SDavid van Moolenbroek 	int ch;
346*00b67f09SDavid van Moolenbroek 	dns_rdatatype_t type = 1;
347*00b67f09SDavid van Moolenbroek 	isc_boolean_t printnode = ISC_FALSE;
348*00b67f09SDavid van Moolenbroek 	isc_boolean_t addmode = ISC_FALSE;
349*00b67f09SDavid van Moolenbroek 	isc_boolean_t delmode = ISC_FALSE;
350*00b67f09SDavid van Moolenbroek 	isc_boolean_t holdmode = ISC_FALSE;
351*00b67f09SDavid van Moolenbroek 	isc_boolean_t verbose = ISC_FALSE;
352*00b67f09SDavid van Moolenbroek 	isc_boolean_t done = ISC_FALSE;
353*00b67f09SDavid van Moolenbroek 	isc_boolean_t quiet = ISC_FALSE;
354*00b67f09SDavid van Moolenbroek 	isc_boolean_t time_lookups = ISC_FALSE;
355*00b67f09SDavid van Moolenbroek 	isc_boolean_t found_as;
356*00b67f09SDavid van Moolenbroek 	isc_boolean_t find_zonecut = ISC_FALSE;
357*00b67f09SDavid van Moolenbroek 	isc_boolean_t noexact_zonecut = ISC_FALSE;
358*00b67f09SDavid van Moolenbroek 	int i, v;
359*00b67f09SDavid van Moolenbroek 	dns_rdatasetiter_t *rdsiter;
360*00b67f09SDavid van Moolenbroek 	char t1[256];
361*00b67f09SDavid van Moolenbroek 	char t2[256];
362*00b67f09SDavid van Moolenbroek 	isc_buffer_t tb1, tb2;
363*00b67f09SDavid van Moolenbroek 	isc_region_t r1, r2;
364*00b67f09SDavid van Moolenbroek 	dns_fixedname_t foundname;
365*00b67f09SDavid van Moolenbroek 	dns_name_t *fname;
366*00b67f09SDavid van Moolenbroek 	unsigned int options = 0, zcoptions;
367*00b67f09SDavid van Moolenbroek 	isc_time_t start, finish;
368*00b67f09SDavid van Moolenbroek 	char *origintext;
369*00b67f09SDavid van Moolenbroek 	dbinfo *dbi;
370*00b67f09SDavid van Moolenbroek 	dns_dbversion_t *version;
371*00b67f09SDavid van Moolenbroek 	dns_name_t *origin;
372*00b67f09SDavid van Moolenbroek 	size_t memory_quota = 0;
373*00b67f09SDavid van Moolenbroek 	dns_trust_t trust = 0;
374*00b67f09SDavid van Moolenbroek 	unsigned int addopts;
375*00b67f09SDavid van Moolenbroek 	isc_log_t *lctx = NULL;
376*00b67f09SDavid van Moolenbroek 	size_t n;
377*00b67f09SDavid van Moolenbroek 
378*00b67f09SDavid van Moolenbroek 	dns_result_register();
379*00b67f09SDavid van Moolenbroek 
380*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
381*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(dns_dbtable_create(mctx, dns_rdataclass_in, &dbtable) ==
382*00b67f09SDavid van Moolenbroek 		      ISC_R_SUCCESS);
383*00b67f09SDavid van Moolenbroek 
384*00b67f09SDavid van Moolenbroek 
385*00b67f09SDavid van Moolenbroek 
386*00b67f09SDavid van Moolenbroek 	strcpy(dbtype, "rbt");
387*00b67f09SDavid van Moolenbroek 	while ((ch = isc_commandline_parse(argc, argv, "c:d:t:z:P:Q:glpqvT"))
388*00b67f09SDavid van Moolenbroek 	       != -1) {
389*00b67f09SDavid van Moolenbroek 		switch (ch) {
390*00b67f09SDavid van Moolenbroek 		case 'c':
391*00b67f09SDavid van Moolenbroek 			result = load(isc_commandline_argument, ".", ISC_TRUE);
392*00b67f09SDavid van Moolenbroek 			if (result != ISC_R_SUCCESS)
393*00b67f09SDavid van Moolenbroek 				printf("cache load(%s) %08x: %s\n",
394*00b67f09SDavid van Moolenbroek 				       isc_commandline_argument, result,
395*00b67f09SDavid van Moolenbroek 				       isc_result_totext(result));
396*00b67f09SDavid van Moolenbroek 			break;
397*00b67f09SDavid van Moolenbroek 		case 'd':
398*00b67f09SDavid van Moolenbroek 			n = strlcpy(dbtype, isc_commandline_argument,
399*00b67f09SDavid van Moolenbroek 				    sizeof(dbtype));
400*00b67f09SDavid van Moolenbroek 			if (n >= sizeof(dbtype)) {
401*00b67f09SDavid van Moolenbroek 				fprintf(stderr, "bad db type '%s'\n",
402*00b67f09SDavid van Moolenbroek 					isc_commandline_argument);
403*00b67f09SDavid van Moolenbroek 				exit(1);
404*00b67f09SDavid van Moolenbroek 			}
405*00b67f09SDavid van Moolenbroek 			break;
406*00b67f09SDavid van Moolenbroek 		case 'g':
407*00b67f09SDavid van Moolenbroek 			options |= (DNS_DBFIND_GLUEOK|DNS_DBFIND_VALIDATEGLUE);
408*00b67f09SDavid van Moolenbroek 			break;
409*00b67f09SDavid van Moolenbroek 		case 'l':
410*00b67f09SDavid van Moolenbroek 			RUNTIME_CHECK(isc_log_create(mctx, &lctx,
411*00b67f09SDavid van Moolenbroek 						     NULL) == ISC_R_SUCCESS);
412*00b67f09SDavid van Moolenbroek 			isc_log_setcontext(lctx);
413*00b67f09SDavid van Moolenbroek 			dns_log_init(lctx);
414*00b67f09SDavid van Moolenbroek 			dns_log_setcontext(lctx);
415*00b67f09SDavid van Moolenbroek 			break;
416*00b67f09SDavid van Moolenbroek 		case 'q':
417*00b67f09SDavid van Moolenbroek 			quiet = ISC_TRUE;
418*00b67f09SDavid van Moolenbroek 			verbose = ISC_FALSE;
419*00b67f09SDavid van Moolenbroek 			break;
420*00b67f09SDavid van Moolenbroek 		case 'p':
421*00b67f09SDavid van Moolenbroek 			printnode = ISC_TRUE;
422*00b67f09SDavid van Moolenbroek 			break;
423*00b67f09SDavid van Moolenbroek 		case 'P':
424*00b67f09SDavid van Moolenbroek 			pause_every = atoi(isc_commandline_argument);
425*00b67f09SDavid van Moolenbroek 			break;
426*00b67f09SDavid van Moolenbroek 		case 'Q':
427*00b67f09SDavid van Moolenbroek 			memory_quota = atoi(isc_commandline_argument);
428*00b67f09SDavid van Moolenbroek 			isc_mem_setquota(mctx, memory_quota);
429*00b67f09SDavid van Moolenbroek 			break;
430*00b67f09SDavid van Moolenbroek 		case 't':
431*00b67f09SDavid van Moolenbroek 			type = atoi(isc_commandline_argument);
432*00b67f09SDavid van Moolenbroek 			break;
433*00b67f09SDavid van Moolenbroek 		case 'T':
434*00b67f09SDavid van Moolenbroek 			time_lookups = ISC_TRUE;
435*00b67f09SDavid van Moolenbroek 			break;
436*00b67f09SDavid van Moolenbroek 		case 'v':
437*00b67f09SDavid van Moolenbroek 			verbose = ISC_TRUE;
438*00b67f09SDavid van Moolenbroek 			break;
439*00b67f09SDavid van Moolenbroek 		case 'z':
440*00b67f09SDavid van Moolenbroek 			origintext = strrchr(isc_commandline_argument, '/');
441*00b67f09SDavid van Moolenbroek 			if (origintext == NULL)
442*00b67f09SDavid van Moolenbroek 				origintext = isc_commandline_argument;
443*00b67f09SDavid van Moolenbroek 			else
444*00b67f09SDavid van Moolenbroek 				origintext++;	/* Skip '/'. */
445*00b67f09SDavid van Moolenbroek 			result = load(isc_commandline_argument, origintext,
446*00b67f09SDavid van Moolenbroek 				      ISC_FALSE);
447*00b67f09SDavid van Moolenbroek 			if (result != ISC_R_SUCCESS)
448*00b67f09SDavid van Moolenbroek 				printf("zone load(%s) %08x: %s\n",
449*00b67f09SDavid van Moolenbroek 				       isc_commandline_argument, result,
450*00b67f09SDavid van Moolenbroek 				       isc_result_totext(result));
451*00b67f09SDavid van Moolenbroek 			break;
452*00b67f09SDavid van Moolenbroek 		}
453*00b67f09SDavid van Moolenbroek 	}
454*00b67f09SDavid van Moolenbroek 
455*00b67f09SDavid van Moolenbroek 	argc -= isc_commandline_index;
456*00b67f09SDavid van Moolenbroek 	argv += isc_commandline_index;
457*00b67f09SDavid van Moolenbroek 	POST(argv);
458*00b67f09SDavid van Moolenbroek 
459*00b67f09SDavid van Moolenbroek 	if (argc != 0)
460*00b67f09SDavid van Moolenbroek 		printf("ignoring trailing arguments\n");
461*00b67f09SDavid van Moolenbroek 
462*00b67f09SDavid van Moolenbroek 	/*
463*00b67f09SDavid van Moolenbroek 	 * Some final initialization...
464*00b67f09SDavid van Moolenbroek 	 */
465*00b67f09SDavid van Moolenbroek 	dns_fixedname_init(&foundname);
466*00b67f09SDavid van Moolenbroek 	fname = dns_fixedname_name(&foundname);
467*00b67f09SDavid van Moolenbroek 	dbi = NULL;
468*00b67f09SDavid van Moolenbroek 	origin = dns_rootname;
469*00b67f09SDavid van Moolenbroek 	version = NULL;
470*00b67f09SDavid van Moolenbroek 
471*00b67f09SDavid van Moolenbroek 	if (time_lookups) {
472*00b67f09SDavid van Moolenbroek 		TIME_NOW(&start);
473*00b67f09SDavid van Moolenbroek 	}
474*00b67f09SDavid van Moolenbroek 
475*00b67f09SDavid van Moolenbroek 	while (!done) {
476*00b67f09SDavid van Moolenbroek 		if (!quiet)
477*00b67f09SDavid van Moolenbroek 			printf("\n");
478*00b67f09SDavid van Moolenbroek 		if (fgets(s, sizeof(s), stdin) == NULL) {
479*00b67f09SDavid van Moolenbroek 			done = ISC_TRUE;
480*00b67f09SDavid van Moolenbroek 			continue;
481*00b67f09SDavid van Moolenbroek 		}
482*00b67f09SDavid van Moolenbroek 		len = strlen(s);
483*00b67f09SDavid van Moolenbroek 		if (len > 0U && s[len - 1] == '\n') {
484*00b67f09SDavid van Moolenbroek 			s[len - 1] = '\0';
485*00b67f09SDavid van Moolenbroek 			len--;
486*00b67f09SDavid van Moolenbroek 		}
487*00b67f09SDavid van Moolenbroek 		if (verbose && dbi != NULL) {
488*00b67f09SDavid van Moolenbroek 			if (dbi->wversion != NULL)
489*00b67f09SDavid van Moolenbroek 				printf("future version (%p)\n", dbi->wversion);
490*00b67f09SDavid van Moolenbroek 			for (i = 0; i < dbi->rcount; i++)
491*00b67f09SDavid van Moolenbroek 				if (dbi->rversions[i] != NULL)
492*00b67f09SDavid van Moolenbroek 					printf("open version %d (%p)\n", i,
493*00b67f09SDavid van Moolenbroek 					       dbi->rversions[i]);
494*00b67f09SDavid van Moolenbroek 		}
495*00b67f09SDavid van Moolenbroek 		dns_name_init(&name, offsets);
496*00b67f09SDavid van Moolenbroek 		if (strcmp(s, "!R") == 0) {
497*00b67f09SDavid van Moolenbroek 			DBI_CHECK(dbi);
498*00b67f09SDavid van Moolenbroek 			if (dbi->rcount == MAXVERSIONS) {
499*00b67f09SDavid van Moolenbroek 				printf("too many open versions\n");
500*00b67f09SDavid van Moolenbroek 				continue;
501*00b67f09SDavid van Moolenbroek 			}
502*00b67f09SDavid van Moolenbroek 			dns_db_currentversion(dbi->db,
503*00b67f09SDavid van Moolenbroek 					      &dbi->rversions[dbi->rcount]);
504*00b67f09SDavid van Moolenbroek 			printf("opened version %d\n", dbi->rcount);
505*00b67f09SDavid van Moolenbroek 			dbi->version = dbi->rversions[dbi->rcount];
506*00b67f09SDavid van Moolenbroek 			version = dbi->version;
507*00b67f09SDavid van Moolenbroek 			dbi->rcount++;
508*00b67f09SDavid van Moolenbroek 			continue;
509*00b67f09SDavid van Moolenbroek 		} else if (strcmp(s, "!W") == 0) {
510*00b67f09SDavid van Moolenbroek 			DBI_CHECK(dbi);
511*00b67f09SDavid van Moolenbroek 			if (dbi->wversion != NULL) {
512*00b67f09SDavid van Moolenbroek 				printf("using existing future version\n");
513*00b67f09SDavid van Moolenbroek 				dbi->version = dbi->wversion;
514*00b67f09SDavid van Moolenbroek 				version = dbi->version;
515*00b67f09SDavid van Moolenbroek 				continue;
516*00b67f09SDavid van Moolenbroek 			}
517*00b67f09SDavid van Moolenbroek 			result = dns_db_newversion(dbi->db, &dbi->wversion);
518*00b67f09SDavid van Moolenbroek 			if (result != ISC_R_SUCCESS)
519*00b67f09SDavid van Moolenbroek 				print_result("", result);
520*00b67f09SDavid van Moolenbroek 			else
521*00b67f09SDavid van Moolenbroek 				printf("newversion\n");
522*00b67f09SDavid van Moolenbroek 			dbi->version = dbi->wversion;
523*00b67f09SDavid van Moolenbroek 			version = dbi->version;
524*00b67f09SDavid van Moolenbroek 			continue;
525*00b67f09SDavid van Moolenbroek 		} else if (strcmp(s, "!C") == 0) {
526*00b67f09SDavid van Moolenbroek 			DBI_CHECK(dbi);
527*00b67f09SDavid van Moolenbroek 			addmode = ISC_FALSE;
528*00b67f09SDavid van Moolenbroek 			delmode = ISC_FALSE;
529*00b67f09SDavid van Moolenbroek 			if (dbi->version == NULL)
530*00b67f09SDavid van Moolenbroek 				continue;
531*00b67f09SDavid van Moolenbroek 			if (dbi->version == dbi->wversion) {
532*00b67f09SDavid van Moolenbroek 				printf("closing future version\n");
533*00b67f09SDavid van Moolenbroek 				dbi->wversion = NULL;
534*00b67f09SDavid van Moolenbroek 			} else {
535*00b67f09SDavid van Moolenbroek 				for (i = 0; i < dbi->rcount; i++) {
536*00b67f09SDavid van Moolenbroek 					if (dbi->version ==
537*00b67f09SDavid van Moolenbroek 					    dbi->rversions[i]) {
538*00b67f09SDavid van Moolenbroek 						dbi->rversions[i] = NULL;
539*00b67f09SDavid van Moolenbroek 					  printf("closing open version %d\n",
540*00b67f09SDavid van Moolenbroek 						 i);
541*00b67f09SDavid van Moolenbroek 						break;
542*00b67f09SDavid van Moolenbroek 					}
543*00b67f09SDavid van Moolenbroek 				}
544*00b67f09SDavid van Moolenbroek 			}
545*00b67f09SDavid van Moolenbroek 			dns_db_closeversion(dbi->db, &dbi->version, ISC_TRUE);
546*00b67f09SDavid van Moolenbroek 			version = NULL;
547*00b67f09SDavid van Moolenbroek 			continue;
548*00b67f09SDavid van Moolenbroek 		} else if (strcmp(s, "!X") == 0) {
549*00b67f09SDavid van Moolenbroek 			DBI_CHECK(dbi);
550*00b67f09SDavid van Moolenbroek 			addmode = ISC_FALSE;
551*00b67f09SDavid van Moolenbroek 			delmode = ISC_FALSE;
552*00b67f09SDavid van Moolenbroek 			if (dbi->version == NULL)
553*00b67f09SDavid van Moolenbroek 				continue;
554*00b67f09SDavid van Moolenbroek 			if (dbi->version == dbi->wversion) {
555*00b67f09SDavid van Moolenbroek 				printf("aborting future version\n");
556*00b67f09SDavid van Moolenbroek 				dbi->wversion = NULL;
557*00b67f09SDavid van Moolenbroek 			} else {
558*00b67f09SDavid van Moolenbroek 				for (i = 0; i < dbi->rcount; i++) {
559*00b67f09SDavid van Moolenbroek 					if (dbi->version ==
560*00b67f09SDavid van Moolenbroek 					    dbi->rversions[i]) {
561*00b67f09SDavid van Moolenbroek 						dbi->rversions[i] = NULL;
562*00b67f09SDavid van Moolenbroek 					  printf("closing open version %d\n",
563*00b67f09SDavid van Moolenbroek 						 i);
564*00b67f09SDavid van Moolenbroek 						break;
565*00b67f09SDavid van Moolenbroek 					}
566*00b67f09SDavid van Moolenbroek 				}
567*00b67f09SDavid van Moolenbroek 			}
568*00b67f09SDavid van Moolenbroek 			dns_db_closeversion(dbi->db, &dbi->version, ISC_FALSE);
569*00b67f09SDavid van Moolenbroek 			version = NULL;
570*00b67f09SDavid van Moolenbroek 			continue;
571*00b67f09SDavid van Moolenbroek 		} else if (strcmp(s, "!A") == 0) {
572*00b67f09SDavid van Moolenbroek 			DBI_CHECK(dbi);
573*00b67f09SDavid van Moolenbroek 			delmode = ISC_FALSE;
574*00b67f09SDavid van Moolenbroek 			if (addmode)
575*00b67f09SDavid van Moolenbroek 				addmode = ISC_FALSE;
576*00b67f09SDavid van Moolenbroek 			else
577*00b67f09SDavid van Moolenbroek 				addmode = ISC_TRUE;
578*00b67f09SDavid van Moolenbroek 			printf("addmode = %s\n", addmode ? "TRUE" : "FALSE");
579*00b67f09SDavid van Moolenbroek 			continue;
580*00b67f09SDavid van Moolenbroek 		} else if (strcmp(s, "!D") == 0) {
581*00b67f09SDavid van Moolenbroek 			DBI_CHECK(dbi);
582*00b67f09SDavid van Moolenbroek 			addmode = ISC_FALSE;
583*00b67f09SDavid van Moolenbroek 			if (delmode)
584*00b67f09SDavid van Moolenbroek 				delmode = ISC_FALSE;
585*00b67f09SDavid van Moolenbroek 			else
586*00b67f09SDavid van Moolenbroek 				delmode = ISC_TRUE;
587*00b67f09SDavid van Moolenbroek 			printf("delmode = %s\n", delmode ? "TRUE" : "FALSE");
588*00b67f09SDavid van Moolenbroek 			continue;
589*00b67f09SDavid van Moolenbroek 		} else if (strcmp(s, "!H") == 0) {
590*00b67f09SDavid van Moolenbroek 			DBI_CHECK(dbi);
591*00b67f09SDavid van Moolenbroek 			if (holdmode)
592*00b67f09SDavid van Moolenbroek 				holdmode = ISC_FALSE;
593*00b67f09SDavid van Moolenbroek 			else
594*00b67f09SDavid van Moolenbroek 				holdmode = ISC_TRUE;
595*00b67f09SDavid van Moolenbroek 			printf("holdmode = %s\n", holdmode ? "TRUE" : "FALSE");
596*00b67f09SDavid van Moolenbroek 			continue;
597*00b67f09SDavid van Moolenbroek 		} else if (strcmp(s, "!HR") == 0) {
598*00b67f09SDavid van Moolenbroek 			DBI_CHECK(dbi);
599*00b67f09SDavid van Moolenbroek 			for (i = 0; i < dbi->hold_count; i++)
600*00b67f09SDavid van Moolenbroek 				dns_db_detachnode(dbi->db,
601*00b67f09SDavid van Moolenbroek 						  &dbi->hold_nodes[i]);
602*00b67f09SDavid van Moolenbroek 			dbi->hold_count = 0;
603*00b67f09SDavid van Moolenbroek 			holdmode = ISC_FALSE;
604*00b67f09SDavid van Moolenbroek 			printf("held nodes have been detached\n");
605*00b67f09SDavid van Moolenbroek 			continue;
606*00b67f09SDavid van Moolenbroek 		} else if (strcmp(s, "!VC") == 0) {
607*00b67f09SDavid van Moolenbroek 			DBI_CHECK(dbi);
608*00b67f09SDavid van Moolenbroek 			printf("switching to current version\n");
609*00b67f09SDavid van Moolenbroek 			dbi->version = NULL;
610*00b67f09SDavid van Moolenbroek 			version = NULL;
611*00b67f09SDavid van Moolenbroek 			continue;
612*00b67f09SDavid van Moolenbroek 		} else if (strstr(s, "!V") == s) {
613*00b67f09SDavid van Moolenbroek 			DBI_CHECK(dbi);
614*00b67f09SDavid van Moolenbroek 			v = atoi(&s[2]);
615*00b67f09SDavid van Moolenbroek 			if (v >= dbi->rcount || v < 0) {
616*00b67f09SDavid van Moolenbroek 				printf("unknown open version %d\n", v);
617*00b67f09SDavid van Moolenbroek 				continue;
618*00b67f09SDavid van Moolenbroek 			}
619*00b67f09SDavid van Moolenbroek 			if (dbi->rversions[v] == NULL) {
620*00b67f09SDavid van Moolenbroek 				printf("version %d is not open\n", v);
621*00b67f09SDavid van Moolenbroek 				continue;
622*00b67f09SDavid van Moolenbroek 			}
623*00b67f09SDavid van Moolenbroek 			printf("switching to open version %d\n", v);
624*00b67f09SDavid van Moolenbroek 			dbi->version = dbi->rversions[v];
625*00b67f09SDavid van Moolenbroek 			version = dbi->version;
626*00b67f09SDavid van Moolenbroek 			continue;
627*00b67f09SDavid van Moolenbroek 		} else if (strstr(s, "!TR") == s) {
628*00b67f09SDavid van Moolenbroek 			trust = (unsigned int)atoi(&s[3]);
629*00b67f09SDavid van Moolenbroek 			printf("trust level is now %u\n", (unsigned int)trust);
630*00b67f09SDavid van Moolenbroek 			continue;
631*00b67f09SDavid van Moolenbroek 		} else if (strstr(s, "!T") == s) {
632*00b67f09SDavid van Moolenbroek 			type = (unsigned int)atoi(&s[2]);
633*00b67f09SDavid van Moolenbroek 			printf("now searching for type %u\n", type);
634*00b67f09SDavid van Moolenbroek 			continue;
635*00b67f09SDavid van Moolenbroek 		} else if (strcmp(s, "!G") == 0) {
636*00b67f09SDavid van Moolenbroek 			if ((options & DNS_DBFIND_GLUEOK) != 0)
637*00b67f09SDavid van Moolenbroek 				options &= ~DNS_DBFIND_GLUEOK;
638*00b67f09SDavid van Moolenbroek 			else
639*00b67f09SDavid van Moolenbroek 				options |= DNS_DBFIND_GLUEOK;
640*00b67f09SDavid van Moolenbroek 			printf("glue ok = %s\n",
641*00b67f09SDavid van Moolenbroek 			       ((options & DNS_DBFIND_GLUEOK) != 0) ?
642*00b67f09SDavid van Moolenbroek 			       "TRUE" : "FALSE");
643*00b67f09SDavid van Moolenbroek 			continue;
644*00b67f09SDavid van Moolenbroek 		} else if (strcmp(s, "!GV") == 0) {
645*00b67f09SDavid van Moolenbroek 			if ((options & DNS_DBFIND_VALIDATEGLUE) != 0)
646*00b67f09SDavid van Moolenbroek 				options &= ~DNS_DBFIND_VALIDATEGLUE;
647*00b67f09SDavid van Moolenbroek 			else
648*00b67f09SDavid van Moolenbroek 				options |= DNS_DBFIND_VALIDATEGLUE;
649*00b67f09SDavid van Moolenbroek 			printf("validate glue = %s\n",
650*00b67f09SDavid van Moolenbroek 			       ((options & DNS_DBFIND_VALIDATEGLUE) != 0) ?
651*00b67f09SDavid van Moolenbroek 			       "TRUE" : "FALSE");
652*00b67f09SDavid van Moolenbroek 			continue;
653*00b67f09SDavid van Moolenbroek 		} else if (strcmp(s, "!WC") == 0) {
654*00b67f09SDavid van Moolenbroek 			if ((options & DNS_DBFIND_NOWILD) != 0)
655*00b67f09SDavid van Moolenbroek 				options &= ~DNS_DBFIND_NOWILD;
656*00b67f09SDavid van Moolenbroek 			else
657*00b67f09SDavid van Moolenbroek 				options |= DNS_DBFIND_NOWILD;
658*00b67f09SDavid van Moolenbroek 			printf("wildcard matching = %s\n",
659*00b67f09SDavid van Moolenbroek 			       ((options & DNS_DBFIND_NOWILD) == 0) ?
660*00b67f09SDavid van Moolenbroek 			       "TRUE" : "FALSE");
661*00b67f09SDavid van Moolenbroek 			continue;
662*00b67f09SDavid van Moolenbroek 		} else if (strstr(s, "!LS ") == s) {
663*00b67f09SDavid van Moolenbroek 			DBI_CHECK(dbi);
664*00b67f09SDavid van Moolenbroek 			list(dbi, &s[4]);
665*00b67f09SDavid van Moolenbroek 			continue;
666*00b67f09SDavid van Moolenbroek 		} else if (strcmp(s, "!LS") == 0) {
667*00b67f09SDavid van Moolenbroek 			DBI_CHECK(dbi);
668*00b67f09SDavid van Moolenbroek 			list(dbi, NULL);
669*00b67f09SDavid van Moolenbroek 			continue;
670*00b67f09SDavid van Moolenbroek 		} else if (strstr(s, "!DU ") == s) {
671*00b67f09SDavid van Moolenbroek 			DBI_CHECK(dbi);
672*00b67f09SDavid van Moolenbroek 			result = dns_db_dump(dbi->db, dbi->version, s+4);
673*00b67f09SDavid van Moolenbroek 			if (result != ISC_R_SUCCESS) {
674*00b67f09SDavid van Moolenbroek 				printf("\n");
675*00b67f09SDavid van Moolenbroek 				print_result("", result);
676*00b67f09SDavid van Moolenbroek 			}
677*00b67f09SDavid van Moolenbroek 			continue;
678*00b67f09SDavid van Moolenbroek 		} else if (strcmp(s, "!PN") == 0) {
679*00b67f09SDavid van Moolenbroek 			if (printnode)
680*00b67f09SDavid van Moolenbroek 				printnode = ISC_FALSE;
681*00b67f09SDavid van Moolenbroek 			else
682*00b67f09SDavid van Moolenbroek 				printnode = ISC_TRUE;
683*00b67f09SDavid van Moolenbroek 			printf("printnode = %s\n",
684*00b67f09SDavid van Moolenbroek 			       printnode ? "TRUE" : "FALSE");
685*00b67f09SDavid van Moolenbroek 			continue;
686*00b67f09SDavid van Moolenbroek 		} else if (strstr(s, "!P") == s) {
687*00b67f09SDavid van Moolenbroek 			DBI_CHECK(dbi);
688*00b67f09SDavid van Moolenbroek 			v = atoi(&s[2]);
689*00b67f09SDavid van Moolenbroek 			dbi->pause_every = v;
690*00b67f09SDavid van Moolenbroek 			continue;
691*00b67f09SDavid van Moolenbroek 		} else if (strcmp(s, "!+") == 0) {
692*00b67f09SDavid van Moolenbroek 			DBI_CHECK(dbi);
693*00b67f09SDavid van Moolenbroek 			dbi->ascending = ISC_TRUE;
694*00b67f09SDavid van Moolenbroek 			continue;
695*00b67f09SDavid van Moolenbroek 		} else if (strcmp(s, "!-") == 0) {
696*00b67f09SDavid van Moolenbroek 			DBI_CHECK(dbi);
697*00b67f09SDavid van Moolenbroek 			dbi->ascending = ISC_FALSE;
698*00b67f09SDavid van Moolenbroek 			continue;
699*00b67f09SDavid van Moolenbroek 		} else if (strcmp(s, "!DB") == 0) {
700*00b67f09SDavid van Moolenbroek 			dbi = NULL;
701*00b67f09SDavid van Moolenbroek 			origin = dns_rootname;
702*00b67f09SDavid van Moolenbroek 			version = NULL;
703*00b67f09SDavid van Moolenbroek 			printf("now searching all databases\n");
704*00b67f09SDavid van Moolenbroek 			continue;
705*00b67f09SDavid van Moolenbroek 		} else if (strncmp(s, "!DB ", 4) == 0) {
706*00b67f09SDavid van Moolenbroek 			dbi = select_db(s+4);
707*00b67f09SDavid van Moolenbroek 			if (dbi != NULL) {
708*00b67f09SDavid van Moolenbroek 				db = dbi->db;
709*00b67f09SDavid van Moolenbroek 				origin = dns_db_origin(dbi->db);
710*00b67f09SDavid van Moolenbroek 				version = dbi->version;
711*00b67f09SDavid van Moolenbroek 				addmode = ISC_FALSE;
712*00b67f09SDavid van Moolenbroek 				delmode = ISC_FALSE;
713*00b67f09SDavid van Moolenbroek 				holdmode = ISC_FALSE;
714*00b67f09SDavid van Moolenbroek 			} else {
715*00b67f09SDavid van Moolenbroek 				db = NULL;
716*00b67f09SDavid van Moolenbroek 				version = NULL;
717*00b67f09SDavid van Moolenbroek 				origin = dns_rootname;
718*00b67f09SDavid van Moolenbroek 				printf("database not found; "
719*00b67f09SDavid van Moolenbroek 				       "now searching all databases\n");
720*00b67f09SDavid van Moolenbroek 			}
721*00b67f09SDavid van Moolenbroek 			continue;
722*00b67f09SDavid van Moolenbroek 		} else if (strcmp(s, "!ZC") == 0) {
723*00b67f09SDavid van Moolenbroek 			if (find_zonecut)
724*00b67f09SDavid van Moolenbroek 				find_zonecut = ISC_FALSE;
725*00b67f09SDavid van Moolenbroek 			else
726*00b67f09SDavid van Moolenbroek 				find_zonecut = ISC_TRUE;
727*00b67f09SDavid van Moolenbroek 			printf("find_zonecut = %s\n",
728*00b67f09SDavid van Moolenbroek 			       find_zonecut ? "TRUE" : "FALSE");
729*00b67f09SDavid van Moolenbroek 			continue;
730*00b67f09SDavid van Moolenbroek 		} else if (strcmp(s, "!NZ") == 0) {
731*00b67f09SDavid van Moolenbroek 			if (noexact_zonecut)
732*00b67f09SDavid van Moolenbroek 				noexact_zonecut = ISC_FALSE;
733*00b67f09SDavid van Moolenbroek 			else
734*00b67f09SDavid van Moolenbroek 				noexact_zonecut = ISC_TRUE;
735*00b67f09SDavid van Moolenbroek 			printf("noexact_zonecut = %s\n",
736*00b67f09SDavid van Moolenbroek 			       noexact_zonecut ? "TRUE" : "FALSE");
737*00b67f09SDavid van Moolenbroek 			continue;
738*00b67f09SDavid van Moolenbroek 		}
739*00b67f09SDavid van Moolenbroek 
740*00b67f09SDavid van Moolenbroek 		isc_buffer_init(&source, s, len);
741*00b67f09SDavid van Moolenbroek 		isc_buffer_add(&source, len);
742*00b67f09SDavid van Moolenbroek 		isc_buffer_init(&target, b, sizeof(b));
743*00b67f09SDavid van Moolenbroek 		result = dns_name_fromtext(&name, &source, origin, 0, &target);
744*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS) {
745*00b67f09SDavid van Moolenbroek 			print_result("bad name: ", result);
746*00b67f09SDavid van Moolenbroek 			continue;
747*00b67f09SDavid van Moolenbroek 		}
748*00b67f09SDavid van Moolenbroek 
749*00b67f09SDavid van Moolenbroek 		if (dbi == NULL) {
750*00b67f09SDavid van Moolenbroek 			zcoptions = 0;
751*00b67f09SDavid van Moolenbroek 			if (noexact_zonecut)
752*00b67f09SDavid van Moolenbroek 				zcoptions |= DNS_DBTABLEFIND_NOEXACT;
753*00b67f09SDavid van Moolenbroek 			db = NULL;
754*00b67f09SDavid van Moolenbroek 			result = dns_dbtable_find(dbtable, &name, zcoptions,
755*00b67f09SDavid van Moolenbroek 						  &db);
756*00b67f09SDavid van Moolenbroek 			if (result != ISC_R_SUCCESS &&
757*00b67f09SDavid van Moolenbroek 			    result != DNS_R_PARTIALMATCH) {
758*00b67f09SDavid van Moolenbroek 				if (!quiet) {
759*00b67f09SDavid van Moolenbroek 					printf("\n");
760*00b67f09SDavid van Moolenbroek 					print_result("", result);
761*00b67f09SDavid van Moolenbroek 				}
762*00b67f09SDavid van Moolenbroek 				continue;
763*00b67f09SDavid van Moolenbroek 			}
764*00b67f09SDavid van Moolenbroek 			isc_buffer_init(&tb1, t1, sizeof(t1));
765*00b67f09SDavid van Moolenbroek 			result = dns_name_totext(dns_db_origin(db), ISC_FALSE,
766*00b67f09SDavid van Moolenbroek 						 &tb1);
767*00b67f09SDavid van Moolenbroek 			if (result != ISC_R_SUCCESS) {
768*00b67f09SDavid van Moolenbroek 				printf("\n");
769*00b67f09SDavid van Moolenbroek 				print_result("", result);
770*00b67f09SDavid van Moolenbroek 				dns_db_detach(&db);
771*00b67f09SDavid van Moolenbroek 				continue;
772*00b67f09SDavid van Moolenbroek 			}
773*00b67f09SDavid van Moolenbroek 			isc_buffer_usedregion(&tb1, &r1);
774*00b67f09SDavid van Moolenbroek 			printf("\ndatabase = %.*s (%s)\n",
775*00b67f09SDavid van Moolenbroek 			       (int)r1.length, r1.base,
776*00b67f09SDavid van Moolenbroek 			       (dns_db_iszone(db)) ? "zone" : "cache");
777*00b67f09SDavid van Moolenbroek 		}
778*00b67f09SDavid van Moolenbroek 		node = NULL;
779*00b67f09SDavid van Moolenbroek 		dns_rdataset_init(&rdataset);
780*00b67f09SDavid van Moolenbroek 		dns_rdataset_init(&sigrdataset);
781*00b67f09SDavid van Moolenbroek 
782*00b67f09SDavid van Moolenbroek 		if (find_zonecut && dns_db_iscache(db)) {
783*00b67f09SDavid van Moolenbroek 			zcoptions = options;
784*00b67f09SDavid van Moolenbroek 			if (noexact_zonecut)
785*00b67f09SDavid van Moolenbroek 				zcoptions |= DNS_DBFIND_NOEXACT;
786*00b67f09SDavid van Moolenbroek 			result = dns_db_findzonecut(db, &name, zcoptions,
787*00b67f09SDavid van Moolenbroek 						    0, &node, fname,
788*00b67f09SDavid van Moolenbroek 						    &rdataset, &sigrdataset);
789*00b67f09SDavid van Moolenbroek 		} else {
790*00b67f09SDavid van Moolenbroek 			result = dns_db_find(db, &name, version, type,
791*00b67f09SDavid van Moolenbroek 					     options, 0, &node, fname,
792*00b67f09SDavid van Moolenbroek 					     &rdataset, &sigrdataset);
793*00b67f09SDavid van Moolenbroek 		}
794*00b67f09SDavid van Moolenbroek 
795*00b67f09SDavid van Moolenbroek 		if (!quiet) {
796*00b67f09SDavid van Moolenbroek 			if (dbi != NULL)
797*00b67f09SDavid van Moolenbroek 				printf("\n");
798*00b67f09SDavid van Moolenbroek 			print_result("", result);
799*00b67f09SDavid van Moolenbroek 		}
800*00b67f09SDavid van Moolenbroek 
801*00b67f09SDavid van Moolenbroek 		found_as = ISC_FALSE;
802*00b67f09SDavid van Moolenbroek 		switch (result) {
803*00b67f09SDavid van Moolenbroek 		case ISC_R_SUCCESS:
804*00b67f09SDavid van Moolenbroek 		case DNS_R_GLUE:
805*00b67f09SDavid van Moolenbroek 		case DNS_R_CNAME:
806*00b67f09SDavid van Moolenbroek 		case DNS_R_ZONECUT:
807*00b67f09SDavid van Moolenbroek 			break;
808*00b67f09SDavid van Moolenbroek 		case DNS_R_DNAME:
809*00b67f09SDavid van Moolenbroek 		case DNS_R_DELEGATION:
810*00b67f09SDavid van Moolenbroek 			found_as = ISC_TRUE;
811*00b67f09SDavid van Moolenbroek 			break;
812*00b67f09SDavid van Moolenbroek 		case DNS_R_NXRRSET:
813*00b67f09SDavid van Moolenbroek 			if (dns_rdataset_isassociated(&rdataset))
814*00b67f09SDavid van Moolenbroek 				break;
815*00b67f09SDavid van Moolenbroek 			if (dbi != NULL) {
816*00b67f09SDavid van Moolenbroek 				if (holdmode) {
817*00b67f09SDavid van Moolenbroek 					RUNTIME_CHECK(dbi->hold_count <
818*00b67f09SDavid van Moolenbroek 						      MAXHOLD);
819*00b67f09SDavid van Moolenbroek 					dbi->hold_nodes[dbi->hold_count++] =
820*00b67f09SDavid van Moolenbroek 						node;
821*00b67f09SDavid van Moolenbroek 					node = NULL;
822*00b67f09SDavid van Moolenbroek 				} else
823*00b67f09SDavid van Moolenbroek 					dns_db_detachnode(db, &node);
824*00b67f09SDavid van Moolenbroek 			} else {
825*00b67f09SDavid van Moolenbroek 				dns_db_detachnode(db, &node);
826*00b67f09SDavid van Moolenbroek 				dns_db_detach(&db);
827*00b67f09SDavid van Moolenbroek 			}
828*00b67f09SDavid van Moolenbroek 			continue;
829*00b67f09SDavid van Moolenbroek 		case DNS_R_NXDOMAIN:
830*00b67f09SDavid van Moolenbroek 			if (dns_rdataset_isassociated(&rdataset))
831*00b67f09SDavid van Moolenbroek 				break;
832*00b67f09SDavid van Moolenbroek 			/* FALLTHROUGH */
833*00b67f09SDavid van Moolenbroek 		default:
834*00b67f09SDavid van Moolenbroek 			if (dbi == NULL)
835*00b67f09SDavid van Moolenbroek 				dns_db_detach(&db);
836*00b67f09SDavid van Moolenbroek 			if (quiet)
837*00b67f09SDavid van Moolenbroek 				print_result("", result);
838*00b67f09SDavid van Moolenbroek 			continue;
839*00b67f09SDavid van Moolenbroek 		}
840*00b67f09SDavid van Moolenbroek 		if (found_as && !quiet) {
841*00b67f09SDavid van Moolenbroek 			isc_buffer_init(&tb1, t1, sizeof(t1));
842*00b67f09SDavid van Moolenbroek 			isc_buffer_init(&tb2, t2, sizeof(t2));
843*00b67f09SDavid van Moolenbroek 			result = dns_name_totext(&name, ISC_FALSE, &tb1);
844*00b67f09SDavid van Moolenbroek 			if (result != ISC_R_SUCCESS) {
845*00b67f09SDavid van Moolenbroek 				print_result("", result);
846*00b67f09SDavid van Moolenbroek 				dns_db_detachnode(db, &node);
847*00b67f09SDavid van Moolenbroek 				if (dbi == NULL)
848*00b67f09SDavid van Moolenbroek 					dns_db_detach(&db);
849*00b67f09SDavid van Moolenbroek 				continue;
850*00b67f09SDavid van Moolenbroek 			}
851*00b67f09SDavid van Moolenbroek 			result = dns_name_totext(fname, ISC_FALSE, &tb2);
852*00b67f09SDavid van Moolenbroek 			if (result != ISC_R_SUCCESS) {
853*00b67f09SDavid van Moolenbroek 				print_result("", result);
854*00b67f09SDavid van Moolenbroek 				dns_db_detachnode(db, &node);
855*00b67f09SDavid van Moolenbroek 				if (dbi == NULL)
856*00b67f09SDavid van Moolenbroek 					dns_db_detach(&db);
857*00b67f09SDavid van Moolenbroek 				continue;
858*00b67f09SDavid van Moolenbroek 			}
859*00b67f09SDavid van Moolenbroek 			isc_buffer_usedregion(&tb1, &r1);
860*00b67f09SDavid van Moolenbroek 			isc_buffer_usedregion(&tb2, &r2);
861*00b67f09SDavid van Moolenbroek 			printf("found %.*s as %.*s\n",
862*00b67f09SDavid van Moolenbroek 			       (int)r1.length, r1.base,
863*00b67f09SDavid van Moolenbroek 			       (int)r2.length, r2.base);
864*00b67f09SDavid van Moolenbroek 		}
865*00b67f09SDavid van Moolenbroek 
866*00b67f09SDavid van Moolenbroek 		if (printnode)
867*00b67f09SDavid van Moolenbroek 			dns_db_printnode(db, node, stdout);
868*00b67f09SDavid van Moolenbroek 
869*00b67f09SDavid van Moolenbroek 		if (!found_as && type == dns_rdatatype_any) {
870*00b67f09SDavid van Moolenbroek 			rdsiter = NULL;
871*00b67f09SDavid van Moolenbroek 			result = dns_db_allrdatasets(db, node, version, 0,
872*00b67f09SDavid van Moolenbroek 						     &rdsiter);
873*00b67f09SDavid van Moolenbroek 			if (result == ISC_R_SUCCESS) {
874*00b67f09SDavid van Moolenbroek 				if (!quiet)
875*00b67f09SDavid van Moolenbroek 					print_rdatasets(fname, rdsiter);
876*00b67f09SDavid van Moolenbroek 				dns_rdatasetiter_destroy(&rdsiter);
877*00b67f09SDavid van Moolenbroek 			} else
878*00b67f09SDavid van Moolenbroek 				print_result("", result);
879*00b67f09SDavid van Moolenbroek 		} else {
880*00b67f09SDavid van Moolenbroek 			if (!quiet)
881*00b67f09SDavid van Moolenbroek 				print_rdataset(fname, &rdataset);
882*00b67f09SDavid van Moolenbroek 			if (dns_rdataset_isassociated(&sigrdataset)) {
883*00b67f09SDavid van Moolenbroek 				if (!quiet)
884*00b67f09SDavid van Moolenbroek 					print_rdataset(fname, &sigrdataset);
885*00b67f09SDavid van Moolenbroek 				dns_rdataset_disassociate(&sigrdataset);
886*00b67f09SDavid van Moolenbroek 			}
887*00b67f09SDavid van Moolenbroek 			if (dbi != NULL && addmode && !found_as) {
888*00b67f09SDavid van Moolenbroek 				rdataset.ttl++;
889*00b67f09SDavid van Moolenbroek 				rdataset.trust = trust;
890*00b67f09SDavid van Moolenbroek 				if (dns_db_iszone(db))
891*00b67f09SDavid van Moolenbroek 					addopts = DNS_DBADD_MERGE;
892*00b67f09SDavid van Moolenbroek 				else
893*00b67f09SDavid van Moolenbroek 					addopts = 0;
894*00b67f09SDavid van Moolenbroek 				result = dns_db_addrdataset(db, node, version,
895*00b67f09SDavid van Moolenbroek 							    0, &rdataset,
896*00b67f09SDavid van Moolenbroek 							    addopts, NULL);
897*00b67f09SDavid van Moolenbroek 				if (result != ISC_R_SUCCESS)
898*00b67f09SDavid van Moolenbroek 					print_result("", result);
899*00b67f09SDavid van Moolenbroek 				if (printnode)
900*00b67f09SDavid van Moolenbroek 					dns_db_printnode(db, node, stdout);
901*00b67f09SDavid van Moolenbroek 			} else if (dbi != NULL && delmode && !found_as) {
902*00b67f09SDavid van Moolenbroek 				result = dns_db_deleterdataset(db, node,
903*00b67f09SDavid van Moolenbroek 							       version, type,
904*00b67f09SDavid van Moolenbroek 							       0);
905*00b67f09SDavid van Moolenbroek 				if (result != ISC_R_SUCCESS)
906*00b67f09SDavid van Moolenbroek 					print_result("", result);
907*00b67f09SDavid van Moolenbroek 				if (printnode)
908*00b67f09SDavid van Moolenbroek 					dns_db_printnode(db, node, stdout);
909*00b67f09SDavid van Moolenbroek 			}
910*00b67f09SDavid van Moolenbroek 			dns_rdataset_disassociate(&rdataset);
911*00b67f09SDavid van Moolenbroek 		}
912*00b67f09SDavid van Moolenbroek 
913*00b67f09SDavid van Moolenbroek 		if (dbi != NULL) {
914*00b67f09SDavid van Moolenbroek 			if (holdmode) {
915*00b67f09SDavid van Moolenbroek 				RUNTIME_CHECK(dbi->hold_count < MAXHOLD);
916*00b67f09SDavid van Moolenbroek 				dbi->hold_nodes[dbi->hold_count++] = node;
917*00b67f09SDavid van Moolenbroek 				node = NULL;
918*00b67f09SDavid van Moolenbroek 			} else
919*00b67f09SDavid van Moolenbroek 				dns_db_detachnode(db, &node);
920*00b67f09SDavid van Moolenbroek 		} else {
921*00b67f09SDavid van Moolenbroek 			dns_db_detachnode(db, &node);
922*00b67f09SDavid van Moolenbroek 			dns_db_detach(&db);
923*00b67f09SDavid van Moolenbroek 		}
924*00b67f09SDavid van Moolenbroek 	}
925*00b67f09SDavid van Moolenbroek 
926*00b67f09SDavid van Moolenbroek 	if (time_lookups) {
927*00b67f09SDavid van Moolenbroek 		isc_uint64_t usec;
928*00b67f09SDavid van Moolenbroek 
929*00b67f09SDavid van Moolenbroek 		TIME_NOW(&finish);
930*00b67f09SDavid van Moolenbroek 
931*00b67f09SDavid van Moolenbroek 		usec = isc_time_microdiff(&finish, &start);
932*00b67f09SDavid van Moolenbroek 
933*00b67f09SDavid van Moolenbroek 		printf("elapsed time: %lu.%06lu seconds\n",
934*00b67f09SDavid van Moolenbroek 		       (unsigned long)(usec / 1000000),
935*00b67f09SDavid van Moolenbroek 		       (unsigned long)(usec % 1000000));
936*00b67f09SDavid van Moolenbroek 	}
937*00b67f09SDavid van Moolenbroek 
938*00b67f09SDavid van Moolenbroek 	unload_all();
939*00b67f09SDavid van Moolenbroek 
940*00b67f09SDavid van Moolenbroek 	dns_dbtable_detach(&dbtable);
941*00b67f09SDavid van Moolenbroek 
942*00b67f09SDavid van Moolenbroek 	if (lctx != NULL)
943*00b67f09SDavid van Moolenbroek 		isc_log_destroy(&lctx);
944*00b67f09SDavid van Moolenbroek 
945*00b67f09SDavid van Moolenbroek 	if (!quiet)
946*00b67f09SDavid van Moolenbroek 		isc_mem_stats(mctx, stdout);
947*00b67f09SDavid van Moolenbroek 
948*00b67f09SDavid van Moolenbroek 	return (0);
949*00b67f09SDavid van Moolenbroek }
950