Remove building with NOCRYPTO option
[minix.git] / external / bsd / bind / dist / bin / tests / rbt_test.c
blob450e93fef5b33f50ef55c13dd6df2824aba59ccb
1 /* $NetBSD: rbt_test.c,v 1.6 2014/12/10 04:37:53 christos Exp $ */
3 /*
4 * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1999-2001 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: rbt_test.c,v 1.52 2011/08/28 23:46:41 tbox Exp */
22 #include <config.h>
24 #include <stdlib.h>
26 #include <isc/commandline.h>
27 #include <isc/mem.h>
28 #include <isc/string.h>
29 #include <isc/util.h>
31 #include <dns/rbt.h>
32 #include <dns/fixedname.h>
33 #include <dns/result.h>
35 char *progname;
36 isc_mem_t *mctx;
38 #define DNSNAMELEN 255
40 static dns_name_t *
41 create_name(char *s) {
42 int length;
43 isc_result_t result;
44 isc_buffer_t source, target;
45 static dns_name_t *name;
47 if (s == NULL || *s == '\0') {
48 printf("missing name argument\n");
49 return (NULL);
52 length = strlen(s);
54 isc_buffer_init(&source, s, length);
55 isc_buffer_add(&source, length);
58 * It isn't really necessary in this program to create individual
59 * memory spaces for each name structure and its associated character
60 * string. It is done here to provide a relatively easy way to test
61 * the callback from dns_rbt_deletename that is supposed to free the
62 * data associated with a node.
64 * The buffer for the actual name will immediately follow the
65 * name structure.
67 name = isc_mem_get(mctx, sizeof(*name) + DNSNAMELEN);
68 if (name == NULL) {
69 printf("out of memory!\n");
70 return (NULL);
73 dns_name_init(name, NULL);
74 isc_buffer_init(&target, name + 1, DNSNAMELEN);
76 result = dns_name_fromtext(name, &source, dns_rootname, 0, &target);
78 if (result != ISC_R_SUCCESS) {
79 printf("dns_name_fromtext(%s) failed: %s\n",
80 s, dns_result_totext(result));
81 return (NULL);
84 return (name);
87 static void
88 delete_name(void *data, void *arg) {
89 dns_name_t *name;
91 UNUSED(arg);
92 name = data;
93 isc_mem_put(mctx, name, sizeof(*name) + DNSNAMELEN);
96 static void
97 print_name(dns_name_t *name) {
98 isc_buffer_t target;
99 char buffer[1024];
101 isc_buffer_init(&target, buffer, sizeof(buffer));
104 * ISC_FALSE means absolute names have the final dot added.
106 dns_name_totext(name, ISC_FALSE, &target);
108 printf("%.*s", (int)target.used, (char *)target.base);
111 static void
112 detail(dns_rbt_t *rbt, dns_name_t *name) {
113 dns_name_t *foundname, *origin, *fullname;
114 dns_fixedname_t fixedfoundname, fixedorigin, fixedfullname;
115 dns_rbtnode_t *node1, *node2;
116 dns_rbtnodechain_t chain;
117 isc_result_t result;
118 isc_boolean_t nodes_should_match = ISC_FALSE;
120 dns_rbtnodechain_init(&chain, mctx);
122 dns_fixedname_init(&fixedorigin);
123 dns_fixedname_init(&fixedfullname);
124 dns_fixedname_init(&fixedfoundname);
126 origin = dns_fixedname_name(&fixedorigin);
127 fullname = dns_fixedname_name(&fixedfullname);
128 foundname = dns_fixedname_name(&fixedfoundname);
130 node1 = node2 = NULL;
132 printf("checking chain information for ");
133 print_name(name);
134 printf("\n");
136 result = dns_rbt_findnode(rbt, name, foundname, &node1, &chain,
137 DNS_RBTFIND_EMPTYDATA, NULL, NULL);
139 switch (result) {
140 case ISC_R_SUCCESS:
141 printf(" found exact.");
142 nodes_should_match = ISC_TRUE;
143 break;
144 case DNS_R_PARTIALMATCH:
145 printf(" found parent.");
146 break;
147 case ISC_R_NOTFOUND:
148 printf(" name not found.");
149 break;
150 default:
151 printf(" unexpected result: %s\n", dns_result_totext(result));
152 return;
155 if (node1 != NULL && node1->data != NULL) {
156 printf(" data at node: ");
157 print_name(node1->data);
158 } else
159 printf(" no data at node.");
161 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
162 printf("\n name from dns_rbt_findnode: ");
163 print_name(foundname);
166 result = dns_rbtnodechain_current(&chain, foundname, origin, &node2);
168 if (result == ISC_R_SUCCESS) {
169 printf("\n name from dns_rbtnodechain_current: ");
171 result = dns_name_concatenate(foundname, origin,
172 fullname, NULL);
173 if (result == ISC_R_SUCCESS)
174 print_name(fullname);
175 else
176 printf("%s\n", dns_result_totext(result));
177 printf("\n (foundname = ");
178 print_name(foundname);
179 printf(", origin = ");
180 print_name(origin);
181 printf(")\n");
182 if (nodes_should_match && node1 != node2)
183 printf(" nodes returned from each function "
184 "DO NOT match!\n");
186 } else
187 printf("\n result from dns_rbtnodechain_current: %s\n",
188 dns_result_totext(result));
190 printf(" level_matches = %d, level_count = %d\n",
191 chain.level_matches, chain.level_count);
194 static void
195 iterate(dns_rbt_t *rbt, isc_boolean_t forward) {
196 dns_name_t foundname, *origin;
197 dns_rbtnodechain_t chain;
198 dns_fixedname_t fixedorigin;
199 isc_result_t result;
200 isc_result_t (*move)(dns_rbtnodechain_t *chain, dns_name_t *name,
201 dns_name_t *origin);
203 dns_rbtnodechain_init(&chain, mctx);
205 dns_name_init(&foundname, NULL);
206 dns_fixedname_init(&fixedorigin);
207 origin = dns_fixedname_name(&fixedorigin);
209 if (forward) {
210 printf("iterating forward\n" );
211 move = dns_rbtnodechain_next;
213 result = dns_rbtnodechain_first(&chain, rbt, &foundname,
214 origin);
216 } else {
217 printf("iterating backward\n" );
218 move = dns_rbtnodechain_prev;
220 result = dns_rbtnodechain_last(&chain, rbt, &foundname,
221 origin);
224 if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN)
225 printf("start not found!\n");
227 else {
228 for (;;) {
229 if (result == DNS_R_NEWORIGIN) {
230 printf(" new origin: ");
231 print_name(origin);
232 printf("\n");
235 if (result == ISC_R_SUCCESS ||
236 result == DNS_R_NEWORIGIN) {
237 print_name(&foundname);
238 printf("\n");
240 } else {
241 if (result != ISC_R_NOMORE)
242 printf("UNEXEPCTED ITERATION ERROR: %s",
243 dns_result_totext(result));
244 break;
247 result = move(&chain, &foundname, origin);
253 #define CMDCHECK(s) (strncasecmp(command, (s), length) == 0)
254 #define PRINTERR(r) if (r != ISC_R_SUCCESS) \
255 printf("... %s\n", dns_result_totext(r));
258 main(int argc, char **argv) {
259 char *command, *arg, buffer[1024];
260 const char *whitespace;
261 dns_name_t *name, *foundname;
262 dns_fixedname_t fixedname;
263 dns_rbt_t *rbt = NULL;
264 int length, ch;
265 isc_boolean_t show_final_mem = ISC_FALSE;
266 isc_result_t result;
267 void *data;
269 progname = strrchr(*argv, '/');
270 if (progname != NULL)
271 progname++;
272 else
273 progname = *argv;
275 while ((ch = isc_commandline_parse(argc, argv, "m")) != -1) {
276 switch (ch) {
277 case 'm':
278 show_final_mem = ISC_TRUE;
279 break;
283 argc -= isc_commandline_index;
284 argv += isc_commandline_index;
285 POST(argv);
287 if (argc > 1) {
288 printf("Usage: %s [-m]\n", progname);
289 exit(1);
292 setbuf(stdout, NULL);
295 * So isc_mem_stats() can report any allocation leaks.
297 isc_mem_debugging = ISC_MEM_DEBUGRECORD;
299 result = isc_mem_create(0, 0, &mctx);
300 if (result != ISC_R_SUCCESS) {
301 printf("isc_mem_create: %s: exiting\n",
302 dns_result_totext(result));
303 exit(1);
306 result = dns_rbt_create(mctx, delete_name, NULL, &rbt);
307 if (result != ISC_R_SUCCESS) {
308 printf("dns_rbt_create: %s: exiting\n",
309 dns_result_totext(result));
310 exit(1);
313 whitespace = " \t";
315 while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
316 length = strlen(buffer);
318 if (buffer[length - 1] != '\n') {
319 printf("line to long (%lu max), ignored\n",
320 (unsigned long)sizeof(buffer) - 2);
321 continue;
324 buffer[length - 1] = '\0';
326 command = buffer + strspn(buffer, whitespace);
328 if (*command == '#')
329 continue;
331 arg = strpbrk(command, whitespace);
332 if (arg != NULL) {
333 *arg++ = '\0';
334 arg += strspn(arg, whitespace);
337 length = strlen(command);
338 if (*command != '\0') {
339 if (CMDCHECK("add")) {
340 name = create_name(arg);
341 if (name != NULL) {
342 printf("adding name %s\n", arg);
343 result = dns_rbt_addname(rbt,
344 name, name);
345 PRINTERR(result);
348 } else if (CMDCHECK("delete")) {
349 name = create_name(arg);
350 if (name != NULL) {
351 printf("deleting name %s\n", arg);
352 result = dns_rbt_deletename(rbt, name,
353 ISC_FALSE);
354 PRINTERR(result);
355 delete_name(name, NULL);
358 } else if (CMDCHECK("nuke")) {
359 name = create_name(arg);
360 if (name != NULL) {
361 printf("nuking name %s "
362 "and its descendants\n", arg);
363 result = dns_rbt_deletename(rbt, name,
364 ISC_TRUE);
365 PRINTERR(result);
366 delete_name(name, NULL);
369 } else if (CMDCHECK("search")) {
370 name = create_name(arg);
371 if (name != NULL) {
372 printf("searching for name %s ... ",
373 arg);
375 dns_fixedname_init(&fixedname);
376 foundname =
377 dns_fixedname_name(&fixedname);
378 data = NULL;
380 result = dns_rbt_findname(rbt, name, 0,
381 foundname,
382 &data);
383 switch (result) {
384 case ISC_R_SUCCESS:
385 printf("found exact: ");
386 print_name(data);
387 putchar('\n');
388 break;
389 case DNS_R_PARTIALMATCH:
390 printf("found parent: ");
391 print_name(data);
392 printf("\n\t(foundname: ");
393 print_name(foundname);
394 printf(")\n");
395 break;
396 case ISC_R_NOTFOUND:
397 printf("NOT FOUND!\n");
398 break;
399 case ISC_R_NOMEMORY:
400 printf("OUT OF MEMORY!\n");
401 break;
402 default:
403 printf("UNEXPECTED RESULT\n");
406 delete_name(name, NULL);
409 } else if (CMDCHECK("check")) {
411 * Or "chain". I know, I know. Lame name.
412 * I was having a hard time thinking of a
413 * name (especially one that did not have
414 * a conflicting first letter with another
415 * command) that would differentiate this
416 * from the search command.
418 * But it is just a test program, eh?
420 name = create_name(arg);
421 if (name != NULL) {
422 detail(rbt, name);
424 delete_name(name, NULL);
427 } else if (CMDCHECK("forward")) {
428 iterate(rbt, ISC_TRUE);
430 } else if (CMDCHECK("backward")) {
431 iterate(rbt, ISC_FALSE);
433 } else if (CMDCHECK("print")) {
434 if (arg == NULL || *arg == '\0')
435 dns_rbt_printtext(rbt, NULL, stdout);
436 else
437 printf("usage: print\n");
439 } else if (CMDCHECK("quit")) {
440 if (arg == NULL || *arg == '\0')
441 break;
442 else
443 printf("usage: quit\n");
444 } else {
445 printf("a(dd) NAME, d(elete) NAME, "
446 "s(earch) NAME, p(rint), or q(uit)\n");
453 dns_rbt_destroy(&rbt);
455 if (show_final_mem)
456 isc_mem_stats(mctx, stderr);
458 return (0);