[gnome-boxes] unattended-file: Use libarchive for non-DOS images



commit 686e2d50a790edce62ff5008ac8f92d897a27d31
Author: Lasse Schuirmann <lasse schuirmann gmail com>
Date:   Sun Jun 1 17:38:48 2014 +0200

    unattended-file: Use libarchive for non-DOS images
    
    In the following patches Boxes will learn how to handle non-DOS images.
    For these new formats we need libarchive for copying. As libarchive and
    its wrapper only have a sync API we need to run it in an own thread.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=730640

 src/unattended-file.vala |   53 +++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 48 insertions(+), 5 deletions(-)
---
diff --git a/src/unattended-file.vala b/src/unattended-file.vala
index f3b9a6d..24f5b22 100644
--- a/src/unattended-file.vala
+++ b/src/unattended-file.vala
@@ -17,15 +17,58 @@ private interface Boxes.UnattendedFile : GLib.Object {
         var source_file = yield get_source_file (cancellable);
 
         debug ("Copying unattended file '%s' into disk drive/image '%s'", dest_name, disk_file);
-        // FIXME: Perhaps we should use libarchive for this? Make sure to also change the mcopy dependency 
in README.
-        string[] argv = { "mcopy", "-n", "-o", "-i", disk_file,
-                                   source_file.get_path (),
-                                   "::" + dest_name };
-        yield exec (argv, cancellable);
+
+        if (is_libarchive_compatible (disk_file)) {
+            yield run_in_thread(() => {
+                copy_with_libarchive (disk_file, source_file.get_path (), dest_name);
+            });
+        } else
+            yield copy_with_mcopy (disk_file, source_file.get_path (), dest_name, cancellable);
+
         debug ("Copied unattended file '%s' into disk drive/image '%s'", dest_name, disk_file);
     }
 
     protected abstract async File get_source_file (Cancellable? cancellable)  throws GLib.Error;
+
+    private void copy_with_libarchive (string disk_file, string source_file, string dest_name) throws 
GLib.Error {
+        var reader = new ArchiveReader (disk_file);
+        // write into file~ since we can't write into the file we read from
+        var writer = new ArchiveWriter.from_archive_reader (reader, disk_file + "~", false);
+        // override the destination file if necessary
+        writer.import_read_archive (reader, {dest_name});
+        writer.insert_file (source_file, dest_name);
+
+        // close files for moving
+        reader = null;
+        writer = null;
+
+        var src = GLib.File.new_for_path (disk_file + "~");
+        var dst = GLib.File.new_for_path (disk_file);
+        // and copy the new file to overwrite the old one
+        src.move (dst, FileCopyFlags.OVERWRITE);
+    }
+
+    private async void copy_with_mcopy (string       disk_file,
+                                        string       source_file,
+                                        string       dest_name,
+                                        Cancellable? cancellable = null)
+                                        throws GLib.Error {
+        string[] argv = {"mcopy",
+                             "-n",
+                             "-o",
+                             "-i",
+                                 disk_file,
+                             source_file,
+                             "::" + dest_name };
+        yield exec (argv, cancellable);
+    }
+
+    private static bool is_libarchive_compatible (string filename) {
+        // FIXME: We need better way to determine libarchive compatibility cause mcopy is used
+        //        if this function returns false and mcopy can only handle MS-DOS images while
+        //        libarchive can handle other types of disk images
+        return GLib.ContentType.guess (filename, null, null) != "application/x-raw-disk-image";
+    }
 }
 
 private class Boxes.UnattendedRawFile : GLib.Object, Boxes.UnattendedFile {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]