xref: /minix3/external/bsd/bind/dist/bin/tests/rbt_test.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: rbt_test.c,v 1.6 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, 2012, 2014  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: rbt_test.c,v 1.52 2011/08/28 23:46:41 tbox Exp  */
21*00b67f09SDavid van Moolenbroek 
22*00b67f09SDavid van Moolenbroek #include <config.h>
23*00b67f09SDavid van Moolenbroek 
24*00b67f09SDavid van Moolenbroek #include <stdlib.h>
25*00b67f09SDavid van Moolenbroek 
26*00b67f09SDavid van Moolenbroek #include <isc/commandline.h>
27*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
28*00b67f09SDavid van Moolenbroek #include <isc/string.h>
29*00b67f09SDavid van Moolenbroek #include <isc/util.h>
30*00b67f09SDavid van Moolenbroek 
31*00b67f09SDavid van Moolenbroek #include <dns/rbt.h>
32*00b67f09SDavid van Moolenbroek #include <dns/fixedname.h>
33*00b67f09SDavid van Moolenbroek #include <dns/result.h>
34*00b67f09SDavid van Moolenbroek 
35*00b67f09SDavid van Moolenbroek char *progname;
36*00b67f09SDavid van Moolenbroek isc_mem_t *mctx;
37*00b67f09SDavid van Moolenbroek 
38*00b67f09SDavid van Moolenbroek #define DNSNAMELEN 255
39*00b67f09SDavid van Moolenbroek 
40*00b67f09SDavid van Moolenbroek static dns_name_t *
create_name(char * s)41*00b67f09SDavid van Moolenbroek create_name(char *s) {
42*00b67f09SDavid van Moolenbroek 	int length;
43*00b67f09SDavid van Moolenbroek 	isc_result_t result;
44*00b67f09SDavid van Moolenbroek 	isc_buffer_t source, target;
45*00b67f09SDavid van Moolenbroek 	static dns_name_t *name;
46*00b67f09SDavid van Moolenbroek 
47*00b67f09SDavid van Moolenbroek 	if (s == NULL || *s == '\0') {
48*00b67f09SDavid van Moolenbroek 		printf("missing name argument\n");
49*00b67f09SDavid van Moolenbroek 		return (NULL);
50*00b67f09SDavid van Moolenbroek 	}
51*00b67f09SDavid van Moolenbroek 
52*00b67f09SDavid van Moolenbroek 	length = strlen(s);
53*00b67f09SDavid van Moolenbroek 
54*00b67f09SDavid van Moolenbroek 	isc_buffer_init(&source, s, length);
55*00b67f09SDavid van Moolenbroek 	isc_buffer_add(&source, length);
56*00b67f09SDavid van Moolenbroek 
57*00b67f09SDavid van Moolenbroek 	/*
58*00b67f09SDavid van Moolenbroek 	 * It isn't really necessary in this program to create individual
59*00b67f09SDavid van Moolenbroek 	 * memory spaces for each name structure and its associated character
60*00b67f09SDavid van Moolenbroek 	 * string.  It is done here to provide a relatively easy way to test
61*00b67f09SDavid van Moolenbroek 	 * the callback from dns_rbt_deletename that is supposed to free the
62*00b67f09SDavid van Moolenbroek 	 * data associated with a node.
63*00b67f09SDavid van Moolenbroek 	 *
64*00b67f09SDavid van Moolenbroek 	 * The buffer for the actual name will immediately follow the
65*00b67f09SDavid van Moolenbroek 	 * name structure.
66*00b67f09SDavid van Moolenbroek 	 */
67*00b67f09SDavid van Moolenbroek 	name = isc_mem_get(mctx, sizeof(*name) + DNSNAMELEN);
68*00b67f09SDavid van Moolenbroek 	if (name == NULL) {
69*00b67f09SDavid van Moolenbroek 		printf("out of memory!\n");
70*00b67f09SDavid van Moolenbroek 		return (NULL);
71*00b67f09SDavid van Moolenbroek 	}
72*00b67f09SDavid van Moolenbroek 
73*00b67f09SDavid van Moolenbroek 	dns_name_init(name, NULL);
74*00b67f09SDavid van Moolenbroek 	isc_buffer_init(&target, name + 1, DNSNAMELEN);
75*00b67f09SDavid van Moolenbroek 
76*00b67f09SDavid van Moolenbroek 	result = dns_name_fromtext(name, &source, dns_rootname, 0, &target);
77*00b67f09SDavid van Moolenbroek 
78*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) {
79*00b67f09SDavid van Moolenbroek 		printf("dns_name_fromtext(%s) failed: %s\n",
80*00b67f09SDavid van Moolenbroek 		       s, dns_result_totext(result));
81*00b67f09SDavid van Moolenbroek 		return (NULL);
82*00b67f09SDavid van Moolenbroek 	}
83*00b67f09SDavid van Moolenbroek 
84*00b67f09SDavid van Moolenbroek 	return (name);
85*00b67f09SDavid van Moolenbroek }
86*00b67f09SDavid van Moolenbroek 
87*00b67f09SDavid van Moolenbroek static void
delete_name(void * data,void * arg)88*00b67f09SDavid van Moolenbroek delete_name(void *data, void *arg) {
89*00b67f09SDavid van Moolenbroek 	dns_name_t *name;
90*00b67f09SDavid van Moolenbroek 
91*00b67f09SDavid van Moolenbroek 	UNUSED(arg);
92*00b67f09SDavid van Moolenbroek 	name = data;
93*00b67f09SDavid van Moolenbroek 	isc_mem_put(mctx, name, sizeof(*name) + DNSNAMELEN);
94*00b67f09SDavid van Moolenbroek }
95*00b67f09SDavid van Moolenbroek 
96*00b67f09SDavid van Moolenbroek static void
print_name(dns_name_t * name)97*00b67f09SDavid van Moolenbroek print_name(dns_name_t *name) {
98*00b67f09SDavid van Moolenbroek 	isc_buffer_t target;
99*00b67f09SDavid van Moolenbroek 	char buffer[1024];
100*00b67f09SDavid van Moolenbroek 
101*00b67f09SDavid van Moolenbroek 	isc_buffer_init(&target, buffer, sizeof(buffer));
102*00b67f09SDavid van Moolenbroek 
103*00b67f09SDavid van Moolenbroek 	/*
104*00b67f09SDavid van Moolenbroek 	 * ISC_FALSE means absolute names have the final dot added.
105*00b67f09SDavid van Moolenbroek 	 */
106*00b67f09SDavid van Moolenbroek 	dns_name_totext(name, ISC_FALSE, &target);
107*00b67f09SDavid van Moolenbroek 
108*00b67f09SDavid van Moolenbroek 	printf("%.*s", (int)target.used, (char *)target.base);
109*00b67f09SDavid van Moolenbroek }
110*00b67f09SDavid van Moolenbroek 
111*00b67f09SDavid van Moolenbroek static void
detail(dns_rbt_t * rbt,dns_name_t * name)112*00b67f09SDavid van Moolenbroek detail(dns_rbt_t *rbt, dns_name_t *name) {
113*00b67f09SDavid van Moolenbroek 	dns_name_t *foundname, *origin, *fullname;
114*00b67f09SDavid van Moolenbroek 	dns_fixedname_t fixedfoundname, fixedorigin, fixedfullname;
115*00b67f09SDavid van Moolenbroek 	dns_rbtnode_t *node1, *node2;
116*00b67f09SDavid van Moolenbroek 	dns_rbtnodechain_t chain;
117*00b67f09SDavid van Moolenbroek 	isc_result_t result;
118*00b67f09SDavid van Moolenbroek 	isc_boolean_t nodes_should_match = ISC_FALSE;
119*00b67f09SDavid van Moolenbroek 
120*00b67f09SDavid van Moolenbroek 	dns_rbtnodechain_init(&chain, mctx);
121*00b67f09SDavid van Moolenbroek 
122*00b67f09SDavid van Moolenbroek 	dns_fixedname_init(&fixedorigin);
123*00b67f09SDavid van Moolenbroek 	dns_fixedname_init(&fixedfullname);
124*00b67f09SDavid van Moolenbroek 	dns_fixedname_init(&fixedfoundname);
125*00b67f09SDavid van Moolenbroek 
126*00b67f09SDavid van Moolenbroek 	origin = dns_fixedname_name(&fixedorigin);
127*00b67f09SDavid van Moolenbroek 	fullname = dns_fixedname_name(&fixedfullname);
128*00b67f09SDavid van Moolenbroek 	foundname = dns_fixedname_name(&fixedfoundname);
129*00b67f09SDavid van Moolenbroek 
130*00b67f09SDavid van Moolenbroek 	node1 = node2 = NULL;
131*00b67f09SDavid van Moolenbroek 
132*00b67f09SDavid van Moolenbroek 	printf("checking chain information for ");
133*00b67f09SDavid van Moolenbroek 	print_name(name);
134*00b67f09SDavid van Moolenbroek 	printf("\n");
135*00b67f09SDavid van Moolenbroek 
136*00b67f09SDavid van Moolenbroek 	result = dns_rbt_findnode(rbt, name, foundname, &node1, &chain,
137*00b67f09SDavid van Moolenbroek 				  DNS_RBTFIND_EMPTYDATA, NULL, NULL);
138*00b67f09SDavid van Moolenbroek 
139*00b67f09SDavid van Moolenbroek 	switch (result) {
140*00b67f09SDavid van Moolenbroek 	case ISC_R_SUCCESS:
141*00b67f09SDavid van Moolenbroek 		printf("  found exact.");
142*00b67f09SDavid van Moolenbroek 		nodes_should_match = ISC_TRUE;
143*00b67f09SDavid van Moolenbroek 		break;
144*00b67f09SDavid van Moolenbroek 	case DNS_R_PARTIALMATCH:
145*00b67f09SDavid van Moolenbroek 		printf("  found parent.");
146*00b67f09SDavid van Moolenbroek 		break;
147*00b67f09SDavid van Moolenbroek 	case ISC_R_NOTFOUND:
148*00b67f09SDavid van Moolenbroek 		printf("  name not found.");
149*00b67f09SDavid van Moolenbroek 		break;
150*00b67f09SDavid van Moolenbroek 	default:
151*00b67f09SDavid van Moolenbroek 		printf("  unexpected result: %s\n", dns_result_totext(result));
152*00b67f09SDavid van Moolenbroek 		return;
153*00b67f09SDavid van Moolenbroek 	}
154*00b67f09SDavid van Moolenbroek 
155*00b67f09SDavid van Moolenbroek 	if (node1 != NULL && node1->data != NULL) {
156*00b67f09SDavid van Moolenbroek 		printf("  data at node: ");
157*00b67f09SDavid van Moolenbroek 		print_name(node1->data);
158*00b67f09SDavid van Moolenbroek 	} else
159*00b67f09SDavid van Moolenbroek 		printf("  no data at node.");
160*00b67f09SDavid van Moolenbroek 
161*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
162*00b67f09SDavid van Moolenbroek 		printf("\n  name from dns_rbt_findnode: ");
163*00b67f09SDavid van Moolenbroek 		print_name(foundname);
164*00b67f09SDavid van Moolenbroek 	}
165*00b67f09SDavid van Moolenbroek 
166*00b67f09SDavid van Moolenbroek 	result = dns_rbtnodechain_current(&chain, foundname, origin, &node2);
167*00b67f09SDavid van Moolenbroek 
168*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS) {
169*00b67f09SDavid van Moolenbroek 		printf("\n  name from dns_rbtnodechain_current: ");
170*00b67f09SDavid van Moolenbroek 
171*00b67f09SDavid van Moolenbroek 		result = dns_name_concatenate(foundname, origin,
172*00b67f09SDavid van Moolenbroek 					      fullname, NULL);
173*00b67f09SDavid van Moolenbroek 		if (result == ISC_R_SUCCESS)
174*00b67f09SDavid van Moolenbroek 			print_name(fullname);
175*00b67f09SDavid van Moolenbroek 		else
176*00b67f09SDavid van Moolenbroek 			printf("%s\n", dns_result_totext(result));
177*00b67f09SDavid van Moolenbroek 		printf("\n      (foundname = ");
178*00b67f09SDavid van Moolenbroek 		print_name(foundname);
179*00b67f09SDavid van Moolenbroek 		printf(", origin = ");
180*00b67f09SDavid van Moolenbroek 		print_name(origin);
181*00b67f09SDavid van Moolenbroek 		printf(")\n");
182*00b67f09SDavid van Moolenbroek 		if (nodes_should_match && node1 != node2)
183*00b67f09SDavid van Moolenbroek 			printf("  nodes returned from each function "
184*00b67f09SDavid van Moolenbroek 			       "DO NOT match!\n");
185*00b67f09SDavid van Moolenbroek 
186*00b67f09SDavid van Moolenbroek 	} else
187*00b67f09SDavid van Moolenbroek 		printf("\n  result from dns_rbtnodechain_current: %s\n",
188*00b67f09SDavid van Moolenbroek 		       dns_result_totext(result));
189*00b67f09SDavid van Moolenbroek 
190*00b67f09SDavid van Moolenbroek 	printf("  level_matches = %d, level_count = %d\n",
191*00b67f09SDavid van Moolenbroek 	       chain.level_matches, chain.level_count);
192*00b67f09SDavid van Moolenbroek }
193*00b67f09SDavid van Moolenbroek 
194*00b67f09SDavid van Moolenbroek static void
iterate(dns_rbt_t * rbt,isc_boolean_t forward)195*00b67f09SDavid van Moolenbroek iterate(dns_rbt_t *rbt, isc_boolean_t forward) {
196*00b67f09SDavid van Moolenbroek 	dns_name_t foundname, *origin;
197*00b67f09SDavid van Moolenbroek 	dns_rbtnodechain_t chain;
198*00b67f09SDavid van Moolenbroek 	dns_fixedname_t fixedorigin;
199*00b67f09SDavid van Moolenbroek 	isc_result_t result;
200*00b67f09SDavid van Moolenbroek 	isc_result_t (*move)(dns_rbtnodechain_t *chain, dns_name_t *name,
201*00b67f09SDavid van Moolenbroek 			     dns_name_t *origin);
202*00b67f09SDavid van Moolenbroek 
203*00b67f09SDavid van Moolenbroek 	dns_rbtnodechain_init(&chain, mctx);
204*00b67f09SDavid van Moolenbroek 
205*00b67f09SDavid van Moolenbroek 	dns_name_init(&foundname, NULL);
206*00b67f09SDavid van Moolenbroek 	dns_fixedname_init(&fixedorigin);
207*00b67f09SDavid van Moolenbroek 	origin = dns_fixedname_name(&fixedorigin);
208*00b67f09SDavid van Moolenbroek 
209*00b67f09SDavid van Moolenbroek 	if (forward) {
210*00b67f09SDavid van Moolenbroek 		printf("iterating forward\n" );
211*00b67f09SDavid van Moolenbroek 		move = dns_rbtnodechain_next;
212*00b67f09SDavid van Moolenbroek 
213*00b67f09SDavid van Moolenbroek 		result = dns_rbtnodechain_first(&chain, rbt, &foundname,
214*00b67f09SDavid van Moolenbroek 						origin);
215*00b67f09SDavid van Moolenbroek 
216*00b67f09SDavid van Moolenbroek 	} else {
217*00b67f09SDavid van Moolenbroek 		printf("iterating backward\n" );
218*00b67f09SDavid van Moolenbroek 		move = dns_rbtnodechain_prev;
219*00b67f09SDavid van Moolenbroek 
220*00b67f09SDavid van Moolenbroek 		result = dns_rbtnodechain_last(&chain, rbt, &foundname,
221*00b67f09SDavid van Moolenbroek 					       origin);
222*00b67f09SDavid van Moolenbroek 	}
223*00b67f09SDavid van Moolenbroek 
224*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN)
225*00b67f09SDavid van Moolenbroek 		printf("start not found!\n");
226*00b67f09SDavid van Moolenbroek 
227*00b67f09SDavid van Moolenbroek 	else {
228*00b67f09SDavid van Moolenbroek 		for (;;) {
229*00b67f09SDavid van Moolenbroek 			if (result == DNS_R_NEWORIGIN) {
230*00b67f09SDavid van Moolenbroek 				printf("  new origin: ");
231*00b67f09SDavid van Moolenbroek 				print_name(origin);
232*00b67f09SDavid van Moolenbroek 				printf("\n");
233*00b67f09SDavid van Moolenbroek 			}
234*00b67f09SDavid van Moolenbroek 
235*00b67f09SDavid van Moolenbroek 			if (result == ISC_R_SUCCESS ||
236*00b67f09SDavid van Moolenbroek 			    result == DNS_R_NEWORIGIN) {
237*00b67f09SDavid van Moolenbroek 				print_name(&foundname);
238*00b67f09SDavid van Moolenbroek 				printf("\n");
239*00b67f09SDavid van Moolenbroek 
240*00b67f09SDavid van Moolenbroek 			} else {
241*00b67f09SDavid van Moolenbroek 				if (result != ISC_R_NOMORE)
242*00b67f09SDavid van Moolenbroek 				       printf("UNEXEPCTED ITERATION ERROR: %s",
243*00b67f09SDavid van Moolenbroek 					      dns_result_totext(result));
244*00b67f09SDavid van Moolenbroek 				break;
245*00b67f09SDavid van Moolenbroek 			}
246*00b67f09SDavid van Moolenbroek 
247*00b67f09SDavid van Moolenbroek 			result = move(&chain, &foundname, origin);
248*00b67f09SDavid van Moolenbroek 		}
249*00b67f09SDavid van Moolenbroek 	}
250*00b67f09SDavid van Moolenbroek }
251*00b67f09SDavid van Moolenbroek 
252*00b67f09SDavid van Moolenbroek 
253*00b67f09SDavid van Moolenbroek #define CMDCHECK(s)	(strncasecmp(command, (s), length) == 0)
254*00b67f09SDavid van Moolenbroek #define PRINTERR(r)	if (r != ISC_R_SUCCESS) \
255*00b67f09SDavid van Moolenbroek 				printf("... %s\n", dns_result_totext(r));
256*00b67f09SDavid van Moolenbroek 
257*00b67f09SDavid van Moolenbroek int
main(int argc,char ** argv)258*00b67f09SDavid van Moolenbroek main(int argc, char **argv) {
259*00b67f09SDavid van Moolenbroek 	char *command, *arg, buffer[1024];
260*00b67f09SDavid van Moolenbroek 	const char *whitespace;
261*00b67f09SDavid van Moolenbroek 	dns_name_t *name, *foundname;
262*00b67f09SDavid van Moolenbroek 	dns_fixedname_t fixedname;
263*00b67f09SDavid van Moolenbroek 	dns_rbt_t *rbt = NULL;
264*00b67f09SDavid van Moolenbroek 	int length, ch;
265*00b67f09SDavid van Moolenbroek 	isc_boolean_t show_final_mem = ISC_FALSE;
266*00b67f09SDavid van Moolenbroek 	isc_result_t result;
267*00b67f09SDavid van Moolenbroek 	void *data;
268*00b67f09SDavid van Moolenbroek 
269*00b67f09SDavid van Moolenbroek 	progname = strrchr(*argv, '/');
270*00b67f09SDavid van Moolenbroek 	if (progname != NULL)
271*00b67f09SDavid van Moolenbroek 		progname++;
272*00b67f09SDavid van Moolenbroek 	else
273*00b67f09SDavid van Moolenbroek 		progname = *argv;
274*00b67f09SDavid van Moolenbroek 
275*00b67f09SDavid van Moolenbroek 	while ((ch = isc_commandline_parse(argc, argv, "m")) != -1) {
276*00b67f09SDavid van Moolenbroek 		switch (ch) {
277*00b67f09SDavid van Moolenbroek 		case 'm':
278*00b67f09SDavid van Moolenbroek 			show_final_mem = ISC_TRUE;
279*00b67f09SDavid van Moolenbroek 			break;
280*00b67f09SDavid van Moolenbroek 		}
281*00b67f09SDavid van Moolenbroek 	}
282*00b67f09SDavid van Moolenbroek 
283*00b67f09SDavid van Moolenbroek 	argc -= isc_commandline_index;
284*00b67f09SDavid van Moolenbroek 	argv += isc_commandline_index;
285*00b67f09SDavid van Moolenbroek 	POST(argv);
286*00b67f09SDavid van Moolenbroek 
287*00b67f09SDavid van Moolenbroek 	if (argc > 1) {
288*00b67f09SDavid van Moolenbroek 		printf("Usage: %s [-m]\n", progname);
289*00b67f09SDavid van Moolenbroek 		exit(1);
290*00b67f09SDavid van Moolenbroek 	}
291*00b67f09SDavid van Moolenbroek 
292*00b67f09SDavid van Moolenbroek 	setbuf(stdout, NULL);
293*00b67f09SDavid van Moolenbroek 
294*00b67f09SDavid van Moolenbroek 	/*
295*00b67f09SDavid van Moolenbroek 	 * So isc_mem_stats() can report any allocation leaks.
296*00b67f09SDavid van Moolenbroek 	 */
297*00b67f09SDavid van Moolenbroek 	isc_mem_debugging = ISC_MEM_DEBUGRECORD;
298*00b67f09SDavid van Moolenbroek 
299*00b67f09SDavid van Moolenbroek 	result = isc_mem_create(0, 0, &mctx);
300*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) {
301*00b67f09SDavid van Moolenbroek 		printf("isc_mem_create: %s: exiting\n",
302*00b67f09SDavid van Moolenbroek 		       dns_result_totext(result));
303*00b67f09SDavid van Moolenbroek 		exit(1);
304*00b67f09SDavid van Moolenbroek 	}
305*00b67f09SDavid van Moolenbroek 
306*00b67f09SDavid van Moolenbroek 	result = dns_rbt_create(mctx, delete_name, NULL, &rbt);
307*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) {
308*00b67f09SDavid van Moolenbroek 		printf("dns_rbt_create: %s: exiting\n",
309*00b67f09SDavid van Moolenbroek 		       dns_result_totext(result));
310*00b67f09SDavid van Moolenbroek 		exit(1);
311*00b67f09SDavid van Moolenbroek 	}
312*00b67f09SDavid van Moolenbroek 
313*00b67f09SDavid van Moolenbroek 	whitespace = " \t";
314*00b67f09SDavid van Moolenbroek 
315*00b67f09SDavid van Moolenbroek 	while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
316*00b67f09SDavid van Moolenbroek 		length = strlen(buffer);
317*00b67f09SDavid van Moolenbroek 
318*00b67f09SDavid van Moolenbroek 		if (buffer[length - 1] != '\n') {
319*00b67f09SDavid van Moolenbroek 			printf("line to long (%lu max), ignored\n",
320*00b67f09SDavid van Moolenbroek 			       (unsigned long)sizeof(buffer) - 2);
321*00b67f09SDavid van Moolenbroek 			continue;
322*00b67f09SDavid van Moolenbroek 		}
323*00b67f09SDavid van Moolenbroek 
324*00b67f09SDavid van Moolenbroek 		buffer[length - 1] = '\0';
325*00b67f09SDavid van Moolenbroek 
326*00b67f09SDavid van Moolenbroek 		command = buffer + strspn(buffer, whitespace);
327*00b67f09SDavid van Moolenbroek 
328*00b67f09SDavid van Moolenbroek 		if (*command == '#')
329*00b67f09SDavid van Moolenbroek 			continue;
330*00b67f09SDavid van Moolenbroek 
331*00b67f09SDavid van Moolenbroek 		arg = strpbrk(command, whitespace);
332*00b67f09SDavid van Moolenbroek 		if (arg != NULL) {
333*00b67f09SDavid van Moolenbroek 			*arg++ = '\0';
334*00b67f09SDavid van Moolenbroek 			arg += strspn(arg, whitespace);
335*00b67f09SDavid van Moolenbroek 		}
336*00b67f09SDavid van Moolenbroek 
337*00b67f09SDavid van Moolenbroek 		length = strlen(command);
338*00b67f09SDavid van Moolenbroek 		if (*command != '\0') {
339*00b67f09SDavid van Moolenbroek 			if (CMDCHECK("add")) {
340*00b67f09SDavid van Moolenbroek 				name = create_name(arg);
341*00b67f09SDavid van Moolenbroek 				if (name != NULL) {
342*00b67f09SDavid van Moolenbroek 					printf("adding name %s\n", arg);
343*00b67f09SDavid van Moolenbroek 					result = dns_rbt_addname(rbt,
344*00b67f09SDavid van Moolenbroek 								 name, name);
345*00b67f09SDavid van Moolenbroek 					PRINTERR(result);
346*00b67f09SDavid van Moolenbroek 				}
347*00b67f09SDavid van Moolenbroek 
348*00b67f09SDavid van Moolenbroek 			} else if (CMDCHECK("delete")) {
349*00b67f09SDavid van Moolenbroek 				name = create_name(arg);
350*00b67f09SDavid van Moolenbroek 				if (name != NULL) {
351*00b67f09SDavid van Moolenbroek 					printf("deleting name %s\n", arg);
352*00b67f09SDavid van Moolenbroek 					result = dns_rbt_deletename(rbt, name,
353*00b67f09SDavid van Moolenbroek 								    ISC_FALSE);
354*00b67f09SDavid van Moolenbroek 					PRINTERR(result);
355*00b67f09SDavid van Moolenbroek 					delete_name(name, NULL);
356*00b67f09SDavid van Moolenbroek 				}
357*00b67f09SDavid van Moolenbroek 
358*00b67f09SDavid van Moolenbroek 			} else if (CMDCHECK("nuke")) {
359*00b67f09SDavid van Moolenbroek 				name = create_name(arg);
360*00b67f09SDavid van Moolenbroek 				if (name != NULL) {
361*00b67f09SDavid van Moolenbroek 					printf("nuking name %s "
362*00b67f09SDavid van Moolenbroek 					       "and its descendants\n", arg);
363*00b67f09SDavid van Moolenbroek 					result = dns_rbt_deletename(rbt, name,
364*00b67f09SDavid van Moolenbroek 								    ISC_TRUE);
365*00b67f09SDavid van Moolenbroek 					PRINTERR(result);
366*00b67f09SDavid van Moolenbroek 					delete_name(name, NULL);
367*00b67f09SDavid van Moolenbroek 				}
368*00b67f09SDavid van Moolenbroek 
369*00b67f09SDavid van Moolenbroek 			} else if (CMDCHECK("search")) {
370*00b67f09SDavid van Moolenbroek 				name = create_name(arg);
371*00b67f09SDavid van Moolenbroek 				if (name != NULL) {
372*00b67f09SDavid van Moolenbroek 					printf("searching for name %s ... ",
373*00b67f09SDavid van Moolenbroek 					       arg);
374*00b67f09SDavid van Moolenbroek 
375*00b67f09SDavid van Moolenbroek 					dns_fixedname_init(&fixedname);
376*00b67f09SDavid van Moolenbroek 					foundname =
377*00b67f09SDavid van Moolenbroek 						dns_fixedname_name(&fixedname);
378*00b67f09SDavid van Moolenbroek 					data = NULL;
379*00b67f09SDavid van Moolenbroek 
380*00b67f09SDavid van Moolenbroek 					result = dns_rbt_findname(rbt, name, 0,
381*00b67f09SDavid van Moolenbroek 								  foundname,
382*00b67f09SDavid van Moolenbroek 								  &data);
383*00b67f09SDavid van Moolenbroek 					switch (result) {
384*00b67f09SDavid van Moolenbroek 					case ISC_R_SUCCESS:
385*00b67f09SDavid van Moolenbroek 						printf("found exact: ");
386*00b67f09SDavid van Moolenbroek 						print_name(data);
387*00b67f09SDavid van Moolenbroek 						putchar('\n');
388*00b67f09SDavid van Moolenbroek 						break;
389*00b67f09SDavid van Moolenbroek 					case DNS_R_PARTIALMATCH:
390*00b67f09SDavid van Moolenbroek 						printf("found parent: ");
391*00b67f09SDavid van Moolenbroek 						print_name(data);
392*00b67f09SDavid van Moolenbroek 						printf("\n\t(foundname: ");
393*00b67f09SDavid van Moolenbroek 						print_name(foundname);
394*00b67f09SDavid van Moolenbroek 						printf(")\n");
395*00b67f09SDavid van Moolenbroek 						break;
396*00b67f09SDavid van Moolenbroek 					case ISC_R_NOTFOUND:
397*00b67f09SDavid van Moolenbroek 						printf("NOT FOUND!\n");
398*00b67f09SDavid van Moolenbroek 						break;
399*00b67f09SDavid van Moolenbroek 					case ISC_R_NOMEMORY:
400*00b67f09SDavid van Moolenbroek 						printf("OUT OF MEMORY!\n");
401*00b67f09SDavid van Moolenbroek 						break;
402*00b67f09SDavid van Moolenbroek 					default:
403*00b67f09SDavid van Moolenbroek 						printf("UNEXPECTED RESULT\n");
404*00b67f09SDavid van Moolenbroek 					}
405*00b67f09SDavid van Moolenbroek 
406*00b67f09SDavid van Moolenbroek 					delete_name(name, NULL);
407*00b67f09SDavid van Moolenbroek 				}
408*00b67f09SDavid van Moolenbroek 
409*00b67f09SDavid van Moolenbroek 			} else if (CMDCHECK("check")) {
410*00b67f09SDavid van Moolenbroek 				/*
411*00b67f09SDavid van Moolenbroek 				 * Or "chain".  I know, I know.  Lame name.
412*00b67f09SDavid van Moolenbroek 				 * I was having a hard time thinking of a
413*00b67f09SDavid van Moolenbroek 				 * name (especially one that did not have
414*00b67f09SDavid van Moolenbroek 				 * a conflicting first letter with another
415*00b67f09SDavid van Moolenbroek 				 * command) that would differentiate this
416*00b67f09SDavid van Moolenbroek 				 * from the search command.
417*00b67f09SDavid van Moolenbroek 				 *
418*00b67f09SDavid van Moolenbroek 				 * But it is just a test program, eh?
419*00b67f09SDavid van Moolenbroek 				 */
420*00b67f09SDavid van Moolenbroek 				name = create_name(arg);
421*00b67f09SDavid van Moolenbroek 				if (name != NULL) {
422*00b67f09SDavid van Moolenbroek 					detail(rbt, name);
423*00b67f09SDavid van Moolenbroek 
424*00b67f09SDavid van Moolenbroek 					delete_name(name, NULL);
425*00b67f09SDavid van Moolenbroek 				}
426*00b67f09SDavid van Moolenbroek 
427*00b67f09SDavid van Moolenbroek 			} else if (CMDCHECK("forward")) {
428*00b67f09SDavid van Moolenbroek 				iterate(rbt, ISC_TRUE);
429*00b67f09SDavid van Moolenbroek 
430*00b67f09SDavid van Moolenbroek 			} else if (CMDCHECK("backward")) {
431*00b67f09SDavid van Moolenbroek 				iterate(rbt, ISC_FALSE);
432*00b67f09SDavid van Moolenbroek 
433*00b67f09SDavid van Moolenbroek 			} else if (CMDCHECK("print")) {
434*00b67f09SDavid van Moolenbroek 				if (arg == NULL || *arg == '\0')
435*00b67f09SDavid van Moolenbroek 					dns_rbt_printtext(rbt, NULL, stdout);
436*00b67f09SDavid van Moolenbroek 				else
437*00b67f09SDavid van Moolenbroek 					printf("usage: print\n");
438*00b67f09SDavid van Moolenbroek 
439*00b67f09SDavid van Moolenbroek 			} else if (CMDCHECK("quit")) {
440*00b67f09SDavid van Moolenbroek 				if (arg == NULL || *arg == '\0')
441*00b67f09SDavid van Moolenbroek 					break;
442*00b67f09SDavid van Moolenbroek 				else
443*00b67f09SDavid van Moolenbroek 					printf("usage: quit\n");
444*00b67f09SDavid van Moolenbroek 			} else {
445*00b67f09SDavid van Moolenbroek 				printf("a(dd) NAME, d(elete) NAME, "
446*00b67f09SDavid van Moolenbroek 				       "s(earch) NAME, p(rint), or q(uit)\n");
447*00b67f09SDavid van Moolenbroek 
448*00b67f09SDavid van Moolenbroek 			}
449*00b67f09SDavid van Moolenbroek 		}
450*00b67f09SDavid van Moolenbroek 
451*00b67f09SDavid van Moolenbroek 	}
452*00b67f09SDavid van Moolenbroek 
453*00b67f09SDavid van Moolenbroek 	dns_rbt_destroy(&rbt);
454*00b67f09SDavid van Moolenbroek 
455*00b67f09SDavid van Moolenbroek 	if (show_final_mem)
456*00b67f09SDavid van Moolenbroek 		isc_mem_stats(mctx, stderr);
457*00b67f09SDavid van Moolenbroek 
458*00b67f09SDavid van Moolenbroek 	return (0);
459*00b67f09SDavid van Moolenbroek }
460