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