#!/usr/bin/perl
#
#NAME
#  PurgeFiles - delete all instances of a file
#
#SYNOPSIS
#  PurgeFiles [dir]... file...
#
DESCRIPTION
#  This program accepts a list of files and directories.   It  searches
#  thru the directories for the files and deletes them. The deletion is
#  done on matching dev+inode numbers, not on names, so it is the exact
#  files  that  are  deleted  (regardless of what their names may be in
#  other directories.
#
#  Stated differently:  PurgeFiles removes all links to the named files
#  from the directories, no matter what they may be named.
#
#  If no directories are named, '.' is used.
#
#AUTHOR
#  John Chambers <jc@trillian.mit.edu>

$| = 1;
($me = $0) =~ s'.*/'';
$V = $ENV{"D_$me"} || $ENV{"V_$me"} || $ENV{"T_$me"} || 0;
$dirs = $fils = $exitstat = 0;

for $a (@ARGV) {
	if (-d $a) {
		$dir[$dirs++] = $a;
	} else {
		if (($dev,$ino) = stat($a)) {
			$fil[$fils] = $a;
			$dev[$fils] = $dev;
			$ino[$fils] = $ino;
			print STDERR "$me: File $fils is $dev[$fils],$ino[$fils].\n" if $V>4;
			++$fils;
		} else { 
			print STDERR "$me: Can't stat \"$a\" ($!)\n";
		}
	}
}
$dir[$dirs++] = ('.') if !@dir;

for $d (@dir) {
	&scandir($d);
}

exit $exitstat;

sub scandir {
	local($d) = @_;
	local($f,@files,$i,$p);
	if (opendir(D,$d)) {
		@files = readdir D;
		closedir D;
		for $f (@files) {
			next if ($f eq '.' || $f eq '..');
			$p = "$d/$f";
			print STDERR "$me: \"$p\" ...\n" if $V>5;
			if (-d $p) {
				print STDERR "$me: \"$p\" is a directory\n" if $V>4;
				&scandir($p);
			} else {
				if (($dev,$ino) = stat($p)) {
					print STDERR "$me: \"$p\" is $dev,$ino.\n" if $V>4;
					for ($i=0; $i<$fils; $i++) {
						print STDERR "$me: File $i is $dev[$i],$ino[$i].\n" if $V>4;
						if ($dev == $dev[$i] && $ino  == $ino[$i]) {
							print STDERR "$me: \"$fil[$i]\" matches \"$p\"\n" if $V>1;
							unlink($p);
						}
					}
				} else {
					print STDERR "$me: Can't stat \"$p\" ($!)\n" if $V>1;
				}
			}
		}
	}
}
