summaryrefslogtreecommitdiff
path: root/adns-0.6/client
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--adns-0.6/client/.cvsignore11
-rw-r--r--adns-0.6/client/Makefile.in74
-rw-r--r--adns-0.6/client/adh-main.c243
-rw-r--r--adns-0.6/client/adh-opts.c337
-rw-r--r--adns-0.6/client/adh-query.c274
-rw-r--r--adns-0.6/client/adnshost.h118
-rw-r--r--adns-0.6/client/adnslogres.c239
-rw-r--r--adns-0.6/client/adnsresfilter.c454
-rw-r--r--adns-0.6/client/adnstest.c337
-rw-r--r--adns-0.6/client/fanftest.c85
-rw-r--r--adns-0.6/client/x.gdb2
11 files changed, 2174 insertions, 0 deletions
diff --git a/adns-0.6/client/.cvsignore b/adns-0.6/client/.cvsignore
new file mode 100644
index 0000000..45bcf1e
--- /dev/null
+++ b/adns-0.6/client/.cvsignore
@@ -0,0 +1,11 @@
+Makefile
+adnstest
+adnstest_s
+adnslogres
+adnslogres_s
+adnshost
+adnshost_s
+adnsresfilter
+adnsresfilter_s
+fanftest
+fanftest_s
diff --git a/adns-0.6/client/Makefile.in b/adns-0.6/client/Makefile.in
new file mode 100644
index 0000000..a7b3aaa
--- /dev/null
+++ b/adns-0.6/client/Makefile.in
@@ -0,0 +1,74 @@
+# client/Makefile - client program(s) Makefile
+#
+# 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 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)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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.
+
+srcdir= @srcdir@
+VPATH= @srcdir@
+
+PROGS_SYSDEP= @PROGS_HAVE_TSEARCH@
+
+PROGRAMS= adnstest adnslogres adnshost $(PROGS_SYSDEP)
+PROGRAMS_LOCAL= fanftest
+PROGRAMS_ALL= $(PROGRAMS) $(PROGRAMS_LOCAL)
+
+TARG_INSTALL= $(PROGRAMS)
+TARG_LOCAL= $(addsuffix _s, $(PROGRAMS_ALL))
+TARGETS= $(TARG_LOCAL) $(TARG_INSTALL)
+include $(srcdir)/../settings.make
+
+DIRCFLAGS= -I$(srcdir)/../src
+
+TARG_OBJS= $(addsuffix .o, $(PROGRAMS_ALL))
+ADH_OBJS= adh-main.o adh-opts.o adh-query.o
+ALL_OBJS= $(ADH_OBJS) $(TARG_OBJS)
+
+ADNSDIR= $(srcdir)/../src/
+
+STATIC_LIB= $(ADNSDIR)/libadns.a
+DYNAMIC_DEP= $(srcdir)/../dynamic/$(SHLIBFILE)
+DYNAMIC_LINK= -L$(srcdir)/../dynamic -ladns
+
+all: $(TARGETS)
+
+install: $(TARG_INSTALL)
+ set -xe; for f in $(TARG_INSTALL); \
+ do $(INSTALL_PROGRAM) $$f $(bin_dir)/$$f; done
+
+uninstall:
+ for f in $(TARGETS); do rm -f $(bin_dir)/$$f; done
+
+adnshost: $(ADH_OBJS) $(DYNAMIC_DEP)
+ $(CC) $(LDFLAGS) $(ADH_OBJS) $(DYNAMIC_LINK) -o $@ $(LDLIBS)
+
+adnshost_s: $(ADH_OBJS) $(STATIC_LIB)
+ $(CC) $(LDFLAGS) $(ADH_OBJS) $(STATIC_LIB) -o $@ $(LDLIBS)
+
+$(ADH_OBJS): adnshost.h
+$(ALL_OBJS): $(ADNSDIR)/adns.h $(ADNSDIR)/config.h
+adnsresfilter.o: $(ADNSDIR)/tvarith.h
+
+%: %.o $(DYNAMIC_DEP)
+ $(CC) $(LDFLAGS) $< $(DYNAMIC_LINK) -o $@ $(LDLIBS)
+
+%_s: %.o $(STATIC_LIB)
+ $(CC) $(LDFLAGS) $< $(STATIC_LIB) -o $@ $(LDLIBS)
+
diff --git a/adns-0.6/client/adh-main.c b/adns-0.6/client/adh-main.c
new file mode 100644
index 0000000..81cff54
--- /dev/null
+++ b/adns-0.6/client/adh-main.c
@@ -0,0 +1,243 @@
+/*
+ * adh-main.c
+ * - useful general-purpose resolver client program
+ * main program and useful subroutines
+ */
+/*
+ * 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 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)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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.
+ */
+
+#include "adnshost.h"
+
+void sysfail(const char *what, int errnoval) {
+ fprintf(stderr,"adnshost failed: %s: %s\n",what,strerror(errnoval));
+ exit(10);
+}
+
+void usageerr(const char *fmt, ...) {
+ va_list al;
+ fputs("adnshost usage error: ",stderr);
+ va_start(al,fmt);
+ vfprintf(stderr,fmt,al);
+ va_end(al);
+ putc('\n',stderr);
+ exit(11);
+}
+
+void outerr(void) {
+ sysfail("write to stdout",errno);
+}
+
+void *xmalloc(size_t sz) {
+ void *p;
+
+ p= malloc(sz); if (!p) sysfail("malloc",sz);
+ return p;
+}
+
+char *xstrsave(const char *str) {
+ char *p;
+
+ p= xmalloc(strlen(str)+1);
+ strcpy(p,str);
+ return p;
+}
+
+void of_type(const struct optioninfo *oi, const char *arg) {
+ static const struct typename {
+ adns_rrtype type;
+ const char *desc;
+ } typenames[]= {
+ /* enhanced versions */
+ { adns_r_ns, "ns" },
+ { adns_r_soa, "soa" },
+ { adns_r_ptr, "ptr" },
+ { adns_r_mx, "mx" },
+ { adns_r_rp, "rp" },
+ { adns_r_addr, "addr" },
+
+ /* types with only one version */
+ { adns_r_cname, "cname" },
+ { adns_r_hinfo, "hinfo" },
+ { adns_r_txt, "txt" },
+
+ /* raw versions */
+ { adns_r_a, "a" },
+ { adns_r_ns_raw, "ns-" },
+ { adns_r_soa_raw, "soa-" },
+ { adns_r_ptr_raw, "ptr-" },
+ { adns_r_mx_raw, "mx-" },
+ { adns_r_rp_raw, "rp-" },
+
+ { adns_r_none, 0 }
+ };
+
+ const struct typename *tnp;
+
+ for (tnp=typenames;
+ tnp->type && strcmp(arg,tnp->desc);
+ tnp++);
+ if (!tnp->type) usageerr("unknown RR type %s",arg);
+ ov_type= tnp->type;
+}
+
+int rcode;
+
+static void process_optarg(const char *arg,
+ const char *const **argv_p,
+ const char *value) {
+ const struct optioninfo *oip;
+ int invert;
+
+ if (arg[0] == '-' || arg[0] == '+') {
+ if (arg[0] == '-' && arg[1] == '-') {
+ if (!strncmp(arg,"--no-",5)) {
+ invert= 1;
+ oip= opt_findl(arg+5);
+ } else {
+ invert= 0;
+ oip= opt_findl(arg+2);
+ }
+ if (oip->type == ot_funcarg) {
+ arg= argv_p ? *++(*argv_p) : value;
+ if (!arg) usageerr("option --%s requires a value argument",oip->lopt);
+ } else {
+ if (value) usageerr("option --%s does not take a value",oip->lopt);
+ arg= 0;
+ }
+ opt_do(oip,arg,invert);
+ } else if (arg[0] == '-' && arg[1] == 0) {
+ arg= argv_p ? *++(*argv_p) : value;
+ if (!arg) usageerr("option `-' must be followed by a domain");
+ query_do(arg);
+ } else { /* arg[1] != '-', != '\0' */
+ invert= (arg[0] == '+');
+ ++arg;
+ while (*arg) {
+ oip= opt_finds(&arg);
+ if (oip->type == ot_funcarg) {
+ if (!*arg) {
+ arg= argv_p ? *++(*argv_p) : value;
+ if (!arg) usageerr("option -%s requires a value argument",oip->sopt);
+ } else {
+ if (value) usageerr("two values for option -%s given !",oip->sopt);
+ }
+ opt_do(oip,arg,invert);
+ arg= "";
+ } else {
+ if (value) usageerr("option -%s does not take a value",oip->sopt);
+ opt_do(oip,0,invert);
+ }
+ }
+ }
+ } else { /* arg[0] != '-' */
+ query_do(arg);
+ }
+}
+
+static void read_stdin(void) {
+ static int used, avail;
+ static char *buf;
+
+ int anydone, r;
+ char *newline, *space;
+
+ anydone= 0;
+ while (!anydone || used) {
+ while (!(newline= memchr(buf,'\n',used))) {
+ if (used == avail) {
+ avail += 20; avail <<= 1;
+ buf= realloc(buf,avail);
+ if (!buf) sysfail("realloc stdin buffer",errno);
+ }
+ do {
+ r= read(0,buf+used,avail-used);
+ } while (r < 0 && errno == EINTR);
+ if (r == 0) {
+ if (used) {
+ /* fake up final newline */
+ buf[used++]= '\n';
+ r= 1;
+ } else {
+ ov_pipe= 0;
+ return;
+ }
+ }
+ if (r < 0) sysfail("read stdin",errno);
+ used += r;
+ }
+ *newline++= 0;
+ space= strchr(buf,' ');
+ if (space) *space++= 0;
+ process_optarg(buf,0,space);
+ used -= (newline-buf);
+ memmove(buf,newline,used);
+ anydone= 1;
+ }
+}
+
+int main(int argc, const char *const *argv) {
+ struct timeval *tv, tvbuf;
+ adns_query qu;
+ void *qun_v;
+ adns_answer *answer;
+ int r, maxfd;
+ fd_set readfds, writefds, exceptfds;
+ const char *arg;
+
+ while ((arg= *++argv)) process_optarg(arg,&argv,0);
+
+ if (!ov_pipe && !ads) usageerr("no domains given, and -f/--pipe not used; try --help");
+
+ ensure_adns_init();
+
+ for (;;) {
+ for (;;) {
+ qu= ov_asynch ? 0 : outstanding.head ? outstanding.head->qu : 0;
+ r= adns_check(ads,&qu,&answer,&qun_v);
+ if (r == EAGAIN) break;
+ if (r == ESRCH) { if (!ov_pipe) goto x_quit; else break; }
+ assert(!r);
+ query_done(qun_v,answer);
+ }
+ maxfd= 0;
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+ FD_ZERO(&exceptfds);
+ if (ov_pipe) {
+ maxfd= 1;
+ FD_SET(0,&readfds);
+ }
+ tv= 0;
+ adns_beforeselect(ads, &maxfd, &readfds,&writefds,&exceptfds, &tv,&tvbuf,0);
+ r= select(maxfd, &readfds,&writefds,&exceptfds, tv);
+ if (r == -1) {
+ if (errno == EINTR) continue;
+ sysfail("select",errno);
+ }
+ adns_afterselect(ads, maxfd, &readfds,&writefds,&exceptfds, 0);
+ if (ov_pipe && FD_ISSET(0,&readfds)) read_stdin();
+ }
+x_quit:
+ if (fclose(stdout)) outerr();
+ exit(rcode);
+}
diff --git a/adns-0.6/client/adh-opts.c b/adns-0.6/client/adh-opts.c
new file mode 100644
index 0000000..46d5606
--- /dev/null
+++ b/adns-0.6/client/adh-opts.c
@@ -0,0 +1,337 @@
+/*
+ * adh-opts.c
+ * - useful general-purpose resolver client program
+ * 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 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)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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.
+ */
+
+#include "adnshost.h"
+
+int ov_env=1, ov_pipe=0, ov_asynch=0;
+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, ov_format=fmt_default;
+char *ov_id= 0;
+struct perqueryflags_remember ov_pqfr = { 1,1,1, tm_none };
+
+static const struct optioninfo global_options[]= {
+ { ot_desconly, "global binary options:" },
+ { ot_flag, "Do not look at environment variables at all",
+ "e", "env", &ov_env, 0 },
+ { ot_flag, "Read queries on stdin instead of using args",
+ "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",
+ "Vq", "quiet", &ov_verbose, adns_if_noerrprint },
+ { ot_value, "Report unexpected kinds of problem only (default)",
+ "Vn", "no-quiet", &ov_verbose, 0 },
+ { ot_value, "Debugging mode",
+ "Vd", "debug", &ov_verbose, adns_if_debug },
+
+ { ot_desconly, "other global options:" },
+ { ot_func, "Print usage information",
+ 0, "help", 0,0, of_help },
+
+ { ot_end }
+};
+
+static const struct optioninfo perquery_options[]= {
+ { ot_desconly, "per-query options:" },
+ { 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_ptr, "addr" },
+
+ { ot_desconly, "per-query binary options:" },
+ { ot_flag, "Use the search list",
+ "s", "search", &ov_search, 1 },
+ { ot_flag, "Let query domains contain quote-requiring chars",
+ "Qq", "qc-query", &ov_qc_query, 1 },
+ { ot_flag, "Let hostnames in answers contain ...",
+ "Qa", "qc-anshost", &ov_qc_anshost, 1 },
+ { ot_flag, "Prevent CNAME target domains from containing ...",
+ "Qc", "qc-cname", &ov_qc_cname, 0 },
+ { ot_flag, "Force use of a virtual circuit",
+ "u", "tcp", &ov_tcp, 1 },
+ { ot_flag, "Do not display owner name in output",
+ "Do", "show-owner", &ov_pqfr.show_owner, 0 },
+ { ot_flag, "Do not display RR type in output",
+ "Dt", "show-type", &ov_pqfr.show_type, 0 },
+ { ot_flag, "Do not display CNAME target in output",
+ "Dc", "show-cname", &ov_pqfr.show_cname, 0 },
+
+ { ot_desconly, "per-query TTL mode (NB TTL is minimum across all info in reply):" },
+ { ot_value, "Show the TTL as a TTL",
+ "Tt", "ttl-ttl", &ov_pqfr.ttl, tm_rel },
+ { ot_value, "Show the TTL as a time_t when the data might expire",
+ "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 CNAME handling mode:" },
+ { ot_value, "Call it an error if a CNAME is found",
+ "Cf", "cname-reject", &ov_cname, adns_qf_cname_forbid },
+ { ot_value, "Allow references to CNAMEs in other RRs",
+ "Cl", "cname-loose", &ov_cname, adns_qf_cname_loose },
+ { ot_value, "CNAME ok for query domain, but not in RRs (default)",
+ "Cs", "cname-ok", &ov_cname, 0 },
+
+ { 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> (no error if not found)",
+ 0, "cancel-id", 0,0, &of_cancel_id, "id" },
+
+ { ot_end }
+};
+
+static void printusage(void) {
+ static const struct optioninfo *const all_optiontables[]= {
+ global_options, perquery_options, 0
+ };
+
+ const struct optioninfo *const *oiap, *oip=0;
+ int maxsopt, maxlopt, l;
+
+ maxsopt= maxlopt= 0;
+
+ for (oiap=all_optiontables; *oiap; oiap++) {
+ for (oip=*oiap; oip->type != ot_end; oip++) {
+ if (oip->type == ot_funcarg) continue;
+ if (oip->sopt) { l= strlen(oip->sopt); if (l>maxsopt) maxsopt= l; }
+ if (oip->lopt) {
+ l= strlen(oip->lopt);
+ if (oip->type == ot_flag && !oip->value) l+= 3;
+ if (l>maxlopt) maxlopt= l;
+ }
+ }
+ }
+
+ fputs("usage: adnshost [global-opts] [query-opts] query-domain\n"
+ " [[query-opts] query-domain ...]\n"
+ " adnshost [global-opts] [query-opts] -f|--pipe\n",
+ stdout);
+
+ for (oiap=all_optiontables; *oiap; oiap++) {
+ putchar('\n');
+ for (oip=*oiap; oip->type != ot_end; oip++) {
+ switch (oip->type) {
+ case ot_flag:
+ if (!oip->value) {
+ if (oip->sopt) {
+ printf(" +%-*s --no-%-*s %s\n",
+ maxsopt, oip->sopt,
+ maxlopt-2, oip->lopt,
+ oip->desc);
+ } else {
+ printf(" --no-%-*s %s\n",
+ maxlopt+maxsopt+1, oip->lopt,
+ oip->desc);
+ }
+ break;
+ }
+ case ot_value: case ot_func: /* fall through */
+ if (oip->sopt) {
+ printf(" -%-*s --%-*s %s\n",
+ maxsopt, oip->sopt,
+ maxlopt+1, oip->lopt,
+ oip->desc);
+ } else {
+ printf(" --%-*s %s\n",
+ maxlopt+maxsopt+3, oip->lopt,
+ oip->desc);
+ }
+ break;
+ case ot_funcarg:
+ if (oip->sopt) {
+ l= (maxlopt + maxsopt - 9 -
+ (strlen(oip->sopt) + strlen(oip->lopt) + 2*strlen(oip->argdesc)));
+ printf(" -%s<%s> / --%s <%s>%*s%s\n",
+ oip->sopt, oip->argdesc, oip->lopt, oip->argdesc,
+ l>2 ? l : 2, "",
+ oip->desc);
+ } else {
+ l= (maxlopt + maxsopt + 1 -
+ (strlen(oip->lopt) + strlen(oip->argdesc)));
+ printf(" --%s <%s>%*s%s\n",
+ oip->lopt, oip->argdesc,
+ l>2 ? l : 2, "",
+ oip->desc);
+ }
+ break;
+ case ot_desconly:
+ printf("%s\n", oip->desc);
+ break;
+ default:
+ abort();
+ }
+ }
+ }
+
+ printf("\nEscaping domains which might start with `-':\n"
+ " - %-*s Next argument is a domain, but more options may follow\n",
+ maxlopt+maxsopt+3, "<domain>");
+
+ fputs("\n"
+ "Query domains should always be quoted according to master file format.\n"
+ "\n"
+ "For binary options, --FOO and --no-FOO are opposites, as are\n"
+ "-X and +X. In each case the default is the one not listed.\n"
+ "Per query options stay set a particular way until they are reset,\n"
+ "whether they appear on the command line or on stdin.\n"
+ "All global options must preceed the first query domain.\n"
+ "\n"
+ "With -f, the input should be lines with either an option, possibly\n"
+ "with a value argument (separated from the option by a space if it's a long\n"
+ "option), or a domain (possibly preceded by a hyphen and a space to\n"
+ "distinguish it from an option).\n"
+ "\n"
+ "Output format is master file format without class or TTL by default:\n"
+ " [<owner>] [<ttl>] [<type>] <data>\n"
+ "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 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"
+ "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"
+ "the CNAME target; the CNAME indirection and error formats above are not used.\n"
+ "\n"
+ "Exit status:\n"
+ " 0 all went well\n"
+ " 1-6 at least one query failed with statustype:\n"
+ " 1 localfail )\n"
+ " 2 remotefail ) temporary errors\n"
+ " 3 tempfail __)_________________\n"
+ " 4 misconfig )\n"
+ " 5 misquery ) permanent errors\n"
+ " 6 permfail )\n"
+ " 10 system trouble\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"
+ "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) {
+ printusage();
+ if (fclose(stdout)) sysfail("finish writing output",errno);
+ exit(0);
+}
+
+typedef int comparer_type(const char **optp, const struct optioninfo *entry);
+
+static int oc_long(const char **optp, const struct optioninfo *entry) {
+ return entry->lopt && !strcmp(*optp,entry->lopt);
+}
+
+static int oc_short(const char **optp, const struct optioninfo *entry) {
+ const char *sopt;
+ int l;
+
+ sopt= entry->sopt;
+ if (!sopt) return 0;
+ l= strlen(sopt);
+ if (memcmp(*optp,sopt,l)) return 0;
+ (*optp) += l;
+ return 1;
+}
+
+static const struct optioninfo *find1(const char **optp,
+ const struct optioninfo *table,
+ comparer_type *comparer) {
+ for (;;) {
+ if (table->type == ot_end) return 0;
+ if (comparer(optp,table)) return table;
+ table++;
+ }
+}
+
+static const struct optioninfo *find(const char **optp,
+ 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,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); }
+
+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, const char *arg, int invert) {
+ switch (oip->type) {
+ 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:
+ if (invert) noninvert(oip);
+ oip->func(oip,arg);
+ return;
+ default:
+ abort();
+ }
+}
diff --git a/adns-0.6/client/adh-query.c b/adns-0.6/client/adh-query.c
new file mode 100644
index 0000000..bae71f4
--- /dev/null
+++ b/adns-0.6/client/adh-query.c
@@ -0,0 +1,274 @@
+/*
+ * adh-query.c
+ * - useful general-purpose resolver client program
+ * make queries and print answers
+ */
+/*
+ * 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 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)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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.
+ */
+
+#include "adnshost.h"
+
+adns_state ads;
+struct outstanding_list outstanding;
+
+static unsigned long idcounter;
+
+void ensure_adns_init(void) {
+ int r;
+
+ if (ads) return;
+
+ if (signal(SIGPIPE,SIG_IGN) == SIG_ERR) sysfail("ignore SIGPIPE",errno);
+ r= adns_init(&ads,
+ adns_if_noautosys|adns_if_nosigpipe |
+ (ov_env ? 0 : adns_if_noenv) |
+ ov_verbose,
+ 0);
+ if (r) sysfail("adns_init",r);
+
+ if (ov_format == fmt_default)
+ ov_format= ov_asynch ? fmt_asynch : fmt_simple;
+}
+
+static void prep_query(struct query_node **qun_r, int *quflags_r) {
+ struct query_node *qun;
+ char idbuf[20];
+
+ if (ov_pipe && !ads) usageerr("-f/--pipe not consistent with domains on command line");
+ ensure_adns_init();
+
+ qun= malloc(sizeof(*qun));
+ qun->pqfr= ov_pqfr;
+ if (ov_id) {
+ qun->id= xstrsave(ov_id);
+ } else {
+ sprintf(idbuf,"%lu",idcounter++);
+ idcounter &= 0x0fffffffflu;
+ qun->id= xstrsave(idbuf);
+ }
+
+ *quflags_r=
+ (ov_search ? adns_qf_search : 0) |
+ (ov_tcp ? adns_qf_usevc : 0) |
+ ((ov_pqfr.show_owner || ov_format == fmt_simple) ? adns_qf_owner : 0) |
+ (ov_qc_query ? adns_qf_quoteok_query : 0) |
+ (ov_qc_anshost ? adns_qf_quoteok_anshost : 0) |
+ (ov_qc_cname ? 0 : adns_qf_quoteok_cname) |
+ ov_cname,
+
+ *qun_r= qun;
+}
+
+void of_ptr(const struct optioninfo *oi, const char *arg) {
+ struct query_node *qun;
+ int quflags, r;
+ struct sockaddr_in sa;
+
+ memset(&sa,0,sizeof(sa));
+ sa.sin_family= AF_INET;
+ if (!inet_aton(arg,&sa.sin_addr)) usageerr("invalid IP address %s",arg);
+
+ prep_query(&qun,&quflags);
+ r= adns_submit_reverse(ads,
+ (struct sockaddr*)&sa,
+ ov_type == adns_r_none ? adns_r_ptr : ov_type,
+ quflags,
+ qun,
+ &qun->qu);
+ if (r) sysfail("adns_submit_reverse",r);
+
+ LIST_LINK_TAIL(outstanding,qun);
+}
+
+void query_do(const char *domain) {
+ struct query_node *qun;
+ int quflags, r;
+
+ prep_query(&qun,&quflags);
+ r= adns_submit(ads, domain,
+ ov_type == adns_r_none ? adns_r_addr : ov_type,
+ quflags,
+ qun,
+ &qun->qu);
+ if (r) sysfail("adns_submit",r);
+
+ LIST_LINK_TAIL(outstanding,qun);
+}
+
+static void dequeue_query(struct query_node *qun) {
+ LIST_UNLINK(outstanding,qun);
+ free(qun->id);
+ free(qun);
+}
+
+static void print_withspace(const char *str) {
+ if (printf("%s ", str) == EOF) outerr();
+}
+
+static void print_ttl(struct query_node *qun, adns_answer *answer) {
+ unsigned long ttl;
+ time_t now;
+
+ switch (qun->pqfr.ttl) {
+ case tm_none:
+ return;
+ case tm_rel:
+ if (time(&now) == (time_t)-1) sysfail("get current time",errno);
+ ttl= answer->expires < now ? 0 : answer->expires - now;
+ break;
+ case tm_abs:
+ ttl= answer->expires;
+ break;
+ default:
+ abort();
+ }
+ if (printf("%lu ",ttl) == EOF) outerr();
+}
+
+static void print_owner_ttl(struct query_node *qun, adns_answer *answer) {
+ if (qun->pqfr.show_owner) print_withspace(answer->owner);
+ print_ttl(qun,answer);
+}
+
+static void check_status(adns_status st) {
+ static const adns_status statuspoints[]= {
+ adns_s_ok,
+ adns_s_max_localfail, adns_s_max_remotefail, adns_s_max_tempfail,
+ adns_s_max_misconfig, adns_s_max_misquery
+ };
+
+ const adns_status *spp;
+ int minrcode;
+
+ for (minrcode=0, spp=statuspoints;
+ spp < statuspoints + (sizeof(statuspoints)/sizeof(statuspoints[0]));
+ spp++)
+ if (st > *spp) minrcode++;
+ if (rcode < minrcode) rcode= minrcode;
+}
+
+static void print_status(adns_status st, struct query_node *qun, adns_answer *answer) {
+ const char *statustypeabbrev, *statusabbrev, *statusstring;
+
+ statustypeabbrev= adns_errtypeabbrev(st);
+ statusabbrev= adns_errabbrev(st);
+ statusstring= adns_strerror(st);
+ assert(!strchr(statusstring,'"'));
+
+ if (printf("%s %d %s ", statustypeabbrev, st, statusabbrev)
+ == EOF) outerr();
+ print_owner_ttl(qun,answer);
+ if (qun->pqfr.show_cname)
+ print_withspace(answer->cname ? answer->cname : "$");
+ if (printf("\"%s\"\n", statusstring) == EOF) outerr();
+}
+
+static void print_dnsfail(adns_status st, struct query_node *qun, adns_answer *answer) {
+ int r;
+ const char *typename, *statusstring;
+ adns_status ist;
+
+ if (ov_format == fmt_inline) {
+ if (fputs("; failed ",stdout) == EOF) outerr();
+ print_status(st,qun,answer);
+ return;
+ }
+ assert(ov_format == fmt_simple);
+ if (st == adns_s_nxdomain) {
+ r= fprintf(stderr,"%s does not exist\n", answer->owner);
+ } else {
+ ist= adns_rr_info(answer->type, &typename, 0,0,0,0);
+ if (st == adns_s_nodata) {
+ r= fprintf(stderr,"%s has no %s record\n", answer->owner, typename);
+ } else {
+ statusstring= adns_strerror(st);
+ r= fprintf(stderr,"Error during DNS %s lookup for %s: %s\n",
+ typename, answer->owner, statusstring);
+ }
+ }
+ if (r == EOF) sysfail("write error message to stderr",errno);
+}
+
+void query_done(struct query_node *qun, adns_answer *answer) {
+ adns_status st, ist;
+ int rrn, nrrs;
+ const char *rrp, *realowner, *typename;
+ char *datastr;
+
+ st= answer->status;
+ nrrs= answer->nrrs;
+ if (ov_format == fmt_asynch) {
+ check_status(st);
+ if (printf("%s %d ", qun->id, nrrs) == EOF) outerr();
+ print_status(st,qun,answer);
+ } else {
+ if (qun->pqfr.show_cname && answer->cname) {
+ print_owner_ttl(qun,answer);
+ if (qun->pqfr.show_type) print_withspace("CNAME");
+ if (printf("%s\n", answer->cname) == EOF) outerr();
+ }
+ if (st) {
+ check_status(st);
+ print_dnsfail(st,qun,answer);
+ }
+ }
+ if (qun->pqfr.show_owner) {
+ realowner= answer->cname ? answer->cname : answer->owner;
+ assert(realowner);
+ } else {
+ realowner= 0;
+ }
+ if (nrrs) {
+ for (rrn=0, rrp = answer->rrs.untyped;
+ rrn < nrrs;
+ rrn++, rrp += answer->rrsz) {
+ if (realowner) print_withspace(realowner);
+ print_ttl(qun,answer);
+ ist= adns_rr_info(answer->type, &typename, 0, 0, rrp, &datastr);
+ if (ist == adns_s_nomemory) sysfail("adns_rr_info failed",ENOMEM);
+ assert(!ist);
+ if (qun->pqfr.show_type) print_withspace(typename);
+ if (printf("%s\n",datastr) == EOF) outerr();
+ free(datastr);
+ }
+ }
+ if (fflush(stdout)) outerr();
+ free(answer);
+ dequeue_query(qun);
+}
+
+void of_asynch_id(const struct optioninfo *oi, const char *arg) {
+ free(ov_id);
+ ov_id= xstrsave(arg);
+}
+
+void of_cancel_id(const struct optioninfo *oi, const char *arg) {
+ struct query_node *qun;
+
+ for (qun= outstanding.head;
+ qun && strcmp(qun->id,arg);
+ qun= qun->next);
+ if (!qun) return;
+ adns_cancel(qun->qu);
+ dequeue_query(qun);
+}
diff --git a/adns-0.6/client/adnshost.h b/adns-0.6/client/adnshost.h
new file mode 100644
index 0000000..8b459b3
--- /dev/null
+++ b/adns-0.6/client/adnshost.h
@@ -0,0 +1,118 @@
+/*
+ * adnshost.h
+ * - useful general-purpose resolver client program, header file
+ */
+/*
+ * 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 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)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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.
+ */
+
+#ifndef ADNSHOST_H_INCLUDED
+#define ADNSHOST_H_INCLUDED
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "config.h"
+#include "adns.h"
+#include "dlist.h"
+
+/* declarations related to option processing */
+
+struct optioninfo;
+typedef void optfunc(const struct optioninfo *oi, const char *arg);
+
+struct optioninfo {
+ enum oi_type {
+ ot_end, ot_desconly,
+ ot_flag, ot_value, ot_func, ot_funcarg
+ } type;
+ const char *desc;
+ const char *sopt, *lopt;
+ int *storep, value;
+ optfunc *func;
+ const char *argdesc;
+};
+
+enum ttlmode { tm_none, tm_rel, tm_abs };
+enum outputformat { fmt_default, fmt_simple, fmt_inline, fmt_asynch };
+
+struct perqueryflags_remember {
+ int show_owner, show_type, show_cname;
+ int ttl;
+};
+
+extern int ov_env, ov_pipe, ov_asynch;
+extern int ov_verbose;
+extern adns_rrtype ov_type;
+extern int ov_search, ov_qc_query, ov_qc_anshost, ov_qc_cname;
+extern int ov_tcp, ov_cname, ov_format;
+extern char *ov_id;
+extern struct perqueryflags_remember ov_pqfr;
+
+extern optfunc of_help, of_type, of_ptr, of_asynch_id, of_cancel_id;
+
+const struct optioninfo *opt_findl(const char *opt);
+const struct optioninfo *opt_finds(const char **optp);
+void opt_do(const struct optioninfo *oip, const char *arg, int invert);
+
+/* declarations related to query processing */
+
+struct query_node {
+ struct query_node *next, *back;
+ struct perqueryflags_remember pqfr;
+ char *id;
+ adns_query qu;
+};
+
+extern adns_state ads;
+extern struct outstanding_list { struct query_node *head, *tail; } outstanding;
+
+void ensure_adns_init(void);
+void query_do(const char *domain);
+void query_done(struct query_node *qun, adns_answer *answer);
+
+void of_asynch_id(const struct optioninfo *oi, const char *arg);
+void of_cancel_id(const struct optioninfo *oi, const char *arg);
+
+/* declarations related to main program and useful utility functions */
+
+void sysfail(const char *what, int errnoval) NONRETURNING;
+void usageerr(const char *what, ...) NONRETURNPRINTFFORMAT(1,2);
+void outerr(void) NONRETURNING;
+
+void *xmalloc(size_t sz);
+char *xstrsave(const char *str);
+
+extern int rcode;
+
+#endif
diff --git a/adns-0.6/client/adnslogres.c b/adns-0.6/client/adnslogres.c
new file mode 100644
index 0000000..c732823
--- /dev/null
+++ b/adns-0.6/client/adnslogres.c
@@ -0,0 +1,239 @@
+/*
+ * adnslogres.c
+ * - a replacement for the Apache logresolve program using adns
+ */
+/*
+ * This file is
+ * Copyright (C) 1999 Tony Finch <dot@dotat.at>
+ * Copyright (C) 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 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)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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.
+ *
+ * This version was originally supplied by Tony Finch, but has been
+ * modified by Ian Jackson as it was incorporated into adns.
+ */
+
+static const char * const cvsid =
+ "$Id: adnslogres.c,v 1.1.1.1 2000-02-16 17:32:28 sdyoung Exp $";
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include "adns.h"
+
+/* maximum number of concurrent DNS queries */
+#define MAXPENDING 1000
+
+/* maximum length of a line */
+#define MAXLINE 1024
+
+/* option flags */
+#define OPT_DEBUG 1
+#define OPT_POLL 2
+
+static const char *progname;
+
+#define msg(fmt, args...) fprintf(stderr, "%s: " fmt "\n", progname, ##args)
+
+static void aargh(const char *cause) {
+ const char *why = strerror(errno);
+ if (!why) why = "Unknown error";
+ msg("%s: %s (%d)", cause, why, errno);
+ exit(1);
+}
+
+/*
+ * Parse the IP address and convert to a reverse domain name.
+ */
+static char *ipaddr2domain(char *start, char **addr, char **rest) {
+ static char buf[30]; /* "123.123.123.123.in-addr.arpa.\0" */
+ char *ptrs[5];
+ int i;
+
+ ptrs[0]= start;
+retry:
+ while (!isdigit(*ptrs[0]))
+ if (!*ptrs[0]++) {
+ strcpy(buf, "invalid.");
+ *addr= *rest= NULL;
+ return buf;
+ }
+ for (i= 1; i < 5; i++) {
+ ptrs[i]= ptrs[i-1];
+ while (isdigit(*ptrs[i]++));
+ if ((i == 4 && !isspace(ptrs[i][-1])) ||
+ (i != 4 && ptrs[i][-1] != '.') ||
+ (ptrs[i]-ptrs[i-1] > 4)) {
+ ptrs[0]= ptrs[i]-1;
+ goto retry;
+ }
+ }
+ sprintf(buf, "%.*s.%.*s.%.*s.%.*s.in-addr.arpa.",
+ ptrs[4]-ptrs[3]-1, ptrs[3],
+ ptrs[3]-ptrs[2]-1, ptrs[2],
+ ptrs[2]-ptrs[1]-1, ptrs[1],
+ ptrs[1]-ptrs[0]-1, ptrs[0]);
+ *addr= ptrs[0];
+ *rest= ptrs[4]-1;
+ return buf;
+}
+
+static void printline(FILE *outf, char *start, char *addr, char *rest, char *domain) {
+ if (domain)
+ fprintf(outf, "%.*s%s%s", addr - start, start, domain, rest);
+ else
+ fputs(start, outf);
+ if (ferror(outf)) aargh("write output");
+}
+
+typedef struct logline {
+ struct logline *next;
+ char *start, *addr, *rest;
+ adns_query query;
+} logline;
+
+static logline *readline(FILE *inf, adns_state adns, int opts) {
+ static char buf[MAXLINE];
+ char *str;
+ logline *line;
+
+ if (fgets(buf, MAXLINE, inf)) {
+ str= malloc(sizeof(*line) + strlen(buf) + 1);
+ if (!str) aargh("malloc");
+ line= (logline*)str;
+ line->next= NULL;
+ line->start= str+sizeof(logline);
+ strcpy(line->start, buf);
+ str= ipaddr2domain(line->start, &line->addr, &line->rest);
+ if (opts & OPT_DEBUG)
+ msg("submitting %.*s -> %s", line->rest-line->addr, line->addr, str);
+ if (adns_submit(adns, str, adns_r_ptr,
+ adns_qf_quoteok_cname|adns_qf_cname_loose,
+ NULL, &line->query))
+ aargh("adns_submit");
+ return line;
+ }
+ if (!feof(inf))
+ aargh("fgets");
+ return NULL;
+}
+
+static void proclog(FILE *inf, FILE *outf, int opts) {
+ int eof, err, len;
+ adns_state adns;
+ adns_answer *answer;
+ logline *head, *tail, *line;
+
+ errno= adns_init(&adns, (opts & OPT_DEBUG) ? adns_if_debug : 0, 0);
+ if (errno) aargh("adns_init");
+ head= tail= readline(inf, adns, opts);
+ len= 1; eof= 0;
+ while (head) {
+ if (opts & OPT_DEBUG)
+ msg("%d in queue; checking %.*s", len,
+ head->rest-head->addr, head->addr);
+ if (eof || len > MAXPENDING)
+ if (opts & OPT_POLL)
+ err= adns_wait_poll(adns, &head->query, &answer, NULL);
+ else
+ err= adns_wait(adns, &head->query, &answer, NULL);
+ else
+ err= adns_check(adns, &head->query, &answer, NULL);
+ if (err != EAGAIN) {
+ printline(outf, head->start, head->addr, head->rest,
+ answer->status == adns_s_ok ? *answer->rrs.str : NULL);
+ line= head; head= head->next;
+ free(line); free(answer);
+ len--;
+ }
+ if (!eof) {
+ line= readline(inf, adns, opts);
+ if (!line)
+ eof= 1;
+ else {
+ if (!head)
+ head= line;
+ else
+ tail->next= line;
+ tail= line;
+ len++;
+ }
+ }
+ }
+ adns_finish(adns);
+}
+
+static void usage(void) {
+ fprintf(stderr, "usage: %s [-d] [-p] [logfile]\n", progname);
+ exit(1);
+}
+
+int main(int argc, char *argv[]) {
+ int c, opts;
+ FILE *inf;
+
+ progname= strrchr(*argv, '/');
+ if (progname)
+ progname++;
+ else
+ progname= *argv;
+ opts= 0;
+
+ while ((c= getopt(argc, argv, "dp")) != -1)
+ switch (c) {
+ case 'd':
+ opts|= OPT_DEBUG;
+ break;
+ case 'p':
+ opts|= OPT_POLL;
+ break;
+ default:
+ usage();
+ }
+
+ argc-= optind;
+ argv+= optind;
+
+ inf= NULL;
+ if (argc == 0)
+ inf= stdin;
+ else if (argc == 1)
+ inf= fopen(*argv, "r");
+ else
+ usage();
+
+ if (!inf)
+ aargh("couldn't open input");
+
+ proclog(inf, stdout, opts);
+
+ if (fclose(inf))
+ aargh("fclose input");
+ if (fclose(stdout))
+ aargh("fclose output");
+
+ return 0;
+}
diff --git a/adns-0.6/client/adnsresfilter.c b/adns-0.6/client/adnsresfilter.c
new file mode 100644
index 0000000..f265773
--- /dev/null
+++ b/adns-0.6/client/adnsresfilter.c
@@ -0,0 +1,454 @@
+/*
+ * adnsresfilter.c
+ * - filter which does resolving, not part of the library
+ */
+/*
+ * This file is
+ * Copyright (C) 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 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)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <search.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include <sys/fcntl.h>
+
+#include "adns.h"
+#include "config.h"
+#include "dlist.h"
+#include "tvarith.h"
+
+struct outqueuenode {
+ struct outqueuenode *next, *back;
+ void *buffer;
+ char *textp;
+ int textlen;
+ struct timeval printbefore;
+ struct treething *addr;
+};
+
+static int bracket, forever, address;
+static unsigned long timeout=100;
+static adns_rrtype rrt= adns_r_ptr;
+
+static int outblocked, inputeof;
+static struct { struct outqueuenode *head, *tail; } outqueue;
+static int peroutqueuenode, outqueuelen;
+
+static struct sockaddr_in sa;
+static adns_state ads;
+
+static char addrtextbuf[14];
+static int cbyte, inbyte, inbuf;
+static unsigned char bytes[4];
+static struct timeval printbefore;
+
+struct treething {
+ unsigned char bytes[4];
+ adns_query qu;
+ adns_answer *ans;
+};
+
+static struct treething *newthing;
+static void *treeroot;
+
+static int nonblock(int fd, int isnonblock) {
+ int r;
+
+ r= fcntl(fd,F_GETFL);
+ if (r==-1) return -1;
+ r= fcntl(fd,F_SETFL, isnonblock ? r|O_NONBLOCK : r&~O_NONBLOCK);
+ if (r==-1) return -1;
+ return 0;
+}
+
+static void quit(int exitstatus) NONRETURNING;
+static void quit(int exitstatus) {
+ nonblock(0,0);
+ nonblock(1,0);
+ exit(exitstatus);
+}
+
+static void sysfail(const char *what) NONRETURNING;
+static void sysfail(const char *what) {
+ fprintf(stderr,"adnsresfilter: system call failed: %s: %s\n",what,strerror(errno));
+ quit(2);
+}
+
+static void *xmalloc(size_t sz) {
+ void *r;
+ r= malloc(sz); if (r) return r;
+ sysfail("malloc");
+}
+
+static void outputerr(void) NONRETURNING;
+static void outputerr(void) { sysfail("write to stdout"); }
+
+static void usage(void) {
+ if (printf("usage: adnsresfilter [<options ...>]\n"
+ " adnsresfilter -h|--help\n"
+ "options: -t<milliseconds>|--timeout <milliseconds>\n"
+ " -w|--wait (always wait for queries to time out or fail)\n"
+ " -b|--brackets (require [...] around IP addresses)\n"
+ " -a|--address (always include [address] in output)\n"
+ " -u|--unchecked (do not forward map for checking)\n"
+ "Timeout is the maximum amount to delay any particular bit of output for.\n"
+ "Lookups will go on in the background. Default timeout = 100 (ms).\n")
+ == EOF) outputerr();
+}
+
+static void usageerr(const char *why) NONRETURNING;
+static void usageerr(const char *why) {
+ fprintf(stderr,"adnsresfilter: bad usage: %s\n",why);
+ usage();
+ quit(1);
+}
+
+static void adnsfail(const char *what, int e) NONRETURNING;
+static void adnsfail(const char *what, int e) {
+ fprintf(stderr,"adnsresfilter: adns call failed: %s: %s\n",what,strerror(e));
+ quit(2);
+}
+
+static void settimeout(const char *arg) {
+ char *ep;
+ timeout= strtoul(arg,&ep,0);
+ if (*ep) usageerr("invalid timeout");
+}
+
+static void parseargs(const char *const *argv) {
+ const char *arg;
+ int c;
+
+ while ((arg= *++argv)) {
+ if (arg[0] != '-') usageerr("no non-option arguments are allowed");
+ if (arg[1] == '-') {
+ if (!strcmp(arg,"--brackets")) {
+ bracket= 1;
+ } else if (!strcmp(arg,"--unchecked")) {
+ rrt= adns_r_ptr_raw;
+ } else if (!strcmp(arg,"--wait")) {
+ forever= 1;
+ } else if (!strcmp(arg,"--address")) {
+ address= 1;
+ } else if (!strcmp(arg,"--help")) {
+ usage(); quit(0);
+ } else if (!strcmp(arg,"--timeout")) {
+ if (!(arg= *++argv)) usageerr("--timeout needs a value");
+ settimeout(arg);
+ forever= 0;
+ } else {
+ usageerr("unknown long option");
+ }
+ } else {
+ while ((c= *++arg)) {
+ switch (c) {
+ case 'b':
+ bracket= 1;
+ break;
+ case 'u':
+ rrt= adns_r_ptr_raw;
+ break;
+ case 'w':
+ forever= 1;
+ break;
+ case 'a':
+ address= 1;
+ break;
+ case 'h':
+ usage();
+ quit(0);
+ case 't':
+ if (*++arg) settimeout(arg);
+ else if ((arg= *++argv)) settimeout(arg);
+ else usageerr("-t needs a value");
+ forever= 0;
+ arg= "\0";
+ break;
+ default:
+ usageerr("unknown short option");
+ }
+ }
+ }
+ }
+}
+
+static void queueoutchar(int c) {
+ struct outqueuenode *entry;
+
+ entry= outqueue.tail;
+ if (!entry || entry->addr || entry->textlen >= peroutqueuenode) {
+ peroutqueuenode= !peroutqueuenode || !entry || entry->addr ? 128 :
+ peroutqueuenode >= 1024 ? 4096 : peroutqueuenode<<2;
+ entry= xmalloc(sizeof(*entry));
+ entry->buffer= xmalloc(peroutqueuenode);
+ entry->textp= entry->buffer;
+ entry->textlen= 0;
+ entry->addr= 0;
+ LIST_LINK_TAIL(outqueue,entry);
+ outqueuelen++;
+ }
+ entry->textp[entry->textlen++]= c;
+}
+
+static void queueoutstr(const char *str, int len) {
+ while (len-- > 0) queueoutchar(*str++);
+}
+
+static void writestdout(struct outqueuenode *entry) {
+ int r;
+
+ while (entry->textlen) {
+ r= write(1, entry->textp, entry->textlen);
+ if (r < 0) {
+ if (errno == EINTR) continue;
+ if (errno == EAGAIN) { outblocked= 1; break; }
+ sysfail("write stdout");
+ }
+ assert(r <= entry->textlen);
+ entry->textp += r;
+ entry->textlen -= r;
+ }
+ if (!entry->textlen) {
+ LIST_UNLINK(outqueue,entry);
+ free(entry->buffer);
+ free(entry);
+ outqueuelen--;
+ }
+}
+
+static void replacetextwithname(struct outqueuenode *entry) {
+ char *name, *newbuf;
+ int namelen, newlen;
+
+ name= entry->addr->ans->rrs.str[0];
+ namelen= strlen(name);
+ if (!address) {
+ free(entry->buffer);
+ entry->buffer= 0;
+ entry->textp= name;
+ entry->textlen= namelen;
+ } else {
+ newlen= entry->textlen + namelen + (bracket ? 0 : 2);
+ newbuf= xmalloc(newlen + 1);
+ sprintf(newbuf, bracket ? "%s%.*s" : "%s[%.*s]", name, entry->textlen, entry->textp);
+ free(entry->buffer);
+ entry->buffer= entry->textp= newbuf;
+ entry->textlen= newlen;
+ }
+}
+
+static void checkadnsqueries(void) {
+ adns_query qu;
+ adns_answer *ans;
+ void *context;
+ struct treething *foundthing;
+ int r;
+
+ for (;;) {
+ qu= 0; context= 0; ans= 0;
+ r= adns_check(ads,&qu,&ans,&context);
+ if (r == ESRCH || r == EAGAIN) break;
+ assert(!r);
+ foundthing= context;
+ foundthing->ans= ans;
+ foundthing->qu= 0;
+ }
+}
+
+static void restartbuf(void) {
+ if (inbuf>0) queueoutstr(addrtextbuf,inbuf);
+ inbuf= 0;
+}
+
+static int comparer(const void *a, const void *b) {
+ return memcmp(a,b,4);
+}
+
+static void procaddr(void) {
+ struct treething *foundthing;
+ void **searchfound;
+ struct outqueuenode *entry;
+ int r;
+
+ if (!newthing) {
+ newthing= xmalloc(sizeof(struct treething));
+ newthing->qu= 0;
+ newthing->ans= 0;
+ }
+
+ memcpy(newthing->bytes,bytes,4);
+ searchfound= tsearch(newthing,&treeroot,comparer);
+ if (!searchfound) sysfail("tsearch");
+ foundthing= *searchfound;
+
+ if (foundthing == newthing) {
+ newthing= 0;
+ memcpy(&sa.sin_addr,bytes,4);
+ r= adns_submit_reverse(ads, (const struct sockaddr*)&sa,
+ rrt,0,foundthing,&foundthing->qu);
+ if (r) adnsfail("submit",r);
+ }
+ entry= xmalloc(sizeof(*entry));
+ entry->buffer= xmalloc(inbuf);
+ entry->textp= entry->buffer;
+ memcpy(entry->textp,addrtextbuf,inbuf);
+ entry->textlen= inbuf;
+ entry->addr= foundthing;
+ entry->printbefore= printbefore;
+ LIST_LINK_TAIL(outqueue,entry);
+ outqueuelen++;
+ inbuf= 0;
+ cbyte= -1;
+}
+
+static void startaddr(void) {
+ bytes[cbyte=0]= 0;
+ inbyte= 0;
+}
+
+static void readstdin(void) {
+ char readbuf[512], *p;
+ int r, c, nbyte;
+
+ while ((r= read(0,readbuf,sizeof(readbuf))) <= 0) {
+ if (r == 0) { inputeof= 1; return; }
+ if (r == EAGAIN) return;
+ if (r != EINTR) sysfail("read stdin");
+ }
+ for (p=readbuf; r>0; r--,p++) {
+ c= *p;
+ if (cbyte==-1 && bracket && c=='[') {
+ addrtextbuf[inbuf++]= c;
+ startaddr();
+ } else if (cbyte==-1 && !bracket && !isalnum(c)) {
+ queueoutchar(c);
+ startaddr();
+ } else if (cbyte>=0 && inbyte<3 && c>='0' && c<='9' &&
+ (nbyte= bytes[cbyte]*10 + (c-'0')) <= 255) {
+ bytes[cbyte]= nbyte;
+ addrtextbuf[inbuf++]= c;
+ inbyte++;
+ } else if (cbyte>=0 && cbyte<3 && inbyte>0 && c=='.') {
+ bytes[++cbyte]= 0;
+ addrtextbuf[inbuf++]= c;
+ inbyte= 0;
+ } else if (cbyte==3 && inbyte>0 && bracket && c==']') {
+ addrtextbuf[inbuf++]= c;
+ procaddr();
+ } else if (cbyte==3 && inbyte>0 && !bracket && !isalnum(c)) {
+ procaddr();
+ queueoutchar(c);
+ startaddr();
+ } else {
+ restartbuf();
+ queueoutchar(c);
+ cbyte= -1;
+ if (!bracket && !isalnum(c)) startaddr();
+ }
+ }
+ if (cbyte==3 && inbyte>0 && !bracket) procaddr();
+}
+
+static void startup(void) {
+ int r;
+
+ if (nonblock(0,1)) sysfail("set stdin to nonblocking mode");
+ if (nonblock(1,1)) sysfail("set stdout to nonblocking mode");
+ memset(&sa,0,sizeof(sa));
+ sa.sin_family= AF_INET;
+ r= adns_init(&ads,0,0); if (r) adnsfail("init",r);
+ cbyte= -1;
+ inbyte= -1;
+ inbuf= 0;
+ if (!bracket) startaddr();
+}
+
+int main(int argc, const char *const *argv) {
+ int r, maxfd;
+ fd_set readfds, writefds, exceptfds;
+ struct outqueuenode *entry;
+ struct timeval *tv, tvbuf, now;
+
+ parseargs(argv);
+ startup();
+
+ while (!inputeof || outqueue.head) {
+ maxfd= 2;
+ tv= 0;
+ FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds);
+ if ((entry= outqueue.head) && !outblocked) {
+ if (!entry->addr) {
+ writestdout(entry);
+ continue;
+ }
+ if (entry->addr->ans) {
+ if (entry->addr->ans->nrrs)
+ replacetextwithname(entry);
+ entry->addr= 0;
+ continue;
+ }
+ r= gettimeofday(&now,0); if (r) sysfail("gettimeofday");
+ if (forever) {
+ tv= 0;
+ } else if (!timercmp(&now,&entry->printbefore,<)) {
+ entry->addr= 0;
+ continue;
+ } else {
+ tvbuf.tv_sec= entry->printbefore.tv_sec - now.tv_sec - 1;
+ tvbuf.tv_usec= entry->printbefore.tv_usec - now.tv_usec + 1000000;
+ tvbuf.tv_sec += tvbuf.tv_usec / 1000000;
+ tvbuf.tv_usec %= 1000000;
+ tv= &tvbuf;
+ }
+ adns_beforeselect(ads,&maxfd,&readfds,&writefds,&exceptfds,
+ &tv,&tvbuf,&now);
+ }
+ if (outblocked) FD_SET(1,&writefds);
+ if (!inputeof && outqueuelen<1024) FD_SET(0,&readfds);
+
+ r= select(maxfd,&readfds,&writefds,&exceptfds,tv);
+ if (r < 0) { if (r == EINTR) continue; else sysfail("select"); }
+
+ r= gettimeofday(&now,0); if (r) sysfail("gettimeofday");
+ adns_afterselect(ads,maxfd,&readfds,&writefds,&exceptfds,&now);
+ checkadnsqueries();
+
+ if (FD_ISSET(0,&readfds)) {
+ if (!forever) {
+ printbefore= now;
+ timevaladd(&printbefore,timeout);
+ }
+ readstdin();
+ } else if (FD_ISSET(1,&writefds)) {
+ outblocked= 0;
+ }
+ }
+ if (nonblock(0,0)) sysfail("un-nonblock stdin");
+ if (nonblock(1,0)) sysfail("un-nonblock stdout");
+ if (ferror(stdin) || fclose(stdin)) sysfail("read stdin");
+ if (fclose(stdout)) sysfail("close stdout");
+ exit(0);
+}
diff --git a/adns-0.6/client/adnstest.c b/adns-0.6/client/adnstest.c
new file mode 100644
index 0000000..2460dbf
--- /dev/null
+++ b/adns-0.6/client/adnstest.c
@@ -0,0 +1,337 @@
+/*
+ * adnstest.c
+ * - simple test program, not part of the library
+ */
+/*
+ * 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 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)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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.
+ */
+
+#include <stdio.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "adns.h"
+
+#include "config.h"
+
+#ifndef OUTPUTSTREAM
+# define OUTPUTSTREAM stdout
+#endif
+
+struct myctx {
+ adns_query qu;
+ int doneyet, found;
+ const char *fdom;
+};
+
+static struct myctx *mcs;
+static adns_state ads;
+static adns_rrtype *types_a;
+
+static void quitnow(int rc) NONRETURNING;
+static void quitnow(int rc) {
+ free(mcs);
+ free(types_a);
+ if (ads) adns_finish(ads);
+
+ exit(rc);
+}
+
+#ifndef HAVE_POLL
+#undef poll
+int poll(struct pollfd *ufds, int nfds, int timeout) {
+ fputs("poll(2) not supported on this system\n",stderr);
+ quitnow(5);
+}
+#define adns_beforepoll(a,b,c,d,e) 0
+#define adns_afterpoll(a,b,c,d) 0
+#endif
+
+static void failure_status(const char *what, adns_status st) NONRETURNING;
+static void failure_status(const char *what, adns_status st) {
+ fprintf(stderr,"adns failure: %s: %s\n",what,adns_strerror(st));
+ quitnow(2);
+}
+
+static void failure_errno(const char *what, int errnoval) NONRETURNING;
+static void failure_errno(const char *what, int errnoval) {
+ fprintf(stderr,"adns failure: %s: errno=%d\n",what,errnoval);
+ quitnow(2);
+}
+
+static void usageerr(const char *why) NONRETURNING;
+static void usageerr(const char *why) {
+ fprintf(stderr,
+ "bad usage: %s\n"
+ "usage: adnstest [-<initflagsnum>[,<owninitflags>]] [/<initstring>]\n"
+ " [ :<typenum>,... ]\n"
+ " [ [<queryflagsnum>[,<ownqueryflags>]/]<domain> ... ]\n"
+ "initflags: p use poll(2) instead of select(2)\n"
+ " s use adns_wait with specified query, instead of 0\n"
+ "queryflags: a print status abbrevs instead of strings\n"
+ "exit status: 0 ok (though some queries may have failed)\n"
+ " 1 used by test harness to indicate test failed\n"
+ " 2 unable to submit or init or some such\n"
+ " 3 unexpected failure\n"
+ " 4 usage error\n"
+ " 5 operation not supported on this system\n",
+ why);
+ quitnow(4);
+}
+
+static const adns_rrtype defaulttypes[]= {
+ adns_r_a,
+ adns_r_ns_raw,
+ adns_r_cname,
+ adns_r_soa_raw,
+ adns_r_ptr_raw,
+ adns_r_hinfo,
+ adns_r_mx_raw,
+ adns_r_txt,
+ adns_r_rp_raw,
+
+ adns_r_addr,
+ adns_r_ns,
+ adns_r_ptr,
+ adns_r_mx,
+
+ adns_r_soa,
+ adns_r_rp,
+
+ adns_r_none
+};
+
+static void dumptype(adns_status ri, const char *rrtn, const char *fmtn) {
+ fprintf(stdout, "%s(%s)%s%s",
+ ri ? "?" : rrtn, ri ? "?" : fmtn ? fmtn : "-",
+ ri ? " " : "", ri ? adns_strerror(ri) : "");
+}
+
+static void fdom_split(const char *fdom, const char **dom_r, int *qf_r,
+ char *ownflags, int ownflags_l) {
+ int qf;
+ char *ep;
+
+ qf= strtoul(fdom,&ep,0);
+ if (*ep == ',' && strchr(ep,'/')) {
+ ep++;
+ while (*ep != '/') {
+ if (--ownflags_l <= 0) { fputs("too many flags\n",stderr); quitnow(3); }
+ *ownflags++= *ep++;
+ }
+ }
+ if (*ep != '/') { *dom_r= fdom; *qf_r= 0; }
+ else { *dom_r= ep+1; *qf_r= qf; }
+ *ownflags= 0;
+}
+
+static int consistsof(const char *string, const char *accept) {
+ return strspn(string,accept) == strlen(string);
+}
+
+int main(int argc, char *const *argv) {
+ adns_query qu;
+ struct myctx *mc, *mcw;
+ void *mcr;
+ adns_answer *ans;
+ const char *initstring, *rrtn, *fmtn;
+ const char *const *fdomlist, *domain;
+ char *show, *cp;
+ int len, i, qc, qi, tc, ti, ch, qflags, initflagsnum;
+ adns_status ri;
+ int r;
+ const adns_rrtype *types;
+ struct timeval now;
+ char ownflags[10];
+ char *ep;
+ const char *initflags, *owninitflags;
+
+ if (argv[0] && argv[1] && argv[1][0] == '-') {
+ initflags= argv[1]+1;
+ argv++;
+ } else {
+ initflags= "";
+ }
+ if (argv[0] && argv[1] && argv[1][0] == '/') {
+ initstring= argv[1]+1;
+ argv++;
+ } else {
+ initstring= 0;
+ }
+
+ initflagsnum= strtoul(initflags,&ep,0);
+ if (*ep == ',') {
+ owninitflags= ep+1;
+ if (!consistsof(owninitflags,"ps")) usageerr("unknown owninitflag");
+ } else if (!*ep) {
+ owninitflags= "";
+ } else {
+ usageerr("bad <initflagsnum>[,<owninitflags>]");
+ }
+
+ if (argv[0] && argv[1] && argv[1][0] == ':') {
+ for (cp= argv[1]+1, tc=1; (ch= *cp); cp++)
+ if (ch==',') tc++;
+ types_a= malloc(sizeof(*types_a)*(tc+1));
+ if (!types_a) { perror("malloc types"); quitnow(3); }
+ for (cp= argv[1]+1, ti=0; ti<tc; ti++) {
+ types_a[ti]= strtoul(cp,&cp,10);
+ if ((ch= *cp)) {
+ if (ch != ',') usageerr("unexpected char (not comma) in or between types");
+ cp++;
+ }
+ }
+ types_a[ti]= adns_r_none;
+ types= types_a;
+ argv++;
+ } else {
+ types_a= 0;
+ types= defaulttypes;
+ }
+
+ if (!(argv[0] && argv[1])) usageerr("no query domains supplied");
+ fdomlist= (const char *const*)argv+1;
+
+ for (qc=0; fdomlist[qc]; qc++);
+ for (tc=0; types[tc] != adns_r_none; tc++);
+ mcs= malloc(tc ? sizeof(*mcs)*qc*tc : 1);
+ if (!mcs) { perror("malloc mcs"); quitnow(3); }
+
+ if (initstring) {
+ r= adns_init_strcfg(&ads,
+ (adns_if_debug|adns_if_noautosys|adns_if_checkc_freq)
+ ^initflagsnum,
+ stdout,initstring);
+ } else {
+ r= adns_init(&ads,
+ (adns_if_debug|adns_if_noautosys)^initflagsnum,
+ 0);
+ }
+ if (r) failure_errno("init",r);
+
+ for (qi=0; qi<qc; qi++) {
+ fdom_split(fdomlist[qi],&domain,&qflags,ownflags,sizeof(ownflags));
+ if (!consistsof(ownflags,"a")) usageerr("unknown ownqueryflag");
+ for (ti=0; ti<tc; ti++) {
+ mc= &mcs[qi*tc+ti];
+ mc->doneyet= 0;
+ mc->fdom= fdomlist[qi];
+
+ fprintf(stdout,"%s flags %d type %d",domain,qflags,types[ti]);
+ r= adns_submit(ads,domain,types[ti],qflags,mc,&mc->qu);
+ if (r == ENOSYS) {
+ fprintf(stdout," not implemented\n");
+ mc->qu= 0;
+ mc->doneyet= 1;
+ } else if (r) {
+ failure_errno("submit",r);
+ } else {
+ ri= adns_rr_info(types[ti], &rrtn,&fmtn,0, 0,0);
+ putc(' ',stdout);
+ dumptype(ri,rrtn,fmtn);
+ fprintf(stdout," submitted\n");
+ }
+ }
+ }
+
+ for (;;) {
+ for (qi=0; qi<qc; qi++) {
+ for (ti=0; ti<tc; ti++) {
+ mc= &mcs[qi*tc+ti];
+ mc->found= 0;
+ }
+ }
+ for (adns_forallqueries_begin(ads);
+ (qu= adns_forallqueries_next(ads,&mcr));
+ ) {
+ mc= mcr;
+ assert(qu == mc->qu);
+ assert(!mc->doneyet);
+ mc->found= 1;
+ }
+ mcw= 0;
+ for (qi=0; qi<qc; qi++) {
+ for (ti=0; ti<tc; ti++) {
+ mc= &mcs[qi*tc+ti];
+ if (mc->doneyet) continue;
+ assert(mc->found);
+ if (!mcw) mcw= mc;
+ }
+ }
+ if (!mcw) break;
+
+ if (strchr(owninitflags,'s')) {
+ qu= mcw->qu;
+ mc= mcw;
+ } else {
+ qu= 0;
+ mc= 0;
+ }
+
+ if (strchr(owninitflags,'p')) {
+ r= adns_wait_poll(ads,&qu,&ans,&mcr);
+ } else {
+ r= adns_wait(ads,&qu,&ans,&mcr);
+ }
+ if (r) failure_errno("wait/check",r);
+
+ if (mc) assert(mcr==mc);
+ else mc= mcr;
+ assert(qu==mc->qu);
+ assert(!mc->doneyet);
+
+ fdom_split(mc->fdom,&domain,&qflags,ownflags,sizeof(ownflags));
+
+ if (gettimeofday(&now,0)) { perror("gettimeofday"); quitnow(3); }
+
+ ri= adns_rr_info(ans->type, &rrtn,&fmtn,&len, 0,0);
+ fprintf(stdout, "%s flags %d type ",domain,qflags);
+ dumptype(ri,rrtn,fmtn);
+ fprintf(stdout, "%s%s: %s; nrrs=%d; cname=%s; owner=%s; ttl=%ld\n",
+ ownflags[0] ? " ownflags=" : "", ownflags,
+ strchr(ownflags,'a')
+ ? adns_errabbrev(ans->status)
+ : adns_strerror(ans->status),
+ ans->nrrs,
+ ans->cname ? ans->cname : "$",
+ ans->owner ? ans->owner : "$",
+ (long)ans->expires - (long)now.tv_sec);
+ if (ans->nrrs) {
+ assert(!ri);
+ for (i=0; i<ans->nrrs; i++) {
+ ri= adns_rr_info(ans->type, 0,0,0, ans->rrs.bytes + i*len, &show);
+ if (ri) failure_status("info",ri);
+ fprintf(stdout," %s\n",show);
+ free(show);
+ }
+ }
+ free(ans);
+
+ mc->doneyet= 1;
+ }
+
+ quitnow(0);
+}
diff --git a/adns-0.6/client/fanftest.c b/adns-0.6/client/fanftest.c
new file mode 100644
index 0000000..2051f28
--- /dev/null
+++ b/adns-0.6/client/fanftest.c
@@ -0,0 +1,85 @@
+/*
+ * fanftest.c
+ * - a small test program from Tony Finch
+ */
+/*
+ * This file is
+ * Copyright (C) 1999 Tony Finch <dot@dotat.at>
+ * Copyright (C) 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 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)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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.
+ *
+ * This version was originally supplied by Tony Finch, but has been
+ * modified by Ian Jackson as it was incorporated into adns.
+ */
+
+static const char * const cvsid =
+ "$Id: fanftest.c,v 1.1.1.1 2000-02-16 17:32:29 sdyoung Exp $";
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "adns.h"
+
+static const char *progname;
+
+static void aargh(const char *msg) {
+ fprintf(stderr, "%s: %s: %s (%d)\n", progname, msg,
+ strerror(errno) ? strerror(errno) : "Unknown error", errno);
+ exit(1);
+}
+
+int main(int argc, char *argv[]) {
+ adns_state adns;
+ adns_query query;
+ adns_answer *answer;
+
+ progname= strrchr(*argv, '/');
+ if (progname)
+ progname++;
+ else
+ progname= *argv;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s <domain>\n", progname);
+ exit(1);
+ }
+
+ errno= adns_init(&adns, adns_if_debug, 0);
+ if (errno) aargh("adns_init");
+
+ errno= adns_submit(adns, argv[1], adns_r_ptr,
+ adns_qf_quoteok_cname|adns_qf_cname_loose,
+ NULL, &query);
+ if (errno) aargh("adns_submit");
+
+ errno= adns_wait(adns, &query, &answer, NULL);
+ if (errno) aargh("adns_init");
+
+ printf("%s\n", answer->status == adns_s_ok ? *answer->rrs.str : "dunno");
+
+ adns_finish(adns);
+
+ return 0;
+}
diff --git a/adns-0.6/client/x.gdb b/adns-0.6/client/x.gdb
new file mode 100644
index 0000000..2ee7597
--- /dev/null
+++ b/adns-0.6/client/x.gdb
@@ -0,0 +1,2 @@
+file adnsresfilter_s
+set args <testinput -t2000