CPAN-Checksums
view release on metacpan or search on metacpan
lib/CPAN/Checksums.pm view on Meta::CPAN
close $fh;
}
return($old_ddump,$is_signed);
}
sub updatedir ($;$) {
my($dirname, $root) = @_;
my $ckfn = File::Spec->catfile($dirname, "CHECKSUMS"); # checksum-file-name
my($old_ddump,$is_signed) = _read_old_ddump($ckfn);
my($old_dref) = makehashref($old_ddump);
my $dref = _dir_to_dref($dirname,$old_dref,$root);
local $Data::Dumper::Indent = 1;
local $Data::Dumper::Quotekeys = 1;
local $Data::Dumper::Sortkeys = 1;
my $ddump = Data::Dumper->new([$dref],["cksum"])->Dump;
my @ckfnstat = stat $ckfn;
if ($old_ddump) {
local $DIRNAME = $dirname;
if ( !!$SIGNING_KEY == !!$is_signed ) { # either both or neither
if (!$MIN_MTIME_CHECKSUMS || $ckfnstat[9] > $MIN_MTIME_CHECKSUMS ) {
# recent enough
return 1 if $old_ddump eq $ddump;
return 1 if ckcmp($old_dref,$dref);
}
}
if ($CAUTION) {
my $report = investigate($old_dref,$dref);
warn $report if $report;
}
}
my $ft = File::Temp->new(
DIR => $dirname,
TEMPLATE => "CHECKSUMS.XXXX",
CLEANUP => 0,
) or die;
my $tckfn = $ft->filename;
close $ft;
my($fh) = new IO::File;
open $fh, ">$tckfn\0" or die "Couldn't open >$tckfn\: $!";
local $\;
if ($SIGNING_KEY) {
print $fh "0&&<<''; # this PGP-signed message is also valid perl\n";
close $fh;
open $fh, "| $SIGNING_PROGRAM $SIGNING_KEY >> $tckfn"
or die "Could not call gpg: $!";
$ddump .= "__END__\n";
}
my $message = sprintf "# CHECKSUMS file written on %s GMT by CPAN::Checksums (v%s)\n%s",
scalar gmtime, $VERSION, $ddump;
print $fh $message;
my $success = close $fh;
if ($SIGNING_KEY && !$success) {
warn "Couldn't run '$SIGNING_PROGRAM $SIGNING_KEY'!
Writing to $tckfn directly";
open $fh, ">$tckfn\0" or die "Couldn't open >$tckfn\: $!";
print $fh $message;
close $fh or warn "Couldn't close $tckfn: $!";
}
chmod 0644, $ckfn or die "Couldn't chmod to 0644 for $ckfn\: $!" if -f $ckfn;
rename $tckfn, $ckfn or die "Could not rename: $!";
chmod 0444, $ckfn or die "Couldn't chmod to 0444 for $ckfn\: $!";
return 2;
}
sub _add_digests ($$$$$$$) {
my($de,$dref,$module,$constructor_args,$keyname,$abs,$old_dref) = @_;
my($fh) = new IO::File;
my $dig = $module->new(@$constructor_args);
$fh->open("$abs\0") or die "Couldn't open $abs: $!";
binmode($fh); # make sure it's called as a function, solaris with
# perl 5.8.4 complained about missing method in
# IO::File
$dig->addfile($fh);
$fh->close;
my $digest = $dig->hexdigest;
$dref->{$de}{$keyname} = $digest;
$dig = $module->new(@$constructor_args);
if ($de =~ /\.(gz|tgz)$/) {
my($buffer, $zip);
if (exists $old_dref->{$de}{$keyname} &&
$dref->{$de}{$keyname} eq $old_dref->{$de}{$keyname} &&
exists $old_dref->{$de}{"$keyname-ungz"}
) {
$dref->{$de}{"$keyname-ungz"} = $old_dref->{$de}{"$keyname-ungz"};
return;
}
if ($zip = Compress::Zlib::gzopen($abs, "rb")) {
$dig->add($buffer)
while $zip->gzread($buffer) > 0;
$dref->{$de}{"$keyname-ungz"} = $dig->hexdigest;
$zip->gzclose;
}
} elsif ($de =~ /\.(bz2|tbz)$/) {
my($buffer, $zip);
if (exists $old_dref->{$de}{$keyname} &&
$dref->{$de}{$keyname} eq $old_dref->{$de}{$keyname} &&
exists $old_dref->{$de}{"$keyname-unbz2"}
) {
$dref->{$de}{"$keyname-unbz2"} = $old_dref->{$de}{"$keyname-unbz2"};
return;
}
if ($zip = Compress::Bzip2::bzopen($abs, "rb")) {
$dig->add($buffer)
while $zip->bzread($buffer) > 0;
$dref->{$de}{"$keyname-unbz2"} = $dig->hexdigest;
$zip->bzclose;
}
}
}
sub ckcmp ($$) {
my($old,$new) = @_;
for ($old,$new) {
$_ = makehashref($_);
}
Data::Compare::Compare($old,$new);
}
# see if a file changed but the name not
sub investigate ($$) {
my($old,$new) = @_;
( run in 0.708 second using v1.01-cache-2.11-cpan-437f7b0c052 )