host.c revision 153816
1/* 2 * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 2000-2003 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id: host.c,v 1.76.2.5.2.13 2005/07/04 03:29:45 marka Exp $ */ 19 20#include <config.h> 21#include <limits.h> 22 23#include <isc/app.h> 24#include <isc/commandline.h> 25#include <isc/netaddr.h> 26#include <isc/print.h> 27#include <isc/string.h> 28#include <isc/util.h> 29#include <isc/task.h> 30#include <isc/stdlib.h> 31 32#include <dns/byaddr.h> 33#include <dns/fixedname.h> 34#include <dns/message.h> 35#include <dns/name.h> 36#include <dns/rdata.h> 37#include <dns/rdataclass.h> 38#include <dns/rdataset.h> 39#include <dns/rdatatype.h> 40 41#include <dig/dig.h> 42 43static isc_boolean_t short_form = ISC_TRUE, listed_server = ISC_FALSE; 44static isc_boolean_t default_lookups = ISC_TRUE; 45static int seen_error = -1; 46static isc_boolean_t list_addresses = ISC_TRUE; 47static dns_rdatatype_t list_type = dns_rdatatype_a; 48 49static const char *opcodetext[] = { 50 "QUERY", 51 "IQUERY", 52 "STATUS", 53 "RESERVED3", 54 "NOTIFY", 55 "UPDATE", 56 "RESERVED6", 57 "RESERVED7", 58 "RESERVED8", 59 "RESERVED9", 60 "RESERVED10", 61 "RESERVED11", 62 "RESERVED12", 63 "RESERVED13", 64 "RESERVED14", 65 "RESERVED15" 66}; 67 68static const char *rcodetext[] = { 69 "NOERROR", 70 "FORMERR", 71 "SERVFAIL", 72 "NXDOMAIN", 73 "NOTIMP", 74 "REFUSED", 75 "YXDOMAIN", 76 "YXRRSET", 77 "NXRRSET", 78 "NOTAUTH", 79 "NOTZONE", 80 "RESERVED11", 81 "RESERVED12", 82 "RESERVED13", 83 "RESERVED14", 84 "RESERVED15", 85 "BADVERS" 86}; 87 88struct rtype { 89 unsigned int type; 90 const char *text; 91}; 92 93struct rtype rtypes[] = { 94 { 1, "has address" }, 95 { 2, "name server" }, 96 { 5, "is an alias for" }, 97 { 11, "has well known services" }, 98 { 12, "domain name pointer" }, 99 { 13, "host information" }, 100 { 15, "mail is handled by" }, 101 { 16, "descriptive text" }, 102 { 19, "x25 address" }, 103 { 20, "ISDN address" }, 104 { 24, "has signature" }, 105 { 25, "has key" }, 106 { 28, "has IPv6 address" }, 107 { 29, "location" }, 108 { 0, NULL } 109}; 110 111static void 112show_usage(void) { 113 fputs( 114"Usage: host [-aCdlriTwv] [-c class] [-N ndots] [-t type] [-W time]\n" 115" [-R number] hostname [server]\n" 116" -a is equivalent to -v -t *\n" 117" -c specifies query class for non-IN data\n" 118" -C compares SOA records on authoritative nameservers\n" 119" -d is equivalent to -v\n" 120" -l lists all hosts in a domain, using AXFR\n" 121" -i IP6.INT reverse lookups\n" 122" -N changes the number of dots allowed before root lookup is done\n" 123" -r disables recursive processing\n" 124" -R specifies number of retries for UDP packets\n" 125" -t specifies the query type\n" 126" -T enables TCP/IP mode\n" 127" -v enables verbose output\n" 128" -w specifies to wait forever for a reply\n" 129" -W specifies how long to wait for a reply\n" 130" -4 use IPv4 query transport only\n" 131" -6 use IPv6 query transport only\n", stderr); 132 exit(1); 133} 134 135void 136dighost_shutdown(void) { 137 isc_app_shutdown(); 138} 139 140void 141received(int bytes, isc_sockaddr_t *from, dig_query_t *query) { 142 isc_time_t now; 143 int diff; 144 145 if (!short_form) { 146 char fromtext[ISC_SOCKADDR_FORMATSIZE]; 147 isc_sockaddr_format(from, fromtext, sizeof(fromtext)); 148 TIME_NOW(&now); 149 diff = (int) isc_time_microdiff(&now, &query->time_sent); 150 printf("Received %u bytes from %s in %d ms\n", 151 bytes, fromtext, diff/1000); 152 } 153} 154 155void 156trying(char *frm, dig_lookup_t *lookup) { 157 UNUSED(lookup); 158 159 if (!short_form) 160 printf("Trying \"%s\"\n", frm); 161} 162 163static void 164say_message(dns_name_t *name, const char *msg, dns_rdata_t *rdata, 165 dig_query_t *query) 166{ 167 isc_buffer_t *b = NULL; 168 char namestr[DNS_NAME_FORMATSIZE]; 169 isc_region_t r; 170 isc_result_t result; 171 unsigned int bufsize = BUFSIZ; 172 173 dns_name_format(name, namestr, sizeof(namestr)); 174 retry: 175 result = isc_buffer_allocate(mctx, &b, bufsize); 176 check_result(result, "isc_buffer_allocate"); 177 result = dns_rdata_totext(rdata, NULL, b); 178 if (result == ISC_R_NOSPACE) { 179 isc_buffer_free(&b); 180 bufsize *= 2; 181 goto retry; 182 } 183 check_result(result, "dns_rdata_totext"); 184 isc_buffer_usedregion(b, &r); 185 if (query->lookup->identify_previous_line) { 186 printf("Nameserver %s:\n\t", 187 query->servname); 188 } 189 printf("%s %s %.*s", namestr, 190 msg, (int)r.length, (char *)r.base); 191 if (query->lookup->identify) { 192 printf(" on server %s", query->servname); 193 } 194 printf("\n"); 195 isc_buffer_free(&b); 196} 197#ifdef DIG_SIGCHASE 198/* Just for compatibility : not use in host program */ 199isc_result_t 200printrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset, 201 isc_buffer_t *target) 202{ 203 UNUSED(owner_name); 204 UNUSED(rdataset); 205 UNUSED(target); 206 return(ISC_FALSE); 207} 208#endif 209static isc_result_t 210printsection(dns_message_t *msg, dns_section_t sectionid, 211 const char *section_name, isc_boolean_t headers, 212 dig_query_t *query) 213{ 214 dns_name_t *name, *print_name; 215 dns_rdataset_t *rdataset; 216 dns_rdata_t rdata = DNS_RDATA_INIT; 217 isc_buffer_t target; 218 isc_result_t result, loopresult; 219 isc_region_t r; 220 dns_name_t empty_name; 221 char t[4096]; 222 isc_boolean_t first; 223 isc_boolean_t no_rdata; 224 225 if (sectionid == DNS_SECTION_QUESTION) 226 no_rdata = ISC_TRUE; 227 else 228 no_rdata = ISC_FALSE; 229 230 if (headers) 231 printf(";; %s SECTION:\n", section_name); 232 233 dns_name_init(&empty_name, NULL); 234 235 result = dns_message_firstname(msg, sectionid); 236 if (result == ISC_R_NOMORE) 237 return (ISC_R_SUCCESS); 238 else if (result != ISC_R_SUCCESS) 239 return (result); 240 241 for (;;) { 242 name = NULL; 243 dns_message_currentname(msg, sectionid, &name); 244 245 isc_buffer_init(&target, t, sizeof(t)); 246 first = ISC_TRUE; 247 print_name = name; 248 249 for (rdataset = ISC_LIST_HEAD(name->list); 250 rdataset != NULL; 251 rdataset = ISC_LIST_NEXT(rdataset, link)) { 252 if (query->lookup->rdtype == dns_rdatatype_axfr && 253 !((!list_addresses && 254 (list_type == dns_rdatatype_any || 255 rdataset->type == list_type)) || 256 (list_addresses && 257 (rdataset->type == dns_rdatatype_a || 258 rdataset->type == dns_rdatatype_aaaa || 259 rdataset->type == dns_rdatatype_ns || 260 rdataset->type == dns_rdatatype_ptr)))) 261 continue; 262 if (!short_form) { 263 result = dns_rdataset_totext(rdataset, 264 print_name, 265 ISC_FALSE, 266 no_rdata, 267 &target); 268 if (result != ISC_R_SUCCESS) 269 return (result); 270#ifdef USEINITALWS 271 if (first) { 272 print_name = &empty_name; 273 first = ISC_FALSE; 274 } 275#else 276 UNUSED(first); /* Shut up compiler. */ 277#endif 278 } else { 279 loopresult = dns_rdataset_first(rdataset); 280 while (loopresult == ISC_R_SUCCESS) { 281 struct rtype *t; 282 const char *rtt; 283 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 284 char typebuf2[DNS_RDATATYPE_FORMATSIZE 285 + 20]; 286 dns_rdataset_current(rdataset, &rdata); 287 288 for (t = rtypes; t->text != NULL; t++) { 289 if (t->type == rdata.type) { 290 rtt = t->text; 291 goto found; 292 } 293 } 294 295 dns_rdatatype_format(rdata.type, 296 typebuf, 297 sizeof(typebuf)); 298 snprintf(typebuf2, sizeof(typebuf2), 299 "has %s record", typebuf); 300 rtt = typebuf2; 301 found: 302 say_message(print_name, rtt, 303 &rdata, query); 304 dns_rdata_reset(&rdata); 305 loopresult = 306 dns_rdataset_next(rdataset); 307 } 308 } 309 } 310 if (!short_form) { 311 isc_buffer_usedregion(&target, &r); 312 if (no_rdata) 313 printf(";%.*s", (int)r.length, 314 (char *)r.base); 315 else 316 printf("%.*s", (int)r.length, (char *)r.base); 317 } 318 319 result = dns_message_nextname(msg, sectionid); 320 if (result == ISC_R_NOMORE) 321 break; 322 else if (result != ISC_R_SUCCESS) 323 return (result); 324 } 325 326 return (ISC_R_SUCCESS); 327} 328 329static isc_result_t 330printrdata(dns_message_t *msg, dns_rdataset_t *rdataset, dns_name_t *owner, 331 const char *set_name, isc_boolean_t headers) 332{ 333 isc_buffer_t target; 334 isc_result_t result; 335 isc_region_t r; 336 char t[4096]; 337 338 UNUSED(msg); 339 if (headers) 340 printf(";; %s SECTION:\n", set_name); 341 342 isc_buffer_init(&target, t, sizeof(t)); 343 344 result = dns_rdataset_totext(rdataset, owner, ISC_FALSE, ISC_FALSE, 345 &target); 346 if (result != ISC_R_SUCCESS) 347 return (result); 348 isc_buffer_usedregion(&target, &r); 349 printf("%.*s", (int)r.length, (char *)r.base); 350 351 return (ISC_R_SUCCESS); 352} 353 354isc_result_t 355printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) { 356 isc_boolean_t did_flag = ISC_FALSE; 357 dns_rdataset_t *opt, *tsig = NULL; 358 dns_name_t *tsigname; 359 isc_result_t result = ISC_R_SUCCESS; 360 int force_error; 361 362 UNUSED(headers); 363 364 /* 365 * We get called multiple times. 366 * Preserve any existing error status. 367 */ 368 force_error = (seen_error == 1) ? 1 : 0; 369 seen_error = 1; 370 if (listed_server) { 371 char sockstr[ISC_SOCKADDR_FORMATSIZE]; 372 373 printf("Using domain server:\n"); 374 printf("Name: %s\n", query->userarg); 375 isc_sockaddr_format(&query->sockaddr, sockstr, 376 sizeof(sockstr)); 377 printf("Address: %s\n", sockstr); 378 printf("Aliases: \n\n"); 379 } 380 381 if (msg->rcode != 0) { 382 char namestr[DNS_NAME_FORMATSIZE]; 383 dns_name_format(query->lookup->name, namestr, sizeof(namestr)); 384 printf("Host %s not found: %d(%s)\n", namestr, 385 msg->rcode, rcodetext[msg->rcode]); 386 return (ISC_R_SUCCESS); 387 } 388 389 if (default_lookups && query->lookup->rdtype == dns_rdatatype_a) { 390 char namestr[DNS_NAME_FORMATSIZE]; 391 dig_lookup_t *lookup; 392 393 /* Add AAAA and MX lookups. */ 394 395 dns_name_format(query->lookup->name, namestr, sizeof(namestr)); 396 lookup = clone_lookup(query->lookup, ISC_FALSE); 397 if (lookup != NULL) { 398 strncpy(lookup->textname, namestr, 399 sizeof(lookup->textname)); 400 lookup->textname[sizeof(lookup->textname)-1] = 0; 401 lookup->rdtype = dns_rdatatype_aaaa; 402 lookup->rdtypeset = ISC_TRUE; 403 lookup->origin = NULL; 404 lookup->retries = tries; 405 ISC_LIST_APPEND(lookup_list, lookup, link); 406 } 407 lookup = clone_lookup(query->lookup, ISC_FALSE); 408 if (lookup != NULL) { 409 strncpy(lookup->textname, namestr, 410 sizeof(lookup->textname)); 411 lookup->textname[sizeof(lookup->textname)-1] = 0; 412 lookup->rdtype = dns_rdatatype_mx; 413 lookup->rdtypeset = ISC_TRUE; 414 lookup->origin = NULL; 415 lookup->retries = tries; 416 ISC_LIST_APPEND(lookup_list, lookup, link); 417 } 418 } 419 420 if (!short_form) { 421 printf(";; ->>HEADER<<- opcode: %s, status: %s, id: %u\n", 422 opcodetext[msg->opcode], rcodetext[msg->rcode], 423 msg->id); 424 printf(";; flags: "); 425 if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) { 426 printf("qr"); 427 did_flag = ISC_TRUE; 428 } 429 if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0) { 430 printf("%saa", did_flag ? " " : ""); 431 did_flag = ISC_TRUE; 432 } 433 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 434 printf("%stc", did_flag ? " " : ""); 435 did_flag = ISC_TRUE; 436 } 437 if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) { 438 printf("%srd", did_flag ? " " : ""); 439 did_flag = ISC_TRUE; 440 } 441 if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0) { 442 printf("%sra", did_flag ? " " : ""); 443 did_flag = ISC_TRUE; 444 } 445 if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0) { 446 printf("%sad", did_flag ? " " : ""); 447 did_flag = ISC_TRUE; 448 } 449 if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0) { 450 printf("%scd", did_flag ? " " : ""); 451 did_flag = ISC_TRUE; 452 } 453 printf("; QUERY: %u, ANSWER: %u, " 454 "AUTHORITY: %u, ADDITIONAL: %u\n", 455 msg->counts[DNS_SECTION_QUESTION], 456 msg->counts[DNS_SECTION_ANSWER], 457 msg->counts[DNS_SECTION_AUTHORITY], 458 msg->counts[DNS_SECTION_ADDITIONAL]); 459 opt = dns_message_getopt(msg); 460 if (opt != NULL) 461 printf(";; EDNS: version: %u, udp=%u\n", 462 (unsigned int)((opt->ttl & 0x00ff0000) >> 16), 463 (unsigned int)opt->rdclass); 464 tsigname = NULL; 465 tsig = dns_message_gettsig(msg, &tsigname); 466 if (tsig != NULL) 467 printf(";; PSEUDOSECTIONS: TSIG\n"); 468 } 469 if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_QUESTION]) && 470 !short_form) { 471 printf("\n"); 472 result = printsection(msg, DNS_SECTION_QUESTION, "QUESTION", 473 ISC_TRUE, query); 474 if (result != ISC_R_SUCCESS) 475 return (result); 476 } 477 if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER])) { 478 if (!short_form) 479 printf("\n"); 480 result = printsection(msg, DNS_SECTION_ANSWER, "ANSWER", 481 ISC_TF(!short_form), query); 482 if (result != ISC_R_SUCCESS) 483 return (result); 484 } 485 486 if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_AUTHORITY]) && 487 !short_form) { 488 printf("\n"); 489 result = printsection(msg, DNS_SECTION_AUTHORITY, "AUTHORITY", 490 ISC_TRUE, query); 491 if (result != ISC_R_SUCCESS) 492 return (result); 493 } 494 if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ADDITIONAL]) && 495 !short_form) { 496 printf("\n"); 497 result = printsection(msg, DNS_SECTION_ADDITIONAL, 498 "ADDITIONAL", ISC_TRUE, query); 499 if (result != ISC_R_SUCCESS) 500 return (result); 501 } 502 if ((tsig != NULL) && !short_form) { 503 printf("\n"); 504 result = printrdata(msg, tsig, tsigname, 505 "PSEUDOSECTION TSIG", ISC_TRUE); 506 if (result != ISC_R_SUCCESS) 507 return (result); 508 } 509 if (!short_form) 510 printf("\n"); 511 512 if (short_form && !default_lookups && 513 ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER])) { 514 char namestr[DNS_NAME_FORMATSIZE]; 515 char typestr[DNS_RDATATYPE_FORMATSIZE]; 516 dns_name_format(query->lookup->name, namestr, sizeof(namestr)); 517 dns_rdatatype_format(query->lookup->rdtype, typestr, 518 sizeof(typestr)); 519 printf("%s has no %s record\n", namestr, typestr); 520 } 521 seen_error = force_error; 522 return (result); 523} 524 525static void 526parse_args(isc_boolean_t is_batchfile, int argc, char **argv) { 527 char hostname[MXNAME]; 528 dig_lookup_t *lookup; 529 int c; 530 char store[MXNAME]; 531 isc_textregion_t tr; 532 isc_result_t result = ISC_R_SUCCESS; 533 dns_rdatatype_t rdtype; 534 dns_rdataclass_t rdclass; 535 isc_uint32_t serial = 0; 536 537 UNUSED(is_batchfile); 538 539 lookup = make_empty_lookup(); 540 541 while ((c = isc_commandline_parse(argc, argv, "lvwrdt:c:aTCN:R:W:Dni46")) 542 != EOF) { 543 switch (c) { 544 case 'l': 545 lookup->tcp_mode = ISC_TRUE; 546 lookup->rdtype = dns_rdatatype_axfr; 547 lookup->rdtypeset = ISC_TRUE; 548 fatalexit = 3; 549 break; 550 case 'v': 551 case 'd': 552 short_form = ISC_FALSE; 553 break; 554 case 'r': 555 lookup->recurse = ISC_FALSE; 556 break; 557 case 't': 558 if (strncasecmp(isc_commandline_argument, 559 "ixfr=", 5) == 0) { 560 rdtype = dns_rdatatype_ixfr; 561 /* XXXMPA add error checking */ 562 serial = strtoul(isc_commandline_argument + 5, 563 NULL, 10); 564 result = ISC_R_SUCCESS; 565 } else { 566 tr.base = isc_commandline_argument; 567 tr.length = strlen(isc_commandline_argument); 568 result = dns_rdatatype_fromtext(&rdtype, 569 (isc_textregion_t *)&tr); 570 } 571 572 if (result != ISC_R_SUCCESS) { 573 fatalexit = 2; 574 fatal("invalid type: %s\n", 575 isc_commandline_argument); 576 } 577 if (!lookup->rdtypeset || 578 lookup->rdtype != dns_rdatatype_axfr) 579 lookup->rdtype = rdtype; 580 lookup->rdtypeset = ISC_TRUE; 581 if (rdtype == dns_rdatatype_axfr) { 582 /* -l -t any -v */ 583 list_type = dns_rdatatype_any; 584 short_form = ISC_FALSE; 585 lookup->tcp_mode = ISC_TRUE; 586 } else if (rdtype == dns_rdatatype_ixfr) { 587 lookup->ixfr_serial = serial; 588 list_type = rdtype; 589 } else 590 list_type = rdtype; 591 list_addresses = ISC_FALSE; 592 default_lookups = ISC_FALSE; 593 break; 594 case 'c': 595 tr.base = isc_commandline_argument; 596 tr.length = strlen(isc_commandline_argument); 597 result = dns_rdataclass_fromtext(&rdclass, 598 (isc_textregion_t *)&tr); 599 600 if (result != ISC_R_SUCCESS) { 601 fatalexit = 2; 602 fatal("invalid class: %s\n", 603 isc_commandline_argument); 604 } else { 605 lookup->rdclass = rdclass; 606 lookup->rdclassset = ISC_TRUE; 607 } 608 default_lookups = ISC_FALSE; 609 break; 610 case 'a': 611 if (!lookup->rdtypeset || 612 lookup->rdtype != dns_rdatatype_axfr) 613 lookup->rdtype = dns_rdatatype_any; 614 list_type = dns_rdatatype_any; 615 list_addresses = ISC_FALSE; 616 lookup->rdtypeset = ISC_TRUE; 617 short_form = ISC_FALSE; 618 default_lookups = ISC_FALSE; 619 break; 620 case 'i': 621 lookup->ip6_int = ISC_TRUE; 622 break; 623 case 'n': 624 /* deprecated */ 625 break; 626 case 'w': 627 /* 628 * The timer routines are coded such that 629 * timeout==MAXINT doesn't enable the timer 630 */ 631 timeout = INT_MAX; 632 break; 633 case 'W': 634 timeout = atoi(isc_commandline_argument); 635 if (timeout < 1) 636 timeout = 1; 637 break; 638 case 'R': 639 tries = atoi(isc_commandline_argument) + 1; 640 if (tries < 2) 641 tries = 2; 642 break; 643 case 'T': 644 lookup->tcp_mode = ISC_TRUE; 645 break; 646 case 'C': 647 debug("showing all SOAs"); 648 lookup->rdtype = dns_rdatatype_ns; 649 lookup->rdtypeset = ISC_TRUE; 650 lookup->rdclass = dns_rdataclass_in; 651 lookup->rdclassset = ISC_TRUE; 652 lookup->ns_search_only = ISC_TRUE; 653 lookup->trace_root = ISC_TRUE; 654 lookup->identify_previous_line = ISC_TRUE; 655 default_lookups = ISC_FALSE; 656 break; 657 case 'N': 658 debug("setting NDOTS to %s", 659 isc_commandline_argument); 660 ndots = atoi(isc_commandline_argument); 661 break; 662 case 'D': 663 debugging = ISC_TRUE; 664 break; 665 case '4': 666 if (have_ipv4) { 667 isc_net_disableipv6(); 668 have_ipv6 = ISC_FALSE; 669 } else 670 fatal("can't find IPv4 networking"); 671 break; 672 case '6': 673 if (have_ipv6) { 674 isc_net_disableipv4(); 675 have_ipv4 = ISC_FALSE; 676 } else 677 fatal("can't find IPv6 networking"); 678 break; 679 } 680 } 681 682 lookup->retries = tries; 683 684 if (isc_commandline_index >= argc) 685 show_usage(); 686 687 strncpy(hostname, argv[isc_commandline_index], sizeof(hostname)); 688 hostname[sizeof(hostname)-1]=0; 689 if (argc > isc_commandline_index + 1) { 690 set_nameserver(argv[isc_commandline_index+1]); 691 debug("server is %s", argv[isc_commandline_index+1]); 692 listed_server = ISC_TRUE; 693 } 694 695 lookup->pending = ISC_FALSE; 696 if (get_reverse(store, sizeof(store), hostname, 697 lookup->ip6_int, ISC_TRUE) == ISC_R_SUCCESS) { 698 strncpy(lookup->textname, store, sizeof(lookup->textname)); 699 lookup->textname[sizeof(lookup->textname)-1] = 0; 700 lookup->rdtype = dns_rdatatype_ptr; 701 lookup->rdtypeset = ISC_TRUE; 702 default_lookups = ISC_FALSE; 703 } else { 704 strncpy(lookup->textname, hostname, sizeof(lookup->textname)); 705 lookup->textname[sizeof(lookup->textname)-1]=0; 706 } 707 lookup->new_search = ISC_TRUE; 708 ISC_LIST_APPEND(lookup_list, lookup, link); 709 710 usesearch = ISC_TRUE; 711} 712 713int 714main(int argc, char **argv) { 715 isc_result_t result; 716 717 tries = 2; 718 719 ISC_LIST_INIT(lookup_list); 720 ISC_LIST_INIT(server_list); 721 ISC_LIST_INIT(search_list); 722 723 fatalexit = 1; 724 725 debug("main()"); 726 progname = argv[0]; 727 result = isc_app_start(); 728 check_result(result, "isc_app_start"); 729 setup_libs(); 730 parse_args(ISC_FALSE, argc, argv); 731 setup_system(); 732 result = isc_app_onrun(mctx, global_task, onrun_callback, NULL); 733 check_result(result, "isc_app_onrun"); 734 isc_app_run(); 735 cancel_all(); 736 destroy_libs(); 737 isc_app_finish(); 738 return ((seen_error == 0) ? 0 : 1); 739} 740 741