Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygengeneral.c
Go to the documentation of this file.
00001 /* 00002 * general.c 00003 * - diagnostic functions 00004 * - vbuf handling 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 #include <stdlib.h> 00030 00031 #ifdef ADNS_JGAA_WIN32 00032 # include "adns_win32.h" 00033 #else 00034 # include <unistd.h> 00035 # include <sys/types.h> 00036 # include <sys/socket.h> 00037 # include <netinet/in.h> 00038 # include <arpa/inet.h> 00039 #endif 00040 00041 #include "internal.h" 00042 00043 /* Core diagnostic functions */ 00044 00045 void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent, 00046 int serv, adns_query qu, const char *fmt, va_list al) { 00047 const char *bef, *aft; 00048 vbuf vb; 00049 00050 if (!ads->diagfile || 00051 (!(ads->iflags & adns_if_debug) && (!prevent || (ads->iflags & prevent)))) 00052 return; 00053 00054 if (ads->iflags & adns_if_logpid) { 00055 fprintf(ads->diagfile,"adns%s [%ld]: ",pfx,(long)getpid()); 00056 } else { 00057 fprintf(ads->diagfile,"adns%s: ",pfx); 00058 } 00059 00060 vfprintf(ads->diagfile,fmt,al); 00061 00062 bef= " ("; 00063 aft= "\n"; 00064 00065 if (qu && qu->query_dgram) { 00066 adns__vbuf_init(&vb); 00067 fprintf(ads->diagfile,"%sQNAME=%s, QTYPE=%s", 00068 bef, 00069 adns__diag_domain(qu->ads,-1,0, &vb, 00070 qu->query_dgram,qu->query_dglen,DNS_HDRSIZE), 00071 qu->typei ? qu->typei->rrtname : "<unknown>"); 00072 if (qu->typei && qu->typei->fmtname) 00073 fprintf(ads->diagfile,"(%s)",qu->typei->fmtname); 00074 bef=", "; aft=")\n"; 00075 adns__vbuf_free(&vb); 00076 } 00077 00078 if (serv>=0) { 00079 fprintf(ads->diagfile,"%sNS=%s",bef,inet_ntoa(ads->servers[serv].addr)); 00080 bef=", "; aft=")\n"; 00081 } 00082 00083 fputs(aft,ads->diagfile); 00084 } 00085 00086 void adns__debug(adns_state ads, int serv, adns_query qu, const char *fmt, ...) { 00087 va_list al; 00088 00089 va_start(al,fmt); 00090 adns__vdiag(ads," debug",0,serv,qu,fmt,al); 00091 va_end(al); 00092 } 00093 00094 void adns__warn(adns_state ads, int serv, adns_query qu, const char *fmt, ...) { 00095 va_list al; 00096 00097 va_start(al,fmt); 00098 adns__vdiag(ads," warning",adns_if_noerrprint|adns_if_noserverwarn,serv,qu,fmt,al); 00099 va_end(al); 00100 } 00101 00102 void adns__diag(adns_state ads, int serv, adns_query qu, const char *fmt, ...) { 00103 va_list al; 00104 00105 va_start(al,fmt); 00106 adns__vdiag(ads,"",adns_if_noerrprint,serv,qu,fmt,al); 00107 va_end(al); 00108 } 00109 00110 /* vbuf functions */ 00111 00112 void adns__vbuf_init(vbuf *vb) { 00113 vb->used= vb->avail= 0; vb->buf= 0; 00114 } 00115 00116 int adns__vbuf_ensure(vbuf *vb, int want) { 00117 void *nb; 00118 00119 if (vb->avail >= want) return 1; 00120 nb= realloc(vb->buf, (size_t) want); if (!nb) return 0; 00121 vb->buf= nb; 00122 vb->avail= want; 00123 return 1; 00124 } 00125 00126 void adns__vbuf_appendq(vbuf *vb, const byte *data, int len) { 00127 memcpy(vb->buf+vb->used,data, (size_t) len); 00128 vb->used+= len; 00129 } 00130 00131 int adns__vbuf_append(vbuf *vb, const byte *data, int len) { 00132 int newlen; 00133 void *nb; 00134 00135 newlen= vb->used+len; 00136 if (vb->avail < newlen) { 00137 if (newlen<20) newlen= 20; 00138 newlen <<= 1; 00139 nb= realloc(vb->buf,(size_t) newlen); 00140 if (!nb) { newlen= vb->used+len; nb= realloc(vb->buf, (size_t) newlen); } 00141 if (!nb) return 0; 00142 vb->buf= nb; 00143 vb->avail= newlen; 00144 } 00145 adns__vbuf_appendq(vb,data,len); 00146 return 1; 00147 } 00148 00149 int adns__vbuf_appendstr(vbuf *vb, const char *data) { 00150 int l; 00151 l= strlen(data); 00152 return adns__vbuf_append(vb,(byte*)data,l); 00153 } 00154 00155 void adns__vbuf_free(vbuf *vb) { 00156 free(vb->buf); 00157 adns__vbuf_init(vb); 00158 } 00159 00160 /* Additional diagnostic functions */ 00161 00162 const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, 00163 vbuf *vb, const byte *dgram, int dglen, int cbyte) { 00164 adns_status st; 00165 00166 st= adns__parse_domain(ads,serv,qu,vb, pdf_quoteok, dgram,dglen,&cbyte,dglen); 00167 if (st == adns_s_nomemory) { 00168 return "<cannot report domain... out of memory>"; 00169 } 00170 if (st) { 00171 vb->used= 0; 00172 if (!(adns__vbuf_appendstr(vb,"<bad format... ") && 00173 adns__vbuf_appendstr(vb,adns_strerror(st)) && 00174 adns__vbuf_appendstr(vb,">") && 00175 adns__vbuf_append(vb,(byte*)"",1))) { 00176 return "<cannot report bad format... out of memory>"; 00177 } 00178 } 00179 if (!vb->used) { 00180 adns__vbuf_appendstr(vb,"<truncated ...>"); 00181 adns__vbuf_append(vb,(byte*)"",1); 00182 } 00183 return (char*)vb->buf; 00184 } 00185 00186 adns_status adns_rr_info(adns_rrtype type, 00187 const char **rrtname_r, const char **fmtname_r, 00188 int *len_r, 00189 const void *datap, char **data_r) { 00190 const typeinfo *typei; 00191 vbuf vb; 00192 adns_status st; 00193 00194 typei= adns__findtype(type); 00195 if (!typei) return adns_s_unknownrrtype; 00196 00197 if (rrtname_r) *rrtname_r= typei->rrtname; 00198 if (fmtname_r) *fmtname_r= typei->fmtname; 00199 if (len_r) *len_r= typei->rrsz; 00200 00201 if (!datap) return adns_s_ok; 00202 00203 adns__vbuf_init(&vb); 00204 st= typei->convstring(&vb,datap); 00205 if (st) goto x_freevb; 00206 if (!adns__vbuf_append(&vb,(byte*)"",1)) { st= adns_s_nomemory; goto x_freevb; } 00207 assert((int)strlen((char*)vb.buf) == vb.used-1); 00208 *data_r= realloc(vb.buf, (size_t) vb.used); 00209 if (!*data_r) *data_r= (char*)vb.buf; 00210 return adns_s_ok; 00211 00212 x_freevb: 00213 adns__vbuf_free(&vb); 00214 return st; 00215 } 00216 00217 00218 #define SINFO(n,s) { adns_s_##n, #n, s } 00219 00220 static const struct sinfo { 00221 adns_status st; 00222 const char *abbrev; 00223 const char *string; 00224 } sinfos[]= { 00225 SINFO( ok, "OK" ), 00226 00227 SINFO( nomemory, "Out of memory" ), 00228 SINFO( unknownrrtype, "Query not implemented in DNS library" ), 00229 SINFO( systemfail, "General resolver or system failure" ), 00230 00231 SINFO( timeout, "DNS query timed out" ), 00232 SINFO( allservfail, "All nameservers failed" ), 00233 SINFO( norecurse, "Recursion denied by nameserver" ), 00234 SINFO( invalidresponse, "Nameserver sent bad response" ), 00235 SINFO( unknownformat, "Nameserver used unknown format" ), 00236 00237 SINFO( rcodeservfail, "Nameserver reports failure" ), 00238 SINFO( rcodeformaterror, "Query not understood by nameserver" ), 00239 SINFO( rcodenotimplemented, "Query not implemented by nameserver" ), 00240 SINFO( rcoderefused, "Query refused by nameserver" ), 00241 SINFO( rcodeunknown, "Nameserver sent unknown response code" ), 00242 00243 SINFO( inconsistent, "Inconsistent resource records in DNS" ), 00244 SINFO( prohibitedcname, "DNS alias found where canonical name wanted" ), 00245 SINFO( answerdomaininvalid, "Found syntactically invalid domain name" ), 00246 SINFO( answerdomaintoolong, "Found overly-long domain name" ), 00247 SINFO( invaliddata, "Found invalid DNS data" ), 00248 00249 SINFO( querydomainwrong, "Domain invalid for particular DNS query type" ), 00250 SINFO( querydomaininvalid, "Domain name is syntactically invalid" ), 00251 SINFO( querydomaintoolong, "Domain name or component is too long" ), 00252 00253 SINFO( nxdomain, "No such domain" ), 00254 SINFO( nodata, "No such data" ) 00255 }; 00256 00257 static int si_compar(const void *key, const void *elem) { 00258 const adns_status *st= key; 00259 const struct sinfo *si= elem; 00260 00261 return *st < si->st ? -1 : *st > si->st ? 1 : 0; 00262 } 00263 00264 static const struct sinfo *findsinfo(adns_status st) { 00265 return bsearch(&st,sinfos,sizeof(sinfos)/sizeof(*sinfos),sizeof(*sinfos),si_compar); 00266 } 00267 00268 const char *adns_strerror(adns_status st) { 00269 const struct sinfo *si; 00270 00271 si= findsinfo(st); 00272 return si->string; 00273 } 00274 00275 const char *adns_errabbrev(adns_status st) { 00276 const struct sinfo *si; 00277 00278 si= findsinfo(st); 00279 return si->abbrev; 00280 } 00281 00282 00283 #define STINFO(max) { adns_s_max_##max, #max } 00284 00285 static const struct stinfo { 00286 adns_status stmax; 00287 const char *abbrev; 00288 } stinfos[]= { 00289 { adns_s_ok, "ok" }, 00290 STINFO( localfail ), 00291 STINFO( remotefail ), 00292 STINFO( tempfail ), 00293 STINFO( misconfig ), 00294 STINFO( misquery ), 00295 STINFO( permfail ) 00296 }; 00297 00298 static int sti_compar(const void *key, const void *elem) { 00299 const adns_status *st= key; 00300 const struct stinfo *sti= elem; 00301 00302 adns_status here, min, max; 00303 00304 here= *st; 00305 min= (sti==stinfos) ? 0 : sti[-1].stmax+1; 00306 max= sti->stmax; 00307 00308 return here < min ? -1 : here > max ? 1 : 0; 00309 } 00310 00311 const char *adns_errtypeabbrev(adns_status st) { 00312 const struct stinfo *sti; 00313 00314 sti= bsearch(&st,stinfos,sizeof(stinfos)/sizeof(*stinfos),sizeof(*stinfos),sti_compar); 00315 return sti->abbrev; 00316 } 00317 00318 00319 void adns__isort(void *array, int nobjs, int sz, void *tempbuf, 00320 int (*needswap)(void *context, const void *a, const void *b), 00321 void *context) { 00322 byte *data= array; 00323 int i, place; 00324 00325 for (i=0; i<nobjs; i++) { 00326 for (place= i; 00327 place>0 && needswap(context, data + (place-1)*sz, data + i*sz); 00328 place--); 00329 if (place != i) { 00330 memcpy(tempbuf, data + i*sz, (size_t) sz); 00331 memmove(data + (place+1)*sz, data + place*sz, (size_t) (i-place)*sz); 00332 memcpy(data + place*sz, tempbuf, (size_t) sz); 00333 } 00334 } 00335 } 00336 00337 /* SIGPIPE protection. */ 00338 /* Not required under Win32 with MSVC */ 00339 00340 void adns__sigpipe_protect(adns_state ads) { 00341 #ifndef ADNS_JGAA_WIN32 00342 sigset_t toblock; 00343 struct sigaction sa; 00344 int r; 00345 00346 if (ads->iflags & adns_if_nosigpipe) return; 00347 00348 sigfillset(&toblock); 00349 sigdelset(&toblock,SIGPIPE); 00350 00351 sa.sa_handler= SIG_IGN; 00352 sigfillset(&sa.sa_mask); 00353 sa.sa_flags= 0; 00354 00355 r= sigprocmask(SIG_SETMASK,&toblock,&ads->stdsigmask); assert(!r); 00356 r= sigaction(SIGPIPE,&sa,&ads->stdsigpipe); assert(!r); 00357 #endif 00358 } 00359 00360 void adns__sigpipe_unprotect(adns_state ads) { 00361 #ifndef ADNS_JGAA_WIN32 00362 int r; 00363 00364 if (ads->iflags & adns_if_nosigpipe) return; 00365 00366 r= sigaction(SIGPIPE,&ads->stdsigpipe,0); assert(!r); 00367 r= sigprocmask(SIG_SETMASK,&ads->stdsigmask,0); assert(!r); 00368 #endif 00369 } Generated on Sun May 27 2012 04:20:50 for ReactOS by
1.7.6.1
|