trivial: Move the archive decompression to common code

This commit is contained in:
Richard Hughes 2017-08-08 12:21:39 +01:00
parent d7704d4cc2
commit 94f939aa4d
8 changed files with 104 additions and 81 deletions

View File

@ -227,6 +227,7 @@ plugin_deps += giounix
plugin_deps += gmodule plugin_deps += gmodule
plugin_deps += gusb plugin_deps += gusb
plugin_deps += soup plugin_deps += soup
plugin_deps += libarchive
subdir('data') subdir('data')
subdir('docs') subdir('docs')

View File

@ -22,8 +22,6 @@
#include "config.h" #include "config.h"
#include <appstream-glib.h> #include <appstream-glib.h>
#include <archive_entry.h>
#include <archive.h>
#include <string.h> #include <string.h>
#include "fu-plugin.h" #include "fu-plugin.h"
@ -143,23 +141,6 @@ fu_plugin_raspberrypi_parse_firmware (FuDevice *device, const gchar *fn, GError
return TRUE; return TRUE;
} }
static gboolean
fu_plugin_raspberrypi_explode_file (struct archive_entry *entry, const gchar *dir)
{
const gchar *tmp;
g_autofree gchar *buf = NULL;
/* no output file */
if (archive_entry_pathname (entry) == NULL)
return FALSE;
/* update output path */
tmp = archive_entry_pathname (entry);
buf = g_build_filename (dir, tmp, NULL);
archive_entry_update_pathname_utf8 (entry, buf);
return TRUE;
}
gboolean gboolean
fu_plugin_update_online (FuPlugin *plugin, fu_plugin_update_online (FuPlugin *plugin,
FuDevice *device, FuDevice *device,
@ -168,75 +149,19 @@ fu_plugin_update_online (FuPlugin *plugin,
GError **error) GError **error)
{ {
FuPluginData *data = fu_plugin_get_data (plugin); FuPluginData *data = fu_plugin_get_data (plugin);
gboolean ret = TRUE;
gboolean valid;
int r;
struct archive *arch = NULL;
struct archive_entry *entry;
g_autofree gchar *fwfn = NULL; g_autofree gchar *fwfn = NULL;
/* decompress anything matching either glob */ /* decompress anything matching either glob */
fu_plugin_set_status (plugin, FWUPD_STATUS_DECOMPRESSING);
arch = archive_read_new ();
archive_read_support_format_all (arch);
archive_read_support_filter_all (arch);
r = archive_read_open_memory (arch,
(void *) g_bytes_get_data (blob_fw, NULL),
(size_t) g_bytes_get_size (blob_fw));
if (r) {
ret = FALSE;
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
"Cannot open: %s",
archive_error_string (arch));
goto out;
}
fu_plugin_set_status (plugin, FWUPD_STATUS_DEVICE_WRITE); fu_plugin_set_status (plugin, FWUPD_STATUS_DEVICE_WRITE);
for (;;) { if (!fu_common_extract_archive (blob_fw, data->fw_dir, error))
g_autofree gchar *path = NULL; return FALSE;
r = archive_read_next_header (arch, &entry);
if (r == ARCHIVE_EOF)
break;
if (r != ARCHIVE_OK) {
ret = FALSE;
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
"Cannot read header: %s",
archive_error_string (arch));
goto out;
}
/* only extract if valid */
valid = fu_plugin_raspberrypi_explode_file (entry, data->fw_dir);
if (!valid)
continue;
r = archive_read_extract (arch, entry, 0);
if (r != ARCHIVE_OK) {
ret = FALSE;
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
"Cannot extract: %s",
archive_error_string (arch));
goto out;
}
}
/* get the new VC build info */ /* get the new VC build info */
fu_plugin_set_status (plugin, FWUPD_STATUS_DEVICE_VERIFY); fu_plugin_set_status (plugin, FWUPD_STATUS_DEVICE_VERIFY);
fwfn = g_build_filename (data->fw_dir, fwfn = g_build_filename (data->fw_dir,
FU_PLUGIN_RPI_FIRMWARE_FILENAME, FU_PLUGIN_RPI_FIRMWARE_FILENAME,
NULL); NULL);
if (!fu_plugin_raspberrypi_parse_firmware (device, fwfn, error)) return fu_plugin_raspberrypi_parse_firmware (device, fwfn, error);
return FALSE;
out:
if (arch != NULL) {
archive_read_close (arch);
archive_read_free (arch);
}
return ret;
} }
void void

View File

@ -108,7 +108,7 @@ fu_plugin_raspberrypi_func (void)
FWUPD_INSTALL_FLAG_NONE, &error); FWUPD_INSTALL_FLAG_NONE, &error);
g_assert_no_error (error); g_assert_no_error (error);
g_assert (ret); g_assert (ret);
g_assert_cmpint (cnt, ==, 3); g_assert_cmpint (cnt, ==, 2);
/* check the file was exploded to the right place */ /* check the file was exploded to the right place */
g_assert (g_file_test ("/tmp/rpiboot/start.elf", G_FILE_TEST_EXISTS)); g_assert (g_file_test ("/tmp/rpiboot/start.elf", G_FILE_TEST_EXISTS));

