From: ian Date: Wed, 3 Nov 1999 02:25:25 +0000 (+0000) Subject: + * New fanftest test program from Tony Finch (ignored by `make install'). X-Git-Tag: privaterel-1999-11-02-wolff X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=adns.git;a=commitdiff_plain;h=592aa664063e35f61dafab9d278647af54e6bd24 + * New fanftest test program from Tony Finch (ignored by `make install'). @@ -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. -- --- diff --git a/changelog b/changelog index d58e0b9..6f688d5 100644 --- 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. -- diff --git a/client/.cvsignore b/client/.cvsignore index d2f94fd..45bcf1e 100644 --- a/client/.cvsignore +++ b/client/.cvsignore @@ -5,5 +5,7 @@ adnslogres adnslogres_s adnshost adnshost_s +adnsresfilter +adnsresfilter_s fanftest fanftest_s diff --git a/client/Makefile.in b/client/Makefile.in index 9d131c9..770d8ac 100644 --- a/client/Makefile.in +++ b/client/Makefile.in @@ -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 index 0000000..40685b1 --- /dev/null +++ b/client/adnsresfilter.c @@ -0,0 +1,232 @@ +/* + * adnsresfilter.c + * - filter which does resolving, not part of the library + */ +/* + * This file is + * Copyright (C) 1999 Ian Jackson + * + * It is part of adns, which is + * Copyright (C) 1997-1999 Ian Jackson + * Copyright (C) 1999 Tony Finch + * + * 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 +#include +#include +#include +#include +#include +#include + +#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 []\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); +}