Hello community, here is the log from the commit of package mksusecd for openSUSE:Factory checked in at 2015-07-14 17:45:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/mksusecd (Old) and /work/SRC/openSUSE:Factory/.mksusecd.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "mksusecd" Changes: -------- --- /work/SRC/openSUSE:Factory/mksusecd/mksusecd.changes 2015-07-08 07:00:01.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.mksusecd.new/mksusecd.changes 2015-07-14 17:46:20.000000000 +0200 @@ -1,0 +2,6 @@ +Mon Jul 13 15:06:21 CEST 2015 - snw...@suse.com + +- fix cpio archive unpacking +- 1.28 + +------------------------------------------------------------------- Old: ---- mksusecd-1.27.tar.xz New: ---- mksusecd-1.28.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ mksusecd.spec ++++++ --- /var/tmp/diff_new_pack.0Hd11i/_old 2015-07-14 17:46:20.000000000 +0200 +++ /var/tmp/diff_new_pack.0Hd11i/_new 2015-07-14 17:46:20.000000000 +0200 @@ -18,7 +18,7 @@ Name: mksusecd -Version: 1.27 +Version: 1.28 Release: 0 Summary: Create SUSE Linux installation ISOs License: GPL-3.0+ ++++++ mksusecd-1.27.tar.xz -> mksusecd-1.28.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mksusecd-1.27/VERSION new/mksusecd-1.28/VERSION --- old/mksusecd-1.27/VERSION 2015-07-07 14:01:57.000000000 +0200 +++ new/mksusecd-1.28/VERSION 2015-07-13 15:01:09.000000000 +0200 @@ -1 +1 @@ -1.27 +1.28 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mksusecd-1.27/changelog new/mksusecd-1.28/changelog --- old/mksusecd-1.27/changelog 2015-07-07 14:01:57.000000000 +0200 +++ new/mksusecd-1.28/changelog 2015-07-13 15:01:09.000000000 +0200 @@ -1,3 +1,6 @@ +2015-07-13: 1.28 + - fix cpio archive unpacking + 2015-07-07: 1.27 - README: link to mkdud; grammar; formatting diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mksusecd-1.27/mksusecd new/mksusecd-1.28/mksusecd --- old/mksusecd-1.27/mksusecd 2015-07-07 14:01:57.000000000 +0200 +++ new/mksusecd-1.28/mksusecd 2015-07-13 15:01:09.000000000 +0200 @@ -181,7 +181,7 @@ sub sign_content; sub file_magic; sub get_archive_type; -sub unpack_cpio; +sub unpack_cpiox; sub unpack_archive; sub format_array; sub get_initrd_modules; @@ -351,9 +351,12 @@ die "$_: unsupported source type\n"; } } - else { + elsif(-e _) { die "$_: unsupported source type\n"; } + else { + die "$_: no such file or directory\n"; + } } if(!@sources) { @@ -2421,7 +2424,10 @@ if($t =~ /^RPM/) { $type = "cpio.rpm$type"; } - elsif($t =~ / (cpio|tar) archive/) { + elsif($t =~ /^ASCII cpio archive \(SVR4/) { + $type = "cpiox$type"; + } + elsif($t =~ /\b(cpio|tar) archive/) { $type = "$1$type"; } elsif($t =~ /^(gzip|XZ) compressed data/) { @@ -2440,6 +2446,8 @@ } } while($type =~ /^\./); + # print "$file = $type\n"; + return $type; } @@ -2447,56 +2455,99 @@ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Unpack cpio archive. # -# unpack_cpio(dir, file, part) +# unpack_cpiox(dir, file, part) # # - dir: the directory to unpack to # - file: the archive file name # - part: the part number of a multipart archive (kernel initramfs-like) # (0 = unpack all) # -sub unpack_cpio +sub unpack_cpiox { my $dst = shift; my $file = shift; my $part = shift() + 0; - my ($p, $buf_size, $buf, $cnt); + my ($f, $p, $buf, $cnt, $len, $magic, $head, $fname_len, $data_len, $fname, $ofs); my $cpio_cmd = 'cpio --quiet -dmiu --sparse --no-absolute-filenames 2>/dev/null'; $cnt = 1; - $buf_size = 1 << 16; - if(open my $f, $file) { - while(sysread($f, $buf, $buf_size, length $buf) > 0) { - # printf STDERR "read buf = %d\n", length $buf; - - for(my $i = 0; $i < length($buf); $i += 512) { - # printf STDERR "buf = %d, i = %d\n", length($buf), $i; - if(substr($buf, $i, 512) =~ /TRAILER!!!\x00*$/) { - # printf STDERR "end = %d, writing %d\n", $i, $i + 512; - open $p, "| ( cd $dst ; $cpio_cmd )" if !$p && ($part == 0 || $part == $cnt); - if($p) { - syswrite $p, substr($buf, 0, $i + 512); - close $p; - undef $p; - } - substr($buf, 0, $i + 512) = ""; - $i = -512; - $cnt++; - } - } - if(length($buf)) { - # printf STDERR "writing %d\n", length($buf); - open $p, "| ( cd $dst ; $cpio_cmd )" if !$p && ($part == 0 || $part == $cnt); - syswrite $p, $buf if $p; - $buf = ""; + sub read_write + { + my $len = $_[0]; + my $read; + + undef $buf; + + open $p, "| ( cd $dst ; $cpio_cmd )" if !$p && ($part == 0 || $part == $cnt); + + return $len if !$len; + + while($len) { + my $x = sysread $f, substr($buf, length $buf), $len; + last if !$x; + $read += $x; + $len -= $x; + }; + + syswrite $p, $buf, $read if $read && $p; + + return $read; + } + + if(open $f, $file) { + while(($len = read_write(110)) == 110) { + $ofs += 110; + + # printf "header = \"%s\" %d\n", $buf, length($buf); + + $magic = substr($buf, 0, 6); + $head = substr($buf, 6); + + $fname_len = hex substr $buf, 94, 8; + $data_len = hex substr $buf, 54, 8; + + # print "$magic - $fname_len - $data_len\n"; + + die "broken cpio header\n" if $magic ne "070701" && $magic ne "070702"; + + $fname_len += (2, 1, 0, 3)[$fname_len & 3]; + $data_len = (($data_len + 3) & ~3); + + read_write $fname_len; + $fname = $buf; + $fname =~ s/\x00*$//; + + read_write $data_len; + + $ofs += $fname_len + $data_len; + + # print "fname = \"$fname\"\n"; + + # printf "ofs = 0x%x\n", $ofs; + + if( + $fname eq 'TRAILER!!!' && + $head eq '00000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000' + ) { + my $pad = ($ofs + 0x1ff) & ~0x1ff; + read_write $pad - $ofs; + $ofs = $pad; + $cnt++; + close $p if $p; + undef $p; } } close $p if $p; close $f; + + if($len) { + die "error reading cpio archive $len\n"; + } } else { die "failed to read file\n"; @@ -2524,7 +2575,7 @@ return undef if $type eq ''; my $cmd; - my $cpio; + my $cpiox; if($type eq 'dir') { $cmd = "tar -C '$file' -cf - ."; @@ -2556,20 +2607,28 @@ last; } elsif($_ eq 'cpio') { + $cmd = "cat '$file'" if !$cmd; + $cmd .= " | ( cd '$dir' ; cpio --quiet -dmiu --sparse --no-absolute-filenames 2>/dev/null )"; + last; + } + elsif($_ eq 'cpiox') { if(!$cmd) { $cmd = $file; } else { $cmd .= " |"; } - $cpio = 1; + $cpiox = 1; last; } } - if($cpio) { - # print STDERR "unpack_cpio($cmd)\n"; - unpack_cpio $dir, $cmd, $part; + # cpiox = concatenated compressed cpio archives as the kernel uses for initrd + # must be SVR4 ASCII format, with or without CRC ('cpio -H newc') + # in this case we have to parse the cpio stream and handle the 'TRAILER!!!' entries + if($cpiox) { + # print STDERR "unpack_cpiox($cmd)\n"; + unpack_cpiox $dir, $cmd, $part; } else { # print STDERR "$cmd\n";