static GsApp* gs_plugin_app_from_pki (LiPkgInfo *pki) { const gchar *cptkind_str; GsApp *app; cptkind_str = li_pkg_info_get_component_kind (pki); if ((cptkind_str != NULL) && (g_strcmp0 (cptkind_str, "desktop") == 0)) { g_autofree gchar *tmp = NULL; /* type=desktop AppStream components result in a Limba bundle name which has the .desktop stripped away. * We need to re-add it for GNOME Software. * In any other case, the Limba bundle name equals the AppStream ID of the component it contains */ tmp = g_strdup_printf ("%s.desktop", li_pkg_info_get_name (pki)); app = gs_app_new (tmp); gs_app_set_kind (app, AS_APP_KIND_DESKTOP); } else { app = gs_app_new (li_pkg_info_get_name (pki)); gs_app_set_kind (app, AS_APP_KIND_GENERIC); } /* TODO: scope?, branch? */ gs_app_set_management_plugin (app, "limba"); gs_app_set_state (app, AS_APP_STATE_UPDATABLE_LIVE); gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_LIMBA); gs_app_set_name (app, GS_APP_QUALITY_LOWEST, li_pkg_info_get_name (pki)); gs_app_set_summary (app, GS_APP_QUALITY_LOWEST, li_pkg_info_get_name (pki)); gs_app_set_version (app, li_pkg_info_get_version (pki)); gs_app_add_source (app, li_pkg_info_get_id (pki)); return app; }
gboolean gs_plugin_add_updates (GsPlugin *plugin, GsAppList *list, GCancellable *cancellable, GError **error) { guint i; g_autoptr(GError) error_local = NULL; g_auto(GStrv) package_ids = NULL; /* get the id's if the file exists */ package_ids = pk_offline_get_prepared_ids (&error_local); if (package_ids == NULL) { if (g_error_matches (error_local, PK_OFFLINE_ERROR, PK_OFFLINE_ERROR_NO_DATA)) { return TRUE; } g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_INVALID_FORMAT, "Failed to get prepared IDs: %s", error_local->message); return FALSE; } /* add them to the new array */ for (i = 0; package_ids[i] != NULL; i++) { g_autoptr(GsApp) app = NULL; g_auto(GStrv) split = NULL; /* search in the cache */ app = gs_plugin_cache_lookup (plugin, package_ids[i]); if (app != NULL) { gs_app_list_add (list, app); continue; } /* create new app */ app = gs_app_new (NULL); gs_app_add_quirk (app, AS_APP_QUIRK_NEEDS_REBOOT); gs_app_set_management_plugin (app, "packagekit"); gs_app_add_source_id (app, package_ids[i]); split = pk_package_id_split (package_ids[i]); gs_app_add_source (app, split[PK_PACKAGE_ID_NAME]); gs_app_set_update_version (app, split[PK_PACKAGE_ID_VERSION]); gs_app_set_state (app, AS_APP_STATE_UPDATABLE); gs_app_set_kind (app, AS_APP_KIND_GENERIC); gs_app_set_size_download (app, 0); gs_app_list_add (list, app); /* save in the cache */ gs_plugin_cache_add (plugin, package_ids[i], app); } return TRUE; }
/** * gs_refine_item_management_plugin: */ static void gs_refine_item_management_plugin (GsApp *app, AsApp *item) { GPtrArray *bundles; const gchar *management_plugin = NULL; const gchar *runtime = NULL; guint i; /* find the default bundle kind */ bundles = as_app_get_bundles (item); for (i = 0; i < bundles->len; i++) { AsBundle *bundle = g_ptr_array_index (bundles, i); if (as_bundle_get_kind (bundle) == AS_BUNDLE_KIND_XDG_APP) { management_plugin = "XgdApp"; gs_app_add_source (app, as_bundle_get_id (bundle)); /* automatically add runtime */ runtime = as_bundle_get_runtime (bundle); if (runtime != NULL) { g_autoptr(GsApp) app2 = NULL; app2 = gs_appstream_create_runtime (app, runtime); if (app2 != NULL) { g_debug ("runtime for %s is %s", gs_app_get_id (app), runtime); gs_app_set_runtime (app, app2); } } break; } if (as_bundle_get_kind (bundle) == AS_BUNDLE_KIND_LIMBA) { management_plugin = "Limba"; gs_app_add_source (app, as_bundle_get_id (bundle)); break; } } /* fall back to PackageKit */ if (management_plugin == NULL && as_app_get_pkgname_default (item) != NULL) management_plugin = "PackageKit"; if (management_plugin != NULL) gs_app_set_management_plugin (app, management_plugin); }
/** * gs_appstream_create_runtime: */ GsApp * gs_appstream_create_runtime (GsApp *parent, const gchar *runtime) { const gchar *id_parent; g_autofree gchar *id = NULL; g_autofree gchar *source = NULL; g_auto(GStrv) id_split = NULL; g_auto(GStrv) runtime_split = NULL; g_autoptr(GsApp) app = NULL; /* get the name/arch/branch */ runtime_split = g_strsplit (runtime, "/", -1); if (g_strv_length (runtime_split) != 3) return NULL; /* find the parent app ID prefix */ id_parent = gs_app_get_id (parent); if (id_parent == NULL) return NULL; id_split = g_strsplit (id_parent, ":", 2); if (g_strv_length (id_split) == 2) { id = g_strdup_printf ("%s:%s.runtime", id_split[0], runtime_split[0]); } else { id = g_strdup_printf ("%s.runtime", runtime_split[0]); } /* create the complete GsApp from the single string */ app = gs_app_new (id); source = g_strdup_printf ("runtime/%s", runtime); gs_app_add_source (app, source); gs_app_set_kind (app, AS_APP_KIND_RUNTIME); gs_app_set_version (app, id_split[2]); return g_steal_pointer (&app); }
/** * gs_plugin_filename_to_app: */ gboolean gs_plugin_filename_to_app (GsPlugin *plugin, GList **list, const gchar *filename, GCancellable *cancellable, GError **error) { const gchar *package_id; gboolean supported; PkDetails *item; ProgressData data; g_autoptr (PkResults) results = NULL; g_autofree gchar *basename = NULL; g_autofree gchar *license_spdx = NULL; g_auto(GStrv) files = NULL; g_auto(GStrv) split = NULL; g_autoptr(GPtrArray) array = NULL; g_autoptr(GsApp) app = NULL; /* does this match any of the mimetypes we support */ if (!gs_plugin_packagekit_refresh_content_type_matches (filename, &supported, cancellable, error)) return FALSE; if (!supported) return TRUE; data.plugin = plugin; data.ptask = NULL; /* get details */ files = g_strsplit (filename, "\t", -1); pk_client_set_cache_age (PK_CLIENT (plugin->priv->task), G_MAXUINT); results = pk_client_get_details_local (PK_CLIENT (plugin->priv->task), files, cancellable, gs_plugin_packagekit_progress_cb, &data, error); if (results == NULL) return FALSE; /* get results */ array = pk_results_get_details_array (results); if (array->len == 0) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "no details for %s", filename); return FALSE; } if (array->len > 1) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "too many details [%i] for %s", array->len, filename); return FALSE; } /* create application */ item = g_ptr_array_index (array, 0); app = gs_app_new (NULL); package_id = pk_details_get_package_id (item); split = pk_package_id_split (package_id); basename = g_path_get_basename (filename); gs_app_set_management_plugin (app, "PackageKit"); gs_app_set_kind (app, GS_APP_KIND_PACKAGE); gs_app_set_state (app, AS_APP_STATE_AVAILABLE_LOCAL); if (pk_details_get_summary (item)) gs_app_set_name (app, GS_APP_QUALITY_LOWEST, pk_details_get_summary (item)); else gs_app_set_name (app, GS_APP_QUALITY_LOWEST, split[PK_PACKAGE_ID_NAME]); gs_app_set_version (app, split[PK_PACKAGE_ID_VERSION]); gs_app_set_metadata (app, "PackageKit::local-filename", filename); gs_app_set_origin (app, basename); gs_app_add_source (app, split[PK_PACKAGE_ID_NAME]); gs_app_add_source_id (app, package_id); gs_plugin_packagekit_refresh_set_text (app, pk_details_get_description (item)); gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, pk_details_get_url (item)); gs_app_set_size (app, pk_details_get_size (item)); license_spdx = as_utils_license_to_spdx (pk_details_get_license (item)); gs_app_set_licence (app, license_spdx, GS_APP_QUALITY_LOWEST); /* look for a desktop file so we can use a valid application id */ if (!gs_plugin_packagekit_refresh_guess_app_id (plugin, app, filename, cancellable, error)) return FALSE; gs_plugin_add_app (list, app); return TRUE; }
/** * gs_plugin_add_updates: */ gboolean gs_plugin_add_updates (GsPlugin *plugin, GList **list, GCancellable *cancellable, GError **error) { g_autoptr(GList) updates = NULL; GList *l; g_autoptr(GError) error_local = NULL; updates = li_manager_get_update_list (plugin->priv->mgr, &error_local); if (error_local != NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Failed to list updates: %s", error_local->message); return FALSE; } for (l = updates; l != NULL; l = l->next) { LiPkgInfo *old_pki; LiPkgInfo *new_pki; const gchar *cptkind_str; g_autoptr(GsApp) app = NULL; LiUpdateItem *uitem = LI_UPDATE_ITEM (l->data); old_pki = li_update_item_get_installed_pkg (uitem); new_pki = li_update_item_get_available_pkg (uitem); cptkind_str = li_pkg_info_get_component_kind (old_pki); if ((cptkind_str != NULL) && (g_strcmp0 (cptkind_str, "desktop") == 0)) { g_autofree gchar *tmp = NULL; /* type=desktop AppStream components result in a Limba bundle name which has the .desktop stripped away. * We need to re-add it for GNOME Software. * In any other case, the Limba bundle name equals the AppStream ID of the component it contains */ tmp = g_strdup_printf ("%s.desktop", li_pkg_info_get_name (old_pki)); app = gs_app_new (tmp); gs_app_set_kind (app, AS_APP_KIND_DESKTOP); } else { app = gs_app_new (li_pkg_info_get_name (old_pki)); } gs_app_set_management_plugin (app, "Limba"); gs_app_set_state (app, AS_APP_STATE_UPDATABLE_LIVE); gs_app_set_kind (app, AS_APP_KIND_GENERIC); gs_plugin_add_app (list, app); gs_app_set_name (app, GS_APP_QUALITY_LOWEST, li_pkg_info_get_name (old_pki)); gs_app_set_summary (app, GS_APP_QUALITY_LOWEST, li_pkg_info_get_name (old_pki)); gs_app_set_version (app, li_pkg_info_get_version (old_pki)); gs_app_set_update_version (app, li_pkg_info_get_version (new_pki)); gs_app_add_source (app, li_pkg_info_get_id (old_pki)); gs_plugin_add_app (list, app); } return TRUE; }
/** * gs_plugin_refine_app: */ gboolean gs_plugin_refine_app (GsPlugin *plugin, GsApp *app, GsPluginRefineFlags flags, GCancellable *cancellable, GError **error) { Header h; const gchar *fn; gint rc; g_auto(rpmdbMatchIterator) mi = NULL; g_auto(rpmts) ts = NULL; /* not required */ if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_VERSION) == 0 && (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_SIZE) == 0 && (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_LICENSE) == 0 && (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_SETUP_ACTION) == 0) return TRUE; /* no need to run the plugin */ if (gs_app_get_source_default (app) != NULL && gs_app_get_source_id_default (app) != NULL) return TRUE; /* open db readonly */ ts = rpmtsCreate(); rpmtsSetRootDir (ts, NULL); rc = rpmtsOpenDB (ts, O_RDONLY); if (rc != 0) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Failed to open rpmdb: %i", rc); return FALSE; } /* look for a specific file */ fn = gs_app_get_metadata_item (app, "appstream::source-file"); if (fn == NULL) return TRUE; if (!g_str_has_prefix (fn, "/usr")) return TRUE; mi = rpmtsInitIterator (ts, RPMDBI_INSTFILENAMES, fn, 0); if (mi == NULL) { g_debug ("rpm: no search results for %s", fn); return TRUE; } /* on rpm-ostree this package cannot be removed 'live' */ gs_app_add_quirk (app, AS_APP_QUIRK_COMPULSORY); /* process any results */ g_debug ("rpm: querying for %s with %s", gs_app_get_id (app), fn); while ((h = rpmdbNextIterator (mi)) != NULL) { guint64 epoch; const gchar *name; const gchar *version; const gchar *arch; const gchar *release; const gchar *license; /* add default source */ name = headerGetString (h, RPMTAG_NAME); if (gs_app_get_source_default (app) == NULL) { g_debug ("rpm: setting source to %s", name); gs_app_add_source (app, name); } /* set size */ if (gs_app_get_size_download (app) == 0) gs_app_set_size_download (app, 0); if (gs_app_get_size_installed (app) == 0) { guint64 tmp; tmp = headerGetNumber (h, RPMTAG_SIZE); gs_app_set_size_installed (app, tmp); } /* set license */ license = headerGetString (h, RPMTAG_LICENSE); if (gs_app_get_license (app) == NULL && license != NULL) { g_autofree gchar *tmp = NULL; tmp = as_utils_license_to_spdx (license); gs_app_set_license (app, GS_APP_QUALITY_NORMAL, tmp); } /* add version */ version = headerGetString (h, RPMTAG_VERSION); if (gs_app_get_version (app) == NULL) { g_debug ("rpm: setting version to %s", version); gs_app_set_version (app, version); } /* add source-id */ if (gs_app_get_source_id_default (app) == NULL) { g_autofree gchar *tmp = NULL; release = headerGetString (h, RPMTAG_RELEASE); arch = headerGetString (h, RPMTAG_ARCH); epoch = headerGetNumber (h, RPMTAG_EPOCH); if (epoch > 0) { tmp = g_strdup_printf ("%s;%" G_GUINT64_FORMAT ":%s-%s;%s;installed", name, epoch, version, release, arch); } else { tmp = g_strdup_printf ("%s;%s-%s;%s;installed", name, version, release, arch); } g_debug ("rpm: setting source-id to %s", tmp); gs_app_add_source_id (app, tmp); } } return TRUE; }
gboolean gs_plugin_file_to_app (GsPlugin *plugin, GsAppList *list, GFile *file, GCancellable *cancellable, GError **error) { GsApp *app; guint i; g_autofree gchar *content_type = NULL; g_autofree gchar *output = NULL; g_auto(GStrv) argv = NULL; g_auto(GStrv) tokens = NULL; g_autoptr(GString) str = NULL; const gchar *mimetypes[] = { "application/vnd.debian.binary-package", NULL }; /* does this match any of the mimetypes we support */ content_type = gs_utils_get_content_type (file, cancellable, error); if (content_type == NULL) return FALSE; if (!g_strv_contains (mimetypes, content_type)) return TRUE; /* exec sync */ argv = g_new0 (gchar *, 5); argv[0] = g_strdup (DPKG_DEB_BINARY); argv[1] = g_strdup ("--showformat=${Package}\\n" "${Version}\\n" "${Installed-Size}\\n" "${Homepage}\\n" "${Description}"); argv[2] = g_strdup ("-W"); argv[3] = g_file_get_path (file); if (!g_spawn_sync (NULL, argv, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL, NULL, NULL, &output, NULL, NULL, error)) { gs_utils_error_convert_gio (error); return FALSE; } /* parse output */ tokens = g_strsplit (output, "\n", 0); if (g_strv_length (tokens) < 5) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_NOT_SUPPORTED, "dpkg-deb output format incorrect:\n\"%s\"\n", output); return FALSE; } /* create app */ app = gs_app_new (NULL); gs_app_set_state (app, AS_APP_STATE_AVAILABLE_LOCAL); gs_app_add_source (app, tokens[0]); gs_app_set_name (app, GS_APP_QUALITY_LOWEST, tokens[0]); gs_app_set_version (app, tokens[1]); gs_app_set_size_installed (app, 1024 * g_ascii_strtoull (tokens[2], NULL, 10)); gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, tokens[3]); gs_app_set_summary (app, GS_APP_QUALITY_LOWEST, tokens[4]); gs_app_set_kind (app, AS_APP_KIND_GENERIC); gs_app_set_metadata (app, "GnomeSoftware::Creator", gs_plugin_get_name (plugin)); /* multiline text */ str = g_string_new (""); for (i = 5; tokens[i] != NULL; i++) { if (g_strcmp0 (tokens[i], " .") == 0) { if (str->len > 0) g_string_truncate (str, str->len - 1); g_string_append (str, "\n"); continue; } g_strstrip (tokens[i]); g_string_append_printf (str, "%s ", tokens[i]); } if (str->len > 0) g_string_truncate (str, str->len - 1); gs_app_set_description (app, GS_APP_QUALITY_LOWEST, str->str); /* success */ gs_app_list_add (list, app); return TRUE; }
gboolean gs_plugin_url_to_app (GsPlugin *plugin, GsAppList *list, const gchar *url, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); g_autofree gchar *scheme = NULL; g_autofree gchar *path = NULL; const gchar *id = NULL; const gchar * const *id_like = NULL; g_auto(GStrv) package_ids = NULL; g_autoptr(PkResults) results = NULL; g_autoptr(GsApp) app = NULL; g_autoptr(GsOsRelease) os_release = NULL; g_autoptr(GPtrArray) packages = NULL; g_autoptr(GPtrArray) details = NULL; g_autoptr(GsPackagekitHelper) helper = gs_packagekit_helper_new (plugin); path = gs_utils_get_url_path (url); /* only do this for apt:// on debian or debian-like distros */ os_release = gs_os_release_new (error); if (os_release == NULL) { g_prefix_error (error, "failed to determine OS information:"); return FALSE; } else { id = gs_os_release_get_id (os_release); id_like = gs_os_release_get_id_like (os_release); scheme = gs_utils_get_url_scheme (url); if (!(g_strcmp0 (scheme, "apt") == 0 && (g_strcmp0 (id, "debian") == 0 || g_strv_contains (id_like, "debian")))) { return TRUE; } } app = gs_app_new (NULL); gs_plugin_packagekit_set_packaging_format (plugin, app); gs_app_add_source (app, path); gs_app_set_kind (app, AS_APP_KIND_GENERIC); gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); package_ids = g_new0 (gchar *, 2); package_ids[0] = g_strdup (path); g_mutex_lock (&priv->client_mutex); results = pk_client_resolve (priv->client, pk_bitfield_from_enums (PK_FILTER_ENUM_NEWEST, PK_FILTER_ENUM_ARCH, -1), package_ids, cancellable, gs_packagekit_helper_cb, helper, error); g_mutex_unlock (&priv->client_mutex); if (!gs_plugin_packagekit_results_valid (results, error)) { g_prefix_error (error, "failed to resolve package_ids: "); return FALSE; } /* get results */ packages = pk_results_get_package_array (results); details = pk_results_get_details_array (results); if (packages->len >= 1) { if (gs_app_get_local_file (app) != NULL) return TRUE; gs_plugin_packagekit_resolve_packages_app (plugin, packages, app); gs_plugin_packagekit_refine_details_app (plugin, details, app); gs_app_list_add (list, app); } else { g_warning ("no results returned"); } return TRUE; }
/** * gs_plugin_add_updates_historical: */ gboolean gs_plugin_add_updates_historical (GsPlugin *plugin, GList **list, GCancellable *cancellable, GError **error) { gboolean ret; guint i; _cleanup_strv_free_ gchar **package_ids = NULL; _cleanup_free_ gchar *error_details = NULL; _cleanup_free_ gchar *packages = NULL; _cleanup_keyfile_unref_ GKeyFile *key_file = NULL; /* was any offline update attempted */ if (!g_file_test (PK_OFFLINE_UPDATE_RESULTS_FILENAME, G_FILE_TEST_EXISTS)) return TRUE; /* open the file */ key_file = g_key_file_new (); ret = g_key_file_load_from_file (key_file, PK_OFFLINE_UPDATE_RESULTS_FILENAME, G_KEY_FILE_NONE, error); if (!ret) return FALSE; /* only return results if successful */ ret = g_key_file_get_boolean (key_file, PK_OFFLINE_UPDATE_RESULTS_GROUP, "Success", NULL); if (!ret) { error_details = g_key_file_get_string (key_file, PK_OFFLINE_UPDATE_RESULTS_GROUP, "ErrorDetails", error); if (error_details == NULL) return FALSE; g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, error_details); return FALSE; } /* get list of package-ids */ packages = g_key_file_get_string (key_file, PK_OFFLINE_UPDATE_RESULTS_GROUP, "Packages", NULL); if (packages == NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_NOT_SUPPORTED, "No 'Packages' in %s", PK_OFFLINE_UPDATE_RESULTS_FILENAME); return FALSE; } package_ids = g_strsplit (packages, ",", -1); for (i = 0; package_ids[i] != NULL; i++) { _cleanup_object_unref_ GsApp *app = NULL; _cleanup_strv_free_ gchar **split = NULL; app = gs_app_new (NULL); split = g_strsplit (package_ids[i], ";", 4); gs_app_add_source (app, split[0]); gs_app_set_update_version (app, split[1]); gs_app_set_management_plugin (app, "PackageKit"); gs_app_add_source_id (app, package_ids[i]); gs_app_set_state (app, AS_APP_STATE_UPDATABLE); gs_app_set_kind (app, GS_APP_KIND_PACKAGE); gs_plugin_add_app (list, app); } return TRUE; }
gboolean gs_plugin_add_updates_historical (GsPlugin *plugin, GsAppList *list, GCancellable *cancellable, GError **error) { gboolean ret; guint64 mtime; guint i; g_auto(GStrv) package_ids = NULL; g_autofree gchar *packages = NULL; g_autoptr(GFile) file = NULL; g_autoptr(GFileInfo) info = NULL; g_autoptr(GKeyFile) key_file = NULL; /* was any offline update attempted */ if (!g_file_test (PK_OFFLINE_UPDATE_RESULTS_FILENAME, G_FILE_TEST_EXISTS)) return TRUE; /* get the mtime of the results */ file = g_file_new_for_path (PK_OFFLINE_UPDATE_RESULTS_FILENAME); info = g_file_query_info (file, G_FILE_ATTRIBUTE_TIME_MODIFIED, G_FILE_QUERY_INFO_NONE, cancellable, error); if (info == NULL) return FALSE; mtime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED); /* open the file */ key_file = g_key_file_new (); ret = g_key_file_load_from_file (key_file, PK_OFFLINE_UPDATE_RESULTS_FILENAME, G_KEY_FILE_NONE, error); if (!ret) return FALSE; /* only return results if successful */ ret = g_key_file_get_boolean (key_file, PK_OFFLINE_UPDATE_RESULTS_GROUP, "Success", NULL); if (!ret) { g_autofree gchar *code = NULL; g_autofree gchar *details = NULL; code = g_key_file_get_string (key_file, PK_OFFLINE_UPDATE_RESULTS_GROUP, "ErrorCode", error); if (code == NULL) return FALSE; details = g_key_file_get_string (key_file, PK_OFFLINE_UPDATE_RESULTS_GROUP, "ErrorDetails", error); if (details == NULL) return FALSE; return gs_plugin_packagekit_convert_error (error, pk_error_enum_from_string (code), details); } /* get list of package-ids */ packages = g_key_file_get_string (key_file, PK_OFFLINE_UPDATE_RESULTS_GROUP, "Packages", NULL); if (packages == NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_NOT_SUPPORTED, "No 'Packages' in %s", PK_OFFLINE_UPDATE_RESULTS_FILENAME); return FALSE; } package_ids = g_strsplit (packages, ",", -1); for (i = 0; package_ids[i] != NULL; i++) { g_autoptr(GsApp) app = NULL; g_auto(GStrv) split = NULL; app = gs_app_new (NULL); split = g_strsplit (package_ids[i], ";", 4); gs_app_add_source (app, split[0]); gs_app_set_update_version (app, split[1]); gs_app_set_management_plugin (app, "packagekit"); gs_app_add_source_id (app, package_ids[i]); gs_app_set_state (app, AS_APP_STATE_UPDATABLE); gs_app_set_kind (app, AS_APP_KIND_GENERIC); gs_app_set_install_date (app, mtime); gs_app_set_metadata (app, "GnomeSoftware::Creator", gs_plugin_get_name (plugin)); gs_app_list_add (list, app); } return TRUE; }