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 += gusb
plugin_deps += soup
plugin_deps += libarchive
subdir('data')
subdir('docs')

View File

@ -22,8 +22,6 @@
#include "config.h"
#include <appstream-glib.h>
#include <archive_entry.h>
#include <archive.h>
#include <string.h>
#include "fu-plugin.h"
@ -143,23 +141,6 @@ fu_plugin_raspberrypi_parse_firmware (FuDevice *device, const gchar *fn, GError
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
fu_plugin_update_online (FuPlugin *plugin,
FuDevice *device,
@ -168,75 +149,19 @@ fu_plugin_update_online (FuPlugin *plugin,
GError **error)
{
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;
/* 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);
for (;;) {
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_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;
}
}
if (!fu_common_extract_archive (blob_fw, data->fw_dir, error))
return FALSE;
/* get the new VC build info */
fu_plugin_set_status (plugin, FWUPD_STATUS_DEVICE_VERIFY);
fwfn = g_build_filename (data->fw_dir,
FU_PLUGIN_RPI_FIRMWARE_FILENAME,
NULL);
if (!fu_plugin_raspberrypi_parse_firmware (device, fwfn, error))
return FALSE;
out:
if (arch != NULL) {
archive_read_close (arch);
archive_read_free (arch);
}
return ret;
return fu_plugin_raspberrypi_parse_firmware (device, fwfn, error);
}
void

View File

@ -108,7 +108,7 @@ fu_plugin_raspberrypi_func (void)
FWUPD_INSTALL_FLAG_NONE, &error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (cnt, ==, 3);
g_assert_cmpint (cnt, ==, 2);
/* check the file was exploded to the right place */
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 : [
plugin_deps,
libarchive,
],
)
@ -41,7 +40,6 @@ if get_option('enable-tests')
dependencies : [
plugin_deps,
sqlite,
libarchive,
valgrind,
],
link_with : [

View File

@ -22,6 +22,8 @@
#include <config.h>
#include <gio/gunixinputstream.h>
#include <archive_entry.h>
#include <archive.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);
}
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,
gsize count,
GError **error);
gboolean fu_common_extract_archive (GBytes *blob,
const gchar *dir,
GError **error);
#endif /* __FU_COMMON_H__ */

View File

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

View File

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