1 /* $NetBSD: db_test.c,v 1.7 2014/12/10 04:37:53 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004, 2005, 2007-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1999-2001 Internet Software Consortium. 6 * 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. 10 * 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. 18 */ 19 20 /* Id: db_test.c,v 1.70 2011/08/29 23:46:44 tbox Exp */ 21 22 /*! \file 23 * \author 24 * Principal Author: Bob Halley 25 */ 26 27 #include <config.h> 28 29 #include <stdlib.h> 30 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> 37 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> 46 47 #define MAXHOLD 100 48 #define MAXVERSIONS 100 49 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; 64 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; 72 73 static void 74 print_result(const char *message, isc_result_t result) { 75 76 if (message == NULL) 77 message = ""; 78 printf("%s%sresult %08x: %s\n", message, (*message == '\0') ? "" : " ", 79 result, isc_result_totext(result)); 80 } 81 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; 88 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); 97 } 98 99 static void 100 print_rdatasets(dns_name_t *name, dns_rdatasetiter_t *rdsiter) { 101 isc_result_t result; 102 dns_rdataset_t rdataset; 103 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); 111 } 112 if (result != ISC_R_NOMORE) 113 print_result("", result); 114 } 115 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; 124 125 if (strcasecmp(origintext, "cache") == 0) { 126 if (cache_dbi == NULL) 127 printf("the cache does not exist\n"); 128 return (cache_dbi); 129 } 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); 139 } 140 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; 146 } 147 148 return (dbi); 149 } 150 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; 163 164 dns_fixedname_init(&fname); 165 name = dns_fixedname_name(&fname); 166 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); 175 } 176 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); 197 } 198 } else 199 result = ISC_R_SUCCESS; 200 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; 213 } 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; 227 } 228 } 229 if (result != ISC_R_NOMORE) 230 print_result("", result); 231 232 dns_dbiterator_destroy(&dbi->dbiterator); 233 if (dbi->iversion != NULL) 234 dns_db_closeversion(dbi->db, &dbi->iversion, ISC_FALSE); 235 } 236 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; 246 247 dbi = isc_mem_get(mctx, sizeof(*dbi)); 248 if (dbi == NULL) 249 return (ISC_R_NOMEMORY); 250 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); 264 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); 273 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); 281 } 282 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); 289 } 290 printf("loaded\n"); 291 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); 301 } 302 } 303 ISC_LIST_APPEND(dbs, dbi, link); 304 305 return (ISC_R_SUCCESS); 306 } 307 308 static void 309 unload_all(void) { 310 dbinfo *dbi, *dbi_next; 311 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; 320 } 321 dns_db_detach(&dbi->db); 322 ISC_LIST_UNLINK(dbs, dbi, link); 323 isc_mem_put(mctx, dbi, sizeof(*dbi)); 324 } 325 } 326 327 #define DBI_CHECK(dbi) \ 328 if ((dbi) == NULL) { \ 329 printf("You must first select a database with !DB\n"); \ 330 continue; \ 331 } 332 333 int 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; 377 378 dns_result_register(); 379 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); 383 384 385 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); 404 } 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; 452 } 453 } 454 455 argc -= isc_commandline_index; 456 argv += isc_commandline_index; 457 POST(argv); 458 459 if (argc != 0) 460 printf("ignoring trailing arguments\n"); 461 462 /* 463 * Some final initialization... 464 */ 465 dns_fixedname_init(&foundname); 466 fname = dns_fixedname_name(&foundname); 467 dbi = NULL; 468 origin = dns_rootname; 469 version = NULL; 470 471 if (time_lookups) { 472 TIME_NOW(&start); 473 } 474 475 while (!done) { 476 if (!quiet) 477 printf("\n"); 478 if (fgets(s, sizeof(s), stdin) == NULL) { 479 done = ISC_TRUE; 480 continue; 481 } 482 len = strlen(s); 483 if (len > 0U && s[len - 1] == '\n') { 484 s[len - 1] = '\0'; 485 len--; 486 } 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]); 494 } 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; 501 } 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; 516 } 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", 540 i); 541 break; 542 } 543 } 544 } 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", 563 i); 564 break; 565 } 566 } 567 } 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; 618 } 619 if (dbi->rversions[v] == NULL) { 620 printf("version %d is not open\n", v); 621 continue; 622 } 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); 676 } 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"); 720 } 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; 738 } 739 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; 747 } 748 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); 761 } 762 continue; 763 } 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; 772 } 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"); 777 } 778 node = NULL; 779 dns_rdataset_init(&rdataset); 780 dns_rdataset_init(&sigrdataset); 781 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); 793 } 794 795 if (!quiet) { 796 if (dbi != NULL) 797 printf("\n"); 798 print_result("", result); 799 } 800 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); 827 } 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; 839 } 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; 850 } 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; 858 } 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); 864 } 865 866 if (printnode) 867 dns_db_printnode(db, node, stdout); 868 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); 886 } 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, 904 0); 905 if (result != ISC_R_SUCCESS) 906 print_result("", result); 907 if (printnode) 908 dns_db_printnode(db, node, stdout); 909 } 910 dns_rdataset_disassociate(&rdataset); 911 } 912 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); 923 } 924 } 925 926 if (time_lookups) { 927 isc_uint64_t usec; 928 929 TIME_NOW(&finish); 930 931 usec = isc_time_microdiff(&finish, &start); 932 933 printf("elapsed time: %lu.%06lu seconds\n", 934 (unsigned long)(usec / 1000000), 935 (unsigned long)(usec % 1000000)); 936 } 937 938 unload_all(); 939 940 dns_dbtable_detach(&dbtable); 941 942 if (lctx != NULL) 943 isc_log_destroy(&lctx); 944 945 if (!quiet) 946 isc_mem_stats(mctx, stdout); 947 948 return (0); 949 } 950