mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-11 06:05:31 +00:00
libfwupd: Add fwupd_client_install_release()
This allows us to remove a lot of copy-and-paste code in GNOME Software.
This commit is contained in:
parent
02d94d3139
commit
f4c55d888e
@ -1426,6 +1426,101 @@ fwupd_client_install (FwupdClient *client,
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_client_install_release:
|
||||
* @client: A #FwupdClient
|
||||
* @device: A #FwupdDevice
|
||||
* @release: A #FwupdRelease
|
||||
* @install_flags: the #FwupdInstallFlags, e.g. %FWUPD_INSTALL_FLAG_ALLOW_REINSTALL
|
||||
* @cancellable: A #GCancellable, or %NULL
|
||||
* @error: A #GError, or %NULL
|
||||
*
|
||||
* Installs a new release on a device, downloading the firmware if required.
|
||||
*
|
||||
* Returns: %TRUE for success
|
||||
*
|
||||
* Since: 1.4.5
|
||||
**/
|
||||
gboolean
|
||||
fwupd_client_install_release (FwupdClient *client,
|
||||
FwupdDevice *device,
|
||||
FwupdRelease *release,
|
||||
FwupdInstallFlags install_flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
GChecksumType checksum_type;
|
||||
const gchar *checksum_expected;
|
||||
const gchar *remote_id;
|
||||
const gchar *uri_tmp;
|
||||
g_autofree gchar *checksum_actual = NULL;
|
||||
g_autofree gchar *uri_str = NULL;
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
|
||||
/* work out what remote-specific URI fields this should use */
|
||||
uri_tmp = fwupd_release_get_uri (release);
|
||||
remote_id = fwupd_release_get_remote_id (release);
|
||||
if (remote_id != NULL) {
|
||||
g_autoptr(FwupdRemote) remote = NULL;
|
||||
g_autofree gchar *fn = NULL;
|
||||
|
||||
/* if a remote-id was specified, the remote has to exist */
|
||||
remote = fwupd_client_get_remote_by_id (client, remote_id, cancellable, error);
|
||||
if (remote == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* local and directory remotes have the firmware already */
|
||||
if (fwupd_remote_get_kind (remote) == FWUPD_REMOTE_KIND_LOCAL) {
|
||||
const gchar *fn_cache = fwupd_remote_get_filename_cache (remote);
|
||||
g_autofree gchar *path = g_path_get_dirname (fn_cache);
|
||||
|
||||
fn = g_build_filename (path, uri_tmp, NULL);
|
||||
} else if (fwupd_remote_get_kind (remote) == FWUPD_REMOTE_KIND_DIRECTORY) {
|
||||
fn = g_strdup (uri_tmp + 7);
|
||||
}
|
||||
|
||||
/* install with flags chosen by the user */
|
||||
if (fn != NULL) {
|
||||
return fwupd_client_install (client, fwupd_device_get_id (device),
|
||||
fn, install_flags, cancellable, error);
|
||||
}
|
||||
|
||||
/* remote file */
|
||||
uri_str = fwupd_remote_build_firmware_uri (remote, uri_tmp, error);
|
||||
if (uri_str == NULL)
|
||||
return FALSE;
|
||||
} else {
|
||||
uri_str = g_strdup (uri_tmp);
|
||||
}
|
||||
|
||||
/* download file */
|
||||
blob = fwupd_client_download_bytes (client, uri_str,
|
||||
FWUPD_CLIENT_DOWNLOAD_FLAG_NONE,
|
||||
cancellable, error);
|
||||
if (blob == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* verify checksum */
|
||||
checksum_expected = fwupd_checksum_get_best (fwupd_release_get_checksums (release));
|
||||
checksum_type = fwupd_checksum_guess_kind (checksum_expected);
|
||||
checksum_actual = g_compute_checksum_for_bytes (checksum_type, blob);
|
||||
if (g_strcmp0 (checksum_expected, checksum_actual) != 0) {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"Checksum invalid, expected %s got %s",
|
||||
checksum_expected, checksum_actual);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* if the device specifies ONLY_OFFLINE automatically set this flag */
|
||||
if (fwupd_device_has_flag (device, FWUPD_DEVICE_FLAG_ONLY_OFFLINE))
|
||||
install_flags |= FWUPD_INSTALL_FLAG_OFFLINE;
|
||||
return fwupd_client_install_bytes (client,
|
||||
fwupd_device_get_id (device), blob,
|
||||
install_flags, NULL, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_client_get_details:
|
||||
* @client: A #FwupdClient
|
||||
|
@ -144,6 +144,12 @@ gboolean fwupd_client_install_bytes (FwupdClient *client,
|
||||
FwupdInstallFlags install_flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_install_release (FwupdClient *client,
|
||||
FwupdDevice *device,
|
||||
FwupdRelease *release,
|
||||
FwupdInstallFlags install_flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_update_metadata (FwupdClient *client,
|
||||
const gchar *remote_id,
|
||||
const gchar *metadata_fn,
|
||||
|
@ -451,6 +451,7 @@ LIBFWUPD_1.4.5 {
|
||||
global:
|
||||
fwupd_client_download_bytes;
|
||||
fwupd_client_install_bytes;
|
||||
fwupd_client_install_release;
|
||||
fwupd_client_refresh_remote;
|
||||
fwupd_client_set_feature_flags;
|
||||
fwupd_client_set_user_agent;
|
||||
|
153
src/fu-util.c
153
src/fu-util.c
@ -78,11 +78,6 @@ struct FuUtilPrivate {
|
||||
};
|
||||
|
||||
static gboolean fu_util_report_history (FuUtilPrivate *priv, gchar **values, GError **error);
|
||||
static gboolean fu_util_download_file (FuUtilPrivate *priv,
|
||||
const gchar *uri_str,
|
||||
const gchar *fn,
|
||||
const gchar *checksum_expected,
|
||||
GError **error);
|
||||
|
||||
static void
|
||||
fu_util_client_notify_cb (GObject *object,
|
||||
@ -562,6 +557,7 @@ static gchar *
|
||||
fu_util_download_if_required (FuUtilPrivate *priv, const gchar *perhapsfn, GError **error)
|
||||
{
|
||||
g_autofree gchar *filename = NULL;
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
g_autoptr(SoupURI) uri = NULL;
|
||||
|
||||
/* a local file */
|
||||
@ -575,7 +571,14 @@ fu_util_download_if_required (FuUtilPrivate *priv, const gchar *perhapsfn, GErro
|
||||
filename = fu_util_get_user_cache_path (perhapsfn);
|
||||
if (!fu_common_mkdir_parent (filename, error))
|
||||
return NULL;
|
||||
if (!fu_util_download_file (priv, perhapsfn, filename, NULL, error))
|
||||
blob = fwupd_client_download_bytes (priv->client, perhapsfn,
|
||||
FWUPD_CLIENT_DOWNLOAD_FLAG_NONE,
|
||||
priv->cancellable, error);
|
||||
if (blob == NULL)
|
||||
return NULL;
|
||||
|
||||
/* save file to cache */
|
||||
if (!fu_common_set_contents_bytes (filename, blob, error))
|
||||
return NULL;
|
||||
return g_steal_pointer (&filename);
|
||||
}
|
||||
@ -1003,82 +1006,6 @@ fu_util_verify_update (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_util_file_exists_with_checksum (const gchar *fn,
|
||||
const gchar *checksum_expected,
|
||||
GChecksumType checksum_type)
|
||||
{
|
||||
gsize len = 0;
|
||||
g_autofree gchar *checksum_actual = NULL;
|
||||
g_autofree gchar *data = NULL;
|
||||
|
||||
if (!g_file_get_contents (fn, &data, &len, NULL))
|
||||
return FALSE;
|
||||
checksum_actual = g_compute_checksum_for_data (checksum_type,
|
||||
(guchar *) data, len);
|
||||
return g_strcmp0 (checksum_expected, checksum_actual) == 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_util_download_file (FuUtilPrivate *priv,
|
||||
const gchar *uri_str,
|
||||
const gchar *fn,
|
||||
const gchar *checksum_expected,
|
||||
GError **error)
|
||||
{
|
||||
GChecksumType checksum_type;
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autofree gchar *checksum_actual = NULL;
|
||||
|
||||
/* check if the file already exists with the right checksum */
|
||||
checksum_type = fwupd_checksum_guess_kind (checksum_expected);
|
||||
if (fu_util_file_exists_with_checksum (fn, checksum_expected, checksum_type)) {
|
||||
g_debug ("skpping download as file already exists");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* download data */
|
||||
if (g_str_has_suffix (uri_str, ".jcat") ||
|
||||
g_str_has_suffix (uri_str, ".asc") ||
|
||||
g_str_has_suffix (uri_str, ".p7b") ||
|
||||
g_str_has_suffix (uri_str, ".p7c")) {
|
||||
/* TRANSLATORS: downloading new signing file */
|
||||
g_print ("%s %s", _("Fetching signature"), uri_str);
|
||||
} else if (g_str_has_suffix (uri_str, ".gz")) {
|
||||
/* TRANSLATORS: downloading new metadata file */
|
||||
g_print ("%s %s", _("Fetching metadata"), uri_str);
|
||||
} else if (g_str_has_suffix (uri_str, ".cab")) {
|
||||
/* TRANSLATORS: downloading new firmware file */
|
||||
g_print ("%s %s", _("Fetching firmware"), uri_str);
|
||||
} else {
|
||||
/* TRANSLATORS: downloading unknown file */
|
||||
g_print ("%s %s", _("Fetching file"), uri_str);
|
||||
}
|
||||
g_print ("\n");
|
||||
blob = fwupd_client_download_bytes (priv->client, uri_str,
|
||||
FWUPD_CLIENT_DOWNLOAD_FLAG_NONE,
|
||||
priv->cancellable, error);
|
||||
if (blob == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* verify checksum */
|
||||
if (checksum_expected != NULL) {
|
||||
checksum_actual = g_compute_checksum_for_bytes (checksum_type, blob);
|
||||
if (g_strcmp0 (checksum_expected, checksum_actual) != 0) {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"Checksum invalid, expected %s got %s",
|
||||
checksum_expected, checksum_actual);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* save file */
|
||||
return fu_common_set_contents_bytes (fn, blob, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_util_download_metadata_enable_lvfs (FuUtilPrivate *priv, GError **error)
|
||||
{
|
||||
@ -1552,72 +1479,14 @@ fu_util_update_device_with_release (FuUtilPrivate *priv,
|
||||
FwupdRelease *rel,
|
||||
GError **error)
|
||||
{
|
||||
GPtrArray *checksums;
|
||||
const gchar *remote_id;
|
||||
const gchar *uri_tmp;
|
||||
g_autofree gchar *fn = NULL;
|
||||
g_autofree gchar *uri_str = NULL;
|
||||
|
||||
if (!priv->no_safety_check && !priv->assume_yes) {
|
||||
if (!fu_util_prompt_warning (dev,
|
||||
fu_util_get_tree_title (priv),
|
||||
error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* work out what remote-specific URI fields this should use */
|
||||
uri_tmp = fwupd_release_get_uri (rel);
|
||||
remote_id = fwupd_release_get_remote_id (rel);
|
||||
if (remote_id != NULL) {
|
||||
g_autoptr(FwupdRemote) remote = NULL;
|
||||
remote = fwupd_client_get_remote_by_id (priv->client,
|
||||
remote_id,
|
||||
NULL,
|
||||
error);
|
||||
if (remote == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* local and directory remotes have the firmware already */
|
||||
if (fwupd_remote_get_kind (remote) == FWUPD_REMOTE_KIND_LOCAL) {
|
||||
const gchar *fn_cache = fwupd_remote_get_filename_cache (remote);
|
||||
g_autofree gchar *path = g_path_get_dirname (fn_cache);
|
||||
|
||||
fn = g_build_filename (path, uri_tmp, NULL);
|
||||
} else if (fwupd_remote_get_kind (remote) == FWUPD_REMOTE_KIND_DIRECTORY) {
|
||||
fn = g_strdup (uri_tmp + 7);
|
||||
}
|
||||
/* install with flags chosen by the user */
|
||||
if (fn != NULL) {
|
||||
return fwupd_client_install (priv->client,
|
||||
fwupd_device_get_id (dev),
|
||||
fn, priv->flags, NULL, error);
|
||||
}
|
||||
|
||||
uri_str = fwupd_remote_build_firmware_uri (remote, uri_tmp, error);
|
||||
if (uri_str == NULL)
|
||||
return FALSE;
|
||||
} else {
|
||||
uri_str = g_strdup (uri_tmp);
|
||||
}
|
||||
|
||||
/* download file */
|
||||
g_print ("Downloading %s for %s...\n",
|
||||
fwupd_release_get_version (rel),
|
||||
fwupd_device_get_name (dev));
|
||||
fn = fu_util_get_user_cache_path (uri_str);
|
||||
if (!fu_common_mkdir_parent (fn, error))
|
||||
return FALSE;
|
||||
checksums = fwupd_release_get_checksums (rel);
|
||||
if (!fu_util_download_file (priv, uri_str, fn,
|
||||
fwupd_checksum_get_best (checksums),
|
||||
error))
|
||||
return FALSE;
|
||||
/* if the device specifies ONLY_OFFLINE automatically set this flag */
|
||||
if (fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_ONLY_OFFLINE))
|
||||
priv->flags |= FWUPD_INSTALL_FLAG_OFFLINE;
|
||||
return fwupd_client_install (priv->client,
|
||||
fwupd_device_get_id (dev), fn,
|
||||
priv->flags, NULL, error);
|
||||
return fwupd_client_install_release (priv->client, dev, rel, priv->flags,
|
||||
priv->cancellable, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
Loading…
Reference in New Issue
Block a user