95 lines
1.7 KiB
Perl
Executable file
95 lines
1.7 KiB
Perl
Executable file
#!/usr/bin/perl
|
|
|
|
=encoding utf8
|
|
|
|
=head1 NAME
|
|
|
|
rrm - record and remove file
|
|
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
B<rrm> I<file>
|
|
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
B<rrm> records a file's MD5sum before removing it. It makes it
|
|
possible to automatically remove the file again should it ever
|
|
reappear.
|
|
|
|
This is useful for cleaning up photos where other partial backups of
|
|
the photos are later added: Photos removed once can easily be
|
|
identified and removed automatically if added by the backup.
|
|
|
|
|
|
=head1 EXAMPLE
|
|
|
|
B<rrm> IMG_2035.JPG
|
|
|
|
Restore a backup containing I<IMG_2035.JPG>.
|
|
|
|
B<rclean>
|
|
|
|
B<rclean> will find B<IMG_2035.JPG> as it has the same size and SHA256sum
|
|
as an already removed file.
|
|
|
|
|
|
=head1 FILES
|
|
|
|
The file B<.rrm> contains the database of size, sha256sum, and names of
|
|
the files. It is created in current directory if it cannot be found in
|
|
any of the (grand*)parent directories.
|
|
|
|
|
|
=head1 SEE ALSO
|
|
|
|
B<rclean>(1), B<rm>(1), B<sha256sum>(1)
|
|
|
|
|
|
=cut
|
|
|
|
|
|
use Digest::SHA;
|
|
|
|
my %size;
|
|
my %hashval;
|
|
my @remove;
|
|
for my $file (@ARGV) {
|
|
if(not -e $file) {
|
|
warn("File does not exist: $file");
|
|
next;
|
|
}
|
|
if(not -f $file) {
|
|
warn("Not a file: $file");
|
|
next;
|
|
}
|
|
if(-s $file > 0) {
|
|
$size{$file} = -s $file;
|
|
my $sha = Digest::SHA->new(256);
|
|
$sha->addfile($file);
|
|
$hashval{$file} = "SHA256:".$sha->b64digest;
|
|
push @remove, $file;
|
|
}
|
|
}
|
|
|
|
$rrmfile = find_rrm_file(".") || ".rrm";
|
|
|
|
open(RRM,">>",$rrmfile) || die("Cannot write to $rrmfile.");
|
|
print RRM map { $size{$_}."\t".$hashval{$_}."\t".$_."\0\n" } @remove;
|
|
close RRM;
|
|
unlink @remove;
|
|
|
|
sub find_rrm_file {
|
|
my $dir = shift;
|
|
if(-r "$dir/.rrm") {
|
|
return "$dir/.rrm";
|
|
}
|
|
if(join(" ",stat $dir) eq join(" ",stat "../$dir")) {
|
|
# We have reached root dir (.. = .)
|
|
return undef;
|
|
} else {
|
|
return find_rrm_file("../$dir");
|
|
}
|
|
}
|