[PATCH] Dpkg::Checksums: New module with code to determine and verify checksums
---
scripts/Dpkg/Checksums.pm | 57 +++++++++++++++++++++++++++++++++++++++++++++
scripts/Makefile.am | 1 +
scripts/po/POTFILES.in | 1 +
3 files changed, 59 insertions(+), 0 deletions(-)
create mode 100644 scripts/Dpkg/Checksums.pm
diff --git a/scripts/Dpkg/Checksums.pm b/scripts/Dpkg/Checksums.pm
new file mode 100644
index 0000000..0c1dc12
--- /dev/null
+++ b/scripts/Dpkg/Checksums.pm
@@ -0,0 +1,57 @@
+package Dpkg::Checksums;
+
+use strict;
+use warnings;
+
+use Dpkg;
+use Dpkg::Gettext;
+use Dpkg::ErrorHandling qw(internerr syserr subprocerr failure error);
+
+use base qw(Exporter);
+our @EXPORT = qw(@check_supported %check_supported %check_prog $check_regex
+ getchecksum verifychecksum);
+
+our @check_supported = qw(md5sum sha1sum sha256sum);
+our %check_supported = map { $_ => 1 } @check_supported;
+our %check_prog = ( 32 => 'md5sum', 40 => 'sha1sum', 64 => 'sha256sum' );
+our $check_regex = qr/(?:[0-9a-f]{32}|[0-9a-f]{40}|[0-9a-f]{64})/;
+
+sub extractchecksum {
+ (my $checksum = shift) or return;
+ $checksum =~ s/^($check_regex)\s*\*?-?\s*\n?$/$1/o
+ || failure(_g("checksum program gave bogus output `%s'"), $checksum);
+ return $checksum;
+}
+
+sub getchecksum {
+ my ($checksum_prog, $file) = @_;
+ open(STDIN, "<", $file) ||
+ syserr(_g("cannot open file %s for reading"), $file);
+ (my @s = stat(STDIN)) || syserr(_g("cannot fstat file %s"), $file);
+ my $size = $s[7];
+ my $sum = `$checksum_prog`;
+ $? && subprocerr("%s %s", $checksum_prog, $file);
+ open(STDIN, "<", "/dev/null")
+ || &syserr(_g("reopen stdin from /dev/null"));
+ $sum = extractchecksum($sum);
+
+ return ($sum, $size);
+}
+
+sub verifychecksum {
+ my ($file, $checksum, $size, $source) = @_;
+
+ my $checksum_prog = $check_prog{length $checksum};
+ internerr("checksum $checksum for $file had bogus length")
+ unless $checksum_prog;
+
+ my ($newsum, $newsize) = getchecksum($checksum_prog, $file);
+ unless ($newsize eq $size) {
+ error(_g("Tried to verify checksum %s of file %s (from %s) but the file has wrong size %u instead of expected %u"),
+ $checksum, $file, $source, $newsize, $size);
+ }
+ unless ($newsum eq $checksum) {
+ error(_g("Tried to verify checksum %s of file %s (from %s) but got %s instead"),
+ $checksum, $file, $source, $newsum);
+ }
+}
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index e27f294..a0b1a96 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -89,6 +89,7 @@ nobase_dist_perllib_DATA = \
Dpkg/Cdata.pm \
Dpkg/Changelog.pm \
Dpkg/Changelog/Debian.pm \
+ Dpkg/Checksums.pm \
Dpkg/Compression.pm \
Dpkg/Control.pm \
Dpkg/Deps.pm \
diff --git a/scripts/po/POTFILES.in b/scripts/po/POTFILES.in
index 4a14b35..58b0090 100644
--- a/scripts/po/POTFILES.in
+++ b/scripts/po/POTFILES.in
@@ -18,6 +18,7 @@ scripts/Dpkg/Arch.pm
scripts/Dpkg/Cdata.pm
scripts/Dpkg/Changelog.pm
scripts/Dpkg/Changelog/Debian.pm
+scripts/Dpkg/Compression.pm
scripts/Dpkg/Control.pm
scripts/Dpkg/Deps.pm
scripts/Dpkg/ErrorHandling.pm
--
1.5.3.8
Reply to: