/* **********************************************************
 * *                                                        *
 * *  read and write remote files.                          *
 * *  run remote execuatables                               *
 * *                                                        *
 * **********************************************************
 * File: libs/config/sigrfopen.c
 *
 *        COPYRIGHT (c) 1987, 1989, 1990, 1993, 1996, 1997, 1998,
 *                       2000, 2001, 2002  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.
 *
 *  This program has 2 purposes:
 *    1. Read and write remote files
 *    2. Run remote executables 
 *
 *  If we are reading or writing remote files.
 *    argc must = 4;
 *    args[1] = hostname.
 *    args[2] = path.  Can also use iris env var like ${IRIS_CONFIG}AGC1.DAT
 *    args[3] = r or w. for read and write
 *
 *  If we are do remote  executing then args[2] must be -c
 *    argc must be  (argc >= 4) && (argc <= 6)
 *    args[1] = hostname.
 *    args[2] = -c.  -c means command
 *    args[3] =  exe. Can also use iris env var like ${IRIS_BIN}zauto
 *    args[4] = options to the remote executable
 *    args[.] = 
 *    args[x] =  
 *
 *    Lib fuction sigrfopen will be the only one that ever calls
 *    this exe.
 *    fp = sigrfopen("hail", "${IRIS_CONFIG}AGC1.DAT" "r");
 *    fp = sigrfopen("hail", "${IRIS_CONFIG}AGC1.DAT" "w");
 *    when done read or writing call lib function
 *    sigrclose(fp);
 *
 *    Lib fuction sigrfopen will be the only on that ever calls
 *    this exe.
 *    fp = sigrcmd("hail", "ls -als");
 *    when done read or writing call lib function
 *    sigrclose(fp);
 */

#include <stdio.h>
#include <stdlib.h>
#include <rpc/rpc.h>
#include <netdb.h>
#include <pwd.h>
#include <unistd.h>

#include "sigtypes.h"
#define BUF_SIZE 4000

static    struct servent *servent;
static    struct passwd *pwd;
static    char   ruser[40];
static    char   cmd[200];
static    int    fd;
static    int    in_size;
static    char   buf[BUF_SIZE];
static    FILE   *fp;
static    FILE   *fp_gzip;
static    const char   *shell_str = " . ./.profile 1>&- 2>&- ; ";


static void remoteFileOpenRead(char *hostname_a, const char *path_filename_a)
{
   sprintf(cmd, "%s gzip -c %s", shell_str, path_filename_a);
   fd = rcmd(&hostname_a, servent->s_port, pwd->pw_name, ruser, cmd, NULL);

   if (fd < 0)
      exit(EXIT_FAILURE);

   fp = fdopen(fd, "r");
   fp_gzip = popen("gunzip -c 2>&-", "w");
   if (NULL != fp_gzip)
   {
      while(1)
      {
         in_size = fread(buf, sizeof(char), BUF_SIZE, fp);
         if (in_size <= 0)
            break;
         fwrite(buf, sizeof(char), in_size, fp_gzip);
      }
      pclose(fp_gzip); 
   }
   fclose(fp);
}

static void remoteFileOpenWrite(char *hostname_a, const char *path_filename_a)
{
   const char *temp_file = "/tmp/iris_remcmd_$$";

   sprintf(cmd, "gunzip -c > %s ; %s  mv %s %s", 
      temp_file, shell_str, temp_file, path_filename_a);
   fd = rcmd(&hostname_a, servent->s_port, pwd->pw_name, ruser, cmd, NULL);

   if (fd < 0)
      exit(EXIT_FAILURE);

   fp = fdopen(fd, "w");
   fp_gzip = popen("gzip -c 2>&-", "r");
   if (NULL != fp_gzip)
   {
      while(1)
      {
         in_size = fread(buf, sizeof(char), BUF_SIZE, fp_gzip);
         if (in_size <= 0)
            break;
         fwrite(buf, sizeof(char), in_size, fp);
      }
      pclose(fp_gzip); 
   }
   fclose(fp);
}

static void remoteCmd(char *hostname_a, const char *path_filename_a)
{
   sprintf(cmd, "%s %s ", shell_str, path_filename_a);
   fd = rcmd(&hostname_a, servent->s_port, pwd->pw_name, ruser, cmd, NULL);

   if (fd < 0)
      exit(EXIT_FAILURE);

   fp = fdopen(fd, "r");
   while(1)
   {
      in_size = fread(buf, sizeof(char), BUF_SIZE, fp);
      if (in_size <= 0)
         break;
      fwrite(buf, sizeof(char), in_size, stdout);
   }
   fclose(fp);
}

int main(int argc, char *argv[])
{
   if (argc >= 4)
   {
      char hostname[40];
      char path_filename[PATHNAME_SIZE];

      servent = getservbyname("shell", "tcp");
      pwd = getpwuid(getuid());
      strcpy (ruser, pwd->pw_name);

      strcpy(hostname, argv[1]);
      /****************************** 
      * Checking for remote command
      ******************************/
      if (!strcmp(argv[2], "-c"))
      {
         int ii;

         path_filename[0] = '\0';
         for (ii = 3; ii < argc; ii++)
         {
            strcat(path_filename, argv[ii]);
            strcat(path_filename, " ");
         }
         remoteCmd(hostname, path_filename);
      }
      /****************************** 
      * Must be doing a remote file  
      * read or write
      ******************************/
      else if (argc == 4)
      {
         strcpy(path_filename, argv[2]);

         if      (!strcmp(argv[3], "r"))
            remoteFileOpenRead(hostname, path_filename);
         else if (!strcmp(argv[3], "w"))
            remoteFileOpenWrite(hostname, path_filename);
         else
         {
            printf("FAILED\n");
            exit(EXIT_FAILURE);
         }
      }
      else
         exit(EXIT_FAILURE);
   }
   else
      exit(EXIT_FAILURE);

   exit(EXIT_SUCCESS);
}
