[gnome-software/wip/hughsie/fwupd: 15/21] Actually download the firmware updates
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/hughsie/fwupd: 15/21] Actually download the firmware updates
- Date: Wed, 11 Mar 2015 19:50:18 +0000 (UTC)
commit fe1897667c10190e1709c1fe99a63fc06571aee4
Author: Richard Hughes <richard hughsie com>
Date: Thu Mar 5 20:31:35 2015 +0000
Actually download the firmware updates
src/plugins/gs-plugin-fwupd.c | 165 ++++++++++++++++++++++++++++++++++++++++-
1 files changed, 163 insertions(+), 2 deletions(-)
---
diff --git a/src/plugins/gs-plugin-fwupd.c b/src/plugins/gs-plugin-fwupd.c
index 00a6cd7..543ad13 100644
--- a/src/plugins/gs-plugin-fwupd.c
+++ b/src/plugins/gs-plugin-fwupd.c
@@ -21,6 +21,7 @@
#include <config.h>
#include <gio/gio.h>
+#include <libsoup/soup.h>
#include "gs-cleanup.h"
@@ -34,10 +35,42 @@
struct GsPluginPrivate {
gsize done_init;
GDBusProxy *proxy;
+ GPtrArray *to_download;
AsStore *store;
+ GPtrArray *to_ignore;
+ SoupSession *session;
+ gchar *cachedir;
};
/**
+ * gs_plugin_fwupd_setup_networking:
+ */
+static gboolean
+gs_plugin_fwupd_setup_networking (GsPlugin *plugin, GError **error)
+{
+ /* already set up */
+ if (plugin->priv->session != NULL)
+ return TRUE;
+
+ /* set up a session */
+ plugin->priv->session = soup_session_sync_new_with_options (SOUP_SESSION_USER_AGENT,
+ "gnome-software",
+ SOUP_SESSION_TIMEOUT, 5000,
+ NULL);
+ if (plugin->priv->session == NULL) {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "%s: failed to setup networking",
+ plugin->name);
+ return FALSE;
+ }
+ soup_session_add_feature_by_type (plugin->priv->session,
+ SOUP_TYPE_PROXY_RESOLVER_DEFAULT);
+ return TRUE;
+}
+
+/**
* gs_plugin_get_name:
*/
const gchar *
@@ -54,6 +87,8 @@ gs_plugin_initialize (GsPlugin *plugin)
{
plugin->priv = GS_PLUGIN_GET_PRIVATE (GsPluginPrivate);
plugin->priv->store = as_store_new ();
+ plugin->priv->to_download = g_ptr_array_new_with_free_func (g_free);
+ plugin->priv->to_ignore = g_ptr_array_new_with_free_func (g_free);
}
/**
@@ -62,9 +97,14 @@ gs_plugin_initialize (GsPlugin *plugin)
void
gs_plugin_destroy (GsPlugin *plugin)
{
+ g_free (plugin->priv->cachedir);
g_object_unref (plugin->priv->store);
+ g_ptr_array_unref (plugin->priv->to_download);
+ g_ptr_array_unref (plugin->priv->to_ignore);
if (plugin->priv->proxy != NULL)
g_object_unref (plugin->priv->proxy);
+ if (plugin->priv->session != NULL)
+ g_object_unref (plugin->priv->session);
}
/**
@@ -73,6 +113,7 @@ gs_plugin_destroy (GsPlugin *plugin)
static gboolean
gs_plugin_startup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
{
+ gint rc;
_cleanup_object_unref_ GDBusConnection *conn = NULL;
conn = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error);
if (conn == NULL)
@@ -88,6 +129,20 @@ gs_plugin_startup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
if (plugin->priv->proxy == NULL)
return FALSE;
+ /* create the cache location */
+ plugin->priv->cachedir = g_build_filename (g_get_user_cache_dir (),
+ "gnome-software",
+ "firmware",
+ NULL);
+ rc = g_mkdir_with_parents (plugin->priv->cachedir, 0700);
+ if (rc != 0) {
+ g_set_error_literal (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "Could not create firmware cache");
+ return FALSE;
+ }
+
/* this is hugely wasteful */
if (!as_store_load (plugin->priv->store,
AS_STORE_LOAD_FLAG_APP_INFO_SYSTEM,
@@ -98,6 +153,27 @@ gs_plugin_startup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
}
/**
+ * gs_plugin_fwupd_add_required_location:
+ */
+static void
+gs_plugin_fwupd_add_required_location (GsPlugin *plugin, const gchar *location)
+{
+ const gchar *tmp;
+ guint i;
+ for (i = 0; i < plugin->priv->to_ignore->len; i++) {
+ tmp = g_ptr_array_index (plugin->priv->to_ignore, i);
+ if (g_strcmp0 (tmp, location) == 0)
+ return;
+ }
+ for (i = 0; i < plugin->priv->to_download->len; i++) {
+ tmp = g_ptr_array_index (plugin->priv->to_download, i);
+ if (g_strcmp0 (tmp, location) == 0)
+ return;
+ }
+ g_ptr_array_add (plugin->priv->to_download, g_strdup (location));
+}
+
+/**
* gs_plugin_fwupd_add_device:
*/
static gboolean
@@ -112,6 +188,9 @@ gs_plugin_fwupd_add_device (GsPlugin *plugin,
GPtrArray *releases;
const gchar *tmp;
guint i;
+ _cleanup_free_ gchar *basename = NULL;
+ _cleanup_free_ gchar *filename_cache = NULL;
+ _cleanup_free_ gchar *update_location = NULL;
_cleanup_free_ gchar *update_version = NULL;
_cleanup_object_unref_ GsApp *app = NULL;
_cleanup_string_free_ GString *update_desc = NULL;
@@ -140,8 +219,10 @@ gs_plugin_fwupd_add_device (GsPlugin *plugin,
continue;
/* get the update text, if it exists */
- if (update_version == NULL)
+ if (update_version == NULL) {
update_version = g_strdup (as_release_get_version (rel));
+ update_location = g_strdup (as_release_get_location_default (rel));
+ }
tmp = as_release_get_description (rel, NULL);
if (tmp == NULL)
continue;
@@ -161,6 +242,28 @@ gs_plugin_fwupd_add_device (GsPlugin *plugin,
return FALSE;
}
+ /* nowhere to download the update from */
+ if (update_location == NULL) {
+ g_set_error_literal (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "no location available for firmware");
+ return FALSE;
+ }
+
+ /* does the firmware already exist in the cache? */
+ basename = g_path_get_basename (update_location);
+ filename_cache = g_build_filename (plugin->priv->cachedir, basename, NULL);
+ if (!g_file_test (filename_cache, G_FILE_TEST_EXISTS)) {
+ gs_plugin_fwupd_add_required_location (plugin, update_location);
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "%s does not yet exist, wait patiently",
+ filename_cache);
+ return FALSE;
+ }
+
/* remove trailing newline */
if (update_desc->len > 0)
g_string_truncate (update_desc, update_desc->len - 1);
@@ -171,7 +274,7 @@ gs_plugin_fwupd_add_device (GsPlugin *plugin,
gs_app_set_state (app, AS_APP_STATE_UPDATABLE);
gs_app_set_update_details (app, update_desc->str);
gs_app_set_update_version (app, update_version);
-// gs_app_add_source_id (app, package_ids[i]);
+ gs_app_add_source_id (app, filename_cache);
gs_app_add_source (app, as_app_get_name (item, NULL));
gs_app_set_kind (app, GS_APP_KIND_SYSTEM);
gs_plugin_add_app (list, app);
@@ -247,3 +350,61 @@ gs_plugin_add_updates (GsPlugin *plugin,
return TRUE;
}
+
+/**
+ * gs_plugin_refresh:
+ */
+gboolean
+gs_plugin_refresh (GsPlugin *plugin,
+ guint cache_age,
+ GsPluginRefreshFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ const gchar *tmp;
+ guint i;
+
+ /* ensure networking is set up */
+ if (!gs_plugin_fwupd_setup_networking (plugin, error))
+ return FALSE;
+
+ /* download the files to the cachedir */
+ for (i = 0; i < plugin->priv->to_download->len; i++) {
+ guint status_code;
+ _cleanup_error_free_ GError *error_local = NULL;
+ _cleanup_free_ gchar *basename = NULL;
+ _cleanup_free_ gchar *filename_cache = NULL;
+ _cleanup_object_unref_ SoupMessage *msg = NULL;
+
+ tmp = g_ptr_array_index (plugin->priv->to_download, i);
+ basename = g_path_get_basename (tmp);
+ filename_cache = g_build_filename (plugin->priv->cachedir, basename, NULL);
+ g_debug ("downloading %s to %s", tmp, filename_cache);
+
+ /* set sync request */
+ msg = soup_message_new (SOUP_METHOD_GET, tmp);
+ status_code = soup_session_send_message (plugin->priv->session, msg);
+ if (status_code != SOUP_STATUS_OK) {
+ g_warning ("Failed to download %s, ignoring: %s",
+ tmp, soup_status_get_phrase (status_code));
+ g_ptr_array_remove (plugin->priv->to_download, (gpointer) tmp);
+ g_ptr_array_add (plugin->priv->to_ignore, g_strdup (tmp));
+ continue;
+ }
+
+ /* save binary file */
+ if (!g_file_set_contents (filename_cache,
+ msg->response_body->data,
+ msg->response_body->length,
+ &error_local)) {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "Failed to save firmware: %s",
+ error_local->message);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]