+int adns_submit(adns_state ads,
+ const char *owner,
+ adns_rrtype type,
+ adns_queryflags flags,
+ void *context,
+ adns_query *query_r) {
+ qcontext ctx;
+ int id, r, ol;
+ vbuf vb;
+ adns_status stat;
+ const typeinfo *typei;
+ struct timeval now;
+
+ typei= adns__findtype(type);
+ if (!typei) return adns_s_notimplemented;
+
+ ctx.ext= context;
+ r= gettimeofday(&now,0); if (r) return errno;
+ id= 0;
+
+ adns__vbuf_init(&vb);
+
+ ol= strlen(owner);
+ if (ol<=1 || ol>DNS_MAXDOMAIN+1) { stat= adns_s_domaintoolong; goto xit; }
+
+ if (owner[ol-1]=='.' && owner[ol-2]!='\\') { flags &= ~adns_qf_search; ol--; }
+
+ stat= adns__mkquery(ads,&vb,&id, owner,ol, typei,flags);
+
+ xit:
+ return adns__internal_submit(ads,query_r, typei,&vb,id, flags,now, stat,&ctx);
+}
+
+int adns_synchronous(adns_state ads,
+ const char *owner,
+ adns_rrtype type,
+ adns_queryflags flags,
+ adns_answer **answer_r) {
+ adns_query qu;
+ int r;
+
+ r= adns_submit(ads,owner,type,flags,0,&qu);
+ if (r) return r;
+
+ r= adns_wait(ads,&qu,answer_r,0);
+ if (r) adns_cancel(qu);
+
+ return r;
+}
+
+static void *alloc_common(adns_query qu, size_t sz) {
+ allocnode *an;
+
+ if (!sz) return qu; /* Any old pointer will do */
+ assert(!qu->final_allocspace);
+ an= malloc(MEM_ROUND(MEM_ROUND(sizeof(*an)) + sz));
+ if (!an) return 0;
+ an->next= qu->allocations;
+ qu->allocations= an;
+ return (byte*)an + MEM_ROUND(sizeof(*an));
+}
+
+void *adns__alloc_interim(adns_query qu, size_t sz) {
+ sz= MEM_ROUND(sz);
+ qu->interim_allocd += sz;
+ return alloc_common(qu,sz);
+}
+
+void *adns__alloc_mine(adns_query qu, size_t sz) {
+ return alloc_common(qu,MEM_ROUND(sz));
+}
+
+void *adns__alloc_final(adns_query qu, size_t sz) {
+ /* When we're in the _final stage, we _subtract_ from interim_alloc'd
+ * each allocation, and use final_allocspace to point to the next free
+ * bit.