mrc0mmand / rpms / libguestfs

Forked from rpms/libguestfs 3 years ago
Clone

Blame SOURCES/0133-filearch-support-gzip-xz-compressed-files.patch

ffd6ed
From 525a1da911aaccb8587ec4d1b095b2be30f63f90 Mon Sep 17 00:00:00 2001
ffd6ed
From: Pino Toscano <ptoscano@redhat.com>
ffd6ed
Date: Tue, 14 Apr 2015 11:07:57 +0200
ffd6ed
Subject: [PATCH] filearch: support gzip/xz-compressed files
ffd6ed
ffd6ed
Extract them to find out the architecture of the data they hold.
ffd6ed
Useful to detect the architecture of e.g. compressed Linux modules.
ffd6ed
ffd6ed
Provide in the test.iso two samples (compressing existing test data) of
ffd6ed
binaries compressed with gzip and xz.
ffd6ed
ffd6ed
(cherry picked from commit 7291b226d1b08c762ae2f2715a2ac9ed7b8d5d14)
ffd6ed
---
ffd6ed
 .gitignore             |  2 ++
ffd6ed
 generator/actions.ml   |  4 ++++
ffd6ed
 src/filearch.c         | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++
ffd6ed
 tests/data/Makefile.am | 12 ++++++++++
ffd6ed
 4 files changed, 82 insertions(+)
ffd6ed
ffd6ed
diff --git a/.gitignore b/.gitignore
ffd6ed
index 269d735..267caa9 100644
ffd6ed
--- a/.gitignore
ffd6ed
+++ b/.gitignore
ffd6ed
@@ -502,12 +502,14 @@ Makefile.in
ffd6ed
 /tests/data/100krandom
ffd6ed
 /tests/data/10klines
ffd6ed
 /tests/data/abssymlink
ffd6ed
+/tests/data/bin-x86_64-dynamic.gz
ffd6ed
 /tests/data/blank-disk-*
ffd6ed
 /tests/data/blank-disk-*
ffd6ed
 /tests/data/hello.b64
ffd6ed
 /tests/data/initrd
ffd6ed
 /tests/data/initrd-x86_64.img
ffd6ed
 /tests/data/initrd-x86_64.img.gz
ffd6ed
+/tests/data/lib-i586.so.xz
ffd6ed
 /tests/data/test-grep.txt.gz
ffd6ed
 /tests/data/test.iso
ffd6ed
 /tests/disks/test-qemu-drive-libvirt.xml
ffd6ed
diff --git a/generator/actions.ml b/generator/actions.ml
ffd6ed
index c7a1777..ca0208b 100644
ffd6ed
--- a/generator/actions.ml
ffd6ed
+++ b/generator/actions.ml
ffd6ed
@@ -813,6 +813,10 @@ to specify the QEMU interface emulation to use at run time." };
ffd6ed
         [["file_architecture"; "/initrd-x86_64.img"]], "x86_64"), [];
ffd6ed
       InitISOFS, Always, TestResultString (
ffd6ed
         [["file_architecture"; "/initrd-x86_64.img.gz"]], "x86_64"), [];
ffd6ed
+      InitISOFS, Always, TestResultString (
ffd6ed
+        [["file_architecture"; "/bin-x86_64-dynamic.gz"]], "x86_64"), [];
ffd6ed
+      InitISOFS, Always, TestResultString (
ffd6ed
+        [["file_architecture"; "/lib-i586.so.xz"]], "i386"), [];
ffd6ed
     ];
ffd6ed
     shortdesc = "detect the architecture of a binary file";
ffd6ed
     longdesc = "\
ffd6ed
diff --git a/src/filearch.c b/src/filearch.c
ffd6ed
index e851279..40e2225 100644
ffd6ed
--- a/src/filearch.c
ffd6ed
+++ b/src/filearch.c
ffd6ed
@@ -278,6 +278,66 @@ cpio_arch (guestfs_h *g, const char *file, const char *path)
ffd6ed
   return ret;
ffd6ed
 }
ffd6ed
 
