#!/usr/bin/perl -w
#---------#---------#---------#---------#---------#---------#---------#---------
#
# Date:         18 Oct 00
# Title:        copy a file to many hosts using Net::FTP
# Creator:      larg
# Description:
#   The script takes a file name with its path.
#   it logs into each  host in turn.
#   If the remote path does not exist, it is created.
# Modifications:
#
#---------#---------#---------#---------#---------#---------#---------#---------

# hosts and accounts
   my %hosts      = (
      "ics01"  => "10.216.4.28",
      "ics02"  => "10.216.4.53",
      "lcs03"  => "10.216.4.34",
      "lds04"  => "10.216.4.60"
                 );                               #


   my $username01 = "user";       # account is common to all  hosts
   my $password01 = "pass";

# why roll your own sockets when you can use a rolling machine?
   use Net::FTP;
   my $ftp;

# status message indent system
# prints details of its progress to STDOUT
   my $indent = '   ';
   my $spaces = 0;

# command line options (using a perl standard library)
        use Getopt::Long;
# options (values are inserted into the variables $opt_...)
# debug -  the ftp session transcript is printed to STDERR
# source - the file to put and where it is
# dest - where it goes on the remote hosts

        $opt_debug = undef;
        GetOptions( "debug!", "source=s", "dest=s" );
        unless (defined $opt_source and defined $opt_dest ) {
                print "usage: \n   $0 [--debug] --source <path/file.name> --dest <path/[file.name]> \n";
                print "NOTE: \n";
                print "If no trailing slash is included in the destination path, \n";
                print "the last element is assumed to be a FILENAME. \n";
                exit 1;
        }

# files and directories (another perl standard library)
        use File::Basename;

        my $local_file   = basename( "$opt_source", '');
        my $local_dir    = dirname( "$opt_source");

# if the destination ends in a /, assume no filename was supplied.
# otherwise, path and filename was given
        my ($remote_file, $remote_dir);
        if ( substr( $opt_dest, -1, 1) eq '/') {

                $remote_file  = $local_file;
                $remote_dir   = $opt_dest; # trailing slash doesn't seem to matter
        } else {
                $remote_file  = basename( "$opt_dest", '');
                $remote_dir   = dirname( "$opt_dest");
        }

#---------#---------#---------#---------#---------#---------#---------#---------
   my $dir_created = 'true';
   my $file_copied = '';
   my $changed_dir = '';

   $spaces++;
   foreach $host ( keys %hosts ) {

      # status message
      print $indent x $spaces . "logging into $hosts{$host} ... \n";

      chdir "$local_dir" or die "can't cd to $local_dir: $!";
      $ftp = Net::FTP->new(
               "$hosts{$host}",
               Debug => $opt_debug ? 1 : 0
      );
      $ftp->login("$username01", "$password01");

      # status message
      print $indent x $spaces . "copying from file $local_file to file $remote_file ... ";

# If the directory does not exist, we must create it.
      # returns an empty string or TRUE
      $changed_dir = $ftp->cwd("$remote_dir");
      unless ( $changed_dir ) {
         $dir_created = $ftp->mkdir("$remote_dir", "recurse");
         $changed_dir = $ftp->cwd("$remote_dir");
      }
      if ($dir_created) {
# get: copy files from remote to local host
#         $ftp->type('binary'); # can be ascii, binary, ebcdic or byte
         $file_copied = $ftp->put( "$local_file", "$remote_file" );
#         $ftp->type('ascii'); # can be ascii, binary, ebcdic or byte
      }

# report the result
      if ( $file_copied  ) {
         print " \n";
      } else {
         print "failed! \n";
      }
      $ftp->quit;
   }
   $spaces--;
   print "done. \n";

