From: Michael Tremer Date: Mon, 3 Feb 2025 10:39:28 +0000 (+0000) Subject: repo: Read any existing repository metadata before download X-Git-Tag: 0.9.30~171 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b8de3345b1a28dfab72839465bfa449329e7674b;p=pakfire.git repo: Read any existing repository metadata before download This way we can verify that the downloaded version is more recent. Signed-off-by: Michael Tremer --- diff --git a/src/pakfire/repo.c b/src/pakfire/repo.c index 5a6d5af8..8726ff50 100644 --- a/src/pakfire/repo.c +++ b/src/pakfire/repo.c @@ -75,6 +75,9 @@ struct pakfire_repo_appdata { // SOLV Repo Repo* repo; + // Metadata + struct pakfire_repomd repomd; + // Description char description[MAX_DESCRIPTION]; @@ -604,13 +607,48 @@ ERROR: return r; } +static int pakfire_repo_parse_repomd(struct pakfire_repo* self, + struct pakfire_repomd* repomd, struct json_object* root) { + int r; + + // Parse version + r = pakfire_json_get_int64(root, "version", &repomd->version); + if (r < 0) + goto ERROR; + + // Check if we support this version + switch (repomd->version) { + case 0: + break; + + default: + ERROR(self->ctx, "Unsupported version of repository metadata: %ld\n", repomd->version); + r = -ENOTSUP; + goto ERROR; + } + + DEBUG(self->ctx, "Parsing repository metadata in version %ld\n", repomd->version); + + // Parse revision + r = pakfire_json_get_int64(root, "revision", &repomd->revision); + if (r < 0) + goto ERROR; + + // XXX There is more to do here... + +ERROR: + return r; +} + static int pakfire_repo_read_metadata(struct pakfire_repo* repo, const char* path) { + struct json_object* json = NULL; char database_path[PATH_MAX]; int r; DEBUG(repo->ctx, "Reading repository metadata from %s...\n", path); - struct json_object* json = pakfire_json_parse_from_file(repo->ctx, path); + // Parse the existing metadata + json = pakfire_json_parse_from_file(repo->ctx, path); if (!json) { switch (errno) { case ENOENT: @@ -621,13 +659,23 @@ static int pakfire_repo_read_metadata(struct pakfire_repo* repo, const char* pat return pakfire_repo_scan(repo, 0); } - break; - } - ERROR(repo->ctx, "Could not parse metadata from %s: %m\n", path); - return 1; + // Otherwise accept this and hope we will be able to download some data + return 0; + + default: + ERROR(repo->ctx, "Could not parse metadata from %s: %m\n", path); + return -errno; + } } + // Parse the JSON object + r = pakfire_repo_parse_repomd(repo, &repo->appdata->repomd, json); + if (r < 0) + goto ERROR; + + + struct json_object* database = NULL; // Search for the database name @@ -659,7 +707,8 @@ static int pakfire_repo_read_metadata(struct pakfire_repo* repo, const char* pat ERROR: // Free the parsed JSON object - json_object_put(json); + if (json) + json_object_put(json); return r; } @@ -767,50 +816,6 @@ ERROR: return r; } -static int pakfire_repo_parse_repomd(struct pakfire_repo* self, - struct pakfire_repomd* repomd, const struct pakfire_buffer* buffer) { - struct json_object* root = NULL; - int r; - - // Parse JSON from buffer - root = pakfire_json_parse(self->ctx, buffer->data, buffer->length); - if (!root) { - r = -EBADMSG; - goto ERROR; - } - - // Parse version - r = pakfire_json_get_int64(root, "version", &repomd->version); - if (r < 0) - goto ERROR; - - // Check if we support this version - switch (repomd->version) { - case 0: - break; - - default: - ERROR(self->ctx, "Unsupported version of repository metadata: %ld\n", repomd->version); - r = -ENOTSUP; - goto ERROR; - } - - DEBUG(self->ctx, "Parsing repository metadata in version %ld\n", repomd->version); - - // Parse revision - r = pakfire_json_get_int64(root, "revision", &repomd->revision); - if (r < 0) - goto ERROR; - - // XXX There is more to do here... - -ERROR: - if (root) - json_object_put(root); - - return r; -} - static int pakfire_repo_verify_metadata( struct pakfire_repo* self, const struct pakfire_buffer* repomd) { struct pakfire_buffer signature = {}; @@ -867,6 +872,7 @@ static int pakfire_repo_download_metadata(struct pakfire_repo* repo, const char* struct pakfire_repomd repomd = {}; struct pakfire_buffer buffer = {}; struct pakfire_xfer* xfer = NULL; + struct json_object* json = NULL; int r; // Local repositories don't need to download metadata @@ -920,14 +926,23 @@ static int pakfire_repo_download_metadata(struct pakfire_repo* repo, const char* goto ERROR; } + // Parse JSON from buffer + json = pakfire_json_parse(repo->ctx, buffer.data, buffer.length); + if (!json) { + r = -EBADMSG; + goto ERROR; + } + // Parse the metadata - r = pakfire_repo_parse_repomd(repo, &repomd, &buffer); + r = pakfire_repo_parse_repomd(repo, &repomd, json); if (r < 0) goto ERROR; ERROR: if (xfer) pakfire_xfer_unref(xfer); + if (json) + json_object_put(json); if (buffer.data) free(buffer.data); @@ -943,13 +958,19 @@ static int pakfire_repo_refresh_metadata(struct pakfire_repo* repo, const int fo if (r) return r; + // Parse metadata from disk + r = pakfire_repo_read_metadata(repo, path); + if (r < 0) + return + // Potentially download new metadata r = pakfire_repo_download_metadata(repo, path, force); - if (r) + if (r < 0) return r; - // Parse metadata - return pakfire_repo_read_metadata(repo, path); + // XXX Read the database here? + + return 0; } static void pakfire_repo_free_appdata(struct pakfire_repo_appdata* appdata) {