* option handling tables etc.
*/
/*
- * This file is
- * Copyright (C) 1997-1999 Ian Jackson <ian@davenant.greenend.org.uk>
- *
- * It is part of adns, which is
- * Copyright (C) 1997-1999 Ian Jackson <ian@davenant.greenend.org.uk>
- * Copyright (C) 1999 Tony Finch <dot@dotat.at>
+ * This file is part of adns, which is
+ * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
+ * Copyright (C) 2014 Mark Wooding
+ * Copyright (C) 1999-2000,2003,2006 Tony Finch
+ * Copyright (C) 1991 Massachusetts Institute of Technology
+ * (See the file INSTALL for full details.)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
+ * the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * along with this program; if not, write to the Free Software Foundation.
*/
#include "adnshost.h"
int ov_verbose= 0;
adns_rrtype ov_type= adns_r_none;
int ov_search=0, ov_qc_query=0, ov_qc_anshost=0, ov_qc_cname=1;
-int ov_tcp=0, ov_cname=0;
+int ov_tcp=0, ov_cname=0, ov_afflags=0, ov_v6map=0, ov_format=fmt_default;
char *ov_id= 0;
struct perqueryflags_remember ov_pqfr = { 1,1,1, tm_none };
"f", "pipe", &ov_pipe, 1 },
{ ot_flag, "Allow answers to be reordered",
"a", "asynch", &ov_asynch, 1 },
+
+ { ot_desconly, "answer/error output format and destination (see below):" },
+ { ot_value, "Answers to stdout, errors as messages to stderr (default)",
+ "Fs", "fmt-simple", &ov_format, fmt_simple },
+ { ot_value, "Answers and errors both to stdout in parseable format",
+ "Fi", "fmt-inline", &ov_format, fmt_inline },
+ { ot_value, "Fully-parseable output format (default for --asynch)",
+ "Fa", "fmt-asynch", &ov_format, fmt_asynch },
{ ot_desconly, "global verbosity level:" },
{ ot_value, "Do not print anything to stderr",
"Vd", "debug", &ov_verbose, adns_if_debug },
{ ot_desconly, "other global options:" },
+ { ot_funcarg, "Configuration to use instead of /etc/resolv.conf",
+ 0, "config", 0,0, of_config, "<config-text>" },
+ { ot_func, "Print version number",
+ 0, "version", 0,0, of_version },
{ ot_func, "Print usage information",
0, "help", 0,0, of_help },
{ ot_funcarg, "Query type (see below)",
"t", "type", 0,0, &of_type, "type" },
{ ot_funcarg, "Do reverse query (address -> name lookup)",
- "i", "ptr", 0,0, &of_type, "addr" },
+ "i", "ptr", 0,0, &of_ptr, "addr" },
+ { ot_funcarg2, "Lookup in in-addr-like `zone' (eg MAPS RBL)",
+ 0, "reverse", 0,0, &of_reverse, "addr","zone" },
{ ot_desconly, "per-query binary options:" },
{ ot_flag, "Use the search list",
"Ta", "ttl-abs", &ov_pqfr.ttl, tm_abs },
{ ot_value, "Do not show the TTL (default)",
"Tn", "no-ttl", &ov_pqfr.ttl, tm_none },
+
+ { ot_desconly, "per-query address family options (for `addr' etc.):" },
+ { ot_value, "Only return IPv4 addresses",
+ "A4", "--addr-ipv4-only", &ov_afflags, adns_qf_want_ipv4 },
+ { ot_value, "Only return IPv6 addresses",
+ "A6", "--addr-ipv6-only", &ov_afflags, adns_qf_want_ipv6 },
+ { ot_value, "Return all available addresses (default)",
+ "Aa", "--addr-all", &ov_afflags, 0 },
+ { ot_flag, "Return IPv4 addresses as IPv6-mapped",
+ "Am", "--addr-ipv6-mapped", &ov_v6map, 1 },
{ ot_desconly, "per-query CNAME handling mode:" },
{ ot_value, "Call it an error if a CNAME is found",
{ ot_desconly, "asynchronous/pipe mode options:" },
{ ot_funcarg, "Set <id>, default is decimal sequence starting 0",
0, "asynch-id", 0,0, &of_asynch_id, "id" },
- { ot_funcarg, "Cancel the query with id <id>",
+ { ot_funcarg, "Cancel the query with id <id> (no error if not found)",
0, "cancel-id", 0,0, &of_cancel_id, "id" },
{ ot_end }
oip->desc);
}
break;
+ case ot_funcarg2:
+ assert(!oip->sopt);
+ l= (maxlopt + maxsopt - 2 -
+ (strlen(oip->lopt) + strlen(oip->argdesc) + strlen(oip->argdesc2)));
+ printf(" --%s <%s> <%s>%*s%s\n",
+ oip->lopt, oip->argdesc, oip->argdesc2,
+ l>2 ? l : 2, "",
+ oip->desc);
+ break;
case ot_desconly:
printf("%s\n", oip->desc);
break;
"or if the <owner> domain refers to a CNAME and --show-cname is on\n"
" [<owner>] [<ttl>] CNAME <cname>\n"
" [<cname>] [<ttl>] <type> <data>\n"
- "When a query fails you get a line like this (broken here for readability):\n"
+ "When a query fails you get an error message to stderr (with --fmt-simple).\n"
+ "Specify --fmt-inline for lines like this (broken here for readability):\n"
" ; failed <statustype> <statusnum> <statusabbrev> \\\n"
" [<owner>] [<ttl>] [<cname>] \"<status string>\"\n"
- "\n"
- "If you use --asynch each answer (success or failure) is preceded by a line\n"
+ "If you use --fmt-asynch, which is the default for --asynch,\n"
+ "each answer (success or failure) is preceded by a line\n"
" <id> <nrrs> <statustype> <statusnum> <statusabbrev> \\\n"
" [<owner>] [<ttl>] [<cname>] \"<status string>\"\n"
"where <nrrs> is the number of RRs that follow and <cname> will be `$' or\n"
" 11 usage problems\n"
"\n"
"Query types (see adns.h; default is addr):\n"
- " ns soa ptr mx rp addr - enhanced versions\n"
- " cname hinfo txt - types with only one version\n"
- " a ns- soa- ptr- mx- rp- - _raw versions\n"
+ " ns soa ptr mx rp srv addr - enhanced versions\n"
+ " cname hinfo txt - types with only one version\n"
+ " a aaaa ns- soa- ptr- mx- rp- srv- - _raw versions\n"
+ " type<number> - `unknown' type, RFC3597\n"
"Default is addr, or ptr for -i/--ptr queries\n",
stdout);
if (ferror(stdout)) sysfail("write usage message",errno);
}
-void of_help(const struct optioninfo *oi, const char *arg) {
+void of_version(const struct optioninfo *oi, const char *arg, const char *arg2) {
+ VERSION_PRINT_QUIT("adnshost");
+}
+
+void of_help(const struct optioninfo *oi, const char *arg, const char *arg2) {
printusage();
if (fclose(stdout)) sysfail("finish writing output",errno);
- exit(0);
+ quitnow(0);
}
typedef int comparer_type(const char **optp, const struct optioninfo *entry);
const char *prefix,
comparer_type *comparer) {
const struct optioninfo *oip;
+ const char *opt;
+ opt= *optp;
oip= find1(optp,perquery_options,comparer);
if (oip) return oip;
oip= find1(optp,global_options,comparer);
- if (!oip) usageerr("unknown option %s%s",prefix,*optp);
- if (ads) usageerr("global option %s%s specified after query domain(s)",prefix,*optp);
+ if (!oip) usageerr("unknown option %s%s",prefix,opt);
+ if (ads) usageerr("global option %s%s specified after query domain(s)",prefix,opt);
return oip;
}
const struct optioninfo *opt_findl(const char *opt) { return find(&opt,"--",oc_long); }
const struct optioninfo *opt_finds(const char **optp) { return find(optp,"-",oc_short); }
-void opt_do(const struct optioninfo *oip, const char *arg) {
+static void noninvert(const struct optioninfo *oip) NONRETURNING;
+static void noninvert(const struct optioninfo *oip) {
+ usageerr("option %s%s%s%s%s may not be inverted",
+ oip->sopt ? "-" : "", oip->sopt ? oip->sopt : "",
+ oip->lopt && oip->sopt ? " / " : "",
+ oip->lopt ? "--" : "", oip->lopt ? oip->lopt : "");
+}
+
+void opt_do(const struct optioninfo *oip, int invert,
+ const char *arg, const char *arg2) {
switch (oip->type) {
- case ot_flag: case ot_value:
+ case ot_flag:
+ assert(!arg);
+ *oip->storep= !invert;
+ return;
+ case ot_value:
assert(!arg);
+ if (invert) noninvert(oip);
*oip->storep= oip->value;
return;
- case ot_func: case ot_funcarg:
- oip->func(oip,0);
+ case ot_func: case ot_funcarg: case ot_funcarg2:
+ if (invert) noninvert(oip);
+ oip->func(oip,arg,arg2);
return;
default:
abort();