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