chiark / gitweb /
+ * New fanftest test program from Tony Finch (ignored by `make install'). privaterel-1999-11-02-wolff
authorian <ian>
Wed, 3 Nov 1999 02:25:25 +0000 (02:25 +0000)
committerian <ian>
Wed, 3 Nov 1999 02:25:25 +0000 (02:25 +0000)
@@ -19,8 +19,9 @@
   General improvements
   * New adns_if_logpid option (functionality suggested by Tony Finch).
   * Better control of adnshost output and error messages (new -F options).
-  * New fanftest test program from Tony Finch.
+  * New fanftest test program from Tony Finch (ignored by `make install').
   * Declare flags parameters as enums again, not ints.
+  * New adnsresfilter general-purpose number->name mapping filter program.

  --

changelog
client/.cvsignore
client/Makefile.in
client/adnsresfilter.c [new file with mode: 0644]

index d58e0b9..6f688d5 100644 (file)
--- a/changelog
+++ b/changelog
@@ -19,8 +19,9 @@ adns (0.6) unstable; urgency=high
   General improvements
   * New adns_if_logpid option (functionality suggested by Tony Finch).
   * Better control of adnshost output and error messages (new -F options).
-  * New fanftest test program from Tony Finch.
+  * New fanftest test program from Tony Finch (ignored by `make install').
   * Declare flags parameters as enums again, not ints.
+  * New adnsresfilter general-purpose number->name mapping filter program.
 
  --
 
index d2f94fd..45bcf1e 100644 (file)
@@ -5,5 +5,7 @@ adnslogres
 adnslogres_s
 adnshost
 adnshost_s
+adnsresfilter
+adnsresfilter_s
 fanftest
 fanftest_s
index 9d131c9..770d8ac 100644 (file)
@@ -24,7 +24,7 @@
 srcdir=                @srcdir@
 VPATH=         @srcdir@
 
-PROGRAMS=      adnstest adnslogres adnshost
+PROGRAMS=      adnstest adnslogres adnshost adnsresfilter
 PROGRAMS_LOCAL=        fanftest
 
 TARG_INSTALL=  $(PROGRAMS)
diff --git a/client/adnsresfilter.c b/client/adnsresfilter.c
new file mode 100644 (file)
index 0000000..40685b1
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * 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 "adns.h"
+#include "config.h"
+
+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));
+  exit(2);
+}
+
+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: -b|--brackets\n"
+            "         -w|--wait\n"
+            "         -u|--unchecked\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();
+  exit(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));
+  exit(2);
+}
+
+static int bracket, forever;
+static adns_rrtype rrt= adns_r_ptr;
+
+static struct sockaddr_in sa;
+static adns_state ads;
+
+static char buf[14];
+static int c, cbyte, inbyte, inbuf;
+static unsigned char bytes[4];
+
+struct treething {
+  unsigned char bytes[4];
+  adns_query qu;
+  adns_answer *ans;
+};
+
+static struct treething *newthing;
+static void *treeroot;
+
+static int comparer(const void *a, const void *b) {
+  return memcmp(a,b,4);
+}
+
+static void restartbuf(void) {
+  if (inbuf>0) {
+    buf[inbuf++]= 0;
+    if (fputs(buf,stdout) < 0) outputerr();
+  }
+  inbuf= 0;
+}
+
+static void procaddr(void) {
+  struct treething *foundthing;
+  void *expectreturn, **searchfound;
+  int r;
+  
+  if (!newthing) {
+    newthing= malloc(sizeof(struct treething));
+    if (!newthing) sysfail("malloc");
+    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);
+  }
+  if (!foundthing->ans) {
+    expectreturn= foundthing;
+    r= (forever ? adns_wait : adns_check)
+      (ads,&foundthing->qu,&foundthing->ans,&expectreturn);
+    assert(r==EAGAIN || (!r && foundthing->ans && expectreturn==foundthing));
+  }
+  if (foundthing->ans && foundthing->ans->nrrs > 0) {
+    if (fputs(foundthing->ans->rrs.str[0],stdout) < 0) outputerr();
+    inbuf= 0;
+  } else {
+    restartbuf();
+  }
+  cbyte= -1;
+}
+
+static void startaddr(void) {
+  bytes[cbyte=0]= 0;
+  inbyte= 0;
+}
+
+static void mustputchar(int c) {
+  if (putchar(c) == EOF) outputerr();
+}
+
+int main(int argc, const char *const *argv) {
+  const char *arg;
+  int nbyte, r;
+
+  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,"--help")) {
+       usage(); exit(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 'h':
+         usage(); exit(0);
+       default:
+         usageerr("unknown short option");
+       }
+      }
+    }
+  }
+  if (setvbuf(stdout,0,_IOLBF,0)) sysfail("setvbuf stdout");
+
+  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();
+  while ((c= getchar()) != EOF) {
+    if (cbyte==-1 && bracket && c=='[') {
+      buf[inbuf++]= c;
+      startaddr();
+    } else if (cbyte==-1 && !bracket && !isalnum(c)) {
+      mustputchar(c);
+      startaddr();
+    } else if (cbyte>=0 && inbyte<3 && c>='0' && c<='9' &&
+              (nbyte= bytes[cbyte]*10 + (c-'0')) <= 255) {
+      bytes[cbyte]= nbyte;
+      buf[inbuf++]= c;
+      inbyte++;
+    } else if (cbyte>=0 && cbyte<3 && inbyte>0 && c=='.') {
+      bytes[++cbyte]= 0;
+      buf[inbuf++]= c;
+      inbyte= 0;
+    } else if (cbyte==3 && inbyte>0 && bracket && c==']') {
+      buf[inbuf++]= c;
+      procaddr();
+    } else if (cbyte==3 && inbyte>0 && !bracket && !isalnum(c)) {
+      procaddr();
+      mustputchar(c);
+      startaddr();
+    } else {
+      restartbuf();
+      mustputchar(c);
+      cbyte= -1;
+      if (!bracket && !isalnum(c)) startaddr();
+    }
+  }
+  if (ferror(stdin) || fclose(stdin)) sysfail("read stdin");
+  if (cbyte==3 && inbyte>0 && !bracket) procaddr();
+  if (fclose(stdout)) sysfail("close stdout");
+  exit(0);
+}