• Patch: Elm ME+ 2.5 PLalpha46 -> Elm ME+ 2.5 PLalpha47 [5/7] (6/7)

    From Kari Hurtta@21:1/5 to All on Sat Feb 10 14:46:35 2018
    [continued from previous message]

    + DPRINT(Debug,14,(&Debug,
    + "query_one_name: [pid %d] query %lu %s: failed to parse query\n",
    + pid,
    + (unsigned long)querynum,
    + name_buffer ? name_buffer : name));
    + free_resolv_query_item(&ret);
    + goto failure;
    + }
    +
    + inc_resolv_query_item_recount(ret);
    +
    + select_resolv_process(pid,querynum,name_buffer ? name_buffer : name);
    +
    + failure:
    + if (name_buffer)
    + free(name_buffer);
    +
    + DPRINT(Debug,14,(&Debug, "query_one_name=%p [pid %d]",ret,pid));
    +
    + if (*err_p) {
    + DPRINT(Debug,14,(&Debug, "; *err_p=%d",*err_p));
    + }
    +
    + DPRINT(Debug,14,(&Debug, "\n"));
    +
    + return ret;
    + }
    +
    +
    + /* Returns 1 is answer is already ready */
    + static int resolv_answer_ready P_((struct resolv_query_item * qitem,
    + int * resize,
    + int pid));
    + static int resolv_answer_ready(qitem,resize,pid)
    + struct resolv_query_item * qitem;
    + int * resize;
    + int pid;
    + {
    + int done = 0;
    +
    + if (RESOLV_QUERY_ITEM_magic != qitem->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "resolv_answer_ready",
    + "Bad magic number (resolv_query_item)",0);
    +
    + DPRINT(Debug,16,(&Debug,
    + "resolv_answer_ready: [pid %d] start --------------------------\n",
    + pid));
    + DPRINT(Debug,16,(&Debug,
    + " : querynum = %lu\n",
    + (unsigned long)qitem->querynum));
    + DPRINT(Debug,16,(&Debug,
    + " : name = %s\n",
    + qitem->name ? qitem->name : "<none>"));
    + DPRINT(Debug,16,(&Debug,
    + " : last_errno = %d\n",
    + qitem->last_errno));
    + DPRINT(Debug,16,(&Debug,
    + " : looking_up = %d",
    + qitem->looking_up));
    + switch (qitem->looking_up) {
    + case l_up_none: DPRINT(Debug,16,(&Debug," (none)")); break;
    + case l_up_printed: DPRINT(Debug,16,(&Debug," (printed)")); break;
    + case l_up_error: DPRINT(Debug,16,(&Debug," (error)")); break;
    + case l_up_truncated_retry: DPRINT(Debug,16,(&Debug," (truncated retry)")); break;
    + case l_up_stalled: DPRINT(Debug,16,(&Debug," (stalled)")); break;
    + }
    + DPRINT(Debug,16,(&Debug,"\n"));
    + DPRINT(Debug,16,(&Debug,
    + " : fill_have_error = %d\n",
    + qitem->fill_have_error));
    + DPRINT(Debug,16,(&Debug,
    + " : transient_error = %d\n",
    + qitem->transient_error));
    + DPRINT(Debug,16,(&Debug,
    + " : other = %d\n",
    + qitem->other));
    + DPRINT(Debug,16,(&Debug,
    + " : is_search = %d\n",
    + qitem->is_search));
    + DPRINT(Debug,16,(&Debug,
    + " : query_sent = %d\n",
    + qitem->query_sent));
    + DPRINT(Debug,16,(&Debug,
    + " : valid_answer = %d\n",
    + qitem->valid_answer));
    + DPRINT(Debug,16,(&Debug,
    + " : invalid_answer = %d\n",
    + qitem->invalid_answer));
    + DPRINT(Debug,16,(&Debug,
    + " : shutdown = %d\n",
    + qitem->shutdown));
    + DPRINT(Debug,16,(&Debug,
    + "resolv_answer_ready: [pid %d] --------------------------------\n",
    + pid));
    +
    + if (qitem->last_errno) {
    + DPRINT(Debug,14,(&Debug,
    + "resolv_answer_ready: [pid %d] query %lu %s: done, error %d (%s)\n",
    + pid,(unsigned long)qitem->querynum,
    + qitem->name ? qitem->name : "<none>",
    + qitem->last_errno,strerror(qitem->last_errno)));
    +
    + if (resize && EMSGSIZE == qitem->last_errno && qitem->answer_buffer) { + struct resolv_message * answer_buffer = qitem->answer_buffer;
    +
    + if (RESOLV_MESSAGE_magic != answer_buffer->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "resolv_answer_ready",
    + "Bad magic number (resolv_message)",0);
    +
    + if (answer_buffer->message_size < MAX_resolv_bufsize) {
    + DPRINT(Debug,14,(&Debug,
    + "resolv_answer_ready: [pid %d] query %lu %s: message size %lu, can resized\n",
    + pid,(unsigned long)qitem->querynum,
    + qitem->name ? qitem->name : "<none>",
    + (unsigned long)answer_buffer->message_size)); + *resize = 1;
    + } else
    + goto no_resize;
    +
    + } else {
    + no_resize:
    + if (qitem->looking_up < l_up_error && qitem->name) {
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookError,
    + "Looking up %s: %s"),
    + qitem->name,strerror(qitem->last_errno));
    + qitem->looking_up = l_up_error;
    + }
    + }
    + done = 1;
    +
    + } else if (qitem->fill_have_error ||
    + qitem->transient_error ||
    + qitem->valid_answer ||
    + qitem->failed_answer ||
    + qitem->invalid_answer ||
    + qitem->shutdown) {
    + DPRINT(Debug,14,(&Debug,
    + "resolv_answer_ready: [pid %d] query %lu %s: done%s%s%s%s%s\n",
    + pid,(unsigned long)qitem->querynum,
    + qitem->name ? qitem->name : "<none>",
    + qitem->fill_have_error ? ", fill have error" : "",
    + qitem->transient_error ? ", (fill have) transient error" : "",
    + qitem->valid_answer ? ", valid answer" : "",
    + qitem->invalid_answer ? ", invalid answer" : "",
    + qitem->shutdown ? ", shutdown" : ""));
    +
    + done = 1;
    + } else if (qitem->answer_buffer) {
    + struct resolv_message * answer_buffer = qitem->answer_buffer;
    +
    + if (RESOLV_MESSAGE_magic != answer_buffer->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "resolv_answer_ready",
    + "Bad magic number (resolv_message)",0);
    +
    + if (answer_buffer->message_parsed) {
    + DPRINT(Debug,14,(&Debug,
    + "resolv_answer_ready: [pid %d] query %lu %s: done, message parsed\n",
    + pid,(unsigned long)qitem->querynum,
    + qitem->name ? qitem->name : "<none>"));
    +
    + done=1;
    + }
    + }
    +
    + DPRINT(Debug,14,(&Debug,
    + "resolv_answer_ready=%d (%s): [pid %d] query %lu %s",
    + done,
    + done ? "done" : "not done",
    + pid,(unsigned long)qitem->querynum,
    + qitem->name ? qitem->name : "<none>"));
    +
    + if (resize) {
    + DPRINT(Debug,14,(&Debug,"; *resize=%d",
    + *resize));
    + }
    +
    + DPRINT(Debug,14,(&Debug,"\n"));
    +
    + return done;
    +
    + }
    +
    + #define STALLED_SECONDS_DEFAULT (5 * 60)
    + static const int MAX_stalled_seconds = (STALLED_SECONDS_DEFAULT > (60 *60)) ? STALLED_SECONDS_DEFAULT : (60 *60);
    + static const int MIN_stalled_seconds = (STALLED_SECONDS_DEFAULT < 30) ? STALLED_SECONDS_DEFAULT : 30;
    +
    + static char resolv_stalled_seconds_value[SHORT]; /* cache exact string */
    + static int resolv_stalled_seconds
    + #if defined(RESOLV_SENDOK) && defined(RESOLV_SEQPACKET) && defined(BACKGROUD_PROCESSES)
    + = STALLED_SECONDS_DEFAULT /* deadline 5 minutes from reference time of query */
    + #endif
    + ;
    +
    +
    + /* return 1 if got answer */
    + static int resolv_wait_answer P_((struct resolv_query_item * qitem,
    + int * resize,
    + struct cancel_data ** cancel_p));
    + static int resolv_wait_answer(qitem, resize, cancel_p)
    + struct resolv_query_item * qitem;
    + int * resize;
    + struct cancel_data ** cancel_p
    + /* May be NULL, Used if dns lookup was cancelable
    + -- not really canceled, just
    + stop waiting of result
    + */;
    + {
    +
    + char *X = NULL;
    + int pid = getpid();
    + struct schedule_timelimit wait_deadline = NO_schedule_timelimit;
    + struct schedule_timelimit current = NO_schedule_timelimit;
    + int done = 0;
    +
    + if (RESOLV_QUERY_ITEM_magic != qitem->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "resolv_wait_answer",
    + "Bad magic number (resolv_query_item)",0);
    +
    + if (resize)
    + *resize = 0;
    +
    + X = schedule_timeout_string(& (qitem->query_time));
    + if (X) {
    + DPRINT(Debug,14,(&Debug,
    + "resolv_wait_answer: [pid %d] query %lu %s: query time %s\n",
    + pid,(unsigned long)qitem->querynum,
    + qitem->name ? qitem->name : "<NONE>",X));
    + free(X); X = NULL;
    + }
    +
    + if (schedule_set_next_timeout0(&wait_deadline,& (qitem->query_time),resolv_stalled_seconds,
    + se_use_time_MAX)) {
    +
    + X = schedule_timeout_string(&wait_deadline);
    +
    + if (X) {
    + DPRINT(Debug,14,(&Debug,
    + "resolv_wait_answer: [pid %d] query %lu %s: wait deadline %s\n",
    + pid,(unsigned long)qitem->querynum,
    + qitem->name ? qitem->name : "<NONE>",X));
    + free(X); X = NULL;
    + }
    + }
    +
    + done = resolv_answer_ready(qitem,resize,pid);
    +
    + #if defined(RESOLV_SENDOK) && defined(RESOLV_SEQPACKET)
    + while (!done) {
    + enum wait_for_status r;
    +
    + errno = 0;
    +
    + if (cancel_p) {
    +
    + if (l_up_none == qitem->looking_up && qitem->name) {
    + if (!*cancel_p || is_schedule_cancel(*cancel_p,NULL)) {
    + r = wait_for_action_or_timeout_settime_c(resolv_read_message,1,&current,
    + *cancel_p);
    + } else {
    + DPRINT(Debug,14,(&Debug,
    + "resolv_wait_answer: 'Looking up' already printed.\n"));
    + qitem->looking_up = l_up_printed;
    +
    + r = wait_for_action_or_deadline_settime_c(resolv_read_message,&wait_deadline,
    + &current,*cancel_p);
    + }
    + } else {
    + r = wait_for_action_or_deadline_settime_c(resolv_read_message,&wait_deadline,
    + &current,*cancel_p); + }
    +
    + } else {
    + if (l_up_none == qitem->looking_up && qitem->name)
    + r = wait_for_action_or_timeout_settime(resolv_read_message,1,&current);
    + else
    + r = wait_for_action_or_deadline_settime(resolv_read_message,&wait_deadline,
    + &current);
    + }
    +
    + if (r > wait_for_none) {
    +
    + done = resolv_answer_ready(qitem,resize,pid);
    +
    + if (!done) {
    + if (l_up_none == qitem->looking_up && qitem->name) {
    +
    + if (qitem->looking_up < l_up_error && qitem->name) {
    + if (cancel_p && *cancel_p) {
    + if (is_schedule_cancel(*cancel_p,NULL))
    + set_cancel_message(*cancel_p,
    + -1 /* Show immediately */,
    + CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookingUp,
    + "Looking up %s ..."),
    + qitem->name);
    + else {
    + DPRINT(Debug,14,(&Debug,
    + "resolv_wait_answer: 'Looking up' already printed.\n"));
    + }
    +
    + } else
    + lib_transient(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookingUp,
    + "Looking up %s ..."),
    + qitem->name);
    + }
    +
    + qitem->looking_up = l_up_printed;
    +
    + /* Messages may wait events -- so recheck status .... */
    + done = resolv_answer_ready(qitem,resize,pid);
    +
    + } else if (schedule_timeout_reached(&wait_deadline,&current)) { + if (qitem->looking_up < l_up_error && qitem->name) {
    + lib_transient(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookingUpStalled,
    + "Looking up %s: Stalled (giving up)"),
    + qitem->name);
    +
    + qitem->looking_up = l_up_stalled;
    +
    + /* Messages may wait events -- so recheck status .... */
    + done = resolv_answer_ready(qitem,resize,pid);
    + }
    +
    + DPRINT(Debug,14,(&Debug,
    + "resolv_wait_answer: [pid %d] query %lu %s: timeout\n",
    + pid,(unsigned long)qitem->querynum,
    + qitem->name ? qitem->name : "<none>"));
    + goto timeout;
    + }
    + }
    + } else {
    + switch (r) {
    + int err;
    + case wait_for_done: break;
    + case wait_for_none:
    + DPRINT(Debug,14,(&Debug,
    + "resolv_wait_answer: [pid %d] query %lu %s: unexpected result from wait_for_action_or_...\n",
    + pid,(unsigned long)qitem->querynum,
    + qitem->name ? qitem->name : "<none>"));
    + break;
    + case wait_for_error:
    + err = errno;
    +
    + DPRINT(Debug,14,(&Debug,
    + "resolv_wait_answer: [pid %d] query %lu %s: errno=%d, %s\n",
    + pid,(unsigned long)qitem->querynum,
    + qitem->name ? qitem->name : "<none>",
    + err,strerror(err)));
    + if (err == EINTR && cancel_p && *cancel_p && is_canceled(*cancel_p)) {
    + DPRINT(Debug,12,(&Debug,
    + "bgconnect_wait_delay: wait canceled\n")); +
    + goto out;
    + }
    + break;
    + }
    + }
    + }
    + #endif
    +
    + out:
    + timeout:
    + X = schedule_timeout_string(&current);
    +
    + DPRINT(Debug,14,(&Debug,
    + "resolv_wait_answer=%d%s [pid %d] query %lu %s",
    + done,
    + done ? " (done) " : "",
    + pid,(unsigned long)qitem->querynum,
    + qitem->name ? qitem->name : "<none>"));
    + if (X) {
    + DPRINT(Debug,14,(&Debug," at %s",
    + X));
    + free(X);
    + }
    +
    + DPRINT(Debug,14,(&Debug,"\n"));
    + return done;
    + }
    +
    + /* input / output flags */
    + static const struct check_query_answer_f {
    + unsigned int have_error :1;
    + unsigned int other :1;
    + unsigned int no_name :1;
    + unsigned int end_search :1;
    + } NULL_check_query_answer_f = {
    + 0,0,0,0
    + };
    +
    + static struct resolv_cache * check_query_answer P_((struct resolv_query_item * query,
    + const char * name,
    + enum looking_up * looking_up_p,
    + char ** search_name_p,
    + struct check_query_answer_f * flags_p));
    + static struct resolv_cache * check_query_answer(query,name,looking_up_p,
    + search_name_p,flags_p)
    + struct resolv_query_item * query;
    + const char * name;
    + enum looking_up * looking_up_p;
    + char ** search_name_p;
    + struct check_query_answer_f * flags_p;
    + {
    + struct resolv_cache * ret = NULL;
    +
    + if (RESOLV_QUERY_ITEM_magic != query->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "check_query_answer",
    + "Bad magic number (resolv_query_item)",0);
    +
    +
    + DPRINT(Debug,14,(&Debug,
    + "check_query_answer: %s: query %lu %s: IN flags have_error:%d other:%d no_name:%d end_search:%d\n",
    + name,
    + (unsigned long)query->querynum,
    + query->name ? query->name : "<none>",
    + flags_p->have_error,
    + flags_p->other,
    + flags_p->no_name,
    + flags_p->end_search));
    +
    + if (query->answer_buffer) {
    + struct resolv_message * answer_buffer = query->answer_buffer;
    +
    + if (RESOLV_MESSAGE_magic != answer_buffer->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "check_query_answer",
    + "Bad magic number (resolv_message)",0);
    +
    + if (answer_buffer->message_parsed) {
    + ns_rcode response_code =
    + ns_msg_getflag(answer_buffer->parsed_message,
    + ns_f_rcode);
    + unsigned short aa UNUSED_VAROK =
    + ns_msg_getflag(answer_buffer->parsed_message,
    + ns_f_aa);
    +
    + DPRINT(Debug,14,(&Debug,
    + "check_query_answer: %s: query %lu %s: answer buffer: resonse code=%d, authorative=%d (%s)\n",
    + name,
    + (unsigned long)query->querynum,
    + query->name ? query->name : "<none>",
    + response_code,aa,
    + aa ? "yes" : "no"));
    +
    + if (ns_r_nxdomain == response_code) {
    +
    + DPRINT(Debug,14,(&Debug,
    + "check_query_answer: %s: query %lu %s: no name\n",
    + name,(unsigned long)query->querynum,
    + query->name ? query->name : "<none>"));
    + flags_p->no_name = 1;
    + }
    + }
    + }
    +
    + if (query->valid_answer) {
    + DPRINT(Debug,14,(&Debug,
    + "check_query_answer: %s: query %lu %s: valid answer set\n",
    + name,(unsigned long)query->querynum,
    + query->name ? query->name : "<none>"));
    +
    + if (query->other) { /* Name found, no more search */
    + flags_p->end_search = 1;
    + flags_p->other = 1;
    + }
    +
    + ret = query-> cache_answer_ret;
    + if (ret) {
    + inc_resolv_cache_refcount(ret);
    +
    + DPRINT(Debug,14,(&Debug,
    + "check_query_answer: %s: query %lu %s: got resolv cache record\n",
    + name,(unsigned long)query->querynum,
    + query->name ? query->name : "<none>"));
    + }
    +
    + if (search_name_p && query->answer_search_name) {
    +
    + if (*search_name_p) {
    + DPRINT(Debug,14,(&Debug,
    + "check_query_answer: %s: query %lu %s: changing *search_name_p: %s => %s\n",
    + name,(unsigned long)query->querynum,
    + query->name ? query->name : "<none>",
    + *search_name_p,
    + query->answer_search_name));
    +
    + *search_name_p = strmcpy(*search_name_p,query->answer_search_name);
    + } else {
    + DPRINT(Debug,14,(&Debug,
    + "check_query_answer: %s: query %lu %s: setting *search_name_p: %s\n",
    + name,(unsigned long)query->querynum,
    + query->name ? query->name : "<none>",
    + query->answer_search_name));
    +
    + *search_name_p = safe_strdup(query->answer_search_name);
    + }
    + }
    + }
    +
    + if (query->failed_answer) {
    +
    + struct resolv_query_hdr * answer_hdr = query->answer_hdr;
    +
    + DPRINT(Debug,14,(&Debug,
    + "check_query_answer: %s: query %lu %s: failed answer set\n",
    + name,(unsigned long)query->querynum,
    + query->name ? query->name : "<none>"));
    +
    + if (answer_hdr) {
    + if ( RESOLV_QUERY_HDR_magic != answer_hdr->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "check_query_answer",
    + "Bad magic number (resolv_query_hdr)",0);
    +
    + DPRINT(Debug,14,(&Debug,
    + "check_query_answer: %s: query %lu %s: answer hdr: h_errno=%d, errno=%d (%s)\n",
    + name,(unsigned long)query->querynum,
    + query->name ? query->name : "<none>",
    + answer_hdr->h_errno_val,answer_hdr->errno_val,
    + strerror(answer_hdr->errno_val)));
    +
    + switch(answer_hdr->h_errno_val) {
    + case HOST_NOT_FOUND:
    + if (query->looking_up < l_up_error) {
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookNotFound,
    + "Looking up %s: not found"),
    + name);
    +
    + query->looking_up = l_up_error;
    + if (looking_up_p)
    + *looking_up_p = l_up_error;
    + }
    +
    + flags_p->end_search = 1;
    + break;
    +
    + case NO_DATA:
    + flags_p->other = 1;
    + break;
    +
    + case TRY_AGAIN:
    +
    + if (query->looking_up < l_up_error) {
    + if (answer_hdr->errno_val)
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookErrno,
    + "Looking up %s: %s"),
    + name,strerror(answer_hdr->errno_val));
    + else
    + lib_transient(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookTryAgain,
    + "Looking up %s: not found yet"), + name);
    +
    + query->looking_up = l_up_error;
    + }
    +
    + flags_p->have_error= 1;
    + flags_p->end_search = 1;
    + break;
    +
    + case NO_RECOVERY:
    +
    + if (query->looking_up < l_up_error) {
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookBadName,
    + "Looking up %s: bad name or refused query"),
    + name);
    +
    + query->looking_up = l_up_error;
    + }
    +
    + flags_p->have_error = 1;
    + flags_p->end_search = 1;
    + break;
    +
    + case NETDB_INTERNAL:
    + default:
    +
    + if (answer_hdr->errno_val) {
    +
    + if (query->looking_up < l_up_error) {
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookErrno,
    + "Looking up %s: %s"),
    + name,strerror(answer_hdr->errno_val));
    + query->looking_up = l_up_error;
    + }
    +
    + flags_p->have_error = 1;
    + flags_p->end_search = 1;
    +
    + } else if (answer_hdr->h_errno_val) {
    +
    + if (query->looking_up < l_up_error) {
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookFailed,
    + "Looking up %s: failed"),
    + name);
    +
    + query->looking_up = l_up_error;
    + }
    +
    + flags_p->have_error = 1;
    + flags_p->end_search = 1;
    +
    + } else {
    + DPRINT(Debug,14,(&Debug,
    + "check_query_answer: %s: query %lu %s: no error data on failed answer\n",
    + name,(unsigned long)query->querynum,
    + query->name ? query->name : "<none>"));
    + }
    + break;
    + }
    + }
    + }
    +
    + if (query->transient_error) {
    + DPRINT(Debug,14,(&Debug,
    + "check_query_answer: %s: query %lu %s: fill have transient error set\n",
    + name,(unsigned long)query->querynum,
    + query->name ? query->name : "<none>"));
    + }
    +
    + if (query->fill_have_error) {
    +
    + DPRINT(Debug,14,(&Debug,
    + "check_query_answer: %s: query %lu %s: fill have error set\n",
    + name,(unsigned long)query->querynum,
    + query->name ? query->name : "<none>"));
    +
    + flags_p->have_error = 1;
    + flags_p->end_search = 1;
    +
    + if (query->looking_up < l_up_error) {
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookErrorProcess,
    + "Looking up %s: Failed to process answer"),
    + name);
    +
    + query->looking_up = l_up_error;
    + }
    +
    +
    + }
    +
    + if (looking_up_p)
    + *looking_up_p = query->looking_up;
    +
    + DPRINT(Debug,14,(&Debug,
    + "check_query_answer: %s: query %lu %s: OUT flags have_error:%d other:%d no_name:%d end_search:%d\n",
    + name,
    + (unsigned long)query->querynum,
    + query->name ? query->name : "<none>",
    + flags_p->have_error,
    + flags_p->other,
    + flags_p->no_name,
    + flags_p->end_search));
    +
    + return ret;
    + }
    +
    + /* return 1 if still have answer */
    + static int resize_query_answer P_((struct resolv_query_item * query,
    + int * resize,
    + struct cancel_data ** cancel_p));
    + static int resize_query_answer(query,resize,cancel_p)
    + struct resolv_query_item * query;
    + int * resize;
    + struct cancel_data ** cancel_p
    + /* May be NULL, Used if dns lookup was cancelable
    + -- not really canceled, just
    + stop waiting of result
    + */;
    + {
    + size_t asize = RESOLV_BUFSIZE;
    + int need_recheck = 0;
    + int answer_ok = 1;
    + int pid = getpid();
    +
    + if (RESOLV_QUERY_ITEM_magic != query->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "resize_query_answer",
    + "Bad magic number (resolv_query_item)",0);
    +
    + do {
    + int need_resize = 0;
    + int anslen = 0;
    +
    + if (resize) {
    + need_resize = *resize;
    +
    + if (need_resize) {
    + DPRINT(Debug,14,(&Debug,
    + "resize_query_answer: [pid %d] query %lu %s: resizing request %s set\n",
    + pid,
    + (unsigned long)query->querynum,
    + query->name ? query->name : "<none>",
    + need_recheck ? "still" : "already"));
    + *resize = 0;
    + }
    + }
    +
    + need_recheck = 0;
    +
    + if (query->answer_buffer) {
    + struct resolv_message * answer_buffer = query->answer_buffer;
    +
    + if (RESOLV_MESSAGE_magic != answer_buffer->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "check_query_answer",
    + "Bad magic number (resolv_message)",0);
    +
    + asize = answer_buffer->message_size;
    +
    + DPRINT(Debug,14,(&Debug,
    + "resize_query_answer: [pid %d] query %lu %s: answer size %lu\n",
    + pid,
    + (unsigned long)query->querynum,
    + query->name ? query->name : "<none>",
    + (unsigned long)asize));
    +
    + } else {
    + DPRINT(Debug,14,(&Debug,
    + "resize_query_answer: [pid %d] query %lu %s: no answer buffer?\n",
    + pid,
    + (unsigned long)query->querynum,
    + query->name ? query->name : "<none>"));
    +
    + query->answer_buffer = new_resolv_message();
    + need_resize = 1;
    + }
    +
    + if (query->answer_hdr) {
    +
    + struct resolv_query_hdr * answer_hdr = query->answer_hdr;
    +
    + if (RESOLV_QUERY_HDR_magic != answer_hdr->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "resize_query_answer",
    + "Bad magic number (resolv_query_hdr)",0);
    +
    + if (answer_hdr->errno_val) {
    + DPRINT(Debug,14,(&Debug,
    + "resize_query_answer: [pid %d] query %lu %s: answer hdr errno %d (%s), answer buffer message size %lu\n",
    + pid,
    + (unsigned long)query->querynum,
    + query->name ? query->name : "<none>",
    + answer_hdr->errno_val,
    + strerror(answer_hdr->errno_val),
    + (unsigned long)query->answer_buffer->message_size));
    +
    + if (EMSGSIZE == answer_hdr->errno_val &&
    + query->answer_buffer->message_size < MAX_resolv_bufsize) { + DPRINT(Debug,14,(&Debug,
    + "resize_query_answer: [pid %d] query %lu %s: answer buffer message size %lu, can resized\n",
    + pid,
    + (unsigned long)query->querynum,
    + query->name ? query->name : "<none>",
    + (unsigned long)query->answer_buffer->message_size));
    + need_resize = 1;
    +
    + anslen = query->answer_buffer->message_len;
    + }
    + }
    + }
    +
    +
    + if (need_resize) {
    +
    + if (asize < MAX_resolv_bufsize) {
    + size_t old UNUSED_VAROK = asize;
    +
    + if (asize < sizeof (struct resolv_sizeupdate))
    + asize = sizeof (struct resolv_sizeupdate);
    + else
    + asize <<= 1;
    +
    + if (asize > MAX_resolv_bufsize)
    + asize = MAX_resolv_bufsize;
    +
    + DPRINT(Debug,14,(&Debug,
    + "resize_query_answer: [pid %d] query %lu %s: resizing answer buffer message size %lu => %lu\n",
    + pid,
    + (unsigned long)query->querynum,
    + query->name ? query->name : "<none>",
    + (unsigned long)old,
    + (unsigned long)asize));
    +
    + if (anslen) {
    + lib_transient(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookTruncatedRetry,
    + "Looking up %s: Answer truncated (%d bytes), retrying..."),
    + query->name ? query->name : "<none>",
    + anslen);
    + query->looking_up = l_up_truncated_retry;
    + }
    +
    + resize_resolv_message(query->answer_buffer,asize);
    +
    + /* Reset answer data */
    + if (query->answer_hdr)
    + *(query->answer_hdr) = NULL_resolv_query_hdr;
    + query->last_errno = 0;
    + if (query->cache_answer_ret)
    + free_resolv_cache(& (query->cache_answer_ret));
    +
    + query->fill_have_error = 0;
    + query->transient_error = 0;
    + query->other = 0;
    + query->query_sent = 0; /* cause resent */
    + query->valid_answer = 0;
    + query->failed_answer = 0;
    + query-> invalid_answer = 0;
    + query->shutdown = 0;
    +
    + select_resolv_process(pid,query->querynum,
    + query->name ? query->name : "<none>");
    +
    +
    + answer_ok = resolv_wait_answer(query,resize,cancel_p);
    +
    + if (answer_ok) {
    + DPRINT(Debug,14,(&Debug,
    + "resize_query_answer: [pid %d] query %lu %s: got answer after resent\n",
    + pid,
    + (unsigned long)query->querynum,
    + query->name ? query->name : "<none>"));
    + need_recheck = 1;
    + } else
    + need_recheck = 0;
    +
    + } else
    + need_recheck = 0;
    +
    + } else
    + need_recheck = 0;
    +
    + if (need_recheck) {
    + DPRINT(Debug,14,(&Debug,
    + "resize_query_answer: [pid %d] query %lu %s: rechecking\n",
    + pid,
    + (unsigned long)query->querynum,
    + query->name ? query->name : "<none>"));
    + }
    +
    + } while (need_recheck);
    +
    + DPRINT(Debug,14,(&Debug,
    + "resize_query_answer%d%s: [pid %d] query %lu %s\n",
    + answer_ok,
    + answer_ok ? " (answer ok)" : " (no answer)",
    + pid,
    + (unsigned long)query->querynum,
    + query->name ? query->name : "<none>"));
    +
    +
    + return answer_ok;
    + }
    +
    +
    + static void end_query_helper P_((struct resolv_query_item ** query_p,
    + const int err,
    + const char * name,
    + struct resolv_cache ** ret_p,
    + enum looking_up * looking_up_p,
    + char ** search_name_p,
    + struct check_query_answer_f * flags_p,
    + struct cancel_data ** cancel_p
    + /* May be NULL, Used if dns lookup was cancelable
    + -- not really canceled, just
    + stop waiting of result
    + */));
    + static void end_query_helper(query_p,err,name,ret_p,looking_up_p,search_name_p,
    + flags_p,cancel_p)
    + struct resolv_query_item ** query_p;
    + const int err;
    + const char * name;
    + struct resolv_cache ** ret_p;
    + enum looking_up * looking_up_p;
    + char ** search_name_p;
    + struct check_query_answer_f * flags_p;
    + struct cancel_data ** cancel_p
    + /* May be NULL, Used if dns lookup was cancelable
    + -- not really canceled, just
    + stop waiting of result
    + */;
    + {
    +
    + if (*query_p) {
    + int resize = 0;
    +
    + if (RESOLV_QUERY_ITEM_magic != (*query_p)->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "end_query_helper",
    + "Bad magic number (resolv_query_item)",0);
    +
    + DPRINT(Debug,16,(&Debug,
    + "end_query_helper: %s: got query\n",
    + name));
    +
    + if (*ret_p)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "end_query_helper",
    + "result already set",0);
    +
    + if (resolv_wait_answer(*query_p,&resize,cancel_p)) {
    +
    + if (resize_query_answer(*query_p,&resize,cancel_p)) {
    + *ret_p = check_query_answer(*query_p,name,looking_up_p,
    + search_name_p,flags_p);
    + } else
    + goto end_search;
    + } else {
    + end_search:
    + if (cancel_p && *cancel_p &&
    + is_canceled(*cancel_p)) {
    +
    + DPRINT(Debug,14,(&Debug,
    + "end_query_helper: %s: DNS lookup canceled\n", + name));
    +
    + flags_p->end_search = 1;
    + flags_p->have_error = 1; /* Not actually used when is_canceled()
    + is set, in that case error is set directly
    + on caller
    + */
    + goto fail;
    +
    + } else {
    + DPRINT(Debug,14,(&Debug,
    + "end_query_helper: %s: no answer\n",
    + name));
    + flags_p->end_search = 1; /* No answer or no answer after retry*/
    + }
    + }
    +
    + } else if (err) {
    + DPRINT(Debug,14,(&Debug,
    + "end_query_helper: %s: error %d (%s)\n",
    + name,err,strerror(err)));
    +
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookError,
    + "Looking up %s: %s"),
    + name,strerror(err));
    +
    + if (looking_up_p)
    + *looking_up_p = l_up_error;
    +
    + flags_p->end_search = 1;
    + } else {
    + DPRINT(Debug,16,(&Debug,
    + "end_query_helper: %s: no query\n",
    + name));
    +
    + flags_p->no_name = 1; /* searching only when NRXDOMAIN was previous result */
    + }
    +
    + fail:
    +
    + if (*query_p)
    + free_resolv_query_item(query_p);
    +
    + DPRINT(Debug,16,(&Debug,
    + "end_query_helper: %s: handled%s%s%s%s\n",
    + name,
    + flags_p->end_search ? ", end search" : "",
    + flags_p->no_name ? ", no name" : "",
    + flags_p->have_error ? ", have error" : "",
    + *ret_p ? ", answer set" : ""));
    + }
    +
    + S_(lookup_resolv_cache_qm_f lookup_resolv_cache_nonblocked)
    + struct resolv_cache * lookup_resolv_cache_nonblocked
    + P_((struct resolv_cache * record,
    + const char * name,
    + const struct schedule_timelimit * now,
    + const ns_type q_type,
    + const int is_search,
    + enum looking_up * looking_up,
    + char ** search_name,
    + int * have_error,
    + int * other,
    + struct cancel_data ** cancel_p));
    + static struct resolv_cache * lookup_resolv_cache_nonblocked(record,name,now, + q_type,is_search,
    + looking_up_p,search_name_p,
    + have_error_p,other_p,
    + cancel_p)
    + struct resolv_cache * record;
    + const char * name;
    + const struct schedule_timelimit * now;

    [continued in next message]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)