+
+int adns__getrrsz_default(const typeinfo *typei, adns_rrtype type)
+ { return typei->fixed_rrsz; }
+
+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_unknownrrtype;
+
+ if (rrtname_r) *rrtname_r= typei->rrtname;
+ if (fmtname_r) *fmtname_r= typei->fmtname;
+ if (len_r) *len_r= typei->getrrsz(typei, type);
+
+ if (!datap) return adns_s_ok;
+
+ adns__vbuf_init(&vb);
+ st= typei->convstring(&vb,type,datap);
+ if (st) goto x_freevb;
+ if (!adns__vbuf_append(&vb,"",1)) { st= adns_s_nomemory; 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, #n, s }
+
+static const struct sinfo {
+ adns_status st;
+ const char *abbrev;
+ const char *string;
+} sinfos[]= {
+ SINFO( ok, "OK" ),
+
+ SINFO( nomemory, "Out of memory" ),
+ SINFO( unknownrrtype, "Query not implemented in DNS library" ),
+ SINFO( systemfail, "General resolver or system failure" ),
+
+ SINFO( timeout, "DNS query timed out" ),
+ SINFO( allservfail, "All nameservers failed" ),
+ SINFO( norecurse, "Recursion denied by nameserver" ),
+ SINFO( invalidresponse, "Nameserver sent bad response" ),
+ SINFO( unknownformat, "Nameserver used unknown format" ),
+
+ SINFO( rcodeservfail, "Nameserver reports failure" ),
+ SINFO( rcodeformaterror, "Query not understood by nameserver" ),
+ SINFO( rcodenotimplemented, "Query not implemented by nameserver" ),
+ SINFO( rcoderefused, "Query refused by nameserver" ),
+ SINFO( rcodeunknown, "Nameserver sent unknown response code" ),
+
+ SINFO( inconsistent, "Inconsistent resource records in DNS" ),
+ SINFO( prohibitedcname, "DNS alias found where canonical name wanted" ),
+ SINFO( answerdomaininvalid, "Found syntactically invalid domain name" ),
+ SINFO( answerdomaintoolong, "Found overly-long domain name" ),
+ SINFO( invaliddata, "Found invalid DNS data" ),
+
+ SINFO( querydomainwrong, "Domain invalid for particular DNS query type" ),
+ SINFO( querydomaininvalid, "Domain name is syntactically invalid" ),
+ SINFO( querydomaintoolong, "Domain name or component is too long" ),
+
+ SINFO( nxdomain, "No such domain" ),
+ SINFO( nodata, "No such data" )
+};
+
+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;
+}
+
+static const struct sinfo *findsinfo(adns_status st) {
+ return bsearch(&st,sinfos, sizeof(sinfos)/sizeof(*sinfos),
+ sizeof(*sinfos), si_compar);
+}
+