On Fri, Dec 07, 2018 at 02:33:48PM +0100, Fabiano Fidêncio wrote: > --latest option checks whether there's a new osinfo-db available from > the official libosinfo's release website, downloads and install it. > > The download and installation is only then when the version available in > libosinfo's release website is newer than the version installed in the > (specified location in) system. > > The file we query in order to get the "latest" available version > (https://db.libosinfo.org/latest.json) is a json that looks like: > { > "version": 1, > "release": { > "version": "20181203", > "archive": "https://releases.pagure.org/libosinfo/osinfo-db-20181203.tar.xz", > "signature": "https://releases.pagure.org/libosinfo/osinfo-db-20181203.tar.xz.asc" > } > } > > The file will be automatically updated whenever a new release is done > (in a day interval). > > This commit also introduces a new dependency: json-glib, which is used > to easily manipulate the queried file's content. > > Signed-off-by: Fabiano Fidêncio <fidencio@xxxxxxxxxx> > --- > configure.ac | 1 + > tools/Makefile.am | 3 + > tools/osinfo-db-import.c | 151 +++++++++++++++++++++++++++++++++++++++ > 3 files changed, 155 insertions(+) The osinfo-db-tools.spec.in file needs changing too. > 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]) No particular version needed ? > > 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/tools/osinfo-db-import.c b/tools/osinfo-db-import.c > index e4b7824..2117084 100644 > --- a/tools/osinfo-db-import.c > +++ b/tools/osinfo-db-import.c > @@ -24,12 +24,17 @@ > > #include <locale.h> > #include <glib/gi18n.h> > +#include <glib-object.h> > +#include <json-glib/json-glib.h> > #include <stdlib.h> > #include <archive.h> > #include <archive_entry.h> > > #include "osinfo-db-util.h" > > +#define LATEST_URI "https://db.libosinfo.org/latest.json" > +#define VERSION_FILE "VERSION" > + > const char *argv0; > > static int osinfo_db_import_create_reg(GFile *file, > @@ -183,6 +188,120 @@ osinfo_db_import_download_file(const gchar *url, > return ret; > } > > +static gboolean osinfo_db_get_installed_version(GFile *dir, > + gchar **version) > +{ > + GFile *file = NULL; > + GFileInfo *info = NULL; > + GFileInputStream *stream = NULL; > + goffset count; > + GError *err = NULL; > + gboolean ret = FALSE; > + > + file = g_file_get_child(dir, VERSION_FILE); > + if (file == NULL) > + return FALSE; > + > + info = g_file_query_info(file, "standard", G_FILE_QUERY_INFO_NONE, NULL, &err); > + if (err != NULL) { > + /* In the case the file was not found, it just means that there's no > + * osinfo-db installed in the specified, directory. Let's just return > + * TRUE and proceed normally from here. */ > + if (err->code == G_IO_ERROR_NOT_FOUND) { > + ret = TRUE; > + goto cleanup; > + } > + g_printerr("Failed to query info for file %s: %s\n", > + VERSION_FILE, err->message); > + goto cleanup; > + } > + > + stream = g_file_read(file, NULL, &err); > + if (err != NULL) { > + g_printerr("Failed to read the file %s: %s\n", > + VERSION_FILE, err->message); > + goto cleanup; > + } > + > + count = g_file_info_get_size(info); > + *version = g_malloc0(count*sizeof(gchar)); > + if (*version == NULL) > + goto cleanup; > + > + if (!g_input_stream_read_all(G_INPUT_STREAM(stream), > + (void *)*version, > + count, > + NULL, > + NULL, > + &err)) { > + g_printerr("Failed get the content of file %s: %s\n", > + VERSION_FILE, err->message); > + goto cleanup; > + } Isn't this series of calls from g_file_read, down to here, just duplicating g_file_load_contents() ? > +static gboolean osinfo_db_get_latest_info(gchar **version, > + gchar **url) > +{ > + JsonParser *parser = NULL; > + JsonReader *reader = NULL; > + GFile *uri = NULL; > + GError *err = NULL; > + gchar *content = NULL; > + gboolean ret = FALSE; > + > + uri = g_file_new_for_uri(LATEST_URI); > + if (uri == NULL) > + return FALSE; > + > + if (!g_file_load_contents(uri, NULL, &content, NULL, NULL, &err)) { > + g_printerr("Could not load the content of "LATEST_URI": %s\n", > + err->message); > + goto cleanup; > + } > + > + parser = json_parser_new(); > + json_parser_load_from_data(parser, content, -1, NULL); > + > + reader = json_reader_new(json_parser_get_root(parser)); > + > + json_reader_read_member(reader, "release"); > + json_reader_read_member(reader, "version"); > + *version = g_strdup(json_reader_get_string_value(reader)); > + json_reader_end_member(reader); > + json_reader_read_member(reader, "archive"); > + *url = g_strdup(json_reader_get_string_value(reader)); > + json_reader_end_member(reader); > + json_reader_end_member(reader); I would think we need error checking on all of these json_* method return values. > + > + ret = TRUE; > + > + cleanup: > + g_object_unref(uri); > + if (parser != NULL) > + g_object_unref(parser); > + if (reader != NULL) > + g_object_unref(reader); > + g_free(content); > + > + return ret; > +} > + > static int osinfo_db_import_extract(GFile *target, > const char *source, > gboolean verbose) 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 :| _______________________________________________ Libosinfo mailing list Libosinfo@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libosinfo