#!/usr/bin/perl

# $Id: spreadframes,v 1.1 1999/07/26 02:28:44 revl Exp revl $

#
# $Log: spreadframes,v $
# Revision 1.1  1999/07/26 02:28:44  revl
# Initial revision
#
# 


# ***************************************************************************
#  Author      : Rev Lebaredian
#  E-Mail      : revl@steamboat-software.com
#  Company     : Steamboat Software
#  Date        : July 24, 1999 
#  Description : Utitlity for executing commands across a network using rsh.
#
#  Copyright (C) 1999 Steamboat Software
#  
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#  
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#  
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#  ***************************************************************************



use Getopt::Long;


# ******************************************************
#    Prototypes
# ******************************************************

sub Execute($$);


# ******************************************************
#    Global Defaults
# ******************************************************

my($RshCmd) = "rsh";

# ******************************************************
#    Global Variables
# ******************************************************

my(%Jobs) = ( );
my(@CommandLines) = ( );
my(@Hosts) = ( );
my($Verbose) = 0;
my($Delay) = 0;



# ******************************************************
#    Parse Args
# ******************************************************

my($Ret) = &GetOptions('verbose', \$Verbose,
                       'delay=i', \$Delay);

while($#ARGV >= 0)
 {
  push @Hosts, (shift @ARGV);
 }


# ******************************************************
#    Parse Args
# ******************************************************

while(<STDIN>)
 {
  push @CommandLines, $_;
 }

# ******************************************************
#    Main Body
# ******************************************************

while($#Hosts >= 0 && $#CommandLines >= 0)
 {
  my($Line) = shift @CommandLines;
  my($Host) = shift @Hosts;
  chop $Line;

  Execute($Line, $Host);
  if($Delay > 0.0)
   {
    sleep($Delay);
   }
 }


my($ID);
while(($ID = wait()) != -1)
 {
  my($Host) = $Jobs{$ID};

  print STDERR "$ID returned from $Host\n";

  delete($Jobs{$ID});


  if($#CommandLines >= 0)
   {
    my($Line) = shift @CommandLines;
    Execute($Line, $Host);
   }
 }

# ******************************************************
#    Functions
# ******************************************************

sub Execute($$)
 {
  my($Line) = $_[0];
  my($Host) = $_[1];

  if($Verbose)
   {
    print STDERR "Executing \"", $Line, "\" on \"$Host\".\n";
   }

  my($ChildID);
  if($ChildID = fork())
    {
     # Parent
     $Jobs{$ChildID} = $Host;
     return($ChildID);
    }
   else
    {
     # Child
     #$SIG{CHLD} = "";
     if($Ret = system("$RshCmd $Host '$Line'"))
       {
        print STDERR "ERROR : Could not execute command \"$Line\" on host \"$Host\".";
       }
      else
       {
        if($Verbose)
         {
          print STDERR "Successfully completed frame \"$Line\" on \"$Host\".\n";
         }
       }
     
     exit $Ret;
    }
 }

