X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=client%2Fadnsresfilter.c;h=770af173169abc589897371ef9ff1de441f848b7;hb=cd4a70625461f933beae7923520cef2523524e0d;hp=bba1b1c65c6e1680985d4bcc193f0b47f5706896;hpb=5a0be2445e09e1d0fc6ae995b6c0296bc28e657d;p=adns.git diff --git a/client/adnsresfilter.c b/client/adnsresfilter.c index bba1b1c..770af17 100644 --- a/client/adnsresfilter.c +++ b/client/adnsresfilter.c @@ -3,16 +3,16 @@ * - filter which does resolving, not part of the library */ /* - * This file is - * Copyright (C) 1999-2000 Ian Jackson - * - * It is part of adns, which is - * Copyright (C) 1997-2000 Ian Jackson - * Copyright (C) 1999 Tony Finch + * This file is part of adns, which is + * Copyright (C) 1997-2000,2003,2006,2014 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, @@ -21,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 @@ -41,11 +40,15 @@ #include "adns.h" #include "dlist.h" #include "tvarith.h" +#include "client.h" + +#ifdef ADNS_REGRESS_TEST +# include "hredirect.h" +#endif struct outqueuenode { struct outqueuenode *next, *back; - void *buffer; - char *textp; + char *buffer, *textp; int textlen; struct timeval printbefore; struct treething *addr; @@ -54,6 +57,8 @@ struct outqueuenode { static int bracket, forever, address; static unsigned long timeout= 1000; static adns_rrtype rrt= adns_r_ptr; +static adns_initflags initflags= 0; +static const char *config_text; static int outblocked, inputeof; static struct { struct outqueuenode *head, *tail; } outqueue; @@ -86,8 +91,7 @@ static int nonblock(int fd, int isnonblock) { return 0; } -static void quit(int exitstatus) NONRETURNING; -static void quit(int exitstatus) { +void quitnow(int exitstatus) { nonblock(0,0); nonblock(1,0); exit(exitstatus); @@ -96,7 +100,7 @@ static void quit(int 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); + quitnow(2); } static void *xmalloc(size_t sz) { @@ -110,28 +114,31 @@ static void outputerr(void) { sysfail("write to stdout"); } static void usage(void) { if (printf("usage: adnsresfilter []\n" - " adnsresfilter -h|--help\n" + " adnsresfilter -h|--help | --version\n" "options: -t|--timeout \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" + " --config (use this instead of resolv.conf)\n" + " --debug (turn on adns resolver debugging)\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") + "Lookups will go on in the background. Default timeout = 1000 (ms).\n") == EOF) outputerr(); + if (fflush(stdout)) sysfail("flush stdout"); } static void usageerr(const char *why) NONRETURNING; static void usageerr(const char *why) { fprintf(stderr,"adnsresfilter: bad usage: %s\n",why); usage(); - quit(1); + quitnow(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); + quitnow(2); } static void settimeout(const char *arg) { @@ -147,48 +154,55 @@ static void parseargs(const char *const *argv) { 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; + if (!strcmp(arg,"--timeout")) { + if (!(arg= *++argv)) usageerr("--timeout needs a value"); + settimeout(arg); + forever= 0; } else if (!strcmp(arg,"--wait")) { forever= 1; + } else if (!strcmp(arg,"--brackets")) { + bracket= 1; } else if (!strcmp(arg,"--address")) { address= 1; + } else if (!strcmp(arg,"--unchecked")) { + rrt= adns_r_ptr_raw; + } else if (!strcmp(arg,"--config")) { + if (!(arg= *++argv)) usageerr("--config needs a value"); + config_text= arg; + } else if (!strcmp(arg,"--debug")) { + initflags |= adns_if_debug; } 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; + usage(); quitnow(0); + } else if (!strcmp(arg,"--version")) { + VERSION_PRINT_QUIT("adnsresfilter"); quitnow(0); } else { usageerr("unknown long option"); } } else { while ((c= *++arg)) { switch (c) { - case 'b': - bracket= 1; - break; - case 'u': - rrt= adns_r_ptr_raw; + case 't': + if (*++arg) settimeout(arg); + else if ((arg= *++argv)) settimeout(arg); + else usageerr("-t needs a value"); + forever= 0; + arg= "\0"; break; case 'w': forever= 1; break; + case 'b': + bracket= 1; + break; case 'a': address= 1; break; + case 'u': + rrt= adns_r_ptr_raw; + 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; + quitnow(0); default: usageerr("unknown short option"); } @@ -201,7 +215,8 @@ static void queueoutchar(int c) { struct outqueuenode *entry; entry= outqueue.tail; - if (!entry || entry->addr || entry->textlen >= peroutqueuenode) { + if (!entry || entry->addr || + entry->textlen >= peroutqueuenode - (entry->textp - entry->buffer)) { peroutqueuenode= !peroutqueuenode || !entry || entry->addr ? 128 : peroutqueuenode >= 1024 ? 4096 : peroutqueuenode<<2; entry= xmalloc(sizeof(*entry)); @@ -380,7 +395,12 @@ static void startup(void) { 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); + if (config_text) { + r= adns_init_strcfg(&ads,initflags,stderr,config_text); + } else { + r= adns_init(&ads,initflags,0); + } + if (r) adnsfail("init",r); cbyte= -1; inbyte= -1; inbuf= 0; @@ -449,7 +469,6 @@ int main(int argc, const char *const *argv) { } 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"); + adns_finish(ads); exit(0); }