#!/usr/bin/perl
#
#NAME
#  rsdir - rsync directories on a list of mirror hosts
#  rsdrl - rsync directories on a list of mirror hosts and relink files
#
#SYNOPSIS
#  rsdir dir...
#  rsdrl dir...
#
#WARNING
#  This MUST be run from $HOME!  (Unless $base is changed below.)
#
#DESCRIPTION
#  This is how I synchronize my files with a number of machines  that
#  I use as mirrors.
#
#  This program uses rsync to synchronize  the  list  of  directories
#  with the corresponding directories on several other machines.
#
#SETUP
#  The following things are hard-coded into this script:
#
#  The list of mirror hosts:
	@hosts =  qw( trillian.mit.edu );
#	@hosts =  qw( jc.tzo.net trillian.mit.edu lochaber.tullochgorm.com );
#	@hosts =  qw( kendy trill loch );
#
#  The transport protocol is also fixed:
	$ENV{'RSYNC_RSH'} = 'ssh';
#
# Here is the base path on remote systems:
	$base = '';	# Null for home directory
#
#OPTIONS
#
#EXAMPLES
#
#FILES
#
#BUGS
#  While the local directories will be rsync'd with  each  host,  the
#  remote hosts will not necessarily be rsync'd with each other. This
#  is order dependent:  host1's files will end up  on  with  all  the
#  hosts  (including  the  local  host).   But  host2's  files  won't
#  necessarily be on host1. To ensure completion, repeat the command.
#
#SEE ALSO
#
#AUTHOR
#  John Chambers <jc@trillian.mit.edu>
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

$| = 1;	# Don't buffer stdio
($P = $0) =~ s".*/"";
$V = $ENV{"V_$P"} || 2;

$home = $ENV{'HOME'} || ".";
$rlflag = ($P eq 'rsdrl');	# Whether to relink after rsync
#rsOpts = 'CHvurptz';		# rsync options (minya)
#rsOpts = 'Cabvuz';			# rsync options (kendy)
$rsOpts = 'CHlprtuvz';		# rsync options
$cleanflag = 0;				# Whether to do a cleanup first
#print "Password:$pswd\n" if $V>5;

for $dir (@ARGV) {
	print "\n";
	print "==== $dir/\n";
#	$XF = "$dir/.rsExclude";
	if      (-f ($XF = "$dir/.rsExclude")) {
		$Xopt = "--exclude-from=$XF"
	} elsif (-f ($XF = ".rsExclude")) {
		$Xopt = "--exclude-from=$XF"
	} elsif (-f ($XF = "$home/.rsExclude")) {
		$Xopt = "--exclude-from=$XF"
	} else {
		$Xopt = '';
	}
	for $hst (@hosts) {	# Load new files into local file system
		print "<=== $hst\n";
		$frcmd = "rsync -$rsOpts $Xopt $hst:$base$dir/ $dir/";
		print "     $frcmd\n";
		system $frcmd;
	}
	for $hst (@hosts) {	# Sync remote file systems to ours
		print "===> $hst\n";
		$tocmd = "rsync -$rsOpts $Xopt $dir/ $hst:$base$dir/";
		print "     $tocmd\n";
		system $tocmd;
	}
	if ($rlflag) {	# Are we starting a relink?
		$rlcmd = "relink +rv $dir";
		$rllog = "$dir/relink.log";
		unlink($rllog) if -f $rllog;
		print "	$rlcmd\n" if $V>1;
		system "$rlcmd >$rllog 2>&1 &";
	}
}
