#!/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 $| = 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; } } } } }