From c54bfac727f2b995c0d8409b0423a6a7508fe2ea Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Mon, 3 Feb 2025 14:16:53 +0000 Subject: [PATCH] repo: Download the package database Signed-off-by: Michael Tremer --- src/pakfire/repo.c | 146 ++++++++++++++++++++------------------------- 1 file changed, 66 insertions(+), 80 deletions(-) diff --git a/src/pakfire/repo.c b/src/pakfire/repo.c index 3ea48370..4a619543 100644 --- a/src/pakfire/repo.c +++ b/src/pakfire/repo.c @@ -535,43 +535,45 @@ struct pakfire_mirrorlist* pakfire_repo_get_mirrorlist(struct pakfire_repo* self return NULL; } -static int pakfire_repo_download_database(struct pakfire_repo* repo, - const char* filename, const char* path) { +static int pakfire_repo_download_database( + struct pakfire_repo* repo, const char* filename, const char* path) { struct pakfire_xfer* xfer = NULL; char title[NAME_MAX]; int r; + // Don't perform any downloads for local repositories + if (pakfire_repo_is_local(repo)) + return 0; + // Do nothing if the file already exists if (pakfire_path_exists(path)) { DEBUG(repo->ctx, "Database %s already present. Skipping download\n", filename); return 0; } - const char* name = pakfire_repo_get_name(repo); - // Make title - r = pakfire_string_format(title, _("Package Database: %s"), name); - if (r) - return r; + r = pakfire_string_format(title, _("Package Database: %s"), pakfire_repo_get_name(repo)); + if (r < 0) + goto ERROR; - // Create a new transfer - r = pakfire_repo_xfer_create(&xfer, repo, "repodata/%s", filename); - if (r) + // Create a new transfers + r = pakfire_repo_xfer_create(&xfer, repo, "%s", filename); + if (r < 0) goto ERROR; // Set title r = pakfire_xfer_set_title(xfer, title); - if (r) + if (r < 0) goto ERROR; // Set path r = pakfire_xfer_set_output_path(xfer, path); - if (r) + if (r < 0) goto ERROR; // Run the xfer r = pakfire_xfer_run(xfer, 0); - if (r) + if (r < 0) goto ERROR; ERROR: @@ -581,16 +583,38 @@ ERROR: return r; } -static int pakfire_repo_read_database(struct pakfire_repo* repo, const char* path) { +static int pakfire_repo_read_database(struct pakfire_repo* self) { + struct pakfire_repomd* repomd = &self->appdata->repomd; + char path[PATH_MAX]; FILE* f = NULL; int r; - DEBUG(repo->ctx, "Read package database from %s...\n", path); + // Make sure the path is set + if (!*repomd->packages.path) { + ERROR(self->ctx, "Package database path is not set. Aborting.\n"); + r = -EINVAL; + goto ERROR; + } + + // Make the total path + r = pakfire_repo_path(self, path, "%s", repomd->packages.path); + if (r < 0) + goto ERROR; + + // Download the database + r = pakfire_repo_download_database(self, repomd->packages.path, path); + if (r < 0) { + ERROR(self->ctx, "Failed to download package database %s: %s\n", + repomd->packages.path, strerror(-r)); + goto ERROR; + } + + DEBUG(self->ctx, "Read package database from %s...\n", path); // Open the database file f = fopen(path, "r"); if (!f) { - ERROR(repo->ctx, "Could not open package database at %s: %m\n", path); + ERROR(self->ctx, "Could not open package database at %s: %m\n", path); r = -errno; goto ERROR; } @@ -603,13 +627,13 @@ static int pakfire_repo_read_database(struct pakfire_repo* repo, const char* pat } // Drop any previous data - r = pakfire_repo_clear(repo); - if (r) + r = pakfire_repo_clear(self); + if (r < 0) goto ERROR; // Read database - r = pakfire_repo_read_solv(repo, f, 0); - if (r) + r = pakfire_repo_read_solv(self, f, 0); + if (r < 0) goto ERROR; ERROR: @@ -719,7 +743,6 @@ static int pakfire_repo_parse_repomd(struct pakfire_repo* self, 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); @@ -745,7 +768,8 @@ static int pakfire_repo_read_metadata(struct pakfire_repo* repo, const char* pat default: ERROR(repo->ctx, "Could not parse metadata from %s: %m\n", path); - return -errno; + r = -errno; + goto ERROR; } } @@ -757,37 +781,6 @@ static int pakfire_repo_read_metadata(struct pakfire_repo* repo, const char* pat goto ERROR; } - - - struct json_object* database = NULL; - - // Search for the database name - int found = json_object_object_get_ex(json, "database", &database); - if (!found) { - ERROR(repo->ctx, "Could not read database name from metadata\n"); - r = 1; - goto ERROR; - } - - const char* filename = json_object_get_string(database); - - // Make the path to the database - r = pakfire_repo_path(repo, database_path, "repodata/%s", filename); - if (r) - goto ERROR; - - // Download the database - if (!pakfire_repo_is_local(repo) && !pakfire_ctx_has_flag(repo->ctx, PAKFIRE_CTX_OFFLINE)) { - r = pakfire_repo_download_database(repo, filename, database_path); - if (r) - goto ERROR; - } - - // Read the database - r = pakfire_repo_read_database(repo, database_path); - if (r) - goto ERROR; - ERROR: // Free the parsed JSON object if (json) @@ -1055,30 +1048,6 @@ ERROR: return r; } -static int pakfire_repo_refresh_metadata(struct pakfire_repo* repo, const int force) { - char path[PATH_MAX]; - int r; - - // Make the metadata path - r = pakfire_repo_path(repo, path, "%s", "repodata/repomd.json"); - if (r) - return r; - - // Parse metadata from disk - r = pakfire_repo_read_metadata(repo, path); - if (r < 0) - return r; - - // Potentially download new metadata - r = pakfire_repo_download_metadata(repo, path, force); - if (r < 0) - return r; - - // XXX Read the database here? - - return 0; -} - static void pakfire_repo_free_appdata(struct pakfire_repo_appdata* appdata) { // Don't free if something is still holding references if (--appdata->nrefs > 0) @@ -2175,9 +2144,11 @@ static int pakfire_repo_sync(struct pakfire_repo* self) { } int pakfire_repo_refresh(struct pakfire_repo* repo, int force) { - const char* name = pakfire_repo_get_name(repo); + char path[PATH_MAX]; int r; + const char* name = pakfire_repo_get_name(repo); + // Skip refreshing any "internal" repositories if (pakfire_repo_is_internal(repo)) return 0; @@ -2199,8 +2170,23 @@ int pakfire_repo_refresh(struct pakfire_repo* repo, int force) { ERROR(repo->ctx, "Could not refresh mirrorlist, but will continue anyways...\n"); } - // Refresh metadata - r = pakfire_repo_refresh_metadata(repo, force); + // Make the metadata path + r = pakfire_repo_path(repo, path, "%s", "repodata/repomd.json"); + if (r) + return r; + + // Parse metadata from disk + r = pakfire_repo_read_metadata(repo, path); + if (r < 0) + return r; + + // Potentially download new metadata + r = pakfire_repo_download_metadata(repo, path, force); + if (r < 0) + return r; + + // Read the database + r = pakfire_repo_read_database(repo); if (r < 0) return r; -- 2.39.5