ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

adnslogres.c
Go to the documentation of this file.
00001 /*
00002  * adnslogres.c
00003  * - a replacement for the Apache logresolve program using adns
00004  */
00005 /*
00006  *  This file is
00007  *   Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
00008  *   Copyright (C) 1999-2000 Ian Jackson <ian@davenant.greenend.org.uk>
00009  *
00010  *  It is part of adns, which is
00011  *    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
00012  *    Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
00013  *
00014  *  This program is free software; you can redistribute it and/or modify
00015  *  it under the terms of the GNU General Public License as published by
00016  *  the Free Software Foundation; either version 2, or (at your option)
00017  *  any later version.
00018  *
00019  *  This program is distributed in the hope that it will be useful,
00020  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  *  GNU General Public License for more details.
00023  *
00024  *  You should have received a copy of the GNU General Public License
00025  *  along with this program; if not, write to the Free Software Foundation,
00026  *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00027  *
00028  *  This version was originally supplied by Tony Finch, but has been
00029  *  modified by Ian Jackson as it was incorporated into adns and
00030  *  subsequently.
00031  */
00032 
00033 #ifdef ADNS_JGAA_WIN32
00034 # include "adns_win32.h"
00035 # include "getopt.h"
00036 #else
00037 # include <sys/types.h>
00038 # include <sys/time.h>
00039 # include <unistd.h>
00040 # include <string.h>
00041 # include <stdlib.h>
00042 # include <stdio.h>
00043 # include <ctype.h>
00044 # include <errno.h>
00045 # include <stdarg.h>
00046 #endif
00047 
00048 #include "config.h"
00049 #include "adns.h"
00050 #include "client.h"
00051 
00052 #ifdef ADNS_REGRESS_TEST
00053 # include "hredirect.h"
00054 #endif
00055 
00056 /* maximum number of concurrent DNS queries */
00057 #define MAXMAXPENDING 64000
00058 #define DEFMAXPENDING 2000
00059 
00060 /* maximum length of a line */
00061 #define MAXLINE 1024
00062 
00063 /* option flags */
00064 #define OPT_DEBUG 1
00065 
00066 #ifdef HAVE_POLL
00067 # define OPT_POLL 2
00068 #endif
00069 
00070 static const char *const progname= "adnslogres";
00071 static const char *config_text;
00072 
00073 #define guard_null(str) ((str) ? (str) : "")
00074 
00075 #define sensible_ctype(type,ch) (type((unsigned char)(ch)))
00076   /* isfoo() functions from ctype.h can't safely be fed char - blech ! */
00077 
00078 static void msg(const char *fmt, ...) {
00079   va_list al;
00080 
00081   fprintf(stderr, "%s: ", progname);
00082   va_start(al,fmt);
00083   vfprintf(stderr, fmt, al);
00084   va_end(al);
00085   fputc('\n',stderr);
00086 }
00087 
00088 static void aargh(const char *cause) {
00089   const char *why = strerror(errno);
00090   if (!why) why = "Unknown error";
00091   msg("%s: %s (%d)", cause, why, errno);
00092   exit(1);
00093 }
00094 
00095 /*
00096  * Parse the IP address and convert to a reverse domain name.
00097  */
00098 static char *ipaddr2domain(char *start, char **addr, char **rest) {
00099   static char buf[30]; /* "123.123.123.123.in-addr.arpa.\0" */
00100   char *ptrs[5];
00101   int i;
00102 
00103   ptrs[0]= start;
00104 retry:
00105   while (!sensible_ctype(isdigit,*ptrs[0]))
00106     if (!*ptrs[0]++) {
00107       strcpy(buf, "invalid.");
00108       *addr= *rest= NULL;
00109       return buf;
00110     }
00111   for (i= 1; i < 5; i++) {
00112     ptrs[i]= ptrs[i-1];
00113     while (sensible_ctype(isdigit,*ptrs[i]++));
00114     if ((i == 4 && !sensible_ctype(isspace,ptrs[i][-1])) ||
00115     (i != 4 && ptrs[i][-1] != '.') ||
00116     (ptrs[i]-ptrs[i-1] > 4)) {
00117       ptrs[0]= ptrs[i]-1;
00118       goto retry;
00119     }
00120   }
00121   sprintf(buf, "%.*s.%.*s.%.*s.%.*s.in-addr.arpa.",
00122       ptrs[4]-ptrs[3]-1, ptrs[3],
00123       ptrs[3]-ptrs[2]-1, ptrs[2],
00124       ptrs[2]-ptrs[1]-1, ptrs[1],
00125       ptrs[1]-ptrs[0]-1, ptrs[0]);
00126   *addr= ptrs[0];
00127   *rest= ptrs[4]-1;
00128   return buf;
00129 }
00130 
00131 static void printline(FILE *outf, char *start, char *addr, char *rest, char *domain) {
00132   if (domain)
00133     fprintf(outf, "%.*s%s%s", addr - start, start, domain, rest);
00134   else
00135     fputs(start, outf);
00136   if (ferror(outf)) aargh("write output");
00137 }
00138 
00139 typedef struct logline {
00140   struct logline *next;
00141   char *start, *addr, *rest;
00142   adns_query query;
00143 } logline;
00144 
00145 static logline *readline(FILE *inf, adns_state adns, int opts) {
00146   static char buf[MAXLINE];
00147   char *str;
00148   logline *line;
00149 
00150   if (fgets(buf, MAXLINE, inf)) {
00151     str= malloc(sizeof(*line) + strlen(buf) + 1);
00152     if (!str) aargh("malloc");
00153     line= (logline*)str;
00154     line->next= NULL;
00155     line->start= str+sizeof(logline);
00156     strcpy(line->start, buf);
00157     str= ipaddr2domain(line->start, &line->addr, &line->rest);
00158     if (opts & OPT_DEBUG)
00159       msg("submitting %.*s -> %s", line->rest-line->addr, guard_null(line->addr), str);
00160     if (adns_submit(adns, str, adns_r_ptr,
00161             adns_qf_quoteok_cname|adns_qf_cname_loose,
00162             NULL, &line->query))
00163       aargh("adns_submit");
00164     return line;
00165   }
00166   if (!feof(inf))
00167     aargh("fgets");
00168   return NULL;
00169 }
00170 
00171 static void proclog(FILE *inf, FILE *outf, int maxpending, int opts) {
00172   int eof, err, len;
00173   adns_state adns;
00174   adns_answer *answer;
00175   logline *head, *tail, *line;
00176   adns_initflags initflags;
00177 
00178   initflags= (opts & OPT_DEBUG) ? adns_if_debug : 0;
00179   if (config_text) {
00180     errno= adns_init_strcfg(&adns, initflags, stderr, config_text);
00181   } else {
00182     errno= adns_init(&adns, initflags, 0);
00183   }
00184   if (errno) aargh("adns_init");
00185   head= tail= readline(inf, adns, opts);
00186   len= 1; eof= 0;
00187   while (head) {
00188     while (head) {
00189       if (opts & OPT_DEBUG)
00190     msg("%d in queue; checking %.*s", len,
00191         head->rest-head->addr, guard_null(head->addr));
00192       if (eof || len >= maxpending) {
00193 #ifdef HAVE_POLL
00194     if (opts & OPT_POLL)
00195       err= adns_wait_poll(adns, &head->query, &answer, NULL);
00196     else
00197 #endif
00198       err= adns_wait(adns, &head->query, &answer, NULL);
00199       } else {
00200     err= adns_check(adns, &head->query, &answer, NULL);
00201       }
00202       if ((err == EAGAIN) || (EWOULDBLOCK == err)) break;
00203       if (err) {
00204     fprintf(stderr, "%s: adns_wait/check: %s", progname, strerror(err));
00205     exit(1);
00206       }
00207       printline(outf, head->start, head->addr, head->rest,
00208         answer->status == adns_s_ok ? *answer->rrs.str : NULL);
00209       line= head; head= head->next;
00210       free(line);
00211       free(answer);
00212       len--;
00213     }
00214     if (!eof) {
00215       line= readline(inf, adns, opts);
00216       if (line) {
00217         if (!head) head= line;
00218         else tail->next= line;
00219         tail= line; len++;
00220       } else {
00221     eof= 1;
00222       }
00223     }
00224   }
00225   adns_finish(adns);
00226 }
00227 
00228 static void printhelp(FILE *file) {
00229   fputs("usage: adnslogres [<options>] [<logfile>]\n"
00230     "       adnslogres --version|--help\n"
00231     "options: -c <concurrency>  set max number of outstanding queries\n"
00232 #ifdef HAVE_POLL
00233     "         -p                use poll(2) instead of select(2)\n"
00234 #endif
00235     "         -d                turn on debugging\n"
00236     "         -C <config>       use instead of contents of resolv.conf\n",
00237     stdout);
00238 }
00239 
00240 static void usage(void) {
00241   printhelp(stderr);
00242   exit(1);
00243 }
00244 
00245 int main(int argc, char *argv[]) {
00246   int c, opts, maxpending;
00247   extern char *optarg;
00248   FILE *inf;
00249 
00250   if (argv[1] && !strncmp(argv[1],"--",2)) {
00251     if (!strcmp(argv[1],"--help")) {
00252       printhelp(stdout);
00253     } else if (!strcmp(argv[1],"--version")) {
00254       fputs(VERSION_MESSAGE("adnslogres"),stdout);
00255     } else {
00256       usage();
00257     }
00258     if (ferror(stdout) || fclose(stdout)) { perror("stdout"); exit(1); }
00259     exit(0);
00260   }
00261 
00262   maxpending= DEFMAXPENDING;
00263   opts= 0;
00264   while ((c= getopt(argc, argv, "c:C:dp")) != -1)
00265     switch (c) {
00266     case 'c':
00267       maxpending= atoi(optarg);
00268       if (maxpending < 1 || maxpending > MAXMAXPENDING) {
00269        fprintf(stderr, "%s: unfeasible concurrency %d\n", progname, maxpending);
00270        exit(1);
00271       }
00272       break;
00273     case 'C':
00274       config_text= optarg;
00275       break;
00276     case 'd':
00277       opts|= OPT_DEBUG;
00278       break;
00279 #ifdef HAVE_POLL
00280     case 'p':
00281       opts|= OPT_POLL;
00282       break;
00283 #endif
00284     default:
00285       usage();
00286     }
00287 
00288   argc-= optind;
00289   argv+= optind;
00290 
00291   inf= NULL;
00292   if (argc == 0)
00293     inf= stdin;
00294   else if (argc == 1)
00295     inf= fopen(*argv, "r");
00296   else
00297     usage();
00298 
00299   if (!inf)
00300     aargh("couldn't open input");
00301 
00302   proclog(inf, stdout, maxpending, opts);
00303 
00304   if (fclose(inf))
00305     aargh("fclose input");
00306   if (fclose(stdout))
00307     aargh("fclose output");
00308 
00309   return 0;
00310 }

Generated on Sun May 27 2012 04:33:25 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.