#!/usr/local/bin/perl

sub attr {
    ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
     $atime,$mtime,$ctime,$blksize,$blocks) = lstat $path;

    $mode = sprintf ("%04o", $mode & 07777);
    ($major, $minor) = $rdev ? $rdev > 0xFFFF ?
	($rdev >> 18, $rdev & 0x3FFFF) : ($rdev >> 8, $rdev & 0xFF) : ();

	-l _ ? "=>".readlink $path :
	-d _ ? "=d$mode $uid.$gid" : 
	-f _ ? "=f$mode $uid.$gid $mtime $size" :
	-c _ ? "=c$mode $uid.$gid $major,$minor" :
	-b _ ? "=b$mode $uid.$gid $major,$minor" :
	-p _ ? "=p$mode $uid.$gid" : 
	-s _ ? "=s$mode $uid.$gid" : "";
}

sub find {
    local($_)=local($path)=@_; local($attr)=&attr||return;

    if (-f _ && $expire && $hugefilethreshold && -s _ > $hugefilethreshold) {
	unlink $lasthugefile
	    if $lasthugefile =~ /^\Q$_~/ && -s _ > $lasthugesize;
	$lasthugefile = $_;
	$lasthugesize = -s _;
    }

    if (-d _ && ! $prune{$_} && ! /$exclude/o && opendir(DIR,$_)) { 
	for local($_) (reverse sort readdir DIR) { 
	    /^[.][.]?$/o || &find("$path/$_");
	}
    }
    $expire && /~{$expire}$/o && (unlink || rmdir);
    $expire && /~$/o && rename ($_, "$_~");
    /$exclude/o && next;
    print "$_\0$attr\0";
}

$exclude='~$'; 

$prune{"/backup"}=1;
$prune{"/cdrom"}=1;
$prune{"/disk"}=1;
$prune{"/dos"}=1;
$prune{"/export"}=1;
$prune{"/home"}=1;
$prune{"/loc"}=1;
$prune{"/mirror"}=1;
$prune{"/mnt"}=1;
$prune{"/tmp"}=1;
$prune{"/usr/informix/giga"}=1;

$expire=1; $lasthugefilethreshold=2*1024*1024;

open(STDIN, "-|") || exit &find(".");

open(STDIN, "-|") || &remote("cd / && perl -0lne '/^=/ || lstat || print'");

rename $_, "$_~" while chop($_=<>);

open(STDOUT, "|-") || exit exec "cpio -i";

open(STDOUT, "|-") || &remote "cpio -o";

open(STDIN, "-|") || exec "cat $0";


__END__


exec "cat";


    $ENV{"EXPIRE"} && /~{$ENV{"EXPIRE"}}$/ ) { -d $_ ? unlink $_ : rmdir $_; }
	if ($expire && /~$/) { rename $_, "$_~"; }
	else { print "$path\n"; }

rsh="sh -c"

echo '
 
perl -c - 
# perl - $DIRECTORY | 
# $SERVER "cd /; exec perl -lne 'lstat||print'" | 
# perl -lne 'rename$_,"$_~"'


list='
sub find {
    local($path,$device) = @_;
    local($attr)=&attr; 
    return warn "Cannot stat $path: $!\n" if ! -e _;
    $device= $dev if ! $device;
    if (-d _ && $dev == $device) { 
	opendir(DIR,$path); for (reverse sort readdir DIR) { 
	    &find("$path/$_", $dev) unless /^[.][.]?$/;
	}
    }
    print "$path\n$attr\n" unless $path =~ /\n|~$/;
} foreach (@ARGV) { &find ("./$_"); }
'

compare='
{
    while (1) {
	chop ($path=<> || exit);
	chop ($attr=<>);
	if ($attr ne &attr) {
	    rename $path, "$path~" unless -d _;
	    print "$path\n"; 
	}
    }
}'

echo "$attr $list" | $rsh "cd / && exec perl - $partitions" | 
perl -e "$attr $compare" | $rsh "cd / && exec /mach/bin/cpio -oH crc" |
$cpio -idm