View File

@ -19,7 +19,6 @@ shared_module('fu_plugin_raspberrypi',
], ],
dependencies : [ dependencies : [
plugin_deps, plugin_deps,
libarchive,
], ],
) )
@ -41,7 +40,6 @@ if get_option('enable-tests')
dependencies : [ dependencies : [
plugin_deps, plugin_deps,
sqlite, sqlite,
libarchive,
valgrind, valgrind,
], ],
link_with : [ link_with : [

View File

@ -22,6 +22,8 @@
#include <config.h> #include <config.h>
#include <gio/gunixinputstream.h> #include <gio/gunixinputstream.h>
#include <archive_entry.h>
#include <archive.h>
#include "fwupd-error.h" #include "fwupd-error.h"
@ -110,3 +112,93 @@ fu_common_get_contents_fd (gint fd, gsize count, GError **error)
} }
return g_steal_pointer (&blob); return g_steal_pointer (&blob);
} }
static gboolean
fu_common_extract_archive_entry (struct archive_entry *entry, const gchar *dir)
{
const gchar *tmp;
g_autofree gchar *buf = NULL;
/* no output file */
if (archive_entry_pathname (entry) == NULL)
return FALSE;
/* update output path */
tmp = archive_entry_pathname (entry);
buf = g_build_filename (dir, tmp, NULL);
archive_entry_update_pathname_utf8 (entry, buf);
return TRUE;
}
/**
* fu_common_extract_archive:
* @blob: a #GBytes archive as a blob
* @directory: a directory name to extract to
* @error: A #GError, or %NULL
*
* Extracts an achive to a directory.
*
* Returns: %TRUE for success
**/
gboolean
fu_common_extract_archive (GBytes *blob, const gchar *dir, GError **error)
{
gboolean ret = TRUE;
int r;
struct archive *arch = NULL;
struct archive_entry *entry;
/* decompress anything matching either glob */
arch = archive_read_new ();
archive_read_support_format_all (arch);
archive_read_support_filter_all (arch);
r = archive_read_open_memory (arch,
(void *) g_bytes_get_data (blob, NULL),
(size_t) g_bytes_get_size (blob));
if (r != 0) {
ret = FALSE;
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
"Cannot open: %s",
archive_error_string (arch));
goto out;
}
for (;;) {
gboolean valid;
g_autofree gchar *path = NULL;
r = archive_read_next_header (arch, &entry);
if (r == ARCHIVE_EOF)
break;
if (r != ARCHIVE_OK) {
ret = FALSE;
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
"Cannot read header: %s",
archive_error_string (arch));
goto out;
}
/* only extract if valid */
valid = fu_common_extract_archive_entry (entry, dir);
if (!valid)
continue;
r = archive_read_extract (arch, entry, 0);
if (r != ARCHIVE_OK) {
ret = FALSE;
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
"Cannot extract: %s",
archive_error_string (arch));
goto out;
}
}
out:
if (arch != NULL) {
archive_read_close (arch);
archive_read_free (arch);
}
return ret;
}

View File

@ -32,5 +32,8 @@ GBytes *fu_common_get_contents_bytes (const gchar *filename,
GBytes *fu_common_get_contents_fd (gint fd, GBytes *fu_common_get_contents_fd (gint fd,
gsize count, gsize count,
GError **error); GError **error);
gboolean fu_common_extract_archive (GBytes *blob,
const gchar *dir,
GError **error);
#endif /* __FU_COMMON_H__ */ #endif /* __FU_COMMON_H__ */

View File

@ -27,6 +27,7 @@
#include <glib-object.h> #include <glib-object.h>
#include <gusb.h> #include <gusb.h>
#include "fu-common.h"
#include "fu-device.h" #include "fu-device.h"
#include "fu-hwids.h" #include "fu-hwids.h"

View File

@ -7,6 +7,7 @@ install_data(['org.freedesktop.fwupd.xml'],
libfwupdprivate = static_library( libfwupdprivate = static_library(
'fwupdprivate', 'fwupdprivate',
sources : [ sources : [
'fu-common.c',
'fu-device.c', 'fu-device.c',
'fu-hwids.c', 'fu-hwids.c',
'fu-pending.c', 'fu-pending.c',
@ -52,6 +53,7 @@ executable(
polkit, polkit,
soup, soup,
sqlite, sqlite,
libarchive,
], ],
link_with : [ link_with : [
fwupd, fwupd,
@ -104,6 +106,7 @@ executable(
gpgme, gpgme,
gpgerror, gpgerror,
valgrind, valgrind,
libarchive,
], ],
link_with : fwupd, link_with : fwupd,
c_args : [ c_args : [