2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000-2003 Internet Software Consortium.
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.
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.
18 /* $Id: nslookup.c,v 1.90.2.7 2004/06/07 03:59:08 marka Exp $ */
25 #include <isc/buffer.h>
26 #include <isc/commandline.h>
27 #include <isc/event.h>
28 #include <isc/string.h>
29 #include <isc/timer.h>
32 #include <isc/netaddr.h>
34 #include <dns/message.h>
36 #include <dns/fixedname.h>
37 #include <dns/rdata.h>
38 #include <dns/rdataclass.h>
39 #include <dns/rdataset.h>
40 #include <dns/rdatastruct.h>
41 #include <dns/rdatatype.h>
42 #include <dns/byaddr.h>
46 extern ISC_LIST(dig_lookup_t) lookup_list;
47 extern ISC_LIST(dig_server_t) server_list;
48 extern ISC_LIST(dig_searchlist_t) search_list;
50 extern isc_boolean_t have_ipv6, usesearch, qr, debugging;
51 extern in_port_t port;
52 extern unsigned int timeout;
53 extern isc_mem_t *mctx;
54 extern dns_messageid_t id;
58 extern int lookup_counter;
60 extern isc_taskmgr_t *taskmgr;
61 extern isc_task_t *global_task;
62 extern char *progname;
64 static isc_boolean_t short_form = ISC_TRUE,
65 tcpmode = ISC_FALSE, deprecation_msg = ISC_TRUE,
66 identify = ISC_FALSE, stats = ISC_TRUE,
67 comments = ISC_TRUE, section_question = ISC_TRUE,
68 section_answer = ISC_TRUE, section_authority = ISC_TRUE,
69 section_additional = ISC_TRUE, recurse = ISC_TRUE,
71 static isc_boolean_t in_use = ISC_FALSE;
72 static char defclass[MXRD] = "IN";
73 static char deftype[MXRD] = "A";
74 static isc_event_t *global_event = NULL;
76 static char domainopt[DNS_NAME_MAXTEXT];
78 static const char *rcodetext[] = {
98 static const char *rtypetext[] = {
100 "internet address = ", /* 1 */
101 "nameserver = ", /* 2 */
104 "canonical name = ", /* 5 */
109 "rtype_10 = ", /* 10 */
110 "protocol = ", /* 11 */
114 "mail exchanger = ", /* 15 */
118 "x25 address = ", /* 19 */
119 "isdn address = ", /* 20 */
122 "nsap_ptr = ", /* 23 */
123 "signature = ", /* 24 */
127 "has AAAA address ", /* 28 */
130 "rtype_31 = ", /* 31 */
131 "rtype_32 = ", /* 32 */
132 "service = ", /* 33 */
133 "rtype_34 = ", /* 34 */
137 "v6 address = ", /* 38 */
139 "rtype_40 = ", /* 40 */
140 "optional = "}; /* 41 */
142 #define N_KNOWN_RRTYPES (sizeof(rtypetext) / sizeof(rtypetext[0]))
144 static void flush_lookup_list(void);
145 static void getinput(isc_task_t *task, isc_event_t *event);
148 dighost_shutdown(void) {
149 isc_event_t *event = global_event;
152 debug("dighost_shutdown()");
159 isc_task_send(global_task, &event);
163 printsoa(dns_rdata_t *rdata) {
166 char namebuf[DNS_NAME_FORMATSIZE];
168 result = dns_rdata_tostruct(rdata, &soa, NULL);
169 check_result(result, "dns_rdata_tostruct");
171 dns_name_format(&soa.origin, namebuf, sizeof(namebuf));
172 printf("\torigin = %s\n", namebuf);
173 dns_name_format(&soa.contact, namebuf, sizeof(namebuf));
174 printf("\tmail addr = %s\n", namebuf);
175 printf("\tserial = %u\n", soa.serial);
176 printf("\trefresh = %u\n", soa.refresh);
177 printf("\tretry = %u\n", soa.retry);
178 printf("\texpire = %u\n", soa.expire);
179 printf("\tminimum = %u\n", soa.minimum);
180 dns_rdata_freestruct(&soa);
184 printa(dns_rdata_t *rdata) {
186 char text[sizeof("255.255.255.255")];
189 isc_buffer_init(&b, text, sizeof(text));
190 result = dns_rdata_totext(rdata, NULL, &b);
191 check_result(result, "dns_rdata_totext");
192 printf("Address: %.*s\n", (int)isc_buffer_usedlength(&b),
193 (char *)isc_buffer_base(&b));
197 printrdata(dns_rdata_t *rdata) {
199 isc_buffer_t *b = NULL;
200 unsigned int size = 1024;
201 isc_boolean_t done = ISC_FALSE;
203 if (rdata->type < N_KNOWN_RRTYPES)
204 printf("%s", rtypetext[rdata->type]);
206 printf("rdata_%d = ", rdata->type);
209 result = isc_buffer_allocate(mctx, &b, size);
210 if (result != ISC_R_SUCCESS)
211 check_result(result, "isc_buffer_allocate");
212 result = dns_rdata_totext(rdata, NULL, b);
213 if (result == ISC_R_SUCCESS) {
214 printf("%.*s\n", (int)isc_buffer_usedlength(b),
215 (char *)isc_buffer_base(b));
217 } else if (result != ISC_R_NOSPACE)
218 check_result(result, "dns_rdata_totext");
225 printsection(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers,
226 dns_section_t section) {
227 isc_result_t result, loopresult;
229 dns_rdataset_t *rdataset = NULL;
230 dns_rdata_t rdata = DNS_RDATA_INIT;
231 char namebuf[DNS_NAME_FORMATSIZE];
236 debug("printsection()");
238 result = dns_message_firstname(msg, section);
239 if (result == ISC_R_NOMORE)
240 return (ISC_R_SUCCESS);
241 else if (result != ISC_R_SUCCESS)
245 dns_message_currentname(msg, section,
247 for (rdataset = ISC_LIST_HEAD(name->list);
249 rdataset = ISC_LIST_NEXT(rdataset, link)) {
250 loopresult = dns_rdataset_first(rdataset);
251 while (loopresult == ISC_R_SUCCESS) {
252 dns_rdataset_current(rdataset, &rdata);
253 switch (rdata.type) {
254 case dns_rdatatype_a:
255 if (section != DNS_SECTION_ANSWER)
256 goto def_short_section;
257 dns_name_format(name, namebuf,
259 printf("Name:\t%s\n", namebuf);
262 case dns_rdatatype_soa:
263 dns_name_format(name, namebuf,
265 printf("%s\n", namebuf);
270 dns_name_format(name, namebuf,
272 printf("%s\t", namebuf);
276 dns_rdata_reset(&rdata);
277 loopresult = dns_rdataset_next(rdataset);
280 result = dns_message_nextname(msg, section);
281 if (result == ISC_R_NOMORE)
283 else if (result != ISC_R_SUCCESS) {
287 return (ISC_R_SUCCESS);
291 detailsection(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers,
292 dns_section_t section) {
293 isc_result_t result, loopresult;
295 dns_rdataset_t *rdataset = NULL;
296 dns_rdata_t rdata = DNS_RDATA_INIT;
297 char namebuf[DNS_NAME_FORMATSIZE];
301 debug("detailsection()");
305 case DNS_SECTION_QUESTION:
308 case DNS_SECTION_ANSWER:
311 case DNS_SECTION_AUTHORITY:
312 puts(" AUTHORITY RECORDS:");
314 case DNS_SECTION_ADDITIONAL:
315 puts(" ADDITIONAL RECORDS:");
320 result = dns_message_firstname(msg, section);
321 if (result == ISC_R_NOMORE)
322 return (ISC_R_SUCCESS);
323 else if (result != ISC_R_SUCCESS)
327 dns_message_currentname(msg, section,
329 for (rdataset = ISC_LIST_HEAD(name->list);
331 rdataset = ISC_LIST_NEXT(rdataset, link)) {
332 if (section == DNS_SECTION_QUESTION) {
333 dns_name_format(name, namebuf,
335 printf("\t%s, ", namebuf);
336 dns_rdatatype_format(rdataset->type,
339 printf("type = %s, ", namebuf);
340 dns_rdataclass_format(rdataset->rdclass,
343 printf("class = %s\n", namebuf);
345 loopresult = dns_rdataset_first(rdataset);
346 while (loopresult == ISC_R_SUCCESS) {
347 dns_rdataset_current(rdataset, &rdata);
349 dns_name_format(name, namebuf,
351 printf(" -> %s\n", namebuf);
353 switch (rdata.type) {
354 case dns_rdatatype_soa:
361 dns_rdata_reset(&rdata);
362 loopresult = dns_rdataset_next(rdataset);
365 result = dns_message_nextname(msg, section);
366 if (result == ISC_R_NOMORE)
368 else if (result != ISC_R_SUCCESS) {
372 return (ISC_R_SUCCESS);
376 received(int bytes, isc_sockaddr_t *from, dig_query_t *query)
384 trying(char *frm, dig_lookup_t *lookup) {
391 printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) {
392 char servtext[ISC_SOCKADDR_FORMATSIZE];
394 debug("printmessage()");
396 isc_sockaddr_format(&query->sockaddr, servtext, sizeof(servtext));
397 printf("Server:\t\t%s\n", query->servname);
398 printf("Address:\t%s\n", servtext);
403 isc_boolean_t headers = ISC_TRUE;
404 puts("------------");
405 /* detailheader(query, msg);*/
406 detailsection(query, msg, headers, DNS_SECTION_QUESTION);
407 detailsection(query, msg, headers, DNS_SECTION_ANSWER);
408 detailsection(query, msg, headers, DNS_SECTION_AUTHORITY);
409 detailsection(query, msg, headers, DNS_SECTION_ADDITIONAL);
410 puts("------------");
413 if (msg->rcode != 0) {
414 char nametext[DNS_NAME_FORMATSIZE];
415 dns_name_format(query->lookup->name,
416 nametext, sizeof(nametext));
417 printf("** server can't find %s: %s\n", nametext,
418 rcodetext[msg->rcode]);
419 debug("returning with rcode == 0");
420 return (ISC_R_SUCCESS);
423 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0)
424 puts("Non-authoritative answer:");
425 if (!ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER]))
426 printsection(query, msg, headers, DNS_SECTION_ANSWER);
428 printf("*** Can't find %s: No answer\n",
429 query->lookup->textname);
431 if (((msg->flags & DNS_MESSAGEFLAG_AA) == 0) &&
432 (query->lookup->rdtype != dns_rdatatype_a)) {
433 puts("\nAuthoritative answers can be found from:");
434 printsection(query, msg, headers,
435 DNS_SECTION_AUTHORITY);
436 printsection(query, msg, headers,
437 DNS_SECTION_ADDITIONAL);
439 return (ISC_R_SUCCESS);
443 show_settings(isc_boolean_t full, isc_boolean_t serv_only) {
445 isc_sockaddr_t sockaddr;
446 dig_searchlist_t *listent;
448 srv = ISC_LIST_HEAD(server_list);
450 while (srv != NULL) {
451 char sockstr[ISC_SOCKADDR_FORMATSIZE];
453 get_address(srv->servername, port, &sockaddr);
454 isc_sockaddr_format(&sockaddr, sockstr, sizeof(sockstr));
455 printf("Default server: %s\nAddress: %s\n",
456 srv->servername, sockstr);
459 srv = ISC_LIST_NEXT(srv, link);
463 printf("\nSet options:\n");
464 printf(" %s\t\t\t%s\t\t%s\n",
465 tcpmode ? "vc" : "novc",
466 short_form ? "nodebug" : "debug",
467 debugging ? "d2" : "nod2");
468 printf(" %s\t\t%s\n",
469 usesearch ? "search" : "nosearch",
470 recurse ? "recurse" : "norecurse");
471 printf(" timeout = %d\t\tretry = %d\tport = %d\n",
472 timeout, tries, port);
473 printf(" querytype = %-8s\tclass = %s\n", deftype, defclass);
474 printf(" srchlist = ");
475 for (listent = ISC_LIST_HEAD(search_list);
477 listent = ISC_LIST_NEXT(listent, link)) {
478 printf("%s", listent->origin);
479 if (ISC_LIST_NEXT(listent, link) != NULL)
486 testtype(char *typetext) {
489 dns_rdatatype_t rdtype;
492 tr.length = strlen(typetext);
493 result = dns_rdatatype_fromtext(&rdtype, &tr);
494 if (result == ISC_R_SUCCESS)
497 printf("unknown query type: %s\n", typetext);
503 testclass(char *typetext) {
506 dns_rdataclass_t rdclass;
509 tr.length = strlen(typetext);
510 result = dns_rdataclass_fromtext(&rdclass, &tr);
511 if (result == ISC_R_SUCCESS)
514 printf("unknown query class: %s\n", typetext);
520 safecpy(char *dest, char *src, int size) {
521 strncpy(dest, src, size);
527 setoption(char *opt) {
528 if (strncasecmp(opt, "all", 4) == 0) {
529 show_settings(ISC_TRUE, ISC_FALSE);
530 } else if (strncasecmp(opt, "class=", 6) == 0) {
531 if (testclass(&opt[6]))
532 safecpy(defclass, &opt[6], sizeof(defclass));
533 } else if (strncasecmp(opt, "cl=", 3) == 0) {
534 if (testclass(&opt[3]))
535 safecpy(defclass, &opt[3], sizeof(defclass));
536 } else if (strncasecmp(opt, "type=", 5) == 0) {
537 if (testtype(&opt[5]))
538 safecpy(deftype, &opt[5], sizeof(deftype));
539 } else if (strncasecmp(opt, "ty=", 3) == 0) {
540 if (testtype(&opt[3]))
541 safecpy(deftype, &opt[3], sizeof(deftype));
542 } else if (strncasecmp(opt, "querytype=", 10) == 0) {
543 if (testtype(&opt[10]))
544 safecpy(deftype, &opt[10], sizeof(deftype));
545 } else if (strncasecmp(opt, "query=", 6) == 0) {
546 if (testtype(&opt[6]))
547 safecpy(deftype, &opt[6], sizeof(deftype));
548 } else if (strncasecmp(opt, "qu=", 3) == 0) {
549 if (testtype(&opt[3]))
550 safecpy(deftype, &opt[3], sizeof(deftype));
551 } else if (strncasecmp(opt, "q=", 2) == 0) {
552 if (testtype(&opt[2]))
553 safecpy(deftype, &opt[2], sizeof(deftype));
554 } else if (strncasecmp(opt, "domain=", 7) == 0) {
555 safecpy(domainopt, &opt[7], sizeof(domainopt));
556 set_search_domain(domainopt);
557 usesearch = ISC_TRUE;
558 } else if (strncasecmp(opt, "do=", 3) == 0) {
559 safecpy(domainopt, &opt[3], sizeof(domainopt));
560 set_search_domain(domainopt);
561 usesearch = ISC_TRUE;
562 } else if (strncasecmp(opt, "port=", 5) == 0) {
563 port = atoi(&opt[5]);
564 } else if (strncasecmp(opt, "po=", 3) == 0) {
565 port = atoi(&opt[3]);
566 } else if (strncasecmp(opt, "timeout=", 8) == 0) {
567 timeout = atoi(&opt[8]);
568 } else if (strncasecmp(opt, "t=", 2) == 0) {
569 timeout = atoi(&opt[2]);
570 } else if (strncasecmp(opt, "rec", 3) == 0) {
572 } else if (strncasecmp(opt, "norec", 5) == 0) {
574 } else if (strncasecmp(opt, "retry=", 6) == 0) {
575 tries = atoi(&opt[6]);
576 } else if (strncasecmp(opt, "ret=", 4) == 0) {
577 tries = atoi(&opt[4]);
578 } else if (strncasecmp(opt, "def", 3) == 0) {
579 usesearch = ISC_TRUE;
580 } else if (strncasecmp(opt, "nodef", 5) == 0) {
581 usesearch = ISC_FALSE;
582 } else if (strncasecmp(opt, "vc", 3) == 0) {
584 } else if (strncasecmp(opt, "novc", 5) == 0) {
586 } else if (strncasecmp(opt, "deb", 3) == 0) {
587 short_form = ISC_FALSE;
588 } else if (strncasecmp(opt, "nodeb", 5) == 0) {
589 short_form = ISC_TRUE;
590 } else if (strncasecmp(opt, "d2", 2) == 0) {
591 debugging = ISC_TRUE;
592 } else if (strncasecmp(opt, "nod2", 4) == 0) {
593 debugging = ISC_FALSE;
594 } else if (strncasecmp(opt, "search",3) == 0) {
595 usesearch = ISC_TRUE;
596 } else if (strncasecmp(opt, "nosearch",5) == 0) {
597 usesearch = ISC_FALSE;
598 } else if (strncasecmp(opt, "sil",3) == 0) {
599 deprecation_msg = ISC_FALSE;
601 printf("*** Invalid option: %s\n", opt);
606 addlookup(char *opt) {
607 dig_lookup_t *lookup;
610 dns_rdatatype_t rdtype;
611 dns_rdataclass_t rdclass;
614 debug("addlookup()");
616 tr.length = strlen(deftype);
617 result = dns_rdatatype_fromtext(&rdtype, &tr);
618 if (result != ISC_R_SUCCESS) {
619 printf("unknown query type: %s\n", deftype);
620 rdclass = dns_rdatatype_a;
623 tr.length = strlen(defclass);
624 result = dns_rdataclass_fromtext(&rdclass, &tr);
625 if (result != ISC_R_SUCCESS) {
626 printf("unknown query class: %s\n", defclass);
627 rdclass = dns_rdataclass_in;
629 lookup = make_empty_lookup();
630 if (get_reverse(store, opt, lookup->ip6_int, ISC_TRUE)
633 safecpy(lookup->textname, store, sizeof(lookup->textname));
634 lookup->rdtype = dns_rdatatype_ptr;
635 lookup->rdtypeset = ISC_TRUE;
637 safecpy(lookup->textname, opt, sizeof(lookup->textname));
638 lookup->rdtype = rdtype;
639 lookup->rdtypeset = ISC_TRUE;
641 lookup->rdclass = rdclass;
642 lookup->rdclassset = ISC_TRUE;
643 lookup->trace = ISC_FALSE;
644 lookup->trace_root = lookup->trace;
645 lookup->ns_search_only = ISC_FALSE;
646 lookup->identify = identify;
647 lookup->recurse = recurse;
648 lookup->aaonly = aaonly;
649 lookup->retries = tries;
651 lookup->comments = comments;
652 lookup->tcp_mode = tcpmode;
653 lookup->stats = stats;
654 lookup->section_question = section_question;
655 lookup->section_answer = section_answer;
656 lookup->section_authority = section_authority;
657 lookup->section_additional = section_additional;
658 lookup->new_search = ISC_TRUE;
659 ISC_LIST_INIT(lookup->q);
660 ISC_LINK_INIT(lookup, link);
661 ISC_LIST_APPEND(lookup_list, lookup, link);
662 lookup->origin = NULL;
663 ISC_LIST_INIT(lookup->my_server_list);
664 debug("looking up %s", lookup->textname);
668 flush_server_list(void) {
669 dig_server_t *s, *ps;
671 debug("flush_server_list()");
672 s = ISC_LIST_HEAD(server_list);
675 s = ISC_LIST_NEXT(s, link);
676 ISC_LIST_DEQUEUE(server_list, ps, link);
677 isc_mem_free(mctx, ps);
682 * This works on the global server list, instead of on a per-lookup
683 * server list, since the change is persistent.
693 srv = isc_mem_allocate(mctx, sizeof(struct dig_server));
695 fatal("memory allocation failure");
696 safecpy(srv->servername, opt, sizeof(srv->servername));
697 ISC_LIST_INITANDAPPEND(server_list, srv, link);
701 get_next_command(void) {
707 buf = isc_mem_allocate(mctx, COMMSIZE);
709 fatal("memory allocation failure");
712 ptr = fgets(buf, COMMSIZE, stdin);
719 ptr = next_token(&input, " \t\r\n");
722 arg = next_token(&input, " \t\r\n");
723 if ((strcasecmp(ptr, "set") == 0) &&
726 else if ((strcasecmp(ptr, "server") == 0) ||
727 (strcasecmp(ptr, "lserver") == 0)) {
729 show_settings(ISC_TRUE, ISC_TRUE);
730 } else if (strcasecmp(ptr, "exit") == 0) {
733 } else if (strcasecmp(ptr, "help") == 0 ||
734 strcasecmp(ptr, "?") == 0)
736 printf("The '%s' command is not yet implemented.\n", ptr);
738 } else if (strcasecmp(ptr, "finger") == 0 ||
739 strcasecmp(ptr, "root") == 0 ||
740 strcasecmp(ptr, "ls") == 0 ||
741 strcasecmp(ptr, "view") == 0)
743 printf("The '%s' command is not implemented.\n", ptr);
748 isc_mem_free(mctx, buf);
752 parse_args(int argc, char **argv) {
753 isc_boolean_t have_lookup = ISC_FALSE;
755 usesearch = ISC_TRUE;
756 for (argc--, argv++; argc > 0; argc--, argv++) {
757 debug("main parsing %s", argv[0]);
758 if (argv[0][0] == '-') {
760 setoption(&argv[0][1]);
762 have_lookup = ISC_TRUE;
765 have_lookup = ISC_TRUE;
776 flush_lookup_list(void) {
777 dig_lookup_t *l, *lp;
779 dig_server_t *s, *sp;
782 l = ISC_LIST_HEAD(lookup_list);
784 q = ISC_LIST_HEAD(l->q);
786 if (q->sock != NULL) {
787 isc_socket_cancel(q->sock, NULL,
789 isc_socket_detach(&q->sock);
791 if (ISC_LINK_LINKED(&q->recvbuf, link))
792 ISC_LIST_DEQUEUE(q->recvlist, &q->recvbuf,
794 if (ISC_LINK_LINKED(&q->lengthbuf, link))
795 ISC_LIST_DEQUEUE(q->lengthlist, &q->lengthbuf,
797 isc_buffer_invalidate(&q->recvbuf);
798 isc_buffer_invalidate(&q->lengthbuf);
800 q = ISC_LIST_NEXT(q, link);
801 ISC_LIST_DEQUEUE(l->q, qp, link);
802 isc_mem_free(mctx, qp);
804 s = ISC_LIST_HEAD(l->my_server_list);
807 s = ISC_LIST_NEXT(s, link);
808 ISC_LIST_DEQUEUE(l->my_server_list, sp, link);
809 isc_mem_free(mctx, sp);
812 if (l->sendmsg != NULL)
813 dns_message_destroy(&l->sendmsg);
814 if (l->timer != NULL)
815 isc_timer_detach(&l->timer);
817 l = ISC_LIST_NEXT(l, link);
818 ISC_LIST_DEQUEUE(lookup_list, lp, link);
819 isc_mem_free(mctx, lp);
824 getinput(isc_task_t *task, isc_event_t *event) {
826 if (global_event == NULL)
827 global_event = event;
830 if (ISC_LIST_HEAD(lookup_list) != NULL) {
839 main(int argc, char **argv) {
842 ISC_LIST_INIT(lookup_list);
843 ISC_LIST_INIT(server_list);
844 ISC_LIST_INIT(search_list);
846 result = isc_app_start();
847 check_result(result, "isc_app_start");
852 parse_args(argc, argv);
854 if (deprecation_msg) {
856 "Note: nslookup is deprecated and may be removed from future releases.\n"
857 "Consider using the `dig' or `host' programs instead. Run nslookup with\n"
858 "the `-sil[ent]' option to prevent this message from appearing.\n", stderr);
861 if (domainopt[0] != '\0')
862 set_search_domain(domainopt);
864 result = isc_app_onrun(mctx, global_task, onrun_callback,
867 result = isc_app_onrun(mctx, global_task, getinput, NULL);
868 check_result(result, "isc_app_onrun");
869 in_use = ISC_TF(!in_use);
874 debug("done, and starting to shut down");
875 if (global_event != NULL)
876 isc_event_free(&global_event);