[Libosinfo] [osinfo-db-tools PATCH v4 2/3] import: Learn how to deal with URLs
Daniel P. Berrangé
berrange at redhat.com
Thu Dec 13 17:38:36 UTC 2018
On Fri, Dec 07, 2018 at 02:33:47PM +0100, Fabiano Fidêncio wrote:
> Signed-off-by: Fabiano Fidêncio <fidencio at redhat.com>
> ---
> tools/osinfo-db-import.c | 90 ++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 86 insertions(+), 4 deletions(-)
>
> diff --git a/tools/osinfo-db-import.c b/tools/osinfo-db-import.c
> index 72f21ba..e4b7824 100644
> --- a/tools/osinfo-db-import.c
> +++ b/tools/osinfo-db-import.c
> @@ -134,6 +134,55 @@ static GFile *osinfo_db_import_get_file(GFile *target,
> return g_file_resolve_relative_path(target, tmp);
> }
>
> +static int
> +osinfo_db_import_download_file(const gchar *url,
> + gchar **source_file)
> +{
> + GFile *in = NULL;
> + GFile *out = NULL;
> + GError *err = NULL;
> + gchar *filename = NULL;
> + GFileCopyFlags flags = G_FILE_COPY_OVERWRITE | G_FILE_COPY_BACKUP;
> + int ret = -1;
> +
> + in = g_file_new_for_uri(url);
> + if (in == NULL)
> + return -1;
> +
> + filename = g_file_get_basename(in);
> + if (filename == NULL)
> + goto cleanup;
> +
> + *source_file = g_strdup_printf("%s/%s", g_get_user_cache_dir(), filename);
> + if (*source_file == NULL)
> + goto cleanup;
> +
> + out = g_file_new_for_path(*source_file);
> + if (out == NULL)
> + goto cleanup;
> +
> + if (!g_file_copy(in, out, flags, NULL, NULL, NULL, &err)) {
> + g_printerr("Could not download file \"%s\": %s\n",
> + url, err->message);
> + goto cleanup;
> + }
> +
> + ret = 0;
> +
> + cleanup:
> + g_free(filename);
> + if (in != NULL)
> + g_object_unref(in);
> + if (out != NULL)
> + g_object_unref(out);
> + if (err != NULL)
> + g_error_free(err);
> + if (ret != 0)
> + unlink(*source_file);
> +
> + return ret;
> +}
> +
> static int osinfo_db_import_extract(GFile *target,
> const char *source,
> gboolean verbose)
> @@ -143,6 +192,8 @@ static int osinfo_db_import_extract(GFile *target,
> int ret = -1;
> int r;
> GFile *file = NULL;
> + gchar *source_file = NULL;
> + const gchar *uri_schemes[] = {"ftp", "http", NULL};
>
> arc = archive_read_new();
>
> @@ -152,9 +203,38 @@ 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) {
> + gboolean download_file = FALSE;
> + gsize i;
> +
> + file = g_file_new_for_uri(source);
> + if (file == NULL)
> + goto cleanup;
> +
> + /* The supported uri schemes here are "ftp", "http" and "https".
> + * However, "https" is not set as part of the array as it matches with
> + * "http". */
> + for (i = 0; uri_schemes[i] != NULL; i++) {
> + if (g_file_has_uri_scheme(file, uri_schemes[i])) {
> + download_file = TRUE;
> + break;
> + }
Rather than checking for URI schemes, can we just call
g_file_is_native()
Also 'file' is no longer required but we've not unrefd it.
> + }
> +
> + if (download_file) {
> + if (osinfo_db_import_download_file(source, &source_file) < 0)
This method creates a GFile for 'source' again which is a bit
of a waste of time given we already have a GFile just above
that we could pass in
> + 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;
> }
>
> @@ -164,7 +244,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;
> }
>
> @@ -178,7 +258,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;
> }
>
> @@ -187,6 +267,8 @@ static int osinfo_db_import_extract(GFile *target,
> archive_read_free(arc);
> if (file)
> g_object_unref(file);
> + unlink(source_file);
This deletes the user's input file which is not nice. We must only
delete the file if it was a temp file we created.
Can we in fact call unlink immediately after archive_read_open_file()
and rely on UNIX open FD semantics.
> + g_free(source_file);
> return ret;
> }
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
More information about the Libosinfo
mailing list