]> git.ipfire.org Git - pakfire.git/commitdiff
repo: Read any existing repository metadata before download
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 3 Feb 2025 10:39:28 +0000 (10:39 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 3 Feb 2025 10:39:28 +0000 (10:39 +0000)
This way we can verify that the downloaded version is more recent.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/repo.c

index 5a6d5af802c507a6e89376fd4700d634c70c1d01..8726ff5005a0377e123f33a5438f74ae195495e7 100644 (file)
@@ -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) {