#!/usr/bin/perl
# Written by Anthony D. Joseph (adj@eecs.berkeley.edu)
# August 25, 2002

require "getopts.pl";
&Getopts("tgf:u:r:l:n:"); # t for test, f <file> for file containing file list,
                          # r <remote dir>, l <local dir>, u for <user login>, 
                          # n <file> for node file,
                          # g for get files instead of put

# ($#ARGV == 0) || &usage;
# $source = $ARGV[0];

#
# Initialize
#
$NodeCount = 0;
if ($opt_t) {  # Testing only!
    $NodeCmd = "cat";
    $NodeCmdOpt = "";
    $CopyCmd = "echo";
    $Login = "";
    $NodeListHost = "";
    $ListCmd = "C:\\bin\\test.txt";
} else {
    if ($opt_u) {
	$Login = "$opt_u@";
    } else {
	$Login = "";
    }
    $CopyCmd = "scp";

    if ($opt_n) { # Read node list
	$NodeCmd = "cat";
	$NodeCmdOpt = "";
	$NodeListHost = "";
	$ListCmd = $opt_n;
    } else {
	$NodeCmd = "ssh";
	$NodeCmdOpt = "-q";
	$NodeListHost = "bogle.ext.postel.org";
	$ListCmd = "cat /etc/ROOTSTOCK/tmp/data/nodes.txt";
    }
}

die &usage if (!$opt_f);
$Files = $opt_f;
if ($opt_r) {
    $RemoteDir = $opt_r;
} else {
    $RemoteDir = ".";
}
if ($opt_l) {
    $LocalDir = $opt_l;
} else {
    $LocalDir = ".";
}

print "Node Command: $NodeCmd $NodeCmdOpt\n";
print "Login: $Login\n";
print "Node List Host: $NodeListHost\n";
print "List Command: $ListCmd\n";
print "File Set: $Files\n";
print "Remote Directory: $RemoteDir\n";
print "Local Directory: $LocalDir\n";

$FileList = "";

sub usage {
    die("Usage: 
plfiles.pl [-t] [-u <userid>] [-r <dir>] [-l <dir>] [-n <nlist>] -f <flist> ");
}

sub getNodesList {
#    my $line = shift(@_);

    # Get the list of nodes
    if ($opt_t || $opt_n) {
	open (NODES, '<', "$ListCmd") 
	    or die "Can't open node list, $ListCmd: $!";
    } else {
	open (NODES, '-|',
	      "$NodeCmd $NodeCmdOpt $Login $NodeListHost $ListCmd") 
	    or die "Can't execute node list fetch cmd, $NodeCmd $ListCmd: $!";
    }
    while (<NODES>) {              # note use of indirection
        $curline = $_;
        chop($curline);				# Discard \n

	if ($curline =~ /Authentication successful./) { # Skip first line
	    next;
	} elsif (length($curline) == 0) { # Skip blank
	    next;
	} elsif ($curline =~ /warning:/) { # Error
	    die "Error retrieving node list: $curline";
	} 
	$Nodes[$NodeCount++] = $curline;
    }
    close NODES;
    die "No nodes found" if ($NodeCount == 0);
}

sub loadFileList {
    # Get the list of files
    $first = 1;

    open (FILES, '<', "$Files") 
	or die "Can't open file list, $Files: $!";
    while (<FILES>) {              # note use of indirection
        $curline = $_;
        chop($curline);				# Discard \n

	if ($curline =~ /#/) { # Skip comment lines
	    next;
	} elsif (length($curline) == 0) { # Skip blank
	    next;
	} 
	if ($first == 1) {
	    $first = 0;
	    $FileList = $curline;
	} else {
	    $FileList .= ("," . $curline);
	}
    }
    close FILES;
}


&getNodesList();
print "Found $NodeCount nodes:\n";
for $i (0 .. $NodeCount - 1) {
    print "$Nodes[$i]\n";
}

#&loadFileList();
print "Sending files: $FileList\n";

for $i (0 .. $NodeCount - 1) {
    $FileCmd = "\"{" . $Files . "}\"";
    $RemoteCmd = $Login . $Nodes[$i] . ":" . $RemoteDir;
    if ($opt_g) {
	print "Getting files from $Nodes[$i]\n";
	@args = ($CopyCmd, $RemoteCmd . "/" . $FileCmd, 
		 $LocalDir . "/" . $Nodes[$i]);
    } else {
	print "Sending files to $Nodes[$i]\n";
	@args = ($CopyCmd, $LocalDir . "/" . $Files, $RemoteCmd);
    }

    system(@args);
    $exit_value  = $? >> 8;
    if ($exit_value != 0) {
	$signal_num  = $? & 127;
	$dumped_core = $? & 128;
	print "ERROR for $Nodes[$i]: $exit_value, signal: $signal_num, core: $dumped_core\n";
    }
}

