From 69a54f8624734453c44ef5982599b6a8f57401b4 Mon Sep 17 00:00:00 2001 From: cvs Date: Fri, 31 Mar 2000 14:11:23 +0000 Subject: [PATCH] *** empty log message *** --- hardsup/asynsrv_def.h | 4 +- hardsup/asynsrv_utility.c | 494 ++++++++++++++++++++++---------------- 2 files changed, 287 insertions(+), 211 deletions(-) diff --git a/hardsup/asynsrv_def.h b/hardsup/asynsrv_def.h index 6e3873b8..ccaed197 100644 --- a/hardsup/asynsrv_def.h +++ b/hardsup/asynsrv_def.h @@ -1,6 +1,6 @@ #ifndef _asynsrv_def_ #define _asynsrv_def_ -/*------------------------------------------------ AsynSrv_DEF.H Ident V01M +/*------------------------------------------------ AsynSrv_DEF.H Ident V01N */ #ifndef OffsetOf #define OffsetOf(type, identifier) ((size_t)(&((type*) NULL)->identifier)) @@ -32,6 +32,8 @@ char eot[4]; /* Expected terminators */ int max_replies; /* Binary version of #replies in response */ int n_replies; /* # of last response returned to caller */ + void (*idleHandler) (int, int); /* MZ. handler called when waiting .. + ** .. on a response */ }; struct AsynSrv_HostPortSkt { diff --git a/hardsup/asynsrv_utility.c b/hardsup/asynsrv_utility.c index 6baa4aa5..93205646 100644 --- a/hardsup/asynsrv_utility.c +++ b/hardsup/asynsrv_utility.c @@ -1,4 +1,4 @@ -#define ident "1B12" +#define ident "1C02" #ifdef VAXC #module AsynSrv_Utility ident #endif @@ -6,9 +6,6 @@ #pragma module AsynSrv_Utility ident #endif /* -#define DEBUG 1 -*/ -/* ** +--------------------------------------------------------------+ ** | Paul Scherrer Institute | ** | Department ASQ | @@ -47,6 +44,8 @@ ** 1B02 5-May-1997 DM. Set 5 sec time-out on "connect" on VMS systems. ** 1B07 11-Mar-1998 DM. Allow range of msecTmo to be 0 - 999999 (it was ** 100 - 999999). +** 1C01 21-Mar-2000 MZ. Introduced idleHandler +** 1C02 30-Mar-2000 DM. Add trace and flush facilities. **============================================================================ ** The entry points included in this module are described below. Prototypes ** can be defined via: @@ -57,11 +56,14 @@ ** AsynSrv_Config - Configure an open AsynSrv_Utility connection. ** AsynSrv_ConfigDflt - Set defaults for AsynSrv_Open. ** AsynSrv_ErrInfo - Return detailed status from last operation. +** AsynSrv_Flush - Send a "FLUSH" request to an RS-232-C Server. ** AsynSrv_GetReply - Get next reply from a reply buffer. ** AsynSrv_Open - Open a connection to an RS-232-C Server. ** AsynSrv_SendCmnds - Send commands to a channel of an RS-232-C Server. ** AsynSrv_SendCmndsBig - Similar to AsynSrv_SendCmnds but with user ** defined buffer sizes. +** AsynSrv_Trace - Send a "TRACE ON" or "TRACE OFF" request to +** an RS-232-C Server. **--------------------------------------------------------------------- ** int AsynSrv_Close (&asyn_info, force_flag) ** ------------- @@ -124,6 +126,13 @@ ** commands sent to a serial channel on the ** server. The first character specifies the ** number of terminators (max=3). +** "idleHdl" void (*hdl) (int msecTmo, int socket) MZ. +** A handler which is called in AsynSrv_SendCmds +** before receiving the response. The handler +** should contain a call to "select ()" and return +** on a read event on the socket passed as +** argument, or after the timeout specified +** has expired. **--------------------------------------------------------------------- ** int AsynSrv_ConfigDflt (&par_id, par_val, ...) ** ------------------ @@ -185,6 +194,24 @@ ** Returns detailed status of the last operation. Once an error has been ** detected, the error status is frozen until this routine has been called. **------------------------------------------------------------------------- +** int AsynSrv_Flush (&asyn_info) +** ------------- +** Input Args: +** struct AsynSrv__info *asyn_info - the structure used in the call to +** AsynSrv_Open. It contains settings required +** for setting up and sending send_buff. +** Output Args: +** none +** Modified Args: +** none +** Return status: +** Same as AsynSrv_Trace +** Routines called: +** Socket library routines send and recv. +** Description: +** The 4-byte message "-004" is sent to the server to cause it to flush +** its buffers. Otherwise, this routine is identical to AsynSrv_Trace. +**------------------------------------------------------------------------- ** char *AsynSrv_GetReply (&asyn_info, &rcve_buff, &last_rply) ** ---------------- ** Input Args: @@ -394,6 +421,69 @@ ** transmission of zeros) and the send and receive structures are assumed ** to have been extended to the sizes specified by suitable declarations ** in the calling module. +**------------------------------------------------------------------------- +** int AsynSrv_Trace (&asyn_info, state) +** ------------- +** Input Args: +** struct AsynSrv__info *asyn_info - the structure used in the call to +** AsynSrv_Open. It contains settings required +** for setting up and sending send_buff. +** int state - True/False to turn tracing on/off. +** Output Args: +** none +** Modified Args: +** none +** Return status: +** True if no problems detected, otherwise False and errcode (see +** AsynSrv_ErrInfo) is set to indicate the nature of the problem. +** AsynSrv_errcode may be set as follows: +** The next 4 errors are related to network errors whilst sending the +** 4-byte message buffer to the server: +** ASYNSRV__BAD_SEND --> Network problem - server has +** probably abended. +** ASYNSRV__BAD_SEND_PIPE --> Network pipe broken - probably same +** cause as ASYNSRV__BAD_SEND. +** ASYNSRV__BAD_SEND_NET --> Some other network problem. "errno" +** may be helpful. +** ASYNSRV__BAD_SEND_UNKN --> Some other network problem happened +** resulting in the message not +** getting sent completely. "errno" is +** probably not helpful in this case. +** ASYNSRV__BAD_RECV \ These are network errors whilst +** ASYNSRV__BAD_RECV_PIPE > receiving the 4-byte response. +** ASYNSRV__BAD_RECV_NET / They are analogous to ASYNSRV__BAD_SEND +** ASYNSRV__BAD_RECV_UNKN / ... ASYNSRV__BAD_SEND_UNKN. +** ASYNSRV__BAD_NOT_BCD --> The 4-byte response header is not an +** echo of the 4 bytes which were sent. +** ASYNSRV__FORCED_CLOSED --> The connection to the channel has been +** forcefully closed. See below. +** ASYNSRV__FORCED_CLOSED occurs if AsynSrv_Close has been called +** for another device on the same server and the 'force_flag' +** was set (see AsynSrv_Close). The caller should call +** AsynSrv_Close and then AsynSrv_Open to re-establish a +** connection to the server. +** Routines called: +** Socket library routines send and recv. +** Description: +** To turn on tracing, the 4-byte message "-002" is sent to the server. +** To turn off tracing, the 4-byte message "-003" is sent to the server. +** The server is expected to respond by echoing the message. +** +** For any of the following errors: +** ASYNSRV__BAD_SEND (Note: ASYNSRV__BAD_SEND_LEN and +** ASYNSRV__BAD_SEND_PIPE ASYNSRV__BAD_RECV_LEN and +** ASYNSRV__BAD_SEND_NET ASYNSRV__BAD_REPLY +** ASYNSRV__BAD_SEND_UNKN do not cause a close) +** ASYNSRV__BAD_RECV +** ASYNSRV__BAD_RECV_PIPE +** ASYNSRV__BAD_RECV_NET +** ASYNSRV__BAD_RECV_UNKN +** ASYNSRV__BAD_NOT_BCD +** the network link to the server is force-closed via a call to +** AsynSrv_Close. Once the error has been corrected, the link can be +** re-opened via a call to AsynSrv_Open. As a result of the force-close, +** other active handles will need to be released via a call to +** AsynSrv_Close before AsynSrv_Open is called. **============================================================================*/ /* **--------------------------------------------------------------------------- @@ -412,6 +502,7 @@ #include #ifdef __VMS +#pragma nostandard /* The "$" characters in ucx$inetdef.h give trouble! */ #include #include #else @@ -615,6 +706,8 @@ return False; } memcpy (asyn_info->eot, my_eot, 4); + }else if (strcmp (txt_ptr, "idleHdl") == 0) { /* MZ. */ + asyn_info->idleHandler = (void (*) (int, int)) va_arg (ap, void *); }else { AsynSrv_errcode = ASYNSRV__BAD_PAR; return False; @@ -764,6 +857,94 @@ } /* **--------------------------------------------------------------------------- +** AsynSrv_Flush: Send a Flush command to RS232C server. +*/ + int AsynSrv_Flush ( +/* ============= +*/ struct AsynSrv__info *asyn_info) { + + int status; + char cmnd[8], rply[8]; + /*---------------------------------------------- + ** Pre-set the routine name (in case of error) + */ + if (AsynSrv_errcode == 0 && AsynSrv_call_depth < 5) { + strcpy (AsynSrv_routine[AsynSrv_call_depth], "AsynSrv_Flush"); + AsynSrv_call_depth++; + } + /*---------------------------------------------- + ** Do nothing if no connection - the connection gets + ** closed if an error is detected. The connection may + ** also be marked to have been forcefully closed. + */ + if (asyn_info->skt <= 0) { + if ((AsynSrv_errcode == 0) && (asyn_info->skt < 0)) { + AsynSrv_errcode = ASYNSRV__FORCED_CLOSED; + } + return False; + } + /*---------------------------------------------- + ** Set up message for server. + */ + strcpy (cmnd, "-004"); + + status = send (asyn_info->skt, cmnd, 4, 0); /* Send the request */ + if (status != 4) { + GetErrno (&AsynSrv_errno, &AsynSrv_vaxc_errno); + if (status == 0) { + AsynSrv_errcode = ASYNSRV__BAD_SEND; /* Server exited (probably) */ + fprintf (stderr, "\nAsynSrv_Flush/send: probable network problem"); + }else if (status == -1) { + if (AsynSrv_errno == EPIPE) { + AsynSrv_errcode = ASYNSRV__BAD_SEND_PIPE; /* Server exited (probably) */ + fprintf (stderr, "\nAsynSrv_Flush/send: broken network pipe"); + }else { + AsynSrv_errcode = ASYNSRV__BAD_SEND_NET; /* It's some other net problem */ + perror ("AsynSrv_Flush/send"); + } + }else { + AsynSrv_errcode = ASYNSRV__BAD_SEND_UNKN; /* TCP/IP problems */ + fprintf (stderr, "\nAsynSrv_Flush/send: probable TCP/IP problem"); + } + AsynSrv_Close (asyn_info, True); /* Force close TCP/IP connection */ + fprintf (stderr, " - link to server force-closed.\n"); + return False; + } + + status = recv (asyn_info->skt, rply, 4, 0); + if (status != 4) { + GetErrno (&AsynSrv_errno, &AsynSrv_vaxc_errno); + if (status == 0) { + AsynSrv_errcode = ASYNSRV__BAD_RECV; /* Server exited (probably) */ + fprintf (stderr, "\nAsynSrv_Flush/recv: probable network problem"); + }else if (status == -1) { + if (AsynSrv_errno == EPIPE) { + AsynSrv_errcode = ASYNSRV__BAD_RECV_PIPE; /* Server exited (probably) */ + fprintf (stderr, "\nAsynSrv_Flush/recv: broken network pipe"); + }else { + AsynSrv_errcode = ASYNSRV__BAD_RECV_NET; /* It's some other net problem */ + perror ("AsynSrv_Flush/recv"); + } + }else { + AsynSrv_errcode = ASYNSRV__BAD_RECV_UNKN; /* TCP/IP problems */ + fprintf (stderr, "\nAsynSrv_Flush/recv: probable TCP/IP problem"); + } + AsynSrv_Close (asyn_info, True); /* Force close TCP/IP connection */ + fprintf (stderr, " - link to server force-closed.\n"); + return False; + } + if (memcmp (cmnd, rply, 4) != 0) { + AsynSrv_errcode = ASYNSRV__BAD_NOT_BCD; /* Message not echoed OK */ + AsynSrv_Close (asyn_info, True); /* Force close TCP/IP connection */ + fprintf (stderr, "\nAsynSrv_Flush/recv: command not echoed correctly" + " - link to server force-closed.\n"); + return False; + } + if (AsynSrv_errcode == 0) AsynSrv_call_depth--; + return True; + } +/* +**--------------------------------------------------------------------------- ** AsynSrv_GetReply: Get next reply from a reply buffer. */ char *AsynSrv_GetReply ( @@ -791,9 +972,6 @@ } } } -#ifdef DEBUG - printf("Reply: %s\n", pntr); -#endif return pntr; } /* @@ -878,6 +1056,7 @@ AsynSrv_eot, sizeof (asyn_info->eot)); asyn_info->max_replies = asyn_info->n_replies = 0; + asyn_info->idleHandler = NULL; AsynSrv_call_depth--; return True; } @@ -890,16 +1069,16 @@ return False; } /*-------------------------------------------------------- -** But, before going any further, do some quick checks on -** values in asyn_info. +** There's room for a new connection but, before going any +** further, do some quick checks on values in asyn_info. */ - if ((asyn_info->port <= 0) || - (asyn_info->port > 65535)) { + if ((asyn_info->port <= 0) || + (asyn_info->port > 65535) || + (asyn_info->chan < 0) || + (asyn_info->chan > 255)) { AsynSrv_errcode = ASYNSRV__BAD_PAR; /* Something is bad! */ return False; } - if (asyn_info->chan < 0) asyn_info->chan = 0; - if (asyn_info->chan > 255) asyn_info->chan = 0; /*-------------------------------------------------------- ** Set up a new connection. */ @@ -1011,6 +1190,7 @@ ** .. dflt terminator(s) */ asyn_info->max_replies = 0; asyn_info->n_replies = 0; + asyn_info->idleHandler = NULL; /* ** Send a null command buffer to the server. This should give ** a "protocol mismatch" error response and from this we can get @@ -1167,9 +1347,6 @@ cmnd_lst_ptr += c_len; ncmnds++; bytes_left = bytes_left - size; -#ifdef DEBUG - printf("Sending: %s\n",txt_ptr); -#endif txt_ptr = va_arg (ap, char *); } } @@ -1206,6 +1383,14 @@ return False; } + if (asyn_info->idleHandler != NULL) { /* MZ. */ + sscanf(asyn_info->tmo, "%4d", &i); /* Decode timeout from ASCII .. + ** .. encoded deci-sec */ + asyn_info->idleHandler (i*150, asyn_info->skt); /* Wait for an event .. + ** .. on asyn_info->skt or a .. + ** .. timeout of 1.5*tmo */ + } + size = sizeof (rcve_buff->msg_size); status = recv (asyn_info->skt, rcve_buff->msg_size, size, 0); if (status != size) { @@ -1557,206 +1742,95 @@ } /* **--------------------------------------------------------------------------- -** AsynSrv_Force: Open a connection to an RS-232-C Server. -** Thereby insisting on an own socket. +** AsynSrv_Trace: Send a Trace command to RS232C server. */ - int AsynSrv_Force ( -/* ============ -*/ struct AsynSrv__info *asyn_info) { + int AsynSrv_Trace ( +/* ============= +*/ struct AsynSrv__info *asyn_info, + int state) { - int i, status; - int my_skt; - char old_time_out[4]; - union { - char chars[4]; - int val; - } time_out; - char buff[128]; - struct RS__MsgStruct s_buff; - struct RS__RespStruct r_buff; - unsigned int oto_len, oto_status; - struct hostent *rmt_hostent; - struct in_addr *rmt_inet_addr_pntr; - struct in_addr rmt_inet_addr; - int rmt_sockname_len; - struct sockaddr_in lcl_sockname; - struct sockaddr_in rmt_sockname; - - char *errtxt_ptr; - int errcode, my_errno, my_vaxc_errno; -/*-------------------------------------------------------- -*/ - asyn_info->skt = 0; -/*-------------------------------------------------------- -** Initialise the error info stack and pre-set the -** routine name (in case of error). -*/ - AsynSrv_errcode = AsynSrv_errno = AsynSrv_vaxc_errno = 0; - strcpy (AsynSrv_routine[0], "AsynSrv_Open"); - AsynSrv_call_depth = 1; -/*-------------------------------------------------------- -** But, before going any further, do some quick checks on -** values in asyn_info. -*/ - if ((asyn_info->port <= 0) || - (asyn_info->port > 65535)) { - AsynSrv_errcode = ASYNSRV__BAD_PAR; /* Something is bad! */ - return False; - } - if (asyn_info->chan < 0) asyn_info->chan = 0; - if (asyn_info->chan > 255) asyn_info->chan = 0; -/*-------------------------------------------------------- -** Set up a new connection. -*/ - /*--------------------------- - ** Get the Internet address of the server. - */ - rmt_inet_addr.s_addr = inet_addr (asyn_info->host); - if (rmt_inet_addr.s_addr != -1) { - rmt_inet_addr_pntr = &rmt_inet_addr; - }else { - rmt_hostent = gethostbyname (asyn_info->host); - if (rmt_hostent == NULL) { - AsynSrv_errcode = ASYNSRV__BAD_HOST; - GetErrno (&AsynSrv_errno, &AsynSrv_vaxc_errno); /* Save errno info */ - fprintf (stderr, "\nAsynSrv_Open/gethostbyname: Failed to get Internet " - "address of \"%s\".\n", asyn_info->host); - return False; - } - rmt_inet_addr_pntr = (struct in_addr *) rmt_hostent->h_addr_list[0]; - } - /*--------------------------- - ** Create a TCP/IP socket for connecting to server and bind it. - */ - my_skt = socket (AF_INET, SOCK_STREAM, 0); - if (my_skt <= 0) { - AsynSrv_errcode = ASYNSRV__BAD_SOCKET; - GetErrno (&AsynSrv_errno, &AsynSrv_vaxc_errno); /* Save the errno info */ - fprintf (stderr, "\nAsynSrv_Open/socket: Failed to create a socket.\n"); - return False; - } - lcl_sockname.sin_family = AF_INET; - lcl_sockname.sin_port = htons (0); - lcl_sockname.sin_addr.s_addr = 0; - status = bind (my_skt, (struct sockaddr *) &lcl_sockname, - sizeof (lcl_sockname)); - if (status == -1) { - close (my_skt); - AsynSrv_errcode = ASYNSRV__BAD_BIND; - GetErrno (&AsynSrv_errno, &AsynSrv_vaxc_errno); /* Save the errno info */ - fprintf (stderr, "\nAsynSrv_Open/bind: Failed to bind socket.\n"); - return False; - } - /*--------------------------- - ** Set short time-out (VMS systems only) - */ -#ifdef __VMS - oto_len = sizeof (old_time_out); /* Save current time-out first */ - oto_status = getsockopt (my_skt, IPPROTO_TCP, UCX$C_TCP_PROBE_IDLE, - old_time_out, &oto_len); - - if (oto_status == 0) { - time_out.val = AsynSrv_connect_tmo; /* Set new time-out */ - status = setsockopt (my_skt, IPPROTO_TCP, UCX$C_TCP_PROBE_IDLE, - time_out.chars, sizeof (time_out)); - } -#endif - /*--------------------------- - ** Connect to RS-232-C Server. - */ - rmt_sockname_len = sizeof (rmt_sockname); - rmt_sockname.sin_family = AF_INET; - rmt_sockname.sin_port = htons (asyn_info->port); - rmt_sockname.sin_addr.s_addr = rmt_inet_addr_pntr->s_addr; - status = connect (my_skt, (struct sockaddr *) &rmt_sockname, - sizeof (rmt_sockname)); - if (status != 0) { - close (my_skt); - AsynSrv_errcode = ASYNSRV__BAD_CONNECT; - GetErrno (&AsynSrv_errno, &AsynSrv_vaxc_errno); /* Save the errno info */ - fprintf (stderr, - "\nAsynSrv_Open/connect: Failed to connect to server.\n"); - perror ("AsynSrv_Open"); - return False; - } - /*--------------------------- - ** Restore time-out (VMS only) - */ -#ifdef __VMS - if (oto_status == 0) { - setsockopt (my_skt, IPPROTO_TCP, UCX$C_TCP_PROBE_IDLE, - old_time_out, oto_len); - } -#endif - /*--------------------------------------------------- - ** Setup the defaults in the AsynSrv__info data structure. - */ - asyn_info->skt = my_skt; /* Return socket number to caller */ - - asyn_info->protocol_code = 0; /* Ensure protocol_code set to "unknown" */ - memcpy (asyn_info->protocol_id, "\0\0\0\0", - sizeof (asyn_info->protocol_id)); - asyn_info->cmnd_hdr_len = 4; - strcpy (asyn_info->cmnd_fmt, "%04d"); - asyn_info->rply_hdr_len = 4; - strcpy (asyn_info->rply_fmt, "%4d"); - - sprintf (buff, "%04d", asyn_info->chan); /* Convert channel # to ASCII */ - memcpy (asyn_info->chan_char, buff, sizeof (asyn_info->chan_char)); - - sprintf (buff, "%04d", AsynSrv_msec_tmo/100); /* Set dflt time-out .. - ** .. (deci-secs) */ - memcpy (asyn_info->tmo, buff, sizeof (asyn_info->tmo)); - - memcpy (asyn_info->eot, AsynSrv_eot, sizeof (asyn_info->eot)); /* Set .. - ** .. dflt terminator(s) */ - asyn_info->max_replies = 0; - asyn_info->n_replies = 0; - /* - ** Send a null command buffer to the server. This should give - ** a "protocol mismatch" error response and from this we can get - ** the actual protocol level supported by the server. - */ - status = AsynSrv_SendCmnds (asyn_info, &s_buff, &r_buff, NULL); - if (!status && (AsynSrv_errcode == ASYNSRV__BAD_PROT_LVL)) { - /* - ** As expected, we got a "protocol mismatch" error. - ** Save the server's protocol level for future use. + int status; + char cmnd[8], rply[8]; + /*---------------------------------------------- + ** Pre-set the routine name (in case of error) */ - memcpy (asyn_info->protocol_id, r_buff.s_pcol_lvl, - sizeof (r_buff.s_pcol_lvl)); - if (strncmp (r_buff.s_pcol_lvl, RS__PROTOCOL_ID_V01B, - strlen (RS__PROTOCOL_ID_V01B)) == 0) { - asyn_info->protocol_code = RS__PROTOCOL_CODE_V01B; - asyn_info->cmnd_hdr_len = 4; - strcpy (asyn_info->cmnd_fmt, "%04d"); - asyn_info->rply_hdr_len = 4; - strcpy (asyn_info->rply_fmt, "%4d"); - }else if (strncmp (r_buff.s_pcol_lvl, RS__PROTOCOL_ID, - strlen (RS__PROTOCOL_ID)) == 0) { - asyn_info->protocol_code = RS__PROTOCOL_CODE; - asyn_info->cmnd_hdr_len = 2; - strcpy (asyn_info->cmnd_fmt, "%02d"); - asyn_info->rply_hdr_len = 2; - strcpy (asyn_info->rply_fmt, "%2d"); - }else { - close (my_skt); - asyn_info->skt = 0; - fprintf (stderr, - "\nAsynSrv_Open: Server protocol level is unrecognised.\n" - " Server level is \"%4s\"\n", r_buff.s_pcol_lvl); - return False; + if (AsynSrv_errcode == 0 && AsynSrv_call_depth < 5) { + strcpy (AsynSrv_routine[AsynSrv_call_depth], "AsynSrv_Trace"); + AsynSrv_call_depth++; + } + /*---------------------------------------------- + ** Do nothing if no connection - the connection gets + ** closed if an error is detected. The connection may + ** also be marked to have been forcefully closed. + */ + if (asyn_info->skt <= 0) { + if ((AsynSrv_errcode == 0) && (asyn_info->skt < 0)) { + AsynSrv_errcode = ASYNSRV__FORCED_CLOSED; } - }else { - close (my_skt); - asyn_info->skt = 0; - AsynSrv_errcode = ASYNSRV__BAD_PROT_LVL; - fprintf (stderr, - "\nAsynSrv_Open: Problem getting protocol level of Server!\n"); return False; } - AsynSrv_errcode = AsynSrv_errno = AsynSrv_vaxc_errno = 0; - AsynSrv_call_depth = 0; + /*---------------------------------------------- + ** Select message for server according to value of state. + */ + if (state) { + strcpy (cmnd, "-002"); + }else { + strcpy (cmnd, "-003"); + } + + status = send (asyn_info->skt, cmnd, 4, 0); /* Send the request */ + if (status != 4) { + GetErrno (&AsynSrv_errno, &AsynSrv_vaxc_errno); + if (status == 0) { + AsynSrv_errcode = ASYNSRV__BAD_SEND; /* Server exited (probably) */ + fprintf (stderr, "\nAsynSrv_Trace/send: probable network problem"); + }else if (status == -1) { + if (AsynSrv_errno == EPIPE) { + AsynSrv_errcode = ASYNSRV__BAD_SEND_PIPE; /* Server exited (probably) */ + fprintf (stderr, "\nAsynSrv_Trace/send: broken network pipe"); + }else { + AsynSrv_errcode = ASYNSRV__BAD_SEND_NET; /* It's some other net problem */ + perror ("AsynSrv_Trace/send"); + } + }else { + AsynSrv_errcode = ASYNSRV__BAD_SEND_UNKN; /* TCP/IP problems */ + fprintf (stderr, "\nAsynSrv_Trace/send: probable TCP/IP problem"); + } + AsynSrv_Close (asyn_info, True); /* Force close TCP/IP connection */ + fprintf (stderr, " - link to server force-closed.\n"); + return False; + } + + status = recv (asyn_info->skt, rply, 4, 0); + if (status != 4) { + GetErrno (&AsynSrv_errno, &AsynSrv_vaxc_errno); + if (status == 0) { + AsynSrv_errcode = ASYNSRV__BAD_RECV; /* Server exited (probably) */ + fprintf (stderr, "\nAsynSrv_Trace/recv: probable network problem"); + }else if (status == -1) { + if (AsynSrv_errno == EPIPE) { + AsynSrv_errcode = ASYNSRV__BAD_RECV_PIPE; /* Server exited (probably) */ + fprintf (stderr, "\nAsynSrv_Trace/recv: broken network pipe"); + }else { + AsynSrv_errcode = ASYNSRV__BAD_RECV_NET; /* It's some other net problem */ + perror ("AsynSrv_Trace/recv"); + } + }else { + AsynSrv_errcode = ASYNSRV__BAD_RECV_UNKN; /* TCP/IP problems */ + fprintf (stderr, "\nAsynSrv_Trace/recv: probable TCP/IP problem"); + } + AsynSrv_Close (asyn_info, True); /* Force close TCP/IP connection */ + fprintf (stderr, " - link to server force-closed.\n"); + return False; + } + if (memcmp (cmnd, rply, 4) != 0) { + AsynSrv_errcode = ASYNSRV__BAD_NOT_BCD; /* Message not echoed OK */ + AsynSrv_Close (asyn_info, True); /* Force close TCP/IP connection */ + fprintf (stderr, "\nAsynSrv_Trace/recv: command not echoed correctly" + " - link to server force-closed.\n"); + return False; + } + if (AsynSrv_errcode == 0) AsynSrv_call_depth--; return True; } /*-------------------------------------------- End of AsynSrv_Utility.C -----*/