[Libosinfo] [osinfo-db-tools PATCH 1/1] import: Learn how to deal with URLs
Fabiano Fidêncio
fidencio at redhat.com
Tue Sep 25 12:45:20 UTC 2018
Signed-off-by: Fabiano Fidêncio <fidencio at redhat.com>
---
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
More information about the Libosinfo
mailing list