/** * fwupd_result_new: * * Creates a new result. * * Returns: a new #FwupdResult * * Since: 0.7.0 **/ FwupdResult * fwupd_result_new (void) { FwupdResult *result; result = g_object_new (FWUPD_TYPE_RESULT, NULL); return FWUPD_RESULT (result); }
/** * fwupd_result_finalize: **/ static void fwupd_result_finalize (GObject *object) { FwupdResult *result = FWUPD_RESULT (object); FwupdResultPrivate *priv = GET_PRIVATE (result); g_free (priv->device_description); g_free (priv->device_checksum); g_free (priv->device_id); g_free (priv->device_name); g_free (priv->device_vendor); g_free (priv->device_provider); g_free (priv->device_version); g_free (priv->device_version_lowest); g_free (priv->guid); g_free (priv->update_description); g_free (priv->update_error); g_free (priv->update_filename); g_free (priv->update_checksum); g_free (priv->update_id); g_free (priv->update_license); g_free (priv->update_name); g_free (priv->update_summary); g_free (priv->update_uri); g_free (priv->update_homepage); g_free (priv->update_vendor); g_free (priv->update_version); G_OBJECT_CLASS (fwupd_result_parent_class)->finalize (object); }
/** * fu_provider_clear_results: **/ gboolean fu_provider_clear_results (FuProvider *provider, FuDevice *device, GError **error) { FuProviderClass *klass = FU_PROVIDER_GET_CLASS (provider); g_autoptr(GError) error_local = NULL; g_autoptr(FwupdResult) res_pending = NULL; g_autoptr(FuPending) pending = NULL; /* handled by the provider */ if (klass->clear_results != NULL) return klass->clear_results (provider, device, error); /* handled using the database */ pending = fu_pending_new (); res_pending = fu_pending_get_device (pending, fu_device_get_id (device), &error_local); if (res_pending == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Failed to find %s in pending database: %s", fu_device_get_id (device), error_local->message); return FALSE; } /* remove from pending database */ return fu_pending_remove_device (pending, FWUPD_RESULT (device), error); }
/** * fu_provider_schedule_update: **/ static gboolean fu_provider_schedule_update (FuProvider *provider, FuDevice *device, GBytes *blob_cab, GError **error) { gchar tmpname[] = {"XXXXXX.cap"}; guint i; g_autofree gchar *dirname = NULL; g_autofree gchar *filename = NULL; g_autoptr(FwupdResult) res_tmp = NULL; g_autoptr(FuPending) pending = NULL; g_autoptr(GFile) file = NULL; /* id already exists */ pending = fu_pending_new (); res_tmp = fu_pending_get_device (pending, fu_device_get_id (device), NULL); if (res_tmp != NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_ALREADY_PENDING, "%s is already scheduled to be updated", fu_device_get_id (device)); return FALSE; } /* create directory */ dirname = g_build_filename (LOCALSTATEDIR, "lib", "fwupd", NULL); file = g_file_new_for_path (dirname); if (!g_file_query_exists (file, NULL)) { if (!g_file_make_directory_with_parents (file, NULL, error)) return FALSE; } /* get a random filename */ for (i = 0; i < 6; i++) tmpname[i] = g_random_int_range ('A', 'Z'); filename = g_build_filename (dirname, tmpname, NULL); /* just copy to the temp file */ fu_provider_set_status (provider, FWUPD_STATUS_SCHEDULING); if (!g_file_set_contents (filename, g_bytes_get_data (blob_cab, NULL), g_bytes_get_size (blob_cab), error)) return FALSE; /* schedule for next boot */ g_debug ("schedule %s to be installed to %s on next boot", filename, fu_device_get_id (device)); fu_device_set_update_filename (device, filename); /* add to database */ if (!fu_pending_add_device (pending, FWUPD_RESULT (device), error)) return FALSE; /* next boot we run offline */ return fu_provider_offline_setup (error); }
/** * fwupd_result_get_property: **/ static void fwupd_result_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { FwupdResult *result = FWUPD_RESULT (object); FwupdResultPrivate *priv = GET_PRIVATE (result); switch (prop_id) { case PROP_DEVICE_ID: g_value_set_string (value, priv->device_id); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
/** * fu_provider_update: **/ gboolean fu_provider_update (FuProvider *provider, FuDevice *device, GBytes *blob_cab, GBytes *blob_fw, FuPlugin *plugin, FwupdInstallFlags flags, GError **error) { FuProviderClass *klass = FU_PROVIDER_GET_CLASS (provider); g_autoptr(FuPending) pending = NULL; g_autoptr(FwupdResult) res_pending = NULL; GError *error_update = NULL; /* schedule for next reboot, or handle in the provider */ if (flags & FWUPD_INSTALL_FLAG_OFFLINE) { if (klass->update_offline == NULL) return fu_provider_schedule_update (provider, device, blob_cab, error); return klass->update_offline (provider, device, blob_fw, flags, error); } /* cancel the pending action */ if (!fu_provider_offline_invalidate (error)) return FALSE; /* we have support using a plugin */ if (plugin != NULL) { return fu_plugin_run_device_update (plugin, device, blob_fw, error); } /* online */ if (klass->update_online == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "No online update possible"); return FALSE; } pending = fu_pending_new (); res_pending = fu_pending_get_device (pending, fu_device_get_id (device), NULL); if (!klass->update_online (provider, device, blob_fw, flags, &error_update)) { /* save the error to the database */ if (res_pending != NULL) { fu_pending_set_error_msg (pending, FWUPD_RESULT (device), error_update->message, NULL); } g_propagate_error (error, error_update); return FALSE; } /* cleanup */ if (res_pending != NULL) { const gchar *tmp; /* update pending database */ fu_pending_set_state (pending, FWUPD_RESULT (device), FWUPD_UPDATE_STATE_SUCCESS, NULL); /* delete cab file */ tmp = fwupd_result_get_update_filename (res_pending); if (tmp != NULL && g_str_has_prefix (tmp, LIBEXECDIR)) { g_autoptr(GError) error_local = NULL; g_autoptr(GFile) file = NULL; file = g_file_new_for_path (tmp); if (!g_file_delete (file, NULL, &error_local)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Failed to delete %s: %s", tmp, error_local->message); return FALSE; } } } return TRUE; }