From 07851a4895f9c5bd446b102e20e341936346ad63 Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 19 Dec 2004 20:35:08 +0000 Subject: [PATCH] reassemble adns log messages --- adns/adns.c | 58 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/adns/adns.c b/adns/adns.c index e768cd6..01f0dc6 100644 --- a/adns/adns.c +++ b/adns/adns.c @@ -58,6 +58,10 @@ * cancels outstanding queries */ +#define _GNU_SOURCE + +#include + #include "tables.h" #include "hbytes.h" @@ -125,7 +129,7 @@ static int oifn_reverse_any(Tcl_Interp *ip, const OptionInfo *oi, static void optparse_blank(OptionParse *op) { memset(op,0,sizeof(*op)); - op->errfile= 0; + op->errfile= stderr; op->errcallback= 0; op->config_string= 0; } @@ -170,6 +174,7 @@ struct Resolver { int maxfd; fd_set handling[3]; ScriptToInvoke errcallback; + Tcl_Obj *errstring_accum; }; /* The default resolver is recorded using Tcl_SetAssocData with key @@ -220,9 +225,36 @@ static const OptionInfo resolver_optioninfos[]= { { 0 } }; +static void adnslogfn_flushmessage(Resolver *res) { + scriptinv_invoke(&res->errcallback, 1, &res->errstring_accum); + Tcl_SetObjLength(res->errstring_accum, 0); +} + static void adnslogfn_callback(adns_state ads, void *logfndata, const char *fmt, va_list al) { - abort(); /* fixme implement adns_logcallbackfn */ + Resolver *res= logfndata; + int l, newline; + char *str; + + l= vasprintf(&str,fmt,al); + if (l<0) { + posixerr(res->interp,errno,"construct adns log callback string"); + Tcl_BackgroundError(res->interp); + } + + if (l==0) { free(str); return; } + if ((newline= l>0 && str[l-1]=='\n')) l--; + + if (!res->errstring_accum) { + res->errstring_accum= Tcl_NewStringObj(str,l); + Tcl_IncrRefCount(res->errstring_accum); + } else { + Tcl_AppendToObj(res->errstring_accum,str,l); + } + free(str); + + if (newline) + adnslogfn_flushmessage(res); } static Resolver *default_resolver(Tcl_Interp *ip) { @@ -231,11 +263,20 @@ static Resolver *default_resolver(Tcl_Interp *ip) { static void destroy_resolver(Tcl_Interp *ip, Resolver *res) { void *query_v; + int logstring_len; + char *rstr; adns_query aqu; if (res == default_resolver(ip)) Tcl_DeleteAssocData(ip,ASSOC_DEFAULTRES); + if (res->errstring_accum) { + rstr= Tcl_GetStringFromObj(res->errstring_accum, &logstring_len); + assert(rstr); + if (logstring_len) + adnslogfn_flushmessage(res); + } + if (res->ads) { /* although adns would throw these away for us, we need to * destroy our own data too and only adns has a list of them */ @@ -248,6 +289,7 @@ static void destroy_resolver(Tcl_Interp *ip, Resolver *res) { adns_finish(res->ads); } asynch_cancelhandlers(res); + scriptinv_cancel(&res->errcallback); TFREE(res); } @@ -275,20 +317,20 @@ static int create_resolver(Tcl_Interp *ip, const OptionParse *op, res->ads= 0; res->timertoken= 0; res->maxfd= 0; - scriptinv_init(&res->errcallback); for (i=0; i<3; i++) FD_ZERO(&res->handling[i]); + scriptinv_init(&res->errcallback); + res->errstring_accum= 0; + + if (op->errcallback) + scriptinv_set(&res->errcallback, ip, op->errcallback, 0); ec= adns_init_logfn(&res->ads, op->aflags | adns_if_noautosys, op->config_string, op->errcallback ? adnslogfn_callback : 0, - op->errcallback ? (void*)op->errcallback - : (void*)op->errfile); + op->errcallback ? (void*)res : (void*)op->errfile); if (ec) { rc= posixerr(ip,ec,"create adns resolver"); goto x_rc; } - if (op->errcallback) - scriptinv_set(&res->errcallback, ip, op->errcallback, 0); - *res_r= res; return TCL_OK; -- 2.30.2