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.4.2.7 2004/08/18 23:25:58 marka Exp $ */
25 #include <isc/buffer.h>
26 #include <isc/commandline.h>
27 #include <isc/event.h>
28 #include <isc/parseint.h>
29 #include <isc/string.h>
30 #include <isc/timer.h>
33 #include <isc/netaddr.h>
35 #include <dns/message.h>
37 #include <dns/fixedname.h>
38 #include <dns/rdata.h>
39 #include <dns/rdataclass.h>
40 #include <dns/rdataset.h>
41 #include <dns/rdatastruct.h>
42 #include <dns/rdatatype.h>
43 #include <dns/byaddr.h>
47 extern ISC_LIST(dig_lookup_t) lookup_list;
48 extern dig_serverlist_t server_list;
49 extern ISC_LIST(dig_searchlist_t) search_list;
51 extern isc_boolean_t usesearch, debugging;
52 extern in_port_t port;
53 extern unsigned int timeout;
54 extern isc_mem_t *mctx;
56 extern int lookup_counter;
57 extern isc_task_t *global_task;
58 extern char *progname;
60 static isc_boolean_t short_form = ISC_TRUE,
62 identify = ISC_FALSE, stats = ISC_TRUE,
63 comments = ISC_TRUE, section_question = ISC_TRUE,
64 section_answer = ISC_TRUE, section_authority = ISC_TRUE,
65 section_additional = ISC_TRUE, recurse = ISC_TRUE,
67 static isc_boolean_t in_use = ISC_FALSE;
68 static char defclass[MXRD] = "IN";
69 static char deftype[MXRD] = "A";
70 static isc_event_t *global_event = NULL;
72 static char domainopt[DNS_NAME_MAXTEXT];
74 static const char *rcodetext[] = {
94 static const char *rtypetext[] = {
96 "internet address = ", /* 1 */
97 "nameserver = ", /* 2 */
100 "canonical name = ", /* 5 */
105 "rtype_10 = ", /* 10 */
106 "protocol = ", /* 11 */
110 "mail exchanger = ", /* 15 */
114 "x25 address = ", /* 19 */
115 "isdn address = ", /* 20 */
118 "nsap_ptr = ", /* 23 */
119 "signature = ", /* 24 */
123 "has AAAA address ", /* 28 */
126 "rtype_31 = ", /* 31 */
127 "rtype_32 = ", /* 32 */
128 "service = ", /* 33 */
129 "rtype_34 = ", /* 34 */
133 "v6 address = ", /* 38 */
135 "rtype_40 = ", /* 40 */
136 "optional = " /* 41 */
139 #define N_KNOWN_RRTYPES (sizeof(rtypetext) / sizeof(rtypetext[0]))
141 static void flush_lookup_list(void);
142 static void getinput(isc_task_t *task, isc_event_t *event);
145 dighost_shutdown(void) {
146 isc_event_t *event = global_event;
149 debug("dighost_shutdown()");
156 isc_task_send(global_task, &event);
160 printsoa(dns_rdata_t *rdata) {
163 char namebuf[DNS_NAME_FORMATSIZE];
165 result = dns_rdata_tostruct(rdata, &soa, NULL);
166 check_result(result, "dns_rdata_tostruct");
168 dns_name_format(&soa.origin, namebuf, sizeof(namebuf));
169 printf("\torigin = %s\n", namebuf);
170 dns_name_format(&soa.contact, namebuf, sizeof(namebuf));
171 printf("\tmail addr = %s\n", namebuf);
172 printf("\tserial = %u\n", soa.serial);
173 printf("\trefresh = %u\n", soa.refresh);
174 printf("\tretry = %u\n", soa.retry);
175 printf("\texpire = %u\n", soa.expire);
176 printf("\tminimum = %u\n", soa.minimum);
177 dns_rdata_freestruct(&soa);
181 printa(dns_rdata_t *rdata) {
183 char text[sizeof("255.255.255.255")];
186 isc_buffer_init(&b, text, sizeof(text));
187 result = dns_rdata_totext(rdata, NULL, &b);
188 check_result(result, "dns_rdata_totext");
189 printf("Address: %.*s\n", (int)isc_buffer_usedlength(&b),
190 (char *)isc_buffer_base(&b));
193 /* Just for compatibility : not use in host program */
195 printrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset,
196 isc_buffer_t *target)
205 printrdata(dns_rdata_t *rdata) {
207 isc_buffer_t *b = NULL;
208 unsigned int size = 1024;
209 isc_boolean_t done = ISC_FALSE;
211 if (rdata->type < N_KNOWN_RRTYPES)
212 printf("%s", rtypetext[rdata->type]);
214 printf("rdata_%d = ", rdata->type);
217 result = isc_buffer_allocate(mctx, &b, size);
218 if (result != ISC_R_SUCCESS)
219 check_result(result, "isc_buffer_allocate");
220 result = dns_rdata_totext(rdata, NULL, b);
221 if (result == ISC_R_SUCCESS) {
222 printf("%.*s\n", (int)isc_buffer_usedlength(b),
223 (char *)isc_buffer_base(b));
225 } else if (result != ISC_R_NOSPACE)
226 check_result(result, "dns_rdata_totext");
233 printsection(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers,
234 dns_section_t section) {
235 isc_result_t result, loopresult;
237 dns_rdataset_t *rdataset = NULL;
238 dns_rdata_t rdata = DNS_RDATA_INIT;
239 char namebuf[DNS_NAME_FORMATSIZE];
244 debug("printsection()");
246 result = dns_message_firstname(msg, section);
247 if (result == ISC_R_NOMORE)
248 return (ISC_R_SUCCESS);
249 else if (result != ISC_R_SUCCESS)
253 dns_message_currentname(msg, section,
255 for (rdataset = ISC_LIST_HEAD(name->list);
257 rdataset = ISC_LIST_NEXT(rdataset, link)) {
258 loopresult = dns_rdataset_first(rdataset);
259 while (loopresult == ISC_R_SUCCESS) {
260 dns_rdataset_current(rdataset, &rdata);
261 switch (rdata.type) {
262 case dns_rdatatype_a:
263 if (section != DNS_SECTION_ANSWER)
264 goto def_short_section;
265 dns_name_format(name, namebuf,
267 printf("Name:\t%s\n", namebuf);
270 case dns_rdatatype_soa:
271 dns_name_format(name, namebuf,
273 printf("%s\n", namebuf);
278 dns_name_format(name, namebuf,
280 printf("%s\t", namebuf);
284 dns_rdata_reset(&rdata);
285 loopresult = dns_rdataset_next(rdataset);
288 result = dns_message_nextname(msg, section);
289 if (result == ISC_R_NOMORE)
291 else if (result != ISC_R_SUCCESS) {
295 return (ISC_R_SUCCESS);
299 detailsection(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers,
300 dns_section_t section) {
301 isc_result_t result, loopresult;
303 dns_rdataset_t *rdataset = NULL;
304 dns_rdata_t rdata = DNS_RDATA_INIT;
305 char namebuf[DNS_NAME_FORMATSIZE];
309 debug("detailsection()");
313 case DNS_SECTION_QUESTION:
316 case DNS_SECTION_ANSWER:
319 case DNS_SECTION_AUTHORITY:
320 puts(" AUTHORITY RECORDS:");
322 case DNS_SECTION_ADDITIONAL:
323 puts(" ADDITIONAL RECORDS:");
328 result = dns_message_firstname(msg, section);
329 if (result == ISC_R_NOMORE)
330 return (ISC_R_SUCCESS);
331 else if (result != ISC_R_SUCCESS)
335 dns_message_currentname(msg, section,
337 for (rdataset = ISC_LIST_HEAD(name->list);
339 rdataset = ISC_LIST_NEXT(rdataset, link)) {
340 if (section == DNS_SECTION_QUESTION) {
341 dns_name_format(name, namebuf,
343 printf("\t%s, ", namebuf);
344 dns_rdatatype_format(rdataset->type,
347 printf("type = %s, ", namebuf);
348 dns_rdataclass_format(rdataset->rdclass,
351 printf("class = %s\n", namebuf);
353 loopresult = dns_rdataset_first(rdataset);
354 while (loopresult == ISC_R_SUCCESS) {
355 dns_rdataset_current(rdataset, &rdata);
357 dns_name_format(name, namebuf,
359 printf(" -> %s\n", namebuf);
361 switch (rdata.type) {
362 case dns_rdatatype_soa:
369 dns_rdata_reset(&rdata);
370 loopresult = dns_rdataset_next(rdataset);
373 result = dns_message_nextname(msg, section);
374 if (result == ISC_R_NOMORE)
376 else if (result != ISC_R_SUCCESS) {
380 return (ISC_R_SUCCESS);
384 received(int bytes, isc_sockaddr_t *from, dig_query_t *query)
392 trying(char *frm, dig_lookup_t *lookup) {
399 printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) {
400 char servtext[ISC_SOCKADDR_FORMATSIZE];
402 debug("printmessage()");
404 isc_sockaddr_format(&query->sockaddr, servtext, sizeof(servtext));
405 printf("Server:\t\t%s\n", query->servname);
406 printf("Address:\t%s\n", servtext);
411 isc_boolean_t headers = ISC_TRUE;
412 puts("------------");
413 /* detailheader(query, msg);*/
414 detailsection(query, msg, headers, DNS_SECTION_QUESTION);
415 detailsection(query, msg, headers, DNS_SECTION_ANSWER);
416 detailsection(query, msg, headers, DNS_SECTION_AUTHORITY);
417 detailsection(query, msg, headers, DNS_SECTION_ADDITIONAL);
418 puts("------------");
421 if (msg->rcode != 0) {
422 char nametext[DNS_NAME_FORMATSIZE];
423 dns_name_format(query->lookup->name,
424 nametext, sizeof(nametext));
425 printf("** server can't find %s: %s\n", nametext,
426 rcodetext[msg->rcode]);
427 debug("returning with rcode == 0");
428 return (ISC_R_SUCCESS);
431 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0)
432 puts("Non-authoritative answer:");
433 if (!ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER]))
434 printsection(query, msg, headers, DNS_SECTION_ANSWER);
436 printf("*** Can't find %s: No answer\n",
437 query->lookup->textname);
439 if (((msg->flags & DNS_MESSAGEFLAG_AA) == 0) &&
440 (query->lookup->rdtype != dns_rdatatype_a)) {
441 puts("\nAuthoritative answers can be found from:");
442 printsection(query, msg, headers,
443 DNS_SECTION_AUTHORITY);
444 printsection(query, msg, headers,
445 DNS_SECTION_ADDITIONAL);
447 return (ISC_R_SUCCESS);
451 show_settings(isc_boolean_t full, isc_boolean_t serv_only) {
453 isc_sockaddr_t sockaddr;
454 dig_searchlist_t *listent;
456 srv = ISC_LIST_HEAD(server_list);
458 while (srv != NULL) {
459 char sockstr[ISC_SOCKADDR_FORMATSIZE];
461 get_address(srv->servername, port, &sockaddr);
462 isc_sockaddr_format(&sockaddr, sockstr, sizeof(sockstr));
463 printf("Default server: %s\nAddress: %s\n",
464 srv->servername, sockstr);
467 srv = ISC_LIST_NEXT(srv, link);
471 printf("\nSet options:\n");
472 printf(" %s\t\t\t%s\t\t%s\n",
473 tcpmode ? "vc" : "novc",
474 short_form ? "nodebug" : "debug",
475 debugging ? "d2" : "nod2");
476 printf(" %s\t\t%s\n",
477 usesearch ? "search" : "nosearch",
478 recurse ? "recurse" : "norecurse");
479 printf(" timeout = %d\t\tretry = %d\tport = %d\n",
480 timeout, tries, port);
481 printf(" querytype = %-8s\tclass = %s\n", deftype, defclass);
482 printf(" srchlist = ");
483 for (listent = ISC_LIST_HEAD(search_list);
485 listent = ISC_LIST_NEXT(listent, link)) {
486 printf("%s", listent->origin);
487 if (ISC_LIST_NEXT(listent, link) != NULL)
494 testtype(char *typetext) {
497 dns_rdatatype_t rdtype;
500 tr.length = strlen(typetext);
501 result = dns_rdatatype_fromtext(&rdtype, &tr);
502 if (result == ISC_R_SUCCESS)
505 printf("unknown query type: %s\n", typetext);
511 testclass(char *typetext) {
514 dns_rdataclass_t rdclass;
517 tr.length = strlen(typetext);
518 result = dns_rdataclass_fromtext(&rdclass, &tr);
519 if (result == ISC_R_SUCCESS)
522 printf("unknown query class: %s\n", typetext);
528 safecpy(char *dest, char *src, int size) {
529 strncpy(dest, src, size);
534 parse_uint(isc_uint32_t *uip, const char *value, isc_uint32_t max,
537 isc_result_t result = isc_parse_uint32(&n, value, 10);
538 if (result == ISC_R_SUCCESS && n > max)
539 result = ISC_R_RANGE;
540 if (result != ISC_R_SUCCESS) {
541 printf("invalid %s '%s': %s\n", desc,
542 value, isc_result_totext(result));
546 return (ISC_R_SUCCESS);
550 set_port(const char *value) {
552 isc_result_t result = parse_uint(&n, value, 65535, "port");
553 if (result == ISC_R_SUCCESS)
554 port = (isc_uint16_t) n;
558 set_timeout(const char *value) {
560 isc_result_t result = parse_uint(&n, value, UINT_MAX, "timeout");
561 if (result == ISC_R_SUCCESS)
566 set_tries(const char *value) {
568 isc_result_t result = parse_uint(&n, value, INT_MAX, "tries");
569 if (result == ISC_R_SUCCESS)
574 setoption(char *opt) {
575 if (strncasecmp(opt, "all", 4) == 0) {
576 show_settings(ISC_TRUE, ISC_FALSE);
577 } else if (strncasecmp(opt, "class=", 6) == 0) {
578 if (testclass(&opt[6]))
579 safecpy(defclass, &opt[6], sizeof(defclass));
580 } else if (strncasecmp(opt, "cl=", 3) == 0) {
581 if (testclass(&opt[3]))
582 safecpy(defclass, &opt[3], sizeof(defclass));
583 } else if (strncasecmp(opt, "type=", 5) == 0) {
584 if (testtype(&opt[5]))
585 safecpy(deftype, &opt[5], sizeof(deftype));
586 } else if (strncasecmp(opt, "ty=", 3) == 0) {
587 if (testtype(&opt[3]))
588 safecpy(deftype, &opt[3], sizeof(deftype));
589 } else if (strncasecmp(opt, "querytype=", 10) == 0) {
590 if (testtype(&opt[10]))
591 safecpy(deftype, &opt[10], sizeof(deftype));
592 } else if (strncasecmp(opt, "query=", 6) == 0) {
593 if (testtype(&opt[6]))
594 safecpy(deftype, &opt[6], sizeof(deftype));
595 } else if (strncasecmp(opt, "qu=", 3) == 0) {
596 if (testtype(&opt[3]))
597 safecpy(deftype, &opt[3], sizeof(deftype));
598 } else if (strncasecmp(opt, "q=", 2) == 0) {
599 if (testtype(&opt[2]))
600 safecpy(deftype, &opt[2], sizeof(deftype));
601 } else if (strncasecmp(opt, "domain=", 7) == 0) {
602 safecpy(domainopt, &opt[7], sizeof(domainopt));
603 set_search_domain(domainopt);
604 usesearch = ISC_TRUE;
605 } else if (strncasecmp(opt, "do=", 3) == 0) {
606 safecpy(domainopt, &opt[3], sizeof(domainopt));
607 set_search_domain(domainopt);
608 usesearch = ISC_TRUE;
609 } else if (strncasecmp(opt, "port=", 5) == 0) {
611 } else if (strncasecmp(opt, "po=", 3) == 0) {
613 } else if (strncasecmp(opt, "timeout=", 8) == 0) {
614 set_timeout(&opt[8]);
615 } else if (strncasecmp(opt, "t=", 2) == 0) {
616 set_timeout(&opt[2]);
617 } else if (strncasecmp(opt, "rec", 3) == 0) {
619 } else if (strncasecmp(opt, "norec", 5) == 0) {
621 } else if (strncasecmp(opt, "retry=", 6) == 0) {
623 } else if (strncasecmp(opt, "ret=", 4) == 0) {
625 } else if (strncasecmp(opt, "def", 3) == 0) {
626 usesearch = ISC_TRUE;
627 } else if (strncasecmp(opt, "nodef", 5) == 0) {
628 usesearch = ISC_FALSE;
629 } else if (strncasecmp(opt, "vc", 3) == 0) {
631 } else if (strncasecmp(opt, "novc", 5) == 0) {
633 } else if (strncasecmp(opt, "deb", 3) == 0) {
634 short_form = ISC_FALSE;
635 } else if (strncasecmp(opt, "nodeb", 5) == 0) {
636 short_form = ISC_TRUE;
637 } else if (strncasecmp(opt, "d2", 2) == 0) {
638 debugging = ISC_TRUE;
639 } else if (strncasecmp(opt, "nod2", 4) == 0) {
640 debugging = ISC_FALSE;
641 } else if (strncasecmp(opt, "search", 3) == 0) {
642 usesearch = ISC_TRUE;
643 } else if (strncasecmp(opt, "nosearch", 5) == 0) {
644 usesearch = ISC_FALSE;
645 } else if (strncasecmp(opt, "sil", 3) == 0) {
646 /* deprecation_msg = ISC_FALSE; */
648 printf("*** Invalid option: %s\n", opt);
653 addlookup(char *opt) {
654 dig_lookup_t *lookup;
657 dns_rdatatype_t rdtype;
658 dns_rdataclass_t rdclass;
661 debug("addlookup()");
663 tr.length = strlen(deftype);
664 result = dns_rdatatype_fromtext(&rdtype, &tr);
665 if (result != ISC_R_SUCCESS) {
666 printf("unknown query type: %s\n", deftype);
667 rdclass = dns_rdatatype_a;
670 tr.length = strlen(defclass);
671 result = dns_rdataclass_fromtext(&rdclass, &tr);
672 if (result != ISC_R_SUCCESS) {
673 printf("unknown query class: %s\n", defclass);
674 rdclass = dns_rdataclass_in;
676 lookup = make_empty_lookup();
677 if (get_reverse(store, sizeof(store), opt, lookup->ip6_int, ISC_TRUE)
679 safecpy(lookup->textname, store, sizeof(lookup->textname));
680 lookup->rdtype = dns_rdatatype_ptr;
681 lookup->rdtypeset = ISC_TRUE;
683 safecpy(lookup->textname, opt, sizeof(lookup->textname));
684 lookup->rdtype = rdtype;
685 lookup->rdtypeset = ISC_TRUE;
687 lookup->rdclass = rdclass;
688 lookup->rdclassset = ISC_TRUE;
689 lookup->trace = ISC_FALSE;
690 lookup->trace_root = lookup->trace;
691 lookup->ns_search_only = ISC_FALSE;
692 lookup->identify = identify;
693 lookup->recurse = recurse;
694 lookup->aaonly = aaonly;
695 lookup->retries = tries;
697 lookup->comments = comments;
698 lookup->tcp_mode = tcpmode;
699 lookup->stats = stats;
700 lookup->section_question = section_question;
701 lookup->section_answer = section_answer;
702 lookup->section_authority = section_authority;
703 lookup->section_additional = section_additional;
704 lookup->new_search = ISC_TRUE;
705 ISC_LIST_INIT(lookup->q);
706 ISC_LINK_INIT(lookup, link);
707 ISC_LIST_APPEND(lookup_list, lookup, link);
708 lookup->origin = NULL;
709 ISC_LIST_INIT(lookup->my_server_list);
710 debug("looking up %s", lookup->textname);
714 get_next_command(void) {
720 buf = isc_mem_allocate(mctx, COMMSIZE);
722 fatal("memory allocation failure");
725 ptr = fgets(buf, COMMSIZE, stdin);
732 ptr = next_token(&input, " \t\r\n");
735 arg = next_token(&input, " \t\r\n");
736 if ((strcasecmp(ptr, "set") == 0) &&
739 else if ((strcasecmp(ptr, "server") == 0) ||
740 (strcasecmp(ptr, "lserver") == 0)) {
742 show_settings(ISC_TRUE, ISC_TRUE);
743 } else if (strcasecmp(ptr, "exit") == 0) {
746 } else if (strcasecmp(ptr, "help") == 0 ||
747 strcasecmp(ptr, "?") == 0) {
748 printf("The '%s' command is not yet implemented.\n", ptr);
750 } else if (strcasecmp(ptr, "finger") == 0 ||
751 strcasecmp(ptr, "root") == 0 ||
752 strcasecmp(ptr, "ls") == 0 ||
753 strcasecmp(ptr, "view") == 0) {
754 printf("The '%s' command is not implemented.\n", ptr);
759 isc_mem_free(mctx, buf);
763 parse_args(int argc, char **argv) {
764 isc_boolean_t have_lookup = ISC_FALSE;
766 usesearch = ISC_TRUE;
767 for (argc--, argv++; argc > 0; argc--, argv++) {
768 debug("main parsing %s", argv[0]);
769 if (argv[0][0] == '-') {
771 setoption(&argv[0][1]);
773 have_lookup = ISC_TRUE;
776 have_lookup = ISC_TRUE;
781 set_nameserver(argv[0]);
787 flush_lookup_list(void) {
788 dig_lookup_t *l, *lp;
790 dig_server_t *s, *sp;
793 l = ISC_LIST_HEAD(lookup_list);
795 q = ISC_LIST_HEAD(l->q);
797 if (q->sock != NULL) {
798 isc_socket_cancel(q->sock, NULL,
800 isc_socket_detach(&q->sock);
802 if (ISC_LINK_LINKED(&q->recvbuf, link))
803 ISC_LIST_DEQUEUE(q->recvlist, &q->recvbuf,
805 if (ISC_LINK_LINKED(&q->lengthbuf, link))
806 ISC_LIST_DEQUEUE(q->lengthlist, &q->lengthbuf,
808 isc_buffer_invalidate(&q->recvbuf);
809 isc_buffer_invalidate(&q->lengthbuf);
811 q = ISC_LIST_NEXT(q, link);
812 ISC_LIST_DEQUEUE(l->q, qp, link);
813 isc_mem_free(mctx, qp);
815 s = ISC_LIST_HEAD(l->my_server_list);
818 s = ISC_LIST_NEXT(s, link);
819 ISC_LIST_DEQUEUE(l->my_server_list, sp, link);
820 isc_mem_free(mctx, sp);
823 if (l->sendmsg != NULL)
824 dns_message_destroy(&l->sendmsg);
825 if (l->timer != NULL)
826 isc_timer_detach(&l->timer);
828 l = ISC_LIST_NEXT(l, link);
829 ISC_LIST_DEQUEUE(lookup_list, lp, link);
830 isc_mem_free(mctx, lp);
835 getinput(isc_task_t *task, isc_event_t *event) {
837 if (global_event == NULL)
838 global_event = event;
841 if (ISC_LIST_HEAD(lookup_list) != NULL) {
850 main(int argc, char **argv) {
853 ISC_LIST_INIT(lookup_list);
854 ISC_LIST_INIT(server_list);
855 ISC_LIST_INIT(search_list);
857 result = isc_app_start();
858 check_result(result, "isc_app_start");
863 parse_args(argc, argv);
866 if (domainopt[0] != '\0')
867 set_search_domain(domainopt);
869 result = isc_app_onrun(mctx, global_task, onrun_callback,
872 result = isc_app_onrun(mctx, global_task, getinput, NULL);
873 check_result(result, "isc_app_onrun");
874 in_use = ISC_TF(!in_use);
879 debug("done, and starting to shut down");
880 if (global_event != NULL)
881 isc_event_free(&global_event);