[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[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: