chiark / gitweb /
Use struct sockaddr in several places; distinguish various places where
[adns.git] / src / general.c
index 2ced4c06b6c35a390bdc49924613730b58b46664..8311dd7d5eb1d0f3559475c15c93f546fce6e18f 100644 (file)
@@ -46,9 +46,11 @@ void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent,
     adns__vbuf_init(&vb);
     fprintf(stderr,"%sQNAME=%s, QTYPE=%s",
            bef,
-           adns__diag_domain(qu->ads,-1,0, &vb,qu->flags,
+           adns__diag_domain(qu->ads,-1,0, &vb,
                              qu->query_dgram,qu->query_dglen,DNS_HDRSIZE),
-           qu->typei ? qu->typei->name : "<unknown>");
+           qu->typei ? qu->typei->rrtname : "<unknown>");
+    if (qu->typei && qu->typei->fmtname)
+      fprintf(stderr,"(%s)",qu->typei->fmtname);
     bef=", "; aft=")\n";
   }
   
@@ -111,9 +113,10 @@ int adns__vbuf_append(vbuf *vb, const byte *data, int len) {
 
   newlen= vb->used+len;
   if (vb->avail < newlen) {
+    if (newlen<20) newlen= 20;
     newlen <<= 1;
     nb= realloc(vb->buf,newlen);
-    if (!nb) { newlen >>= 1; nb= realloc(vb->buf,newlen); }
+    if (!nb) { newlen= vb->used+len; nb= realloc(vb->buf,newlen); }
     if (!nb) return 0;
     vb->buf= nb;
     vb->avail= newlen;
@@ -122,13 +125,24 @@ int adns__vbuf_append(vbuf *vb, const byte *data, int len) {
   return 1;
 }
 
+int adns__vbuf_appendstr(vbuf *vb, const char *data) {
+  int l;
+  l= strlen(data);
+  return adns__vbuf_append(vb,data,l);
+}
+
+void adns__vbuf_free(vbuf *vb) {
+  free(vb->buf);
+  adns__vbuf_init(vb);
+}
+
 /* Additional diagnostic functions */
 
-const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb,
-                             int flags, const byte *dgram, int dglen, int cbyte) {
+const char *adns__diag_domain(adns_state ads, int serv, adns_query qu,
+                             vbuf *vb, const byte *dgram, int dglen, int cbyte) {
   adns_status st;
 
-  st= adns__parse_domain(ads,serv,qu,vb, flags,dgram,dglen,&cbyte,dglen);
+  st= adns__parse_domain(ads,serv,qu,vb, pdf_quoteok, dgram,dglen,&cbyte,dglen);
   if (st == adns_s_nolocalmem) {
     return "<cannot report domain... out of memory>";
   }
@@ -147,9 +161,80 @@ const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb,
   }
   return vb->buf;
 }
-    
+
+adns_status adns_rr_info(adns_rrtype type,
+                        const char **rrtname_r, const char **fmtname_r,
+                        int *len_r,
+                        const void *datap, char **data_r) {
+  const typeinfo *typei;
+  vbuf vb;
+  adns_status st;
+
+  typei= adns__findtype(type);
+  if (!typei) return adns_s_notimplemented;
+
+  if (rrtname_r) *rrtname_r= typei->rrtname;
+  if (fmtname_r) *fmtname_r= typei->fmtname;
+  if (len_r) *len_r= typei->rrsz;
+
+  if (!datap) return adns_s_ok;
+  
+  adns__vbuf_init(&vb);
+  st= typei->convstring(&vb,datap);
+  if (st) goto x_freevb;
+  if (!adns__vbuf_append(&vb,"",1)) { st= adns_s_nolocalmem; goto x_freevb; }
+  assert(strlen(vb.buf) == vb.used-1);
+  *data_r= realloc(vb.buf,vb.used);
+  if (!*data_r) *data_r= vb.buf;
+  return adns_s_ok;
+
+ x_freevb:
+  adns__vbuf_free(&vb);
+  return st;
+}
+
+#define SINFO(n,s) { adns_s_##n, s }
+
+static const struct sinfo {
+  adns_status st;
+  const char *string;
+} sinfos[]= {
+  SINFO(  ok,                  "OK"                                    ),
+  SINFO(  timeout,             "Timed out"                             ),
+  SINFO(  nolocalmem,          "Out of memory"                         ),
+  SINFO(  allservfail,         "No working nameservers"                ),
+  SINFO(  servfail,            "Nameserver failure"                    ),
+  SINFO(  notimplemented,      "Query not implemented"                 ),
+  SINFO(  refused,             "Refused by nameserver"                 ),
+  SINFO(  reasonunknown,       "Reason unknown"                        ),
+  SINFO(  norecurse,           "Recursion denied by nameserver"        ),
+  SINFO(  serverfaulty,        "Nameserver sent bad data"              ),
+  SINFO(  unknownreply,        "Reply from nameserver not understood"  ),
+  SINFO(  invaliddata,         "Invalid data"                          ),
+  SINFO(  inconsistent,        "Inconsistent data"                     ),
+  SINFO(  cname,               "RR refers to an alias"                 ),
+  SINFO(  invalidanswerdomain, "Received syntactically invalid domain" ),
+  SINFO(  nxdomain,            "No such domain"                        ),
+  SINFO(  nodata,              "No such data"                          ),
+  SINFO(  invalidquerydomain,  "Domain syntactically invalid"          ),
+  SINFO(  domaintoolong,       "Domain name too long"                  )
+};
+
+static int si_compar(const void *key, const void *elem) {
+  const adns_status *st= key;
+  const struct sinfo *si= elem;
+
+  return *st < si->st ? -1 : *st > si->st ? 1 : 0;
+}
+
 const char *adns_strerror(adns_status st) {
   static char buf[100];
+
+  const struct sinfo *si;
+
+  si= bsearch(&st,sinfos,sizeof(sinfos)/sizeof(*si),sizeof(*si),si_compar);
+  if (si) return si->string;
+  
   snprintf(buf,sizeof(buf),"code %d",st);
   return buf;
 }