diff --git a/xdg-app-builtins-repo-contents.c b/xdg-app-builtins-repo-contents.c index 387aae36..e0038b1b 100644 --- a/xdg-app-builtins-repo-contents.c +++ b/xdg-app-builtins-repo-contents.c @@ -6,7 +6,6 @@ #include #include "libgsystem.h" -#include #include "xdg-app-builtins.h" #include "xdg-app-utils.h" @@ -24,50 +23,6 @@ static GOptionEntry options[] = { { NULL } }; -static gboolean -load_contents (const char *uri, GBytes **contents, GCancellable *cancellable, GError **error) -{ - gboolean ret = FALSE; - gs_free char *scheme = NULL; - - scheme = g_uri_parse_scheme (uri); - if (strcmp (scheme, "file") == 0) - { - char *buffer; - gsize length; - gs_unref_object GFile *file = NULL; - - g_debug ("Loading summary %s using GIO", uri); - file = g_file_new_for_uri (uri); - if (!g_file_load_contents (file, cancellable, &buffer, &length, NULL, NULL)) - goto out; - - *contents = g_bytes_new_take (buffer, length); - } - else - { - gs_unref_object SoupSession *session = NULL; - gs_unref_object SoupMessage *msg = NULL; - - g_debug ("Loading summary %s using libsoup", uri); - session = soup_session_new (); - msg = soup_message_new ("GET", uri); - soup_session_send_message (session, msg); - - if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) - goto out; - - *contents = g_bytes_new (msg->response_body->data, msg->response_body->length); - } - - ret = TRUE; - - g_debug ("Received %ld bytes", g_bytes_get_size (*contents)); - -out: - return ret; -} - gboolean xdg_app_builtin_repo_contents (int argc, char **argv, GCancellable *cancellable, GError **error) { @@ -76,6 +31,7 @@ xdg_app_builtin_repo_contents (int argc, char **argv, GCancellable *cancellable, gs_unref_object XdgAppDir *dir = NULL; gs_unref_object OstreeRepo *repo = NULL; gs_unref_hashtable GHashTable *refs = NULL; + gs_free char *title = NULL; GHashTableIter iter; gpointer key; gpointer value; @@ -100,47 +56,9 @@ xdg_app_builtin_repo_contents (int argc, char **argv, GCancellable *cancellable, repository = argv[1]; repo = xdg_app_dir_get_repo (dir); - if (!ostree_repo_remote_get_url (repo, repository, &url, error)) + if (!ostree_repo_load_summary (repo, repository, &refs, &title, cancellable, error)) goto out; - summary_url = g_build_filename (url, "summary", NULL); - if (load_contents (summary_url, &bytes, cancellable, NULL)) - { - gs_unref_variant GVariant *summary; - gs_unref_variant GVariant *ref_list; - int n; - - refs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - - summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, bytes, FALSE); - ref_list = g_variant_get_child_value (summary, 0); - n = g_variant_n_children (ref_list); - g_debug ("Summary contains %d refs", n); - for (i = 0; i < n; i++) - { - gs_unref_variant GVariant *ref = NULL; - gs_unref_variant GVariant *csum_v = NULL; - char *refname; - char *checksum; - - ref = g_variant_get_child_value (ref_list, i); - g_variant_get (ref, "(&s(t@aya{sv}))", &refname, NULL, &csum_v, NULL); - - if (!ostree_validate_rev (refname, error)) - goto out; - - checksum = ostree_checksum_from_bytes_v (csum_v); - g_debug ("%s summary: %s -> %s\n", repository, refname, checksum); - g_hash_table_insert (refs, g_strdup (refname), checksum); - } - } - else - { - g_printerr ("Failed to load summary file for remote %s, listing local refs\n", repository); - if (!ostree_repo_list_refs (repo, NULL, &refs, cancellable, error)) - goto out; - } - names = g_ptr_array_new_with_free_func (g_free); g_hash_table_iter_init (&iter, refs); diff --git a/xdg-app-utils.c b/xdg-app-utils.c index 4657b937..0e4cfbd3 100644 --- a/xdg-app-utils.c +++ b/xdg-app-utils.c @@ -5,6 +5,7 @@ #include #include "libgsystem.h" +#include #include #include @@ -343,3 +344,114 @@ xdg_app_remove_dangling_symlinks (GFile *dir, out: return ret; } + +static gboolean +load_contents (const char *uri, GBytes **contents, GCancellable *cancellable, GError **error) +{ + gboolean ret = FALSE; + gs_free char *scheme = NULL; + + scheme = g_uri_parse_scheme (uri); + if (strcmp (scheme, "file") == 0) + { + char *buffer; + gsize length; + gs_unref_object GFile *file = NULL; + + g_debug ("Loading summary %s using GIO", uri); + file = g_file_new_for_uri (uri); + if (!g_file_load_contents (file, cancellable, &buffer, &length, NULL, NULL)) + goto out; + + *contents = g_bytes_new_take (buffer, length); + } + else + { + gs_unref_object SoupSession *session = NULL; + gs_unref_object SoupMessage *msg = NULL; + + g_debug ("Loading summary %s using libsoup", uri); + session = soup_session_new (); + msg = soup_message_new ("GET", uri); + soup_session_send_message (session, msg); + + if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) + goto out; + + *contents = g_bytes_new (msg->response_body->data, msg->response_body->length); + } + + ret = TRUE; + + g_debug ("Received %ld bytes", g_bytes_get_size (*contents)); + +out: + return ret; +} + +gboolean +ostree_repo_load_summary (OstreeRepo *repo, + const char *repository, + GHashTable **refs, + gchar **title, + GCancellable *cancellable, + GError **error) +{ + gboolean ret = FALSE; + gs_free char *url = NULL; + gs_free char *summary_url = NULL; + gs_unref_bytes GBytes *bytes = NULL; + gs_unref_hashtable GHashTable *local_refs = NULL; + gs_free char *local_title = NULL; + + if (!ostree_repo_remote_get_url (repo, repository, &url, error)) + goto out; + + summary_url = g_build_filename (url, "summary", NULL); + if (load_contents (summary_url, &bytes, cancellable, NULL)) + { + gs_unref_variant GVariant *summary; + gs_unref_variant GVariant *ref_list; + gs_unref_variant GVariant *extensions; + GVariantDict dict; + int i, n; + + local_refs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, bytes, FALSE); + ref_list = g_variant_get_child_value (summary, 0); + extensions = g_variant_get_child_value (summary, 1); + + n = g_variant_n_children (ref_list); + g_debug ("Summary contains %d refs", n); + for (i = 0; i < n; i++) + { + gs_unref_variant GVariant *ref = NULL; + gs_unref_variant GVariant *csum_v = NULL; + char *refname; + char *checksum; + + ref = g_variant_get_child_value (ref_list, i); + g_variant_get (ref, "(&s(t@aya{sv}))", &refname, NULL, &csum_v, NULL); + + if (!ostree_validate_rev (refname, error)) + goto out; + + checksum = ostree_checksum_from_bytes_v (csum_v); + g_debug ("%s summary: %s -> %s", repository, refname, checksum); + g_hash_table_insert (local_refs, g_strdup (refname), checksum); + } + + g_variant_dict_init (&dict, extensions); + g_variant_dict_lookup (&dict, "xa.title", "s", &local_title); + g_debug ("%s summary: title %s", repository, local_title); + g_variant_dict_end (&dict); + } + + *refs = g_hash_table_ref (local_refs); + *title = g_strdup (local_title); + + ret = TRUE; +out: + return ret; +} diff --git a/xdg-app-utils.h b/xdg-app-utils.h index b18cf280..82ef68d0 100644 --- a/xdg-app-utils.h +++ b/xdg-app-utils.h @@ -2,6 +2,7 @@ #define __XDG_APP_UTILS_H__ #include +#include const char * xdg_app_get_arch (void); @@ -33,6 +34,13 @@ gboolean xdg_app_remove_dangling_symlinks (GFile *dir, GCancellable *cancellable, GError **error); +gboolean ostree_repo_load_summary (OstreeRepo *repo, + const char *repository, + GHashTable **refs, + gchar **title, + GCancellable *cancellable, + GError **error); + #if !GLIB_CHECK_VERSION(2,43,1) static inline gboolean g_strv_contains (const gchar * const *strv,