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

adh-query.c
Go to the documentation of this file.
00001 /*
00002  * adh-query.c
00003  * - useful general-purpose resolver client program
00004  *   make queries and print answers
00005  */
00006 /*
00007  *  This file is
00008  *    Copyright (C) 1997-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 
00029 #ifdef ADNS_JGAA_WIN32
00030 # include "adns_win32.h"
00031 #endif
00032 
00033 #include "adnshost.h"
00034 
00035 adns_state ads;
00036 struct outstanding_list outstanding;
00037 
00038 static unsigned long idcounter;
00039 
00040 void ensure_adns_init(void) {
00041   adns_initflags initflags;
00042   int r;
00043 
00044   if (ads) return;
00045 
00046 #ifdef SIGPIPE
00047   if (signal(SIGPIPE,SIG_IGN) == SIG_ERR) sysfail("ignore SIGPIPE",errno);
00048 #endif
00049 
00050   initflags= adns_if_noautosys|adns_if_nosigpipe|ov_verbose;
00051   if (!ov_env) initflags |= adns_if_noenv;
00052 
00053   if (config_text) {
00054     r= adns_init_strcfg(&ads, initflags, stderr, config_text);
00055   } else {
00056     r= adns_init(&ads, initflags, 0);
00057   }
00058   if (r) sysfail("adns_init",r);
00059 
00060   if (ov_format == fmt_default)
00061     ov_format= ov_asynch ? fmt_asynch : fmt_simple;
00062 }
00063 
00064 static void prep_query(struct query_node **qun_r, int *quflags_r) {
00065   struct query_node *qun;
00066   char idbuf[20];
00067 
00068   if (ov_pipe && !ads) usageerr("-f/--pipe not consistent with domains on command line");
00069   ensure_adns_init();
00070 
00071   qun= malloc(sizeof(*qun));
00072   qun->pqfr= ov_pqfr;
00073   if (ov_id) {
00074     qun->id= xstrsave(ov_id);
00075   } else {
00076     sprintf(idbuf,"%lu",idcounter++);
00077     idcounter &= 0x0fffffffflu;
00078     qun->id= xstrsave(idbuf);
00079   }
00080 
00081   *quflags_r=
00082     (ov_search ? adns_qf_search : 0) |
00083     (ov_tcp ? adns_qf_usevc : 0) |
00084     ((ov_pqfr.show_owner || ov_format == fmt_simple) ? adns_qf_owner : 0) |
00085     (ov_qc_query ? adns_qf_quoteok_query : 0) |
00086     (ov_qc_anshost ? adns_qf_quoteok_anshost : 0) |
00087     (ov_qc_cname ? 0 : adns_qf_quoteok_cname) |
00088     ov_cname,
00089 
00090   *qun_r= qun;
00091 }
00092 
00093 void of_ptr(const struct optioninfo *oi, const char *arg, const char *arg2) {
00094   struct query_node *qun;
00095   int quflags, r;
00096   struct sockaddr_in sa;
00097 
00098   memset(&sa,0,sizeof(sa));
00099   sa.sin_family= AF_INET;
00100   if (!inet_aton(arg,&sa.sin_addr)) usageerr("invalid IP address %s",arg);
00101 
00102   prep_query(&qun,&quflags);
00103   qun->owner= xstrsave(arg);
00104   r= adns_submit_reverse(ads,
00105              (struct sockaddr*)&sa,
00106              ov_type == adns_r_none ? adns_r_ptr : ov_type,
00107              quflags,
00108              qun,
00109              &qun->qu);
00110   if (r) sysfail("adns_submit_reverse",r);
00111 
00112   LIST_LINK_TAIL(outstanding,qun);
00113 }
00114 
00115 void of_reverse(const struct optioninfo *oi, const char *arg, const char *arg2) {
00116   struct query_node *qun;
00117   int quflags, r;
00118   struct sockaddr_in sa;
00119 
00120   memset(&sa,0,sizeof(sa));
00121   sa.sin_family= AF_INET;
00122   if (!inet_aton(arg,&sa.sin_addr)) usageerr("invalid IP address %s",arg);
00123 
00124   prep_query(&qun,&quflags);
00125   qun->owner= xmalloc(strlen(arg) + strlen(arg2) + 2);
00126   sprintf(qun->owner, "%s %s", arg,arg2);
00127   r= adns_submit_reverse_any(ads,
00128                  (struct sockaddr*)&sa, arg2,
00129                  ov_type == adns_r_none ? adns_r_txt : ov_type,
00130                  quflags,
00131                  qun,
00132                  &qun->qu);
00133   if (r) sysfail("adns_submit_reverse",r);
00134 
00135   LIST_LINK_TAIL(outstanding,qun);
00136 }
00137 
00138 void query_do(const char *domain) {
00139   struct query_node *qun;
00140   int quflags, r;
00141 
00142   prep_query(&qun,&quflags);
00143   qun->owner= xstrsave(domain);
00144   r= adns_submit(ads, domain,
00145          ov_type == adns_r_none ? adns_r_addr : ov_type,
00146          quflags,
00147          qun,
00148          &qun->qu);
00149   if (r) sysfail("adns_submit",r);
00150 
00151   LIST_LINK_TAIL(outstanding,qun);
00152 }
00153 
00154 static void dequeue_query(struct query_node *qun) {
00155   LIST_UNLINK(outstanding,qun);
00156   free(qun->id);
00157   free(qun->owner);
00158   free(qun);
00159 }
00160 
00161 static void print_withspace(const char *str) {
00162   if (printf("%s ", str) == EOF) outerr();
00163 }
00164 
00165 static void print_ttl(struct query_node *qun, adns_answer *answer) {
00166   unsigned long ttl;
00167   time_t now;
00168 
00169   switch (qun->pqfr.ttl) {
00170   case tm_none:
00171     return;
00172   case tm_rel:
00173     if (time(&now) == (time_t)-1) sysfail("get current time",errno);
00174     ttl= answer->expires < now ? 0 : answer->expires - now;
00175     break;
00176   case tm_abs:
00177     ttl= answer->expires;
00178     break;
00179   default:
00180     abort();
00181   }
00182   if (printf("%lu ",ttl) == EOF) outerr();
00183 }
00184 
00185 static const char *owner_show(struct query_node *qun, adns_answer *answer) {
00186   return answer->owner ? answer->owner : qun->owner;
00187 }
00188 
00189 static void print_owner_ttl(struct query_node *qun, adns_answer *answer) {
00190   if (qun->pqfr.show_owner) print_withspace(owner_show(qun,answer));
00191   print_ttl(qun,answer);
00192 }
00193 
00194 static void check_status(adns_status st) {
00195   static const adns_status statuspoints[]= {
00196     adns_s_ok,
00197     adns_s_max_localfail, adns_s_max_remotefail, adns_s_max_tempfail,
00198     adns_s_max_misconfig, adns_s_max_misquery
00199   };
00200 
00201   const adns_status *spp;
00202   int minrcode;
00203 
00204   for (minrcode=0, spp=statuspoints;
00205        spp < statuspoints + (sizeof(statuspoints)/sizeof(statuspoints[0]));
00206        spp++)
00207     if (st > *spp) minrcode++;
00208   if (rcode < minrcode) rcode= minrcode;
00209 }
00210 
00211 static void print_status(adns_status st, struct query_node *qun, adns_answer *answer) {
00212   const char *statustypeabbrev, *statusabbrev, *statusstring;
00213 
00214   statustypeabbrev= adns_errtypeabbrev(st);
00215   statusabbrev= adns_errabbrev(st);
00216   statusstring= adns_strerror(st);
00217   assert(!strchr(statusstring,'"'));
00218 
00219   if (printf("%s %d %s ", statustypeabbrev, st, statusabbrev)
00220       == EOF) outerr();
00221   print_owner_ttl(qun,answer);
00222   if (qun->pqfr.show_cname)
00223     print_withspace(answer->cname ? answer->cname : "$");
00224   if (printf("\"%s\"\n", statusstring) == EOF) outerr();
00225 }
00226 
00227 static void print_dnsfail(adns_status st, struct query_node *qun, adns_answer *answer) {
00228   int r;
00229   const char *typename, *statusstring;
00230   adns_status ist;
00231 
00232   if (ov_format == fmt_inline) {
00233     if (fputs("; failed ",stdout) == EOF) outerr();
00234     print_status(st,qun,answer);
00235     return;
00236   }
00237   assert(ov_format == fmt_simple);
00238   if (st == adns_s_nxdomain) {
00239     r= fprintf(stderr,"%s does not exist\n", owner_show(qun,answer));
00240   } else {
00241     ist= adns_rr_info(answer->type, &typename, 0,0,0,0);
00242     if (st == adns_s_nodata) {
00243       r= fprintf(stderr,"%s has no %s record\n", owner_show(qun,answer), typename);
00244     } else {
00245       statusstring= adns_strerror(st);
00246       r= fprintf(stderr,"Error during DNS %s lookup for %s: %s\n",
00247          typename, owner_show(qun,answer), statusstring);
00248     }
00249   }
00250   if (r == EOF) sysfail("write error message to stderr",errno);
00251 }
00252 
00253 void query_done(struct query_node *qun, adns_answer *answer) {
00254   adns_status st, ist;
00255   int rrn, nrrs;
00256   const char *rrp, *realowner, *typename;
00257   char *datastr;
00258 
00259   st= answer->status;
00260   nrrs= answer->nrrs;
00261   if (ov_format == fmt_asynch) {
00262     check_status(st);
00263     if (printf("%s %d ", qun->id, nrrs) == EOF) outerr();
00264     print_status(st,qun,answer);
00265   } else {
00266     if (qun->pqfr.show_cname && answer->cname) {
00267       print_owner_ttl(qun,answer);
00268       if (qun->pqfr.show_type) print_withspace("CNAME");
00269       if (printf("%s\n", answer->cname) == EOF) outerr();
00270     }
00271     if (st) {
00272       check_status(st);
00273       print_dnsfail(st,qun,answer);
00274     }
00275   }
00276   if (qun->pqfr.show_owner) {
00277     realowner= answer->cname ? answer->cname : owner_show(qun,answer);
00278     assert(realowner);
00279   } else {
00280     realowner= 0;
00281   }
00282   if (nrrs) {
00283     for (rrn=0, rrp = answer->rrs.untyped;
00284      rrn < nrrs;
00285      rrn++, rrp += answer->rrsz) {
00286       if (realowner) print_withspace(realowner);
00287       print_ttl(qun,answer);
00288       ist= adns_rr_info(answer->type, &typename, 0, 0, rrp, &datastr);
00289       if (ist == adns_s_nomemory) sysfail("adns_rr_info failed",ENOMEM);
00290       assert(!ist);
00291       if (qun->pqfr.show_type) print_withspace(typename);
00292       if (printf("%s\n",datastr) == EOF) outerr();
00293       free(datastr);
00294     }
00295   }
00296   if (fflush(stdout)) outerr();
00297   free(answer);
00298   dequeue_query(qun);
00299 }
00300 
00301 void of_asynch_id(const struct optioninfo *oi, const char *arg, const char *arg2) {
00302   free(ov_id);
00303   ov_id= xstrsave(arg);
00304 }
00305 
00306 void of_cancel_id(const struct optioninfo *oi, const char *arg, const char *arg2) {
00307   struct query_node *qun;
00308 
00309   for (qun= outstanding.head;
00310        qun && strcmp(qun->id,arg);
00311        qun= qun->next);
00312   if (!qun) return;
00313   adns_cancel(qun->qu);
00314   dequeue_query(qun);
00315 }

Generated on Sat May 26 2012 04:32:16 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.