From 45209466afa76eb93f5c27028c9b5c5e6ea4f572 Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Mon, 13 Apr 2015 11:18:46 +0200 Subject: [PATCH] filearch: move libmagic code in an own function Also use a cleanup attribue to ease the close of the magic_t handle. This is mostly code motion, hopefully with no actual behaviour changes. (cherry picked from commit 20acc1f124a3f3af365c27b7654bead5beb1ef4c) --- src/filearch.c | 100 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 68 insertions(+), 32 deletions(-) diff --git a/src/filearch.c b/src/filearch.c index c0380d9..e851279 100644 --- a/src/filearch.c +++ b/src/filearch.c @@ -74,6 +74,22 @@ free_regexps (void) pcre_free (re_elf_ppc64); } +# ifdef HAVE_ATTRIBUTE_CLEANUP +# define CLEANUP_MAGIC_T_FREE __attribute__((cleanup(cleanup_magic_t_free))) + +static void +cleanup_magic_t_free (void *ptr) +{ + magic_t m = *(magic_t *) ptr; + + if (m) + magic_close (m); +} + +# else +# define CLEANUP_MAGIC_T_FREE +# endif + /* Convert output from 'file' command on ELF files to the canonical * architecture string. Caller must free the result. */ @@ -120,6 +136,55 @@ is_regular_file (const char *filename) return lstat (filename, &statbuf) == 0 && S_ISREG (statbuf.st_mode); } +static char * +magic_for_file (guestfs_h *g, const char *filename, bool *loading_ok, + bool *matched) +{ + int flags; + CLEANUP_MAGIC_T_FREE magic_t m = NULL; + const char *line; + char *elf_arch; + + flags = g->verbose ? MAGIC_DEBUG : 0; + flags |= MAGIC_ERROR | MAGIC_RAW; + + if (loading_ok) + *loading_ok = false; + if (matched) + *matched = false; + + m = magic_open (flags); + if (m == NULL) { + perrorf (g, "magic_open"); + return NULL; + } + + if (magic_load (m, NULL) == -1) { + perrorf (g, "magic_load: default magic database file"); + return NULL; + } + + line = magic_file (m, filename); + if (line == NULL) { + perrorf (g, "magic_file: %s", filename); + return NULL; + } + + if (loading_ok) + *loading_ok = true; + + elf_arch = match1 (g, line, re_file_elf); + if (elf_arch == NULL) { + error (g, "no re_file_elf match in '%s'", line); + return NULL; + } + + if (matched) + *matched = true; + + return canonical_elf_arch (g, elf_arch); +} + /* Download and uncompress the cpio file to find binaries within. */ static const char *initrd_binaries[] = { "bin/ls", @@ -198,40 +263,11 @@ cpio_arch (guestfs_h *g, const char *file, const char *path) safe_asprintf (g, "%s/%s", dir, initrd_binaries[i]); if (is_regular_file (bin)) { - int flags; - magic_t m; - const char *line; - CLEANUP_FREE char *elf_arch = NULL; + bool loading_ok, matched; - flags = g->verbose ? MAGIC_DEBUG : 0; - flags |= MAGIC_ERROR | MAGIC_RAW; - - m = magic_open (flags); - if (m == NULL) { - perrorf (g, "magic_open"); - goto out; - } - - if (magic_load (m, NULL) == -1) { - perrorf (g, "magic_load: default magic database file"); - magic_close (m); - goto out; - } - - line = magic_file (m, bin); - if (line == NULL) { - perrorf (g, "magic_file: %s", bin); - magic_close (m); - goto out; - } - - elf_arch = match1 (g, line, re_file_elf); - if (elf_arch != NULL) { - ret = canonical_elf_arch (g, elf_arch); - magic_close (m); + ret = magic_for_file (g, bin, &loading_ok, &matched); + if (!loading_ok || matched) goto out; - } - magic_close (m); } } error (g, "file_architecture: could not determine architecture of cpio archive"); -- 1.8.3.1