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

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

    + int err = errno;
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvFailedSocketPair,
    + "Failed to create socket pair: %s"),
    + strerror(err));
    + }
    +
    + fail:
    + return ret;
    + }
    +
    + #endif
    +
    + S_(have_qm_f have_non_blocking_qm)
    + static int have_non_blocking_qm P_((void));
    + static int have_non_blocking_qm()
    + {
    + int ret = 0;
    + int pid0 = getpid();
    +
    + if (process_list) {
    + size_t i;
    +
    + for (i = 0; i < process_list_len && !ret; i++) {
    + if (process_list[i]) {
    + int XX = 0;
    + if (RESOLV_PROCESS_magic != process_list[i]->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"have_non_blocking_qm",
    + "Bad magic number (resolv_process)",0);
    +
    + XX = resolv_process_ok(process_list[i]);
    +
    + DPRINT(Debug,12,(&Debug, "have_non_blocking_qm: #%lu",
    + (unsigned long)i));
    + if (XX) {
    + DPRINT(Debug,12,(&Debug, " -- OK"));
    + ret = 1;
    + }
    + DPRINT(Debug,12,(&Debug, "\n"));
    +
    + if (XX && process_list[i]->message) {
    + union action_routine_data data;
    +
    + if (RESOLV_MESSAGE_STATE_magic != process_list[i]->message->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"have_non_blocking_qm",
    + "Bad magic number (resolv_message_state)",0);
    +
    + if (process_list[i]->message->broken_pipe) {
    + DPRINT(Debug,12,(&Debug, " : #%lu -- broken pipe (or EOF)\n",
    + (unsigned long)i));
    +
    + /* Not handled here */
    + }
    +
    + if (process_list[i]->message->write_prepared) {
    + DPRINT(Debug,12,(&Debug, " : #%lu -- write prepared (busy)\n",
    + (unsigned long)i));
    + }
    +
    + if (process_list[i]->message->query_in_progress) {
    + DPRINT(Debug,12,(&Debug, " : #%lu -- query in progress (busy)\n",
    + (unsigned long)i));
    + }
    +
    + #if defined(RESOLV_SENDOK) && defined(RESOLV_SEQPACKET)
    + data.resolv = process_list[i]->message;
    + /* This should be no-op */
    + change_action(process_list[i]->socket,-1,
    + resolv_read_message,
    + process_list[i]->message->write_prepared ?
    + resolv_write_message : no_action_routine,
    +
    + no_action_routine,
    + resolv_free_state,resolv_inc_state_refcount,data);
    + #endif
    +
    + } else if (process_list[i]->message) {
    +
    + if (RESOLV_MESSAGE_STATE_magic != process_list[i]->message->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"have_non_blocking_qm",
    + "Bad magic number (resolv_message_state)",0);
    +
    + if (process_list[i]->message->broken_pipe) {
    + DPRINT(Debug,12,(&Debug, " : #%lu -- broken pipe (or EOF)\n",
    + (unsigned long)i));
    + }
    +
    + if (process_list[i]->message->write_prepared) {
    + DPRINT(Debug,12,(&Debug, " : #%lu -- write prepared (busy)\n",
    + (unsigned long)i));
    + }
    +
    + if (process_list[i]->message->query_in_progress) {
    + DPRINT(Debug,12,(&Debug, " : #%lu -- query in progress (busy)\n",
    + (unsigned long)i));
    + }
    + }
    +
    + } else {
    + DPRINT(Debug,15,(&Debug, "have_non_blocking_qm: #%lu -- unused entry\n",
    + (unsigned long)i));
    + }
    + }
    + }
    +
    + if (ret) {
    + DPRINT(Debug,12,(&Debug, "have_non_blocking_qm: Available\n"));
    + }
    +
    + if (!ret) {
    +
    + if (qm_non_blocking == query_mode) {
    + #if defined(RESOLV_SENDOK) && defined(RESOLV_SEQPACKET) && defined(BACKGROUD_PROCESSES)
    +
    + struct resolv_process * pr = give_resolv_process(pid0);
    + if (pr) {
    + int r = res_init();
    +
    + if (0 == r) {
    +
    +
    + DPRINT(Debug,12,(&Debug, "have_non_blocking_qm: Started\n"));
    + ret = 1;
    +
    + } else if (r < 0) {
    + int err = errno;
    +
    + DPRINT(Debug,12,(&Debug,
    + "have_non_blocking_qm: res_init failed: errno = %d (%s)\n",
    + err,strerror(err)));
    +
    + lib_error(CATGETS(elm_msg_cat,
    + ResolvSet,
    + ResolvResInitFailed,
    + "Failed to initialize with res_init: %s"),
    + strerror(err));
    + }
    +
    + free_resolv_process(&pr);
    + } else {
    + DPRINT(Debug,12,(&Debug, "have_non_blocking_qm: Failed to add process for res_send()\n"));
    +
    + }
    + #else
    + DPRINT(Debug,12,(&Debug, "have_non_blocking_qm: Not supported\n"));
    + #endif
    + } else {
    + DPRINT(Debug,12,(&Debug, "have_non_blocking_qm: query-mode=%d",
    + query_mode));
    + if (query_mode >= 0 && query_mode < NUM_query_mode) {
    + DPRINT(Debug,12,(&Debug, " %s",
    + QUERY_MODE[query_mode]));
    + }
    + DPRINT(Debug,12,(&Debug, "\n"));
    + }
    + }
    +
    + DPRINT(Debug,12,(&Debug, "have_non_blocking_qm=%d (pid %d)\n",ret,pid0)); +
    + return ret;
    + }
    +
    + static int prepare_write_message P_((struct resolv_message_state *st, int socket,
    + struct resolv_query_hdr *result_hdr,
    + unsigned char * buffer, size_t buffer_len));
    + static int prepare_write_message(st,socket,result_hdr,buffer,buffer_len)
    + struct resolv_message_state *st;
    + int socket;
    + struct resolv_query_hdr *result_hdr;
    + unsigned char * buffer;
    + size_t buffer_len;
    + {
    + int ret = 0;
    + int pid = getpid();
    +
    + if (RESOLV_MESSAGE_STATE_magic != st->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"prepare_write_message",
    + "Bad magic number (resolv_message_state)",0);
    +
    + if (RESOLV_QUERY_HDR_magic != result_hdr->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "prepare_write_message",
    + "Bad magic number (resolv_query_hdr)",0);
    +
    + if (result_hdr->buflen != buffer_len)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "prepare_write_message",
    + "Bad buf_len",0);
    +
    + if (st->write_prepared && st->write_pos) {
    + SIGDPRINT(Debug,14,(&Debug,
    + "prepare_write_message: [pid %d] socket=%d on middle of write\n",
    + pid,socket));
    + ret = 0;
    + } else {
    + union action_routine_data data;
    +
    + if (buffer_len > st->write_buffer_size) {
    + struct resolv_query_hdr Z = NULL_resolv_query_hdr;
    + struct resolv_sizeupdate U = NULL_resolv_sizeupdate;
    + union resolv_sizeupdate_p update_buffer;
    +
    + unsigned short A = buffer_len;
    + if (A < RESOLV_BUFSIZE)
    + A = RESOLV_BUFSIZE;
    + if (A < sizeof U)
    + A = sizeof U;
    +
    + SIGDPRINT(Debug,14,(&Debug,
    + "prepare_write_message: [pid %d] socket=%d: Changing write buffer size %lu => %d (need write %lu bytes)\n",
    + pid,socket,(unsigned long)(st->write_buffer_size),A,(unsigned long)buffer_len));
    +
    + st->write_buffer_size = A;
    + st->write_buffer = safe_realloc(st->write_buffer,st->write_buffer_size);
    +
    + U.querysize = st->write_buffer_size;
    + U.anssize = st->read_buffer_size;
    + update_buffer.update = &U;
    +
    + Z.buflen = sizeof U;
    + Z.senderpid = pid;
    + Z.msg = qm_sizeupdate;
    +
    + st->write_hdr = Z;
    + memcpy(st->write_buffer, update_buffer.buffer,sizeof U);
    + st->write_buffer_len = sizeof U;
    +
    + ret = 0;
    + } else {
    + st->write_hdr = *result_hdr;
    +
    + SIGDPRINT(Debug,14,(&Debug,
    + "prepare_write_message: [pid %d] socket=%d Preparing write %lu bytes (buffer size %lu)\n",
    + pid,socket,(unsigned long)buffer_len,(unsigned long)(st->write_buffer_size)));
    + if (buffer_len) {
    + memcpy(st->write_buffer,buffer,buffer_len);
    + st->write_buffer_len = buffer_len;
    + } else {
    + st->write_buffer_len = 0;
    + }
    +
    + ret = 1;
    + }
    +
    + st->write_pos = 0;
    + st->write_prepared = 1;
    + data.resolv = st;
    +
    + #if defined(RESOLV_SENDOK) && defined(RESOLV_SEQPACKET)
    + change_action(socket,-1,resolv_read_message,resolv_write_message,
    + no_action_routine,
    + resolv_free_state,resolv_inc_state_refcount,data);
    + #else
    + ret = 0;
    + #endif
    + }
    +
    + SIGDPRINT(Debug,14,(&Debug, "prepare_write_message=%d: [pid %d] socket=%d\n",
    + ret,pid,socket));
    +
    + return ret;
    + }
    +
    + void free_non_blocking_qm()
    + {
    + int mypid = getpid();
    + /* Free resources alloced by have_non_blocking_qm() */
    +
    + if (process_list) {
    + size_t i;
    + int have_write = 0;
    +
    + for (i = 0; i < process_list_len; i++) {
    +
    + if (process_list[i]) {
    + int shut = 0;
    + if (RESOLV_PROCESS_magic != process_list[i]->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"free_non_blocking_qm",
    + "Bad magic number (resolv_process)",0);
    +
    + DPRINT(Debug,12,(&Debug,"free_non_blocking_qm: process #%lu: pid=%d, state=%d",
    + (unsigned long)i,
    + process_list[i]->pid,
    + process_list[i]->state));
    +
    + switch(process_list[i]->state) {
    + case ps_none: SIGDPRINT(Debug,12,(&Debug, " (none) ")); break;
    + case ps_forked: SIGDPRINT(Debug,12,(&Debug, " (forked) ")); + shut = 1;
    + break;
    + case ps_running: SIGDPRINT(Debug,12,(&Debug, " (running) ")); + shut = 1;
    + break;
    + case ps_shutdown: SIGDPRINT(Debug,12,(&Debug, " (shutdown)")); break;
    + case ps_exited: SIGDPRINT(Debug,12,(&Debug, " (exited) ")); break;
    + case ps_died: SIGDPRINT(Debug,12,(&Debug, " (died) ")); break;
    + }
    +
    + if (-1 != process_list[i]->socket) {
    + DPRINT(Debug,12,(&Debug,", socket=%d",
    + process_list[i]->socket));
    + } else
    + shut = 0;
    +
    + if (process_list[i]->message) {
    + if (RESOLV_MESSAGE_STATE_magic != process_list[i]->message->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"free_non_blocking_qm",
    + "Bad magic number (resolv_message_state)",0);
    +
    + if (! process_list[i]->message->write_prepared) {
    + DPRINT(Debug,12,(&Debug,", write available"));
    + } else
    + shut = 0;
    + } else
    + shut = 0;
    + DPRINT(Debug,12,(&Debug,"\n"));
    +
    + #if defined(RESOLV_SENDOK) && defined(RESOLV_SEQPACKET)
    + if (shut) {
    + int r;
    + struct resolv_query_hdr Z = NULL_resolv_query_hdr;
    + Z.senderpid = mypid;
    + Z.msg = qm_shutdown;
    +
    + r = prepare_write_message(process_list[i]->message,process_list[i]->socket,
    + &Z,NULL,0);
    +
    + if (!r) {
    + enum wait_for_status rz;
    +
    + DPRINT(Debug,12,(&Debug,"free_non_blocking_qm: process #%d: Pausing for socket %d\n",
    + i,process_list[i]->socket));
    +
    + if ((rz = wait_for_action_or_timeout(resolv_write_message,1)) > wait_for_none)
    + r = prepare_write_message(process_list[i]->message,process_list[i]->socket,
    + &Z,NULL,0);
    + else {
    + switch (rz) {
    + int err UNUSED_VAROK;
    + case wait_for_done: break;
    + case wait_for_none:
    + DPRINT(Debug,12,(&Debug,
    + "free_non_blocking_qm: unexpected result from wait_for_action_or_timeout\n"));
    + break;
    + case wait_for_error:
    + err = errno;
    + DPRINT(Debug,12,(&Debug,"free_non_blocking_qm: wait errno=%d, %s\n",
    + err,strerror(err)));
    + break;
    + }
    + }
    + }
    +
    + if (r)
    + have_write = 1;
    + }
    + #endif
    + }
    + }
    +
    + #if defined(RESOLV_SENDOK) && defined(RESOLV_SEQPACKET)
    + if (have_write)
    + wait_for_action_or_timeout(resolv_write_message,0);
    + #endif
    +
    + #ifdef BACKGROUD_PROCESSES
    + if (handle_sigchld) {
    + DPRINT(Debug,12,(&Debug,"free_non_blocking_qm: checking for died processes.\n"));
    + sigchld_handler();
    + }
    +
    + for (i = 0; i < process_list_len; i++) {
    +
    + if (process_list[i]) {
    + if (RESOLV_PROCESS_magic != process_list[i]->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"free_non_blocking_qm",
    + "Bad magic number (resolv_process)",0);
    +
    + if (process_list[i]->state >= ps_forked &&
    + process_list[i]->state <= ps_exited) {
    + int r;
    +
    + DPRINT(Debug,12,(&Debug,"free_non_blocking_qm: process #%lu: pid=%d, ",
    + (unsigned long)i,
    + process_list[i]->pid));
    +
    + r = kill (process_list[i]->pid,SIGTERM);
    + if (0 == r) {
    + int s;
    + int exit_code;
    + DPRINT(Debug,12,(&Debug,"sent SIGTERM, waiting for termination\n"));
    +
    + s = wait_background_end(process_list[i]->pid,&exit_code);
    +
    + DPRINT(Debug,12,(&Debug,"free_non_blocking_qm: process #%lu: pid=%d, ",
    + (unsigned long)i,
    + process_list[i]->pid));
    + switch (s) {
    + case 1: DPRINT(Debug,12,(&Debug,"exited with status %d",exit_code)); break;
    + case 2: DPRINT(Debug,12,(&Debug,"no process")); break; + }
    + if (s < 0) {
    + DPRINT(Debug,12,(&Debug,"Dies with signal %d%s%s", + -s,
    + -s == SIGTERM ? " (SIGTERM)" : "", + -s == SIGINT ? " (SIGINT)" : ""
    + ));
    + }
    + } else if (-1 == r) {
    + int err UNUSED_VAROK = errno;
    + SIGDPRINT(Debug,12,(&Debug, "error %d: %s",
    + err,strerror(err)));
    + }
    + DPRINT(Debug,12,(&Debug,"\n"));
    + }
    + }
    + }
    + if (handle_sigchld) {
    + DPRINT(Debug,12,(&Debug,"free_non_blocking_qm: checking for died processes.\n"));
    + sigchld_handler();
    + }
    + #endif
    +
    + for (i = 0; i < process_list_len; i++) {
    +
    + if (process_list[i])
    + free_resolv_process(& (process_list[i]));
    + }
    + free(process_list);
    + process_list = NULL;
    +
    + }
    + process_list_len = 0;
    +
    + if (query_list) {
    + size_t i;
    +
    + for (i = 0; i < query_list_len; i++) {
    + if (query_list[i])
    + free_resolv_query_item(& (query_list[i]));
    + }
    + free(query_list);
    + query_list = NULL;
    + }
    + query_list_len = 0;
    +
    + }
    +
    + #define MAX_PROCESS 2
    + static int prx_max_processes = MAX_PROCESS;
    +
    + #define MAX_SKIP_PROCESS 5
    + static int prx_max_skip_process = MAX_SKIP_PROCESS;
    +
    + static const int MAX_prx_processes = (MAX_PROCESS + MAX_SKIP_PROCESS > 100) ? (MAX_PROCESS + MAX_SKIP_PROCESS) : 100;
    +
    +
    +
    + static void select_resolv_process P_((int pid,size_t querynum,const char *name));
    + static void select_resolv_process(pid,querynum,name)
    + int pid;
    + size_t querynum;
    + const char * name;
    + {
    + struct resolv_process * prx_static[MAX_PROCESS];
    + struct resolv_process ** prx = prx_static;
    + size_t prx_len = sizeof (prx_static) / sizeof (prx_static[0]);
    + size_t prx_count = 0;
    + size_t t;
    +
    + DPRINT(Debug,16,(&Debug,
    + "select_resolv_process: prx_max_processes=%d prx_max_skip_process=%d process_list_len=%lu\n",
    + prx_max_processes,
    + prx_max_skip_process,
    + (unsigned long)process_list_len
    + ));
    +
    + #if defined(RESOLV_SENDOK) && defined(RESOLV_SEQPACKET)
    + if (process_list) {
    + static size_t prindex = 0;
    + size_t previous_prindex = prindex;
    + size_t i;
    + int have_forked = 0;
    + int check_pipe = 0;
    +
    + int skip_count = 0;
    +
    + for (i = 0; i < process_list_len; i++) {
    + if (process_list[i]) {
    + if (RESOLV_PROCESS_magic != process_list[i]->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"select_resolv_process",
    + "Bad magic number (resolv_process)",0);
    +
    + if (ps_forked == process_list[i]->state &&
    + -1 != process_list[i]->pid) {
    + DPRINT(Debug,14,(&Debug, "select_resolv_process: process index %lu (pid %d) have state forked\n",
    + (unsigned long)i,process_list[i]->pid));
    + have_forked = 1;
    + break;
    + } else if (ps_shutdown < process_list[i]->state &&
    + -1 != process_list[i]->pid) {
    + DPRINT(Debug,14,(&Debug, "select_resolv_process: process index %lu (pid %d) have process ended",
    + (unsigned long)i,process_list[i]->pid));
    + if (process_list[i]->message) {
    + if (RESOLV_MESSAGE_STATE_magic != process_list[i]->message->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"select_resolv_process",
    + "Bad magic number (resolv_message_state)",0); +
    + if (process_list[i]->message->broken_pipe) {
    + DPRINT(Debug,14,(&Debug, "-- broken pipe (or EOF)"));
    + } else {
    + DPRINT(Debug,14,(&Debug, "-- EOF not read yet"));
    + check_pipe = 1;
    + }
    + }
    + DPRINT(Debug,14,(&Debug, "\n"));
    + }
    + }
    + }
    +
    + if (have_forked) {
    + DPRINT(Debug,14,(&Debug, "select_resolv_process: [pid %d] waiting running message from forked process.\n",
    + pid));
    + wait_for_action_or_timeout(resolv_read_message,1);
    + } else if (check_pipe) {
    + DPRINT(Debug,14,(&Debug, "select_resolv_process: [pid %d] polling EOF from pipe\n",
    + pid));
    + wait_for_action_or_timeout(resolv_read_message,0);
    + }
    +
    + do {
    + prindex++;
    +
    + if (prindex >= process_list_len) {
    + size_t X UNUSED_VAROK = prindex;
    +
    + prindex = 0;
    + DPRINT(Debug,14,(&Debug, "select_resolv_process: [pid %d] query %lu %s: reached process index %lu -- wrapping to %lu\n",
    + pid,
    + (unsigned long)querynum,
    + name,
    + (unsigned long)X,(unsigned long)prindex));
    + }
    +
    + if (prindex < process_list_len &&
    + prx_count < prx_max_processes) {
    +
    + if (prx_count > prx_len)
    + panic("RESOLV PANIC",__FILE__,__LINE__,
    + "select_resolv_process",
    + "Overflow",0);
    + else if (prx_count == prx_len) {
    +
    + if (prx == prx_static &&
    + prx_max_processes > prx_count) {
    + size_t a;
    +
    + DPRINT(Debug,14,(&Debug, "select_resolv_process: allocating list %lu",
    + (unsigned long)prx_len));
    +
    + prx_len = prx_max_processes;
    + if (prx_len > process_list_len+1 &&
    + process_list_len+1 > prx_count) {
    + DPRINT(Debug,14,(&Debug, " (max %d)",
    + prx_max_processes));
    + prx_len = process_list_len+1;
    + }
    +
    + DPRINT(Debug,14,(&Debug, " => %lu\n",
    + (unsigned long)prx_len));
    +
    + prx = safe_calloc(prx_len,sizeof(prx[0]));
    + for (a = 0;
    + a < prx_count &&
    + a < sizeof (prx_static) / sizeof (prx_static[0]);
    + a++)
    + prx[a] = prx_static[a];
    +
    + } else {
    + DPRINT(Debug,14,(&Debug,
    + "select_resolv_process: allocating list %lu -- something wrong\n",
    + (unsigned long)prx_len));
    + break;
    + }
    + }
    +
    + if (process_list[prindex]) {
    +
    + if (RESOLV_PROCESS_magic != process_list[prindex]->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"select_resolv_process",
    + "Bad magic number (resolv_process)",0);
    +
    + if (resolv_process_ok(process_list[prindex])) {
    +
    + DPRINT(Debug,14,(&Debug,
    + "select_resolv_process: [pid %d] query %lu %s: process index %lu is available (pid %d, socket %d)\n",
    + pid,
    + (unsigned long)querynum,
    + name,
    + (unsigned long)prindex,
    + process_list[prindex]->pid,
    + process_list[prindex]->socket));
    +
    + if (process_list[prindex]->message) {
    + if (RESOLV_MESSAGE_STATE_magic != process_list[prindex]->message->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"select_resolv_process",
    + "Bad magic number (resolv_message_state)",0);
    +
    + if (process_list[prindex]->message->broken_pipe) { + int r;
    + int may_delete = 0;
    +
    + DPRINT(Debug,14,(&Debug, "select_resolv_process: process #%lu: (pid %d, socket %d) -- broken pipe (or EOF)",
    + (unsigned long)prindex,
    + process_list[prindex]->pid,
    + process_list[prindex]->socket));
    +
    + r = kill(process_list[prindex]->pid,
    + SIGTERM);
    +
    + if (0 == r) {
    + int s;
    + int exit_code;
    +
    + DPRINT(Debug,14,(&Debug,"; sent SIGTERM, waiting for termination\n"));
    +
    + s = wait_background_end(process_list[prindex]->pid,&exit_code);
    +
    + DPRINT(Debug,14,(&Debug,"select_resolv_process: process #%lu: pid=%d, ",
    + (unsigned long)prindex,
    + process_list[prindex]->pid));
    + switch (s) {
    + case 1:
    + DPRINT(Debug,14,(&Debug,"exited with status %d",exit_code));
    + may_delete = 1;
    + break;
    + case 2: DPRINT(Debug,14,(&Debug,"no process"));
    + may_delete = 1;
    + break;
    + }
    + if (s < 0) {
    + DPRINT(Debug,14,(&Debug,"Dies with signal %d%s%s",
    + -s,
    + -s == SIGTERM ? " (SIGTERM)" : "",
    + -s == SIGINT ? " (SIGINT)" : ""
    + ));
    + may_delete = 1;
    + }
    + } else if (-1 == r) {
    + int err = errno;
    + SIGDPRINT(Debug,14,(&Debug, "; tried send SIGTERM, got error %d: %s",
    + err,strerror(err)));
    +
    + if (ESRCH == err)
    + may_delete = 1;
    + }
    +
    + if (may_delete)
    + goto cleanup_process;
    +
    + DPRINT(Debug,14,(&Debug,"\n"));
    +
    + goto skip_it;
    + }
    +
    + if (process_list[prindex]->message->write_prepared ||
    + process_list[prindex]->message->query_in_progress) {
    + DPRINT(Debug,14,(&Debug,
    + "select_resolv_process: process #%lu: (pid %d, socket %d)%s%s\n",
    + (unsigned long)prindex,
    + process_list[prindex]->pid,
    + process_list[prindex]->socket, + process_list[prindex]->message->write_prepared ?
    + " -- write prepared (busy)" : "",
    + process_list[prindex]->message->query_in_progress ?
    + " -- query in progress (busy)" : "",
    + process_list[prindex]->pid,
    + process_list[prindex]->socket));
    +
    + if (skip_count >= prx_max_skip_process) {
    + DPRINT(Debug,14,(&Debug,
    + "select_resolv_process: Already %d skipped, using anyway\n",
    + skip_count));
    + } else {
    + skip_count ++;
    + goto skip_it;
    + }
    + }
    +
    + }
    +
    + prx[prx_count] = process_list[prindex];
    + inc_resolv_process_refcount(prx[prx_count]);
    + prx_count++;
    + } else if (ps_shutdown < process_list[prindex]->state &&
    + -1 != process_list[prindex]->pid) {
    + DPRINT(Debug,14,(&Debug,
    + "select_resolv_process: [pid %d] query %lu %s: process index %lu not available (pid %d, socket %d)",
    + pid,
    + (unsigned long)querynum,
    + name,
    + (unsigned long)prindex,
    + process_list[prindex]->pid,
    + process_list[prindex]->socket));
    +
    + if (process_list[prindex]->message) {
    + if (RESOLV_MESSAGE_STATE_magic != process_list[prindex]->message->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"select_resolv_process",
    + "Bad magic number (resolv_message_state)",0);
    +
    + if (process_list[prindex]->message->broken_pipe) { + DPRINT(Debug,14,(&Debug," -- broken pipe (or EOF)"));
    + goto cleanup_process;
    + }
    + DPRINT(Debug,14,(&Debug,", ignored now\n"));
    +
    + } else
    + goto cleanup_process;
    + } else if (-1 == process_list[prindex]->pid) {
    + DPRINT(Debug,14,(&Debug,
    + "select_resolv_process: [pid %d] query %lu %s: process index %lu not available (no process?)",
    + pid,
    + (unsigned long)querynum,
    + name,
    + (unsigned long)prindex));
    +
    + cleanup_process:
    + SIGDPRINT(Debug,14,(&Debug, "; may delete process #%lu index entry\n",
    + (unsigned long)prindex));
    +
    + free_resolv_process(& (process_list[prindex]));
    +
    + }
    + } else {
    + DPRINT(Debug,15,(&Debug,
    + "select_resolv_process: [pid %d] query %lu %s: process index %lu unused entry\n",
    + pid,
    + (unsigned long)querynum,
    + name,
    + (unsigned long)prindex));
    + }
    + }
    +
    + skip_it: ;
    +
    + } while (prindex != previous_prindex &&
    + prx_count < prx_max_processes);
    + }
    +
    + if (prx_count < prx_max_processes &&
    + prx_count < prx_len) {
    +
    + prx[prx_count] = give_resolv_process(pid);
    +
    + DPRINT(Debug,14,(&Debug,
    + "select_resolv_process: [pid %d] query %lu %s: added process (pid %d, socket %d)\n",
    + pid,
    + (unsigned long)querynum,
    + name,
    + prx[prx_count]->pid,
    + prx[prx_count]->socket));
    +
    + inc_resolv_process_refcount(prx[prx_count]);
    + prx_count++;
    + }
    +
    + for (t = 0; t < prx_count; t++) {
    +
    + union action_routine_data data;
    +
    + if (RESOLV_PROCESS_magic != prx[t]->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"select_resolv_process",
    + "Bad magic number (resolv_process)",0);
    +
    + if (prx[t]->message) {
    + if (RESOLV_MESSAGE_STATE_magic != prx[t]->message->magic)
    + panic("RESOLV PANIC",__FILE__,__LINE__,"select_resolv_process", + "Bad magic number (resolv_message_state)",0);
    +
    + } else if (! prx[t]->message) {
    + DPRINT(Debug,14,(&Debug,
    + "select_resolv_process: [pid %d] query %lu %s: adding message state for pid %d (socket %d)\n",
    + pid,
    + (unsigned long)querynum,
    + name,
    + prx[t]->pid,
    + prx[t]->socket));
    + prx[t]->message =
    + new_resolv_message_state(pid /* my pid -- senderpid */);
    + }
    +
    + data.resolv = prx[t]->message;
    +
    + change_action(prx[t]->socket,-1,resolv_read_message,resolv_write_message,
    + no_action_routine,
    + resolv_free_state,resolv_inc_state_refcount,data);
    +
    + DPRINT(Debug,14,(&Debug,
    + "select_resolv_process: [pid %d] query %lu %s: scheduled write for pid %d socket %d\n",
    + pid,
    + (unsigned long)querynum,
    + name,
    + prx[t]->pid,
    + prx[t]->socket));
    +
    + free_resolv_process(& prx[t]);
    + }
    + #endif
    +
    + if (prx != prx_static)
    + free(prx);
    + }
    +
    + static struct resolv_query_item *query_one_name P_((struct resolv_cache * record,
    + const char * name,
    + const char * domain,
    + const struct schedule_timelimit * now,
    + ns_type q_type,
    + enum looking_up * looking_up,
    + int * err_p,
    + int is_search
    + ));
    + static struct resolv_query_item *query_one_name(record,name,domain,now,q_type,
    + looking_up,err_p, is_search)
    + struct resolv_cache * record;
    + const char * name;
    + const char * domain;
    + const struct schedule_timelimit * now;
    + ns_type q_type;
    + enum looking_up * looking_up;
    + int * err_p;
    + int is_search;
    + {
    + struct resolv_query_item * ret = NULL;
    + int pid = getpid();
    +
    + static size_t querynum = 0;
    + size_t previous_querynum = querynum;
    +
    + char * name_buffer = NULL;
    + size_t qsize = RESOLV_BUFSIZE;
    + int retry = 0;
    +
    + *err_p = 0;
    +
    + do {
    +
    + querynum++;
    + if (querynum >= query_list_len) {
    + size_t X UNUSED_VAROK = querynum;
    +
    + querynum = 0;
    + DPRINT(Debug,14,(&Debug, "query_one_name: [pid %d] name %s domain %s -- reached query number %lu -- wrapping to %lu\n",
    + pid,name,
    + domain ? domain : "<none>",
    + (unsigned long)X,(unsigned long)querynum));
    + }
    +
    + /* 0 is not used */
    + if (querynum > 0 && querynum < query_list_len &&
    + ! query_list[querynum]) {
    +
    + DPRINT(Debug,14,(&Debug, "query_one_name: [pid %d] name %s domain %s -- query number %lu is available\n",
    + pid,name,
    + domain ? domain : "<none>",(unsigned long)querynum));
    + break;
    + }
    +
    +
    + } while (querynum != previous_querynum);
    +
    + if (querynum < 1 || querynum >= query_list_len ||
    + query_list[querynum]) {
    + size_t nsize = query_list_len +3;
    + /* Increment query list */
    +
    + query_list = safe_array_realloc(query_list,nsize,sizeof (query_list[0]));
    +
    + DPRINT(Debug,14,(&Debug,
    + "query_one_name: [pid %d] name %s domain %s -- enlarging query_list %ld => %ld\n",
    + pid,name,
    + domain ? domain : "<none>",
    + (unsigned long)query_list_len, (unsigned long)nsize)); +
    + querynum = query_list_len;
    + if (!querynum)
    + querynum++;
    +
    + while (query_list_len < nsize)
    + query_list[query_list_len++] = NULL;
    +
    + }
    +
    + if (querynum < 1 || querynum >= query_list_len ||
    + query_list[querynum])
    + panic("RESOLV PANIC",__FILE__,__LINE__,"query_one_name",
    + "Bad magic number (resolv_process) querynum",0);
    +
    +
    + ret = query_list[querynum] = new_resolv_query_item(querynum,name);
    + inc_resolv_query_item_recount(ret);
    + ret->query_time = *now;
    + ret->query_buffer = new_resolv_message();
    + ret->query_hdr = new_resolv_query_hdr();
    + if (is_search) {
    + DPRINT(Debug,14,(&Debug,
    + "query_one_name: [pid %d] name %s domain %s -- setting 'is search'\n",
    + pid,name,
    + domain ? domain : "<none>"));
    +
    + ret->is_search = 1;
    + }
    +
    + ret->answer_buffer = new_resolv_message();
    + resize_resolv_message(ret->answer_buffer,RESOLV_BUFSIZE);
    + ret->answer_hdr = new_resolv_query_hdr();
    + ret->cache_answer_in = record;
    + inc_resolv_cache_refcount(ret->cache_answer_in);
    + if (looking_up)
    + ret->looking_up = *looking_up;
    +
    + if (domain && domain[0]) {
    + size_t a = strlen(name);
    + size_t d = strlen(domain);
    + size_t len = a+d+2;
    + size_t z = a;
    +
    + name_buffer = safe_malloc(len);
    +
    + memcpy(name_buffer,name,a);
    + if ('.' != domain[0])
    + name_buffer[z++] = '.';
    + memcpy(name_buffer+z,domain,d);
    + name_buffer[z+d] = '\0';
    +
    + DPRINT(Debug,14,(&Debug, "query_one_name: [pid %d] query %lu: name %s domain %s => %s\n",
    + pid,
    + (unsigned long)querynum,
    + name,
    + domain ? domain : "<none>",
    + name_buffer));
    +
    + }
    +
    + do {
    + int qlen;
    +
    + resize_resolv_message(ret->query_buffer,qsize);
    +
    + DPRINT(Debug,14,(&Debug, "query_one_name: [pid %d] query %lu %s: query buffer size %u\n",
    + pid,
    + (unsigned long)querynum,
    + name_buffer ? name_buffer : name,
    + (unsigned) ret->query_buffer->message_size));
    +
    + errno = 0;
    +
    + qlen = res_mkquery(QUERY,name_buffer ? name_buffer : name,
    + ns_c_in,q_type,
    + NULL,0 /* Only used with IQUERY */,
    + NULL /* Only used with dynamic update */,
    + ret->query_buffer->message,
    + ret->query_buffer->message_size);
    +
    + if (qlen < 0 ) {
    + int err = errno;
    +
    + DPRINT(Debug,14,(&Debug, "query_one_name: [pid %d] query %lu %s: res_mkquery: err = %d (%s)\n",
    + pid,
    + (unsigned long)querynum,
    + name_buffer ? name_buffer : name,
    + err,strerror(err)));
    +
    + if (EMSGSIZE == err && qsize < MAX_resolv_bufsize) {
    +
    + if (qsize < sizeof (struct resolv_sizeupdate))
    + qsize = sizeof (struct resolv_sizeupdate);
    + else
    + qsize <<=1;
    +
    + if (qsize > MAX_resolv_bufsize)
    + qsize = MAX_resolv_bufsize;
    +
    + retry = 1;
    +
    + } else {
    + *err_p = err;
    +
    + free_resolv_query_item(&ret);
    + goto failure;
    +
    + }
    + } else if (qlen <= USHRT_MAX) {
    + ret->query_buffer->message_len = qlen;
    +
    +
    + DPRINT(Debug,14,(&Debug, "query_one_name: [pid %d] query %lu %s: res_mkquery: message len %u\n",
    + pid,
    + (unsigned long)querynum,
    + name_buffer ? name_buffer : name,
    + (unsigned) ret->query_buffer->message_len));
    +
    + retry = 0;
    + } else {
    + DPRINT(Debug,14,(&Debug,
    + "query_one_name: [pid %d] query %lu %s: query len %d, too long\n",
    + pid,
    + (unsigned long)querynum,
    + name_buffer ? name_buffer : name,
    + qlen));
    + *err_p = EMSGSIZE;
    +
    + free_resolv_query_item(&ret);
    + goto failure;
    + }
    +
    + if (retry) {
    + DPRINT(Debug,14,(&Debug, "query_one_name: [pid %d] query %lu %s: res_mkquery: retrying with size %lu\n",
    + pid,
    + (unsigned long)querynum,
    + name_buffer ? name_buffer : name,
    + (unsigned long)qsize));
    + }
    +
    + } while (retry);
    +
    + ret->query_hdr->buflen = ret->query_buffer->message_len;
    + ret->query_hdr->querynum = querynum;
    + ret->query_hdr->senderpid = pid;
    + ret->query_hdr->msg = qm_query;
    +
    + if (!parse_resolv_message1(ret->query_buffer,err_p)) {

    [continued in next message]

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