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

general.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 doxygen 1.7.6.1

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