Hello community,

here is the log from the commit of package mksusecd for openSUSE:Factory 
checked in at 2017-10-09 19:48:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/mksusecd (Old)
 and      /work/SRC/openSUSE:Factory/.mksusecd.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "mksusecd"

Mon Oct  9 19:48:03 2017 rev:39 rq:532798 version:1.53

Changes:
--------
--- /work/SRC/openSUSE:Factory/mksusecd/mksusecd.changes        2017-05-22 
18:09:50.206113717 +0200
+++ /work/SRC/openSUSE:Factory/.mksusecd.new/mksusecd.changes   2017-10-09 
19:49:02.293429266 +0200
@@ -1,0 +2,11 @@
+Mon Oct 9 14:36:05 UTC 2017 - wfe...@opensuse.org
+
+- merge gh#openSUSE/mksusecd#24
+- rework cpio parsing function to handle blobs added by our product
+  creator
+- ensure initrd has really been unpacked when --rebuild-initrd
+  option is used
+- beautify code
+- 1.53
+
+--------------------------------------------------------------------

Old:
----
  mksusecd-1.52.tar.xz

New:
----
  mksusecd-1.53.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ mksusecd.spec ++++++
--- /var/tmp/diff_new_pack.7uRcnn/_old  2017-10-09 19:49:02.901402545 +0200
+++ /var/tmp/diff_new_pack.7uRcnn/_new  2017-10-09 19:49:02.905402369 +0200
@@ -18,7 +18,7 @@
 
 
 Name:           mksusecd
-Version:        1.52
+Version:        1.53
 Release:        0
 Summary:        Create SUSE Linux installation ISOs
 License:        GPL-3.0+

