/*
 * *******************************************************************
 * *	                                                             *
 * *     IRIS User Product Insert transmitter example program        *
 * *                                                                 *
 * *******************************************************************
 * File: utils/examples/upi_xmt.C
 *
 *            COPYRIGHT (c) 1997, 1999, 2002, 2003, 2004 BY
 *         SIGMET INCORPORATED, WESTFORD MASSACHUSETTS, U.S.A.
 * 
 * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
 * ONLY  IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
 * INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR  ANY OTHER
 * COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
 * OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
 * TRANSFERED.
 */

#include <errno.h>
#include <locale.h>
#ifndef LINUX
#include <signal.h>
#endif  /* #ifndef LINUX */
#include <stdio.h>
#include <stdlib.h>
#ifdef HPUX
#include <string.h>
#endif  /* #ifdef HPUX */
#include <unistd.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/un.h>

#include "sigtypes.h"
#include "signetwork.h"
#include "user_lib.h"

#define MAX_PACKET_SIZE (90)

/* Function prototypes used just in this file */
static void run_tcpip
( const struct command_line *pCommand_a );

static void ProcessCommandLine
( struct command_line *pCommand_a,
  int iArgc_a,
  char **sArgv_a );

static void upi_xmt_sigio_handler
( int signal_a );

/* Shared variables */
struct command_line
{
  char sDirectory[DIRECTORY_SIZE];
  char sHost[MAXHOSTNAMELEN];
  unsigned int iPort;
};

static int socket_c;
static struct command_line Command_c;
/* =====================================================
 * This is an example program showing how to send files to IRIS.
 * This program prompt for a file (or path) name, then sends it to IRIS.
 * It uses RCP to copy the file.
 *
 */
int main( int iArgc_a, char** sArgv_a )
{
  UINT4 iConnectStat;

  /* ------------------------------------------------------------------- */

  setlocale( LC_ALL, "" );

  ProcessCommandLine( &Command_c, iArgc_a, sArgv_a );

  iConnectStat = SIG_CONNECT_OK;
  socket_c = SocketConnectNoBlock( AF_INET, Command_c.sHost, Command_c.iPort,
				   upi_xmt_sigio_handler, &iConnectStat );
  if (socket_c == -1) exit(EXIT_FAILURE);

  run_tcpip( &Command_c );

  exit(EXIT_SUCCESS) ;
}

/* ===========================================
 * Run a loop sending products to the specified machine 
 */
static void run_tcpip
( const struct command_line *pCommand_a )
{
  char sline[80], smessage[100], starget_path[PATHNAME_SIZE], starget_filename[80], *sfile;
  char scommand[240];
  int ilength, ierror, isend_count, lcopy_ok, iexit_status, last_fgets_was_interrupted;

  isend_count = 0;
  last_fgets_was_interrupted = FALSE;
  while (TRUE)
    {
      if (!last_fgets_was_interrupted) printf( "Please enter file to transfer: " );
      sfile = fgets( sline, 80, stdin );
      if (NULL == sfile)
	{
	  last_fgets_was_interrupted = TRUE;
	  continue;
	}
      last_fgets_was_interrupted = FALSE;

      /* Trim trailing carriage return from file name */
      ilength = strlen(sfile)-1;
      if (ilength == 0) continue;
      sfile[ilength] = 0;

      sprintf( starget_filename, "upi_xmt%4.4d", isend_count++ );
      strcpy( starget_path, pCommand_a->sDirectory );
      strcat( starget_path, starget_filename );
      sprintf( scommand, "rcp %s 'operator@%s:%s'", sfile, pCommand_a->sHost, starget_path ) ;
      ierror = system( scommand );
      
      lcopy_ok = FALSE;
      if (ierror == -1) 
	{
	  perror( "system" );
	}
      else
	{
	  if (WIFEXITED(ierror)) 
	    {
	      iexit_status = WEXITSTATUS(ierror);
	      if (iexit_status)
		printf( "Error with RCP call, exit status: %d.\n", iexit_status );
	      else
		lcopy_ok = TRUE;
	    }
	  else
	    printf( "Error with RCP call.\n" );
	}

      /* Notify the other end of the file */
      if (lcopy_ok)
	{
	  strcpy( smessage, "FILE " );
	  strcat( smessage, starget_filename );
	  ilength = strlen(smessage);
	  ierror = send( socket_c, smessage, ilength+1, 0 );
	  if (ierror == -1) perror( "send" );
	}

    }
  
  return;

}
/* ================================================================
 * Signal handler for SIGIO signal.  It just does a read, and processes
 * the result.
 */
