Subject: | Failure on Win32 (when a cpio-archive contains "\r\n") |
It appears the module has never been tested on the Win32 platform. I
wanted to use it for some quick modification of a (small) initrd file
(e.g. http://distro.ibiblio.org/tinycorelinux/4.x/x86/archive/4.2/
distribution_files/core.gz).
An attempt to read the (extracted) cpio archive using the most basic
steps:
use Archive::Cpio;
my $cpio = Archive::Cpio->new;
$cpio->read("core.cpio");
resulted in:
bad header value 000000us
It turns out that the file prior to this failure (i.e. 'usr/sbin/
visudo', which is pretty much the first non-text file in the archive)
contains two occurrences of CR-LF (i.e. "0x0d 0x0a"), and therefore the
reading of the next header is off by two bytes, which gets reported by
the error message above.
A simple fix would be to add a 'binmode()' call in 'read()', but
considering that 'read_with_handler()' could be called instead I
decided to put it in the latter function. Of course another one is also
required in 'write()'.
So all up the change that worked for me looks like:
--- Cpio.pm-orig 2011-05-31 00:09:05.000000000 +1200
+++ Cpio.pm 2012-01-23 19:01:04.390625000 +1300
@@ -92,6 +92,7 @@
} else {
open($OUT, '>', $file) or die "can't open $file: $!\n";
}
+ binmode($OUT);
$cpio->write_one($OUT, $_) foreach @{$cpio->{list}};
$cpio->write_trailer($OUT);
@@ -170,6 +171,7 @@
my ($cpio, $F, $handler) = @_;
my $FHwp = Archive::Cpio::FileHandle_with_pushback->new($F);
+ binmode($F);
$cpio->{archive_format} ||= detect_archive_format($FHwp);
while (my $entry = $cpio->{archive_format}->read_one($FHwp)) {