[Libguestfs] [PATCH 2/2] filearch: support gzip/xz-compressed files

Pino Toscano ptoscano at redhat.com
Mon Apr 13 11:42:00 UTC 2015


Extract them to find out the architecture of the data they hold.
Useful to detect the architecture of e.g. compressed Linux modules.
---
 src/filearch.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/src/filearch.c b/src/filearch.c
index 219eaae..df65c98 100644
--- a/src/filearch.c
+++ b/src/filearch.c
@@ -250,6 +250,66 @@ cpio_arch (guestfs_h *g, const char *file, const char *path)
   return ret;
 }
 
+static char *
+compressed_file_arch (guestfs_h *g, const char *path, const char *method)
+{
+  CLEANUP_FREE char *tmpdir = guestfs_get_tmpdir (g), *dir = NULL;
+  CLEANUP_FREE char *tempfile = NULL, *tempfile_extracted = NULL;
+  CLEANUP_CMD_CLOSE struct command *cmd = guestfs_int_new_command (g);
+  char *ret = NULL;
+  int64_t size;
+  int r;
+  bool matched;
+
+  if (asprintf (&dir, "%s/libguestfsXXXXXX", tmpdir) == -1) {
+    perrorf (g, "asprintf");
+    return NULL;
+  }
+
+  /* Security: Refuse to download file if it is huge. */
+  size = guestfs_filesize (g, path);
+  if (size == -1 || size > 10000000) {
+    error (g, _("size of %s unreasonable (%" PRIi64 " bytes)"),
+           path, size);
+    goto out;
+  }
+
+  if (mkdtemp (dir) == NULL) {
+    perrorf (g, "mkdtemp");
+    goto out;
+  }
+
+  tempfile = safe_asprintf (g, "%s/file", dir);
+  if (guestfs_download (g, path, tempfile) == -1)
+    goto out;
+
+  tempfile_extracted = safe_asprintf (g, "%s/file_extracted", dir);
+
+  /* Construct a command to extract named binaries from the initrd file. */
+  guestfs_int_cmd_add_string_unquoted (cmd, method);
+  guestfs_int_cmd_add_string_unquoted (cmd, " ");
+  guestfs_int_cmd_add_string_quoted (cmd, tempfile);
+  guestfs_int_cmd_add_string_unquoted (cmd, " > ");
+  guestfs_int_cmd_add_string_quoted (cmd, tempfile_extracted);
+
+  r = guestfs_int_cmd_run (cmd);
+  if (r == -1)
+    goto out;
+  if (!WIFEXITED (r) || WEXITSTATUS (r) != 0) {
+    guestfs_int_external_command_failed (g, r, method, path);
+    goto out;
+  }
+
+  ret = magic_for_file (g, tempfile_extracted, NULL, &matched);
+  if (!matched)
+    error (g, "file_architecture: could not determine architecture of compressed file");
+
+ out:
+  guestfs_int_recursive_remove_dir (g, dir);
+
+  return ret;
+}
+
 char *
 guestfs_impl_file_architecture (guestfs_h *g, const char *path)
 {
@@ -272,6 +332,10 @@ guestfs_impl_file_architecture (guestfs_h *g, const char *path)
     ret = safe_strdup (g, "x86_64");
   else if (strstr (file, "cpio archive"))
     ret = cpio_arch (g, file, path);
+  else if (strstr (file, "gzip compressed data"))
+    ret = compressed_file_arch (g, path, "zcat");
+  else if (strstr (file, "XZ compressed data"))
+    ret = compressed_file_arch (g, path, "xzcat");
   else
     error (g, "file_architecture: unknown architecture: %s", path);
 
-- 
2.1.0




More information about the Libguestfs mailing list