ffd6ed
+static char *
ffd6ed
+compressed_file_arch (guestfs_h *g, const char *path, const char *method)
ffd6ed
+{
ffd6ed
+  CLEANUP_FREE char *tmpdir = guestfs_get_tmpdir (g), *dir = NULL;
ffd6ed
+  CLEANUP_FREE char *tempfile = NULL, *tempfile_extracted = NULL;
ffd6ed
+  CLEANUP_CMD_CLOSE struct command *cmd = guestfs_int_new_command (g);
ffd6ed
+  char *ret = NULL;
ffd6ed
+  int64_t size;
ffd6ed
+  int r;
ffd6ed
+  bool matched;
ffd6ed
+
ffd6ed
+  if (asprintf (&dir, "%s/libguestfsXXXXXX", tmpdir) == -1) {
ffd6ed
+    perrorf (g, "asprintf");
ffd6ed
+    return NULL;
ffd6ed
+  }
ffd6ed
+
ffd6ed
+  /* Security: Refuse to download file if it is huge. */
ffd6ed
+  size = guestfs_filesize (g, path);
ffd6ed
+  if (size == -1 || size > 10000000) {
ffd6ed
+    error (g, _("size of %s unreasonable (%" PRIi64 " bytes)"),
ffd6ed
+           path, size);
ffd6ed
+    goto out;
ffd6ed
+  }
ffd6ed
+
ffd6ed
+  if (mkdtemp (dir) == NULL) {
ffd6ed
+    perrorf (g, "mkdtemp");
ffd6ed
+    goto out;
ffd6ed
+  }
ffd6ed
+
ffd6ed
+  tempfile = safe_asprintf (g, "%s/file", dir);
ffd6ed
+  if (guestfs_download (g, path, tempfile) == -1)
ffd6ed
+    goto out;
ffd6ed
+
ffd6ed
+  tempfile_extracted = safe_asprintf (g, "%s/file_extracted", dir);
ffd6ed
+
ffd6ed
+  /* Construct a command to extract named binaries from the initrd file. */
ffd6ed
+  guestfs_int_cmd_add_string_unquoted (cmd, method);
ffd6ed
+  guestfs_int_cmd_add_string_unquoted (cmd, " ");
ffd6ed
+  guestfs_int_cmd_add_string_quoted (cmd, tempfile);
ffd6ed
+  guestfs_int_cmd_add_string_unquoted (cmd, " > ");
ffd6ed
+  guestfs_int_cmd_add_string_quoted (cmd, tempfile_extracted);
ffd6ed
+
ffd6ed
+  r = guestfs_int_cmd_run (cmd);
ffd6ed
+  if (r == -1)
ffd6ed
+    goto out;
ffd6ed
+  if (!WIFEXITED (r) || WEXITSTATUS (r) != 0) {
ffd6ed
+    guestfs_int_external_command_failed (g, r, method, path);
ffd6ed
+    goto out;
ffd6ed
+  }
ffd6ed
+
ffd6ed
+  ret = magic_for_file (g, tempfile_extracted, NULL, &matched);
ffd6ed
+  if (!matched)
ffd6ed
+    error (g, "file_architecture: could not determine architecture of compressed file");
ffd6ed
+
ffd6ed
+ out:
ffd6ed
+  guestfs_int_recursive_remove_dir (g, dir);
ffd6ed
+
ffd6ed
+  return ret;
ffd6ed
+}
ffd6ed
+
ffd6ed
 char *
ffd6ed
 guestfs__file_architecture (guestfs_h *g, const char *path)
ffd6ed
 {
ffd6ed
@@ -300,6 +360,10 @@ guestfs__file_architecture (guestfs_h *g, const char *path)
ffd6ed
     ret = safe_strdup (g, "x86_64");
ffd6ed
   else if (strstr (file, "cpio archive"))
ffd6ed
     ret = cpio_arch (g, file, path);
ffd6ed
+  else if (strstr (file, "gzip compressed data"))
ffd6ed
+    ret = compressed_file_arch (g, path, "zcat");
ffd6ed
+  else if (strstr (file, "XZ compressed data"))
ffd6ed
+    ret = compressed_file_arch (g, path, "xzcat");
ffd6ed
   else
ffd6ed
     error (g, "file_architecture: unknown architecture: %s", path);
ffd6ed
 
ffd6ed
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
ffd6ed
index 3127787..7e0d66a 100644
ffd6ed
--- a/tests/data/Makefile.am
ffd6ed
+++ b/tests/data/Makefile.am
ffd6ed
@@ -76,6 +76,7 @@ images_files_build = \
ffd6ed
 	100kallspaces \
ffd6ed
 	100krandom \
ffd6ed
 	10klines \
ffd6ed
+	bin-x86_64-dynamic.gz \
ffd6ed
 	blank-disk-1s.raw \
ffd6ed
 	blank-disk-1s.qcow2 \
ffd6ed
 	blank-disk-1K.raw \
ffd6ed
@@ -87,6 +88,7 @@ images_files_build = \
ffd6ed
 	initrd \
ffd6ed
 	initrd-x86_64.img \
ffd6ed
 	initrd-x86_64.img.gz \
ffd6ed
+	lib-i586.so.xz \
ffd6ed
 	test-grep.txt.gz
ffd6ed
 
ffd6ed
 check_DATA = $(images_files_build) test.iso
ffd6ed
@@ -193,3 +195,13 @@ test-grep.txt.gz: test-grep.txt
ffd6ed
 	rm -f $@ $@-t
ffd6ed
 	gzip --best -c $< > $@-t
ffd6ed
 	mv $@-t $@
ffd6ed
+
ffd6ed
+bin-x86_64-dynamic.gz: bin-x86_64-dynamic
ffd6ed
+	rm -f $@ $@-t
ffd6ed
+	gzip --best -c $< > $@-t
ffd6ed
+	mv $@-t $@
ffd6ed
+
ffd6ed
+lib-i586.so.xz: lib-i586.so
ffd6ed
+	rm -f $@ $@-t
ffd6ed
+	xz -c $< > $@-t
ffd6ed
+	mv $@-t $@
ffd6ed
-- 
ffd6ed
1.8.3.1
ffd6ed