chiark / gitweb /
+ * Better control of adnshost output and error messages (new -F options).
authorian <ian>
Fri, 15 Oct 1999 17:55:45 +0000 (17:55 +0000)
committerian <ian>
Fri, 15 Oct 1999 17:55:45 +0000 (17:55 +0000)
@@ -1,4 +1,4 @@
-adns (0.6) unstable; urgency=medium
+adns (0.6) unstable; urgency=high

   Bugfixes:
   * Do not fail assertion if _qf_owner, _qf_search, domain ends in `.'.
@@ -12,6 +12,7 @@
   General improvements
   * New fanftest test program from Tony Finch.
   * New adns_if_logpid option (functionality suggested by Tony Finch).
+  * Better control of adnshost output and error messages (new -F options).

  --

changelog
client/adh-opts.c
client/adh-query.c
client/adnshost.h

index ed6e54c56ff5ca9d1c80d74ba97c41d5a286cd18..0824c4ea7d14ca110875e9eacf2e281c32ce4020 100644 (file)
--- a/changelog
+++ b/changelog
@@ -1,4 +1,4 @@
-adns (0.6) unstable; urgency=medium
+adns (0.6) unstable; urgency=high
 
   Bugfixes:
   * Do not fail assertion if _qf_owner, _qf_search, domain ends in `.'.
@@ -12,6 +12,7 @@ adns (0.6) unstable; urgency=medium
   General improvements
   * New fanftest test program from Tony Finch.
   * New adns_if_logpid option (functionality suggested by Tony Finch).
+  * Better control of adnshost output and error messages (new -F options).
 
  --
 
index 5d9ddb938746b1bd35ec81912366796ba83aa7e0..46d5606d5ada55b77a7a0480843f1f34d684a16f 100644 (file)
@@ -32,7 +32,7 @@ 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;
+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 };
 
@@ -44,6 +44,14 @@ static const struct optioninfo global_options[]= {
     "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",
@@ -216,11 +224,12 @@ static void printusage(void) {
        "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"
index d8bcb7beb57356766335822a844260555e471bfc..bae71f42728c666fc805a507ff405dc5cde17409 100644 (file)
@@ -45,6 +45,9 @@ void ensure_adns_init(void) {
               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) {
@@ -67,7 +70,7 @@ static void prep_query(struct query_node **qun_r, int *quflags_r) {
   *quflags_r=
     (ov_search ? adns_qf_search : 0) |
     (ov_tcp ? adns_qf_usevc : 0) |
-    (ov_pqfr.show_owner ? adns_qf_owner : 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) |
@@ -147,7 +150,7 @@ static void print_owner_ttl(struct query_node *qun, adns_answer *answer) {
   print_ttl(qun,answer);
 }
 
-static void print_status(adns_status st, struct query_node *qun, adns_answer *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,
@@ -155,16 +158,19 @@ static void print_status(adns_status st, struct query_node *qun, adns_answer *an
   };
 
   const adns_status *spp;
-  const char *statustypeabbrev, *statusabbrev, *statusstring;
   int minrcode;
 
-  statustypeabbrev= adns_errtypeabbrev(st);
   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,'"'));
@@ -177,6 +183,32 @@ static void print_status(adns_status st, struct query_node *qun, adns_answer *an
   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;
@@ -185,16 +217,19 @@ void query_done(struct query_node *qun, adns_answer *answer) {
 
   st= answer->status;
   nrrs= answer->nrrs;
-  if (ov_asynch) {
+  if (ov_format == fmt_asynch) {
+    check_status(st);
     if (printf("%s %d ", qun->id, nrrs) == EOF) outerr();
     print_status(st,qun,answer);
   } else {
-    if (st) {
-      if (fputs("; failed ",stdout) == EOF) outerr();
-      print_status(st,qun,answer);
-    } else if (qun->pqfr.show_cname && answer->cname) {
+    if (qun->pqfr.show_cname && answer->cname) {
       print_owner_ttl(qun,answer);
-      if (printf("CNAME %s\n",answer->cname) == EOF) outerr();
+      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) {
index 7fe002055433e2e37b7ffcdc703717e67e76b0d1..cbde4c2d9046260ea842074001bf4087ddac9d49 100644 (file)
@@ -63,6 +63,7 @@ struct optioninfo {
 };
 
 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;
@@ -73,7 +74,7 @@ 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;
+extern int ov_tcp, ov_cname, ov_format;
 extern char *ov_id;
 extern struct perqueryflags_remember ov_pqfr;