#!/usr/bin/perl
# -*- perl -*-

while ($ARGV[0] =~ /^-/) {
    $opt = shift;
    $all = 1 if $opt =~ /-a/;
    $diff = 1 if $opt =~ /-d/;
    $purge = 1 if $opt =~ /-rm/;
    $local = 1 if $opt =~ /-l/;
}

@wn = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
@mn = ("Jan", "Feb", "Mar", "Apr", "May", "Jun",
       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");

$ign_default = ". .. core RCSLOG tags TAGS RCS SCCS .make.state .nse_depinfo \#* .\#* cvslog.* ,* CVS CVS.adm .del-* *.a *.olb *.o *.obj *.so *.Z *\~ *.old *.elc *.ln *.bak *.BAK *.orig *.rej *.exe _\$* *\$";

for $_ (split(' ', $ign_default)) {
    s/\+/\\+/g;
    s/\./\\./g;
    s/\?/\./g;
    s/\*/\.\*/g;
    $def_ignore{$_} = 1;
}

if ($local) {
    open(F, "echo ./CVS |");
} else {
    open(F, "find . -name CVS -print |");
}
while (<F>) {
    chop;
    $entries = $_ . "/Entries";
    ($dir = $_) =~ s@/CVS$@@;
    $dir =~ s@^\./@@;

    %saw = ();
    @e = ();
    %ignore = %def_ignore;
    if (!$all) {
	open(C, "$dir/.cvsignore");
	while (<C>) {
	    s/[\r\n]+$//;
	    s/\+/\\+/g;
	    s/\./\\./g;
	    s/\?/\./g;
	    s/\*/\.\*/g;
	    $ignore{$_} = 1;
	}
	close(C);
    }
    $ignore = "^(" . join('|', keys %ignore) . ")\$";
    $ignore = "" if $ignore eq '^()$'; #'
    open(E, $entries);
    while (<E>) {
	push(@e, $_);
    }
    for $_ (sort @e) {
	chop;
	($junk, $file, $rev, $date, $tag) = split(/\//, $_);
	$saw{$file} = 1;
	next if $junk =~ /^D/;
	$ts = (stat("$dir/$file"))[9];
	($s,$m,$h,$dd,$mm,$yy,$ww) = gmtime($ts);
	$yy += 1900;
	$fd = sprintf("%s %s %2d %02d:%02d:%02d %04d",
		      $wn[$ww], $mn[$mm], $dd, $h, $m, $s, $yy);
	if ($fd ne $date) {
            if ($diff) {
		system "diff -p3 $ARGV[0]/$dir/$file $dir/$file";
	    } else {
		unlink "$dir/$file" if $purge;
		$tmp = "$dir/$file";
		$tmp =~ s@^\./@@;
		print "$tmp\n";
	    }
	}
    }
    close(E);
    opendir(D, $dir);
    for $f (sort readdir(D)) {
	next if $f =~ /^\.\.?$/;
	next if $saw{$f};
	next if $f eq "CVS";
	next if $f =~ /^\.\#/ && !$all;
	next if $f =~ /\~$/ && !$all;
	next if $f =~ /$ignore/ && $ignore && ! $all;
	next if $f =~ /\.(orig|rej|old|save)$/ && !$all;
	unlink "$dir/$f" if $purge;
	print "? $dir/$f\n" unless ($diff || $rm);
    }
    closedir(D);
}
close(F);
