diff --git a/utils/asynsrv_test.c b/utils/asynsrv_test.c new file mode 100755 index 00000000..36393a93 --- /dev/null +++ b/utils/asynsrv_test.c @@ -0,0 +1,861 @@ +#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 -port -chan +** +** Updates: +** 1A01 20-Jan-1997 DM. Initial version. +** 1A07 3-Apr-2000 DM. Add fortify.h +**- +**==================================================================== +*/ +#include +#include +#include +#include + +#include + +#ifdef __VMS + #include +#else + #include + #ifdef FORTIFY + #include + #endif +#endif + +#include +/* +**==================================================================== +*/ +#include +#include +#include +/* + +**-------------------------------------------------------------------------- +** 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 *AsynSrvHost\n" + " -port *AsynSrvPort Dflt=4000\n" + " -chan *AsynSrvChan\n" + " -debug *AsynSrvDebug\n" + " -tmo *AsynSrvTmo Dflt=2\n" + " -tmoC *AsynSrvTmoConn Dflt=5\n" + " -lc *AsynSrvLower\n" + " -uc *AsynSrvUpper\n" + " -ncc *AsynSrvNoCase\n" + " -termout *AsynSrvTermOut Dflt=\"\\r\"\n" + " -termin *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 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 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 */