2 * Copyright (C) 2004-2006 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.12 2006/06/09 23:50:53 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 static isc_boolean_t short_form
= ISC_TRUE
,
49 identify
= ISC_FALSE
, stats
= ISC_TRUE
,
50 comments
= ISC_TRUE
, section_question
= ISC_TRUE
,
51 section_answer
= ISC_TRUE
, section_authority
= ISC_TRUE
,
52 section_additional
= ISC_TRUE
, recurse
= ISC_TRUE
,
54 static isc_boolean_t in_use
= ISC_FALSE
;
55 static char defclass
[MXRD
] = "IN";
56 static char deftype
[MXRD
] = "A";
57 static isc_event_t
*global_event
= NULL
;
59 static char domainopt
[DNS_NAME_MAXTEXT
];
61 static const char *rcodetext
[] = {
81 static const char *rtypetext
[] = {
83 "internet address = ", /* 1 */
84 "nameserver = ", /* 2 */
87 "canonical name = ", /* 5 */
92 "rtype_10 = ", /* 10 */
93 "protocol = ", /* 11 */
97 "mail exchanger = ", /* 15 */
101 "x25 address = ", /* 19 */
102 "isdn address = ", /* 20 */
105 "nsap_ptr = ", /* 23 */
106 "signature = ", /* 24 */
110 "has AAAA address ", /* 28 */
113 "rtype_31 = ", /* 31 */
114 "rtype_32 = ", /* 32 */
115 "service = ", /* 33 */
116 "rtype_34 = ", /* 34 */
120 "v6 address = ", /* 38 */
122 "rtype_40 = ", /* 40 */
123 "optional = " /* 41 */
126 #define N_KNOWN_RRTYPES (sizeof(rtypetext) / sizeof(rtypetext[0]))
128 static void flush_lookup_list(void);
129 static void getinput(isc_task_t
*task
, isc_event_t
*event
);
132 dighost_shutdown(void) {
133 isc_event_t
*event
= global_event
;
136 debug("dighost_shutdown()");
143 isc_task_send(global_task
, &event
);
147 printsoa(dns_rdata_t
*rdata
) {
150 char namebuf
[DNS_NAME_FORMATSIZE
];
152 result
= dns_rdata_tostruct(rdata
, &soa
, NULL
);
153 check_result(result
, "dns_rdata_tostruct");
155 dns_name_format(&soa
.origin
, namebuf
, sizeof(namebuf
));
156 printf("\torigin = %s\n", namebuf
);
157 dns_name_format(&soa
.contact
, namebuf
, sizeof(namebuf
));
158 printf("\tmail addr = %s\n", namebuf
);
159 printf("\tserial = %u\n", soa
.serial
);
160 printf("\trefresh = %u\n", soa
.refresh
);
161 printf("\tretry = %u\n", soa
.retry
);
162 printf("\texpire = %u\n", soa
.expire
);
163 printf("\tminimum = %u\n", soa
.minimum
);
164 dns_rdata_freestruct(&soa
);
168 printa(dns_rdata_t
*rdata
) {
170 char text
[sizeof("255.255.255.255")];
173 isc_buffer_init(&b
, text
, sizeof(text
));
174 result
= dns_rdata_totext(rdata
, NULL
, &b
);
175 check_result(result
, "dns_rdata_totext");
176 printf("Address: %.*s\n", (int)isc_buffer_usedlength(&b
),
177 (char *)isc_buffer_base(&b
));
180 /* Just for compatibility : not use in host program */
182 printrdataset(dns_name_t
*owner_name
, dns_rdataset_t
*rdataset
,
183 isc_buffer_t
*target
)
192 printrdata(dns_rdata_t
*rdata
) {
194 isc_buffer_t
*b
= NULL
;
195 unsigned int size
= 1024;
196 isc_boolean_t done
= ISC_FALSE
;
198 if (rdata
->type
< N_KNOWN_RRTYPES
)
199 printf("%s", rtypetext
[rdata
->type
]);
201 printf("rdata_%d = ", rdata
->type
);
204 result
= isc_buffer_allocate(mctx
, &b
, size
);
205 if (result
!= ISC_R_SUCCESS
)
206 check_result(result
, "isc_buffer_allocate");
207 result
= dns_rdata_totext(rdata
, NULL
, b
);
208 if (result
== ISC_R_SUCCESS
) {
209 printf("%.*s\n", (int)isc_buffer_usedlength(b
),
210 (char *)isc_buffer_base(b
));
212 } else if (result
!= ISC_R_NOSPACE
)
213 check_result(result
, "dns_rdata_totext");
220 printsection(dig_query_t
*query
, dns_message_t
*msg
, isc_boolean_t headers
,
221 dns_section_t section
) {
222 isc_result_t result
, loopresult
;
224 dns_rdataset_t
*rdataset
= NULL
;
225 dns_rdata_t rdata
= DNS_RDATA_INIT
;
226 char namebuf
[DNS_NAME_FORMATSIZE
];
231 debug("printsection()");
233 result
= dns_message_firstname(msg
, section
);
234 if (result
== ISC_R_NOMORE
)
235 return (ISC_R_SUCCESS
);
236 else if (result
!= ISC_R_SUCCESS
)
240 dns_message_currentname(msg
, section
,
242 for (rdataset
= ISC_LIST_HEAD(name
->list
);
244 rdataset
= ISC_LIST_NEXT(rdataset
, link
)) {
245 loopresult
= dns_rdataset_first(rdataset
);
246 while (loopresult
== ISC_R_SUCCESS
) {
247 dns_rdataset_current(rdataset
, &rdata
);
248 switch (rdata
.type
) {
249 case dns_rdatatype_a
:
250 if (section
!= DNS_SECTION_ANSWER
)
251 goto def_short_section
;
252 dns_name_format(name
, namebuf
,
254 printf("Name:\t%s\n", namebuf
);
257 case dns_rdatatype_soa
:
258 dns_name_format(name
, namebuf
,
260 printf("%s\n", namebuf
);
265 dns_name_format(name
, namebuf
,
267 printf("%s\t", namebuf
);
271 dns_rdata_reset(&rdata
);
272 loopresult
= dns_rdataset_next(rdataset
);
275 result
= dns_message_nextname(msg
, section
);
276 if (result
== ISC_R_NOMORE
)
278 else if (result
!= ISC_R_SUCCESS
) {
282 return (ISC_R_SUCCESS
);
286 detailsection(dig_query_t
*query
, dns_message_t
*msg
, isc_boolean_t headers
,
287 dns_section_t section
) {
288 isc_result_t result
, loopresult
;
290 dns_rdataset_t
*rdataset
= NULL
;
291 dns_rdata_t rdata
= DNS_RDATA_INIT
;
292 char namebuf
[DNS_NAME_FORMATSIZE
];
296 debug("detailsection()");
300 case DNS_SECTION_QUESTION
:
303 case DNS_SECTION_ANSWER
:
306 case DNS_SECTION_AUTHORITY
:
307 puts(" AUTHORITY RECORDS:");
309 case DNS_SECTION_ADDITIONAL
:
310 puts(" ADDITIONAL RECORDS:");
315 result
= dns_message_firstname(msg
, section
);
316 if (result
== ISC_R_NOMORE
)
317 return (ISC_R_SUCCESS
);
318 else if (result
!= ISC_R_SUCCESS
)
322 dns_message_currentname(msg
, section
,
324 for (rdataset
= ISC_LIST_HEAD(name
->list
);
326 rdataset
= ISC_LIST_NEXT(rdataset
, link
)) {
327 if (section
== DNS_SECTION_QUESTION
) {
328 dns_name_format(name
, namebuf
,
330 printf("\t%s, ", namebuf
);
331 dns_rdatatype_format(rdataset
->type
,
334 printf("type = %s, ", namebuf
);
335 dns_rdataclass_format(rdataset
->rdclass
,
338 printf("class = %s\n", namebuf
);
340 loopresult
= dns_rdataset_first(rdataset
);
341 while (loopresult
== ISC_R_SUCCESS
) {
342 dns_rdataset_current(rdataset
, &rdata
);
344 dns_name_format(name
, namebuf
,
346 printf(" -> %s\n", namebuf
);
348 switch (rdata
.type
) {
349 case dns_rdatatype_soa
:
356 dns_rdata_reset(&rdata
);
357 loopresult
= dns_rdataset_next(rdataset
);
360 result
= dns_message_nextname(msg
, section
);
361 if (result
== ISC_R_NOMORE
)
363 else if (result
!= ISC_R_SUCCESS
) {
367 return (ISC_R_SUCCESS
);
371 received(int bytes
, isc_sockaddr_t
*from
, dig_query_t
*query
)
379 trying(char *frm
, dig_lookup_t
*lookup
) {
386 printmessage(dig_query_t
*query
, dns_message_t
*msg
, isc_boolean_t headers
) {
387 char servtext
[ISC_SOCKADDR_FORMATSIZE
];
389 debug("printmessage()");
391 isc_sockaddr_format(&query
->sockaddr
, servtext
, sizeof(servtext
));
392 printf("Server:\t\t%s\n", query
->userarg
);
393 printf("Address:\t%s\n", servtext
);
398 isc_boolean_t headers
= ISC_TRUE
;
399 puts("------------");
400 /* detailheader(query, msg);*/
401 detailsection(query
, msg
, headers
, DNS_SECTION_QUESTION
);
402 detailsection(query
, msg
, headers
, DNS_SECTION_ANSWER
);
403 detailsection(query
, msg
, headers
, DNS_SECTION_AUTHORITY
);
404 detailsection(query
, msg
, headers
, DNS_SECTION_ADDITIONAL
);
405 puts("------------");
408 if (msg
->rcode
!= 0) {
409 char nametext
[DNS_NAME_FORMATSIZE
];
410 dns_name_format(query
->lookup
->name
,
411 nametext
, sizeof(nametext
));
412 printf("** server can't find %s: %s\n", nametext
,
413 rcodetext
[msg
->rcode
]);
414 debug("returning with rcode == 0");
415 return (ISC_R_SUCCESS
);
418 if ((msg
->flags
& DNS_MESSAGEFLAG_AA
) == 0)
419 puts("Non-authoritative answer:");
420 if (!ISC_LIST_EMPTY(msg
->sections
[DNS_SECTION_ANSWER
]))
421 printsection(query
, msg
, headers
, DNS_SECTION_ANSWER
);
423 printf("*** Can't find %s: No answer\n",
424 query
->lookup
->textname
);
426 if (((msg
->flags
& DNS_MESSAGEFLAG_AA
) == 0) &&
427 (query
->lookup
->rdtype
!= dns_rdatatype_a
)) {
428 puts("\nAuthoritative answers can be found from:");
429 printsection(query
, msg
, headers
,
430 DNS_SECTION_AUTHORITY
);
431 printsection(query
, msg
, headers
,
432 DNS_SECTION_ADDITIONAL
);
434 return (ISC_R_SUCCESS
);
438 show_settings(isc_boolean_t full
, isc_boolean_t serv_only
) {
440 isc_sockaddr_t sockaddr
;
441 dig_searchlist_t
*listent
;
443 srv
= ISC_LIST_HEAD(server_list
);
445 while (srv
!= NULL
) {
446 char sockstr
[ISC_SOCKADDR_FORMATSIZE
];
448 get_address(srv
->servername
, port
, &sockaddr
);
449 isc_sockaddr_format(&sockaddr
, sockstr
, sizeof(sockstr
));
450 printf("Default server: %s\nAddress: %s\n",
451 srv
->userarg
, sockstr
);
454 srv
= ISC_LIST_NEXT(srv
, link
);
458 printf("\nSet options:\n");
459 printf(" %s\t\t\t%s\t\t%s\n",
460 tcpmode
? "vc" : "novc",
461 short_form
? "nodebug" : "debug",
462 debugging
? "d2" : "nod2");
463 printf(" %s\t\t%s\n",
464 usesearch
? "search" : "nosearch",
465 recurse
? "recurse" : "norecurse");
466 printf(" timeout = %d\t\tretry = %d\tport = %d\n",
467 timeout
, tries
, port
);
468 printf(" querytype = %-8s\tclass = %s\n", deftype
, defclass
);
469 printf(" srchlist = ");
470 for (listent
= ISC_LIST_HEAD(search_list
);
472 listent
= ISC_LIST_NEXT(listent
, link
)) {
473 printf("%s", listent
->origin
);
474 if (ISC_LIST_NEXT(listent
, link
) != NULL
)
481 testtype(char *typetext
) {
484 dns_rdatatype_t rdtype
;
487 tr
.length
= strlen(typetext
);
488 result
= dns_rdatatype_fromtext(&rdtype
, &tr
);
489 if (result
== ISC_R_SUCCESS
)
492 printf("unknown query type: %s\n", typetext
);
498 testclass(char *typetext
) {
501 dns_rdataclass_t rdclass
;
504 tr
.length
= strlen(typetext
);
505 result
= dns_rdataclass_fromtext(&rdclass
, &tr
);
506 if (result
== ISC_R_SUCCESS
)
509 printf("unknown query class: %s\n", typetext
);
515 safecpy(char *dest
, char *src
, int size
) {
516 strncpy(dest
, src
, size
);
521 parse_uint(isc_uint32_t
*uip
, const char *value
, isc_uint32_t max
,
524 isc_result_t result
= isc_parse_uint32(&n
, value
, 10);
525 if (result
== ISC_R_SUCCESS
&& n
> max
)
526 result
= ISC_R_RANGE
;
527 if (result
!= ISC_R_SUCCESS
) {
528 printf("invalid %s '%s': %s\n", desc
,
529 value
, isc_result_totext(result
));
533 return (ISC_R_SUCCESS
);
537 set_port(const char *value
) {
539 isc_result_t result
= parse_uint(&n
, value
, 65535, "port");
540 if (result
== ISC_R_SUCCESS
)
541 port
= (isc_uint16_t
) n
;
545 set_timeout(const char *value
) {
547 isc_result_t result
= parse_uint(&n
, value
, UINT_MAX
, "timeout");
548 if (result
== ISC_R_SUCCESS
)
553 set_tries(const char *value
) {
555 isc_result_t result
= parse_uint(&n
, value
, INT_MAX
, "tries");
556 if (result
== ISC_R_SUCCESS
)
561 setoption(char *opt
) {
562 if (strncasecmp(opt
, "all", 4) == 0) {
563 show_settings(ISC_TRUE
, ISC_FALSE
);
564 } else if (strncasecmp(opt
, "class=", 6) == 0) {
565 if (testclass(&opt
[6]))
566 safecpy(defclass
, &opt
[6], sizeof(defclass
));
567 } else if (strncasecmp(opt
, "cl=", 3) == 0) {
568 if (testclass(&opt
[3]))
569 safecpy(defclass
, &opt
[3], sizeof(defclass
));
570 } else if (strncasecmp(opt
, "type=", 5) == 0) {
571 if (testtype(&opt
[5]))
572 safecpy(deftype
, &opt
[5], sizeof(deftype
));
573 } else if (strncasecmp(opt
, "ty=", 3) == 0) {
574 if (testtype(&opt
[3]))
575 safecpy(deftype
, &opt
[3], sizeof(deftype
));
576 } else if (strncasecmp(opt
, "querytype=", 10) == 0) {
577 if (testtype(&opt
[10]))
578 safecpy(deftype
, &opt
[10], sizeof(deftype
));
579 } else if (strncasecmp(opt
, "query=", 6) == 0) {
580 if (testtype(&opt
[6]))
581 safecpy(deftype
, &opt
[6], sizeof(deftype
));
582 } else if (strncasecmp(opt
, "qu=", 3) == 0) {
583 if (testtype(&opt
[3]))
584 safecpy(deftype
, &opt
[3], sizeof(deftype
));
585 } else if (strncasecmp(opt
, "q=", 2) == 0) {
586 if (testtype(&opt
[2]))
587 safecpy(deftype
, &opt
[2], sizeof(deftype
));
588 } else if (strncasecmp(opt
, "domain=", 7) == 0) {
589 safecpy(domainopt
, &opt
[7], sizeof(domainopt
));
590 set_search_domain(domainopt
);
591 usesearch
= ISC_TRUE
;
592 } else if (strncasecmp(opt
, "do=", 3) == 0) {
593 safecpy(domainopt
, &opt
[3], sizeof(domainopt
));
594 set_search_domain(domainopt
);
595 usesearch
= ISC_TRUE
;
596 } else if (strncasecmp(opt
, "port=", 5) == 0) {
598 } else if (strncasecmp(opt
, "po=", 3) == 0) {
600 } else if (strncasecmp(opt
, "timeout=", 8) == 0) {
601 set_timeout(&opt
[8]);
602 } else if (strncasecmp(opt
, "t=", 2) == 0) {
603 set_timeout(&opt
[2]);
604 } else if (strncasecmp(opt
, "rec", 3) == 0) {
606 } else if (strncasecmp(opt
, "norec", 5) == 0) {
608 } else if (strncasecmp(opt
, "retry=", 6) == 0) {
610 } else if (strncasecmp(opt
, "ret=", 4) == 0) {
612 } else if (strncasecmp(opt
, "def", 3) == 0) {
613 usesearch
= ISC_TRUE
;
614 } else if (strncasecmp(opt
, "nodef", 5) == 0) {
615 usesearch
= ISC_FALSE
;
616 } else if (strncasecmp(opt
, "vc", 3) == 0) {
618 } else if (strncasecmp(opt
, "novc", 5) == 0) {
620 } else if (strncasecmp(opt
, "deb", 3) == 0) {
621 short_form
= ISC_FALSE
;
622 } else if (strncasecmp(opt
, "nodeb", 5) == 0) {
623 short_form
= ISC_TRUE
;
624 } else if (strncasecmp(opt
, "d2", 2) == 0) {
625 debugging
= ISC_TRUE
;
626 } else if (strncasecmp(opt
, "nod2", 4) == 0) {
627 debugging
= ISC_FALSE
;
628 } else if (strncasecmp(opt
, "search", 3) == 0) {
629 usesearch
= ISC_TRUE
;
630 } else if (strncasecmp(opt
, "nosearch", 5) == 0) {
631 usesearch
= ISC_FALSE
;
632 } else if (strncasecmp(opt
, "sil", 3) == 0) {
633 /* deprecation_msg = ISC_FALSE; */
635 printf("*** Invalid option: %s\n", opt
);
640 addlookup(char *opt
) {
641 dig_lookup_t
*lookup
;
644 dns_rdatatype_t rdtype
;
645 dns_rdataclass_t rdclass
;
648 debug("addlookup()");
650 tr
.length
= strlen(deftype
);
651 result
= dns_rdatatype_fromtext(&rdtype
, &tr
);
652 if (result
!= ISC_R_SUCCESS
) {
653 printf("unknown query type: %s\n", deftype
);
654 rdclass
= dns_rdatatype_a
;
657 tr
.length
= strlen(defclass
);
658 result
= dns_rdataclass_fromtext(&rdclass
, &tr
);
659 if (result
!= ISC_R_SUCCESS
) {
660 printf("unknown query class: %s\n", defclass
);
661 rdclass
= dns_rdataclass_in
;
663 lookup
= make_empty_lookup();
664 if (get_reverse(store
, sizeof(store
), opt
, lookup
->ip6_int
, ISC_TRUE
)
666 safecpy(lookup
->textname
, store
, sizeof(lookup
->textname
));
667 lookup
->rdtype
= dns_rdatatype_ptr
;
668 lookup
->rdtypeset
= ISC_TRUE
;
670 safecpy(lookup
->textname
, opt
, sizeof(lookup
->textname
));
671 lookup
->rdtype
= rdtype
;
672 lookup
->rdtypeset
= ISC_TRUE
;
674 lookup
->rdclass
= rdclass
;
675 lookup
->rdclassset
= ISC_TRUE
;
676 lookup
->trace
= ISC_FALSE
;
677 lookup
->trace_root
= lookup
->trace
;
678 lookup
->ns_search_only
= ISC_FALSE
;
679 lookup
->identify
= identify
;
680 lookup
->recurse
= recurse
;
681 lookup
->aaonly
= aaonly
;
682 lookup
->retries
= tries
;
684 lookup
->comments
= comments
;
685 lookup
->tcp_mode
= tcpmode
;
686 lookup
->stats
= stats
;
687 lookup
->section_question
= section_question
;
688 lookup
->section_answer
= section_answer
;
689 lookup
->section_authority
= section_authority
;
690 lookup
->section_additional
= section_additional
;
691 lookup
->new_search
= ISC_TRUE
;
692 ISC_LIST_INIT(lookup
->q
);
693 ISC_LINK_INIT(lookup
, link
);
694 ISC_LIST_APPEND(lookup_list
, lookup
, link
);
695 lookup
->origin
= NULL
;
696 ISC_LIST_INIT(lookup
->my_server_list
);
697 debug("looking up %s", lookup
->textname
);
701 get_next_command(void) {
707 buf
= isc_mem_allocate(mctx
, COMMSIZE
);
709 fatal("memory allocation failure");
713 ptr
= fgets(buf
, COMMSIZE
, stdin
);
720 ptr
= next_token(&input
, " \t\r\n");
723 arg
= next_token(&input
, " \t\r\n");
724 if ((strcasecmp(ptr
, "set") == 0) &&
727 else if ((strcasecmp(ptr
, "server") == 0) ||
728 (strcasecmp(ptr
, "lserver") == 0)) {
732 show_settings(ISC_TRUE
, ISC_TRUE
);
733 } else if (strcasecmp(ptr
, "exit") == 0) {
736 } else if (strcasecmp(ptr
, "help") == 0 ||
737 strcasecmp(ptr
, "?") == 0) {
738 printf("The '%s' command is not yet implemented.\n", ptr
);
740 } else if (strcasecmp(ptr
, "finger") == 0 ||
741 strcasecmp(ptr
, "root") == 0 ||
742 strcasecmp(ptr
, "ls") == 0 ||
743 strcasecmp(ptr
, "view") == 0) {
744 printf("The '%s' command is not implemented.\n", ptr
);
749 isc_mem_free(mctx
, buf
);
753 parse_args(int argc
, char **argv
) {
754 isc_boolean_t have_lookup
= ISC_FALSE
;
756 usesearch
= ISC_TRUE
;
757 for (argc
--, argv
++; argc
> 0; argc
--, argv
++) {
758 debug("main parsing %s", argv
[0]);
759 if (argv
[0][0] == '-') {
761 setoption(&argv
[0][1]);
763 have_lookup
= ISC_TRUE
;
766 have_lookup
= ISC_TRUE
;
771 set_nameserver(argv
[0]);
777 flush_lookup_list(void) {
778 dig_lookup_t
*l
, *lp
;
780 dig_server_t
*s
, *sp
;
783 l
= ISC_LIST_HEAD(lookup_list
);
785 q
= ISC_LIST_HEAD(l
->q
);
787 if (q
->sock
!= NULL
) {
788 isc_socket_cancel(q
->sock
, NULL
,
790 isc_socket_detach(&q
->sock
);
792 if (ISC_LINK_LINKED(&q
->recvbuf
, link
))
793 ISC_LIST_DEQUEUE(q
->recvlist
, &q
->recvbuf
,
795 if (ISC_LINK_LINKED(&q
->lengthbuf
, link
))
796 ISC_LIST_DEQUEUE(q
->lengthlist
, &q
->lengthbuf
,
798 isc_buffer_invalidate(&q
->recvbuf
);
799 isc_buffer_invalidate(&q
->lengthbuf
);
801 q
= ISC_LIST_NEXT(q
, link
);
802 ISC_LIST_DEQUEUE(l
->q
, qp
, link
);
803 isc_mem_free(mctx
, qp
);
805 s
= ISC_LIST_HEAD(l
->my_server_list
);
808 s
= ISC_LIST_NEXT(s
, link
);
809 ISC_LIST_DEQUEUE(l
->my_server_list
, sp
, link
);
810 isc_mem_free(mctx
, sp
);
813 if (l
->sendmsg
!= NULL
)
814 dns_message_destroy(&l
->sendmsg
);
815 if (l
->timer
!= NULL
)
816 isc_timer_detach(&l
->timer
);
818 l
= ISC_LIST_NEXT(l
, link
);
819 ISC_LIST_DEQUEUE(lookup_list
, lp
, link
);
820 isc_mem_free(mctx
, lp
);
825 getinput(isc_task_t
*task
, isc_event_t
*event
) {
827 if (global_event
== NULL
)
828 global_event
= event
;
831 if (ISC_LIST_HEAD(lookup_list
) != NULL
) {
840 main(int argc
, char **argv
) {
843 ISC_LIST_INIT(lookup_list
);
844 ISC_LIST_INIT(server_list
);
845 ISC_LIST_INIT(search_list
);
847 result
= isc_app_start();
848 check_result(result
, "isc_app_start");
853 parse_args(argc
, argv
);
856 if (domainopt
[0] != '\0')
857 set_search_domain(domainopt
);
859 result
= isc_app_onrun(mctx
, global_task
, onrun_callback
,
862 result
= isc_app_onrun(mctx
, global_task
, getinput
, NULL
);
863 check_result(result
, "isc_app_onrun");
864 in_use
= ISC_TF(!in_use
);
869 debug("done, and starting to shut down");
870 if (global_event
!= NULL
)
871 isc_event_free(&global_event
);