/*  HeartBeat.c	13-Aug-01  7:17:04 by ???

    Continuously monitor the operation of a ScanVue unit.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

#ifdef	WIN32
#undef	WIN32
#define	WIN32	1
#endif

#ifdef	VMS
#undef	VMS
#define	VMS	1
#endif


#if	WIN32
#include <fcntl.h>
#include <io.h>
#include <conio.h>
#include <ctype.h>

typedef unsigned long   ulong;
typedef unsigned int	uint;
typedef unsigned char	uchar;

#elif	VMS
#include <in.h>
#include <inet.h>
#include <netdb.h>
#include <types.h>
#include <socket.h>
#include <tcp.h>
#include <unixio.h>
#include <ucx$inetdef.h>
#include <iodef.h>
#include <unixlib.h>
#else
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <ctype.h>
#endif

#ifdef	GCC
typedef unsigned long   ulong;
typedef unsigned char	uchar;
#define	Sleep(t)    sleep(t)
#endif

#define  BUFFER_SIZE 2048

/* Include Windows specific include files */
#ifdef WIN32
#include <windows.h>
#include <winsock.h>
#else
typedef int BOOL;
#endif


#ifndef	TRUE
#define	TRUE (1==1)
#define	FALSE (1==0)
#endif

#define TKNAME(a,b,c,d) (((d)<<24)|((c)<<16)|((b)<<8)|(a))
#include "sloppidef.h"

#define connectPort	1283

int	tcpSocket=0;
int	NumberOfModes;

typedef	struct
  {
    char    Name[50];
    char    Type[20];
    char    Help[512];
    int	    Size;
    char    NVRamContent[200];
    char    CurrentContent[200];
    char    iniContent[200];
    BOOL    New;
  } MODE;

char	    remoteHost[ 255 ];

#if WIN32
#define	CloseSocket(s)	closesocket(s)
#else
#define	CloseSocket(s)	close(s)
#endif

void DisplayHelpAndExit( void )
  {
    fputs( "\nHeartBeat [-Ds] IPAddress\n", stderr );
    fputs( "  -D delay s seconds between checks\n", stderr );
    exit( EXIT_SUCCESS );
  }


void SendPacket( SLPACKET *pkt, char *ModeName )
  {
    int	total  = 0;
    int length = 0;
    int sent   = 0;

    memset( pkt ,0, BUFFER_SIZE );

    total		= sizeof( pkt->header ) + strlen( ModeName ) + 1;
    pkt->header.token	= SLT_MODESETQUERY;
    pkt->header.length	= htonl( total);

    if( *ModeName )
	strcpy( pkt->body.modesetquery.modesetquery, ModeName );

    while( total  !=  sent )
      {
	length	= send( tcpSocket, (const char *)(pkt + sent), total - sent, 0 );
	if( length  <  0 )
	  {
	    printf( "\nError sending..\n");
	    return;
	  }
	sent += length;
      }
  }


void RecvPacket( SLPACKET *pkt )
  {
    int	    length  = 0;
    int	    total   = 0;
    char   *p;

    length  = recv( tcpSocket, (char *)pkt, 4, 0 );
    total   = ntohl( pkt->header.length ) - sizeof pkt->header.length;
    p	    = (char *)&pkt->header.token;

    while ( total  >  0 )
      {
	length	= recv( tcpSocket, p, total, 0 );
	if ( length  <=  0 )
	    continue;
	total	-= length;
	p	+= length;
      }
  }


int main( int argc, char *argv[] )
  {
    int	    status  = 0;
    int	    i, arg;
    int	    gotHost = FALSE;
    time_t  tmr;
    ulong   c	    = 0;
    uint    delay   = 10;

    SLPACKET	       *pkt;
    struct hostent     *phe;
    struct sockaddr_in  remote_sin;

    arg	= 0;
    for ( arg = 1; --argc; arg++ )
      {
	i   = argv[ arg ][ 0 ];
	if (( i   ==  '-' )  ||  ( i  ==  '/' ))
	  {
	    i	= toupper( argv[ arg ][ 1 ] );
	    if ( i  ==  'D' )
	      {
		i   = atoi( argv[ arg ] + 2 );
		if ( i  <  1 )
		    i	= 1;

		delay	= i;
		printf( "Delay in seconds: %d\n", delay );
	      }
	    else
		DisplayHelpAndExit();
	  }
	else
	  {
	    strncpy( remoteHost, argv[ arg ], sizeof remoteHost );
	    gotHost = TRUE;
	  }
      }
    if ( !gotHost )
	DisplayHelpAndExit();

#ifdef WIN32
    {
      WSADATA	WSAData;
      status	= WSAStartup( MAKEWORD( 2,0 ), &WSAData );
      if ( status )
	{
	  printf( "Requested socket version not supported : %d\n", status );
	  exit( EXIT_FAILURE );
	}
    }
#endif

    tcpSocket	= socket( AF_INET, SOCK_STREAM, 0 );
    if ( tcpSocket  ==  -1 )
      {
	printf( "Error creating socket\n" );
	exit( EXIT_FAILURE );
      }

    phe	= gethostbyname( remoteHost );

    if ( !phe )
      {
	printf( "DNS lookup failed for host: %s\n", remoteHost );
	CloseSocket( tcpSocket );
	exit( EXIT_FAILURE );
      }

    memmove((void *)&remote_sin.sin_addr, phe->h_addr, phe->h_length );

    remote_sin.sin_port	    = htons( connectPort );
    remote_sin.sin_family =  AF_INET;

    pkt	= malloc( BUFFER_SIZE );

    while (TRUE)
      {
	status  = connect( tcpSocket, (struct sockaddr *)&remote_sin,
			   sizeof remote_sin );
	if ( status  ==  -1 )
	  {
	    tmr	= time( NULL );
	    printf( "Error connecting to %s at %s", remoteHost, ctime( &tmr ));
	    c	= 0;			/* Restart the count		    */
	    goto    waiting;
	  }


	SendPacket( pkt, "UnitStatus");
	printf( "%d: ", c++ );
	RecvPacket( pkt );

	printf( "%s", pkt->body.moderesponse.moderesponse );

  waiting:
	fflush( stdout );
	CloseSocket( tcpSocket );
	Sleep( delay * 1000 );

	tcpSocket   = socket( AF_INET, SOCK_STREAM, 0 );
	if( tcpSocket == -1 )
	  {
	    tmr	= time( NULL );
	    printf( "Error creating socket at %s", ctime( &tmr ));
	    goto    waiting;
	  }
      }

    return 0;
  }
