xref: /minix3/external/bsd/bind/dist/bin/dig/nslookup.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: nslookup.c,v 1.11 2015/07/08 17:28:54 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2004-2015  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Copyright (C) 2000-2003  Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek  *
7*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek  *
11*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek  */
19*00b67f09SDavid van Moolenbroek 
20*00b67f09SDavid van Moolenbroek #include <config.h>
21*00b67f09SDavid van Moolenbroek 
22*00b67f09SDavid van Moolenbroek #include <stdlib.h>
23*00b67f09SDavid van Moolenbroek #include <unistd.h>
24*00b67f09SDavid van Moolenbroek 
25*00b67f09SDavid van Moolenbroek #include <isc/app.h>
26*00b67f09SDavid van Moolenbroek #include <isc/buffer.h>
27*00b67f09SDavid van Moolenbroek #include <isc/commandline.h>
28*00b67f09SDavid van Moolenbroek #include <isc/event.h>
29*00b67f09SDavid van Moolenbroek #include <isc/parseint.h>
30*00b67f09SDavid van Moolenbroek #include <isc/print.h>
31*00b67f09SDavid van Moolenbroek #include <isc/string.h>
32*00b67f09SDavid van Moolenbroek #include <isc/timer.h>
33*00b67f09SDavid van Moolenbroek #include <isc/util.h>
34*00b67f09SDavid van Moolenbroek #include <isc/task.h>
35*00b67f09SDavid van Moolenbroek #include <isc/netaddr.h>
36*00b67f09SDavid van Moolenbroek 
37*00b67f09SDavid van Moolenbroek #include <dns/message.h>
38*00b67f09SDavid van Moolenbroek #include <dns/name.h>
39*00b67f09SDavid van Moolenbroek #include <dns/fixedname.h>
40*00b67f09SDavid van Moolenbroek #include <dns/rdata.h>
41*00b67f09SDavid van Moolenbroek #include <dns/rdataclass.h>
42*00b67f09SDavid van Moolenbroek #include <dns/rdataset.h>
43*00b67f09SDavid van Moolenbroek #include <dns/rdatastruct.h>
44*00b67f09SDavid van Moolenbroek #include <dns/rdatatype.h>
45*00b67f09SDavid van Moolenbroek #include <dns/byaddr.h>
46*00b67f09SDavid van Moolenbroek 
47*00b67f09SDavid van Moolenbroek #include <dig/dig.h>
48*00b67f09SDavid van Moolenbroek 
49*00b67f09SDavid van Moolenbroek #if defined(HAVE_READLINE)
50*00b67f09SDavid van Moolenbroek #include <readline/readline.h>
51*00b67f09SDavid van Moolenbroek #include <readline/history.h>
52*00b67f09SDavid van Moolenbroek #endif
53*00b67f09SDavid van Moolenbroek 
54*00b67f09SDavid van Moolenbroek static isc_boolean_t short_form = ISC_TRUE,
55*00b67f09SDavid van Moolenbroek 	tcpmode = ISC_FALSE,
56*00b67f09SDavid van Moolenbroek 	identify = ISC_FALSE, stats = ISC_TRUE,
57*00b67f09SDavid van Moolenbroek 	comments = ISC_TRUE, section_question = ISC_TRUE,
58*00b67f09SDavid van Moolenbroek 	section_answer = ISC_TRUE, section_authority = ISC_TRUE,
59*00b67f09SDavid van Moolenbroek 	section_additional = ISC_TRUE, recurse = ISC_TRUE,
60*00b67f09SDavid van Moolenbroek 	aaonly = ISC_FALSE, nofail = ISC_TRUE;
61*00b67f09SDavid van Moolenbroek 
62*00b67f09SDavid van Moolenbroek static isc_boolean_t interactive;
63*00b67f09SDavid van Moolenbroek 
64*00b67f09SDavid van Moolenbroek static isc_boolean_t in_use = ISC_FALSE;
65*00b67f09SDavid van Moolenbroek static char defclass[MXRD] = "IN";
66*00b67f09SDavid van Moolenbroek static char deftype[MXRD] = "A";
67*00b67f09SDavid van Moolenbroek static isc_event_t *global_event = NULL;
68*00b67f09SDavid van Moolenbroek static int query_error = 1, print_error = 0;
69*00b67f09SDavid van Moolenbroek 
70*00b67f09SDavid van Moolenbroek static char domainopt[DNS_NAME_MAXTEXT];
71*00b67f09SDavid van Moolenbroek 
72*00b67f09SDavid van Moolenbroek static const char *rcodetext[] = {
73*00b67f09SDavid van Moolenbroek 	"NOERROR",
74*00b67f09SDavid van Moolenbroek 	"FORMERR",
75*00b67f09SDavid van Moolenbroek 	"SERVFAIL",
76*00b67f09SDavid van Moolenbroek 	"NXDOMAIN",
77*00b67f09SDavid van Moolenbroek 	"NOTIMP",
78*00b67f09SDavid van Moolenbroek 	"REFUSED",
79*00b67f09SDavid van Moolenbroek 	"YXDOMAIN",
80*00b67f09SDavid van Moolenbroek 	"YXRRSET",
81*00b67f09SDavid van Moolenbroek 	"NXRRSET",
82*00b67f09SDavid van Moolenbroek 	"NOTAUTH",
83*00b67f09SDavid van Moolenbroek 	"NOTZONE",
84*00b67f09SDavid van Moolenbroek 	"RESERVED11",
85*00b67f09SDavid van Moolenbroek 	"RESERVED12",
86*00b67f09SDavid van Moolenbroek 	"RESERVED13",
87*00b67f09SDavid van Moolenbroek 	"RESERVED14",
88*00b67f09SDavid van Moolenbroek 	"RESERVED15",
89*00b67f09SDavid van Moolenbroek 	"BADVERS"
90*00b67f09SDavid van Moolenbroek };
91*00b67f09SDavid van Moolenbroek 
92*00b67f09SDavid van Moolenbroek static const char *rtypetext[] = {
93*00b67f09SDavid van Moolenbroek 	"rtype_0 = ",			/* 0 */
94*00b67f09SDavid van Moolenbroek 	"internet address = ",		/* 1 */
95*00b67f09SDavid van Moolenbroek 	"nameserver = ",		/* 2 */
96*00b67f09SDavid van Moolenbroek 	"md = ",			/* 3 */
97*00b67f09SDavid van Moolenbroek 	"mf = ",			/* 4 */
98*00b67f09SDavid van Moolenbroek 	"canonical name = ",		/* 5 */
99*00b67f09SDavid van Moolenbroek 	"soa = ",			/* 6 */
100*00b67f09SDavid van Moolenbroek 	"mb = ",			/* 7 */
101*00b67f09SDavid van Moolenbroek 	"mg = ",			/* 8 */
102*00b67f09SDavid van Moolenbroek 	"mr = ",			/* 9 */
103*00b67f09SDavid van Moolenbroek 	"rtype_10 = ",			/* 10 */
104*00b67f09SDavid van Moolenbroek 	"protocol = ",			/* 11 */
105*00b67f09SDavid van Moolenbroek 	"name = ",			/* 12 */
106*00b67f09SDavid van Moolenbroek 	"hinfo = ",			/* 13 */
107*00b67f09SDavid van Moolenbroek 	"minfo = ",			/* 14 */
108*00b67f09SDavid van Moolenbroek 	"mail exchanger = ",		/* 15 */
109*00b67f09SDavid van Moolenbroek 	"text = ",			/* 16 */
110*00b67f09SDavid van Moolenbroek 	"rp = ",       			/* 17 */
111*00b67f09SDavid van Moolenbroek 	"afsdb = ",			/* 18 */
112*00b67f09SDavid van Moolenbroek 	"x25 address = ",		/* 19 */
113*00b67f09SDavid van Moolenbroek 	"isdn address = ",		/* 20 */
114*00b67f09SDavid van Moolenbroek 	"rt = ",			/* 21 */
115*00b67f09SDavid van Moolenbroek 	"nsap = ",			/* 22 */
116*00b67f09SDavid van Moolenbroek 	"nsap_ptr = ",			/* 23 */
117*00b67f09SDavid van Moolenbroek 	"signature = ",			/* 24 */
118*00b67f09SDavid van Moolenbroek 	"key = ",			/* 25 */
119*00b67f09SDavid van Moolenbroek 	"px = ",			/* 26 */
120*00b67f09SDavid van Moolenbroek 	"gpos = ",			/* 27 */
121*00b67f09SDavid van Moolenbroek 	"has AAAA address ",		/* 28 */
122*00b67f09SDavid van Moolenbroek 	"loc = ",			/* 29 */
123*00b67f09SDavid van Moolenbroek 	"next = ",			/* 30 */
124*00b67f09SDavid van Moolenbroek 	"rtype_31 = ",			/* 31 */
125*00b67f09SDavid van Moolenbroek 	"rtype_32 = ",			/* 32 */
126*00b67f09SDavid van Moolenbroek 	"service = ",			/* 33 */
127*00b67f09SDavid van Moolenbroek 	"rtype_34 = ",			/* 34 */
128*00b67f09SDavid van Moolenbroek 	"naptr = ",			/* 35 */
129*00b67f09SDavid van Moolenbroek 	"kx = ",			/* 36 */
130*00b67f09SDavid van Moolenbroek 	"cert = ",			/* 37 */
131*00b67f09SDavid van Moolenbroek 	"v6 address = ",		/* 38 */
132*00b67f09SDavid van Moolenbroek 	"dname = ",			/* 39 */
133*00b67f09SDavid van Moolenbroek 	"rtype_40 = ",			/* 40 */
134*00b67f09SDavid van Moolenbroek 	"optional = "			/* 41 */
135*00b67f09SDavid van Moolenbroek };
136*00b67f09SDavid van Moolenbroek 
137*00b67f09SDavid van Moolenbroek #define N_KNOWN_RRTYPES (sizeof(rtypetext) / sizeof(rtypetext[0]))
138*00b67f09SDavid van Moolenbroek 
139*00b67f09SDavid van Moolenbroek static void flush_lookup_list(void);
140*00b67f09SDavid van Moolenbroek static void getinput(isc_task_t *task, isc_event_t *event);
141*00b67f09SDavid van Moolenbroek 
142*00b67f09SDavid van Moolenbroek static char *
rcode_totext(dns_rcode_t rcode)143*00b67f09SDavid van Moolenbroek rcode_totext(dns_rcode_t rcode)
144*00b67f09SDavid van Moolenbroek {
145*00b67f09SDavid van Moolenbroek 	static char buf[sizeof("?65535")];
146*00b67f09SDavid van Moolenbroek 	union {
147*00b67f09SDavid van Moolenbroek 		const char *consttext;
148*00b67f09SDavid van Moolenbroek 		char *deconsttext;
149*00b67f09SDavid van Moolenbroek 	} totext;
150*00b67f09SDavid van Moolenbroek 
151*00b67f09SDavid van Moolenbroek 	if (rcode >= (sizeof(rcodetext)/sizeof(rcodetext[0]))) {
152*00b67f09SDavid van Moolenbroek 		snprintf(buf, sizeof(buf), "?%u", rcode);
153*00b67f09SDavid van Moolenbroek 		totext.deconsttext = buf;
154*00b67f09SDavid van Moolenbroek 	} else
155*00b67f09SDavid van Moolenbroek 		totext.consttext = rcodetext[rcode];
156*00b67f09SDavid van Moolenbroek 	return totext.deconsttext;
157*00b67f09SDavid van Moolenbroek }
158*00b67f09SDavid van Moolenbroek 
159*00b67f09SDavid van Moolenbroek void
dighost_shutdown(void)160*00b67f09SDavid van Moolenbroek dighost_shutdown(void) {
161*00b67f09SDavid van Moolenbroek 	isc_event_t *event = global_event;
162*00b67f09SDavid van Moolenbroek 
163*00b67f09SDavid van Moolenbroek 	flush_lookup_list();
164*00b67f09SDavid van Moolenbroek 	debug("dighost_shutdown()");
165*00b67f09SDavid van Moolenbroek 
166*00b67f09SDavid van Moolenbroek 	if (!in_use) {
167*00b67f09SDavid van Moolenbroek 		isc_app_shutdown();
168*00b67f09SDavid van Moolenbroek 		return;
169*00b67f09SDavid van Moolenbroek 	}
170*00b67f09SDavid van Moolenbroek 
171*00b67f09SDavid van Moolenbroek 	isc_task_send(global_task, &event);
172*00b67f09SDavid van Moolenbroek }
173*00b67f09SDavid van Moolenbroek 
174*00b67f09SDavid van Moolenbroek static void
printsoa(dns_rdata_t * rdata)175*00b67f09SDavid van Moolenbroek printsoa(dns_rdata_t *rdata) {
176*00b67f09SDavid van Moolenbroek 	dns_rdata_soa_t soa;
177*00b67f09SDavid van Moolenbroek 	isc_result_t result;
178*00b67f09SDavid van Moolenbroek 	char namebuf[DNS_NAME_FORMATSIZE];
179*00b67f09SDavid van Moolenbroek 
180*00b67f09SDavid van Moolenbroek 	result = dns_rdata_tostruct(rdata, &soa, NULL);
181*00b67f09SDavid van Moolenbroek 	check_result(result, "dns_rdata_tostruct");
182*00b67f09SDavid van Moolenbroek 
183*00b67f09SDavid van Moolenbroek 	dns_name_format(&soa.origin, namebuf, sizeof(namebuf));
184*00b67f09SDavid van Moolenbroek 	printf("\torigin = %s\n", namebuf);
185*00b67f09SDavid van Moolenbroek 	dns_name_format(&soa.contact, namebuf, sizeof(namebuf));
186*00b67f09SDavid van Moolenbroek 	printf("\tmail addr = %s\n", namebuf);
187*00b67f09SDavid van Moolenbroek 	printf("\tserial = %u\n", soa.serial);
188*00b67f09SDavid van Moolenbroek 	printf("\trefresh = %u\n", soa.refresh);
189*00b67f09SDavid van Moolenbroek 	printf("\tretry = %u\n", soa.retry);
190*00b67f09SDavid van Moolenbroek 	printf("\texpire = %u\n", soa.expire);
191*00b67f09SDavid van Moolenbroek 	printf("\tminimum = %u\n", soa.minimum);
192*00b67f09SDavid van Moolenbroek 	dns_rdata_freestruct(&soa);
193*00b67f09SDavid van Moolenbroek }
194*00b67f09SDavid van Moolenbroek 
195*00b67f09SDavid van Moolenbroek static void
printa(dns_rdata_t * rdata)196*00b67f09SDavid van Moolenbroek printa(dns_rdata_t *rdata) {
197*00b67f09SDavid van Moolenbroek 	isc_result_t result;
198*00b67f09SDavid van Moolenbroek 	char text[sizeof("255.255.255.255")];
199*00b67f09SDavid van Moolenbroek 	isc_buffer_t b;
200*00b67f09SDavid van Moolenbroek 
201*00b67f09SDavid van Moolenbroek 	isc_buffer_init(&b, text, sizeof(text));
202*00b67f09SDavid van Moolenbroek 	result = dns_rdata_totext(rdata, NULL, &b);
203*00b67f09SDavid van Moolenbroek 	check_result(result, "dns_rdata_totext");
204*00b67f09SDavid van Moolenbroek 	printf("Address: %.*s\n", (int)isc_buffer_usedlength(&b),
205*00b67f09SDavid van Moolenbroek 	       (char *)isc_buffer_base(&b));
206*00b67f09SDavid van Moolenbroek }
207*00b67f09SDavid van Moolenbroek #ifdef DIG_SIGCHASE
208*00b67f09SDavid van Moolenbroek /* Just for compatibility : not use in host program */
209*00b67f09SDavid van Moolenbroek isc_result_t
printrdataset(dns_name_t * owner_name,dns_rdataset_t * rdataset,isc_buffer_t * target)210*00b67f09SDavid van Moolenbroek printrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset,
211*00b67f09SDavid van Moolenbroek 	      isc_buffer_t *target)
212*00b67f09SDavid van Moolenbroek {
213*00b67f09SDavid van Moolenbroek 	UNUSED(owner_name);
214*00b67f09SDavid van Moolenbroek 	UNUSED(rdataset);
215*00b67f09SDavid van Moolenbroek 	UNUSED(target);
216*00b67f09SDavid van Moolenbroek 	return(ISC_FALSE);
217*00b67f09SDavid van Moolenbroek }
218*00b67f09SDavid van Moolenbroek #endif
219*00b67f09SDavid van Moolenbroek static void
printrdata(dns_rdata_t * rdata)220*00b67f09SDavid van Moolenbroek printrdata(dns_rdata_t *rdata) {
221*00b67f09SDavid van Moolenbroek 	isc_result_t result;
222*00b67f09SDavid van Moolenbroek 	isc_buffer_t *b = NULL;
223*00b67f09SDavid van Moolenbroek 	unsigned int size = 1024;
224*00b67f09SDavid van Moolenbroek 	isc_boolean_t done = ISC_FALSE;
225*00b67f09SDavid van Moolenbroek 
226*00b67f09SDavid van Moolenbroek 	if (rdata->type < N_KNOWN_RRTYPES)
227*00b67f09SDavid van Moolenbroek 		printf("%s", rtypetext[rdata->type]);
228*00b67f09SDavid van Moolenbroek 	else
229*00b67f09SDavid van Moolenbroek 		printf("rdata_%d = ", rdata->type);
230*00b67f09SDavid van Moolenbroek 
231*00b67f09SDavid van Moolenbroek 	while (!done) {
232*00b67f09SDavid van Moolenbroek 		result = isc_buffer_allocate(mctx, &b, size);
233*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS)
234*00b67f09SDavid van Moolenbroek 			check_result(result, "isc_buffer_allocate");
235*00b67f09SDavid van Moolenbroek 		result = dns_rdata_totext(rdata, NULL, b);
236*00b67f09SDavid van Moolenbroek 		if (result == ISC_R_SUCCESS) {
237*00b67f09SDavid van Moolenbroek 			printf("%.*s\n", (int)isc_buffer_usedlength(b),
238*00b67f09SDavid van Moolenbroek 			       (char *)isc_buffer_base(b));
239*00b67f09SDavid van Moolenbroek 			done = ISC_TRUE;
240*00b67f09SDavid van Moolenbroek 		} else if (result != ISC_R_NOSPACE)
241*00b67f09SDavid van Moolenbroek 			check_result(result, "dns_rdata_totext");
242*00b67f09SDavid van Moolenbroek 		isc_buffer_free(&b);
243*00b67f09SDavid van Moolenbroek 		size *= 2;
244*00b67f09SDavid van Moolenbroek 	}
245*00b67f09SDavid van Moolenbroek }
246*00b67f09SDavid van Moolenbroek 
247*00b67f09SDavid van Moolenbroek static isc_result_t
printsection(dig_query_t * query,dns_message_t * msg,isc_boolean_t headers,dns_section_t section)248*00b67f09SDavid van Moolenbroek printsection(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers,
249*00b67f09SDavid van Moolenbroek 	     dns_section_t section) {
250*00b67f09SDavid van Moolenbroek 	isc_result_t result, loopresult;
251*00b67f09SDavid van Moolenbroek 	dns_name_t *name;
252*00b67f09SDavid van Moolenbroek 	dns_rdataset_t *rdataset = NULL;
253*00b67f09SDavid van Moolenbroek 	dns_rdata_t rdata = DNS_RDATA_INIT;
254*00b67f09SDavid van Moolenbroek 	char namebuf[DNS_NAME_FORMATSIZE];
255*00b67f09SDavid van Moolenbroek 
256*00b67f09SDavid van Moolenbroek 	UNUSED(query);
257*00b67f09SDavid van Moolenbroek 	UNUSED(headers);
258*00b67f09SDavid van Moolenbroek 
259*00b67f09SDavid van Moolenbroek 	debug("printsection()");
260*00b67f09SDavid van Moolenbroek 
261*00b67f09SDavid van Moolenbroek 	result = dns_message_firstname(msg, section);
262*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_NOMORE)
263*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
264*00b67f09SDavid van Moolenbroek 	else if (result != ISC_R_SUCCESS)
265*00b67f09SDavid van Moolenbroek 		return (result);
266*00b67f09SDavid van Moolenbroek 	for (;;) {
267*00b67f09SDavid van Moolenbroek 		name = NULL;
268*00b67f09SDavid van Moolenbroek 		dns_message_currentname(msg, section,
269*00b67f09SDavid van Moolenbroek 					&name);
270*00b67f09SDavid van Moolenbroek 		for (rdataset = ISC_LIST_HEAD(name->list);
271*00b67f09SDavid van Moolenbroek 		     rdataset != NULL;
272*00b67f09SDavid van Moolenbroek 		     rdataset = ISC_LIST_NEXT(rdataset, link)) {
273*00b67f09SDavid van Moolenbroek 			loopresult = dns_rdataset_first(rdataset);
274*00b67f09SDavid van Moolenbroek 			while (loopresult == ISC_R_SUCCESS) {
275*00b67f09SDavid van Moolenbroek 				dns_rdataset_current(rdataset, &rdata);
276*00b67f09SDavid van Moolenbroek 				switch (rdata.type) {
277*00b67f09SDavid van Moolenbroek 				case dns_rdatatype_a:
278*00b67f09SDavid van Moolenbroek 					if (section != DNS_SECTION_ANSWER)
279*00b67f09SDavid van Moolenbroek 						goto def_short_section;
280*00b67f09SDavid van Moolenbroek 					dns_name_format(name, namebuf,
281*00b67f09SDavid van Moolenbroek 							sizeof(namebuf));
282*00b67f09SDavid van Moolenbroek 					printf("Name:\t%s\n", namebuf);
283*00b67f09SDavid van Moolenbroek 					printa(&rdata);
284*00b67f09SDavid van Moolenbroek 					break;
285*00b67f09SDavid van Moolenbroek 				case dns_rdatatype_soa:
286*00b67f09SDavid van Moolenbroek 					dns_name_format(name, namebuf,
287*00b67f09SDavid van Moolenbroek 							sizeof(namebuf));
288*00b67f09SDavid van Moolenbroek 					printf("%s\n", namebuf);
289*00b67f09SDavid van Moolenbroek 					printsoa(&rdata);
290*00b67f09SDavid van Moolenbroek 					break;
291*00b67f09SDavid van Moolenbroek 				default:
292*00b67f09SDavid van Moolenbroek 				def_short_section:
293*00b67f09SDavid van Moolenbroek 					dns_name_format(name, namebuf,
294*00b67f09SDavid van Moolenbroek 							sizeof(namebuf));
295*00b67f09SDavid van Moolenbroek 					printf("%s\t", namebuf);
296*00b67f09SDavid van Moolenbroek 					printrdata(&rdata);
297*00b67f09SDavid van Moolenbroek 					break;
298*00b67f09SDavid van Moolenbroek 				}
299*00b67f09SDavid van Moolenbroek 				dns_rdata_reset(&rdata);
300*00b67f09SDavid van Moolenbroek 				loopresult = dns_rdataset_next(rdataset);
301*00b67f09SDavid van Moolenbroek 			}
302*00b67f09SDavid van Moolenbroek 		}
303*00b67f09SDavid van Moolenbroek 		result = dns_message_nextname(msg, section);
304*00b67f09SDavid van Moolenbroek 		if (result == ISC_R_NOMORE)
305*00b67f09SDavid van Moolenbroek 			break;
306*00b67f09SDavid van Moolenbroek 		else if (result != ISC_R_SUCCESS) {
307*00b67f09SDavid van Moolenbroek 			return (result);
308*00b67f09SDavid van Moolenbroek 		}
309*00b67f09SDavid van Moolenbroek 	}
310*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
311*00b67f09SDavid van Moolenbroek }
312*00b67f09SDavid van Moolenbroek 
313*00b67f09SDavid van Moolenbroek static isc_result_t
detailsection(dig_query_t * query,dns_message_t * msg,isc_boolean_t headers,dns_section_t section)314*00b67f09SDavid van Moolenbroek detailsection(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers,
315*00b67f09SDavid van Moolenbroek 	     dns_section_t section) {
316*00b67f09SDavid van Moolenbroek 	isc_result_t result, loopresult;
317*00b67f09SDavid van Moolenbroek 	dns_name_t *name;
318*00b67f09SDavid van Moolenbroek 	dns_rdataset_t *rdataset = NULL;
319*00b67f09SDavid van Moolenbroek 	dns_rdata_t rdata = DNS_RDATA_INIT;
320*00b67f09SDavid van Moolenbroek 	char namebuf[DNS_NAME_FORMATSIZE];
321*00b67f09SDavid van Moolenbroek 
322*00b67f09SDavid van Moolenbroek 	UNUSED(query);
323*00b67f09SDavid van Moolenbroek 
324*00b67f09SDavid van Moolenbroek 	debug("detailsection()");
325*00b67f09SDavid van Moolenbroek 
326*00b67f09SDavid van Moolenbroek 	if (headers) {
327*00b67f09SDavid van Moolenbroek 		switch (section) {
328*00b67f09SDavid van Moolenbroek 		case DNS_SECTION_QUESTION:
329*00b67f09SDavid van Moolenbroek 			puts("    QUESTIONS:");
330*00b67f09SDavid van Moolenbroek 			break;
331*00b67f09SDavid van Moolenbroek 		case DNS_SECTION_ANSWER:
332*00b67f09SDavid van Moolenbroek 			puts("    ANSWERS:");
333*00b67f09SDavid van Moolenbroek 			break;
334*00b67f09SDavid van Moolenbroek 		case DNS_SECTION_AUTHORITY:
335*00b67f09SDavid van Moolenbroek 			puts("    AUTHORITY RECORDS:");
336*00b67f09SDavid van Moolenbroek 			break;
337*00b67f09SDavid van Moolenbroek 		case DNS_SECTION_ADDITIONAL:
338*00b67f09SDavid van Moolenbroek 			puts("    ADDITIONAL RECORDS:");
339*00b67f09SDavid van Moolenbroek 			break;
340*00b67f09SDavid van Moolenbroek 		}
341*00b67f09SDavid van Moolenbroek 	}
342*00b67f09SDavid van Moolenbroek 
343*00b67f09SDavid van Moolenbroek 	result = dns_message_firstname(msg, section);
344*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_NOMORE)
345*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
346*00b67f09SDavid van Moolenbroek 	else if (result != ISC_R_SUCCESS)
347*00b67f09SDavid van Moolenbroek 		return (result);
348*00b67f09SDavid van Moolenbroek 	for (;;) {
349*00b67f09SDavid van Moolenbroek 		name = NULL;
350*00b67f09SDavid van Moolenbroek 		dns_message_currentname(msg, section,
351*00b67f09SDavid van Moolenbroek 					&name);
352*00b67f09SDavid van Moolenbroek 		for (rdataset = ISC_LIST_HEAD(name->list);
353*00b67f09SDavid van Moolenbroek 		     rdataset != NULL;
354*00b67f09SDavid van Moolenbroek 		     rdataset = ISC_LIST_NEXT(rdataset, link)) {
355*00b67f09SDavid van Moolenbroek 			if (section == DNS_SECTION_QUESTION) {
356*00b67f09SDavid van Moolenbroek 				dns_name_format(name, namebuf,
357*00b67f09SDavid van Moolenbroek 						sizeof(namebuf));
358*00b67f09SDavid van Moolenbroek 				printf("\t%s, ", namebuf);
359*00b67f09SDavid van Moolenbroek 				dns_rdatatype_format(rdataset->type,
360*00b67f09SDavid van Moolenbroek 						     namebuf,
361*00b67f09SDavid van Moolenbroek 						     sizeof(namebuf));
362*00b67f09SDavid van Moolenbroek 				printf("type = %s, ", namebuf);
363*00b67f09SDavid van Moolenbroek 				dns_rdataclass_format(rdataset->rdclass,
364*00b67f09SDavid van Moolenbroek 						      namebuf,
365*00b67f09SDavid van Moolenbroek 						      sizeof(namebuf));
366*00b67f09SDavid van Moolenbroek 				printf("class = %s\n", namebuf);
367*00b67f09SDavid van Moolenbroek 			}
368*00b67f09SDavid van Moolenbroek 			loopresult = dns_rdataset_first(rdataset);
369*00b67f09SDavid van Moolenbroek 			while (loopresult == ISC_R_SUCCESS) {
370*00b67f09SDavid van Moolenbroek 				dns_rdataset_current(rdataset, &rdata);
371*00b67f09SDavid van Moolenbroek 
372*00b67f09SDavid van Moolenbroek 				dns_name_format(name, namebuf,
373*00b67f09SDavid van Moolenbroek 						sizeof(namebuf));
374*00b67f09SDavid van Moolenbroek 				printf("    ->  %s\n", namebuf);
375*00b67f09SDavid van Moolenbroek 
376*00b67f09SDavid van Moolenbroek 				switch (rdata.type) {
377*00b67f09SDavid van Moolenbroek 				case dns_rdatatype_soa:
378*00b67f09SDavid van Moolenbroek 					printsoa(&rdata);
379*00b67f09SDavid van Moolenbroek 					break;
380*00b67f09SDavid van Moolenbroek 				default:
381*00b67f09SDavid van Moolenbroek 					printf("\t");
382*00b67f09SDavid van Moolenbroek 					printrdata(&rdata);
383*00b67f09SDavid van Moolenbroek 				}
384*00b67f09SDavid van Moolenbroek 				dns_rdata_reset(&rdata);
385*00b67f09SDavid van Moolenbroek 				printf("\tttl = %u\n", rdataset->ttl);
386*00b67f09SDavid van Moolenbroek 				loopresult = dns_rdataset_next(rdataset);
387*00b67f09SDavid van Moolenbroek 			}
388*00b67f09SDavid van Moolenbroek 		}
389*00b67f09SDavid van Moolenbroek 		result = dns_message_nextname(msg, section);
390*00b67f09SDavid van Moolenbroek 		if (result == ISC_R_NOMORE)
391*00b67f09SDavid van Moolenbroek 			break;
392*00b67f09SDavid van Moolenbroek 		else if (result != ISC_R_SUCCESS) {
393*00b67f09SDavid van Moolenbroek 			return (result);
394*00b67f09SDavid van Moolenbroek 		}
395*00b67f09SDavid van Moolenbroek 	}
396*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
397*00b67f09SDavid van Moolenbroek }
398*00b67f09SDavid van Moolenbroek 
399*00b67f09SDavid van Moolenbroek void
received(int bytes,isc_sockaddr_t * from,dig_query_t * query)400*00b67f09SDavid van Moolenbroek received(int bytes, isc_sockaddr_t *from, dig_query_t *query)
401*00b67f09SDavid van Moolenbroek {
402*00b67f09SDavid van Moolenbroek 	UNUSED(bytes);
403*00b67f09SDavid van Moolenbroek 	UNUSED(from);
404*00b67f09SDavid van Moolenbroek 	UNUSED(query);
405*00b67f09SDavid van Moolenbroek }
406*00b67f09SDavid van Moolenbroek 
407*00b67f09SDavid van Moolenbroek void
trying(char * frm,dig_lookup_t * lookup)408*00b67f09SDavid van Moolenbroek trying(char *frm, dig_lookup_t *lookup) {
409*00b67f09SDavid van Moolenbroek 	UNUSED(frm);
410*00b67f09SDavid van Moolenbroek 	UNUSED(lookup);
411*00b67f09SDavid van Moolenbroek 
412*00b67f09SDavid van Moolenbroek }
413*00b67f09SDavid van Moolenbroek 
414*00b67f09SDavid van Moolenbroek isc_result_t
printmessage(dig_query_t * query,dns_message_t * msg,isc_boolean_t headers)415*00b67f09SDavid van Moolenbroek printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) {
416*00b67f09SDavid van Moolenbroek 	char servtext[ISC_SOCKADDR_FORMATSIZE];
417*00b67f09SDavid van Moolenbroek 
418*00b67f09SDavid van Moolenbroek 	/* I've we've gotten this far, we've reached a server. */
419*00b67f09SDavid van Moolenbroek 	query_error = 0;
420*00b67f09SDavid van Moolenbroek 
421*00b67f09SDavid van Moolenbroek 	debug("printmessage()");
422*00b67f09SDavid van Moolenbroek 
423*00b67f09SDavid van Moolenbroek 	isc_sockaddr_format(&query->sockaddr, servtext, sizeof(servtext));
424*00b67f09SDavid van Moolenbroek 	printf("Server:\t\t%s\n", query->userarg);
425*00b67f09SDavid van Moolenbroek 	printf("Address:\t%s\n", servtext);
426*00b67f09SDavid van Moolenbroek 
427*00b67f09SDavid van Moolenbroek 	puts("");
428*00b67f09SDavid van Moolenbroek 
429*00b67f09SDavid van Moolenbroek 	if (!short_form) {
430*00b67f09SDavid van Moolenbroek 		puts("------------");
431*00b67f09SDavid van Moolenbroek 		/*		detailheader(query, msg);*/
432*00b67f09SDavid van Moolenbroek 		detailsection(query, msg, ISC_TRUE, DNS_SECTION_QUESTION);
433*00b67f09SDavid van Moolenbroek 		detailsection(query, msg, ISC_TRUE, DNS_SECTION_ANSWER);
434*00b67f09SDavid van Moolenbroek 		detailsection(query, msg, ISC_TRUE, DNS_SECTION_AUTHORITY);
435*00b67f09SDavid van Moolenbroek 		detailsection(query, msg, ISC_TRUE, DNS_SECTION_ADDITIONAL);
436*00b67f09SDavid van Moolenbroek 		puts("------------");
437*00b67f09SDavid van Moolenbroek 	}
438*00b67f09SDavid van Moolenbroek 
439*00b67f09SDavid van Moolenbroek 	if (msg->rcode != 0) {
440*00b67f09SDavid van Moolenbroek 		char nametext[DNS_NAME_FORMATSIZE];
441*00b67f09SDavid van Moolenbroek 		dns_name_format(query->lookup->name,
442*00b67f09SDavid van Moolenbroek 				nametext, sizeof(nametext));
443*00b67f09SDavid van Moolenbroek 		printf("** server can't find %s: %s\n",
444*00b67f09SDavid van Moolenbroek 		       nametext, rcode_totext(msg->rcode));
445*00b67f09SDavid van Moolenbroek 		debug("returning with rcode == 0");
446*00b67f09SDavid van Moolenbroek 
447*00b67f09SDavid van Moolenbroek 		/* the lookup failed */
448*00b67f09SDavid van Moolenbroek 		print_error |= 1;
449*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
450*00b67f09SDavid van Moolenbroek 	}
451*00b67f09SDavid van Moolenbroek 
452*00b67f09SDavid van Moolenbroek 	if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0)
453*00b67f09SDavid van Moolenbroek 		puts("Non-authoritative answer:");
454*00b67f09SDavid van Moolenbroek 	if (!ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER]))
455*00b67f09SDavid van Moolenbroek 		printsection(query, msg, headers, DNS_SECTION_ANSWER);
456*00b67f09SDavid van Moolenbroek 	else
457*00b67f09SDavid van Moolenbroek 		printf("*** Can't find %s: No answer\n",
458*00b67f09SDavid van Moolenbroek 		       query->lookup->textname);
459*00b67f09SDavid van Moolenbroek 
460*00b67f09SDavid van Moolenbroek 	if (((msg->flags & DNS_MESSAGEFLAG_AA) == 0) &&
461*00b67f09SDavid van Moolenbroek 	    (query->lookup->rdtype != dns_rdatatype_a)) {
462*00b67f09SDavid van Moolenbroek 		puts("\nAuthoritative answers can be found from:");
463*00b67f09SDavid van Moolenbroek 		printsection(query, msg, headers,
464*00b67f09SDavid van Moolenbroek 			     DNS_SECTION_AUTHORITY);
465*00b67f09SDavid van Moolenbroek 		printsection(query, msg, headers,
466*00b67f09SDavid van Moolenbroek 			     DNS_SECTION_ADDITIONAL);
467*00b67f09SDavid van Moolenbroek 	}
468*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
469*00b67f09SDavid van Moolenbroek }
470*00b67f09SDavid van Moolenbroek 
471*00b67f09SDavid van Moolenbroek static void
show_settings(isc_boolean_t full,isc_boolean_t serv_only)472*00b67f09SDavid van Moolenbroek show_settings(isc_boolean_t full, isc_boolean_t serv_only) {
473*00b67f09SDavid van Moolenbroek 	dig_server_t *srv;
474*00b67f09SDavid van Moolenbroek 	isc_sockaddr_t sockaddr;
475*00b67f09SDavid van Moolenbroek 	dig_searchlist_t *listent;
476*00b67f09SDavid van Moolenbroek 	isc_result_t result;
477*00b67f09SDavid van Moolenbroek 
478*00b67f09SDavid van Moolenbroek 	srv = ISC_LIST_HEAD(server_list);
479*00b67f09SDavid van Moolenbroek 
480*00b67f09SDavid van Moolenbroek 	while (srv != NULL) {
481*00b67f09SDavid van Moolenbroek 		char sockstr[ISC_SOCKADDR_FORMATSIZE];
482*00b67f09SDavid van Moolenbroek 
483*00b67f09SDavid van Moolenbroek 		result = get_address(srv->servername, port, &sockaddr);
484*00b67f09SDavid van Moolenbroek 		check_result(result, "get_address");
485*00b67f09SDavid van Moolenbroek 
486*00b67f09SDavid van Moolenbroek 		isc_sockaddr_format(&sockaddr, sockstr, sizeof(sockstr));
487*00b67f09SDavid van Moolenbroek 		printf("Default server: %s\nAddress: %s\n",
488*00b67f09SDavid van Moolenbroek 			srv->userarg, sockstr);
489*00b67f09SDavid van Moolenbroek 		if (!full)
490*00b67f09SDavid van Moolenbroek 			return;
491*00b67f09SDavid van Moolenbroek 		srv = ISC_LIST_NEXT(srv, link);
492*00b67f09SDavid van Moolenbroek 	}
493*00b67f09SDavid van Moolenbroek 	if (serv_only)
494*00b67f09SDavid van Moolenbroek 		return;
495*00b67f09SDavid van Moolenbroek 	printf("\nSet options:\n");
496*00b67f09SDavid van Moolenbroek 	printf("  %s\t\t\t%s\t\t%s\n",
497*00b67f09SDavid van Moolenbroek 	       tcpmode ? "vc" : "novc",
498*00b67f09SDavid van Moolenbroek 	       short_form ? "nodebug" : "debug",
499*00b67f09SDavid van Moolenbroek 	       debugging ? "d2" : "nod2");
500*00b67f09SDavid van Moolenbroek 	printf("  %s\t\t%s\n",
501*00b67f09SDavid van Moolenbroek 	       usesearch ? "search" : "nosearch",
502*00b67f09SDavid van Moolenbroek 	       recurse ? "recurse" : "norecurse");
503*00b67f09SDavid van Moolenbroek 	printf("  timeout = %d\t\tretry = %d\tport = %d\tndots = %d\n",
504*00b67f09SDavid van Moolenbroek 	       timeout, tries, port, ndots);
505*00b67f09SDavid van Moolenbroek 	printf("  querytype = %-8s\tclass = %s\n", deftype, defclass);
506*00b67f09SDavid van Moolenbroek 	printf("  srchlist = ");
507*00b67f09SDavid van Moolenbroek 	for (listent = ISC_LIST_HEAD(search_list);
508*00b67f09SDavid van Moolenbroek 	     listent != NULL;
509*00b67f09SDavid van Moolenbroek 	     listent = ISC_LIST_NEXT(listent, link)) {
510*00b67f09SDavid van Moolenbroek 		     printf("%s", listent->origin);
511*00b67f09SDavid van Moolenbroek 		     if (ISC_LIST_NEXT(listent, link) != NULL)
512*00b67f09SDavid van Moolenbroek 			     printf("/");
513*00b67f09SDavid van Moolenbroek 	}
514*00b67f09SDavid van Moolenbroek 	printf("\n");
515*00b67f09SDavid van Moolenbroek }
516*00b67f09SDavid van Moolenbroek 
517*00b67f09SDavid van Moolenbroek static isc_boolean_t
testtype(char * typetext)518*00b67f09SDavid van Moolenbroek testtype(char *typetext) {
519*00b67f09SDavid van Moolenbroek 	isc_result_t result;
520*00b67f09SDavid van Moolenbroek 	isc_textregion_t tr;
521*00b67f09SDavid van Moolenbroek 	dns_rdatatype_t rdtype;
522*00b67f09SDavid van Moolenbroek 
523*00b67f09SDavid van Moolenbroek 	tr.base = typetext;
524*00b67f09SDavid van Moolenbroek 	tr.length = strlen(typetext);
525*00b67f09SDavid van Moolenbroek 	result = dns_rdatatype_fromtext(&rdtype, &tr);
526*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS)
527*00b67f09SDavid van Moolenbroek 		return (ISC_TRUE);
528*00b67f09SDavid van Moolenbroek 	else {
529*00b67f09SDavid van Moolenbroek 		printf("unknown query type: %s\n", typetext);
530*00b67f09SDavid van Moolenbroek 		return (ISC_FALSE);
531*00b67f09SDavid van Moolenbroek 	}
532*00b67f09SDavid van Moolenbroek }
533*00b67f09SDavid van Moolenbroek 
534*00b67f09SDavid van Moolenbroek static isc_boolean_t
testclass(char * typetext)535*00b67f09SDavid van Moolenbroek testclass(char *typetext) {
536*00b67f09SDavid van Moolenbroek 	isc_result_t result;
537*00b67f09SDavid van Moolenbroek 	isc_textregion_t tr;
538*00b67f09SDavid van Moolenbroek 	dns_rdataclass_t rdclass;
539*00b67f09SDavid van Moolenbroek 
540*00b67f09SDavid van Moolenbroek 	tr.base = typetext;
541*00b67f09SDavid van Moolenbroek 	tr.length = strlen(typetext);
542*00b67f09SDavid van Moolenbroek 	result = dns_rdataclass_fromtext(&rdclass, &tr);
543*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS)
544*00b67f09SDavid van Moolenbroek 		return (ISC_TRUE);
545*00b67f09SDavid van Moolenbroek 	else {
546*00b67f09SDavid van Moolenbroek 		printf("unknown query class: %s\n", typetext);
547*00b67f09SDavid van Moolenbroek 		return (ISC_FALSE);
548*00b67f09SDavid van Moolenbroek 	}
549*00b67f09SDavid van Moolenbroek }
550*00b67f09SDavid van Moolenbroek 
551*00b67f09SDavid van Moolenbroek static void
set_port(const char * value)552*00b67f09SDavid van Moolenbroek set_port(const char *value) {
553*00b67f09SDavid van Moolenbroek 	isc_uint32_t n;
554*00b67f09SDavid van Moolenbroek 	isc_result_t result = parse_uint(&n, value, 65535, "port");
555*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS)
556*00b67f09SDavid van Moolenbroek 		port = (isc_uint16_t) n;
557*00b67f09SDavid van Moolenbroek }
558*00b67f09SDavid van Moolenbroek 
559*00b67f09SDavid van Moolenbroek static void
set_timeout(const char * value)560*00b67f09SDavid van Moolenbroek set_timeout(const char *value) {
561*00b67f09SDavid van Moolenbroek 	isc_uint32_t n;
562*00b67f09SDavid van Moolenbroek 	isc_result_t result = parse_uint(&n, value, UINT_MAX, "timeout");
563*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS)
564*00b67f09SDavid van Moolenbroek 		timeout = n;
565*00b67f09SDavid van Moolenbroek }
566*00b67f09SDavid van Moolenbroek 
567*00b67f09SDavid van Moolenbroek static void
set_tries(const char * value)568*00b67f09SDavid van Moolenbroek set_tries(const char *value) {
569*00b67f09SDavid van Moolenbroek 	isc_uint32_t n;
570*00b67f09SDavid van Moolenbroek 	isc_result_t result = parse_uint(&n, value, INT_MAX, "tries");
571*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS)
572*00b67f09SDavid van Moolenbroek 		tries = n;
573*00b67f09SDavid van Moolenbroek }
574*00b67f09SDavid van Moolenbroek 
575*00b67f09SDavid van Moolenbroek static void
set_ndots(const char * value)576*00b67f09SDavid van Moolenbroek set_ndots(const char *value) {
577*00b67f09SDavid van Moolenbroek 	isc_uint32_t n;
578*00b67f09SDavid van Moolenbroek 	isc_result_t result = parse_uint(&n, value, 128, "ndots");
579*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS)
580*00b67f09SDavid van Moolenbroek 		ndots = n;
581*00b67f09SDavid van Moolenbroek }
582*00b67f09SDavid van Moolenbroek 
583*00b67f09SDavid van Moolenbroek static void
version(void)584*00b67f09SDavid van Moolenbroek version(void) {
585*00b67f09SDavid van Moolenbroek 	fputs("nslookup " VERSION "\n", stderr);
586*00b67f09SDavid van Moolenbroek }
587*00b67f09SDavid van Moolenbroek 
588*00b67f09SDavid van Moolenbroek static void
setoption(char * opt)589*00b67f09SDavid van Moolenbroek setoption(char *opt) {
590*00b67f09SDavid van Moolenbroek 	if (strncasecmp(opt, "all", 4) == 0) {
591*00b67f09SDavid van Moolenbroek 		show_settings(ISC_TRUE, ISC_FALSE);
592*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "class=", 6) == 0) {
593*00b67f09SDavid van Moolenbroek 		if (testclass(&opt[6]))
594*00b67f09SDavid van Moolenbroek 			strlcpy(defclass, &opt[6], sizeof(defclass));
595*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "cl=", 3) == 0) {
596*00b67f09SDavid van Moolenbroek 		if (testclass(&opt[3]))
597*00b67f09SDavid van Moolenbroek 			strlcpy(defclass, &opt[3], sizeof(defclass));
598*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "type=", 5) == 0) {
599*00b67f09SDavid van Moolenbroek 		if (testtype(&opt[5]))
600*00b67f09SDavid van Moolenbroek 			strlcpy(deftype, &opt[5], sizeof(deftype));
601*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "ty=", 3) == 0) {
602*00b67f09SDavid van Moolenbroek 		if (testtype(&opt[3]))
603*00b67f09SDavid van Moolenbroek 			strlcpy(deftype, &opt[3], sizeof(deftype));
604*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "querytype=", 10) == 0) {
605*00b67f09SDavid van Moolenbroek 		if (testtype(&opt[10]))
606*00b67f09SDavid van Moolenbroek 			strlcpy(deftype, &opt[10], sizeof(deftype));
607*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "query=", 6) == 0) {
608*00b67f09SDavid van Moolenbroek 		if (testtype(&opt[6]))
609*00b67f09SDavid van Moolenbroek 			strlcpy(deftype, &opt[6], sizeof(deftype));
610*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "qu=", 3) == 0) {
611*00b67f09SDavid van Moolenbroek 		if (testtype(&opt[3]))
612*00b67f09SDavid van Moolenbroek 			strlcpy(deftype, &opt[3], sizeof(deftype));
613*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "q=", 2) == 0) {
614*00b67f09SDavid van Moolenbroek 		if (testtype(&opt[2]))
615*00b67f09SDavid van Moolenbroek 			strlcpy(deftype, &opt[2], sizeof(deftype));
616*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "domain=", 7) == 0) {
617*00b67f09SDavid van Moolenbroek 		strlcpy(domainopt, &opt[7], sizeof(domainopt));
618*00b67f09SDavid van Moolenbroek 		set_search_domain(domainopt);
619*00b67f09SDavid van Moolenbroek 		usesearch = ISC_TRUE;
620*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "do=", 3) == 0) {
621*00b67f09SDavid van Moolenbroek 		strlcpy(domainopt, &opt[3], sizeof(domainopt));
622*00b67f09SDavid van Moolenbroek 		set_search_domain(domainopt);
623*00b67f09SDavid van Moolenbroek 		usesearch = ISC_TRUE;
624*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "port=", 5) == 0) {
625*00b67f09SDavid van Moolenbroek 		set_port(&opt[5]);
626*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "po=", 3) == 0) {
627*00b67f09SDavid van Moolenbroek 		set_port(&opt[3]);
628*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "timeout=", 8) == 0) {
629*00b67f09SDavid van Moolenbroek 		set_timeout(&opt[8]);
630*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "t=", 2) == 0) {
631*00b67f09SDavid van Moolenbroek 		set_timeout(&opt[2]);
632*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "rec", 3) == 0) {
633*00b67f09SDavid van Moolenbroek 		recurse = ISC_TRUE;
634*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "norec", 5) == 0) {
635*00b67f09SDavid van Moolenbroek 		recurse = ISC_FALSE;
636*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "retry=", 6) == 0) {
637*00b67f09SDavid van Moolenbroek 		set_tries(&opt[6]);
638*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "ret=", 4) == 0) {
639*00b67f09SDavid van Moolenbroek 		set_tries(&opt[4]);
640*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "def", 3) == 0) {
641*00b67f09SDavid van Moolenbroek 		usesearch = ISC_TRUE;
642*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "nodef", 5) == 0) {
643*00b67f09SDavid van Moolenbroek 		usesearch = ISC_FALSE;
644*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "vc", 3) == 0) {
645*00b67f09SDavid van Moolenbroek 		tcpmode = ISC_TRUE;
646*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "novc", 5) == 0) {
647*00b67f09SDavid van Moolenbroek 		tcpmode = ISC_FALSE;
648*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "deb", 3) == 0) {
649*00b67f09SDavid van Moolenbroek 		short_form = ISC_FALSE;
650*00b67f09SDavid van Moolenbroek 		showsearch = ISC_TRUE;
651*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "nodeb", 5) == 0) {
652*00b67f09SDavid van Moolenbroek 		short_form = ISC_TRUE;
653*00b67f09SDavid van Moolenbroek 		showsearch = ISC_FALSE;
654*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "d2", 2) == 0) {
655*00b67f09SDavid van Moolenbroek 		debugging = ISC_TRUE;
656*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "nod2", 4) == 0) {
657*00b67f09SDavid van Moolenbroek 		debugging = ISC_FALSE;
658*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "search", 3) == 0) {
659*00b67f09SDavid van Moolenbroek 		usesearch = ISC_TRUE;
660*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "nosearch", 5) == 0) {
661*00b67f09SDavid van Moolenbroek 		usesearch = ISC_FALSE;
662*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "sil", 3) == 0) {
663*00b67f09SDavid van Moolenbroek 		/* deprecation_msg = ISC_FALSE; */
664*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "fail", 3) == 0) {
665*00b67f09SDavid van Moolenbroek 		nofail=ISC_FALSE;
666*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "nofail", 3) == 0) {
667*00b67f09SDavid van Moolenbroek 		nofail=ISC_TRUE;
668*00b67f09SDavid van Moolenbroek 	} else if (strncasecmp(opt, "ndots=", 6) == 0) {
669*00b67f09SDavid van Moolenbroek 		set_ndots(&opt[6]);
670*00b67f09SDavid van Moolenbroek 	} else {
671*00b67f09SDavid van Moolenbroek 		printf("*** Invalid option: %s\n", opt);
672*00b67f09SDavid van Moolenbroek 	}
673*00b67f09SDavid van Moolenbroek }
674*00b67f09SDavid van Moolenbroek 
675*00b67f09SDavid van Moolenbroek static void
addlookup(char * opt)676*00b67f09SDavid van Moolenbroek addlookup(char *opt) {
677*00b67f09SDavid van Moolenbroek 	dig_lookup_t *lookup;
678*00b67f09SDavid van Moolenbroek 	isc_result_t result;
679*00b67f09SDavid van Moolenbroek 	isc_textregion_t tr;
680*00b67f09SDavid van Moolenbroek 	dns_rdatatype_t rdtype;
681*00b67f09SDavid van Moolenbroek 	dns_rdataclass_t rdclass;
682*00b67f09SDavid van Moolenbroek 	char store[MXNAME];
683*00b67f09SDavid van Moolenbroek 
684*00b67f09SDavid van Moolenbroek 	debug("addlookup()");
685*00b67f09SDavid van Moolenbroek 	tr.base = deftype;
686*00b67f09SDavid van Moolenbroek 	tr.length = strlen(deftype);
687*00b67f09SDavid van Moolenbroek 	result = dns_rdatatype_fromtext(&rdtype, &tr);
688*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) {
689*00b67f09SDavid van Moolenbroek 		printf("unknown query type: %s\n", deftype);
690*00b67f09SDavid van Moolenbroek 		rdclass = dns_rdatatype_a;
691*00b67f09SDavid van Moolenbroek 	}
692*00b67f09SDavid van Moolenbroek 	tr.base = defclass;
693*00b67f09SDavid van Moolenbroek 	tr.length = strlen(defclass);
694*00b67f09SDavid van Moolenbroek 	result = dns_rdataclass_fromtext(&rdclass, &tr);
695*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) {
696*00b67f09SDavid van Moolenbroek 		printf("unknown query class: %s\n", defclass);
697*00b67f09SDavid van Moolenbroek 		rdclass = dns_rdataclass_in;
698*00b67f09SDavid van Moolenbroek 	}
699*00b67f09SDavid van Moolenbroek 	lookup = make_empty_lookup();
700*00b67f09SDavid van Moolenbroek 	if (get_reverse(store, sizeof(store), opt, lookup->ip6_int, ISC_TRUE)
701*00b67f09SDavid van Moolenbroek 	    == ISC_R_SUCCESS) {
702*00b67f09SDavid van Moolenbroek 		strlcpy(lookup->textname, store, sizeof(lookup->textname));
703*00b67f09SDavid van Moolenbroek 		lookup->rdtype = dns_rdatatype_ptr;
704*00b67f09SDavid van Moolenbroek 		lookup->rdtypeset = ISC_TRUE;
705*00b67f09SDavid van Moolenbroek 	} else {
706*00b67f09SDavid van Moolenbroek 		strlcpy(lookup->textname, opt, sizeof(lookup->textname));
707*00b67f09SDavid van Moolenbroek 		lookup->rdtype = rdtype;
708*00b67f09SDavid van Moolenbroek 		lookup->rdtypeset = ISC_TRUE;
709*00b67f09SDavid van Moolenbroek 	}
710*00b67f09SDavid van Moolenbroek 	lookup->rdclass = rdclass;
711*00b67f09SDavid van Moolenbroek 	lookup->rdclassset = ISC_TRUE;
712*00b67f09SDavid van Moolenbroek 	lookup->trace = ISC_FALSE;
713*00b67f09SDavid van Moolenbroek 	lookup->trace_root = lookup->trace;
714*00b67f09SDavid van Moolenbroek 	lookup->ns_search_only = ISC_FALSE;
715*00b67f09SDavid van Moolenbroek 	lookup->identify = identify;
716*00b67f09SDavid van Moolenbroek 	lookup->recurse = recurse;
717*00b67f09SDavid van Moolenbroek 	lookup->aaonly = aaonly;
718*00b67f09SDavid van Moolenbroek 	lookup->retries = tries;
719*00b67f09SDavid van Moolenbroek 	lookup->udpsize = 0;
720*00b67f09SDavid van Moolenbroek 	lookup->comments = comments;
721*00b67f09SDavid van Moolenbroek 	lookup->tcp_mode = tcpmode;
722*00b67f09SDavid van Moolenbroek 	lookup->stats = stats;
723*00b67f09SDavid van Moolenbroek 	lookup->section_question = section_question;
724*00b67f09SDavid van Moolenbroek 	lookup->section_answer = section_answer;
725*00b67f09SDavid van Moolenbroek 	lookup->section_authority = section_authority;
726*00b67f09SDavid van Moolenbroek 	lookup->section_additional = section_additional;
727*00b67f09SDavid van Moolenbroek 	lookup->new_search = ISC_TRUE;
728*00b67f09SDavid van Moolenbroek 	if (nofail)
729*00b67f09SDavid van Moolenbroek 		lookup->servfail_stops = ISC_FALSE;
730*00b67f09SDavid van Moolenbroek 	ISC_LIST_INIT(lookup->q);
731*00b67f09SDavid van Moolenbroek 	ISC_LINK_INIT(lookup, link);
732*00b67f09SDavid van Moolenbroek 	ISC_LIST_APPEND(lookup_list, lookup, link);
733*00b67f09SDavid van Moolenbroek 	lookup->origin = NULL;
734*00b67f09SDavid van Moolenbroek 	ISC_LIST_INIT(lookup->my_server_list);
735*00b67f09SDavid van Moolenbroek 	debug("looking up %s", lookup->textname);
736*00b67f09SDavid van Moolenbroek }
737*00b67f09SDavid van Moolenbroek 
738*00b67f09SDavid van Moolenbroek static void
do_next_command(char * input)739*00b67f09SDavid van Moolenbroek do_next_command(char *input) {
740*00b67f09SDavid van Moolenbroek 	char *ptr, *arg;
741*00b67f09SDavid van Moolenbroek 
742*00b67f09SDavid van Moolenbroek 	ptr = next_token(&input, " \t\r\n");
743*00b67f09SDavid van Moolenbroek 	if (ptr == NULL)
744*00b67f09SDavid van Moolenbroek 		return;
745*00b67f09SDavid van Moolenbroek 	arg = next_token(&input, " \t\r\n");
746*00b67f09SDavid van Moolenbroek 	if ((strcasecmp(ptr, "set") == 0) &&
747*00b67f09SDavid van Moolenbroek 	    (arg != NULL))
748*00b67f09SDavid van Moolenbroek 		setoption(arg);
749*00b67f09SDavid van Moolenbroek 	else if ((strcasecmp(ptr, "server") == 0) ||
750*00b67f09SDavid van Moolenbroek 		 (strcasecmp(ptr, "lserver") == 0)) {
751*00b67f09SDavid van Moolenbroek 		isc_app_block();
752*00b67f09SDavid van Moolenbroek 		set_nameserver(arg);
753*00b67f09SDavid van Moolenbroek 		check_ra = ISC_FALSE;
754*00b67f09SDavid van Moolenbroek 		isc_app_unblock();
755*00b67f09SDavid van Moolenbroek 		show_settings(ISC_TRUE, ISC_TRUE);
756*00b67f09SDavid van Moolenbroek 	} else if (strcasecmp(ptr, "exit") == 0) {
757*00b67f09SDavid van Moolenbroek 		in_use = ISC_FALSE;
758*00b67f09SDavid van Moolenbroek 	} else if (strcasecmp(ptr, "help") == 0 ||
759*00b67f09SDavid van Moolenbroek 		   strcasecmp(ptr, "?") == 0) {
760*00b67f09SDavid van Moolenbroek 		printf("The '%s' command is not yet implemented.\n", ptr);
761*00b67f09SDavid van Moolenbroek 	} else if (strcasecmp(ptr, "finger") == 0 ||
762*00b67f09SDavid van Moolenbroek 		   strcasecmp(ptr, "root") == 0 ||
763*00b67f09SDavid van Moolenbroek 		   strcasecmp(ptr, "ls") == 0 ||
764*00b67f09SDavid van Moolenbroek 		   strcasecmp(ptr, "view") == 0) {
765*00b67f09SDavid van Moolenbroek 		printf("The '%s' command is not implemented.\n", ptr);
766*00b67f09SDavid van Moolenbroek 	} else
767*00b67f09SDavid van Moolenbroek 		addlookup(ptr);
768*00b67f09SDavid van Moolenbroek }
769*00b67f09SDavid van Moolenbroek 
770*00b67f09SDavid van Moolenbroek static void
get_next_command(void)771*00b67f09SDavid van Moolenbroek get_next_command(void) {
772*00b67f09SDavid van Moolenbroek 	char *buf;
773*00b67f09SDavid van Moolenbroek 	char *ptr;
774*00b67f09SDavid van Moolenbroek 
775*00b67f09SDavid van Moolenbroek 	fflush(stdout);
776*00b67f09SDavid van Moolenbroek 	buf = isc_mem_allocate(mctx, COMMSIZE);
777*00b67f09SDavid van Moolenbroek 	if (buf == NULL)
778*00b67f09SDavid van Moolenbroek 		fatal("memory allocation failure");
779*00b67f09SDavid van Moolenbroek 	isc_app_block();
780*00b67f09SDavid van Moolenbroek 	if (interactive) {
781*00b67f09SDavid van Moolenbroek #ifdef HAVE_READLINE
782*00b67f09SDavid van Moolenbroek 		ptr = readline("> ");
783*00b67f09SDavid van Moolenbroek 		if (ptr != NULL)
784*00b67f09SDavid van Moolenbroek 			add_history(ptr);
785*00b67f09SDavid van Moolenbroek #else
786*00b67f09SDavid van Moolenbroek 		fputs("> ", stderr);
787*00b67f09SDavid van Moolenbroek 		fflush(stderr);
788*00b67f09SDavid van Moolenbroek 		ptr = fgets(buf, COMMSIZE, stdin);
789*00b67f09SDavid van Moolenbroek #endif
790*00b67f09SDavid van Moolenbroek 	} else
791*00b67f09SDavid van Moolenbroek 		ptr = fgets(buf, COMMSIZE, stdin);
792*00b67f09SDavid van Moolenbroek 	isc_app_unblock();
793*00b67f09SDavid van Moolenbroek 	if (ptr == NULL) {
794*00b67f09SDavid van Moolenbroek 		in_use = ISC_FALSE;
795*00b67f09SDavid van Moolenbroek 	} else
796*00b67f09SDavid van Moolenbroek 		do_next_command(ptr);
797*00b67f09SDavid van Moolenbroek #ifdef HAVE_READLINE
798*00b67f09SDavid van Moolenbroek 	if (interactive)
799*00b67f09SDavid van Moolenbroek 		free(ptr);
800*00b67f09SDavid van Moolenbroek #endif
801*00b67f09SDavid van Moolenbroek 	isc_mem_free(mctx, buf);
802*00b67f09SDavid van Moolenbroek }
803*00b67f09SDavid van Moolenbroek 
804*00b67f09SDavid van Moolenbroek static void
parse_args(int argc,char ** argv)805*00b67f09SDavid van Moolenbroek parse_args(int argc, char **argv) {
806*00b67f09SDavid van Moolenbroek 	isc_boolean_t have_lookup = ISC_FALSE;
807*00b67f09SDavid van Moolenbroek 
808*00b67f09SDavid van Moolenbroek 	usesearch = ISC_TRUE;
809*00b67f09SDavid van Moolenbroek 	for (argc--, argv++; argc > 0; argc--, argv++) {
810*00b67f09SDavid van Moolenbroek 		debug("main parsing %s", argv[0]);
811*00b67f09SDavid van Moolenbroek 		if (argv[0][0] == '-') {
812*00b67f09SDavid van Moolenbroek 			if (strncasecmp(argv[0], "-ver", 4) == 0) {
813*00b67f09SDavid van Moolenbroek 				version();
814*00b67f09SDavid van Moolenbroek 				exit(0);
815*00b67f09SDavid van Moolenbroek 			} else if (argv[0][1] != 0) {
816*00b67f09SDavid van Moolenbroek 				setoption(&argv[0][1]);
817*00b67f09SDavid van Moolenbroek 			} else
818*00b67f09SDavid van Moolenbroek 				have_lookup = ISC_TRUE;
819*00b67f09SDavid van Moolenbroek 		} else {
820*00b67f09SDavid van Moolenbroek 			if (!have_lookup) {
821*00b67f09SDavid van Moolenbroek 				have_lookup = ISC_TRUE;
822*00b67f09SDavid van Moolenbroek 				in_use = ISC_TRUE;
823*00b67f09SDavid van Moolenbroek 				addlookup(argv[0]);
824*00b67f09SDavid van Moolenbroek 			} else {
825*00b67f09SDavid van Moolenbroek 				set_nameserver(argv[0]);
826*00b67f09SDavid van Moolenbroek 				check_ra = ISC_FALSE;
827*00b67f09SDavid van Moolenbroek 			}
828*00b67f09SDavid van Moolenbroek 		}
829*00b67f09SDavid van Moolenbroek 	}
830*00b67f09SDavid van Moolenbroek }
831*00b67f09SDavid van Moolenbroek 
832*00b67f09SDavid van Moolenbroek static void
flush_lookup_list(void)833*00b67f09SDavid van Moolenbroek flush_lookup_list(void) {
834*00b67f09SDavid van Moolenbroek 	dig_lookup_t *l, *lp;
835*00b67f09SDavid van Moolenbroek 	dig_query_t *q, *qp;
836*00b67f09SDavid van Moolenbroek 	dig_server_t *s, *sp;
837*00b67f09SDavid van Moolenbroek 
838*00b67f09SDavid van Moolenbroek 	lookup_counter = 0;
839*00b67f09SDavid van Moolenbroek 	l = ISC_LIST_HEAD(lookup_list);
840*00b67f09SDavid van Moolenbroek 	while (l != NULL) {
841*00b67f09SDavid van Moolenbroek 		q = ISC_LIST_HEAD(l->q);
842*00b67f09SDavid van Moolenbroek 		while (q != NULL) {
843*00b67f09SDavid van Moolenbroek 			if (q->sock != NULL) {
844*00b67f09SDavid van Moolenbroek 				isc_socket_cancel(q->sock, NULL,
845*00b67f09SDavid van Moolenbroek 						  ISC_SOCKCANCEL_ALL);
846*00b67f09SDavid van Moolenbroek 				isc_socket_detach(&q->sock);
847*00b67f09SDavid van Moolenbroek 			}
848*00b67f09SDavid van Moolenbroek 			if (ISC_LINK_LINKED(&q->recvbuf, link))
849*00b67f09SDavid van Moolenbroek 				ISC_LIST_DEQUEUE(q->recvlist, &q->recvbuf,
850*00b67f09SDavid van Moolenbroek 						 link);
851*00b67f09SDavid van Moolenbroek 			if (ISC_LINK_LINKED(&q->lengthbuf, link))
852*00b67f09SDavid van Moolenbroek 				ISC_LIST_DEQUEUE(q->lengthlist, &q->lengthbuf,
853*00b67f09SDavid van Moolenbroek 						 link);
854*00b67f09SDavid van Moolenbroek 			isc_buffer_invalidate(&q->recvbuf);
855*00b67f09SDavid van Moolenbroek 			isc_buffer_invalidate(&q->lengthbuf);
856*00b67f09SDavid van Moolenbroek 			qp = q;
857*00b67f09SDavid van Moolenbroek 			q = ISC_LIST_NEXT(q, link);
858*00b67f09SDavid van Moolenbroek 			ISC_LIST_DEQUEUE(l->q, qp, link);
859*00b67f09SDavid van Moolenbroek 			isc_mem_free(mctx, qp);
860*00b67f09SDavid van Moolenbroek 		}
861*00b67f09SDavid van Moolenbroek 		s = ISC_LIST_HEAD(l->my_server_list);
862*00b67f09SDavid van Moolenbroek 		while (s != NULL) {
863*00b67f09SDavid van Moolenbroek 			sp = s;
864*00b67f09SDavid van Moolenbroek 			s = ISC_LIST_NEXT(s, link);
865*00b67f09SDavid van Moolenbroek 			ISC_LIST_DEQUEUE(l->my_server_list, sp, link);
866*00b67f09SDavid van Moolenbroek 			isc_mem_free(mctx, sp);
867*00b67f09SDavid van Moolenbroek 
868*00b67f09SDavid van Moolenbroek 		}
869*00b67f09SDavid van Moolenbroek 		if (l->sendmsg != NULL)
870*00b67f09SDavid van Moolenbroek 			dns_message_destroy(&l->sendmsg);
871*00b67f09SDavid van Moolenbroek 		if (l->timer != NULL)
872*00b67f09SDavid van Moolenbroek 			isc_timer_detach(&l->timer);
873*00b67f09SDavid van Moolenbroek 		lp = l;
874*00b67f09SDavid van Moolenbroek 		l = ISC_LIST_NEXT(l, link);
875*00b67f09SDavid van Moolenbroek 		ISC_LIST_DEQUEUE(lookup_list, lp, link);
876*00b67f09SDavid van Moolenbroek 		isc_mem_free(mctx, lp);
877*00b67f09SDavid van Moolenbroek 	}
878*00b67f09SDavid van Moolenbroek }
879*00b67f09SDavid van Moolenbroek 
880*00b67f09SDavid van Moolenbroek static void
getinput(isc_task_t * task,isc_event_t * event)881*00b67f09SDavid van Moolenbroek getinput(isc_task_t *task, isc_event_t *event) {
882*00b67f09SDavid van Moolenbroek 	UNUSED(task);
883*00b67f09SDavid van Moolenbroek 	if (global_event == NULL)
884*00b67f09SDavid van Moolenbroek 		global_event = event;
885*00b67f09SDavid van Moolenbroek 	while (in_use) {
886*00b67f09SDavid van Moolenbroek 		get_next_command();
887*00b67f09SDavid van Moolenbroek 		if (ISC_LIST_HEAD(lookup_list) != NULL) {
888*00b67f09SDavid van Moolenbroek 			start_lookup();
889*00b67f09SDavid van Moolenbroek 			return;
890*00b67f09SDavid van Moolenbroek 		}
891*00b67f09SDavid van Moolenbroek 	}
892*00b67f09SDavid van Moolenbroek 	isc_app_shutdown();
893*00b67f09SDavid van Moolenbroek }
894*00b67f09SDavid van Moolenbroek 
895*00b67f09SDavid van Moolenbroek int
main(int argc,char ** argv)896*00b67f09SDavid van Moolenbroek main(int argc, char **argv) {
897*00b67f09SDavid van Moolenbroek 	isc_result_t result;
898*00b67f09SDavid van Moolenbroek 
899*00b67f09SDavid van Moolenbroek 	interactive = ISC_TF(isatty(0));
900*00b67f09SDavid van Moolenbroek 
901*00b67f09SDavid van Moolenbroek 	ISC_LIST_INIT(lookup_list);
902*00b67f09SDavid van Moolenbroek 	ISC_LIST_INIT(server_list);
903*00b67f09SDavid van Moolenbroek 	ISC_LIST_INIT(search_list);
904*00b67f09SDavid van Moolenbroek 
905*00b67f09SDavid van Moolenbroek 	check_ra = ISC_TRUE;
906*00b67f09SDavid van Moolenbroek 
907*00b67f09SDavid van Moolenbroek 	result = isc_app_start();
908*00b67f09SDavid van Moolenbroek 	check_result(result, "isc_app_start");
909*00b67f09SDavid van Moolenbroek 
910*00b67f09SDavid van Moolenbroek 	setup_libs();
911*00b67f09SDavid van Moolenbroek 	progname = argv[0];
912*00b67f09SDavid van Moolenbroek 
913*00b67f09SDavid van Moolenbroek 	parse_args(argc, argv);
914*00b67f09SDavid van Moolenbroek 
915*00b67f09SDavid van Moolenbroek 	setup_system();
916*00b67f09SDavid van Moolenbroek 	if (domainopt[0] != '\0')
917*00b67f09SDavid van Moolenbroek 		set_search_domain(domainopt);
918*00b67f09SDavid van Moolenbroek 	if (in_use)
919*00b67f09SDavid van Moolenbroek 		result = isc_app_onrun(mctx, global_task, onrun_callback,
920*00b67f09SDavid van Moolenbroek 				       NULL);
921*00b67f09SDavid van Moolenbroek 	else
922*00b67f09SDavid van Moolenbroek 		result = isc_app_onrun(mctx, global_task, getinput, NULL);
923*00b67f09SDavid van Moolenbroek 	check_result(result, "isc_app_onrun");
924*00b67f09SDavid van Moolenbroek 	in_use = ISC_TF(!in_use);
925*00b67f09SDavid van Moolenbroek 
926*00b67f09SDavid van Moolenbroek 	(void)isc_app_run();
927*00b67f09SDavid van Moolenbroek 
928*00b67f09SDavid van Moolenbroek 	puts("");
929*00b67f09SDavid van Moolenbroek 	debug("done, and starting to shut down");
930*00b67f09SDavid van Moolenbroek 	if (global_event != NULL)
931*00b67f09SDavid van Moolenbroek 		isc_event_free(&global_event);
932*00b67f09SDavid van Moolenbroek 	cancel_all();
933*00b67f09SDavid van Moolenbroek 	destroy_libs();
934*00b67f09SDavid van Moolenbroek 	isc_app_finish();
935*00b67f09SDavid van Moolenbroek 
936*00b67f09SDavid van Moolenbroek 	return (query_error | print_error);
937*00b67f09SDavid van Moolenbroek }
938