static void upi_xmt_sigio_handler( int signal_a )
{
  char data[100];
  int isize;

  isize = recv( socket_c, data, 99, 0 );
  if (isize > 0)
    {
      /* We got some valid data here.  Add terminating NULL, then process */
      data[isize] = 0;
      if (0 == strcmp( data, "NOP" ))
	{

	}
      else if (0 == strcmp( data, "EXIT" ))
	{
	  printf( "Got 'EXIT' message.\n" );
	  exit(EXIT_SUCCESS);
	}
      else
	{
	  sig_signal_va( USER_NETPACKET_COMMAND, 1, data );
	}
    }

  else if (isize < 0)
    {
      /* We an error here, signal all errors except EWOULDBLOCK */
      if (errno != EWOULDBLOCK)
	{
	  perror( "recv" );
	  exit(EXIT_FAILURE);
	}
    }

  else
    {
      /* Zero size indicates that the socket has been closed at the other end */
      printf( "Link broken\n" );
      exit(EXIT_SUCCESS);
    }
  return;

}
/* ==================================
 * Process the command line.
 */
static void ProcessCommandLine
( struct command_line *pCommand_a,
  int iArgc_a,
  char **sArgv_a )
{
  int iArg, ierror;
  char *sptr;

  /* Initialize to default values */
  memset( pCommand_a, 0, sizeof(*pCommand_a) );

  pCommand_a->iPort  = PORT_NETWORK_RECEIVER;
  ierror = gethostname( pCommand_a->sHost, MAXHOSTNAMELEN );
  if (ierror < 0)
    {
      perror( "gethostname" );
      exit(EXIT_FAILURE);
    }
  strcpy( pCommand_a->sDirectory, "/usr/iris_data/product/" );
  
  for (iArg=1; iArg<iArgc_a; iArg++)
    {
      char *sArg=sArgv_a[iArg];
      if ( 0 == strcmp( sArg, "-h" ) )
	{
	  printf( "Command line options:\n" );
	  printf( "  -d dddd : specify the directory to write to\n" );
	  printf( "  -h      : help\n" );
	  printf( "  -n hhhh : specify host name to send to (defaults to localhost)\n" );
	  printf( "  -p pppp : specify port number (default %d)\n", PORT_NETWORK_RECEIVER );
	  exit(EXIT_SUCCESS);
	}
      else if ( 0 == strcmp( sArg, "-d" ) )
	{
	  iArg++;
	  if (iArg<iArgc_a)
	    {
	      int iLength;
	      /* Process the directory name */
	      strncpy( pCommand_a->sDirectory, sArgv_a[iArg], DIRECTORY_SIZE-2 );
	      pCommand_a->sDirectory[DIRECTORY_SIZE-2] = 0;

	      /* Make sure search directory has a trailing "/" */
	      iLength = strlen(pCommand_a->sDirectory);
	      if (pCommand_a->sDirectory[iLength-1]!= '/')
		{
		  pCommand_a->sDirectory[iLength] = '/';
		  pCommand_a->sDirectory[iLength+1] = 0;
		}
	    }
	  else
	    {
	      printf( "Missing directory name after '-d'\n" );
	      exit(EXIT_FAILURE);
	    }
	}
      else if ( 0 == strcmp( sArg, "-n" ) )
	{
	  iArg++;
	  if (iArg<iArgc_a)
	    {
	      /* Process the host name */
	      strncpy( pCommand_a->sHost, sArgv_a[iArg], MAXHOSTNAMELEN-1 );
	      pCommand_a->sHost[MAXHOSTNAMELEN-1] = 0;
	    }
	  else
	    {
	      printf( "Missing host name after '-n'\n" );
	      exit(EXIT_FAILURE);
	    }
	}
      else if ( 0 == strcmp( sArg, "-p" ) )
	{
	  iArg++;
	  if (iArg<iArgc_a)
	    {
	      /* Process the port number */
	      pCommand_a->iPort = strtol( sArgv_a[iArg], &sptr, 10 );
	      if ((pCommand_a->iPort<MIN_USER_PORT) || (pCommand_a->iPort>65535))
		{
		  printf( "Port number %d invalid.\n", pCommand_a->iPort );
		  exit(EXIT_FAILURE);
		}
	    }
	  else
	    {
	      printf( "Missing port number after '-p'\n" );
	      exit(EXIT_FAILURE);
	    }
	}
      else
	{
	  printf( "Unrecognized command line argument '%s'\n", sArgv_a[iArg] );
	  exit(EXIT_FAILURE);
	}
    }
}