++++++ mksusecd-1.52.tar.xz -> mksusecd-1.53.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mksusecd-1.52/VERSION new/mksusecd-1.53/VERSION
--- old/mksusecd-1.52/VERSION   2017-05-22 13:48:59.000000000 +0200
+++ new/mksusecd-1.53/VERSION   2017-10-09 16:36:05.000000000 +0200
@@ -1 +1 @@
-1.52
+1.53
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mksusecd-1.52/changelog new/mksusecd-1.53/changelog
--- old/mksusecd-1.52/changelog 2017-05-22 13:48:59.000000000 +0200
+++ new/mksusecd-1.53/changelog 2017-10-09 16:36:05.000000000 +0200
@@ -1,3 +1,8 @@
+2017-10-09:    1.53
+       - beautify code
+       - ensure initrd has really been unpacked when --rebuild-initrd option 
is used
+       - rework cpio parsing function to handle blobs added by our product 
creator
+
 2017-05-18:    1.52
        - clarify description of --fat option
        - remove iso9660 header when creating image for usb media (bsc #939456)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mksusecd-1.52/mksusecd new/mksusecd-1.53/mksusecd
--- old/mksusecd-1.52/mksusecd  2017-05-22 13:48:59.000000000 +0200
+++ new/mksusecd-1.53/mksusecd  2017-10-09 16:36:05.000000000 +0200
@@ -2045,7 +2045,13 @@
   return undef if !@opt_initrds;
 
   my $tmp_initrd = $tmp->file();
-  my $tmp_dir = $opt_rebuild_initrd ? $orig_initrd : $tmp->dir();
+  my $tmp_dir = $tmp->dir();
+
+  if($opt_rebuild_initrd) {
+    unpack_orig_initrd if !$orig_initrd;
+    die "initrd unpacking failed\n" if !$orig_initrd;
+    $tmp_dir = $orig_initrd;
+  }
 
   for my $i (@opt_initrds) {
     my $type = get_archive_type $i;
@@ -3122,15 +3128,17 @@
 }
 
 
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-# Unpack cpio archive.
+# Unpack multiple concatenated cpio archives.
 #
-# unpack_cpiox(dir, file, part)
+# The archives are expected to be in cpio ASCII format ('cpio -H newc').
+# Between the idividual archives an arbitrary sequence of (binary) zeros is
+# allowed. (This is what the kernel allows for the initramfs image.)
 #
-# -  dir: the directory to unpack to
+# unpack_cpiox(dst, file, part)
+#
+# -  dst: the directory to unpack to
 # - file: the archive file name
-# - part: the part number of a multipart archive (kernel initramfs-like)
-#         (0 = unpack all)
+# - part: the part number (1 based) of a multipart archive (0 = unpack all)
 #
 sub unpack_cpiox
 {
@@ -3138,89 +3146,156 @@
   my $file = shift;
   my $part = shift() + 0;
 
-  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;
+  # the archive number we are looking for (1 based)
+  my $cnt = 1;
+
+  # input and output file handles
+  my ($f, $p);
+
+  # data transfer buffer
+  my $buf;
 
-  $read_write = sub
+  # search for cpio header in input stream on next read operation
+  my $sync = 0;
+
+  # track # of written bytes (reset at start of each cpio archive)
+  my $write_ofs;
+
+  # Read # of bytes from input and write to output.
+  #
+  # bytes = read_write(len)
+  # -   len: number of bytes to transfer
+  # - bytes: size of data actually transferred
+  #
+  # This function implicitly opens a new output pipe if none is open and data
+  # need to be written.
+  #
+  # If the $sync variable is set search the input stream for a valid cpio
+  # header (and reset $sync to 0).
+  #
+  sub read_write
   {
     my $len = $_[0];
-    my $read;
 
-    undef $buf;
+    # nothing to do
+    return $len if !$len;
 
-    open $p, "| ( cd $dst ; $cpio_cmd )" if !$p && ($part == 0 || $part == 
$cnt);
+    # clear buffer
+    undef $buf;
 
-    return $len if !$len;
+    # Search for next cpio header.
+    #
+    # This assumes there's a number of binary zeros in the input stream
+    # until the next cpio header.
+    # Actually this only looks for the next non-zero data blob.
+    if($sync) {
+      $sync = 0;
+      while(sysread($f, $buf, 1) == 1 && $buf eq "\x00") {};
+      $len -= length $buf;
+    }
 
+    # read $len bytes
     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;
-  };
+    # In case we did read something, write it to output pipe.
+    if(length $buf) {
+      # Open a new pipe if needed.
+      # But only if part number matches or is 0 (== all parts).
+      if(!$p && ($part == 0 || $part == $cnt)) {
+        open $p, "| ( cd $dst ; $cpio_cmd )" or die "failed to open cpio: 
$!\n";
+        $write_ofs = 0;
+      }
+
+      # Write data and track output size for padding calculation at the end.
+      if($p) {
+        syswrite $p, $buf;
+        $write_ofs += length $buf;
+      }
+    }
 
-  if(open $f, $file) {
-    while(($len = &$read_write(110)) == 110) {
-      $ofs += 110;
+    return length $buf;
+  }
+
+  # Write padding bytes (pad with 0 to full 512 byte blocks) and close
+  # output pipe.
+  #
+  # write_pad_and_close()
+  #
+  # This also sets a sync flag indicating that we should search for the next
+  # valid cpio header in the input stream.
+  #
+  sub write_pad_and_close
+  {
+    if($p) {
+      my $pad = (($write_ofs + 0x1ff) & ~0x1ff) - $write_ofs;
+      syswrite $p, "\x00" x $pad, $pad if $pad;
+      close $p;
+      undef $p;
+    }
 
-      # printf "header = \"%s\" %d\n", $buf, length($buf);
+    # search for next cpio header in input stream
+    $sync = 1;
+  }
 
-      $magic = substr($buf, 0, 6);
-      $head = substr($buf, 6);
+  # open archive and get going...
+  if(open $f, $file) {
+    my $len;
 
-      $fname_len = hex substr $buf, 94, 8;
-      $data_len = hex substr $buf, 54, 8;
+    # We have to trace the cpio archive structure.
+    # Keep going as long as there's a header.
+    while(($len = read_write(110)) == 110) {
+      my $magic = substr($buf, 0, 6);
+      my $head = substr($buf, 6);
 
-      # print "$magic - $fname_len - $data_len\n";
+      my $fname_len = hex substr $buf, 94, 8;
+      my $data_len = hex substr $buf, 54, 8;
 
-      die "broken cpio header\n" if $magic ne "070701" && $magic ne "070702";
+      die "broken cpio header\n" if $magic !~ /^07070[12]$/;
 
       $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);
+      read_write $fname_len;
 
-      $ofs += $fname_len + $data_len;
-
-      # print "fname = \"$fname\"\n";
+      my $fname = $buf;
+      $fname =~ s/\x00*$//;
 
-      # printf "ofs = 0x%x\n", $ofs;
+      read_write $data_len;
 
+      # Look for cpio archive end marker.
+      # If found, close cpio process. A new process will be started at the
+      # next valid cpio archive header.
       if(
         $fname eq 'TRAILER!!!' &&
-        $head eq 
'00000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000'
+        $head =~ /^0{39}10{55}b0{8}$/i
       ) {
-        my $pad = ($ofs + 0x1ff) & ~0x1ff;
-        &$read_write($pad - $ofs);
-        $ofs = $pad;
-        $cnt++;
-        close $p if $p;
-        undef $p;
+        write_pad_and_close;
+        # exit if we're done
+        if($cnt++ == $part) {
+          close $f;
+          return;
+        }
       }
     }
 
-    close $p if $p;
-
+    # we're done, close input file...
     close $f;
 
-    if($len) {
-      die "error reading cpio archive $len\n";
-    }
+    # ...and output file.
+    write_pad_and_close;
+
+    # If $len is != 0 this means we've seen something that's not a header of
+    # a cpio archive entry.
+    die "invalid cpio data\n" if $len;
   }
   else {
-    die "failed to read file\n";
+    die "error reading cpio archive: $!\n";
   }
 }
 


Reply via email to