As osinfo-db-import handles non-local requests, it'd en ud relying on GVFS under the hood, which would cause the app to not work when running as root. In order to avoid this situation, let's rely on libsoup for this case. It's important to mention that glib minimum version has been bumped to 2.44 as that's the version where g_input_stream_read_all() has been introduced. https://gitlab.com/libosinfo/libosinfo/issues/30 Signed-off-by: Fabiano Fidêncio <fidencio@xxxxxxxxxx> --- configure.ac | 5 +- osinfo-db-tools.spec.in | 1 + tools/Makefile.am | 2 + tools/osinfo-db-import.c | 111 +++++++++++++++++++++++++++++---------- 4 files changed, 90 insertions(+), 29 deletions(-) diff --git a/configure.ac b/configure.ac index 4df1139..d019941 100644 --- a/configure.ac +++ b/configure.ac @@ -63,13 +63,14 @@ m4_if(m4_version_compare([2.61a.100], m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) # Keep these two definitions in agreement. -GLIB_MINIMUM_VERSION="2.36" -GLIB_ENCODED_VERSION="GLIB_VERSION_2_36" +GLIB_MINIMUM_VERSION="2.44" +GLIB_ENCODED_VERSION="GLIB_VERSION_2_44" PKG_CHECK_MODULES([LIBXML], [libxml-2.0 >= 2.6.0]) PKG_CHECK_MODULES([LIBXSLT], [libxslt >= 1.0.0]) PKG_CHECK_MODULES([LIBARCHIVE], [libarchive >= 3.0.0]) PKG_CHECK_MODULES([JSON_GLIB], [json-glib-1.0]) +PKG_CHECK_MODULES([LIBSOUP], [libsoup-2.4]) PKG_CHECK_MODULES([GLIB], [glib-2.0 >= $GLIB_MINIMUM_VERSION gobject-2.0 gio-2.0]) GLIB_CFLAGS="$GLIB_CFLAGS -DGLIB_VERSION_MIN_REQUIRED=$GLIB_ENCODED_VERSION" diff --git a/osinfo-db-tools.spec.in b/osinfo-db-tools.spec.in index 459dde9..8a82c56 100644 --- a/osinfo-db-tools.spec.in +++ b/osinfo-db-tools.spec.in @@ -18,6 +18,7 @@ BuildRequires: gettext-devel BuildRequires: glib2-devel BuildRequires: libxml2-devel >= 2.6.0 BuildRequires: libxslt-devel >= 1.0.0 +BuildRequires: libsoup-devel BuildRequires: libarchive-devel BuildRequires: json-glib-devel BuildRequires: /usr/bin/pod2man diff --git a/tools/Makefile.am b/tools/Makefile.am index e43e85d..f124d4f 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,6 +2,7 @@ AM_CFLAGS = $(GOBJECT_CFLAGS) \ $(GIO_CFLAGS) \ $(GLIB_CFLAGS) \ $(LIBXML_CFLAGS) \ + $(LIBSOUP_CFLAGS) \ -DPKGDATADIR="\"$(pkgdatadir)\"" \ -DDATA_DIR="\"$(datadir)\"" \ -DSYSCONFDIR="\"$(sysconfdir)\"" \ @@ -36,6 +37,7 @@ osinfo_db_import_SOURCES = osinfo-db-import.c $(COMMON_SOURCES) osinfo_db_import_LDADD = $(GOBJECT_LIBS) \ $(GIO_LIBS) \ $(GLIB_LIBS) \ + $(LIBSOUP_LIBS) \ $(JSON_GLIB_LIBS) \ $(LIBARCHIVE_LIBS) osinfo_db_import_CFLAGS = $(AM_CFLAGS) \ diff --git a/tools/osinfo-db-import.c b/tools/osinfo-db-import.c index 675961d..9a6465c 100644 --- a/tools/osinfo-db-import.c +++ b/tools/osinfo-db-import.c @@ -29,6 +29,7 @@ #include <stdlib.h> #include <archive.h> #include <archive_entry.h> +#include <libsoup/soup.h> #include "osinfo-db-util.h" @@ -36,6 +37,7 @@ #define VERSION_FILE "VERSION" const char *argv0; +static SoupSession *session = NULL; static int osinfo_db_import_create_reg(GFile *file, struct archive *arc, @@ -139,33 +141,64 @@ static GFile *osinfo_db_import_get_file(GFile *target, return g_file_resolve_relative_path(target, tmp); } -static int -osinfo_db_import_download_file(GFile *file, - gchar **source_file) +static gchar * +osinfo_db_import_download_file(const gchar *source) { + GInputStream *stream = NULL; GFile *out = NULL; GError *err = NULL; + SoupMessage *message = NULL; gchar *filename = NULL; - GFileCopyFlags flags = G_FILE_COPY_OVERWRITE | G_FILE_COPY_BACKUP; + gchar *source_file = NULL; + gchar *content = NULL; + goffset content_size = 0; + GFileCreateFlags flags = G_FILE_CREATE_REPLACE_DESTINATION; int ret = -1; - filename = g_file_get_basename(file); + filename = g_path_get_basename(source); if (filename == NULL) goto cleanup; - *source_file = g_build_filename(g_get_user_cache_dir(), filename, NULL); - if (*source_file == NULL) + source_file = g_build_filename(g_get_user_cache_dir(), filename, NULL); + if (source_file == NULL) goto cleanup; - out = g_file_new_for_path(*source_file); + out = g_file_new_for_path(source_file); if (out == NULL) goto cleanup; - if (!g_file_copy(file, out, flags, NULL, NULL, NULL, &err)) { - gchar *path = g_file_get_path(file); + if (session == NULL) + session = soup_session_new(); + + if (session == NULL) + goto cleanup; + + message = soup_message_new("GET", source); + if (message == NULL) + goto cleanup; + + stream = soup_session_send(session, message, NULL, &err); + if (stream == NULL || + !SOUP_STATUS_IS_SUCCESSFUL(message->status_code)) { + g_printerr("Could not access %s: %s\n", + source, + err != NULL ? err->message : + soup_status_get_phrase(message->status_code)); + goto cleanup; + } + + content_size = soup_message_headers_get_content_length(message->response_headers); + content = g_malloc0(content_size); + + if (!g_input_stream_read_all(stream, content, content_size, NULL, NULL, &err)) { + g_printerr("Could not load the content of %s: %s\n", + source, err->message); + goto cleanup; + } + + if (!g_file_replace_contents(out, content, content_size, NULL, TRUE, flags, NULL, NULL, &err)) { g_printerr("Could not download file \"%s\": %s\n", - path, err->message); - g_free(path); + source, err->message); goto cleanup; } @@ -173,14 +206,20 @@ osinfo_db_import_download_file(GFile *file, cleanup: g_free(filename); + g_free(content); + g_clear_object(&message); + g_clear_object(&stream); if (out != NULL) g_object_unref(out); if (err != NULL) g_error_free(err); - if (ret != 0 && *source_file != NULL) - unlink(*source_file); + if (ret != 0 && source_file != NULL) { + unlink(source_file); + g_free(source_file); + source_file = NULL; + } - return ret; + return source_file; } static gboolean osinfo_db_get_installed_version(GFile *dir, @@ -214,18 +253,39 @@ static gboolean osinfo_db_get_installed_version(GFile *dir, static gboolean osinfo_db_get_latest_info(gchar **version, gchar **url) { + SoupMessage *message = NULL; + GInputStream *stream = NULL; JsonParser *parser = NULL; JsonReader *reader = NULL; - GFile *uri = NULL; GError *err = NULL; gchar *content = NULL; + goffset content_size = 0; gboolean ret = FALSE; - uri = g_file_new_for_uri(LATEST_URI); - if (uri == NULL) - return FALSE; + if (session == NULL) + session = soup_session_new(); + + if (session == NULL) + goto cleanup; - if (!g_file_load_contents(uri, NULL, &content, NULL, NULL, &err)) { + message = soup_message_new("GET", LATEST_URI); + if (message == NULL) + goto cleanup; + + stream = soup_session_send(session, message, NULL, &err); + if (stream == NULL || + !SOUP_STATUS_IS_SUCCESSFUL(message->status_code)) { + g_printerr("Could not access %s: %s\n", + LATEST_URI, + err != NULL ? err->message : + soup_status_get_phrase(message->status_code)); + goto cleanup; + } + + content_size = soup_message_headers_get_content_length(message->response_headers); + content = g_malloc0(content_size); + + if (!g_input_stream_read_all(stream, content, content_size, NULL, NULL, &err)) { g_printerr("Could not load the content of %s: %s\n", LATEST_URI, err->message); goto cleanup; @@ -286,7 +346,7 @@ static gboolean osinfo_db_get_latest_info(gchar **version, ret = TRUE; cleanup: - g_object_unref(uri); + g_clear_object(&message); if (parser != NULL) g_object_unref(parser); if (reader != NULL) @@ -323,12 +383,8 @@ static int osinfo_db_import_extract(GFile *target, goto cleanup; file_is_native = g_file_is_native(file); - if (!file_is_native) { - if (osinfo_db_import_download_file(file, &source_file) < 0) - goto cleanup; - } else { - source_file = g_file_get_path(file); - } + source_file = file_is_native ? g_file_get_path(file) : + osinfo_db_import_download_file(source); if (source_file == NULL) goto cleanup; @@ -478,6 +534,7 @@ gint main(gint argc, gchar **argv) g_free(installed_version); g_free(latest_version); g_free(latest_url); + g_clear_object(&session); g_clear_error(&error); g_option_context_free(context); -- 2.21.0 _______________________________________________ Libosinfo mailing list Libosinfo@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libosinfo