Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenadh-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
1.7.6.1
|