|
|
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 |
|