1 /* $NetBSD: nslookup.c,v 1.11 2015/07/08 17:28:54 christos Exp $ */
4 * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2000-2003 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.
26 #include <isc/buffer.h>
27 #include <isc/commandline.h>
28 #include <isc/event.h>
29 #include <isc/parseint.h>
30 #include <isc/print.h>
31 #include <isc/string.h>
32 #include <isc/timer.h>
35 #include <isc/netaddr.h>
37 #include <dns/message.h>
39 #include <dns/fixedname.h>
40 #include <dns/rdata.h>
41 #include <dns/rdataclass.h>
42 #include <dns/rdataset.h>
43 #include <dns/rdatastruct.h>
44 #include <dns/rdatatype.h>
45 #include <dns/byaddr.h>
49 #if defined(HAVE_READLINE)
50 #include <readline/readline.h>
51 #include <readline/history.h>
54 static isc_boolean_t short_form
= ISC_TRUE
,
56 identify
= ISC_FALSE
, stats
= ISC_TRUE
,
57 comments
= ISC_TRUE
, section_question
= ISC_TRUE
,
58 section_answer
= ISC_TRUE
, section_authority
= ISC_TRUE
,
59 section_additional
= ISC_TRUE
, recurse
= ISC_TRUE
,
60 aaonly
= ISC_FALSE
, nofail
= ISC_TRUE
;
62 static isc_boolean_t interactive
;
64 static isc_boolean_t in_use
= ISC_FALSE
;
65 static char defclass
[MXRD
] = "IN";
66 static char deftype
[MXRD
] = "A";
67 static isc_event_t
*global_event
= NULL
;
68 static int query_error
= 1, print_error
= 0;
70 static char domainopt
[DNS_NAME_MAXTEXT
];
72 static const char *rcodetext
[] = {
92 static const char *rtypetext
[] = {
94 "internet address = ", /* 1 */
95 "nameserver = ", /* 2 */
98 "canonical name = ", /* 5 */
103 "rtype_10 = ", /* 10 */
104 "protocol = ", /* 11 */
108 "mail exchanger = ", /* 15 */
112 "x25 address = ", /* 19 */
113 "isdn address = ", /* 20 */
116 "nsap_ptr = ", /* 23 */
117 "signature = ", /* 24 */
121 "has AAAA address ", /* 28 */
124 "rtype_31 = ", /* 31 */
125 "rtype_32 = ", /* 32 */
126 "service = ", /* 33 */
127 "rtype_34 = ", /* 34 */
131 "v6 address = ", /* 38 */
133 "rtype_40 = ", /* 40 */
134 "optional = " /* 41 */
137 #define N_KNOWN_RRTYPES (sizeof(rtypetext) / sizeof(rtypetext[0]))
139 static void flush_lookup_list(void);
140 static void getinput(isc_task_t
*task
, isc_event_t
*event
);
143 rcode_totext(dns_rcode_t rcode
)
145 static char buf
[sizeof("?65535")];
147 const char *consttext
;
151 if (rcode
>= (sizeof(rcodetext
)/sizeof(rcodetext
[0]))) {
152 snprintf(buf
, sizeof(buf
), "?%u", rcode
);
153 totext
.deconsttext
= buf
;
155 totext
.consttext
= rcodetext
[rcode
];
156 return totext
.deconsttext
;
160 dighost_shutdown(void) {
161 isc_event_t
*event
= global_event
;
164 debug("dighost_shutdown()");
171 isc_task_send(global_task
, &event
);
175 printsoa(dns_rdata_t
*rdata
) {
178 char namebuf
[DNS_NAME_FORMATSIZE
];
180 result
= dns_rdata_tostruct(rdata
, &soa
, NULL
);
181 check_result(result
, "dns_rdata_tostruct");
183 dns_name_format(&soa
.origin
, namebuf
, sizeof(namebuf
));
184 printf("\torigin = %s\n", namebuf
);
185 dns_name_format(&soa
.contact
, namebuf
, sizeof(namebuf
));
186 printf("\tmail addr = %s\n", namebuf
);
187 printf("\tserial = %u\n", soa
.serial
);
188 printf("\trefresh = %u\n", soa
.refresh
);
189 printf("\tretry = %u\n", soa
.retry
);
190 printf("\texpire = %u\n", soa
.expire
);
191 printf("\tminimum = %u\n", soa
.minimum
);
192 dns_rdata_freestruct(&soa
);
196 printa(dns_rdata_t
*rdata
) {
198 char text
[sizeof("255.255.255.255")];
201 isc_buffer_init(&b
, text
, sizeof(text
));
202 result
= dns_rdata_totext(rdata
, NULL
, &b
);
203 check_result(result
, "dns_rdata_totext");
204 printf("Address: %.*s\n", (int)isc_buffer_usedlength(&b
),
205 (char *)isc_buffer_base(&b
));
208 /* Just for compatibility : not use in host program */
210 printrdataset(dns_name_t
*owner_name
, dns_rdataset_t
*rdataset
,
211 isc_buffer_t
*target
)
220 printrdata(dns_rdata_t
*rdata
) {
222 isc_buffer_t
*b
= NULL
;
223 unsigned int size
= 1024;
224 isc_boolean_t done
= ISC_FALSE
;
226 if (rdata
->type
< N_KNOWN_RRTYPES
)
227 printf("%s", rtypetext
[rdata
->type
]);
229 printf("rdata_%d = ", rdata
->type
);
232 result
= isc_buffer_allocate(mctx
, &b
, size
);
233 if (result
!= ISC_R_SUCCESS
)
234 check_result(result
, "isc_buffer_allocate");
235 result
= dns_rdata_totext(rdata
, NULL
, b
);
236 if (result
== ISC_R_SUCCESS
) {
237 printf("%.*s\n", (int)isc_buffer_usedlength(b
),
238 (char *)isc_buffer_base(b
));
240 } else if (result
!= ISC_R_NOSPACE
)
241 check_result(result
, "dns_rdata_totext");
248 printsection(dig_query_t
*query
, dns_message_t
*msg
, isc_boolean_t headers
,
249 dns_section_t section
) {
250 isc_result_t result
, loopresult
;
252 dns_rdataset_t
*rdataset
= NULL
;
253 dns_rdata_t rdata
= DNS_RDATA_INIT
;
254 char namebuf
[DNS_NAME_FORMATSIZE
];
259 debug("printsection()");
261 result
= dns_message_firstname(msg
, section
);
262 if (result
== ISC_R_NOMORE
)
263 return (ISC_R_SUCCESS
);
264 else if (result
!= ISC_R_SUCCESS
)
268 dns_message_currentname(msg
, section
,
270 for (rdataset
= ISC_LIST_HEAD(name
->list
);
272 rdataset
= ISC_LIST_NEXT(rdataset
, link
)) {
273 loopresult
= dns_rdataset_first(rdataset
);
274 while (loopresult
== ISC_R_SUCCESS
) {
275 dns_rdataset_current(rdataset
, &rdata
);
276 switch (rdata
.type
) {
277 case dns_rdatatype_a
:
278 if (section
!= DNS_SECTION_ANSWER
)
279 goto def_short_section
;
280 dns_name_format(name
, namebuf
,
282 printf("Name:\t%s\n", namebuf
);
285 case dns_rdatatype_soa
:
286 dns_name_format(name
, namebuf
,
288 printf("%s\n", namebuf
);
293 dns_name_format(name
, namebuf
,
295 printf("%s\t", namebuf
);
299 dns_rdata_reset(&rdata
);
300 loopresult
= dns_rdataset_next(rdataset
);
303 result
= dns_message_nextname(msg
, section
);
304 if (result
== ISC_R_NOMORE
)
306 else if (result
!= ISC_R_SUCCESS
) {
310 return (ISC_R_SUCCESS
);
314 detailsection(dig_query_t
*query
, dns_message_t
*msg
, isc_boolean_t headers
,
315 dns_section_t section
) {
316 isc_result_t result
, loopresult
;
318 dns_rdataset_t
*rdataset
= NULL
;
319 dns_rdata_t rdata
= DNS_RDATA_INIT
;
320 char namebuf
[DNS_NAME_FORMATSIZE
];
324 debug("detailsection()");
328 case DNS_SECTION_QUESTION
:
331 case DNS_SECTION_ANSWER
:
334 case DNS_SECTION_AUTHORITY
:
335 puts(" AUTHORITY RECORDS:");
337 case DNS_SECTION_ADDITIONAL
:
338 puts(" ADDITIONAL RECORDS:");
343 result
= dns_message_firstname(msg
, section
);
344 if (result
== ISC_R_NOMORE
)
345 return (ISC_R_SUCCESS
);
346 else if (result
!= ISC_R_SUCCESS
)
350 dns_message_currentname(msg
, section
,
352 for (rdataset
= ISC_LIST_HEAD(name
->list
);
354 rdataset
= ISC_LIST_NEXT(rdataset
, link
)) {
355 if (section
== DNS_SECTION_QUESTION
) {
356 dns_name_format(name
, namebuf
,
358 printf("\t%s, ", namebuf
);
359 dns_rdatatype_format(rdataset
->type
,
362 printf("type = %s, ", namebuf
);
363 dns_rdataclass_format(rdataset
->rdclass
,
366 printf("class = %s\n", namebuf
);
368 loopresult
= dns_rdataset_first(rdataset
);
369 while (loopresult
== ISC_R_SUCCESS
) {
370 dns_rdataset_current(rdataset
, &rdata
);
372 dns_name_format(name
, namebuf
,
374 printf(" -> %s\n", namebuf
);
376 switch (rdata
.type
) {
377 case dns_rdatatype_soa
:
384 dns_rdata_reset(&rdata
);
385 printf("\tttl = %u\n", rdataset
->ttl
);
386 loopresult
= dns_rdataset_next(rdataset
);
389 result
= dns_message_nextname(msg
, section
);
390 if (result
== ISC_R_NOMORE
)
392 else if (result
!= ISC_R_SUCCESS
) {
396 return (ISC_R_SUCCESS
);
400 received(int bytes
, isc_sockaddr_t
*from
, dig_query_t
*query
)
408 trying(char *frm
, dig_lookup_t
*lookup
) {
415 printmessage(dig_query_t
*query
, dns_message_t
*msg
, isc_boolean_t headers
) {
416 char servtext
[ISC_SOCKADDR_FORMATSIZE
];
418 /* I've we've gotten this far, we've reached a server. */
421 debug("printmessage()");
423 isc_sockaddr_format(&query
->sockaddr
, servtext
, sizeof(servtext
));
424 printf("Server:\t\t%s\n", query
->userarg
);
425 printf("Address:\t%s\n", servtext
);
430 puts("------------");
431 /* detailheader(query, msg);*/
432 detailsection(query
, msg
, ISC_TRUE
, DNS_SECTION_QUESTION
);
433 detailsection(query
, msg
, ISC_TRUE
, DNS_SECTION_ANSWER
);
434 detailsection(query
, msg
, ISC_TRUE
, DNS_SECTION_AUTHORITY
);
435 detailsection(query
, msg
, ISC_TRUE
, DNS_SECTION_ADDITIONAL
);
436 puts("------------");
439 if (msg
->rcode
!= 0) {
440 char nametext
[DNS_NAME_FORMATSIZE
];
441 dns_name_format(query
->lookup
->name
,
442 nametext
, sizeof(nametext
));
443 printf("** server can't find %s: %s\n",
444 nametext
, rcode_totext(msg
->rcode
));
445 debug("returning with rcode == 0");
447 /* the lookup failed */
449 return (ISC_R_SUCCESS
);
452 if ((msg
->flags
& DNS_MESSAGEFLAG_AA
) == 0)
453 puts("Non-authoritative answer:");
454 if (!ISC_LIST_EMPTY(msg
->sections
[DNS_SECTION_ANSWER
]))
455 printsection(query
, msg
, headers
, DNS_SECTION_ANSWER
);
457 printf("*** Can't find %s: No answer\n",
458 query
->lookup
->textname
);
460 if (((msg
->flags
& DNS_MESSAGEFLAG_AA
) == 0) &&
461 (query
->lookup
->rdtype
!= dns_rdatatype_a
)) {
462 puts("\nAuthoritative answers can be found from:");
463 printsection(query
, msg
, headers
,
464 DNS_SECTION_AUTHORITY
);
465 printsection(query
, msg
, headers
,
466 DNS_SECTION_ADDITIONAL
);
468 return (ISC_R_SUCCESS
);
472 show_settings(isc_boolean_t full
, isc_boolean_t serv_only
) {
474 isc_sockaddr_t sockaddr
;
475 dig_searchlist_t
*listent
;
478 srv
= ISC_LIST_HEAD(server_list
);
480 while (srv
!= NULL
) {
481 char sockstr
[ISC_SOCKADDR_FORMATSIZE
];
483 result
= get_address(srv
->servername
, port
, &sockaddr
);
484 check_result(result
, "get_address");
486 isc_sockaddr_format(&sockaddr
, sockstr
, sizeof(sockstr
));
487 printf("Default server: %s\nAddress: %s\n",
488 srv
->userarg
, sockstr
);
491 srv
= ISC_LIST_NEXT(srv
, link
);
495 printf("\nSet options:\n");
496 printf(" %s\t\t\t%s\t\t%s\n",
497 tcpmode
? "vc" : "novc",
498 short_form
? "nodebug" : "debug",
499 debugging
? "d2" : "nod2");
500 printf(" %s\t\t%s\n",
501 usesearch
? "search" : "nosearch",
502 recurse
? "recurse" : "norecurse");
503 printf(" timeout = %d\t\tretry = %d\tport = %d\tndots = %d\n",
504 timeout
, tries
, port
, ndots
);
505 printf(" querytype = %-8s\tclass = %s\n", deftype
, defclass
);
506 printf(" srchlist = ");
507 for (listent
= ISC_LIST_HEAD(search_list
);
509 listent
= ISC_LIST_NEXT(listent
, link
)) {
510 printf("%s", listent
->origin
);
511 if (ISC_LIST_NEXT(listent
, link
) != NULL
)
518 testtype(char *typetext
) {
521 dns_rdatatype_t rdtype
;
524 tr
.length
= strlen(typetext
);
525 result
= dns_rdatatype_fromtext(&rdtype
, &tr
);
526 if (result
== ISC_R_SUCCESS
)
529 printf("unknown query type: %s\n", typetext
);
535 testclass(char *typetext
) {
538 dns_rdataclass_t rdclass
;
541 tr
.length
= strlen(typetext
);
542 result
= dns_rdataclass_fromtext(&rdclass
, &tr
);
543 if (result
== ISC_R_SUCCESS
)
546 printf("unknown query class: %s\n", typetext
);
552 set_port(const char *value
) {
554 isc_result_t result
= parse_uint(&n
, value
, 65535, "port");
555 if (result
== ISC_R_SUCCESS
)
556 port
= (isc_uint16_t
) n
;
560 set_timeout(const char *value
) {
562 isc_result_t result
= parse_uint(&n
, value
, UINT_MAX
, "timeout");
563 if (result
== ISC_R_SUCCESS
)
568 set_tries(const char *value
) {
570 isc_result_t result
= parse_uint(&n
, value
, INT_MAX
, "tries");
571 if (result
== ISC_R_SUCCESS
)
576 set_ndots(const char *value
) {
578 isc_result_t result
= parse_uint(&n
, value
, 128, "ndots");
579 if (result
== ISC_R_SUCCESS
)
585 fputs("nslookup " VERSION
"\n", stderr
);
589 setoption(char *opt
) {
590 if (strncasecmp(opt
, "all", 4) == 0) {
591 show_settings(ISC_TRUE
, ISC_FALSE
);
592 } else if (strncasecmp(opt
, "class=", 6) == 0) {
593 if (testclass(&opt
[6]))
594 strlcpy(defclass
, &opt
[6], sizeof(defclass
));
595 } else if (strncasecmp(opt
, "cl=", 3) == 0) {
596 if (testclass(&opt
[3]))
597 strlcpy(defclass
, &opt
[3], sizeof(defclass
));
598 } else if (strncasecmp(opt
, "type=", 5) == 0) {
599 if (testtype(&opt
[5]))
600 strlcpy(deftype
, &opt
[5], sizeof(deftype
));
601 } else if (strncasecmp(opt
, "ty=", 3) == 0) {
602 if (testtype(&opt
[3]))
603 strlcpy(deftype
, &opt
[3], sizeof(deftype
));
604 } else if (strncasecmp(opt
, "querytype=", 10) == 0) {
605 if (testtype(&opt
[10]))
606 strlcpy(deftype
, &opt
[10], sizeof(deftype
));
607 } else if (strncasecmp(opt
, "query=", 6) == 0) {
608 if (testtype(&opt
[6]))
609 strlcpy(deftype
, &opt
[6], sizeof(deftype
));
610 } else if (strncasecmp(opt
, "qu=", 3) == 0) {
611 if (testtype(&opt
[3]))
612 strlcpy(deftype
, &opt
[3], sizeof(deftype
));
613 } else if (strncasecmp(opt
, "q=", 2) == 0) {
614 if (testtype(&opt
[2]))
615 strlcpy(deftype
, &opt
[2], sizeof(deftype
));
616 } else if (strncasecmp(opt
, "domain=", 7) == 0) {
617 strlcpy(domainopt
, &opt
[7], sizeof(domainopt
));
618 set_search_domain(domainopt
);
619 usesearch
= ISC_TRUE
;
620 } else if (strncasecmp(opt
, "do=", 3) == 0) {
621 strlcpy(domainopt
, &opt
[3], sizeof(domainopt
));
622 set_search_domain(domainopt
);
623 usesearch
= ISC_TRUE
;
624 } else if (strncasecmp(opt
, "port=", 5) == 0) {
626 } else if (strncasecmp(opt
, "po=", 3) == 0) {
628 } else if (strncasecmp(opt
, "timeout=", 8) == 0) {
629 set_timeout(&opt
[8]);
630 } else if (strncasecmp(opt
, "t=", 2) == 0) {
631 set_timeout(&opt
[2]);
632 } else if (strncasecmp(opt
, "rec", 3) == 0) {
634 } else if (strncasecmp(opt
, "norec", 5) == 0) {
636 } else if (strncasecmp(opt
, "retry=", 6) == 0) {
638 } else if (strncasecmp(opt
, "ret=", 4) == 0) {
640 } else if (strncasecmp(opt
, "def", 3) == 0) {
641 usesearch
= ISC_TRUE
;
642 } else if (strncasecmp(opt
, "nodef", 5) == 0) {
643 usesearch
= ISC_FALSE
;
644 } else if (strncasecmp(opt
, "vc", 3) == 0) {
646 } else if (strncasecmp(opt
, "novc", 5) == 0) {
648 } else if (strncasecmp(opt
, "deb", 3) == 0) {
649 short_form
= ISC_FALSE
;
650 showsearch
= ISC_TRUE
;
651 } else if (strncasecmp(opt
, "nodeb", 5) == 0) {
652 short_form
= ISC_TRUE
;
653 showsearch
= ISC_FALSE
;
654 } else if (strncasecmp(opt
, "d2", 2) == 0) {
655 debugging
= ISC_TRUE
;
656 } else if (strncasecmp(opt
, "nod2", 4) == 0) {
657 debugging
= ISC_FALSE
;
658 } else if (strncasecmp(opt
, "search", 3) == 0) {
659 usesearch
= ISC_TRUE
;
660 } else if (strncasecmp(opt
, "nosearch", 5) == 0) {
661 usesearch
= ISC_FALSE
;
662 } else if (strncasecmp(opt
, "sil", 3) == 0) {
663 /* deprecation_msg = ISC_FALSE; */
664 } else if (strncasecmp(opt
, "fail", 3) == 0) {
666 } else if (strncasecmp(opt
, "nofail", 3) == 0) {
668 } else if (strncasecmp(opt
, "ndots=", 6) == 0) {
671 printf("*** Invalid option: %s\n", opt
);
676 addlookup(char *opt
) {
677 dig_lookup_t
*lookup
;
680 dns_rdatatype_t rdtype
;
681 dns_rdataclass_t rdclass
;
684 debug("addlookup()");
686 tr
.length
= strlen(deftype
);
687 result
= dns_rdatatype_fromtext(&rdtype
, &tr
);
688 if (result
!= ISC_R_SUCCESS
) {
689 printf("unknown query type: %s\n", deftype
);
690 rdclass
= dns_rdatatype_a
;
693 tr
.length
= strlen(defclass
);
694 result
= dns_rdataclass_fromtext(&rdclass
, &tr
);
695 if (result
!= ISC_R_SUCCESS
) {
696 printf("unknown query class: %s\n", defclass
);
697 rdclass
= dns_rdataclass_in
;
699 lookup
= make_empty_lookup();
700 if (get_reverse(store
, sizeof(store
), opt
, lookup
->ip6_int
, ISC_TRUE
)
702 strlcpy(lookup
->textname
, store
, sizeof(lookup
->textname
));
703 lookup
->rdtype
= dns_rdatatype_ptr
;
704 lookup
->rdtypeset
= ISC_TRUE
;
706 strlcpy(lookup
->textname
, opt
, sizeof(lookup
->textname
));
707 lookup
->rdtype
= rdtype
;
708 lookup
->rdtypeset
= ISC_TRUE
;
710 lookup
->rdclass
= rdclass
;
711 lookup
->rdclassset
= ISC_TRUE
;
712 lookup
->trace
= ISC_FALSE
;
713 lookup
->trace_root
= lookup
->trace
;
714 lookup
->ns_search_only
= ISC_FALSE
;
715 lookup
->identify
= identify
;
716 lookup
->recurse
= recurse
;
717 lookup
->aaonly
= aaonly
;
718 lookup
->retries
= tries
;
720 lookup
->comments
= comments
;
721 lookup
->tcp_mode
= tcpmode
;
722 lookup
->stats
= stats
;
723 lookup
->section_question
= section_question
;
724 lookup
->section_answer
= section_answer
;
725 lookup
->section_authority
= section_authority
;
726 lookup
->section_additional
= section_additional
;
727 lookup
->new_search
= ISC_TRUE
;
729 lookup
->servfail_stops
= ISC_FALSE
;
730 ISC_LIST_INIT(lookup
->q
);
731 ISC_LINK_INIT(lookup
, link
);
732 ISC_LIST_APPEND(lookup_list
, lookup
, link
);
733 lookup
->origin
= NULL
;
734 ISC_LIST_INIT(lookup
->my_server_list
);
735 debug("looking up %s", lookup
->textname
);
739 do_next_command(char *input
) {
742 ptr
= next_token(&input
, " \t\r\n");
745 arg
= next_token(&input
, " \t\r\n");
746 if ((strcasecmp(ptr
, "set") == 0) &&
749 else if ((strcasecmp(ptr
, "server") == 0) ||
750 (strcasecmp(ptr
, "lserver") == 0)) {
753 check_ra
= ISC_FALSE
;
755 show_settings(ISC_TRUE
, ISC_TRUE
);
756 } else if (strcasecmp(ptr
, "exit") == 0) {
758 } else if (strcasecmp(ptr
, "help") == 0 ||
759 strcasecmp(ptr
, "?") == 0) {
760 printf("The '%s' command is not yet implemented.\n", ptr
);
761 } else if (strcasecmp(ptr
, "finger") == 0 ||
762 strcasecmp(ptr
, "root") == 0 ||
763 strcasecmp(ptr
, "ls") == 0 ||
764 strcasecmp(ptr
, "view") == 0) {
765 printf("The '%s' command is not implemented.\n", ptr
);
771 get_next_command(void) {
776 buf
= isc_mem_allocate(mctx
, COMMSIZE
);
778 fatal("memory allocation failure");
782 ptr
= readline("> ");
788 ptr
= fgets(buf
, COMMSIZE
, stdin
);
791 ptr
= fgets(buf
, COMMSIZE
, stdin
);
796 do_next_command(ptr
);
801 isc_mem_free(mctx
, buf
);
805 parse_args(int argc
, char **argv
) {
806 isc_boolean_t have_lookup
= ISC_FALSE
;
808 usesearch
= ISC_TRUE
;
809 for (argc
--, argv
++; argc
> 0; argc
--, argv
++) {
810 debug("main parsing %s", argv
[0]);
811 if (argv
[0][0] == '-') {
812 if (strncasecmp(argv
[0], "-ver", 4) == 0) {
815 } else if (argv
[0][1] != 0) {
816 setoption(&argv
[0][1]);
818 have_lookup
= ISC_TRUE
;
821 have_lookup
= ISC_TRUE
;
825 set_nameserver(argv
[0]);
826 check_ra
= ISC_FALSE
;
833 flush_lookup_list(void) {
834 dig_lookup_t
*l
, *lp
;
836 dig_server_t
*s
, *sp
;
839 l
= ISC_LIST_HEAD(lookup_list
);
841 q
= ISC_LIST_HEAD(l
->q
);
843 if (q
->sock
!= NULL
) {
844 isc_socket_cancel(q
->sock
, NULL
,
846 isc_socket_detach(&q
->sock
);
848 if (ISC_LINK_LINKED(&q
->recvbuf
, link
))
849 ISC_LIST_DEQUEUE(q
->recvlist
, &q
->recvbuf
,
851 if (ISC_LINK_LINKED(&q
->lengthbuf
, link
))
852 ISC_LIST_DEQUEUE(q
->lengthlist
, &q
->lengthbuf
,
854 isc_buffer_invalidate(&q
->recvbuf
);
855 isc_buffer_invalidate(&q
->lengthbuf
);
857 q
= ISC_LIST_NEXT(q
, link
);
858 ISC_LIST_DEQUEUE(l
->q
, qp
, link
);
859 isc_mem_free(mctx
, qp
);
861 s
= ISC_LIST_HEAD(l
->my_server_list
);
864 s
= ISC_LIST_NEXT(s
, link
);
865 ISC_LIST_DEQUEUE(l
->my_server_list
, sp
, link
);
866 isc_mem_free(mctx
, sp
);
869 if (l
->sendmsg
!= NULL
)
870 dns_message_destroy(&l
->sendmsg
);
871 if (l
->timer
!= NULL
)
872 isc_timer_detach(&l
->timer
);
874 l
= ISC_LIST_NEXT(l
, link
);
875 ISC_LIST_DEQUEUE(lookup_list
, lp
, link
);
876 isc_mem_free(mctx
, lp
);
881 getinput(isc_task_t
*task
, isc_event_t
*event
) {
883 if (global_event
== NULL
)
884 global_event
= event
;
887 if (ISC_LIST_HEAD(lookup_list
) != NULL
) {
896 main(int argc
, char **argv
) {
899 interactive
= ISC_TF(isatty(0));
901 ISC_LIST_INIT(lookup_list
);
902 ISC_LIST_INIT(server_list
);
903 ISC_LIST_INIT(search_list
);
907 result
= isc_app_start();
908 check_result(result
, "isc_app_start");
913 parse_args(argc
, argv
);
916 if (domainopt
[0] != '\0')
917 set_search_domain(domainopt
);
919 result
= isc_app_onrun(mctx
, global_task
, onrun_callback
,
922 result
= isc_app_onrun(mctx
, global_task
, getinput
, NULL
);
923 check_result(result
, "isc_app_onrun");
924 in_use
= ISC_TF(!in_use
);
929 debug("done, and starting to shut down");
930 if (global_event
!= NULL
)
931 isc_event_free(&global_event
);
936 return (query_error
| print_error
);