From 11c439cee25a8787998ca347de669c92f5482a36 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 7 May 2019 10:20:10 +0200 Subject: [PATCH] Port flatpak remote-add to use flatpak_parse_repofile We shouldn't be parsing this in two places in the code. Closes: #2884 Approved by: alexlarsson --- app/flatpak-builtins-remote-add.c | 255 +++++++----------------------- 1 file changed, 56 insertions(+), 199 deletions(-) diff --git a/app/flatpak-builtins-remote-add.c b/app/flatpak-builtins-remote-add.c index 19a9ac6c..53b29b65 100644 --- a/app/flatpak-builtins-remote-add.c +++ b/app/flatpak-builtins-remote-add.c @@ -54,13 +54,6 @@ static char *opt_collection_id = NULL; static gboolean opt_from; static char **opt_gpg_import; -static char *comment = NULL; -static char *description = NULL; -static char *icon = NULL; -static char *homepage = NULL; -static char *filter = NULL; - - static GOptionEntry add_options[] = { { "if-not-exists", 0, 0, G_OPTION_ARG_NONE, &opt_if_not_exists, N_("Do nothing if the provided remote exists"), NULL }, { "from", 0, 0, G_OPTION_ARG_NONE, &opt_from, N_("LOCATION specifies a configuration file, not the repo location"), NULL }, @@ -86,31 +79,24 @@ static GOptionEntry common_options[] = { }; -static GKeyFile * -get_config_from_opts (FlatpakDir *dir, const char *remote_name, gboolean *changed) +static gboolean +get_config_from_opts (GKeyFile *config, + const char *remote_name, + GBytes **gpg_data, + GError **error) { - OstreeRepo *repo; - GKeyFile *config; g_autofree char *group = g_strdup_printf ("remote \"%s\"", remote_name); - repo = flatpak_dir_get_repo (dir); - if (repo == NULL) - config = g_key_file_new (); - else - config = ostree_repo_copy_config (repo); - if (opt_no_gpg_verify) { g_key_file_set_boolean (config, group, "gpg-verify", FALSE); g_key_file_set_boolean (config, group, "gpg-verify-summary", FALSE); - *changed = TRUE; } if (opt_do_gpg_verify) { g_key_file_set_boolean (config, group, "gpg-verify", TRUE); g_key_file_set_boolean (config, group, "gpg-verify-summary", TRUE); - *changed = TRUE; } if (opt_url) @@ -119,144 +105,95 @@ get_config_from_opts (FlatpakDir *dir, const char *remote_name, gboolean *change g_key_file_set_string (config, group, "metalink", opt_url + strlen ("metalink=")); else g_key_file_set_string (config, group, "url", opt_url); - *changed = TRUE; } if (opt_collection_id) { g_key_file_set_string (config, group, "collection-id", opt_collection_id); g_key_file_set_boolean (config, group, "gpg-verify-summary", FALSE); - *changed = TRUE; } if (opt_title) { g_key_file_set_string (config, group, "xa.title", opt_title); g_key_file_set_boolean (config, group, "xa.title-is-set", TRUE); - *changed = TRUE; } if (opt_comment) { g_key_file_set_string (config, group, "xa.comment", opt_comment); g_key_file_set_boolean (config, group, "xa.comment-is-set", TRUE); - *changed = TRUE; } if (opt_description) { g_key_file_set_string (config, group, "xa.description", opt_description); g_key_file_set_boolean (config, group, "xa.description-is-set", TRUE); - *changed = TRUE; } if (opt_homepage) { g_key_file_set_string (config, group, "xa.homepage", opt_homepage); g_key_file_set_boolean (config, group, "xa.homepage-is-set", TRUE); - *changed = TRUE; } if (opt_icon) { g_key_file_set_string (config, group, "xa.icon", opt_icon); g_key_file_set_boolean (config, group, "xa.icon-is-set", TRUE); - *changed = TRUE; } if (opt_default_branch) { g_key_file_set_string (config, group, "xa.default-branch", opt_default_branch); g_key_file_set_boolean (config, group, "xa.default-branch-is-set", TRUE); - *changed = TRUE; } if (opt_filter) - { - g_key_file_set_string (config, group, "xa.filter", opt_filter); - *changed = TRUE; - } + g_key_file_set_string (config, group, "xa.filter", opt_filter); if (opt_no_enumerate) - { - g_key_file_set_boolean (config, group, "xa.noenumerate", TRUE); - *changed = TRUE; - } + g_key_file_set_boolean (config, group, "xa.noenumerate", TRUE); if (opt_do_enumerate) - { - g_key_file_set_boolean (config, group, "xa.noenumerate", FALSE); - *changed = TRUE; - } + g_key_file_set_boolean (config, group, "xa.noenumerate", FALSE); if (opt_no_deps) - { - g_key_file_set_boolean (config, group, "xa.nodeps", TRUE); - *changed = TRUE; - } + g_key_file_set_boolean (config, group, "xa.nodeps", TRUE); if (opt_do_deps) - { - g_key_file_set_boolean (config, group, "xa.nodeps", FALSE); - *changed = TRUE; - } + g_key_file_set_boolean (config, group, "xa.nodeps", FALSE); if (opt_disable) - { - g_key_file_set_boolean (config, group, "xa.disable", TRUE); - *changed = TRUE; - } + g_key_file_set_boolean (config, group, "xa.disable", TRUE); if (opt_prio != -1) { g_autofree char *prio_as_string = g_strdup_printf ("%d", opt_prio); g_key_file_set_string (config, group, "xa.prio", prio_as_string); - *changed = TRUE; } - if (comment) + if (opt_gpg_import != NULL) { - g_key_file_set_string (config, group, "xa.comment", comment); - *changed = TRUE; + g_clear_pointer (gpg_data, g_bytes_unref); /* Free if set from flatpakrepo file */ + *gpg_data = flatpak_load_gpg_keys (opt_gpg_import, NULL, error); + if (*gpg_data == NULL) + return FALSE; } - if (description) - { - g_key_file_set_string (config, group, "xa.description", description); - *changed = TRUE; - } - - if (icon) - { - g_key_file_set_string (config, group, "xa.icon", icon); - *changed = TRUE; - } - - if (homepage) - { - g_key_file_set_string (config, group, "xa.homepage", homepage); - *changed = TRUE; - } - - if (filter) - { - g_key_file_set_string (config, group, "xa.filter", filter); - *changed = TRUE; - } - - return config; + return TRUE; } -static void -load_options (const char *filename, - GBytes **gpg_data) +static GKeyFile * +load_options (const char *remote_name, + const char *filename, + GBytes **gpg_data, + GError **error) { - g_autoptr(GError) error = NULL; + g_autoptr(GError) local_error = NULL; g_autoptr(GKeyFile) keyfile = g_key_file_new (); - char *str; - gboolean nodeps; + g_autoptr(GKeyFile) config = NULL; g_autoptr(GBytes) bytes = NULL; - g_autofree char *version = NULL; if (g_str_has_prefix (filename, "http:") || g_str_has_prefix (filename, "https:")) @@ -266,116 +203,35 @@ load_options (const char *filename, g_autoptr(SoupSession) soup_session = NULL; soup_session = flatpak_create_soup_session (PACKAGE_STRING); - bytes = flatpak_load_http_uri (soup_session, filename, 0, NULL, NULL, NULL, &error); + bytes = flatpak_load_http_uri (soup_session, filename, 0, NULL, NULL, NULL, &local_error); if (bytes == NULL) { - g_printerr (_("Can't load uri %s: %s\n"), filename, error->message); - exit (1); + flatpak_fail (error, _("Can't load uri %s: %s\n"), filename, local_error->message); + return NULL; } options_data = g_bytes_get_data (bytes, &options_size); - if (!g_key_file_load_from_data (keyfile, options_data, options_size, 0, &error)) + if (!g_key_file_load_from_data (keyfile, options_data, options_size, 0, &local_error)) { - g_printerr (_("Can't load uri %s: %s\n"), filename, error->message); - exit (1); + flatpak_fail (error, _("Can't load uri %s: %s\n"), filename, local_error->message); + return NULL; } } else { - if (!g_key_file_load_from_file (keyfile, filename, 0, &error)) + if (!g_key_file_load_from_file (keyfile, filename, 0, &local_error)) { - g_printerr (_("Can't load file %s: %s\n"), filename, error->message); - exit (1); + flatpak_fail (error, _("Can't load file %s: %s\n"), filename, local_error->message); + return NULL; } } + config = flatpak_parse_repofile (remote_name, FALSE, keyfile, gpg_data, NULL, error); + if (config == NULL) + return NULL; - if (!g_key_file_has_group (keyfile, FLATPAK_REPO_GROUP)) - { - g_printerr (_("Invalid file format")); - exit (1); - } - - version = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP, - FLATPAK_REPO_VERSION_KEY, NULL); - if (version != NULL && strcmp (version, "1") != 0) - { - g_printerr (_("Invalid version %s, only 1 supported"), version); - exit (1); - } - - str = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP, - FLATPAK_REPO_URL_KEY, NULL); - if (str != NULL) - opt_url = str; - - str = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP, FLATPAK_REPO_DEPLOY_COLLECTION_ID_KEY, NULL); - if (str != NULL && *str != '\0') - opt_collection_id = str; - else - { - str = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP, FLATPAK_REPO_COLLECTION_ID_KEY, NULL); - if (str != NULL && *str != '\0') - opt_collection_id = str; - } - - str = g_key_file_get_locale_string (keyfile, FLATPAK_REPO_GROUP, - FLATPAK_REPO_TITLE_KEY, NULL, NULL); - if (str != NULL) - opt_title = str; - - str = g_key_file_get_locale_string (keyfile, FLATPAK_REPO_GROUP, - FLATPAK_REPO_DEFAULT_BRANCH_KEY, NULL, NULL); - if (str != NULL) - opt_default_branch = str; - - nodeps = g_key_file_get_boolean (keyfile, FLATPAK_REPO_GROUP, - FLATPAK_REPO_NODEPS_KEY, NULL); - if (nodeps) - { - opt_no_deps = TRUE; - opt_do_deps = FALSE; - } - - str = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP, - FLATPAK_REPO_GPGKEY_KEY, NULL); - if (str != NULL) - { - guchar *decoded; - gsize decoded_len; - - str = g_strstrip (str); - decoded = g_base64_decode (str, &decoded_len); - if (decoded_len < 10) /* Check some minimal size so we don't get crap */ - { - g_printerr (_("Invalid gpg key")); - exit (1); - } - - *gpg_data = g_bytes_new_take (decoded, decoded_len); - if (!opt_no_gpg_verify) - opt_do_gpg_verify = TRUE; - } - - comment = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP, - FLATPAK_REPO_COMMENT_KEY, NULL); - - description = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP, - FLATPAK_REPO_DESCRIPTION_KEY, NULL); - - icon = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP, - FLATPAK_REPO_ICON_KEY, NULL); - - homepage = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP, - FLATPAK_REPO_HOMEPAGE_KEY, NULL); - - filter = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP, - FLATPAK_REPO_FILTER_KEY, NULL); - - /* Default to empty so we unset previous filter if one was enabled, unless given as arg */ - if (filter == NULL && opt_filter != NULL) - filter = g_strdup (""); + return g_steal_pointer (&config); } gboolean @@ -392,9 +248,7 @@ flatpak_builtin_remote_add (int argc, char **argv, const char *location = NULL; g_autoptr(GKeyFile) config = NULL; g_autoptr(GBytes) gpg_data = NULL; - gboolean changed = FALSE; g_autoptr(GError) local_error = NULL; - gboolean is_oci; context = g_option_context_new (_("NAME LOCATION - Add a remote repository")); g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); @@ -431,20 +285,31 @@ flatpak_builtin_remote_add (int argc, char **argv, if (opt_from || flatpak_file_arg_has_suffix (location, ".flatpakrepo")) { - load_options (location, &gpg_data); - if (opt_url == NULL) - return flatpak_fail (error, _("No url specified in flatpakrepo file")); + config = load_options (remote_name, location, &gpg_data, error); + if (config == NULL) + return FALSE; } else { + gboolean is_oci; + + config = g_key_file_new (); file = g_file_new_for_commandline_arg (location); if (g_file_is_native (file)) remote_url = g_file_get_uri (file); else remote_url = g_strdup (location); opt_url = remote_url; + + /* Default to gpg verify, except for OCI registries */ + is_oci = opt_url && g_str_has_prefix (opt_url, "oci+"); + if (!opt_no_gpg_verify && !is_oci) + opt_do_gpg_verify = TRUE; } + if (!get_config_from_opts (config, remote_name, &gpg_data, error)) + return FALSE; + remotes = flatpak_dir_list_remotes (dir, cancellable, error); if (remotes == NULL) return FALSE; @@ -458,13 +323,11 @@ flatpak_builtin_remote_add (int argc, char **argv, /* Except, for historical reasons this applies/clears the filter of pre-existing remotes, so that a default-shipped filtering remote can be replaced, clearing the filter, by following standard docs. */ - g_autofree char *old_filter = flatpak_dir_get_remote_filter (dir, remote_name); - const char *new_filter = filter ? filter : opt_filter; - if (new_filter && *new_filter == 0) - new_filter = NULL; - if (g_strcmp0 (old_filter, new_filter) != 0) + g_autofree char *group = g_strdup_printf ("remote \"%s\"", remote_name); + g_autofree char *new_filter = g_key_file_get_string (config, group, "xa.filter", NULL); + + if (!flatpak_dir_compare_remote_filter (dir, remote_name, new_filter)) { - g_autofree char *group = g_strdup_printf ("remote \"%s\"", remote_name); GKeyFile *config = ostree_repo_copy_config (flatpak_dir_get_repo (dir)); g_key_file_set_string (config, group, "xa.filter", new_filter ? new_filter : ""); @@ -479,15 +342,9 @@ flatpak_builtin_remote_add (int argc, char **argv, return flatpak_fail (error, _("Remote %s already exists"), remote_name); } - /* Default to gpg verify, except for OCI registries */ - is_oci = opt_url && g_str_has_prefix (opt_url, "oci+"); - if (!opt_no_gpg_verify && !is_oci) - opt_do_gpg_verify = TRUE; - - config = get_config_from_opts (dir, remote_name, &changed); - if (opt_gpg_import != NULL) { + g_clear_pointer (&gpg_data, g_bytes_unref); gpg_data = flatpak_load_gpg_keys (opt_gpg_import, cancellable, error); if (gpg_data == NULL) return FALSE;