diff --git a/sinqhm/lwl_client.c b/sinqhm/lwl_client.c new file mode 100755 index 00000000..99d699b7 --- /dev/null +++ b/sinqhm/lwl_client.c @@ -0,0 +1,1422 @@ +#define Ident "1B01" +/*---------------------------------------------------------------------------*/ +#ifdef __DECC +#pragma module LWL_CLIENT Ident +#endif +/* +** Link_options - Here is the Linker Option File +**! lwl_client +**! tas_src:[lib]sinq_olb/lib +**! sys$share:decw$xlibshr/share +**!! +**!! To build LWL_CLIENT on LNSA09 +**!! +**!! $ import tasmad +**!! $ define/job deltat_c_tlb sinq_c_tlb +**!! $ sss := tas_src:[sinqhm] +**!! $ bui 'sss'lwl_client debug +** Link_options_end +** +** +--------------------------------------------------------------+ +** | Paul Scherrer Institute | +** | Computing Section | +** | | +** | 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.| +** +--------------------------------------------------------------+ +** +** Module Name . . . . . . . . : [...SINQHM]LWL_CLIENT.C +** +** Author . . . . . . . . . . : D. Maden +** Date of creation . . . . . . : Jan 1997 +** +** LWL_CLIENT is the main program of an Internet Client which transmits +** messages to a LWL_SERVER running on a front-end processor. The server +** writes the data into a LWL Test Generator. +** +** Updates: +** 9-Jan-1997 DM. Initial version. +** 17-Jun-1998 1A05 DM. Set 5 sec time-out on "connect" on VMS systems. +** Add TOF data packet generation. +** 1B01 8-May-2000 DM. Use command line options instead of env variables. +**==================================================================== +*/ + +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include + +#ifdef __VMS +#include +#include +#include +#else +#include +#endif + +#ifdef __VMS +#include +#include +#else +#define SS$_NORMAL EXIT_SUCCESS +#define SS$_BADPARAM EXIT_FAILURE +#define SS$_IVBUFLEN EXIT_FAILURE +#define NO_MEMORY 4 +#endif + +#include +#include +#include +/* +**==================== Global Definitions ===================================== +*/ +#include + +#include "SinqHM_def.h" + +#define DFLT_PORT 3501 +#define NIL '\0' +#define NL '\n' +#define MAXARR 8192 +#define MAXREC 512 +/*------------------------------------------------------------ +** Definitions for the LWL Datagrams +*/ +#define b_LWL_HM_NC 0x10 /* Hist-Mode/No-Coinc Datagram Header */ +#define b_LWL_HM_NC3 0x13 /* Hist-Mode/No-Coinc/3-chan Datagram Header */ +#define b_LWL_HM_C 0x10 /* Hist-Mode+Coinc Datagram Header */ +#define b_LWL_TOF 0x00 /* TOF-Mode Datagram Header */ +#define b_LWL_STR_NC 0x10 /* Strobo-Mode/No-Coinc Datagram Header */ +#define b_LWL_STR_C 0x10 /* Strobo-Mode+Coinc Datagram Header */ + +#define b_LWL_TR_TSI 0x1f /* Transp-Mode Time Status Info */ +#define b_LWL_HM_NC_TSI 0x1f /* Hist-Mode/No-Coinc Time Status Info */ +#define b_LWL_TOF_TSI 0x1f /* TOF-Mode Time Status Info */ +#define b_LWL_STR_NC_TSI 0x1f /* Strobo-Mode/No-Coinc Time Status Info */ + +#define b_LWL_HM_C_TSI 0x0e /* Hist-Mode+Coinc Time Status Info */ +#define b_LWL_STR_C_TSI 0x0e /* Strobo-Mode+Coinc Time Status Info */ +#define b_LWL_TR_ETSI 0x0e /* Transp-Mode Extended Time Status Info */ + +#define b_LWL_FIFO_EMPTY 0x1e /* FIFO Empty */ + +#define b_LWL_HDR_NRL_MASK 0x20 /* Mask for Neutron Rate Low bit */ +#define b_LWL_HDR_BIT8 0x10 /* Pattern for getting Bit-8 set */ +/*------------------------------------------------------------*/ + /* + ** Define the Data Structures we need + */ +/* +**==================== Global Variables ====================================== +*/ + int My_errno, My_vaxc_errno; + + char Rmt_host[32]; + int Rmt_port; + int Pkt_size; + int Verbose; + static int Cnct_skt = 0; /* Connect socket */ + static int Ctrl_C_has_happened; + + static XrmOptionDescRec OptTable[] = { + {"-name", ".name", XrmoptionSepArg, (XPointer) NULL}, + {"-host", ".lwlHost", XrmoptionSepArg, (XPointer) NULL}, + {"-port", ".lwlPort", XrmoptionSepArg, (XPointer) NULL}, + {"-size", ".lwlSize", XrmoptionSepArg, (XPointer) NULL}, + }; +/* +**============================================================================= +** Local routines. +** +** CtrlC_Handler : Catch a Ctrl-C interrupt. +** Do_ETSI : Generate an Extended Time Status Info datagram. +** Do_File : Read and send contents of file to LWL. +** Do_HM : Generate data stream in Histogram Mode. +** Do_HRPT : Generate data stream in HRPT Mode. +** Do_Misc : Generate a miscellaneous datagram. +** Do_TOF : Generate data stream in TOF Mode. +** Do_TS : Generate a Time Status datagram. +** exit_handler : Exit handler in case a forced exit is made. +** openConnection : Open connection to LWL_SERVER. +**---------------------------------------------------------------------------- +** Prototypes +*/ + void CtrlC_Handler (int sigint); + void Do_ESTI (); + void Do_File (); + void Do_HM (int silent); + void Do_Misc (); + void Do_TOF (int silent); + void Do_TS (); + void exit_handler (); + void openConnection (char *node, int port); +/* +**-------------------------------------------------------------------------- +** CtrlC_Handler: Signal handler to detect on keyboard. +*/ + void CtrlC_Handler (int sigint) { +/* ============= +*/ + Ctrl_C_has_happened = 1; + } +/* +**--------------------------------------------------------------------------*/ + void Do_ETSI () { +/* ======= Generate an Extended Time Status Info (hdr + 9 bytes) +*/ + int i, j, status; + char *p_p1, *p_p2, *p_p3, *p_p4, *p_p5, *p_p6, *p_p7, *p_p8, *p_p9; + int p1, p2, p3, p4, p5, p6, p7, p8, p9; + + static unsigned char etsi[] = {0, + b_LWL_HDR_BIT8, b_LWL_TR_ETSI, 0xa5, 0xb6, 0xc7, + 0xd8, 0xe9, 0xfa, 0x0b, 0x1c, 0x2d}; + etsi[0] = sizeof (etsi) - 1; + p_p1 = p_p2 = p_p3 = p_p4 = p_p5 = p_p6 = p_p7 = p_p8 = p_p9 = NULL; + + p_p1 = strtok (NULL, " ,"); + if (p_p1 != NULL) p_p2 = strtok (NULL, " ,"); + if (p_p2 != NULL) p_p3 = strtok (NULL, " ,"); + if (p_p3 != NULL) p_p4 = strtok (NULL, " ,"); + if (p_p4 != NULL) p_p5 = strtok (NULL, " ,"); + if (p_p5 != NULL) p_p6 = strtok (NULL, " ,"); + if (p_p6 != NULL) p_p7 = strtok (NULL, " ,"); + if (p_p7 != NULL) p_p8 = strtok (NULL, " ,"); + if (p_p8 != NULL) p_p9 = strtok (NULL, " ,"); + + if (p_p1 != NULL) {sscanf (p_p1, "%x", &p1); etsi[ 3] = p1 & 0xff;} + if (p_p2 != NULL) {sscanf (p_p2, "%x", &p2); etsi[ 4] = p2 & 0xff;} + if (p_p3 != NULL) {sscanf (p_p3, "%x", &p3); etsi[ 5] = p3 & 0xff;} + if (p_p4 != NULL) {sscanf (p_p4, "%x", &p4); etsi[ 6] = p4 & 0xff;} + if (p_p5 != NULL) {sscanf (p_p5, "%x", &p5); etsi[ 7] = p5 & 0xff;} + if (p_p6 != NULL) {sscanf (p_p6, "%x", &p6); etsi[ 8] = p6 & 0xff;} + if (p_p7 != NULL) {sscanf (p_p7, "%x", &p7); etsi[ 9] = p7 & 0xff;} + if (p_p8 != NULL) {sscanf (p_p8, "%x", &p8); etsi[10] = p8 & 0xff;} + if (p_p9 != NULL) {sscanf (p_p9, "%x", &p9); etsi[11] = p9 & 0xff;} + + status = send (Cnct_skt, etsi, etsi[0]+1, 0); + printf ("Sent: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x " + "0x%02x 0x%02x 0x%02x 0x%02x\n", etsi[1], etsi[2], etsi[3], + etsi[4], etsi[5], etsi[6], etsi[7], etsi[8], etsi[9], + etsi[10], etsi[11]); + etsi[ 3] += 1; + etsi[ 4] += 1; + etsi[ 5] += 1; + etsi[ 6] += 1; + etsi[ 7] += 1; + etsi[ 8] += 1; + etsi[ 9] += 1; + etsi[10] += 1; + etsi[11] += 1; + } +/* +**--------------------------------------------------------------------------*/ + void Do_File () { +/* ======= Read and send the contents of a file. +** +** The file format is: +** +** $ <== all records prior to this "$" are skipped. +** <== subsequent records specify datagrams. +** +** . +** +** End-of-File +** +** The format of a datagram record is: +** ... +** where +** is a hex counter (not used - it can be used to label records) +** is the control byte for the datagram header. Set to 0x10 +** to get Bit-8 of the datagram header set to 1. +** specifies Bits 0-7 of the datagram header. +** ... specify subsequent bytes (Bit-8 = 0). +** All items should be in hex, with or without a 0x prefix. +** For valid datagrams, there should be an even number of bytes. +** +** The file is read into an internal data structure, buff. Pointers +** to the individual records are kept in array p_recs, i.e. p_recs[i] +** is the address of the first byte of record i. This bytes in the +** record are: +** Byte 0 - the number of bytes in the record (excl this one); +** Byte 1 - the Bit-8 control byte for the datagram header; +** Byte 2 - Bits 0-7 of the datagram header; +** Byte 3 ... - subsequent bytes in the datagram. +*/ + int i, j, status, nrec, l_recd; + FILE *stream; + char *p_recd, recd[256], recd1[256]; + char *p_ln, *p_bit8, *p_data; + + char *p_file, *p_ncycles; + int ncycles; + static char last_file[128] = {NIL}; + static int last_ncycles = 1; + + unsigned char *nxt_data; + unsigned char *p_recs[MAXREC]; /* Array of Pointers to the Records */ + unsigned char buff[MAXARR]; /* Array to hold the Records */ + /* + ** ---------- process the arguments and <#-cycles> ---- + */ + p_file = p_ncycles = NULL; + p_file = strtok (NULL, " "); + if (p_file != NULL) p_ncycles = strtok (NULL, " "); + + if (p_file == NULL) p_file = last_file; + if (p_file[0] == NIL) { + printf ("\007No file name specified!\n"); + return; + } + + if (p_ncycles != NULL) { + sscanf (p_ncycles, "%i", &ncycles); + if (ncycles <= 0) ncycles = 1; + }else { + ncycles = last_ncycles; + } + /* + ** ---------- Input File einlesen --------------- + */ + printf ("Opening file %s ...", p_file); + stream = fopen (p_file, "r"); + if (stream == NULL) { + printf ("\n\007Couldn't open %s\n", p_file); + return; + }else { + printf ("\nSkipping over preamble ..."); + recd[0] = NIL; + do { + p_recd = fgets (recd, sizeof (recd), stream); + } while ((p_recd != NULL) && (recd[0] != '$')); + if (p_recd == NULL) { + printf ("\n\007Couldn't find end of preamble!\n"); + return; + } + } + printf (" reading data ..."); + nrec = 0; + nxt_data = buff; + while (fgets (recd, sizeof (recd), stream) != NULL) { + p_recs[nrec] = nxt_data; + nxt_data++; + if (nxt_data > &buff[MAXARR-3]) { + fclose (stream); + printf ("\n\007Abandoned -- more than %d bytes in file!\n", MAXARR-3); + return; + } + l_recd = sizeof (recd1); + StrEdit (recd1, recd, "uncomment compress", &l_recd); + p_ln = strtok (recd1, " \n"); + p_bit8 = (p_ln == NULL) ? NULL : strtok (NULL, " \n"); + p_data = (p_bit8 == NULL) ? NULL : strtok (NULL, " \n"); + if ((p_ln == NULL) || (p_bit8 == NULL) || (p_data == NULL)) { + fclose (stream); + printf ("\n\007Abandoned -- Record %d bad\n \"%s\"\n", nrec, recd); + return; + } + sscanf (p_bit8, "%x", &j); *nxt_data = j; nxt_data++; + sscanf (p_data, "%x", &j); *nxt_data = j; nxt_data++; + *p_recs[nrec] = 2; + while ((p_data = strtok (NULL, " \n")) != NULL) { + sscanf (p_data, "%x", &j); + *nxt_data = j; + nxt_data++; + *p_recs[nrec] += 1; /* Count the bytes in the record */ + if (nxt_data > &buff[MAXARR]) { + fclose (stream); + printf ("\n\007Abandoned -- more than %d bytes in file!\n", MAXARR); + return; + } + } + printf ("\n%5s", p_ln); + for (i = 0; i != *p_recs[nrec]; i++) { + printf (" 0x%02x", *(p_recs[nrec]+i+1)); + } + nrec++; + if (nrec >= MAXREC) { + fclose (stream); + printf ("\n\007Abandoned -- more than %d records in file!\n", MAXREC); + return; + } + } + fclose (stream); + /* + **====== Now loop ncycles times sending the data ======== + */ + for (i = 0; i < ncycles; i++) { + printf ("\nCycle %5d", i+1); + for (j = 0; j < nrec; j++) { + status = send (Cnct_skt, p_recs[j], (*p_recs[j])+1, 0); + } + } + printf ("\nDone.\n"); + + last_ncycles = ncycles; /* Save last used values */ + strcpy (last_file, p_file); + } +/* +**--------------------------------------------------------------------------*/ + void Do_HM (int silent) { +/* ===== Generate a stream of events in "Histogram" Mode +*/ + int i, j, status; + long int nrl; + char *p_nevents, *p_nchans, *p_maxchn[3]; + int nevents, nchans, maxchn[3]; + unsigned char buff[64]; + float scale[3]; + void (* sig_status) (int); + + union { + int wire; + unsigned char b_wire[4]; + } u; + + p_nevents = p_nchans = p_maxchn[0] = p_maxchn[1] = p_maxchn[2] = NULL; + + p_nevents = strtok (NULL, " ,"); + if (p_nevents != NULL) p_nchans = strtok (NULL, " ,"); + if (p_nchans != NULL) p_maxchn[0] = strtok (NULL, " ,"); + if (p_maxchn[0] != NULL) p_maxchn[1] = strtok (NULL, " ,"); + if (p_maxchn[1] != NULL) p_maxchn[2] = strtok (NULL, " ,"); + + if ((p_nevents == NULL) || + (sscanf (p_nevents, "%i", &nevents) != 1)) nevents = 10; + if ((p_nchans == NULL) || + (sscanf (p_nchans, "%i", &nchans) != 1)) nchans = 1; + if ((p_maxchn[0] == NULL) || + (sscanf (p_maxchn[0], "%i", &maxchn[0]) != 1)) maxchn[0] = 1024; + if ((p_maxchn[1] == NULL) || + (sscanf (p_maxchn[1], "%i", &maxchn[1]) != 1)) maxchn[1] = 1024; + if ((p_maxchn[2] == NULL) || + (sscanf (p_maxchn[2], "%i", &maxchn[2]) != 1)) maxchn[2] = 1024; + if (nevents <= 0) nevents = 10; + if ((nchans <= 0) || (nchans > 3)) nchans = 1; + if ((maxchn[0] < 0) || (maxchn[0] > 32767)) maxchn[0] = 1024; + if ((maxchn[1] < 0) || (maxchn[1] > 32767)) maxchn[1] = 1024; + if ((maxchn[2] < 0) || (maxchn[2] > 32767)) maxchn[2] = 1024; + switch (nchans) { + case 1: printf ("HM: %d events, 1 channel, max-channel-value = %d\n", + nevents, maxchn[0]); + break; + case 2: printf ("HM: %d events, 2 channels\n" + " max-channel-0-value = %d\n" + " max-channel-1-value = %d\n", + nevents, maxchn[0], maxchn[1]); + break; + case 3: printf ("HM: %d events, 3 channels\n" + " max-channel-0-value = %d\n" + " max-channel-1-value = %d\n" + " max-channel-2-value = %d\n", + nevents, maxchn[0], maxchn[1], maxchn[2]); + } + Ctrl_C_has_happened = 0; + sig_status = signal (SIGINT, CtrlC_Handler); /* Catch Ctrl-C interrupts */ + if (sig_status == SIG_ERR) { + printf (" Problem setting up a signal handler. You probably\n" + " will not be able to stop by hitting !\n"); + }else { + printf (" Hit to stop: "); + } + + buff[0] = 0x81; /* Get LWL_SERVER to zero message count */ + status = send (Cnct_skt, buff, 1, 0); + if (status != 1) { + printf ("\nBad send status (%d) on \"zero-message\" request. " + "Abandoning!\n", status); + return; + } + + scale[0] = ((float) maxchn[0])/(((float) RAND_MAX) + 1.0); + if (nchans > 1) scale[1] = ((float) maxchn[1])/(((float) RAND_MAX) + 1.0); + if (nchans > 2) scale[2] = ((float) maxchn[2])/(((float) RAND_MAX) + 1.0); + + if (silent == 0) { + printf ("\n "); + if (nchans == 1) printf (" Value"); + if (nchans == 2) printf (" Val0 Val1"); + if (nchans == 3) printf (" Val0 Val1 Val2"); + } + + buff[0] = 5 + (nchans * 2); /* Set up length of datagram */ + buff[1] = b_LWL_HDR_BIT8; + buff[2] = b_LWL_HM_NC | nchans; /* Header for Hist-Mode/No-Coinc/n-Chans */ + buff[3] = 0x00; + buff[4] = 0x00; + buff[5] = 0x00; + i = 0; + do { + buff[5] = i & 0xff; + if (silent == 0) printf ("\n%5d", i); + for (j = 0; j < nchans; j++) { + u.wire = (int) (rand () * scale[j]); + buff[6+2*j] = u.b_wire[1]; + buff[7+2*j] = u.b_wire[0]; + if (silent == 0) printf (" %5d", u.wire); + } + status = send (Cnct_skt, buff, buff[0]+1, 0); + if (silent == 0) { + printf (" 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", + buff[1], buff[2], buff[3], buff[4], buff[5], buff[6], buff[7]); + if (nchans > 1) printf (" 0x%02x 0x%02x", buff[8], buff[9]); + if (nchans > 2) printf (" 0x%02x 0x%02x", buff[10], buff[11]); + } + if (status != (buff[0] + 1)) { + printf ("\nBad send status (%d) on event %d. Abandoning!\n", status, i); + return; + } + i++; + } while ((i != nevents) && (Ctrl_C_has_happened == 0)); + printf ("\nDone: %d\n", i); + signal (SIGINT, SIG_DFL); + + buff[0] = 0x82; /* Get LWL_SERVER to display message count */ + status = send (Cnct_skt, buff, 1, 0); + if (status != 1) { + printf ("\nBad send status (%d) on \"display-message\" request. " + "Abandoning!\n", status); + return; + } + } +/* +**--------------------------------------------------------------------------*/ + void Do_HRPT (int silent) { +/* ======= Generate a stream of events in "HRPT" Mode +*/ + int i, j, status, wire, cnt; + long int nrl; + char *p_nevents, *p_minwire, *p_maxwire, *p_maxcnt; + int nevents, minwire, maxwire, maxcnt; + unsigned char buff[64]; + float scale[2]; + void (* sig_status) (int); + + p_nevents = p_minwire = p_maxwire = p_maxcnt = NULL; + + p_nevents = strtok (NULL, " ,"); + if (p_nevents != NULL) p_minwire = strtok (NULL, " ,"); + if (p_minwire != NULL) p_maxwire = strtok (NULL, " ,"); + if (p_maxwire != NULL) p_maxcnt = strtok (NULL, " ,"); + + if ((p_nevents == NULL) || + (sscanf (p_nevents, "%i", &nevents) != 1)) nevents = 10; + if ((p_minwire == NULL) || + (sscanf (p_minwire, "%i", &minwire) != 1)) minwire = 1; + if ((p_maxwire == NULL) || + (sscanf (p_maxwire, "%i", &maxwire) != 1)) maxwire = 1600; + if ((p_maxcnt == NULL) || + (sscanf (p_maxcnt, "%i", &maxcnt) != 1)) maxcnt = 0x3ff; + if (nevents <= 0) nevents = 10; + if ((minwire < 0) || (minwire > 0x7fff)) minwire = 1; + if ((maxwire < minwire) || (maxwire > 0x7fff)) maxwire = 1600; + if ((maxcnt < 0) || (maxcnt > 0x3ff)) maxcnt = 0x3ff; + printf ("HRPT: %d events, Wire# %d to Wire# %d, max-cnts-per-wire = %d\n", + nevents, minwire, maxwire, maxcnt); + + Ctrl_C_has_happened = 0; + sig_status = signal (SIGINT, CtrlC_Handler); /* Catch Ctrl-C interrupts */ + if (sig_status == SIG_ERR) { + printf (" Problem setting up a signal handler. You probably\n" + " will not be able to stop by hitting !\n"); + }else { + printf (" Hit to stop: "); + } + + buff[0] = 0x81; /* Get LWL_SERVER to zero message count */ + status = send (Cnct_skt, buff, 1, 0); + if (status != 1) { + printf ("\nBad send status (%d) on \"zero-message\" request. " + "Abandoning!\n", status); + return; + } + + scale[0] = ((float) (maxwire - minwire + 1))/(((float) RAND_MAX) + 1.0); + scale[1] = ((float) (maxcnt))/(((float) RAND_MAX) + 1.0); + + if (silent == 0) { + printf ("\n Wire Cnts"); + } + + buff[0] = 11; /* Set up length of datagram */ + buff[1] = b_LWL_HDR_BIT8; + buff[2] = b_LWL_HM_NC3; /* Header for Hist-Mode/No-Coinc/3-Chans */ + buff[3] = 0x00; + buff[4] = 0x00; + i = 0; + do { + buff[5] = i & 0xff; + if (silent == 0) printf ("\n%5d", i); + wire = (int) (rand () * scale[0]); + wire += minwire; + cnt = (int) (rand () * scale[1]); + buff[6] = (wire & 0x0000ff00) >> 8; + buff[7] = wire & 0xff; + buff[8] = (cnt & 0x0000ff00) >> 8; + buff[9] = cnt & 0xff; + buff[10] = (i & 0x0000ff00) >> 8; + buff[11] = i & 0xff; + if (silent == 0) printf (" %5d %5d", wire, cnt); + status = send (Cnct_skt, buff, buff[0]+1, 0); + if (silent == 0) { + printf (" 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x" + " 0x%02x 0x%02x 0x%02x 0x%02x", + buff[1], buff[2], buff[3], buff[4], buff[5], buff[6], buff[7], + buff[8], buff[9], buff[10], buff[11]); + } + if (status != (buff[0] + 1)) { + printf ("\nBad send status (%d) on event %d. Abandoning!\n", status, i); + return; + } + i++; + } while ((i != nevents) && (Ctrl_C_has_happened == 0)); + printf ("\nDone: %d\n", i); + signal (SIGINT, SIG_DFL); + + buff[0] = 0x82; /* Get LWL_SERVER to display message count */ + status = send (Cnct_skt, buff, 1, 0); + if (status != 1) { + printf ("\nBad send status (%d) on \"display-message\" request. " + "Abandoning!\n", status); + return; + } + } +/* +**--------------------------------------------------------------------------*/ + void Do_Misc () { +/* ======= Generate a Miscellaneous Datagram +*/ + int i, j, status; + char *p_p00, *p_p01, *p_p02, *p_p03, *p_p04, *p_p05, *p_p06, *p_p07, + *p_p08, *p_p09, *p_p10, *p_p11, *p_p12, *p_p13, *p_p14, *p_p15, + *p_p16, *p_p17, *p_p18, *p_p19, *p_p20, *p_p21, *p_p22, *p_p23; + + int p00, p01, p02, p03, p04, p05, p06, p07, + p08, p09, p10, p11, p12, p13, p14, p15, + p16, p17, p18, p19, p20, p21, p22, p23; + char *tmp; + + unsigned char misc[32]; + + p_p00 = p_p01 = p_p02 = p_p03 = p_p04 = p_p05 = p_p06 = p_p07 = + p_p08 = p_p09 = p_p10 = p_p11 = p_p12 = p_p13 = p_p14 = p_p15 = + p_p16 = p_p17 = p_p18 = p_p19 = p_p20 = p_p21 = p_p22 = p_p23 = NULL; + misc[0] = 0; /* Initialise number of bytes to be sent */ + + p_p00 = strtok (NULL, " ,"); + if (p_p00 != NULL) {misc[0]++; p_p01 = strtok (NULL, " ,");} + if (p_p01 != NULL) {misc[0]++; p_p02 = strtok (NULL, " ,");} + if (p_p02 != NULL) {misc[0]++; p_p03 = strtok (NULL, " ,");} + if (p_p03 != NULL) {misc[0]++; p_p04 = strtok (NULL, " ,");} + if (p_p04 != NULL) {misc[0]++; p_p05 = strtok (NULL, " ,");} + if (p_p05 != NULL) {misc[0]++; p_p06 = strtok (NULL, " ,");} + if (p_p06 != NULL) {misc[0]++; p_p07 = strtok (NULL, " ,");} + if (p_p07 != NULL) {misc[0]++; p_p08 = strtok (NULL, " ,");} + if (p_p08 != NULL) {misc[0]++; p_p09 = strtok (NULL, " ,");} + if (p_p09 != NULL) {misc[0]++; p_p10 = strtok (NULL, " ,");} + if (p_p10 != NULL) {misc[0]++; p_p11 = strtok (NULL, " ,");} + if (p_p11 != NULL) {misc[0]++; p_p12 = strtok (NULL, " ,");} + if (p_p12 != NULL) {misc[0]++; p_p13 = strtok (NULL, " ,");} + if (p_p13 != NULL) {misc[0]++; p_p14 = strtok (NULL, " ,");} + if (p_p14 != NULL) {misc[0]++; p_p15 = strtok (NULL, " ,");} + if (p_p15 != NULL) {misc[0]++; p_p16 = strtok (NULL, " ,");} + if (p_p16 != NULL) {misc[0]++; p_p17 = strtok (NULL, " ,");} + if (p_p17 != NULL) {misc[0]++; p_p18 = strtok (NULL, " ,");} + if (p_p18 != NULL) {misc[0]++; p_p19 = strtok (NULL, " ,");} + if (p_p19 != NULL) {misc[0]++; p_p20 = strtok (NULL, " ,");} + if (p_p20 != NULL) {misc[0]++; p_p21 = strtok (NULL, " ,");} + if (p_p21 != NULL) {misc[0]++; p_p22 = strtok (NULL, " ,");} + if (p_p22 != NULL) {misc[0]++; p_p23 = strtok (NULL, " ,");} + if (p_p23 != NULL) misc[0]++; + tmp = (p_p23 != NULL) ? strtok (NULL, " ,") : NULL; + if (tmp != NULL) { + printf ("\007Too many bytes specified. The current maximum is 24!\n"); + return; + } + if ((misc[0] & 0x01) != 0) { + printf ("\007Warning - an odd number of bytes was specified.\n" + " This generates an illegal datagram!\n"); + } + if (misc[0] == 0) { + printf ("\007No bytes specified!\n"); + return; + } + + misc[1] = b_LWL_HDR_BIT8; /* The first byte is the Bit-8 byte */ + misc[0]++; /* Count it too */ + + if (p_p00 != NULL) {sscanf (p_p00, "%x", &p00); misc[ 2] = p00 & 0xff;} + if (p_p01 != NULL) {sscanf (p_p01, "%x", &p01); misc[ 3] = p01 & 0xff;} + if (p_p02 != NULL) {sscanf (p_p02, "%x", &p02); misc[ 4] = p02 & 0xff;} + if (p_p03 != NULL) {sscanf (p_p03, "%x", &p03); misc[ 5] = p03 & 0xff;} + if (p_p04 != NULL) {sscanf (p_p04, "%x", &p04); misc[ 6] = p04 & 0xff;} + if (p_p05 != NULL) {sscanf (p_p05, "%x", &p05); misc[ 7] = p05 & 0xff;} + if (p_p06 != NULL) {sscanf (p_p06, "%x", &p06); misc[ 8] = p06 & 0xff;} + if (p_p07 != NULL) {sscanf (p_p07, "%x", &p07); misc[ 9] = p07 & 0xff;} + if (p_p08 != NULL) {sscanf (p_p08, "%x", &p08); misc[10] = p08 & 0xff;} + if (p_p09 != NULL) {sscanf (p_p09, "%x", &p09); misc[11] = p09 & 0xff;} + if (p_p10 != NULL) {sscanf (p_p10, "%x", &p10); misc[12] = p10 & 0xff;} + if (p_p11 != NULL) {sscanf (p_p11, "%x", &p11); misc[13] = p11 & 0xff;} + if (p_p12 != NULL) {sscanf (p_p12, "%x", &p12); misc[14] = p12 & 0xff;} + if (p_p13 != NULL) {sscanf (p_p13, "%x", &p13); misc[15] = p13 & 0xff;} + if (p_p14 != NULL) {sscanf (p_p14, "%x", &p14); misc[16] = p14 & 0xff;} + if (p_p15 != NULL) {sscanf (p_p15, "%x", &p15); misc[17] = p15 & 0xff;} + if (p_p16 != NULL) {sscanf (p_p16, "%x", &p16); misc[18] = p16 & 0xff;} + if (p_p17 != NULL) {sscanf (p_p17, "%x", &p17); misc[19] = p17 & 0xff;} + if (p_p18 != NULL) {sscanf (p_p18, "%x", &p18); misc[20] = p18 & 0xff;} + if (p_p19 != NULL) {sscanf (p_p19, "%x", &p19); misc[21] = p19 & 0xff;} + if (p_p20 != NULL) {sscanf (p_p20, "%x", &p20); misc[22] = p20 & 0xff;} + if (p_p21 != NULL) {sscanf (p_p21, "%x", &p21); misc[23] = p21 & 0xff;} + if (p_p22 != NULL) {sscanf (p_p22, "%x", &p22); misc[24] = p22 & 0xff;} + if (p_p23 != NULL) {sscanf (p_p23, "%x", &p23); misc[25] = p23 & 0xff;} + + status = send (Cnct_skt, misc, misc[0]+1, 0); + printf ("Sent: 0x%02x 0x%02x", misc[1], misc[2]); + if (misc[0] > 2) printf (" 0x%02x", misc[ 3]); + if (misc[0] > 3) printf (" 0x%02x", misc[ 4]); + if (misc[0] > 4) printf (" 0x%02x", misc[ 5]); + if (misc[0] > 5) printf (" 0x%02x", misc[ 6]); + if (misc[0] > 6) printf (" 0x%02x", misc[ 7]); + if (misc[0] > 7) printf (" 0x%02x", misc[ 8]); + if (misc[0] > 8) printf ("\n 0x%02x", misc[ 9]); + if (misc[0] > 9) printf (" 0x%02x", misc[10]); + if (misc[0] > 10) printf (" 0x%02x", misc[11]); + if (misc[0] > 11) printf (" 0x%02x", misc[12]); + if (misc[0] > 12) printf (" 0x%02x", misc[13]); + if (misc[0] > 13) printf (" 0x%02x", misc[14]); + if (misc[0] > 14) printf (" 0x%02x", misc[15]); + if (misc[0] > 15) printf (" 0x%02x", misc[16]); + if (misc[0] > 16) printf ("\n 0x%02x", misc[17]); + if (misc[0] > 17) printf (" 0x%02x", misc[18]); + if (misc[0] > 18) printf (" 0x%02x", misc[19]); + if (misc[0] > 19) printf (" 0x%02x", misc[20]); + if (misc[0] > 20) printf (" 0x%02x", misc[21]); + if (misc[0] > 21) printf (" 0x%02x", misc[22]); + if (misc[0] > 22) printf (" 0x%02x", misc[23]); + if (misc[0] > 23) printf (" 0x%02x", misc[24]); + if (misc[0] > 24) printf (" 0x%02x", misc[25]); + printf ("\n"); + } +/* +**--------------------------------------------------------------------------*/ + void Do_TOF (int silent) { +/* ====== Generate a stream of events in "TOF" Mode +*/ + int i, j, status; + long int nrl; + char *p_nevents, *p_hi_cntr, *p_hi_time, *p_lo_cntr, *p_lo_time; + unsigned int nevents, hi_cntr, hi_time, lo_cntr, lo_time; + unsigned char buff[64]; + float cntr_scale, time_scale; + void (* sig_status) (int); + + union { + int i4; + unsigned char byt[4]; + } cntr, time; + + p_nevents = p_hi_cntr = p_hi_time = p_lo_cntr = p_lo_time = NULL; + + p_nevents = strtok (NULL, " ,"); + if (p_nevents != NULL) p_hi_cntr = strtok (NULL, " ,"); + if (p_hi_cntr != NULL) p_hi_time = strtok (NULL, " ,"); + if (p_hi_time != NULL) p_lo_cntr = strtok (NULL, " ,"); + if (p_lo_cntr != NULL) p_lo_time = strtok (NULL, " ,"); + + if ((p_nevents == NULL) || + (sscanf (p_nevents, "%u", &nevents) != 1)) nevents = 10; + if ((p_hi_cntr == NULL) || + (sscanf (p_hi_cntr, "%u", &hi_cntr) != 1)) hi_cntr = 127; + if ((p_hi_time == NULL) || + (sscanf (p_hi_time, "%u", &hi_time) != 1)) hi_time = LWL_HDR_TS_MASK; + if ((p_lo_cntr == NULL) || + (sscanf (p_lo_cntr, "%u", &lo_cntr) != 1)) lo_cntr = 0; + if ((p_lo_time == NULL) || + (sscanf (p_lo_time, "%u", &lo_time) != 1)) lo_time = 0; + + if (nevents == 0) nevents = 10; + if (hi_cntr > MAX_TOF_CNTR) hi_cntr = 127; + if (hi_time > (LWL_HDR_TS_MASK)) hi_time = LWL_HDR_TS_MASK; + if (lo_cntr > hi_cntr) lo_cntr = 0; + if (lo_time > hi_time) lo_time = 0; + + printf ("TOF: %u events\n" + " Counters from %u to %u\n" + " Time-values from 0x%x to 0x%x\n", + nevents, lo_cntr, hi_cntr, lo_time, hi_time); + + Ctrl_C_has_happened = 0; + sig_status = signal (SIGINT, CtrlC_Handler); /* Catch Ctrl-C interrupts */ + if (sig_status == SIG_ERR) { + printf (" Problem setting up a signal handler. You probably\n" + " will not be able to stop by hitting !\n"); + }else { + printf (" Hit to stop: "); + } + + buff[0] = 0x81; /* Get LWL_SERVER to zero message count */ + status = send (Cnct_skt, buff, 1, 0); + if (status != 1) { + printf ("\nBad send status (%d) on \"zero-message\" request. " + "Abandoning!\n", status); + return; + } + + cntr_scale = ((float) (hi_cntr - lo_cntr + 1))/(((float) RAND_MAX) + 1.0); + time_scale = ((float) (hi_time - lo_time + 1))/(((float) RAND_MAX) + 1.0); + + if (silent == 0) + printf ("\n Time Cntr"); + buff[0] = 7; /* Set up length of datagram */ + buff[1] = b_LWL_HDR_BIT8; + buff[2] = b_LWL_TOF | 1; /* Header for TOF-Mode/1-Chan */ + buff[3] = 0x00; + buff[4] = 0x00; + buff[5] = 0x00; + buff[6] = 0x00; + buff[7] = 0x00; + i = 0; + do { + time.i4 = (int) (rand () * time_scale); + time.i4 += lo_time; + if (time.i4 > hi_time) time.i4 = hi_time; + time.i4 &= LWL_HDR_TS_MASK; + buff[3] = time.byt[2]; + buff[4] = time.byt[1]; + buff[5] = time.byt[0]; + + cntr.i4 = (int) (rand () * cntr_scale); + cntr.i4 += lo_cntr; + if (cntr.i4 > hi_cntr) cntr.i4 = hi_cntr; + buff[6] = cntr.byt[1]; + buff[7] = cntr.byt[0]; + + status = send (Cnct_skt, buff, buff[0]+1, 0); + if (silent == 0) { + printf ("\n%5d %8d %5d 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", + i, time.i4, cntr.i4, + buff[1], buff[2], buff[3], buff[4], buff[5], buff[6], buff[7]); + } + if (status != (buff[0] + 1)) { + printf ("\nBad send status (%d) on event %d. Abandoning!\n", status, i); + return; + } + i++; + } while ((i != nevents) && (Ctrl_C_has_happened == 0)); + printf ("\nDone: %d\n", i); + signal (SIGINT, SIG_DFL); + + buff[0] = 0x82; /* Get LWL_SERVER to display message count */ + status = send (Cnct_skt, buff, 1, 0); + if (status != 1) { + printf ("\nBad send status (%d) on \"display-message\" request. " + "Abandoning!\n", status); + return; + } + } +/* +**--------------------------------------------------------------------------*/ + void Do_TS () { +/* ===== Generate a Time Status packet (hdr + 5 bytes) +*/ + int i, j, status; + char *p_p1, *p_p2, *p_p3, *p_p4, *p_p5; + int p1, p2, p3, p4, p5; + + static unsigned char ts[] = {0, + b_LWL_HDR_BIT8, b_LWL_TR_TSI, 0x2e, 0x3d, 0x4c, + 0x5b, 0x6a}; + ts[0] = sizeof (ts) - 1; + p_p1 = p_p2 = p_p3 = p_p4 = p_p5 = NULL; + + p_p1 = strtok (NULL, " ,"); + if (p_p1 != NULL) p_p2 = strtok (NULL, " ,"); + if (p_p2 != NULL) p_p3 = strtok (NULL, " ,"); + if (p_p3 != NULL) p_p4 = strtok (NULL, " ,"); + if (p_p4 != NULL) p_p5 = strtok (NULL, " ,"); + + if (p_p1 != NULL) {sscanf (p_p1, "%x", &p1); ts[3] = p1 & 0xff;} + if (p_p2 != NULL) {sscanf (p_p2, "%x", &p2); ts[4] = p2 & 0xff;} + if (p_p3 != NULL) {sscanf (p_p3, "%x", &p3); ts[5] = p3 & 0xff;} + if (p_p4 != NULL) {sscanf (p_p4, "%x", &p4); ts[6] = p4 & 0xff;} + if (p_p5 != NULL) {sscanf (p_p5, "%x", &p5); ts[7] = p5 & 0xff;} + + status = send (Cnct_skt, ts, ts[0]+1, 0); + printf ("Sent: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", + ts[1], ts[2], ts[3], ts[4], ts[5], ts[6], ts[7]); + ts[3] += 1; + ts[4] += 1; + ts[5] += 1; + ts[6] += 1; + ts[7] += 1; + } +/* +**---------------------------------------------------------------------------*/ + void exit_handler () { +/* ============ +** We must exit. Tidy up first. +** Close TCP/IP link to front-end. +*/ + int status; + char buff[16]; +/* +** Tell server we're quitting. +*/ + if (Cnct_skt != 0) { + printf ("Closing connection to %s ...\n", Rmt_host); + buff[0] = 0x00; + status = send (Cnct_skt, buff, 1, 0); + status = close (Cnct_skt); + Cnct_skt = 0; + if (status != 0) FailInet ("EXIT_HANDLER -- R/W-Socket close error\n"); + } + } +/* +**--------------------------------------------------------------------------*/ + void openConnection ( +/* ============== +** Open connection to histogram memory front-end. +*/ + char *node, + int port) { + + int i, status; + struct sockaddr_in lcl_sockname; + struct sockaddr_in rmt_sockname; + int rmt_inet_addr; + struct in_addr *rmt_inet_addr_pntr; + struct hostent *rmt_hostent; + int rmt_sockname_len; + unsigned int oto_len, oto_status; + char old_time_out[4]; + union { + char chars[4]; + int val; + } time_out; + /* + ** Get Internet address of the front-end. + */ + for (i=0; i < strlen (node); i++) node[i] = tolower (node[i]); + rmt_hostent = gethostbyname (node); + if (rmt_hostent == NULL) { + /* + ** The following code is to handle nodes which are not yet + ** in the BIND data base. + */ + if (strcmp (node, "sqfe01") == 0) { + rmt_inet_addr_pntr = (struct in_addr *) &rmt_inet_addr; + rmt_inet_addr = inet_addr ("129.129.56.181"); + }else { + printf ("Server Node is %s.\n", node); + FailInet ("\nGethostbyname error."); + } + }else { + rmt_inet_addr_pntr = (struct in_addr *) rmt_hostent->h_addr_list[0]; + } + printf (" LWL_SERVER is running on %s ", node); + printf ("(%s),", inet_ntoa (*rmt_inet_addr_pntr)); + printf (" Port %d\n", port); +/* +** Create a TCP/IP socket for prelim. connect to server and bind it. +*/ + Cnct_skt = socket (AF_INET, SOCK_STREAM, 0); + if (Cnct_skt == -1) FailInet ("Socket error.\n"); + + lcl_sockname.sin_family = AF_INET; + lcl_sockname.sin_port = htons (0); + lcl_sockname.sin_addr.s_addr = 0; + status = bind (Cnct_skt, (struct sockaddr *) &lcl_sockname, + sizeof (lcl_sockname)); + if (status == -1) FailInet ("Bind error.\n"); + /*--------------------------- + ** Set short time-out (VMS systems only) + */ +#ifdef __VMS + oto_len = sizeof (old_time_out); /* Save current time-out first */ + oto_status = getsockopt (Cnct_skt, IPPROTO_TCP, UCX$C_TCP_PROBE_IDLE, + old_time_out, &oto_len); + if (oto_status == 0) { + time_out.val = 5; /* Set new time-out */ + status = setsockopt (Cnct_skt, IPPROTO_TCP, UCX$C_TCP_PROBE_IDLE, + time_out.chars, sizeof (time_out)); + } +#endif +/* +**========================================= Now connect to the server. +*/ + rmt_sockname_len = sizeof (rmt_sockname); + rmt_sockname.sin_family = AF_INET; + rmt_sockname.sin_port = htons (port); + rmt_sockname.sin_addr.s_addr = rmt_inet_addr_pntr->s_addr; + status = connect (Cnct_skt, (struct sockaddr *) &rmt_sockname, + sizeof (rmt_sockname)); + if (status == -1) { + GetErrno (&My_errno, &My_vaxc_errno); + FailInet ("Connect error\n"); + } + /*--------------------------- + ** Restore time-out (VMS only) + */ +#ifdef __VMS + if (oto_status == 0) { + setsockopt (Cnct_skt, IPPROTO_TCP, UCX$C_TCP_PROBE_IDLE, + old_time_out, oto_len); + } +#endif + } +/* +**--------------------------------------------------------------------------- +** setup_xrm_database - setup Resource Manager Database +*/ + int setup_xrm_database ( +/* ================== +*/ XrmDatabase *db, + char *name[], + int *argc, + char *argv[], + int verbose) { + + 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 turns out to be lacking + ** when it gets tested in anger. + */ + status = True; /* Assume success */ + + our_name[0] = NIL; + /* + ** 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 + if (verbose) 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) && verbose) { + if (first) + printf ("Resource database created from file %s.\n", p_fil[i]); + if (!first) + 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, + OptTable, XtNumber(OptTable), 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 OptTable and merge them into database, + ** taking care of any possible name changes. + */ + for (i = 0; i < XtNumber (OptTable); i++) { + if (strcmp (OptTable[i].option, "-name") == 0) continue; + status = XrmGetResource (cmnd_line_db, + StrJoin (text, sizeof (text), + our_name, OptTable[i].specifier), + "ProgramName.Values", + &name_type, &name_value); + if (status) { + StrJoin (text, sizeof (text), lkup_name, OptTable[i].specifier); + XrmPutResource (&lcl_db, text, "String", &name_value); + } + } + } +/*---------------------------------------------------------------- +*/ + *name = lkup_name; + *db = lcl_db; + if ((lcl_db == NULL) && verbose) + printf ("\007Warning -- no resource database found.\n"); + + XrmDestroyDatabase (cmnd_line_db); +/* +** XrmPutFileDatabase (lcl_db, "lwl_client.db"); +*/ + return status; + } +/* +**========================================================================== +** +** Main line program +** ------------------ +**==========================================================================*/ + int main (int argc, char *argv[]) { +/* ==== +*/ + int i, j, k, status, is, silent; + + unsigned char ubuff[16]; + unsigned char fe[] = {5, b_LWL_HDR_BIT8, b_LWL_FIFO_EMPTY, + 0x00, 0x00, 0x00}; + + char recd[256], recd1[256]; + char last_recd[256] = {NIL}; + char *verb; + int l_recd; + time_t startTime; + char cmndLine[132]; + + char buff[80], *appName; + XrmDatabase my_db; + XrmValue value; + char *type; +/*============================================================================ +*/ + startTime = time (NULL); + printf ("LWL_CLIENT Ident %s started.\n", Ident); + printf ("Started at %s", asctime (localtime (&startTime))); + + StrJoin (cmndLine, sizeof (cmndLine), argv[0], ""); + for (i = 1; i < argc; i++) { + StrJoin (cmndLine, sizeof (cmndLine), cmndLine, " "); + StrJoin (cmndLine, sizeof (cmndLine), cmndLine, argv[i]); + } + printf ("Command: %s\n", cmndLine); +/*============================================================================ +** Declare an exit handler to tidy up if we get forced to exit. +*/ + is = atexit (exit_handler); + if (is != 0) { + printf ("LWL_CLIENT -- error setting up exit handler."); + return EXIT_FAILURE; + } +/*============================================================================ +** Setup the resource database and look up the resources. +** If there is a single item left on the command line, assume +** that it is the target host. +*/ + Verbose = False; + for (i = 1; i < argc; i++) if (strcmp ("-v", argv[i]) == 0) Verbose = True; + + setup_xrm_database (&my_db, &appName, &argc, argv, Verbose); + /* - - - - - - - - - - - - - - - - - - - - - - - - */ + status = XrmGetResource (my_db, + StrJoin (buff, sizeof (buff), + appName, ".lwlHost"), + "ProgramName.Values", + &type, &value); + if (status) { + StrJoin (Rmt_host, sizeof (Rmt_host), value.addr, ""); + }else { + if (argc == 2) { + StrJoin (Rmt_host, sizeof (Rmt_host), argv[1], ""); + argc--; + }else { + printf ("\n" + "Host name not defined via the\n" + " \"lwlHost\" resource or the\n" + " \"-host\" option.\n" + "There is no default!\n"); + exit (EXIT_FAILURE); + } + } + /* - - - - - - - - - - - - - - - - - - - - - - - - */ + if (argc > 1) { + printf ("The following illegal options were specified:\n "); + for (i = 1; i < argc; i++) printf (" %s", argv[i]); + printf ("\nThe following options are recognised:\n"); + for (i = 1; i < XtNumber (OptTable); i++) { + printf (" %s\n", OptTable[i].option); + } + exit (EXIT_FAILURE); + } + /* - - - - - - - - - - - - - - - - - - - - - - - - */ + status = XrmGetResource (my_db, + StrJoin (buff, sizeof (buff), + appName, ".lwlPort"), + "ProgramName.Values", + &type, &value); + if (!status) { + Rmt_port = 3501; + }else if ((sscanf (value.addr, "%d", &Rmt_port) != 1) || + (Rmt_port < 1024) || + (Rmt_port > 65535)) { + printf ("\n" + " \"-port %s\" is illegal! It must be an integer in the range " + "1024 to 65535\n" + "\n", value.addr); + exit (EXIT_FAILURE); + } + /* - - - - - - - - - - - - - - - - - - - - - - - - */ + status = XrmGetResource (my_db, + StrJoin (buff, sizeof (buff), + appName, ".lwlSize"), + "ProgramName.Values", + &type, &value); + if (!status) { + Pkt_size = 8192; + }else if ((sscanf (value.addr, "%d", &Pkt_size) != 1) || + (Pkt_size < 256) || + (Pkt_size > 65536)) { + printf ("\n" + " \"-size %s\" is illegal! It must be an integer in the range " + "256 to 65536\n" + "\n", value.addr); + exit (EXIT_FAILURE); + } +/*============================================================================ +** Find out the location of the LWL Server and make +** a connection to it. Any errors during this phase cause the program +** to exit with an error status. +*/ + openConnection (Rmt_host, Rmt_port); +/* +**====================================================== Wait for work ========= +*/ + recd[0] = NIL; + printf ("> "); + while (fgets (recd, sizeof (recd), stdin) != NULL) { + if (strlen (recd) == (sizeof (recd) - 1)) { + printf ("\n\n\007Input buffer overflow -- command ignored!\n\n"); + do { /* Flush the remains */ + fgets (recd, sizeof (recd), stdin); + } while (strlen (recd) == (sizeof (recd) - 1)); + printf ("> "); + continue; + } + i = strlen (recd) - 1; + if (recd[i] == NL) recd[i] = NIL; /* Suppress the trailing \n */ + if (recd[0] == NIL) { /* If just , repeat */ + strcpy (recd, last_recd); + } + l_recd = sizeof (recd1); + StrEdit (recd1, recd, "trim compress uncomment lowercase", &l_recd); + if (l_recd <= 0) { /* Skip empty lines */ + printf ("\n> "); + continue; + } + /* + ** Parse the command + */ + verb = strtok (recd1, " ,"); + if ((strcmp (verb, "q") == 0) || /* Quit */ + (strcmp (verb, "qu") == 0) || + (strcmp (verb, "qui") == 0) || + (strcmp (verb, "quit") == 0) || + (strcmp (verb, "ex") == 0) || + (strcmp (verb, "exi") == 0) || + (strcmp (verb, "exit") == 0)) { + break; + }else if ((strcmp (verb, "et") == 0) || /* Send Extended T Status Info */ + (strcmp (verb, "ets") == 0) || + (strcmp (verb, "etsi") == 0)) { + Do_ETSI (); + }else if (strcmp (verb, "fe") == 0) { /* Send Fifo-empty */ + status = send (Cnct_skt, fe, fe[0]+1, 0); + printf ("Sent: 0x%02x 0x%02x 0x%02x 0x%02x\n", + fe[1], fe[2], fe[3], fe[4]); + }else if ((strcmp (verb, "fi") == 0) || /* Send File */ + (strcmp (verb, "fil") == 0) || + (strcmp (verb, "file") == 0)) { + Do_File (); + }else if ((strcmp (verb, "hm") == 0) || /* Histogram Mode */ + (strcmp (verb, "hm/s") == 0)) { /* Params are: + ** <#-events> + ** <#-chans> (1, 2 or 3) + ** + ** + ** ... + */ + silent = 0; + if (strcmp (verb, "hm/s") == 0) silent = 1; + Do_HM (silent); + }else if ((strcmp (verb, "hr") == 0) || /* HRPT Mode */ + (strcmp (verb, "hrp") == 0) || + (strcmp (verb, "hrpt") == 0) || + (strcmp (verb, "hr/s") == 0) || + (strcmp (verb, "hrp/s") == 0) || + (strcmp (verb, "hrpt/s") == 0)) { /* Params are: + ** <#-events> + ** + ** + ** + ** ... + */ + silent = 0; + if (strcmp (verb, "hr/s") == 0) silent = 1; + if (strcmp (verb, "hrp/s") == 0) silent = 1; + if (strcmp (verb, "hrpt/s") == 0) silent = 1; + Do_HRPT (silent); + }else if ((strcmp (verb, "mi") == 0) || /* Send Miscellaneous Datagram */ + (strcmp (verb, "mis") == 0) || + (strcmp (verb, "misc") == 0)) { + Do_Misc (); + }else if ((strcmp (verb, "tof") == 0) || /* TOF Mode */ + (strcmp (verb, "tof/s") == 0)) { /* Params are: + ** <#-events> (dflt=10) + ** (dflt=127) + ** (dflt=0xfffff) + ** (dflt=0) + ** (dflt=0) + */ + silent = (strcmp (verb, "tof/s") == 0) ? 1 : 0; + Do_TOF (silent); + }else if (strcmp (verb, "ts") == 0) { /* Send Time Stamp */ + Do_TS (); + }else if ((strcmp (verb, "?") == 0) || + (strcmp (verb, "h") == 0) || + (strcmp (verb, "he") == 0) || + (strcmp (verb, "hel") == 0) || + (strcmp (verb, "help") == 0)) { + printf ("\n" + " The following commands are recognised by LWL_CLIENT:\n" + "\n" + " ETSI ... - Send Extended Time Stamp Info (0x0e + 9 bytes)\n" + "\n" + " FE - Send FIFO-Empty (0x1e, 0, 0, 0)\n" + "\n" + " FILE <#-cycles> - Send file to LWL <#-cycles> times.\n" + "\n" + " HM <#-events> <#chans> ... - generate\n" + " data flow in \"Histogram\" Mode.\n" + "\n" + " HM/S <#-events> <#chans> ... - same as HM only" + " silent.\n" + "\n" + " HRPT <#-events> ... " + "- generate\n" + " data flow in \"HRPT\" Mode.\n" + "\n" + " HRPT/S <#-events> ... - same as HRPT only" + " silent.\n" + "\n" + " TOF <#-events> " + "- generate\n" + " data flow in \"TOF\" Mode.\n" + "\n" + " TOF/S <#-events> ... - same as TOF only" + " silent.\n" + "\n" + " MISC ... - Send miscellaneous datagram (up to 10 bytes)\n" + " \" ...\" are in hex, without \"0x\" prefix.\n" + "\n" + " TS ... - Send Time Stamp (0x1f + 5 bytes)\n" + "\n" + " HELP or ? - generate this help text.\n" + "\n" + " To run the program:\n" + " lwl_client [-host] [-port ] [-size ]\n" + "\n" + " Default for = 3501\n" + " Default for = 8192\n" + "\n"); + }else { + printf ("\n Illegal command - type \"?\" for help.\n"); + } + strcpy (last_recd, recd); + /* + ** Get another command. + */ + printf ("> "); + } +/* +** Tell server we're quitting. +*/ + printf ("Closing connection to %s ...\n", Rmt_host); + ubuff[0] = 0x00; + status = send (Cnct_skt, ubuff, 1, 0); + status = close (Cnct_skt); + Cnct_skt = 0; + if (status != 0) FailInet ("LWL_CLIENT -- R/W-Socket close error\n"); + + return EXIT_SUCCESS; + } +/*============================================= End of LWL_CLIENT.C ======*/