summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pm/MGATools/iso.pm124
1 files changed, 124 insertions, 0 deletions
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
+
+<MGATools::iso> includes Mageia iso tools.
+
+=head1 SEE ALSO
+
+mkcd
+
+=head1 COPYRIGHT
+
+Copyright (C) 2000,2001,2002,2003,2004 Mandriva <warly@mandriva.com>
+
+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
+