From f8362971df775aa44f26435dc24e655d79424375 Mon Sep 17 00:00:00 2001 From: Nicolas Vigier Date: Sun, 1 May 2011 21:21:49 +0000 Subject: add include_md5 function --- pm/MGATools/iso.pm | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 pm/MGATools/iso.pm (limited to 'pm/MGATools/iso.pm') diff --git a/pm/MGATools/iso.pm b/pm/MGATools/iso.pm new file mode 100644 index 0000000..8fe13e5 --- /dev/null +++ b/pm/MGATools/iso.pm @@ -0,0 +1,124 @@ +package MGATools::iso; + +use strict; +use Digest::MD5; + +require Exporter; +use URPM; +our @ISA = qw(Exporter);; +our @EXPORT = qw(include_md5); +our ($INFO_OFFSET, $SIZE_OFFSET, $SKIP); +$INFO_OFFSET = 883; +$SIZE_OFFSET = 84; +$SKIP = 15; + +=head1 NAME + +Mageia iso tools + +=head1 SYNOPSYS + + require MGATools::iso; + +=head1 DESCRIPTION + + includes Mageia iso tools. + +=head1 SEE ALSO + +mkcd + +=head1 COPYRIGHT + +Copyright (C) 2000,2001,2002,2003,2004 Mandriva + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +=head1 CREDITS + +md5 code highly inspired from Redhat anaconda md5 in ISO code + +=cut + + +# function copied from Mkcd::Tools +# TODO must add some check of maximum authorized size +sub include_md5 { + my ($iso, $write, $verbose) = @_; + my $ISO; + if ($write) { + open $ISO, "+<$iso" or return "ERROR include_md5: unable to open $iso ($!)\n"; + } else { + open $ISO, $iso or return "ERROR include_md5: unable to open $iso ($!)\n"; + } + binmode $ISO; + my $offset = 16*2048; + # blank header + seek $ISO, $offset, 0; + my ($buf, $msg); + while (1) { + read $ISO,$buf,2048; + my $c = ord $buf; + last if $c == 1; + return "ERROR include_md5: could not find primary volume descriptor\n" if $c == 255; + $offset += 2048 + } + my $size = ((ord substr $buf, $SIZE_OFFSET, 1) * 0x1000000 + + (ord substr $buf, $SIZE_OFFSET + 1, 1) * 0x10000 + + (ord substr $buf, $SIZE_OFFSET + 2, 1) * 0x100 + + (ord substr $buf, $SIZE_OFFSET + 3, 1)) * 2048; + my ($system, $volume, $publisher, $prep, $app) = map { $a = $_ ; $a =~ s/^\s*//; $a =~ s/\s*$//; $a } (substr($buf, 8, 22), substr($buf, 30, 40), substr($buf, 318, 128), substr($buf, 446, 32), substr($buf, 574, 128)); + print "include_md5:\nSystem: \t$system\nVolume: \t$volume\nPublisher: \t$publisher\nData preparer: \t$prep\nApplication: \t$app\nISO size: \t$size\n" if $verbose; + seek $ISO, $offset + $INFO_OFFSET, 0; + read $ISO, $buf,512; + my ($md5sum) = $buf =~ /.md5 = (\S+)/; + $msg .= "include_md5: previous data $buf\n"; + seek $ISO, 0, 0; + my $md5 = new Digest::MD5; + my $read = read $ISO, $buf, $offset + $INFO_OFFSET; + $md5->add($buf); + seek $ISO, 512, 1; + $read += 512; + $|=1; + my $val = int $size/2048/100; + $verbose and print "\rReading: 0 %"; + my ($i, $j); + # skip last $SKIP bytes that sometimes are not correctly burned by some drives + my $n = 1; + while ($n && $read < $size - $SKIP * 2048) { + $n = read $ISO, $buf,2048; + print "\rReading: ", $j++, " %" if ($verbose && !($i++ % $val)); + $md5->add($buf); + $read += $n; + } + print "\n"; + my $digest = $md5->hexdigest; + $msg .= "include_md5: computed md5 $digest\n"; + my $res = $md5sum eq $digest; + if ($md5sum) { + $msg .= "include_md5: previous md5 $md5sum\ninclude_md5: md5sum check "; + $msg .= $res ? "OK\n" : "FAILED\n" + } + print $msg if $verbose; + $write or return $res; + seek $ISO, $offset + $INFO_OFFSET, 0; + my $str = substr "$volume.md5 = $digest", 0, 512; + my $l = length $str; + print $ISO ($l > 512 ? substr $str, -1, 512 : $str . ' ' x (512 - $l)); + close $ISO +} + +1 + -- cgit v1.2.1