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