mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-14 17:28:20 +00:00
trivial: Move the archive decompression to common code
This commit is contained in:
parent
d7704d4cc2
commit
94f939aa4d
@ -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')
|
||||||
|
@ -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
|
||||||
|
@ -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));
|
||||||
|
@ -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 : [
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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__ */
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
@ -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 : [
|
||||||
|
Loading…
Reference in New Issue
Block a user