The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!/usr/bin/perl

# $RCSfile: gcp,v $$Revision: 4.1 $$Date: 92/08/07 17:20:15 $

# Here is a script to do global rcps.  See man page.

$#ARGV >= 1 || die "Not enough arguments.\n";

if ($ARGV[0] eq '-r') {
    $rcp = 'rcp -r';
    shift;
} else {
    $rcp = 'rcp';
}
$args = $rcp;
$dest = $ARGV[$#ARGV];

$SIG{'QUIT'} = 'CLEANUP';
$SIG{'INT'} = 'CONT';

while ($arg = shift) {
    if ($arg =~ /^([-a-zA-Z0-9_+]+):/) {
	if ($systype && $systype ne $1) {
	    die "Can't mix system type specifers ($systype vs $1).\n";
	}
	$#ARGV < 0 || $arg !~ /:$/ || die "No source file specified.\n";
	$systype = $1;
	$args .= " $arg";
    } else {
	if ($#ARGV >= 0) {
	    if ($arg =~ /^[\/~]/) {
		$arg =~ /^(.*)\// && ($dir = $1);
	    } else {
		if (!$pwd) {
		    chop($pwd = `pwd`);
		}
		$dir = $pwd;
	    }
	}
	if ($olddir && $dir ne $olddir && $dest =~ /:$/) {
	    $args .= " $dest$olddir; $rcp";
	}
	$olddir = $dir;
	$args .= " $arg";
    }
}

die "No system type specified.\n" unless $systype;

$args =~ s/:$/:$olddir/;

chop($thishost = `hostname`);

$one_of_these = ":$systype:";
if ($systype =~ s/\+/[+]/g) {
    $one_of_these =~ s/\+/:/g;
}
$one_of_these =~ s/-/:-/g;

@ARGV = ();
push(@ARGV,'.grem') if -f '.grem';
push(@ARGV,'.ghosts') if -f '.ghosts';
push(@ARGV,'/etc/ghosts');

$remainder = '';

line: while (<>) {
    s/[ \t]*\n//;
    if (!$_ || /^#/) {
	next line;
    }
    if (/^([a-zA-Z_0-9]+)=(.+)/) {
	$name = $1; $repl = $2;
	$repl =~ s/\+/:/g;
	$repl =~ s/-/:-/g;
	$one_of_these =~ s/:$name:/:$repl:/;
	$repl =~ s/:/:-/g;
	$one_of_these =~ s/:-$name:/:-$repl:/g;
	next line;
    }
    @gh = split(' ');
    $host = $gh[0];
  next line if $host eq $thishost;	# should handle aliases too
    $wanted = 0;
    foreach $class (@gh) {
	$wanted++ if index($one_of_these,":$class:") >= 0;
	$wanted = -9999 if index($one_of_these,":-$class:") >= 0;
    }
    if ($wanted > 0) {
	($cmd = $args) =~ s/[ \t]$systype:/ $host:/g;
	print "$cmd\n";
	$result = `$cmd 2>&1`;
	$remainder .= "$host+" if
	    $result =~ /Connection timed out|Permission denied/;
	print $result;
    }
}

if ($remainder) {
    chop($remainder);
    open(grem,">.grem") || (printf stderr "Can't create .grem: $!\n");
    print grem 'rem=', $remainder, "\n";
    close(grem);
    print 'rem=', $remainder, "\n";
}

sub CLEANUP {
    exit;
}

sub CONT {
    print "Continuing...\n";	# Just ignore the signal that kills rcp
    $remainder .= "$host+";
}