From 7e58da35af6a5c01aad62932a0097c6b81bed603 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 31 May 2016 16:26:59 +0200 Subject: [PATCH] remote-add: Support remote-add --from=keyfile NAME This allows you to have a single file that describes a repo. It also allows a mimetype handle for it so that you can easily install it via a single click. --- app/flatpak-builtins-add-remote.c | 88 +++++++++++++++++++++++++++---- 1 file changed, 77 insertions(+), 11 deletions(-) diff --git a/app/flatpak-builtins-add-remote.c b/app/flatpak-builtins-add-remote.c index 4ad39ba3..c4781129 100644 --- a/app/flatpak-builtins-add-remote.c +++ b/app/flatpak-builtins-add-remote.c @@ -34,6 +34,11 @@ #include "flatpak-utils.h" #include "flatpak-chain-input-stream.h" +#define FLATPAK_REPO_GROUP "Flatpak Repo" +#define FLATPAK_REPO_URL_KEY "Url" +#define FLATPAK_REPO_TITLE_KEY "Title" +#define FLATPAK_REPO_GPGKEY_KEY "GPGKey" + static gboolean opt_no_gpg_verify; static gboolean opt_do_gpg_verify; static gboolean opt_do_enumerate; @@ -44,11 +49,13 @@ static gboolean opt_disable; static int opt_prio = -1; static char *opt_title; static char *opt_url; +static char *opt_from; static char **opt_gpg_import; static GOptionEntry add_options[] = { { "if-not-exists", 0, 0, G_OPTION_ARG_NONE, &opt_if_not_exists, "Do nothing if the provided remote exists", NULL }, + { "from", 0, 0, G_OPTION_ARG_FILENAME, &opt_from, "Load options from file", "FILE" }, { NULL } }; @@ -190,6 +197,56 @@ get_config_from_opts (FlatpakDir *dir, const char *remote_name) return config; } +static void +load_options (char *filename, + GBytes **gpg_data) +{ + g_autoptr(GError) error = NULL; + g_autoptr(GKeyFile) keyfile = g_key_file_new (); + char *str; + + if (!g_key_file_load_from_file (keyfile, filename, 0, &error)) + { + g_printerr ("Can't load file %s: %s\n", filename, error->message); + exit (1); + } + + if (!g_key_file_has_group (keyfile, FLATPAK_REPO_GROUP)) + { + g_printerr ("Invalid file format"); + 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_locale_string (keyfile, FLATPAK_REPO_GROUP, + FLATPAK_REPO_TITLE_KEY, NULL, NULL); + if (str != NULL) + opt_title = str; + + 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); + opt_do_gpg_verify = TRUE; + } +} + gboolean flatpak_builtin_add_remote (int argc, char **argv, GCancellable *cancellable, GError **error) @@ -201,22 +258,27 @@ flatpak_builtin_add_remote (int argc, char **argv, g_autofree char *title = NULL; g_autofree char *remote_url = NULL; const char *remote_name; - const char *url_or_path; + const char *url_or_path = NULL; g_autoptr(GKeyFile) config = NULL; g_autoptr(GBytes) gpg_data = NULL; - context = g_option_context_new ("NAME LOCATION - Add a remote repository"); + context = g_option_context_new ("NAME [LOCATION] - Add a remote repository"); g_option_context_add_main_entries (context, common_options, NULL); if (!flatpak_option_context_parse (context, add_options, &argc, &argv, 0, &dir, cancellable, error)) return FALSE; - if (argc < 3) - return usage_error (context, "NAME and LOCATION must be specified", error); + if (opt_from) + load_options (opt_from, &gpg_data); + + if (argc < 2) + return usage_error (context, "NAME must be specified", error); + + if (argc < 3 && opt_url == NULL) + return usage_error (context, "LOCATION must be specified", error); remote_name = argv[1]; - url_or_path = argv[2]; remotes = flatpak_dir_list_remotes (dir, cancellable, error); if (remotes == NULL) @@ -230,17 +292,21 @@ flatpak_builtin_add_remote (int argc, char **argv, return flatpak_fail (error, "Remote %s already exists", remote_name); } - file = g_file_new_for_commandline_arg (url_or_path); - if (g_file_is_native (file)) - remote_url = g_file_get_uri (file); - else - remote_url = g_strdup (url_or_path); + if (opt_url == NULL) + { + url_or_path = argv[2]; + file = g_file_new_for_commandline_arg (url_or_path); + if (g_file_is_native (file)) + remote_url = g_file_get_uri (file); + else + remote_url = g_strdup (url_or_path); + opt_url = remote_url; + } /* Default to gpg verify */ if (!opt_no_gpg_verify) opt_do_gpg_verify = TRUE; - opt_url = remote_url; if (opt_title == NULL) {