#!/usr/local/bin/perl

# Reflect: This a Perl script to mirror (reflect) all the files in one 
# directory hierarchy to another.
#
# Usage: reflect <source> <destination>
#

# Written by Rick Niles.
# Version 1.0
# 6/21/95.
# Protected under the GPL.

print "Welcome to reflect\n by Rick Niles.\n\n";
# Set default options....
$do_deletes = 0;
$gzip_files = 1;
$debug = 0;

# Strip switches.
while ($ARGV[0] =~ /^-/)
{
    push(@options, shift);
}
foreach $i (0...$#options)
{
    $cmd = substr($options[$i],1);
    eval "\$$cmd = 1";
    print "$cmd option set.\n";
}

# Grab Input arguments...
$source = shift;
$dest = shift;
$src_len  = length($source);
$dest_len = length($dest);

# Create Destination if in doesn't exist...
if(!( -e $dest))
{
    print "Creating new directory $dest.\n";
    system("mkdir $dest");
}

# Do the UNIX find command...
open(find1, "find $source -print |");
open(find2, "find $dest   -print |");
@src_files  = <find1>;
@dest_files = <find2>;

# Clean up names...
chop @src_files;
chop @dest_files;

# Remove any gz-extension from both lists.
@src_files  = &RMGZ(@src_files);
@dest_files = &RMGZ(@dest_files);

# Remove the seach directory name from the list
#    returns files...
grep(($_ = substr($_,($src_len+1))), @src_files);
grep(($_ = substr($_,($dest_len+1))), @dest_files);
#print "@src_files\n"; # for debugging only...
#print "@dest_files\n";

# Compute old files...
local(%mark);
grep($mark{$_}++,@src_files);
@old = grep(!$mark{$_},@dest_files);

# Compute new files...
local(%mark);
grep($mark{$_}++,@dest_files);
@new = grep(!$mark{$_},@src_files);
@both = grep($mark{$_},@src_files);

@old_files = grep(-f "$dest/$_" | -f "$dest/$_.gz" ,@old);
@old_dirs  = grep(-d "$dest/$_"  ,@old);
@new_files = grep(-f "$source/$_" | -f "$source/$_.gz",@new);
@new_dirs  = grep(-d "$source/$_",@new);
@both_files  = grep(-f "$source/$_" | -f "$source/$_.gz",@both);

## Print stuff for debugging...
if ($debug)
{
    print "New: @new\n";
    print "Old: @old\n";
    print "Both: @both\n";
    print "New Files: @new_files\n";
    print "Old files: @old_files\n";
    print "New dirs: @new_dirs\n";
    print "Old dirs: @old_dirs\n";
}

# Check Common files for updates...
print "\nChecking for modified files...";
$mods = 0;
foreach $i (0...$#both_files)
{
    $name = $both_files[$i];
    $sname ="$source/$name";
    $sname = join('', $sname,'.gz') if(!(-e $sname) );
    $dname ="$dest/$name";
    $dname = join('', $dname,'.gz') if(!(-e $dname) );
    print "testing: $name $sname $dname\n" if ($debug);
    if( -M $sname < -M $dname )
    {
	if($name)		# Assure $name is not empty...
	{
	    if(!$mods)
	    {
		print "\n";
		$mods = 1;
	    }
	    &PRSYS("rm -f $dname");
	    &PRSYS("cp $sname $dest/$name");
	    &PRSYS("gzip -q $dest/$name") if($gzip_files);
        }
    }
}

if(!$mods)
{
    print "none.\n";
}

#Create New directories...
if(($#new_dirs+1))
{
    print "\nCreating new directories...\n";
    foreach $i (0...$#new_dirs)
    {
	$name = $new_dirs[$i];
	if($name)			# Assure $name is not empty...
	{
	    &PRSYS("mkdir $dest/$name");
	}	        
    }
}			       

#Copying new files...
if(($#new_files+1))
{
    print "\nCopying new files...\n";
    foreach $i (0...$#new_files)
    {
	$name = $new_files[$i];
	$sname ="$source/$name";
	$dname ="$dest/$name";
	if(!(-e $sname) )
	{
	    $sname = join('', $sname,'.gz');
	    $dname = join('', $dname,'.gz');
	}
	if($name)			# Assure $name is not empty...
	{
	    &PRSYS("cp $sname $dname");
	    &PRSYS("gzip $dname") if($gzip_files & !grep(/\.gz/,$dname));
	}
    }
}

#### unlink section ########
if($do_deletes)
{

# Unlink files...
    if(($#old_files+1))
    {
	print "\nUnlinking old files...\n";
	foreach $i (0...$#old_files)
	{
	    $name = $old_files[$i];
	    if($name)		# Assure $name is not empty...
	    {
		$dname ="$dest/$name";
		$dname = join('', $dname,'.gz') if(!(-e $dname) );
		&PRSYS("rm $dname");
	    }
	}
}

# Remove old directories....
    if(($#old_dirs+1))
    {
	print "\nRemoving old directories...\n";
	foreach $i (0...$#old_dirs)
	{
	    $name = $old_dirs[$i];
	    if($name)			# Assure $name is not empty...
	    {
		&PRSYS("rmdir $dest/$name");
	    }
	}
    }
}


sub PRSYS
{
## Simple Subroutine to print command to screen and excute it.
    local($string) = @_;
    print "$string\n";
    system($string);
}

sub RMGZ
{
### Subroutine to remove .gz extension from
###   a LIST.
    local(@input) = @_;

    local(@gz)  = grep( /\.gz/,@input);
    local(@ugz) = grep(!/\.gz/,@input);

    local(@new);

    foreach $i (0...$#gz)
    {
        local($len) = length(@gz[$i]);
        @new[$i] = substr(@gz[$i],0,$len-3);
    }

    local(@both) = (@new, @ugz);
}
