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

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

    + case rs_continue: SIGDPRINT(Debug,14,(&Debug, " (continue) ")); break;
    + }
    + SIGDPRINT(Debug,14,(&Debug, "\n"));
    +
    +
    + quitting:
    + hdr.magic = RESOLV_QUERY_HDR_magic;
    + hdr.errno_val = err;
    + hdr.h_errno_val = 0;
    + hdr.msg = qm_shutdown;
    + hdr.buflen = 0;
    + hdr.senderpid = pid;
    + ws = write_message(socket,&hdr,NULL,0,&err,pid,NULL);
    +
    + SIGDPRINT(Debug,12,(&Debug, "resolv_send_process: [pid %d] Stopping\n",pid));
    +
    + if (query_buffer != query_buffer1)
    + free(query_buffer);
    + if (answer_buffer != answer_buffer1)
    + free(answer_buffer);
    + }
    +
    + #endif
    +
    +
    + #define RESOLV_MESSAGE_magic 0xF918
    +
    + static struct resolv_message {
    + unsigned short magic; /* RESOLV_MESSAGE_magic */
    + unsigned short message_len;
    + unsigned char * message;
    + size_t message_size; /* alloced space of message for sizeupdate */
    + ns_msg parsed_message;
    +
    + unsigned int message_parsed :1;
    + } * new_resolv_message P_((void)) UNUSED_FUNCOK;
    +
    + static struct resolv_message * new_resolv_message()
    + {
    + struct resolv_message * ret =
    + safe_zero_alloc(sizeof (*ret));
    +
    + ret->magic = RESOLV_MESSAGE_magic;
    + ret->message_len = 0;
    + ret->message = NULL;
    + ret->message_size = 0;
    + ret->message_parsed = 0;
    +
    + return ret;
    + }
    +
    + static void resize_resolv_message P_((struct resolv_message *msg,
    + size_t newsize))
    + UNUSED_FUNCOK;
    + static void resize_resolv_message(msg,newsize)
    + struct resolv_message *msg;
    + size_t newsize;
    + {
    + if (RESOLV_MESSAGE_magic != msg->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "resize_resolv_message",
    + "Bad magic number (resolv_message)",0);
    +
    + msg->message_size = newsize;
    + msg->message = safe_realloc(msg->message,
    + msg->message_size);
    + msg->message_len = 0;
    + msg->message_parsed = 0;
    + }
    +
    +
    + static void free_resolv_message P_((struct resolv_message **msg))
    + UNUSED_FUNCOK;
    + static void free_resolv_message(msg)
    + struct resolv_message **msg;
    + {
    + if (RESOLV_MESSAGE_magic != (*msg)->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "free_resolv_message",
    + "Bad magic number (resolv_message)",0);
    +
    + if ((*msg)->message) {
    + free ((*msg)->message);
    + (*msg)->message = NULL;
    + }
    +
    + (*msg)->magic = 0; /* Invalidate */
    + free(*msg);
    + *msg = NULL;
    + }
    +
    + #define RESOLV_QUERY_ITEM_magic 0xF919
    +
    + static struct resolv_query_item {
    + unsigned short magic; /* RESOLV_QUERY_ITEM_magic */
    +
    + size_t querynum;
    + struct schedule_timelimit query_time;
    + char * name; /* name for error messages */
    + struct resolv_message * query_buffer;
    + struct resolv_query_hdr * query_hdr;
    +
    + struct resolv_message * answer_buffer;
    + struct resolv_query_hdr * answer_hdr;
    +
    + int last_errno;
    +
    + struct resolv_cache * cache_answer_in; /* 'answer' for fill_resolv_cache() */
    + struct resolv_cache * cache_answer_ret; /* Return value of fill_resolv_cache() */
    + char * answer_search_name; /* Return 'search_name' for fill_resolv_cache() */
    + enum looking_up looking_up; /* Return 'looking_up' for fill_resolv_cache() */
    +
    + unsigned int fill_have_error:1; /* Return 'have_error' for fill_resolv_cache() */
    + unsigned int transient_error:1; /* Return 'have_error' for fill_resolv_cache() */
    + unsigned int other:1; /* have other data for name */
    +
    + unsigned int is_search :1; /* Is search, do not report not found errors yet */
    +
    + unsigned int query_sent :1;
    + unsigned int valid_answer :1;
    + unsigned int failed_answer :1;
    + unsigned int invalid_answer :1; /* Answer not stored */
    + unsigned int shutdown :1; /* shutdown seen */
    +
    + int refcount;
    +
    + } ** query_list = NULL; /* Indezed by querynum , 0 is not used */
    + static size_t query_list_len = 0; /* MAX querynum + 1 */
    +
    + static struct resolv_query_item * new_resolv_query_item P_((size_t querynum, const char *name)) UNUSED_FUNCOK;
    + static struct resolv_query_item * new_resolv_query_item(querynum,name)
    + size_t querynum;
    + const char * name;
    + {
    + struct resolv_query_item *ret =
    + safe_zero_alloc(sizeof (*ret));
    +
    + if (query_list_len > querynum && query_list[querynum])
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "new_resolv_query_item",
    + "querynum is already used",0);
    +
    + ret->magic = RESOLV_QUERY_ITEM_magic;
    + ret->querynum = querynum;
    + ret->query_time = NO_schedule_timelimit;
    + ret->name = name ? safe_strdup(name) : NULL;
    + ret->query_buffer = NULL;
    + ret->query_hdr = NULL;
    + ret->last_errno = 0;
    + ret->cache_answer_in = NULL;
    + ret->cache_answer_ret = NULL;
    + ret->answer_search_name = NULL;
    + ret->looking_up = l_up_none;
    + ret->fill_have_error = 0;
    + ret->transient_error = 0;
    + ret->other = 0;
    + ret->is_search = 0;
    + ret->query_sent = 0;
    + ret->valid_answer = 0;
    + ret->failed_answer = 0;
    + ret->invalid_answer = 0;
    + ret->shutdown = 0;
    +
    + ret->refcount = 1;
    +
    + return ret;
    + }
    +
    + /* Decrements refcount */
    +
    + static void free_resolv_query_item P_(( struct resolv_query_item **ptr));
    + static void free_resolv_query_item(ptr)
    + struct resolv_query_item **ptr;
    + {
    + if (RESOLV_QUERY_ITEM_magic != (*ptr)->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "free_resolv_query_item",
    + "Bad magic number (resolv_query_item)",0);
    +
    + if ((*ptr)->refcount < 1)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"free_resolv_query_item",
    + "Bad refcount",0);
    +
    + (*ptr)->refcount--;
    + if ((*ptr)->refcount > 0) {
    + /* Just reset this reference */
    +
    + *ptr = NULL;
    + return;
    + }
    +
    + if ((*ptr)->name) {
    + free((*ptr)->name);
    + (*ptr)->name = NULL;
    + }
    +
    + if ((*ptr)->query_buffer)
    + free_resolv_message(& ((*ptr)->query_buffer));
    +
    + if ((*ptr)->query_hdr) {
    + free ((*ptr)->query_hdr);
    + (*ptr)->query_hdr = NULL;
    + }
    +
    + if ((*ptr)->answer_buffer)
    + free_resolv_message(& ((*ptr)->answer_buffer));
    +
    + if ((*ptr)->answer_hdr) {
    + free ((*ptr)->answer_hdr);
    + (*ptr)->answer_hdr = NULL;
    + }
    +
    + if ((*ptr)->cache_answer_in)
    + free_resolv_cache(& ((*ptr)->cache_answer_in));
    +
    + if ((*ptr)->cache_answer_ret)
    + free_resolv_cache(& ((*ptr)->cache_answer_ret));
    +
    + if ((*ptr)->answer_search_name) {
    + free((*ptr)->answer_search_name);
    + (*ptr)->answer_search_name = NULL;
    + }
    +
    + (*ptr)->magic = 0; /* Invalidate */
    +
    + free(*ptr);
    + *ptr = NULL;
    + }
    +
    + static void inc_resolv_query_item_recount P_(( struct resolv_query_item *ptr));
    + static void inc_resolv_query_item_recount(ptr)
    + struct resolv_query_item *ptr;
    + {
    + if (RESOLV_QUERY_ITEM_magic != ptr->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "inc_resolv_query_item_recount",
    + "Bad magic number (resolv_query_item)",0);
    +
    + ptr->refcount++;
    + }
    +
    + /* ------------------------------------------------------------------------------- */
    +
    + #define RESOLV_MESSAGE_STATE_magic 0xF91B
    +
    + static struct resolv_message_state {
    + unsigned short magic; /* RESOLV_MESSAGE_STATE_magic */
    +
    + struct resolv_query_hdr read_hdr;
    + unsigned char * read_buffer;
    + size_t read_buffer_len;
    + size_t read_buffer_size;
    + size_t read_pos;
    +
    + struct resolv_query_hdr write_hdr;
    + unsigned char * write_buffer;
    + size_t write_buffer_len;
    + size_t write_buffer_size;
    + size_t write_pos;
    +
    + size_t querynum; /* Last or current query */
    +
    + unsigned int write_prepared:1;
    + unsigned int broken_pipe:1; /* Broken pipe when writing, + EOF when reading
    + */
    + unsigned int query_in_progress:1; /* Query 'querynum' in progress */
    +
    + int refcount;
    + } * new_resolv_message_state P_((int pid)) UNUSED_FUNCOK;
    +
    + static struct resolv_message_state * new_resolv_message_state(pid)
    + int pid;
    + {
    + struct resolv_message_state *ret =
    + safe_zero_alloc(sizeof (*ret));
    +
    + ret->magic = RESOLV_MESSAGE_STATE_magic;
    +
    + ret->read_hdr.magic = RESOLV_QUERY_HDR_magic;
    + ret->read_hdr.buflen = 0;
    + ret->read_hdr.errno_val = 0;
    + ret->read_hdr.h_errno_val = 0;
    + ret->read_hdr.querynum = 0;
    + ret->read_hdr.senderpid = pid;
    + ret->read_hdr.msg = qm_none;
    +
    + ret->read_buffer = NULL;
    + ret->read_buffer_size = 0;
    + ret->read_buffer_len = 0;
    + ret->read_pos = 0;
    +
    + ret->write_hdr.magic = RESOLV_QUERY_HDR_magic;
    + ret->write_hdr.buflen = 0;
    + ret->write_hdr.errno_val = 0;
    + ret->write_hdr.h_errno_val = 0;
    + ret->write_hdr.querynum = 0;
    + ret->write_hdr.senderpid = pid;
    + ret->write_hdr.msg = qm_none;
    +
    + ret->write_buffer = NULL;
    + ret->write_buffer_len = 0;
    + ret->write_buffer_size = 0;
    + ret->write_pos = 0;
    + ret->write_prepared = 0;
    + ret->broken_pipe = 0;
    + ret->query_in_progress = 0;
    + ret->querynum = 0;
    +
    + ret->refcount = 1;
    +
    + return ret;
    + }
    +
    + /* Decrements refcount */
    + static void free_resolv_message_state P_((struct resolv_message_state **ptr));
    + static void free_resolv_message_state(ptr)
    + struct resolv_message_state **ptr;
    + {
    + if (RESOLV_MESSAGE_STATE_magic != (*ptr)->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"free_resolv_message_state",
    + "Bad magic number (resolv_message_state)",0);
    +
    + if ((*ptr)->refcount < 1)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"free_resolv_message_state",
    + "Bad refcount",0);
    +
    + (*ptr)->refcount--;
    + if ((*ptr)->refcount > 0) {
    + /* Just reset this reference */
    +
    + *ptr = NULL;
    + return;
    + }
    +
    + if ((*ptr)->read_buffer) {
    + free((*ptr)->read_buffer);
    + (*ptr)->read_buffer = NULL;
    + }
    +
    + if ((*ptr)->write_buffer) {
    + free((*ptr)->write_buffer);
    + (*ptr)->write_buffer = NULL;
    + }
    +
    + (*ptr)->read_hdr.magic = 0;
    + (*ptr)->write_hdr.magic = 0;
    + (*ptr)->magic = 0; /* Invalidate */
    + free(*ptr);
    + *ptr = NULL;
    + }
    +
    + /* Decrements refcount */
    + static void inc_resolv_message_state_refcount P_((struct resolv_message_state *ptr))
    + UNUSED_FUNCOK;
    + static void inc_resolv_message_state_refcount(ptr)
    + struct resolv_message_state *ptr;
    + {
    + if (RESOLV_MESSAGE_STATE_magic != ptr->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"inc_resolv_message_state_refcount",
    + "Bad magic number (resolv_message_state)",0);
    +
    + ptr->refcount ++;
    + }
    +
    +
    +
    + /* --------------------------------------------------------------------------------*/
    +
    + #define RESOLV_PROCESS_magic 0xF91A
    +
    + static struct resolv_process {
    + unsigned short magic; /* RESOLV_PROCESS_magic */
    +
    + int pid;
    +
    + enum process_state {
    + ps_none = 0,
    + ps_forked = 1,
    + ps_running = 2 /* Got qm_running */,
    + ps_shutdown = 3 /* Got qm_shutdown */,
    + ps_exited = 4 /* Got exit status */,
    + ps_died = 5 /* Got signal */
    + } state;
    +
    + struct resolv_message_state * message;
    + int socket;
    +
    + int refcount;
    + } ** process_list = NULL;
    + static size_t process_list_len = 0;
    +
    +
    + static struct resolv_process * new_resolv_process P_((int pid));
    + static struct resolv_process * new_resolv_process(pid)
    + int pid;
    + {
    + struct resolv_process * ret =
    + safe_zero_alloc(sizeof (*ret));
    +
    + ret->magic = RESOLV_PROCESS_magic;
    + ret->pid = pid;
    + ret->state = ps_none;
    + ret->message = NULL;
    + ret->socket = -1;
    + ret->refcount = 1;
    +
    + return ret;
    + }
    +
    + static void free_resolv_process P_((struct resolv_process **ptr));
    + static void free_resolv_process(ptr)
    + struct resolv_process **ptr;
    + {
    + if (RESOLV_PROCESS_magic != (*ptr)->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"free_resolv_process",
    + "Bad magic number (resolv_process)",0);
    +
    + if ((*ptr)->refcount < 1)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"free_resolv_process",
    + "Bad refcount",0);
    + (*ptr)->refcount--;
    + if ((*ptr)->refcount > 0) {
    + /* Just reset this reference */
    +
    + *ptr = NULL;
    + return;
    + }
    +
    + if ((*ptr)->message) {
    + free_resolv_message_state(& ((*ptr)->message));
    + }
    +
    + if (-1 != (*ptr)->socket) {
    + int r;
    +
    + DPRINT(Debug,12,(&Debug,"free_resolv_process: socket=%d -- clear action\n",
    + (*ptr)->socket));
    +
    + /* No longer schedule for this! */
    + clear_action((*ptr)->socket);
    +
    + DPRINT(Debug,12,(&Debug,"free_resolv_process: Closing socket %d (to process pid %d)",
    + (*ptr)->socket,(*ptr)->pid));
    +
    + r = close((*ptr)->socket);
    + if (-1 == r) {
    + int err UNUSED_VAROK = errno;
    +
    + DPRINT(Debug,12,(&Debug,", failed; errno %d (%s)",
    + err,strerror(err)));
    + }
    + DPRINT(Debug,12,(&Debug,"\n"));
    +
    + (*ptr)->socket = -1;
    + }
    +
    + (*ptr)->magic = 0; /* Invalidate */
    + free(*ptr);
    + *ptr = NULL;
    + }
    +
    + static void inc_resolv_process_refcount P_((struct resolv_process *ptr));
    + static void inc_resolv_process_refcount(ptr)
    + struct resolv_process *ptr;
    + {
    + if (RESOLV_PROCESS_magic != ptr->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"inc_resolv_process_refcount",
    + "Bad magic number (resolv_process)",0);
    +
    + ptr->refcount++;
    + }
    +
    +
    +
    + #if ANSI_C
    + #define S_(x) static x;
    + #else
    + #define S_(x)
    + #endif
    +
    + static int parse_resolv_message1 P_((struct resolv_message * buffer,
    + int * errno_val));
    + static int parse_resolv_message1(buffer,errno_val)
    + struct resolv_message * buffer;
    + int * errno_val;
    + {
    + int ret = 0;
    + int res;
    +
    + if (RESOLV_MESSAGE_magic != buffer->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "parse_resolv_message1",
    + "Bad magic number (resolv_message)",0);
    +
    + res = ns_initparse(buffer->message,buffer->message_len,
    + & (buffer-> parsed_message));
    +
    + if (res < 0) {
    + int err = errno;
    +
    + DPRINT(Debug,14,(&Debug,
    + "parse_resolv_message1: ns_initparse() failed, len %u",
    + (unsigned) buffer->message_len));
    +
    + if (err) {
    + DPRINT(Debug,14,(&Debug,", errno = %d (%s)",
    + err, strerror(err)));
    + if (errno_val)
    + *errno_val = err;
    + }
    +
    + DPRINT(Debug,14,(&Debug,"\n"));
    +
    + } else {
    + DPRINT(Debug,14,(&Debug,
    + "parse_resolv_message1: ns_initparse() succeed, len %u\n",
    + (unsigned) buffer->message_len));
    + buffer->message_parsed = 1;
    + ret = 1;
    + }
    +
    + DPRINT(Debug,14,(&Debug,
    + "parse_resolv_message1=%d",ret));
    + if (errno_val && *errno_val) {
    + DPRINT(Debug,14,(&Debug,
    + "; *errno_val=%d",*errno_val));
    + }
    + DPRINT(Debug,14,(&Debug,"\n"));
    +
    + return ret;
    +
    + }
    +
    + #if defined(RESOLV_SENDOK) && defined(RESOLV_SEQPACKET)
    +
    + static int parse_resolv_message P_((struct resolv_message * buffer,
    + const unsigned char answer_buffer[],
    + const size_t answer_buflen,
    + int * errno_val));
    + static int parse_resolv_message(buffer,answer_buffer,answer_buflen,errno_val) + struct resolv_message * buffer;
    + const unsigned char answer_buffer[];
    + const size_t answer_buflen;
    + int * errno_val;
    + {
    + int ret = 0;
    +
    + errno = 0;
    + if (errno_val)
    + *errno_val = 0;
    +
    + if (RESOLV_MESSAGE_magic != buffer->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + " parse_resolv_message",
    + "Bad magic number (resolv_message)",0);
    +
    + if (answer_buflen > 0 && answer_buffer &&
    + answer_buflen <= buffer->message_size &&
    + answer_buflen <= USHRT_MAX &&
    + buffer->message ) {
    +
    + memcpy(buffer->message, answer_buffer, answer_buflen);
    + buffer->message_len = answer_buflen;
    +
    +
    + ret = parse_resolv_message1(buffer,errno_val);
    + } else {
    + DPRINT(Debug,14,(&Debug,
    + "parse_resolv_message: len %lu\n",(unsigned long)answer_buflen));
    + if (errno_val)
    + *errno_val = EMSGSIZE;
    +
    + }
    +
    + return ret;
    + }
    +
    + static int same_question_rr P_((ns_rr *rr1, ns_rr *rr2));
    + static int same_question_rr(rr1,rr2)
    + ns_rr *rr1;
    + ns_rr *rr2;
    + {
    + char *name1 = ns_rr_name((*rr1));
    + char *name2 = ns_rr_name((*rr2));
    + ns_class recclass1 = ns_rr_class((*rr1));
    + ns_class recclass2 = ns_rr_class((*rr2));
    + ns_type rectype1 = ns_rr_type((*rr1));
    + ns_type rectype2 = ns_rr_type((*rr2));
    +
    + if (! name1 || ! name2) {
    + DPRINT(Debug,14,(&Debug, "same_question_rr: no name\n"));
    + return 0;
    + }
    +
    + if (0 != strcmp(name1,name2)) {
    + DPRINT(Debug,14,(&Debug, "same_question_rr: name mismatch: %s <> %s\n", + name1,name2));
    + return 0;
    + }
    +
    + if (recclass1 != recclass2) {
    + DPRINT(Debug,14,(&Debug, "same_question_rr: %s: class mismatch: %d <> %d\n",
    + name1,recclass1,recclass2));
    + return 0;
    + }
    +
    + if (rectype1 != rectype2) {
    + DPRINT(Debug,14,(&Debug,"same_question_rr: %s: rectype mismatch: %d <> %d\n",
    + name1,rectype1,rectype2));
    + return 0;
    + }
    +
    + return 1;
    + }
    +
    +
    + static void process_answer P_((const int pid,
    + const struct resolv_query_hdr * hdr,
    + const unsigned char answer_buffer[],
    + const size_t answer_buflen, + struct resolv_query_item * qitem));
    + static void process_answer(pid,hdr,answer_buffer,answer_buflen,qitem)
    + const int pid;
    + const struct resolv_query_hdr * hdr;
    + const unsigned char answer_buffer[];
    + const size_t answer_buflen;
    + struct resolv_query_item * qitem;
    + {
    +
    + if (RESOLV_QUERY_HDR_magic != hdr->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "process_answer",
    + "Bad magic number (resolv_query_hdr)",0);
    +
    + if (qitem) {
    +
    + if (RESOLV_QUERY_ITEM_magic != qitem->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"process_answer",
    + "Bad magic number (resolv_query_item)",0);
    +
    +
    + if (qitem->answer_hdr) {
    + if (RESOLV_QUERY_HDR_magic != qitem->answer_hdr->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "process_answer",
    + "Bad magic number resolv_query_hdr)",0);
    + }
    +
    + if (hdr->errno_val) {
    + DPRINT(Debug,14,(&Debug, "process_answer: [pid %d] %lu %s: copying error %d (%s)\n",
    + pid,
    + (unsigned long)(qitem->querynum),
    + qitem->name ? qitem->name : "<NO NAME>",
    + hdr->errno_val,strerror(hdr->errno_val)));
    + qitem->last_errno = hdr->errno_val;
    + }
    +
    + if (qitem->answer_buffer) {
    + int err_rmesg = 0;
    + int ok;
    +
    + if (RESOLV_MESSAGE_magic != qitem->answer_buffer->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "process_answer",
    + "Bad magic number (resolv_message)",0);
    +
    + ok = parse_resolv_message(qitem->answer_buffer,
    + answer_buffer,answer_buflen,&err_rmesg); +
    + if (!ok) {
    + DPRINT(Debug,14,(&Debug, "process_answer: [pid %d] %lu %s: failed to parse message (len %lu)",
    + pid,
    + (unsigned long)(qitem->querynum),
    + qitem->name ? qitem->name : "<NO NAME>",
    + (unsigned long) answer_buflen));
    +
    + if (err_rmesg) {
    + DPRINT(Debug,14,(&Debug, ", error %s (errno %d)",
    + strerror(err_rmesg),err_rmesg));
    +
    + qitem->last_errno = err_rmesg;
    + }
    +
    + DPRINT(Debug,14,(&Debug, "\n"));
    +
    + qitem->invalid_answer = 1;
    +
    + if (qitem->name) {
    + if (err_rmesg) {
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookFParseAnswerE,
    + "Looking up %s: Failed to parse answer: %s"),
    + qitem->name,
    + strerror(err_rmesg));
    + } else
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookFParseAnswer,
    + "Looking up %s: Failed to parse answer"),
    + qitem->name);
    +
    + qitem->looking_up = l_up_error;
    + }
    +
    +
    + } else if (qitem->query_buffer) {
    + char * refname = NULL;
    +
    + if (RESOLV_MESSAGE_magic != qitem->query_buffer->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "process_answer",
    + "Bad magic number (resolv_message)",0);
    +
    + if (ok) {
    + u_int16_t query_id = ns_msg_id(qitem->query_buffer->parsed_message);
    + u_int16_t answer_id = ns_msg_id(qitem->answer_buffer->parsed_message);
    +
    + if (query_id != answer_id) {
    +
    + DPRINT(Debug,14,(&Debug,
    + "process_answer: [pid %d] %lu %s: query id %d <=> answer id %d\n",
    + pid,
    + (unsigned long)(qitem->querynum),
    + qitem->name ? qitem->name : "<NO NAME>",
    + query_id,answer_id));
    +
    + ok = 0;
    + }
    + }
    +
    + if (ok) {
    + int count_query_qd = ns_msg_count(qitem->query_buffer->parsed_message,
    + ns_s_qd);
    + int count_answer_qd = ns_msg_count(qitem->answer_buffer->parsed_message,
    + ns_s_qd);
    +
    + if (count_query_qd != count_answer_qd) {
    + DPRINT(Debug,14,(&Debug,
    + "process_answer: [pid %d] %lu %s: query %d <=> answer %d records on question section\n",
    + pid,
    + (unsigned long)(qitem->querynum),
    + qitem->name ? qitem->name : "<NO NAME>",
    + count_query_qd,count_answer_qd));
    + ok = 0;
    + } else {
    + int recnum;
    +
    + DPRINT(Debug,14,(&Debug,
    + "process_answer: [pid %d] %lu %s: %d records on question section\n",
    + pid,
    + (unsigned long)(qitem->querynum),
    + qitem->name ? qitem->name : "<NO NAME>",
    + count_query_qd));
    +
    + for (recnum = 0; recnum < count_query_qd && ok; recnum++) {
    + ns_rr rrquestion;
    + ns_rr rranswer;
    + int res;
    +
    + errno = 0;
    + res = ns_parserr(&(qitem->query_buffer->parsed_message),
    + ns_s_qd,recnum,&rrquestion);
    +
    + if (res < 0) {
    + int errnum = errno;
    + DPRINT(Debug,14,(&Debug,
    + "process_answer: [pid %d] %lu %s: failed to parse record #%d on question section of query",
    + pid,
    + (unsigned long)(qitem->querynum),
    + qitem->name ? qitem->name : "<NO NAME>",
    + recnum));
    +
    + if (errnum) {
    + DPRINT(Debug,14,(&Debug, ", error %s (errno %d)",
    + strerror(errnum),errnum)); + qitem->last_errno = errnum;
    + }
    +
    + DPRINT(Debug,14,(&Debug,"\n"));
    + ok = 0;
    + }
    +
    + res = ns_parserr(&(qitem->answer_buffer->parsed_message),
    + ns_s_qd,recnum,&rranswer);
    +
    + if (res < 0) {
    + int errnum = errno;
    + DPRINT(Debug,14,(&Debug,
    + "process_answer: [pid %d] %lu %s: failed to parse record #%d on question section of answer",
    + pid,
    + (unsigned long)(qitem->querynum),
    + qitem->name ? qitem->name : "<NO NAME>",
    + recnum));
    + if (errnum) {
    + DPRINT(Debug,14,(&Debug, ", error %s (errno %d)",
    + strerror(errnum),errnum)); + qitem->last_errno = errnum;
    + }
    +
    + DPRINT(Debug,14,(&Debug,"\n"));
    + ok = 0;
    + }
    +
    + if (ok && !same_question_rr(&rrquestion,&rranswer)) {
    + DPRINT(Debug,14,(&Debug,
    + "process_answer: [pid %d] %lu %s: record #%d differ on between question section of query and answer\n",
    + pid,
    + (unsigned long)(qitem->querynum),
    + qitem->name ? qitem->name : "<NO NAME>",
    + recnum));
    + ok = 0;
    + }
    +
    + if (ok && 1 == count_query_qd) {
    + const char * X = ns_rr_name(rranswer);
    + if (X) {
    + refname = strmcpy(refname,X);
    + DPRINT(Debug,14,(&Debug,
    + "process_answer: [pid %d] %lu %s: reference name is %s\n",
    + pid,
    + (unsigned long)(qitem->querynum),
    + qitem->name ? qitem->name : "<NO NAME>",
    + refname));
    + }
    + }
    + }
    + }
    + }
    +
    + if (ok) {
    + ns_rcode response_code =
    + ns_msg_getflag(qitem->answer_buffer->parsed_message,
    + ns_f_rcode);
    + unsigned short aa =
    + ns_msg_getflag(qitem->answer_buffer->parsed_message,
    + ns_f_aa);
    +
    + DPRINT(Debug,14,(&Debug,
    + "process_answer: [pid %d] %lu %s: query name=%s, authorative=%u, response code=%d",
    + pid,
    + (unsigned long)(qitem->querynum),
    + qitem->name ? qitem->name : "<NO NAME>",
    + refname ? refname : "<NO NAME>",
    + (unsigned)aa,
    + response_code));
    + switch (response_code) {
    + case ns_r_noerror: DPRINT(Debug,14,(&Debug," (no error)\n")); break;
    + case ns_r_formerr: DPRINT(Debug,14,(&Debug," (format error)\n"));
    + if (qitem->name) {
    +
    + if (refname && 0 != strcmp(qitem->name,refname))
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookFormErrR,
    + "Looking up %s [%s]: format error"),
    + qitem->name,refname);
    + else
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookFormErr,
    + "Looking up %s: format error"),
    + qitem->name);
    + qitem->looking_up = l_up_error;
    + } else if (refname) {
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookFormErr,
    + "Looking up %s: format error"),
    + refname);
    + qitem->looking_up = l_up_error;
    + }
    +
    + qitem->fill_have_error = 1;
    + break;
    + case ns_r_servfail: DPRINT(Debug,14,(&Debug," (server failure)\n"));
    + if (qitem->name) {
    + if (refname && 0 != strcmp(qitem->name,refname))
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookServFailR,
    + "Looking up %s [%s]: server failure"),
    + qitem->name,refname);
    + else
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookServFail,
    + "Looking up %s: server failure"),
    + qitem->name);
    + qitem->looking_up = l_up_error;
    + } else if (refname) {
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookServFail,
    + "Looking up %s: server failure"), + refname);
    + qitem->looking_up = l_up_error;
    + }
    + break;
    + case ns_r_nxdomain: DPRINT(Debug,14,(&Debug," (name error)"));
    +
    + if (qitem->is_search) {
    + DPRINT(Debug,14,(&Debug," -- using search list for name, do not print error yet.\n"));
    + qitem->transient_error = 1;
    + } else {
    + DPRINT(Debug,14,(&Debug,"\n"));
    + if (aa) {
    + if (qitem->name) {
    + if (refname && 0 != strcmp(qitem->name,refname))
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookNotFoundR, + "Looking up %s [%s]: not found"),
    + qitem->name,refname);
    + else
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookNotFound,
    + "Looking up %s: not found"),
    + qitem->name);
    + qitem->looking_up = l_up_error;
    + } else if (refname) {
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookNotFound,
    + "Looking up %s: not found"),
    + refname);
    + qitem->looking_up = l_up_error;
    + }
    + } else {
    + if (qitem->name) {
    + if (refname && 0 != strcmp(qitem->name,refname))
    + lib_transient(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookTryAgainR,
    + "Looking up %s [%s]: not found yet"),
    + qitem->name,refname);
    + else
    + lib_transient(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookTryAgain,
    + "Looking up %s: not found yet"),
    + qitem->name);
    + qitem->looking_up = l_up_error;
    + } else if (refname) {
    + lib_transient(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookTryAgain,
    + "Looking up %s: not found yet"),
    + refname);
    + }
    + qitem->fill_have_error = 1;
    + }
    + }
    + break;
    + case ns_r_notimpl: DPRINT(Debug,14,(&Debug," (unimplemented)\n"));
    + if (qitem->name) {
    + if (refname && 0 != strcmp(qitem->name,refname))
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookNotImplR,
    + "Looking up %s [%s]: not implemented"),
    + qitem->name,refname);
    + else
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookNotImpl,
    + "Looking up %s: not implemented"),
    + qitem->name);
    + qitem->looking_up = l_up_error;
    + } else if (refname) {
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookNotImpl,
    + "Looking up %s: not implemented"),
    + refname);
    + qitem->looking_up = l_up_error;
    + }
    +
    + qitem->fill_have_error = 1;
    + break;
    + case ns_r_refused: DPRINT(Debug,14,(&Debug," (operation refused)\n"));
    + if (qitem->name) {
    + if (refname && 0 != strcmp(qitem->name,refname))
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookOpRefR,
    + "Looking up %s [%s]: operation refused"),
    + qitem->name,refname);
    + else
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookOpRef,
    + "Looking up %s: operation refused"),
    + qitem->name);
    + qitem->looking_up = l_up_error;
    + } else if (refname) {
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvLookOpRef,
    + "Looking up %s: operation refused"),
    + refname);
    + qitem->looking_up = l_up_error;
    + }
    +
    + qitem->fill_have_error = 1;
    + break;
    + default: DPRINT(Debug,14,(&Debug,"\n")); break;
    + }
    +
    + if (!qitem->answer_hdr)
    + qitem->answer_hdr = safe_malloc(sizeof (* (qitem->answer_hdr)));
    + * (qitem->answer_hdr) = *hdr;
    +
    + if (qitem->cache_answer_ret) {
    + DPRINT(Debug,14,(&Debug,
    + "process_answer: [pid %d] %lu %s: clearing previous answer\n",
    + pid,
    + (unsigned long)(qitem->querynum),
    + qitem->name ? qitem->name : "<NO NAME>"));
    + free_resolv_cache(& (qitem->cache_answer_ret));
    + }
    +
    + if (ns_r_noerror == response_code) {
    + int anscount = ns_msg_count(qitem->answer_buffer->parsed_message,
    + ns_s_an);
    +
    + if (!anscount) {
    + DPRINT(Debug,14,(&Debug,
    + "process_answer: [pid %d] %lu %s: Didn't got answer but name found\n",
    + pid,
    + (unsigned long)(qitem->querynum), + qitem->name ? qitem->name : "<NO NAME>"));
    + qitem->other = 1;
    + } else {
    + DPRINT(Debug,14,(&Debug,
    + "process_answer: [pid %d] %lu %s: %d recors on answer section\n",
    + pid,
    + (unsigned long)(qitem->querynum), + qitem->name ? qitem->name : "<NO NAME>",
    + anscount));

    [continued in next message]

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