[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