dig.c revision d20b7d6bea538bebaec7d319bd90ead44e761069
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews/*
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews * Copyright (C) 2000, 2001 Internet Software Consortium.
0add14467b53f33ace931f9a4790113cb8b5e45dTinderbox User *
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * Permission to use, copy, modify, and distribute this software for any
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * purpose with or without fee is hereby granted, provided that the above
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * copyright notice and this permission notice appear in all copies.
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews *
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews */
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews/* $Id: dig.c,v 1.157 2001/08/23 04:39:31 marka Exp $ */
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt#include <config.h>
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt#include <stdlib.h>
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt#include <time.h>
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews#include <ctype.h>
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews
95de316a5d99b09804eda3223d1a41623d7ed611Evan Hunt#include <isc/app.h>
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt#include <isc/netaddr.h>
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt#include <isc/print.h>
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt#include <isc/string.h>
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt#include <isc/util.h>
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt#include <isc/task.h>
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews#include <dns/byaddr.h>
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews#include <dns/fixedname.h>
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews#include <dns/masterdump.h>
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt#include <dns/message.h>
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt#include <dns/name.h>
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt#include <dns/rdata.h>
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt#include <dns/rdataset.h>
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt#include <dns/rdatatype.h>
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt#include <dns/rdataclass.h>
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt#include <dns/result.h>
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt#include <dig/dig.h>
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Huntextern ISC_LIST(dig_lookup_t) lookup_list;
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Huntextern dig_serverlist_t server_list;
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Huntextern ISC_LIST(dig_searchlist_t) search_list;
ab6fd5e89266a29efdafee3784d2cb06f8624b1bMark Andrews
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Hunt#define ADD_STRING(b, s) { \
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Hunt if (strlen(s) >= isc_buffer_availablelength(b)) \
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Hunt return (ISC_R_NOSPACE); \
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt else \
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Hunt isc_buffer_putstr(b, s); \
ab6fd5e89266a29efdafee3784d2cb06f8624b1bMark Andrews}
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Hunt
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Hunt
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Huntextern isc_boolean_t have_ipv4, have_ipv6, specified_source,
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Hunt usesearch, qr;
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Huntextern in_port_t port;
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Huntextern unsigned int timeout;
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Huntextern isc_mem_t *mctx;
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Huntextern dns_messageid_t id;
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Huntextern int sendcount;
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Huntextern int ndots;
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Huntextern int tries;
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Huntextern int lookup_counter;
89740699cd2191d9b84e67716c281b2dfeba5e56Evan Huntextern int exitcode;
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Huntextern isc_sockaddr_t bind_address;
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewsextern char keynametext[MXNAME];
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewsextern char keyfile[MXNAME];
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewsextern char keysecret[MXNAME];
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewsextern dns_tsigkey_t *key;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Huntextern isc_boolean_t validated;
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewsextern isc_taskmgr_t *taskmgr;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Huntextern isc_task_t *global_task;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Huntextern isc_boolean_t free_now;
6643b0dd91249ace16218ef667967c87b291992cMark Andrewsdig_lookup_t *default_lookup = NULL;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Huntextern isc_boolean_t debugging, memdebugging;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Huntstatic char *batchname = NULL;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Huntstatic FILE *batchfp = NULL;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Huntstatic char *argv0;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Huntstatic char domainopt[DNS_NAME_MAXTEXT];
6643b0dd91249ace16218ef667967c87b291992cMark Andrews
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Huntstatic isc_boolean_t short_form = ISC_FALSE, printcmd = ISC_TRUE,
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt nibble = ISC_FALSE, plusquest = ISC_FALSE, pluscomm = ISC_FALSE,
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt multiline = ISC_FALSE;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Huntstatic const char *opcodetext[] = {
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "QUERY",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "IQUERY",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "STATUS",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "RESERVED3",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "NOTIFY",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "UPDATE",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "RESERVED6",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "RESERVED7",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "RESERVED8",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "RESERVED9",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "RESERVED10",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "RESERVED11",
6643b0dd91249ace16218ef667967c87b291992cMark Andrews "RESERVED12",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "RESERVED13",
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt "RESERVED14",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "RESERVED15"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt};
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Huntstatic const char *rcodetext[] = {
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "NOERROR",
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews "FORMERR",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "SERVFAIL",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "NXDOMAIN",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "NOTIMPL",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "REFUSED",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "YXDOMAIN",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "YXRRSET",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "NXRRSET",
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews "NOTAUTH",
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews "NOTZONE",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "RESERVED11",
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews "RESERVED12",
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews "RESERVED13",
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews "RESERVED14",
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews "RESERVED15",
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews "BADVERS"
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews};
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Huntextern char *progname;
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewsstatic void
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewsprint_usage(FILE *fp) {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews fputs(
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews"Usage: dig [@global-server] [domain] [q-type] [q-class] {q-opt}\n"
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews" {global-d-opt} host [@local-server] {local-d-opt}\n"
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews" [ host [@local-server] {local-d-opt} [...]]\n", fp);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews}
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewsstatic void
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewsusage() {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews print_usage(stderr);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews fputs("\nUse \"dig -h\" (or \"dig -h | more\") "
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews "for complete list of options\n", stderr);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews exit(1);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews}
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewsstatic void
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewshelp(void) {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews print_usage(stdout);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews fputs(
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt"Where: domain are in the Domain Name System\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" q-class is one of (in,hs,ch,...) [default: in]\n"
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt" q-type is one of (a,any,mx,ns,soa,hinfo,axfr,txt,...) [default:a]\n"
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt" (Use ixfr=version for type ixfr)\n"
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt" q-opt is one of:\n"
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt" -x dot-notation (shortcut for in-addr lookups)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" -n (nibble form for reverse IPv6 lookups)\n"
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt" -f filename (batch mode)\n"
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt" -p port (specify port number)\n"
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt" -t type (specify query type)\n"
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt" -c class (specify query class)\n"
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews" -y name:key (specify named base64 tsig key)\n"
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews" d-opt is of the form +keyword[=value], where keyword is:\n"
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews" +[no]vc (TCP mode)\n"
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews" +[no]tcp (TCP mode, alternate syntax)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +time=### (Set query timeout) [5]\n"
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews" +tries=### (Set number of UDP attempts) [3]\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +domain=### (Set default domainname)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +bufsize=### (Set EDNS0 Max UDP packet size)\n"
6643b0dd91249ace16218ef667967c87b291992cMark Andrews" +[no]search (Set whether to use searchlist)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]defname (Ditto)\n"
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt" +[no]recursive (Recursive mode)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]ignore (Don't revert to TCP for TC responses.)"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt"\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]fail (Don't try next server on SERVFAIL)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]besteffort (Try to parse even illegal messages)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]aaonly (Set AA flag in query)\n"
6643b0dd91249ace16218ef667967c87b291992cMark Andrews" +[no]adflag (Set AD flag in query)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]cdflag (Set CD flag in query)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +ndots=### (Set NDOTS value)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]cmd (Control display of command line)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]comments (Control display of comment lines)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]question (Control display of question)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]answer (Control display of answer)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]authority (Control display of authority)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]additional (Control display of additional)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]short (Disable everything except short\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" form of answer)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]all (Set or clear all display flags)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +qr (Print question before sending)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]nssearch (Search all authoritative nameservers)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]identify (ID responders in short answers)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]trace (Trace delegation down from root)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]dnssec (Request DNSSEC records)\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" +[no]multiline (Print records in an expanded format)\n"
6643b0dd91249ace16218ef667967c87b291992cMark Andrews" global d-opts and servers (before host name) affect all queries.\n"
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt" local d-opts and servers (after host name) affect only that lookup.\n",
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt stdout);
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt}
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt/*
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt * Callback from dighost.c to print the received message.
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt */
6643b0dd91249ace16218ef667967c87b291992cMark Andrewsvoid
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Huntreceived(int bytes, isc_sockaddr_t *from, dig_query_t *query) {
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt isc_uint64_t diff;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt isc_time_t now;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt isc_result_t result;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt time_t tnow;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt char fromtext[ISC_SOCKADDR_FORMATSIZE];
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews isc_sockaddr_format(from, fromtext, sizeof(fromtext));
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews result = isc_time_now(&now);
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt check_result(result, "isc_time_now");
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews if (query->lookup->stats && !short_form) {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews diff = isc_time_microdiff(&now, &query->time_sent);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews printf(";; Query time: %ld msec\n", (long int)diff/1000);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews printf(";; SERVER: %s(%s)\n", fromtext, query->servname);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews time(&tnow);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews printf(";; WHEN: %s", ctime(&tnow));
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt if (query->lookup->doing_xfr) {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews printf(";; XFR size: %d records\n",
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews query->rr_count);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews } else {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews printf(";; MSG SIZE rcvd: %d\n", bytes);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews }
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews if (key != NULL) {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews if (!validated)
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews puts(";; WARNING -- Some TSIG could not "
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews "be validated");
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews }
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews if ((key == NULL) && (keysecret[0] != 0)) {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews puts(";; WARNING -- TSIG key was not used.");
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews }
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews puts("");
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews } else if (query->lookup->identify && !short_form) {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews diff = isc_time_microdiff(&now, &query->time_sent);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews printf(";; Received %u bytes from %s(%s) in %d ms\n\n",
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews bytes, fromtext, query->servname,
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews (int)diff/1000);
60988462e5d6db53205851d056e3482a29239be9Evan Hunt }
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews}
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews/*
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews * Callback from dighost.c to print that it is trying a server.
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews * Not used in dig.
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews * XXX print_trying
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews */
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewsvoid
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewstrying(char *frm, dig_lookup_t *lookup) {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews UNUSED(frm);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews UNUSED(lookup);
60988462e5d6db53205851d056e3482a29239be9Evan Hunt}
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews/*
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews * Internal print routine used to print short form replies.
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews */
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Huntstatic isc_result_t
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Huntsay_message(dns_rdata_t *rdata, dig_query_t *query, isc_buffer_t *buf) {
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt isc_result_t result;
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt isc_uint64_t diff;
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt isc_time_t now;
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt char store[sizeof("12345678901234567890")];
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt if (query->lookup->trace || query->lookup->ns_search_only) {
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt result = dns_rdatatype_totext(rdata->type, buf);
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt if (result != ISC_R_SUCCESS)
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt return (result);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews ADD_STRING(buf, " ");
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews }
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews result = dns_rdata_totext(rdata, NULL, buf);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews check_result(result, "dns_rdata_totext");
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt if (query->lookup->identify) {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews result = isc_time_now(&now);
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt if (result != ISC_R_SUCCESS)
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt return (result);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews diff = isc_time_microdiff(&now, &query->time_sent);
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt ADD_STRING(buf, " from server ");
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt ADD_STRING(buf, query->servname);
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt snprintf(store, 19, " in %d ms.", (int)diff/1000);
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt ADD_STRING(buf, store);
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt }
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt ADD_STRING(buf, "\n");
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt return (ISC_R_SUCCESS);
6643b0dd91249ace16218ef667967c87b291992cMark Andrews}
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt/*
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt * short_form message print handler. Calls above say_message()
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt */
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Huntstatic isc_result_t
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Huntshort_answer(dns_message_t *msg, dns_messagetextflag_t flags,
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt isc_buffer_t *buf, dig_query_t *query)
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt{
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt dns_name_t *name;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt dns_rdataset_t *rdataset;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt isc_buffer_t target;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt isc_result_t result, loopresult;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt dns_name_t empty_name;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt char t[4096];
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt dns_rdata_t rdata = DNS_RDATA_INIT;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt UNUSED(flags);
6643b0dd91249ace16218ef667967c87b291992cMark Andrews
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt dns_name_init(&empty_name, NULL);
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt result = dns_message_firstname(msg, DNS_SECTION_ANSWER);
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt if (result == ISC_R_NOMORE)
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt return (ISC_R_SUCCESS);
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt else if (result != ISC_R_SUCCESS)
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt return (result);
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews for (;;) {
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt name = NULL;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt dns_message_currentname(msg, DNS_SECTION_ANSWER, &name);
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt isc_buffer_init(&target, t, sizeof(t));
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt for (rdataset = ISC_LIST_HEAD(name->list);
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt rdataset != NULL;
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews rdataset = ISC_LIST_NEXT(rdataset, link)) {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews loopresult = dns_rdataset_first(rdataset);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews while (loopresult == ISC_R_SUCCESS) {
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt dns_rdataset_current(rdataset, &rdata);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews result = say_message(&rdata, query,
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews buf);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews check_result(result, "say_message");
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews loopresult = dns_rdataset_next(rdataset);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews dns_rdata_reset(&rdata);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews }
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews }
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt result = dns_message_nextname(msg, DNS_SECTION_ANSWER);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews if (result == ISC_R_NOMORE)
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews break;
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews else if (result != ISC_R_SUCCESS)
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews return (result);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews }
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews return (ISC_R_SUCCESS);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews}
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews/*
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews * Callback from dighost.c to print the reply from a server
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews */
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewsisc_result_t
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewsprintmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews isc_result_t result;
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews dns_messagetextflag_t flags;
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews isc_buffer_t *buf = NULL;
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews unsigned int len = OUTPUTBUF;
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews const dns_master_style_t *style;
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews if (multiline)
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt style = &dns_master_style_default;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt else
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt style = &dns_master_style_debug;
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt if (query->lookup->cmdline[0] != 0) {
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt if (!short_form)
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt fputs(query->lookup->cmdline, stdout);
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt query->lookup->cmdline[0]=0;
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt }
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt debug("printmessage(%s %s %s)", headers ? "headers" : "noheaders",
66e50468dde42a9757ac489e738d8b2db8fd7f80Evan Hunt query->lookup->comments ? "comments" : "nocomments",
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews short_form ? "short_form" : "long_form");
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews flags = 0;
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews if (!headers) {
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt flags |= DNS_MESSAGETEXTFLAG_NOHEADERS;
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews flags |= DNS_MESSAGETEXTFLAG_NOCOMMENTS;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt }
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt if (!query->lookup->comments)
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt flags |= DNS_MESSAGETEXTFLAG_NOCOMMENTS;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews result = ISC_R_SUCCESS;
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt result = isc_buffer_allocate(mctx, &buf, len);
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt check_result(result, "isc_buffer_allocate");
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt if (query->lookup->comments && !short_form) {
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt if (query->lookup->cmdline[0] != 0)
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt printf("; %s\n", query->lookup->cmdline);
6643b0dd91249ace16218ef667967c87b291992cMark Andrews if (msg == query->lookup->sendmsg)
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt printf(";; Sending:\n");
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt else
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt printf(";; Got answer:\n");
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt if (headers) {
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt printf(";; ->>HEADER<<- opcode: %s, status: %s, "
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "id: %u\n",
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt opcodetext[msg->opcode], rcodetext[msg->rcode],
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt msg->id);
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt printf(";; flags:");
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0)
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt printf(" qr");
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0)
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt printf(" aa");
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0)
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt printf(" tc");
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0)
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt printf(" rd");
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0)
6643b0dd91249ace16218ef667967c87b291992cMark Andrews printf(" ra");
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0)
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt printf(" ad");
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0)
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt printf(" cd");
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt printf("; QUERY: %u, ANSWER: %u, "
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt "AUTHORITY: %u, ADDITIONAL: %u\n",
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews msg->counts[DNS_SECTION_QUESTION],
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt msg->counts[DNS_SECTION_ANSWER],
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt msg->counts[DNS_SECTION_AUTHORITY],
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt msg->counts[DNS_SECTION_ADDITIONAL]);
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt }
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt }
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Huntrepopulate_buffer:
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews if (query->lookup->comments && headers && !short_form)
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews {
56c9fcf07580457442b80ac32bdb7c07aa0df870Evan Hunt result = dns_message_pseudosectiontotext(msg,
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews DNS_PSEUDOSECTION_OPT,
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews style, flags, buf);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews if (result == ISC_R_NOSPACE) {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewsbuftoosmall:
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews len += OUTPUTBUF;
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews isc_buffer_free(&buf);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews result = isc_buffer_allocate(mctx, &buf, len);
68116c5a5fd36fef812fc207de3b7714db2994d5Evan Hunt if (result == ISC_R_SUCCESS)
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews goto repopulate_buffer;
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews else
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews return (result);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews }
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews check_result(result,
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews "dns_message_pseudosectiontotext");
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews }
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews if (query->lookup->section_question && headers) {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews if (!short_form) {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews result = dns_message_sectiontotext(msg,
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews DNS_SECTION_QUESTION,
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews style, flags, buf);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews if (result == ISC_R_NOSPACE)
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews goto buftoosmall;
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews check_result(result, "dns_message_sectiontotext");
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews }
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews }
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews if (query->lookup->section_answer) {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews if (!short_form) {
result = dns_message_sectiontotext(msg,
DNS_SECTION_ANSWER,
style, flags, buf);
if (result == ISC_R_NOSPACE)
goto buftoosmall;
check_result(result, "dns_message_sectiontotext");
} else {
result = short_answer(msg, flags, buf, query);
if (result == ISC_R_NOSPACE)
goto buftoosmall;
check_result(result, "short_answer");
}
}
if (query->lookup->section_authority) {
if (!short_form) {
result = dns_message_sectiontotext(msg,
DNS_SECTION_AUTHORITY,
style, flags, buf);
if (result == ISC_R_NOSPACE)
goto buftoosmall;
check_result(result, "dns_message_sectiontotext");
}
}
if (query->lookup->section_additional) {
if (!short_form) {
result = dns_message_sectiontotext(msg,
DNS_SECTION_ADDITIONAL,
style, flags, buf);
if (result == ISC_R_NOSPACE)
goto buftoosmall;
check_result(result, "dns_message_sectiontotext");
/*
* Only print the signature on the first record.
*/
if (headers) {
result = dns_message_pseudosectiontotext(
msg,
DNS_PSEUDOSECTION_TSIG,
style, flags, buf);
if (result == ISC_R_NOSPACE)
goto buftoosmall;
check_result(result,
"dns_message_pseudosectiontotext");
result = dns_message_pseudosectiontotext(
msg,
DNS_PSEUDOSECTION_SIG0,
style, flags, buf);
if (result == ISC_R_NOSPACE)
goto buftoosmall;
check_result(result,
"dns_message_pseudosectiontotext");
}
}
}
if (headers && query->lookup->comments && !short_form)
printf("\n");
printf("%.*s", (int)isc_buffer_usedlength(buf),
(char *)isc_buffer_base(buf));
isc_buffer_free(&buf);
return (result);
}
/*
* print the greeting message when the program first starts up.
*/
static void
printgreeting(int argc, char **argv, dig_lookup_t *lookup) {
int i;
int remaining;
static isc_boolean_t first = ISC_TRUE;
char append[MXNAME];
if (printcmd) {
lookup->cmdline[sizeof(lookup->cmdline) - 1] = 0;
snprintf(lookup->cmdline, sizeof(lookup->cmdline),
"%s; <<>> DiG " VERSION " <<>>",
first?"\n":"");
i = 1;
while (i < argc) {
snprintf(append, sizeof(append), " %s", argv[i++]);
remaining = sizeof(lookup->cmdline) -
strlen(lookup->cmdline) - 1;
strncat(lookup->cmdline, append, remaining);
}
remaining = sizeof(lookup->cmdline) -
strlen(lookup->cmdline) - 1;
strncat(lookup->cmdline, "\n", remaining);
if (first) {
snprintf(append, sizeof (append),
";; global options: %s %s\n",
short_form ? "short_form" : "",
printcmd ? "printcmd" : "");
first = ISC_FALSE;
remaining = sizeof(lookup->cmdline) -
strlen(lookup->cmdline) - 1;
strncat(lookup->cmdline, append, remaining);
}
}
}
/*
* Reorder an argument list so that server names all come at the end.
* This is a bit of a hack, to allow batch-mode processing to properly
* handle the server options.
*/
static void
reorder_args(int argc, char *argv[]) {
int i, j;
char *ptr;
int end;
debug("reorder_args()");
end = argc - 1;
while (argv[end][0] == '@') {
end--;
if (end == 0)
return;
}
debug("arg[end]=%s", argv[end]);
for (i = 1; i < end - 1; i++) {
if (argv[i][0] == '@') {
debug("arg[%d]=%s", i, argv[i]);
ptr = argv[i];
for (j = i + 1; j < end; j++) {
debug("Moving %s to %d", argv[j], j - 1);
argv[j - 1] = argv[j];
}
debug("moving %s to end, %d", ptr, end - 1);
argv[end - 1] = ptr;
end--;
if (end < 1)
return;
}
}
}
static isc_uint32_t
parse_uint(char *arg, const char *desc, isc_uint32_t max) {
char *endp;
isc_uint32_t tmp;
tmp = strtoul(arg, &endp, 10);
if (*endp != '\0')
fatal("%s '%s' must be numeric", desc, arg);
if (tmp > max)
fatal("%s '%s' out of range", desc, arg);
return (tmp);
}
/*
* We're not using isc_commandline_parse() here since the command line
* syntax of dig is quite a bit different from that which can be described
* by that routine.
* XXX doc options
*/
static void
plus_option(char *option, isc_boolean_t is_batchfile,
dig_lookup_t *lookup)
{
char option_store[256];
char *cmd, *value, *ptr;
isc_boolean_t state = ISC_TRUE;
strncpy(option_store, option, sizeof(option_store));
option_store[sizeof(option_store)-1]=0;
ptr = option_store;
cmd=next_token(&ptr,"=");
if (cmd == NULL) {
printf(";; Invalid option %s\n",option_store);
return;
}
value=ptr;
if (strncasecmp(cmd,"no",2)==0) {
cmd += 2;
state = ISC_FALSE;
}
switch (cmd[0]) {
case 'a':
switch (cmd[1]) {
case 'a': /* aaflag */
lookup->aaonly = state;
break;
case 'd':
switch (cmd[2]) {
case 'd': /* additional */
lookup->section_additional = state;
break;
case 'f': /* adflag */
lookup->adflag = state;
break;
default:
goto invalid_option;
}
break;
case 'l': /* all */
lookup->section_question = state;
lookup->section_authority = state;
lookup->section_answer = state;
lookup->section_additional = state;
lookup->comments = state;
break;
case 'n': /* answer */
lookup->section_answer = state;
break;
case 'u': /* authority */
lookup->section_authority = state;
break;
default:
goto invalid_option;
}
break;
case 'b':
switch (cmd[1]) {
case 'e':/* besteffort */
lookup->besteffort = state;
break;
case 'u':/* bufsize */
if (value == NULL)
goto need_value;
if (!state)
goto invalid_option;
lookup->udpsize = (isc_uint16_t) parse_uint(value,
"buffer size", COMMSIZE);
if (lookup->udpsize > COMMSIZE)
lookup->udpsize = COMMSIZE;
break;
default:
goto invalid_option;
}
break;
case 'c':
switch (cmd[1]) {
case 'd':/* cdflag */
lookup->cdflag = state;
break;
case 'm': /* cmd */
printcmd = state;
break;
case 'o': /* comments */
lookup->comments = state;
if (lookup == default_lookup)
pluscomm = state;
break;
default:
goto invalid_option;
}
break;
case 'd':
switch (cmd[1]) {
case 'e': /* defname */
usesearch = state;
break;
case 'n': /* dnssec */
lookup->dnssec = state;
break;
case 'o': /* domain */
if (value == NULL)
goto need_value;
if (!state)
goto invalid_option;
strncpy(domainopt, value, sizeof(domainopt));
domainopt[sizeof(domainopt)-1] = '\0';
break;
default:
goto invalid_option;
}
break;
case 'f': /* fail */
lookup->servfail_stops = state;
break;
case 'i':
switch (cmd[1]) {
case 'd': /* identify */
lookup->identify = state;
break;
case 'g': /* ignore */
default: /* Inherets default for compatibility */
lookup->ignore = ISC_TRUE;
}
break;
case 'm': /* multiline */
multiline = state;
break;
case 'n':
switch (cmd[1]) {
case 'd': /* ndots */
if (value == NULL)
goto need_value;
if (!state)
goto invalid_option;
ndots = parse_uint(value, "ndots", MAXNDOTS);
break;
case 's': /* nssearch */
lookup->ns_search_only = state;
if (state) {
lookup->trace_root = ISC_TRUE;
lookup->recurse = ISC_FALSE;
lookup->identify = ISC_TRUE;
lookup->stats = ISC_FALSE;
lookup->comments = ISC_FALSE;
lookup->section_additional = ISC_FALSE;
lookup->section_authority = ISC_FALSE;
lookup->section_question = ISC_FALSE;
lookup->rdtype = dns_rdatatype_ns;
lookup->rdtypeset = ISC_TRUE;
short_form = ISC_TRUE;
}
break;
default:
goto invalid_option;
}
break;
case 'q':
switch (cmd[1]) {
case 'r': /* qr */
qr = state;
break;
case 'u': /* question */
lookup->section_question = state;
if (lookup == default_lookup)
plusquest = state;
break;
default:
goto invalid_option;
}
break;
case 'r': /* recurse */
lookup->recurse = state;
break;
case 's':
switch (cmd[1]) {
case 'e': /* search */
usesearch = state;
break;
case 'h': /* short */
short_form = state;
if (state) {
printcmd = ISC_FALSE;
lookup->section_additional = ISC_FALSE;
lookup->section_authority = ISC_FALSE;
lookup->section_question = ISC_FALSE;
lookup->comments = ISC_FALSE;
lookup->stats = ISC_FALSE;
}
break;
case 't': /* stats */
lookup->stats = state;
break;
default:
goto invalid_option;
}
break;
case 't':
switch (cmd[1]) {
case 'c': /* tcp */
if (!is_batchfile)
lookup->tcp_mode = state;
break;
case 'i': /* timeout */
if (value == NULL)
goto need_value;
if (!state)
goto invalid_option;
timeout = parse_uint(value, "timeout", MAXTIMEOUT);
if (timeout == 0)
timeout = 1;
break;
case 'r':
switch (cmd[2]) {
case 'a': /* trace */
lookup->trace = state;
lookup->trace_root = state;
if (state) {
lookup->recurse = ISC_FALSE;
lookup->identify = ISC_TRUE;
lookup->comments = ISC_FALSE;
lookup->stats = ISC_FALSE;
lookup->section_additional = ISC_FALSE;
lookup->section_authority = ISC_TRUE;
lookup->section_question = ISC_FALSE;
}
break;
case 'i': /* tries */
if (value == NULL)
goto need_value;
if (!state)
goto invalid_option;
lookup->retries = parse_uint(value, "retries",
MAXTRIES);
if (lookup->retries == 0)
lookup->retries = 1;
break;
default:
goto invalid_option;
}
break;
default:
goto invalid_option;
}
break;
case 'v':
#ifdef DNS_OPT_NEWCODES_LIVE
switch (cmd[1]) {
default:
case 'c': /* vc, and default */
#endif /* DNS_OPT_NEWCODES_LIVE */
if (!is_batchfile)
lookup->tcp_mode = state;
break;
#ifdef DNS_OPT_NEWCODES_LIVE
case 'i': /* view */
if (value == NULL)
goto need_value;
if (!state)
goto invalid_option;
strncpy(lookup->viewname, value, MXNAME);
break;
}
break;
case 'z': /* zone */
if (value == NULL)
goto need_value;
if (!state)
goto invalid_option;
strncpy(lookup->zonename, value, MXNAME);
break;
#endif /* DNS_OPT_NEWCODES_LIVE */
default:
invalid_option:
need_value:
fprintf(stderr, "Invalid option: +%s\n",
option);
usage();
}
return;
}
/*
* ISC_TRUE returned if value was used
*/
static isc_boolean_t
dash_option(char *option, char *next, dig_lookup_t **lookup,
isc_boolean_t *open_type_class,
isc_boolean_t *firstarg,
int argc, char **argv)
{
char cmd, *value, *ptr;
isc_result_t result;
isc_boolean_t value_from_next;
isc_textregion_t tr;
dns_rdatatype_t rdtype;
dns_rdataclass_t rdclass;
char textname[MXNAME];
struct in_addr in4;
struct in6_addr in6;
cmd = option[0];
if (strlen(option) > 1) {
value_from_next = ISC_FALSE;
value = &option[1];
} else {
value_from_next = ISC_TRUE;
value = next;
}
switch (cmd) {
case 'd':
debugging = ISC_TRUE;
return (ISC_FALSE);
case 'h':
help();
exit(0);
break;
case 'm': /* memdebug */
/* memdebug is handled in preparse_args() */
return (ISC_FALSE);
case 'n':
nibble = ISC_TRUE;
return (ISC_FALSE);
}
if (value == NULL)
goto invalid_option;
switch (cmd) {
case 'b':
if (have_ipv6 && inet_pton(AF_INET6, value, &in6) == 1)
isc_sockaddr_fromin6(&bind_address, &in6, 0);
else if (have_ipv4 && inet_pton(AF_INET, value, &in4) == 1)
isc_sockaddr_fromin(&bind_address, &in4, 0);
else
fatal("invalid address %s", value);
specified_source = ISC_TRUE;
return (value_from_next);
case 'c':
if ((*lookup)->rdclassset) {
fprintf(stderr, ";; Warning, extra class option\n");
}
*open_type_class = ISC_FALSE;
tr.base = value;
tr.length = strlen(value);
result = dns_rdataclass_fromtext(&rdclass,
(isc_textregion_t *)&tr);
if (result == ISC_R_SUCCESS) {
(*lookup)->rdclass = rdclass;
(*lookup)->rdclassset = ISC_TRUE;
} else
fprintf(stderr, ";; Warning, ignoring "
"invalid class %s\n",
value);
return (value_from_next);
case 'f':
batchname = value;
return (value_from_next);
case 'k':
strncpy(keyfile, value, sizeof(keyfile));
keyfile[sizeof(keyfile)-1]=0;
return (value_from_next);
case 'p':
port = (in_port_t) parse_uint(value, "port number", MAXPORT);
return (value_from_next);
case 't':
*open_type_class = ISC_FALSE;
if (strncasecmp(value, "ixfr=", 5) == 0) {
rdtype = dns_rdatatype_ixfr;
result = ISC_R_SUCCESS;
} else {
tr.base = value;
tr.length = strlen(value);
result = dns_rdatatype_fromtext(&rdtype,
(isc_textregion_t *)&tr);
if (result == ISC_R_SUCCESS &&
rdtype == dns_rdatatype_ixfr)
{
result = DNS_R_UNKNOWN;
}
}
if (result == ISC_R_SUCCESS) {
if ((*lookup)->rdtypeset) {
fprintf(stderr, ";; Warning, "
"extra type option\n");
}
if (rdtype == dns_rdatatype_ixfr) {
(*lookup)->rdtype = dns_rdatatype_ixfr;
(*lookup)->rdtypeset = ISC_TRUE;
(*lookup)->ixfr_serial =
parse_uint(&value[5], "serial number",
MAXSERIAL);
(*lookup)->section_question = plusquest;
(*lookup)->comments = pluscomm;
} else {
(*lookup)->rdtype = rdtype;
(*lookup)->rdtypeset = ISC_TRUE;
if (rdtype == dns_rdatatype_axfr) {
(*lookup)->section_question = plusquest;
(*lookup)->comments = pluscomm;
}
(*lookup)->ixfr_serial = ISC_FALSE;
}
} else
fprintf(stderr, ";; Warning, ignoring "
"invalid type %s\n",
value);
return (value_from_next);
case 'y':
ptr = next_token(&value,":");
if (ptr == NULL) {
usage();
}
strncpy(keynametext, ptr, sizeof(keynametext));
keynametext[sizeof(keynametext)-1]=0;
ptr = next_token(&value, "");
if (ptr == NULL)
usage();
strncpy(keysecret, ptr, sizeof(keysecret));
keysecret[sizeof(keysecret)-1]=0;
return (value_from_next);
case 'x':
*lookup = clone_lookup(default_lookup, ISC_TRUE);
if (get_reverse(textname, value, nibble) == ISC_R_SUCCESS) {
strncpy((*lookup)->textname, textname,
sizeof((*lookup)->textname));
debug("looking up %s", (*lookup)->textname);
(*lookup)->trace_root = ISC_TF((*lookup)->trace ||
(*lookup)->ns_search_only);
(*lookup)->nibble = nibble;
if (!(*lookup)->rdtypeset)
(*lookup)->rdtype = dns_rdatatype_ptr;
if (!(*lookup)->rdclassset)
(*lookup)->rdclass = dns_rdataclass_in;
(*lookup)->new_search = ISC_TRUE;
if (*lookup && *firstarg)
{
printgreeting(argc, argv, *lookup);
*firstarg = ISC_FALSE;
}
ISC_LIST_APPEND(lookup_list, *lookup, link);
} else {
fprintf(stderr, "Invalid IP address %s\n", value);
exit(1);
}
return (value_from_next);
invalid_option:
default:
fprintf(stderr, "Invalid option: -%s\n", option);
usage();
}
return (ISC_FALSE);
}
/*
* Because we may be trying to do memory allocation recording, we're going
* to need to parse the arguments for the -m *before* we start the main
* argument parsing routine.
* I'd prefer not to have to do this, but I am not quite sure how else to
* fix the problem. Argument parsing in dig involves memory allocation
* by its nature, so it can't be done in the main argument parser.
*/
static void
preparse_args(int argc, char **argv) {
int rc;
char **rv;
rc = argc;
rv = argv;
for (rc--, rv++; rc > 0; rc--, rv++) {
if (strcmp(rv[0], "-m") == 0) {
memdebugging = ISC_TRUE;
isc_mem_debugging = ISC_MEM_DEBUGTRACE |
ISC_MEM_DEBUGRECORD;
return;
}
}
}
static void
parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only,
int argc, char **argv) {
isc_result_t result;
isc_textregion_t tr;
isc_boolean_t firstarg = ISC_TRUE;
dig_server_t *srv = NULL;
dig_lookup_t *lookup = NULL;
dns_rdatatype_t rdtype;
dns_rdataclass_t rdclass;
isc_boolean_t open_type_class = ISC_TRUE;
char batchline[MXNAME];
int bargc;
char *bargv[64];
int rc;
char **rv;
#ifndef NOPOSIX
char *homedir;
char rcfile[256];
#endif
char *input;
/*
* The semantics for parsing the args is a bit complex; if
* we don't have a host yet, make the arg apply globally,
* otherwise make it apply to the latest host. This is
* a bit different than the previous versions, but should
* form a consistent user interface.
*
* First, create a "default lookup" which won't actually be used
* anywhere, except for cloning into new lookups
*/
debug("parse_args()");
if (!is_batchfile) {
debug("making new lookup");
default_lookup = make_empty_lookup();
#ifndef NOPOSIX
/*
* Treat .digrc as a special batchfile
*/
homedir = getenv("HOME");
if (homedir != NULL)
snprintf(rcfile, sizeof(rcfile), "%s/.digrc", homedir);
else
strcpy(rcfile, ".digrc");
batchfp = fopen(rcfile, "r");
if (batchfp != NULL) {
while (fgets(batchline, sizeof(batchline),
batchfp) != 0) {
debug("config line %s", batchline);
bargc = 1;
input = batchline;
bargv[bargc] = next_token(&input, " \t\r\n");
while ((bargv[bargc] != NULL) &&
(bargc < 62)) {
bargc++;
bargv[bargc] = next_token(&input, " \t\r\n");
}
bargv[0] = argv[0];
argv0 = argv[0];
reorder_args(bargc, (char **)bargv);
parse_args(ISC_TRUE, ISC_TRUE, bargc,
(char **)bargv);
}
fclose(batchfp);
}
#endif
}
lookup = default_lookup;
rc = argc;
rv = argv;
for (rc--, rv++; rc > 0; rc--, rv++) {
debug("main parsing %s", rv[0]);
if (strncmp(rv[0], "%", 1) == 0)
break;
if (strncmp(rv[0], "@", 1) == 0) {
srv = make_server(&rv[0][1]);
ISC_LIST_APPEND(lookup->my_server_list,
srv, link);
} else if (rv[0][0] == '+') {
plus_option(&rv[0][1], is_batchfile,
lookup);
} else if (rv[0][0] == '-') {
if (rc <= 1) {
if (dash_option(&rv[0][1], NULL,
&lookup, &open_type_class,
&firstarg, argc, argv)) {
rc--;
rv++;
}
} else {
if (dash_option(&rv[0][1], rv[1],
&lookup, &open_type_class,
&firstarg, argc, argv)) {
rc--;
rv++;
}
}
} else {
/*
* Anything which isn't an option
*/
if (open_type_class) {
if (strncmp(rv[0], "ixfr=", 5) == 0) {
rdtype = dns_rdatatype_ixfr;
result = ISC_R_SUCCESS;
} else {
tr.base = rv[0];
tr.length = strlen(rv[0]);
result = dns_rdatatype_fromtext(&rdtype,
(isc_textregion_t *)&tr);
if (result == ISC_R_SUCCESS &&
rdtype == dns_rdatatype_ixfr)
{
result = DNS_R_UNKNOWN;
fprintf(stderr, ";; Warning, "
"ixfr requires a "
"serial number\n");
continue;
}
}
if (result == ISC_R_SUCCESS)
{
if (lookup->rdtypeset) {
fprintf(stderr, ";; Warning, "
"extra type option\n");
}
if (rdtype == dns_rdatatype_ixfr) {
lookup->rdtype = dns_rdatatype_ixfr;
lookup->rdtypeset = ISC_TRUE;
lookup->ixfr_serial =
parse_uint(&rv[0][5],
"serial number",
MAXSERIAL);
lookup->section_question = plusquest;
lookup->comments = pluscomm;
} else {
lookup->rdtype = rdtype;
lookup->rdtypeset = ISC_TRUE;
if (rdtype == dns_rdatatype_axfr) {
lookup->section_question =
plusquest;
lookup->comments = pluscomm;
}
lookup->ixfr_serial = ISC_FALSE;
}
continue;
}
result = dns_rdataclass_fromtext(&rdclass,
(isc_textregion_t *)&tr);
if (result == ISC_R_SUCCESS) {
if (lookup->rdclassset) {
fprintf(stderr, ";; Warning, "
"extra class option\n");
}
lookup->rdclass = rdclass;
lookup->rdclassset = ISC_TRUE;
continue;
}
}
if (!config_only) {
lookup = clone_lookup(default_lookup,
ISC_TRUE);
if (firstarg) {
printgreeting(argc, argv, lookup);
firstarg = ISC_FALSE;
}
strncpy(lookup->textname, rv[0],
sizeof(lookup->textname));
lookup->textname[sizeof(lookup->textname)-1]=0;
lookup->trace_root = ISC_TF(lookup->trace ||
lookup->ns_search_only);
lookup->new_search = ISC_TRUE;
ISC_LIST_APPEND(lookup_list, lookup, link);
debug("looking up %s", lookup->textname);
}
/* XXX Error message */
}
}
/*
* If we have a batchfile, seed the lookup list with the
* first entry, then trust the callback in dighost_shutdown
* to get the rest
*/
if ((batchname != NULL) && !(is_batchfile)) {
if (strcmp(batchname, "-") == 0)
batchfp = stdin;
else
batchfp = fopen(batchname, "r");
if (batchfp == NULL) {
perror(batchname);
if (exitcode < 8)
exitcode = 8;
fatal("Couldn't open specified batch file");
}
/* XXX Remove code dup from shutdown code */
next_line:
if (fgets(batchline, sizeof(batchline), batchfp) != 0) {
bargc = 1;
debug("batch line %s", batchline);
if (batchline[0] == '\r' || batchline[0] == '\n'
|| batchline[0] == '#' || batchline[0] == ';')
goto next_line;
input = batchline;
bargv[bargc] = next_token(&input, " \t\r\n");
while ((bargv[bargc] != NULL) && (bargc < 14)) {
bargc++;
bargv[bargc] = next_token(&input, " \t\r\n");
}
bargv[0] = argv[0];
argv0 = argv[0];
reorder_args(bargc, (char **)bargv);
parse_args(ISC_TRUE, ISC_FALSE, bargc, (char **)bargv);
}
}
/*
* If no lookup specified, search for root
*/
if ((lookup_list.head == NULL) && !config_only) {
lookup = clone_lookup(default_lookup, ISC_TRUE);
lookup->trace_root = ISC_TF(lookup->trace ||
lookup->ns_search_only);
lookup->new_search = ISC_TRUE;
strcpy(lookup->textname, ".");
lookup->rdtype = dns_rdatatype_ns;
lookup->rdtypeset = ISC_TRUE;
if (firstarg) {
printgreeting(argc, argv, lookup);
firstarg = ISC_FALSE;
}
ISC_LIST_APPEND(lookup_list, lookup, link);
}
}
/*
* Callback from dighost.c to allow program-specific shutdown code. Here,
* Here, we're possibly reading from a batch file, then shutting down for
* real if there's nothing in the batch file to read.
*/
void
dighost_shutdown(void) {
char batchline[MXNAME];
int bargc;
char *bargv[16];
char *input;
if (batchname == NULL) {
isc_app_shutdown();
return;
}
if (feof(batchfp)) {
batchname = NULL;
isc_app_shutdown();
if (batchfp != stdin)
fclose(batchfp);
return;
}
if (fgets(batchline, sizeof(batchline), batchfp) != 0) {
debug("batch line %s", batchline);
bargc = 1;
input = batchline;
bargv[bargc] = next_token(&input, " \t\r\n");
while ((bargv[bargc] != NULL) && (bargc < 14)) {
bargc++;
bargv[bargc] = next_token(&input, " \t\r\n");
}
bargv[0] = argv0;
reorder_args(bargc, (char **)bargv);
parse_args(ISC_TRUE, ISC_FALSE, bargc, (char **)bargv);
start_lookup();
} else {
batchname = NULL;
if (batchfp != stdin)
fclose(batchfp);
isc_app_shutdown();
return;
}
}
int
main(int argc, char **argv) {
isc_result_t result;
dig_server_t *s, *s2;
ISC_LIST_INIT(lookup_list);
ISC_LIST_INIT(server_list);
ISC_LIST_INIT(search_list);
debug("main()");
preparse_args(argc, argv);
progname = argv[0];
result = isc_app_start();
check_result(result, "isc_app_start");
setup_libs();
parse_args(ISC_FALSE, ISC_FALSE, argc, argv);
setup_system();
if (domainopt[0] != '\0') {
set_search_domain(domainopt);
usesearch = ISC_TRUE;
}
result = isc_app_onrun(mctx, global_task, onrun_callback, NULL);
check_result(result, "isc_app_onrun");
isc_app_run();
s = ISC_LIST_HEAD(default_lookup->my_server_list);
while (s != NULL) {
debug("freeing server %p belonging to %p",
s, default_lookup);
s2 = s;
s = ISC_LIST_NEXT(s, link);
ISC_LIST_DEQUEUE(default_lookup->my_server_list, s2, link);
isc_mem_free(mctx, s2);
}
isc_mem_free(mctx, default_lookup);
if (batchname != NULL) {
if (batchfp != stdin)
fclose(batchfp);
batchname = NULL;
}
cancel_all();
destroy_libs();
isc_app_finish();
return (exitcode);
}