
- Refactored site specific stuff into a site module - PSI specific stuff is now in the PSI directory. - The old version has been tagged with pre-ansto
862 lines
28 KiB
C
Executable File
862 lines
28 KiB
C
Executable File
#define ident "1A09"
|
||
|
||
#ifdef __DECC
|
||
#pragma module asynsrv_test ident
|
||
#endif
|
||
/*
|
||
** +--------------------------------------------------------------+
|
||
** | Paul Scherrer Institute |
|
||
** | SINQ Project |
|
||
** | |
|
||
** | This software may be used freely by non-profit organizations.|
|
||
** | It may be copied provided that the name of P.S.I. and of the |
|
||
** | author is included. Neither P.S.I. nor the author assume any |
|
||
** | responsibility for the use of this software outside of P.S.I.|
|
||
** +--------------------------------------------------------------+
|
||
**
|
||
** Link_options - Here is the Linker Option File
|
||
**!$ if p1 .eqs. "DEBUG" then dbg1 := /debug
|
||
**!$ if p1 .eqs. "DEBUG" then dbg2 := _dbg
|
||
**!$ link 'dbg1'/exe=asynsrv_test'dbg2'.exe sys$input/options
|
||
**! asynsrv_test
|
||
**! sinq_olb/lib
|
||
**! sys$share:decw$xmlibshr12/share
|
||
**! sys$share:decw$xtlibshrr5/share
|
||
**! sys$share:decw$xlibshr/share
|
||
**!$ purge/nolog asynsrv_test'dbg2'.exe
|
||
**!$ write sys$output "Exec file is asynsrv_test''DBG2'.exe
|
||
**!$ exit
|
||
**!!
|
||
**!! To build on LNSA01 ...
|
||
**!! $ build_cc_select :== decc
|
||
**!! $ import tasmad
|
||
**!! $ define/job deltat_c_tlb sinq_c_tlb
|
||
**!! $ set default ud0:[maden.scratch]
|
||
**!! $ bui tasmad_disk:[mad.tests]asynsrv_test debug
|
||
**!!
|
||
** Link_options_end
|
||
**
|
||
** Building on Alpha Digital Unix:
|
||
**
|
||
** setenv TAS_BASE ~maden/tasmad
|
||
** source $TAS_BASE/tasmad.setup
|
||
** rcp -p "lnsa09:tas_src:[utils]asynsrv_test.c" \
|
||
** $TAS_SRC/utils/asynsrv_test.c
|
||
** cc -std -g -o $TAS_BIN/asynsrv_test \
|
||
** -I$TAS_INC \
|
||
** $TAS_SRC/utils/asynsrv_test.c \
|
||
** -L$TAS_LIB -lsinq -lXm -lXt -lX11
|
||
**
|
||
** Resources and Flags File: decw$user_defaults:SinQ_rc.dat
|
||
** ------------------- or $HOME/SinQ_rc
|
||
**
|
||
** Resource Flag Default Description
|
||
** -------- ---- ------- -----------
|
||
** - -name asynsrv_test Name to use when looking up the
|
||
** resources. The default is the
|
||
** image file name.
|
||
** *AsynSrvHelp -help - Generates help info.
|
||
** *AsynSrvHost -host none The name of the host to which the
|
||
** program wishes to connect.
|
||
** *AsynSrvPort -port 4000 The TCP/IP port of the RS232C server.
|
||
** *AsynSrvChan -chan none The number of the RS232C channel to
|
||
** which the device is attached.
|
||
** *AsynSrvTmo -tmo 2 Time-out in secs for responses to
|
||
** *AsynSrvTmoConn -tmoC 5 Time-out in secs for connect.
|
||
** commands.
|
||
** *AsynSrvDebug -debug If specified, selects debug mode (not
|
||
** yet implemented).
|
||
** *AsynSrvLower -lc - If specified, causes conversion of
|
||
** input to lowercase before sending.
|
||
** *AsynSrvUpper -uc - If specified, causes conversion of
|
||
** input to uppercase before sending.
|
||
** This is the default.
|
||
** *AsynSrvNoCase -ncc - If specified, causes no case
|
||
** conversion of input before sending.
|
||
** *AsynSrvTermOut -termout "\r" Specifies a string to be appended to
|
||
** anything sent to the server.
|
||
** *AsynSrvTermIn -termin "\r" Specifies a string of up to 3 chars
|
||
** which will be recognised as
|
||
** input response terminators.
|
||
** A value given via -name will be converted to lowercase before being used.
|
||
**+
|
||
**---------------------------------------------------------------------------
|
||
** Module Name . . . . . . . . : [...tests]asynsrv_test.c
|
||
**
|
||
** Author . . . . . . . . . . : D. Maden
|
||
** Date of creation . . . . . . : Jan 1997
|
||
**
|
||
** Purpose
|
||
** =======
|
||
** asynsrv_test is a TCP/IP server client which should make a TCP/IP
|
||
** connection to an RS-232-C server and allow the user to transmit
|
||
** commands from the keyboard to a device attached to an RS-232-C channel
|
||
** on the server.
|
||
** Use:
|
||
** ===
|
||
** 1) Set up the host name, TCP/IP port number and RS-232-C channel of the
|
||
** device in the resources file (see above). These can also
|
||
** be supplied as options on the command line.
|
||
**
|
||
** 2) Run the program
|
||
**
|
||
** $ run cpt:[exe]asynsrv_test
|
||
**
|
||
** or, to specify options on the command line, use a DCL foreign
|
||
** command:
|
||
**
|
||
** $ asynsrv_test :== $cpt:[exe]asynsrv_test
|
||
** $ asynsrv_test -host <host> -port <port-number> -chan <chan>
|
||
**
|
||
** Updates:
|
||
** 1A01 20-Jan-1997 DM. Initial version.
|
||
** 1A07 3-Apr-2000 DM. Add fortify.h
|
||
**-
|
||
**====================================================================
|
||
*/
|
||
#include <stdlib.h>
|
||
#include <stdio.h>
|
||
#include <signal.h>
|
||
#include <ctype.h>
|
||
|
||
#include <time.h>
|
||
|
||
#ifdef __VMS
|
||
#include <sys/unixio.h>
|
||
#else
|
||
#include <unistd.h>
|
||
#ifdef FORTIFY
|
||
#include <fortify/fortify.h>
|
||
#endif
|
||
#endif
|
||
|
||
#include <X11/Intrinsic.h>
|
||
/*
|
||
**====================================================================
|
||
*/
|
||
#include <sinq_prototypes.h>
|
||
#include <asynsrv_def.h>
|
||
#include <rs232c_def.h>
|
||
/*
|
||
|
||
**--------------------------------------------------------------------------
|
||
** Define global structures and constants.
|
||
*/
|
||
/*-------------------------------------------------------------
|
||
** Global Variables
|
||
*/
|
||
static int C_gbl_status; /* Return status from C_... routines */
|
||
static int Ctrl_C_has_happened;
|
||
void *Hndl = NULL;
|
||
|
||
static XrmOptionDescRec OpTable[] = {
|
||
{"-name", ".name", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-help", ".AsynSrvHelp", XrmoptionNoArg, (XPointer) "1"},
|
||
{"-host", ".AsynSrvHost", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-port", ".AsynSrvPort", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-chan", ".AsynSrvChan", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-tmoC", ".AsynSrvTmoConn", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-tmoc", ".AsynSrvTmoConn", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-tmo", ".AsynSrvTmo", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-debug", ".AsynSrvDebug", XrmoptionNoArg, (XPointer) "1"},
|
||
{"-lc", ".AsynSrvLower", XrmoptionNoArg, (XPointer) "1"},
|
||
{"-uc", ".AsynSrvUpper", XrmoptionNoArg, (XPointer) "1"},
|
||
{"-ncc", ".AsynSrvNoCase", XrmoptionNoArg, (XPointer) "1"},
|
||
{"-termout", ".AsynSrvTermOut", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-termin", ".AsynSrvTermIn", XrmoptionSepArg, (XPointer) NULL},
|
||
};
|
||
struct AsynSrv__info AsynSrv_info;
|
||
int Debug;
|
||
float TmoC;
|
||
float Tmo;
|
||
int DoLower, DoUpper;
|
||
char TermOut[16];
|
||
char TermIn[16];
|
||
int Do_help;
|
||
|
||
char *Errstack;
|
||
int Errcode, Errno, Vaxc_errno;
|
||
/*
|
||
**--------------------------------------------------------------------------
|
||
** PrintErrInfo: print out error information.
|
||
*/
|
||
void PrintErrInfo (char *text) {
|
||
/* ============
|
||
*/
|
||
|
||
AsynSrv_ErrInfo (&Errstack, &Errcode, &Errno, &Vaxc_errno);
|
||
fprintf (stderr, "\n"
|
||
" Error return from %s.\n"
|
||
" Errstack = \"%s\".\n"
|
||
" Errcode = %d. Errno = %d. Vaxc$errno = %d.\n",
|
||
text, Errstack, Errcode, Errno, Vaxc_errno);
|
||
switch (Errcode) {
|
||
case ASYNSRV__BAD_BIND:
|
||
fprintf (stderr, "ASYNSRV__BAD_BIND\n");
|
||
break;
|
||
case ASYNSRV__BAD_CONNECT:
|
||
fprintf (stderr, "ASYNSRV__BAD_CONNECT\n");
|
||
break;
|
||
case ASYNSRV__BAD_HOST:
|
||
fprintf (stderr, "ASYNSRV__BAD_HOST\n");
|
||
break;
|
||
case ASYNSRV__BAD_PAR:
|
||
fprintf (stderr, "ASYNSRV__BAD_PAR\n");
|
||
break;
|
||
case ASYNSRV__BAD_SOCKET:
|
||
fprintf (stderr, "ASYNSRV__BAD_SOCKET\n");
|
||
break;
|
||
case ASYNSRV__NO_ROOM:
|
||
fprintf (stderr, "ASYNSRV__NO_ROOM\n");
|
||
break;
|
||
default:
|
||
fprintf (stderr, "Unrecognised error code!\n");
|
||
if ((Errno != 0) || (Vaxc_errno != 0)) perror (text);
|
||
}
|
||
return;
|
||
}
|
||
/*
|
||
**--------------------------------------------------------------------------
|
||
** ShowUsage: A simple print-out routine.
|
||
*/
|
||
void ShowUsage (int full) {
|
||
/* =========
|
||
*/
|
||
if (!full) {
|
||
if (Do_help) return;
|
||
printf ("\n"
|
||
"To get help on running the program issue the command:\n"
|
||
"\n"
|
||
" asynsrv_test -help\n"
|
||
"\n");
|
||
return;
|
||
}
|
||
printf ("\n"
|
||
"Usage: asynsrv_test [options ...]\n"
|
||
" \n"
|
||
" Valid options are: Equivalent resource name:\n"
|
||
" -help *AsynSrvHelp\n"
|
||
" -host <host-name> *AsynSrvHost\n"
|
||
" -port <port-number> *AsynSrvPort Dflt=4000\n"
|
||
" -chan <channel-number> *AsynSrvChan\n"
|
||
" -debug *AsynSrvDebug\n"
|
||
" -tmo <secs> *AsynSrvTmo Dflt=2\n"
|
||
" -tmoC <secs> *AsynSrvTmoConn Dflt=5\n"
|
||
" -lc *AsynSrvLower\n"
|
||
" -uc *AsynSrvUpper\n"
|
||
" -ncc *AsynSrvNoCase\n"
|
||
" -termout <term-out-string> *AsynSrvTermOut Dflt=\"\\r\"\n"
|
||
" -termin <term-in-string> *AsynSrvTermIn Dflt=\"\\r\"\n"
|
||
" -termin\n"
|
||
"\n"
|
||
" No default is allowed for -host or -chan,"
|
||
" i.e. values for\n"
|
||
" these parameters must be supplied either via a resource file or"
|
||
" on the\n"
|
||
" command line.\n"
|
||
"\n"
|
||
" -tmo is the time-out for responses to commands.\n"
|
||
" -tmoC is the time-out for the initial connection to the server.\n"
|
||
"\n"
|
||
"To quit the program, issue the command \"#q\".\n"
|
||
"To send a null command, issue the command \"\\0\".\n"
|
||
"Other special commands are:\n"
|
||
" #help\n"
|
||
" #close - gets SerPortServer to close its serial ports.\n"
|
||
" #flush - gets SerPortServer to flush its output.\n"
|
||
" #trace off - turn off SerPortServer tracing.\n"
|
||
" #trace on - turn on SerPortServer tracing.\n"
|
||
" #trace write - gets SerPortServer to write its trace buffer.\n"
|
||
"To send a command starting with \"#\", start it with \"##\".\n"
|
||
"\n");
|
||
return;
|
||
}
|
||
/*
|
||
**--------------------------------------------------------------------------
|
||
** DoInteract: Interact with the RS-232-C Device
|
||
*/
|
||
int DoInteract () {
|
||
/* ==========
|
||
*/
|
||
int status, go_on, no_errors, no_restore, i, j, len, act_len, tok_len;
|
||
|
||
FILE *lun;
|
||
char recd[132], buff[132], cmnd[132], cmnd_prnt[512];
|
||
char eot_save[4], tmo_save[4], term;
|
||
char *rptr, *tok;
|
||
|
||
struct RS__MsgStruct send_buff;
|
||
struct RS__RespStruct rcve_buff;
|
||
|
||
lun = stdin; /* Use standard input */
|
||
|
||
go_on = True;
|
||
no_errors = True;
|
||
|
||
if (lun == stdin) {
|
||
printf ("Issue the command \"#h\" for help and \"#q\" to quit.\n> ");
|
||
fflush (NULL);
|
||
}
|
||
while (go_on && (fgets (recd, sizeof (recd), lun) != NULL)) {
|
||
len = strlen (recd);
|
||
if (len <= 1) {
|
||
if (lun == stdin) {printf ("> "); fflush (NULL);}
|
||
continue;
|
||
}
|
||
if (recd[len-1] != '\n') {
|
||
recd[20] = '\0';
|
||
printf (" Record not terminated by \"\\n\". "
|
||
"It is probably too long!\n"
|
||
" The record starts thus: %s ...\n"
|
||
" It has been skipped.\n", recd);
|
||
if (lun == stdin) {printf ("> "); fflush (NULL);}
|
||
continue;
|
||
}
|
||
recd[len-1] = '\0'; /* Remove the terminating "\n" */
|
||
/*
|
||
** Strip off any trailing stuff (but keep it around so that we
|
||
** can print it out). "Trailing stuff" is anything after a "!".
|
||
*/
|
||
act_len = strcspn (recd, "!");
|
||
len = sizeof (buff);
|
||
if (DoLower) {
|
||
StrEdit (buff, recd, "trim uncomment lowercase", &len);
|
||
}else if (DoUpper) {
|
||
StrEdit (buff, recd, "trim uncomment upcase", &len);
|
||
}else {
|
||
StrEdit (buff, recd, "trim uncomment", &len);
|
||
}
|
||
|
||
len = sizeof (cmnd);
|
||
StrEdit (cmnd, buff, "lowercase", &len);
|
||
|
||
if (strncmp (buff, "##", 2) == 0) { /* "##" at start gets compressed
|
||
** to "#" */
|
||
len = sizeof (buff);
|
||
StrEdit (buff, &buff[1], "trim", &len);
|
||
}
|
||
|
||
tok = strtok (cmnd, " ");
|
||
tok_len = (tok != NULL) ? strlen (tok) : 0;
|
||
if ((tok_len >= 2) &&
|
||
(strncmp (tok, "#exit", tok_len) == 0)) {
|
||
go_on = False;
|
||
}else if ((tok_len >= 2) &&
|
||
(strncmp (tok, "#quit", tok_len) == 0)) {
|
||
go_on = False;
|
||
}else if ((tok_len >= 2) &&
|
||
(strncmp (tok, "#trace", tok_len) == 0)) {
|
||
tok = strtok (NULL, " ");
|
||
tok_len = (tok != NULL) ? strlen (tok) : 0;
|
||
if ((tok_len >= 2) &&
|
||
(strncmp (tok, "on", tok_len) == 0)) {
|
||
printf ("Requesting server to turn tracing on ..."); fflush (NULL);
|
||
status = AsynSrv_Trace (&AsynSrv_info, True);
|
||
if (status) {
|
||
printf (" done.\n");
|
||
}else {
|
||
printf ("\nError detected!\n");
|
||
}
|
||
}else if ((tok_len >= 2) &&
|
||
(strncmp (tok, "off", tok_len) == 0)) {
|
||
printf ("Requesting server to turn tracing off ..."); fflush (NULL);
|
||
status = AsynSrv_Trace (&AsynSrv_info, False);
|
||
if (status) {
|
||
printf (" done.\n");
|
||
}else {
|
||
printf ("\nError detected!\n");
|
||
}
|
||
}else if ((tok_len >= 1) &&
|
||
(strncmp (tok, "write", tok_len) == 0)) {
|
||
printf ("Requesting server to write trace ..."); fflush (NULL);
|
||
status = AsynSrv_Trace_Write (&AsynSrv_info);
|
||
if (status) {
|
||
printf (" done.\n");
|
||
}else {
|
||
printf ("\nError detected!\n");
|
||
}
|
||
}else {
|
||
printf ("Illegal \"#trace\" command! You must "
|
||
"specify \"on\" or \"off\" or \"write\".\n");
|
||
}
|
||
}else if ((tok_len >= 2) &&
|
||
(strncmp (tok, "#flush", tok_len) == 0)) {
|
||
printf ("Requesting server to flush ..."); fflush (NULL);
|
||
status = AsynSrv_Flush (&AsynSrv_info);
|
||
if (status) {
|
||
printf (" done.\n");
|
||
}else {
|
||
printf ("\nError detected!\n");
|
||
}
|
||
}else if ((tok_len >= 2) &&
|
||
(strncmp (tok, "#close", tok_len) == 0)) {
|
||
printf ("Requesting server to close its serial channels ..."); fflush (NULL);
|
||
status = AsynSrv_ChanClose (&AsynSrv_info);
|
||
if (status) {
|
||
printf (" done.\n");
|
||
}else {
|
||
printf ("\nError detected!\n");
|
||
}
|
||
}else if ((tok_len >= 2) &&
|
||
(strncmp (tok, "#help", tok_len) == 0)) {
|
||
ShowUsage (True);
|
||
}else if ((cmnd[0] == '#') && (cmnd[1] != '#')) {
|
||
printf ("Illegal command! If you really want to start a command\n"
|
||
" with a \"#\" character, you should use\n"
|
||
" \"##\" instead!\n");
|
||
}else {
|
||
if (strlen (buff) > 0) {
|
||
StrJoin (buff, sizeof (buff), buff, TermOut); /* Append terminator */
|
||
}
|
||
/*
|
||
** Show user what's getting sent
|
||
*/
|
||
MakePrintable (cmnd_prnt, sizeof (cmnd_prnt), buff);
|
||
printf ("Sending \"%s\" ... ", cmnd_prnt); fflush (NULL);
|
||
|
||
status = AsynSrv_SendCmnds (&AsynSrv_info, &send_buff, &rcve_buff,
|
||
buff, NULL);
|
||
if (!status) {
|
||
go_on = no_errors = False;
|
||
continue;
|
||
}else {
|
||
rptr = AsynSrv_GetReply (&AsynSrv_info, &rcve_buff, NULL);
|
||
if (rptr == NULL) {
|
||
printf ("No response from server!\n");
|
||
go_on = no_errors = False;
|
||
continue;
|
||
}else {
|
||
AsynSrv_GetLenTerm (&AsynSrv_info, &rcve_buff, rptr, &len, &term);
|
||
MakeMemPrintable (cmnd_prnt, sizeof (cmnd_prnt), rptr, len);
|
||
MakeMemPrintable (recd, sizeof (recd), &term, 1);
|
||
j = strlen (cmnd_prnt);
|
||
printf ("\nResponse length = %d. Terminator = \"%s\".\n", len, recd);
|
||
for (i = 0; i < (j/70); i++)
|
||
printf (" \"%.70s\"\\...\n", &cmnd_prnt[i*70]);
|
||
printf (" \"%s\"\n", &cmnd_prnt[i*70]);
|
||
}
|
||
}
|
||
}
|
||
if (lun == stdin) {printf ("> "); fflush (NULL);}
|
||
}
|
||
|
||
if (no_errors) {
|
||
printf ("\"Interaction\" completed.\n");
|
||
}else {
|
||
printf ("Interaction failed.\n");
|
||
}
|
||
return no_errors;
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** SetupXrmDatabase - setup Resource Manager Database
|
||
*/
|
||
int SetupXrmDatabase (
|
||
/* ================
|
||
*/ XrmDatabase *db,
|
||
char *name[],
|
||
int *argc,
|
||
char *argv[]) {
|
||
|
||
static char our_name[80] = "Unknown"; /* This holds the program name */
|
||
static char lkup_name[80] = "Unknown"; /* Name for looking in database */
|
||
|
||
int status, i, first = True;
|
||
char text[80];
|
||
char full_nm0[80];
|
||
char full_nm1[80];
|
||
char *p_fil[] = {0,0,0,0,0,0,0,0,0,0};
|
||
char *my_name;
|
||
char *my_name_last;
|
||
|
||
char *name_type;
|
||
XrmValue name_value;
|
||
|
||
XrmDatabase cmnd_line_db = NULL;
|
||
XrmDatabase lcl_db = NULL;
|
||
/*-----------------------------------------------------
|
||
** This routine merges some resource databases with options specified on
|
||
** the command line. Resources can then be looked up using XrmGetResource.
|
||
** This is a bit like the X-toolkit routine XtAppInitialize does for the
|
||
** extraction of resources by XtGetApplicationResources.
|
||
**
|
||
** I can't help but think that there's a simpler way of doing this but I
|
||
** can't find it in the X manuals. Basically, the problem arises with wanting
|
||
** to avoid the calling program being associated with an X-display, i.e. it
|
||
** is intended for use by "command-line oriented" programs. All the nice,
|
||
** easy-to-use resource/command-line setup routines in Xlib or Xtlib seem to
|
||
** assume one is going to use a display -- not surprising, I suppose,
|
||
** since the concept of Xlib is for writing window based applications!
|
||
**
|
||
** Anyway, the point is that the following way turn out to be lacking
|
||
** when it gets tested in anger.
|
||
*/
|
||
status = True; /* Assume success */
|
||
|
||
our_name[0] = '\0';
|
||
/*
|
||
** Make a list of the databases to be merged, highest priority first.
|
||
*/
|
||
#ifdef __VMS
|
||
p_fil[0] = "decw$user_defaults:SinQ_rc.dat";
|
||
p_fil[1] = "decw$group_defaults:SinQ_rc.dat";
|
||
p_fil[2] = "decw$system_defaults:SinQ_rc.dat";
|
||
p_fil[3] = "decw$user_defaults:decw$xdefaults.dat";
|
||
p_fil[4] = "decw$group_defaults:decw$xdefaults.dat";
|
||
p_fil[5] = "decw$system_defaults:decw$xdefaults.dat";
|
||
p_fil[6] = NULL;
|
||
if (*argc > 0) { /* Find out what we are called - parse file nm */
|
||
my_name = strstr (argv[0], "]"); /* Find end of directory, i.e. "]" */
|
||
my_name++; /* Skip over "]" */
|
||
if (my_name[0] == '[') { /* Handle possible concealed device */
|
||
my_name = strstr (my_name, "]");
|
||
my_name++;
|
||
}
|
||
i = sizeof (our_name);
|
||
StrEdit (our_name, my_name, "lowercase", &i); /* Copy the rest */
|
||
strtok (our_name, "."); /* Close it off at "." */
|
||
}
|
||
#else
|
||
p_fil[0] = StrJoin (full_nm0, sizeof (full_nm0),
|
||
getenv ("HOME"), "/SinQ_rc");
|
||
p_fil[1] = "/usr/lib/X11/app-defaults/SinQ_rc";
|
||
p_fil[2] = StrJoin (full_nm1, sizeof (full_nm1),
|
||
getenv ("HOME"), "/.Xdefaults");
|
||
p_fil[3] = "/usr/lib/X11/app-defaults/Xdefaults";
|
||
p_fil[4] = NULL;
|
||
if (*argc > 0) { /* Find out what we are called - parse file nm */
|
||
/* Find end of directories */
|
||
my_name = argv[0] - 1;
|
||
while (my_name != NULL) {
|
||
my_name_last = my_name;
|
||
my_name_last++;
|
||
my_name = strstr (my_name_last, "/");
|
||
}
|
||
StrJoin (our_name, sizeof (our_name), my_name_last, "");
|
||
}
|
||
#endif
|
||
printf ("My name is \"%s\"\n", our_name);
|
||
/*
|
||
** Initialise and combine all databases
|
||
*/
|
||
XrmInitialize ();
|
||
for (i = 0; i < XtNumber (p_fil); i++) {
|
||
if (p_fil[i] == NULL) break;
|
||
status = XrmCombineFileDatabase (p_fil[i], &lcl_db, False);
|
||
if (status != 0) {
|
||
if (first) {
|
||
printf ("Resource database created from file %s.\n", p_fil[i]);
|
||
}else {
|
||
printf ("File %s merged into resource database.\n", p_fil[i]);
|
||
}
|
||
first = False;
|
||
}
|
||
}
|
||
/*
|
||
** See if there's anything specified on cmnd line, incl "name".
|
||
*/
|
||
XrmParseCommand (&cmnd_line_db,
|
||
OpTable, XtNumber(OpTable), our_name, argc, argv);
|
||
if (cmnd_line_db != NULL) {
|
||
/*
|
||
** There was at least 1 item on cmnd line. Process the line.
|
||
** If -name was specified, adopt it.
|
||
*/
|
||
status = XrmGetResource (cmnd_line_db, /* See if a name was specified */
|
||
StrJoin (text, sizeof (text), our_name, ".name"),
|
||
"ProgramName.Values",
|
||
&name_type, &name_value);
|
||
if (status) {
|
||
i = sizeof (lkup_name);
|
||
StrEdit (lkup_name, name_value.addr, "lowercase", &i);
|
||
printf ("Option list name is \"%s\"\n", lkup_name);
|
||
}else {
|
||
strcpy (lkup_name, our_name);
|
||
}
|
||
/*
|
||
** Loop over all items in OpTable and merge them into database,
|
||
** taking care of any possible name changes.
|
||
*/
|
||
for (i = 0; i < XtNumber (OpTable); i++) {
|
||
if (strcmp (OpTable[i].option, "-name") == 0) continue;
|
||
status = XrmGetResource (cmnd_line_db,
|
||
StrJoin (text, sizeof (text),
|
||
our_name, OpTable[i].specifier),
|
||
"ProgramName.Values",
|
||
&name_type, &name_value);
|
||
if (status) {
|
||
StrJoin (text, sizeof (text), lkup_name, OpTable[i].specifier);
|
||
XrmPutResource (&lcl_db, text, "String", &name_value);
|
||
}
|
||
}
|
||
}
|
||
*name = lkup_name;
|
||
*db = lcl_db;
|
||
if (lcl_db == NULL) printf ("Warning -- no resource database found.\n");
|
||
|
||
XrmDestroyDatabase (cmnd_line_db);
|
||
/*
|
||
** XrmPutFileDatabase (lcl_db, "asynsrv_test.db");
|
||
*/
|
||
return status;
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** GetCheckResources - get and check our resources
|
||
*/
|
||
int GetCheckResources (
|
||
/* =================
|
||
*/ XrmDatabase *db,
|
||
char *appName) {
|
||
|
||
int i, status;
|
||
char buff[80];
|
||
char *type;
|
||
XrmValue value;
|
||
time_t time_now;
|
||
float tmp_secs;
|
||
|
||
status = XrmGetResource (*db,
|
||
StrJoin (buff, sizeof (buff),
|
||
appName, ".AsynSrvHelp"),
|
||
"ProgramName.Values",
|
||
&type, &value);
|
||
Do_help = (status) ? True : False;
|
||
if (Do_help) {
|
||
ShowUsage (True);
|
||
exit (EXIT_SUCCESS);
|
||
}
|
||
|
||
status = XrmGetResource (*db,
|
||
StrJoin (buff, sizeof (buff),
|
||
appName, ".AsynSrvDebug"),
|
||
"ProgramName.Values",
|
||
&type, &value);
|
||
Debug = (status) ? True : False;
|
||
|
||
status = XrmGetResource (*db,
|
||
StrJoin (buff, sizeof (buff),
|
||
appName, ".AsynSrvNoCase"),
|
||
"ProgramName.Values",
|
||
&type, &value);
|
||
if (status) {
|
||
DoLower = False; DoUpper = False;
|
||
}else {
|
||
DoLower = False; DoUpper = True;
|
||
}
|
||
|
||
status = XrmGetResource (*db,
|
||
StrJoin (buff, sizeof (buff),
|
||
appName, ".AsynSrvLower"),
|
||
"ProgramName.Values",
|
||
&type, &value);
|
||
if (status) DoLower = True;
|
||
if (DoLower) DoUpper = False;
|
||
|
||
status = XrmGetResource (*db,
|
||
StrJoin (buff, sizeof (buff),
|
||
appName, ".AsynSrvUpper"),
|
||
"ProgramName.Values",
|
||
&type, &value);
|
||
if (status) DoUpper = True;
|
||
if (DoUpper) DoLower = False;
|
||
|
||
status = XrmGetResource (*db,
|
||
StrJoin (buff, sizeof (buff),
|
||
appName, ".AsynSrvHost"),
|
||
"ProgramName.Values",
|
||
&type, &value);
|
||
if (!status) {
|
||
printf ("No server specified via the -host option. "
|
||
"No default allowed!\n");
|
||
ShowUsage (False);
|
||
return False;
|
||
}else {
|
||
StrJoin (AsynSrv_info.host, sizeof (AsynSrv_info.host), value.addr, "");
|
||
printf ("Using Internet host \"%s\".\n", AsynSrv_info.host);
|
||
}
|
||
|
||
status = XrmGetResource (*db,
|
||
StrJoin (buff, sizeof (buff),
|
||
appName, ".AsynSrvPort"),
|
||
"ProgramName.Values",
|
||
&type, &value);
|
||
if (!status || (sscanf (value.addr, "%d", &AsynSrv_info.port) != 1)) {
|
||
AsynSrv_info.port = 4000;
|
||
printf ("Using the default TCP/IP port number of %d.\n",
|
||
AsynSrv_info.port);
|
||
}else {
|
||
printf ("TCP/IP port number = %d\n", AsynSrv_info.port);
|
||
}
|
||
|
||
status = XrmGetResource (*db,
|
||
StrJoin (buff, sizeof (buff),
|
||
appName, ".AsynSrvChan"),
|
||
"ProgramName.Values",
|
||
&type, &value);
|
||
if (!status || (sscanf (value.addr, "%d", &AsynSrv_info.chan) != 1)) {
|
||
printf ("No RS-232-C channel specified via the -chan option. "
|
||
"No default allowed!\n");
|
||
ShowUsage (False);
|
||
return False;
|
||
}else {
|
||
printf ("RS-232-C channel number = %d\n", AsynSrv_info.chan);
|
||
}
|
||
|
||
status = XrmGetResource (*db,
|
||
StrJoin (buff, sizeof (buff),
|
||
appName, ".AsynSrvTmo"),
|
||
"ProgramName.Values",
|
||
&type, &value);
|
||
if (!status || (sscanf (value.addr, "%f", &Tmo) != 1)) {
|
||
Tmo = 2.0;
|
||
}else {
|
||
printf ("Response time-out = %d msec.\n", (int) ((Tmo + 0.0001) * 1000));
|
||
}
|
||
|
||
status = XrmGetResource (*db,
|
||
StrJoin (buff, sizeof (buff),
|
||
appName, ".AsynSrvTmoConn"),
|
||
"ProgramName.Values",
|
||
&type, &value);
|
||
if (!status || (sscanf (value.addr, "%f", &TmoC) != 1)) {
|
||
TmoC = 5.0;
|
||
}else {
|
||
printf ("Connection time-out = %d secs.\n", (int) (TmoC + 0.0001));
|
||
}
|
||
|
||
status = XrmGetResource (*db,
|
||
StrJoin (buff, sizeof (buff),
|
||
appName, ".AsynSrvTermOut"),
|
||
"ProgramName.Values",
|
||
&type, &value);
|
||
if (!status) {
|
||
printf ("Output terminator is \"\\r\"\n");
|
||
strcpy (TermOut, "\r");
|
||
}else {
|
||
printf ("Output terminator is \"%s\"\n", value.addr);
|
||
i = sizeof (TermOut);
|
||
if (StrEdit (TermOut, value.addr, "trim", &i) == NULL) {
|
||
printf ("Bad output terminator!\n");
|
||
ShowUsage (False);
|
||
return False;
|
||
}
|
||
}
|
||
|
||
status = XrmGetResource (*db,
|
||
StrJoin (buff, sizeof (buff),
|
||
appName, ".AsynSrvTermIn"),
|
||
"ProgramName.Values",
|
||
&type, &value);
|
||
if (!status) {
|
||
printf ("Input terminator is \"\\r\"\n");
|
||
memcpy (TermIn, "1\r\0\0", 4);
|
||
}else {
|
||
printf ("Input terminator is \"%s\"\n", value.addr);
|
||
i = sizeof (TermIn) - 1;
|
||
if (StrEdit (&TermIn[1], value.addr, "trim", &i) == NULL) {
|
||
printf ("Bad input terminator!\n");
|
||
ShowUsage (False);
|
||
return False;
|
||
}
|
||
switch (strlen (&TermIn[1])) {
|
||
case 0: strcpy (TermIn, "0\0\0\0"); break;
|
||
case 1: TermIn[0] = '1'; TermIn[2] = TermIn[3] = '\0'; break;
|
||
case 2: TermIn[0] = '2'; TermIn[3] = '\0'; break;
|
||
case 3: TermIn[0] = '3'; break;
|
||
default:
|
||
printf ("Input terminator string is too long!\n");
|
||
return False;
|
||
}
|
||
}
|
||
return True;
|
||
}
|
||
/*
|
||
**--------------------------------------------------------------------------
|
||
** CtrlC_Handler: Signal handler to detect <Ctrl-C> on keyboard.
|
||
*/
|
||
void CtrlC_Handler (int sigint) {
|
||
/* =============
|
||
*/
|
||
Ctrl_C_has_happened = True;
|
||
}
|
||
/*
|
||
**==========================================================================
|
||
** Main line program
|
||
** ------------------
|
||
*/
|
||
int main (int argc, char **argv) {
|
||
/* ============================
|
||
*/
|
||
char buff[80], text0[80], text1[80];
|
||
int buff_len;
|
||
int status, errcode, errno, vaxc_errno, i;
|
||
char *errName;
|
||
time_t time_now;
|
||
int sec_tmoC, msec_tmo;
|
||
|
||
XrmDatabase my_db;
|
||
char *appName;
|
||
/*-----------------------------------------------------------------------*/
|
||
time_now = time (NULL);
|
||
printf ("RS-232-C Device Test Program, Ident %s.\n", ident);
|
||
printf ("Started at %s", asctime (localtime (&time_now)));
|
||
/*-------------------------------------------------------------
|
||
** Setup the resource database and look up the resources.
|
||
*/
|
||
SetupXrmDatabase (&my_db, &appName, &argc, argv);
|
||
if (argc > 1) {
|
||
if (argc > 2) {
|
||
printf ("\nThe following arguments were not used:\n\n ");
|
||
for (i = 1; i < argc; i++) {
|
||
printf ("\"%s\" ", argv[i]);
|
||
}
|
||
}else {
|
||
printf ("\nArgument \"%s\" was not used.", argv[1]);
|
||
}
|
||
printf ("\n");
|
||
ShowUsage (False);
|
||
return False;
|
||
}
|
||
status = GetCheckResources (&my_db, appName);
|
||
if (!status) return False;
|
||
/*
|
||
** Declare a signal handler to catch <Ctrl-C> so that we
|
||
** can exit cleanly.
|
||
*/
|
||
Ctrl_C_has_happened = False;
|
||
signal (SIGINT, CtrlC_Handler);
|
||
|
||
sec_tmoC = (int) (TmoC + 0.0001);
|
||
msec_tmo = (int) ((Tmo + 0.0001) * 1000);
|
||
status = AsynSrv_ConfigDflt (
|
||
"tmoC", sec_tmoC, /* Specify the connection time-out */
|
||
"msecTmo", msec_tmo, /* Specify the response time-out */
|
||
"eot", TermIn, /* Specify the terminators */
|
||
NULL);
|
||
if (!status) {
|
||
printf ("Error setting default configuration of server connection.\n");
|
||
PrintErrInfo ("AsynSrv_ConfigDflt");
|
||
return False;
|
||
}
|
||
|
||
status = AsynSrv_Open (&AsynSrv_info);
|
||
if (!status) {
|
||
printf ("Error opening connection to server.\n");
|
||
PrintErrInfo ("AsynSrv_Open");
|
||
return False;
|
||
}else {
|
||
|
||
status = DoInteract ();
|
||
if (!status) {
|
||
PrintErrInfo ("DoInteract");
|
||
AsynSrv_Close (&AsynSrv_info, 0);
|
||
return False;
|
||
}
|
||
|
||
status = AsynSrv_Close (&AsynSrv_info, 0);
|
||
}
|
||
return True;
|
||
}
|
||
/*------------------------------------------------- End of asynsrv_test.c */
|