chiark / gitweb /
changelog: Document changes in 1.6.0 and finalise version number
[adns.git] / client / adnstest.c
index c4dd6b120709b28fa3bc15f0a57aea722f2673cc..2198ebcdd23ad169be0f5487643619f6548065ad 100644 (file)
@@ -3,11 +3,16 @@
  * - simple test program, not part of the library
  */
 /*
- *  This file is part of adns, which is Copyright (C) 1997-1999 Ian Jackson
+ *  This file is part of adns, which is
+ *    Copyright (C) 1997-2000,2003,2006,2014-2016,2020  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,
@@ -16,8 +21,7 @@
  *  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 <stdio.h>
 #include <string.h>
 #include <errno.h>
 
-#include "adns.h"
-
+#define ADNS_FEATURE_MANYAF
 #include "config.h"
+#include "adns.h"
 
-#ifndef OUTPUTSTREAM
-# define OUTPUTSTREAM stdout
+#ifdef ADNS_REGRESS_TEST
+# include "hredirect.h"
+# include "harness.h"
+# undef exit
+# define exit Texit
 #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);
-  exit(5);
+  quitnow(5);
 }
 #define adns_beforepoll(a,b,c,d,e) 0
 #define adns_afterpoll(a,b,c,d) 0
@@ -49,13 +75,24 @@ int poll(struct pollfd *ufds, int nfds, int timeout) {
 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));
-  exit(2);
+  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);
-  exit(2);
+  switch (errnoval) {
+#define CE(e) \
+  case e: fprintf(stderr,"adns failure: %s: errno=" #e "\n",what); break
+  CE(EINVAL);
+  CE(EINTR);
+  CE(ESRCH);
+  CE(EAGAIN);
+  CE(ENOSYS);
+  CE(ERANGE);
+#undef CE
+  default: fprintf(stderr,"adns failure: %s: errno=%d\n",what,errnoval); break;
+  }
+  quitnow(2);
 }
 
 static void usageerr(const char *why) NONRETURNING;
@@ -68,6 +105,7 @@ static void usageerr(const char *why) {
          "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"
+         "typenum:      may be 0x<hex>|<dec>, or 0x<hex> or <dec>\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"
@@ -75,7 +113,7 @@ static void usageerr(const char *why) {
          "              4 usage error\n"
          "              5 operation not supported on this system\n",
          why);
-  exit(4);
+  quitnow(4);
 }
 
 static const adns_rrtype defaulttypes[]= {
@@ -102,7 +140,7 @@ static const adns_rrtype defaulttypes[]= {
 
 static void dumptype(adns_status ri, const char *rrtn, const char *fmtn) {
   fprintf(stdout, "%s(%s)%s%s",
-         ri ? "?" : rrtn, ri ? "?" : fmtn ? fmtn : "-",
+         (!ri && rrtn) ? rrtn : "?", ri ? "?" : fmtn ? fmtn : "-",
          ri ? " " : "", ri ? adns_strerror(ri) : "");
 }
 
@@ -115,7 +153,7 @@ static void fdom_split(const char *fdom, const char **dom_r, int *qf_r,
   if (*ep == ',' && strchr(ep,'/')) {
     ep++;
     while (*ep != '/') {
-      if (--ownflags_l <= 0) { fputs("too many flags\n",stderr); exit(3); }
+      if (--ownflags_l <= 0) { fputs("too many flags\n",stderr); quitnow(3); }
       *ownflags++= *ep++;
     }
   }
@@ -129,27 +167,18 @@ static int consistsof(const char *string, const char *accept) {
 }
 
 int main(int argc, char *const *argv) {
-  struct myctx {
-    adns_query qu;
-    int doneyet, found;
-    const char *fdom;
-  };
-  
-  adns_state ads;
   adns_query qu;
-  struct myctx *mcs, *mc, *mcw;
+  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, npollfds, npollfdsavail, timeout;
-  struct pollfd *pollfds;
+  int len, i, qc, qi, tc, ti, ch, qflags, initflagsnum;
   adns_status ri;
   int r;
   const adns_rrtype *types;
   struct timeval now;
-  adns_rrtype *types_a;
   char ownflags[10];
   char *ep;
   const char *initflags, *owninitflags;
@@ -181,18 +210,26 @@ int main(int argc, char *const *argv) {
     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"); exit(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");
+    if (!types_a) { perror("malloc types"); quitnow(3); }
+    for (cp= argv[1]+1, ti=0; ti<tc; ) {
+      types_a[ti]= 0;
+      for (;;) {
+       types_a[ti] |= strtoul(cp,&cp,0);
+       ch= *cp;
+       if (!ch) break;
        cp++;
+       if (ch=='|') continue;
+       if (ch==',') break;
+       usageerr("unexpected char (not comma) in or between types");
       }
+      ti++;
+      if (!ch) break;
     }
-    *cp++= adns_r_none;
+    types_a[ti]= adns_r_none;
     types= types_a;
     argv++;
   } else {
+    types_a= 0;
     types= defaulttypes;
   }
   
@@ -201,9 +238,11 @@ int main(int argc, char *const *argv) {
 
   for (qc=0; fdomlist[qc]; qc++);
   for (tc=0; types[tc] != adns_r_none; tc++);
-  mcs= malloc(sizeof(*mcs)*qc*tc);
-  if (!mcs) { perror("malloc mcs"); exit(3); }
+  mcs= malloc(tc ? sizeof(*mcs)*qc*tc : 1);
+  if (!mcs) { perror("malloc mcs"); quitnow(3); }
 
+  setvbuf(stdout,0,_IOLBF,0);
+  
   if (initstring) {
     r= adns_init_strcfg(&ads,
                        (adns_if_debug|adns_if_noautosys|adns_if_checkc_freq)
@@ -216,9 +255,6 @@ int main(int argc, char *const *argv) {
   }
   if (r) failure_errno("init",r);
 
-  npollfdsavail= 0;
-  pollfds= 0;
-  
   for (qi=0; qi<qc; qi++) {
     fdom_split(fdomlist[qi],&domain,&qflags,ownflags,sizeof(ownflags));
     if (!consistsof(ownflags,"a")) usageerr("unknown ownqueryflag");
@@ -227,7 +263,8 @@ int main(int argc, char *const *argv) {
       mc->doneyet= 0;
       mc->fdom= fdomlist[qi];
 
-      fprintf(stdout,"%s flags %d type %d",domain,qflags,types[ti]);
+      fprintf(stdout,"%s flags %d type %d",
+             domain,qflags,types[ti]&adns_rrt_reprmask);
       r= adns_submit(ads,domain,types[ti],qflags,mc,&mc->qu);
       if (r == ENOSYS) {
        fprintf(stdout," not implemented\n");
@@ -279,23 +316,7 @@ int main(int argc, char *const *argv) {
     }
 
     if (strchr(owninitflags,'p')) {
-      for (;;) {
-       r= adns_check(ads,&qu,&ans,&mcr);
-       if (r != EWOULDBLOCK) break;
-       for (;;) {
-         npollfds= npollfdsavail;
-         timeout= -1;
-         r= adns_beforepoll(ads, pollfds, &npollfds, &timeout, 0);
-         if (r != ERANGE) break;
-         pollfds= realloc(pollfds,sizeof(*pollfds)*npollfds);
-         if (!pollfds) failure_errno("realloc pollfds",errno);
-         npollfdsavail= npollfds;
-       }
-       if (r) failure_errno("beforepoll",r);
-       r= poll(pollfds,npollfds,timeout);
-       if (r == -1) failure_errno("poll",errno);
-       adns_afterpoll(ads,pollfds, r?npollfds:0, 0);
-      }
+      r= adns_wait_poll(ads,&qu,&ans,&mcr);
     } else {
       r= adns_wait(ads,&qu,&ans,&mcr);
     }
@@ -308,7 +329,7 @@ int main(int argc, char *const *argv) {
     
     fdom_split(mc->fdom,&domain,&qflags,ownflags,sizeof(ownflags));
 
-    if (gettimeofday(&now,0)) { perror("gettimeofday"); exit(3); }
+    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);
@@ -336,8 +357,5 @@ int main(int argc, char *const *argv) {
     mc->doneyet= 1;
   }
 
-  free(mcs);
-  adns_finish(ads);
-  
-  exit(0);
+  quitnow(0);
 }