#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    <errno.h>
#include    <netdb.h>
#include    <stdio.h>
#include    <stdlib.h>
#include    <signal.h>
#include    <time.h>


#include    <sys/types.h>
#include    <ctype.h>
#include    <math.h>
#include    <sys/socket.h>
#include    <string.h>

#ifdef	__VMS
#include    <ucx$inetdef.h>
#include    <sys/unixio.h>
#include    <descrip>
#else
#include    <unistd.h>
#endif

#ifdef __VMS
#include    <sys/ssdef.h>
#include    <sys/starlet.h>
#else
#define	    SS$_NORMAL	    EXIT_SUCCESS
#define	    SS$_BADPARAM    EXIT_FAILURE
#define	    SS$_IVBUFLEN    EXIT_FAILURE
#define	    NO_MEMORY	    4
#endif

#include    <netinet/in.h>
#include    <arpa/inet.h>
#include    <X11/Intrinsic.h>
/*
**====================	Global Definitions =====================================
*/
#include    <sinq_prototypes.h>

#include    "SinqHM_def.h"

#define	    DFLT_PORT	3501
#define	    NIL		'\0'
#define	    NL		'\n'
#define	    MAXARR	4000000
#define	    MAXREC	65563
/*------------------------------------------------------------
**		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 <Ctrl-C> 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:
**	    <preamble>
**	    $		    <== all records prior to this "$" are skipped.
**	    <datagram-0>    <== subsequent records specify datagrams.
**	    <datagram-1>
**	    .
**	    <datagram-n>
**	    End-of-File
**
**	The format of a datagram record is:
**	    <cntr> <Bit-8> <Byte-0> <Byte-1> ... <Byte-n>
**	where
**	    <cntr> is a hex counter (not used - it can be used to label records)
**	    <Bit-8> is the control byte for the datagram header. Set to 0x10
**			to get Bit-8 of the datagram header set to 1.
**	    <Byte-0> specifies Bits 0-7 of the datagram header.
**	    <Byte-1> ... <Byte-n> 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 <file> 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);
	/*        sleep(2);      */
      }
    }
    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 <Ctrl-C> signal handler. You probably\n"
	      "    will not be able to stop by hitting <Ctrl-C>!\n");
    }else {
      printf ("    Hit <Ctrl-C> 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 <Ctrl-C> signal handler. You probably\n"
	      "    will not be able to stop by hitting <Ctrl-C>!\n");
    }else {
      printf ("    Hit <Ctrl-C> 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 <Ctrl-C> signal handler. You probably\n"
	      "    will not be able to stop by hitting <Ctrl-C>!\n");
    }else {
      printf ("    Hit <Ctrl-C> 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 <Return>, 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)
						**	<max-chan-0>
						**	<max-chan-1>
						**	...
						*/
	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>
						**	<min-wire>
						**	<max-wire>
						**	<max-cnt-per-wire>
						**	...
						*/
	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)
						  **  <hi-cntr>  (dflt=127)
						  **  <hi-time>  (dflt=0xfffff)
						  **  <lo-cntr>  (dflt=0)
						  **  <lo-time>  (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 <b1> ...   - Send Extended Time Stamp Info (0x0e + 9 bytes)\n"
	"\n"
	"    FE          - Send FIFO-Empty (0x1e, 0, 0, 0)\n"
	"\n"
	"    FILE <file> <#-cycles>   - Send file to LWL <#-cycles> times.\n"
	"\n"
	"    HM <#-events> <#chans> <max-chan-0> <max-chan-1> ...  - generate\n"
	"                                 data flow in \"Histogram\" Mode.\n"
	"\n"
	"    HM/S <#-events> <#chans> <max-chan-0> ...  - same as HM only"
							    " silent.\n"
	"\n"
	"    HRPT <#-events> <min-wire> <max-wire> <max-cnt-per-wire> ...  "
						"- generate\n"
	"                                 data flow in \"HRPT\" Mode.\n"
	"\n"
	"    HRPT/S <#-events> <min-wire> <max-wire> ...  - same as HRPT only"
							    " silent.\n"
	"\n"
	"    TOF <#-events> <hi-cntr> <hi-time> <lo-cntr> <lo-time> "
						"- generate\n"
	"                                 data flow in \"TOF\" Mode.\n"
	"\n"
	"    TOF/S <#-events> <hi-cntr> <hi-time> ...    - same as TOF only"
							    " silent.\n"
	"\n"
	"    MISC <b0> ...    - Send miscellaneous datagram (up to 10 bytes)\n"
	"                       \"<b0> ...\" are in hex, without \"0x\" prefix.\n"
	"\n"
	"    TS <b1> ...      - Send Time Stamp (0x1f + 5 bytes)\n"
	"\n"
	"    HELP or ?   - generate this help text.\n"
	"\n"
	" To run the program:\n"
	"      lwl_client [-host] <host> [-port <port>] [-size <size>]\n"
	"\n"
	"      Default for <port> = 3501\n"
	"      Default for <size> = 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 ======*/
