Signed-off-by: Fabiano Fidêncio <fidencio@xxxxxxxxxx> --- configure.ac | 1 + osinfo-db-tools.spec.in | 1 + tools/Makefile.am | 4 +- tools/osinfo-db-import.c | 120 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 121 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 5e59568..147d262 100644 --- a/configure.ac +++ b/configure.ac @@ -46,6 +46,7 @@ GLIB_ENCODED_VERSION="GLIB_VERSION_2_36" 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([CURL], [libcurl]) 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 90dd231..dc6f21d 100644 --- a/osinfo-db-tools.spec.in +++ b/osinfo-db-tools.spec.in @@ -12,6 +12,7 @@ BuildRequires: intltool BuildRequires: glib2-devel BuildRequires: libxml2-devel >= 2.6.0 BuildRequires: libxslt-devel >= 1.0.0 +BuildRequires: libcurl BuildRequires: libarchive-devel BuildRequires: /usr/bin/pod2man diff --git a/tools/Makefile.am b/tools/Makefile.am index f415297..a25e2e2 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,6 +2,7 @@ AM_CFLAGS = $(GOBJECT_CFLAGS) \ $(GIO_CFLAGS) \ $(GLIB_CFLAGS) \ $(LIBXML_CFLAGS) \ + $(CURL_CFLAGS) \ -DPKGDATADIR="\"$(pkgdatadir)\"" \ -DDATA_DIR="\"$(datadir)\"" \ -DSYSCONFDIR="\"$(sysconfdir)\"" \ @@ -36,7 +37,8 @@ osinfo_db_import_SOURCES = osinfo-db-import.c $(COMMON_SOURCES) osinfo_db_import_LDADD = $(GOBJECT_LIBS) \ $(GIO_LIBS) \ $(GLIB_LIBS) \ - $(LIBARCHIVE_LIBS) + $(LIBARCHIVE_LIBS) \ + $(CURL_LIBS) osinfo_db_export_SOURCES = osinfo-db-export.c $(COMMON_SOURCES) osinfo_db_export_LDADD = $(GOBJECT_LIBS) \ diff --git a/tools/osinfo-db-import.c b/tools/osinfo-db-import.c index 0d0bdd9..a54482c 100644 --- a/tools/osinfo-db-import.c +++ b/tools/osinfo-db-import.c @@ -28,6 +28,7 @@ #include <stdlib.h> #include <archive.h> #include <archive_entry.h> +#include <curl/curl.h> #include "osinfo-db-util.h" @@ -135,6 +136,101 @@ static GFile *osinfo_db_import_get_file(GFile *target, return g_file_resolve_relative_path(target, tmp); } +static int osinfo_db_import_download_file_get_name(const gchar *url, + gchar **filename) +{ + gchar **tokens = NULL; + int ret = -1; + + tokens = g_strsplit(url, "/", -1); + for (size_t i = 0; tokens[i] != NULL; i++) { + if (tokens[i+1] != NULL) + continue; + + if ((*filename = g_strdup(tokens[i])) == NULL) + goto cleanup; + + break; + } + + ret = 0; + + cleanup: + g_strfreev(tokens); + return ret; +} + +static size_t osinfo_db_import_download_file_write_func(void *ptr, + size_t size, + size_t nmemb, + FILE *stream) +{ + return fwrite(ptr, size, nmemb, stream); +} + +static size_t osinfo_db_import_download_file_read_func(void *ptr, + size_t size, + size_t nmemb, + FILE *stream) +{ + return fread(ptr, size, nmemb, stream); +} + +static int +osinfo_db_import_download_file(const gchar *url, + gchar **source_file) +{ + CURL *curl; + CURLcode res; + gchar *filename = NULL; + FILE *file = NULL; + int ret = -1; + + curl = curl_easy_init(); + if (curl == NULL) + return -1; + + if (osinfo_db_import_download_file_get_name(url, &filename) < 0) + goto cleanup; + + *source_file = g_strdup_printf("%s/%s", g_get_user_cache_dir(), filename); + if (*source_file == NULL) + goto cleanup; + + file = fopen(*source_file, "wb"); + if (file == NULL) + goto cleanup; + + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, file); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, + osinfo_db_import_download_file_write_func); + curl_easy_setopt(curl, CURLOPT_READFUNCTION, + osinfo_db_import_download_file_read_func); + + res = curl_easy_perform(curl); + if (res != CURLE_OK) { + g_printerr("%s: cannot download the file %s: %s\n", + argv0, url, curl_easy_strerror(res)); + + goto cleanup; + } + + ret = 0; + + cleanup: + if (ret != 0) { + unlink(*source_file); + } + if (file != NULL) { + fclose(file); + } + g_free(filename); + curl_easy_cleanup(curl); + + return ret; +} + static int osinfo_db_import_extract(GFile *target, const char *source, gboolean verbose) @@ -145,6 +241,7 @@ static int osinfo_db_import_extract(GFile *target, int r; GFile *file = NULL; GError *err = NULL; + gchar *source_file = NULL; arc = archive_read_new(); @@ -154,9 +251,23 @@ static int osinfo_db_import_extract(GFile *target, if (source != NULL && g_str_equal(source, "-")) source = NULL; - if ((r = archive_read_open_filename(arc, source, 10240)) != ARCHIVE_OK) { + if (source != NULL) { + if (g_str_has_prefix(source, "https://") || + g_str_has_prefix(source, "http://") || + g_str_has_prefix(source, "ftp://")) { + if (osinfo_db_import_download_file(source, &source_file) < 0) + goto cleanup; + } else { + source_file = g_strdup(source); + } + + if (source_file == NULL) + goto cleanup; + } + + if ((r = archive_read_open_filename(arc, source_file, 10240)) != ARCHIVE_OK) { g_printerr("%s: cannot open archive %s: %s\n", - argv0, source, archive_error_string(arc)); + argv0, source_file, archive_error_string(arc)); goto cleanup; } @@ -166,7 +277,7 @@ static int osinfo_db_import_extract(GFile *target, break; if (r != ARCHIVE_OK) { g_printerr("%s: cannot read next archive entry in %s: %s\n", - argv0, source, archive_error_string(arc)); + argv0, source_file, archive_error_string(arc)); goto cleanup; } @@ -180,7 +291,7 @@ static int osinfo_db_import_extract(GFile *target, if (archive_read_close(arc) != ARCHIVE_OK) { g_printerr("%s: cannot finish reading archive %s: %s\n", - argv0, source, archive_error_string(arc)); + argv0, source_file, archive_error_string(arc)); goto cleanup; } @@ -191,6 +302,7 @@ static int osinfo_db_import_extract(GFile *target, g_error_free(err); if (file) g_object_unref(file); + g_free(source_file); return ret; } -- 2.17.1 _______________________________________________ Libosinfo mailing list Libosinfo@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libosinfo