Files
sicspsi/utils/asynsrv_test.c
cvs 064ec37e9a - Rearranged directory structure for forking out ANSTO
- 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
2003-06-20 10:18:47 +00:00

862 lines
28 KiB
C
Executable File
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 */