From 77d7842998ad7c1a421f00216d45b4500827e8e2 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Fri, 25 Oct 2024 09:52:36 +0000 Subject: [PATCH] repo: Refactor scanning for archives It does not make too much sense to (ab)use the filelist object because it depends on so many other things and makes the code unnecessarily complicated. Signed-off-by: Michael Tremer --- src/libpakfire/repo.c | 104 +++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 48 deletions(-) diff --git a/src/libpakfire/repo.c b/src/libpakfire/repo.c index c9b92a4e2..9e133c968 100644 --- a/src/libpakfire/repo.c +++ b/src/libpakfire/repo.c @@ -18,7 +18,9 @@ # # #############################################################################*/ +#include #include +#include #include #include #include @@ -39,9 +41,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -1529,20 +1528,22 @@ PAKFIRE_EXPORT int pakfire_repo_clean(struct pakfire_repo* repo, int flags) { return pakfire_rmtree(cache_path, 0); } -static int pakfire_repo_scan_file(struct pakfire_repo* repo, const char* path) { +static int pakfire_repo_scan_archive(struct pakfire_repo* repo, const char* path) { struct pakfire_archive* archive = NULL; struct pakfire_package* package = NULL; int r; - DEBUG(repo->pakfire, "Scanning %s...\n", path); + CTX_DEBUG(repo->ctx, "Scanning %s...\n", path); // Open archive r = pakfire_archive_open(&archive, repo->pakfire, path); - if (r) + if (r < 0) goto ERROR; // Import package into the repository r = pakfire_archive_make_package(archive, repo, &package); + if (r < 0) + goto ERROR; ERROR: if (package) @@ -1553,73 +1554,80 @@ ERROR: return r; } +static int pakfire_repo_scan_filter(const struct dirent* dirent) { + // Skip anything hidden + if (*dirent->d_name == '.') + return 0; + + return !!pakfire_path_match("**.pfm", dirent->d_name); +} + PAKFIRE_EXPORT int pakfire_repo_scan(struct pakfire_repo* repo, int flags) { - struct pakfire_filelist* filelist = NULL; struct pakfire_progress* progress = NULL; + struct dirent** archives = NULL; + char archive[PATH_MAX]; + int num_archives = 0; + int fd = -EBADF; int r; + // Fetch name + const char* name = pakfire_repo_get_name(repo); + + // Fetch path const char* path = pakfire_repo_get_path(repo); - if (!path) { - errno = EINVAL; - return 1; - } + if (!path) + return -EINVAL; - // Create a new filelist - r = pakfire_filelist_create(&filelist, repo->pakfire); - if (r) - goto ERROR; + // Open path + fd = open(path, O_DIRECTORY|O_CLOEXEC); + if (fd < 0) { + switch (errno) { + // If the directory does not exist, there is nothing to scan + case ENOENT: + r = 0; + goto ERROR; - static const char* includes[] = { "**.pfm", NULL }; + default: + r = -errno; + goto ERROR; + } + } - // Find all package files - r = pakfire_filelist_scan(filelist, path, includes, NULL, 0); - if (r) + // Find all archives in the directory + num_archives = scandirat(fd, ".", &archives, pakfire_repo_scan_filter, versionsort); + if (num_archives < 0) { + r = num_archives; goto ERROR; - - // Fetch how many files have been found - const size_t num_files = pakfire_filelist_length(filelist); + } // Create progress indicator r = pakfire_progress_create(&progress, repo->ctx, - PAKFIRE_PROGRESS_SHOW_COUNTER|PAKFIRE_PROGRESS_SHOW_ELAPSED_TIME, NULL); + PAKFIRE_PROGRESS_SHOW_COUNTER|PAKFIRE_PROGRESS_SHOW_ELAPSED_TIME, NULL); if (r) goto ERROR; - const char* name = pakfire_repo_get_name(repo); - // Add title to progress r = pakfire_progress_set_title(progress, _("Scanning %s"), name); if (r) goto ERROR; // Start progress - r = pakfire_progress_start(progress, num_files); + r = pakfire_progress_start(progress, num_archives); if (r < 0) goto ERROR; - for (unsigned int i = 0; i < num_files; i++) { - struct pakfire_file* file = pakfire_filelist_get(filelist, i); - - // Increment progress bar - pakfire_progress_increment(progress, 1); - - // Skip anything that isn't a regular file - int type = pakfire_file_get_type(file); - if (type != S_IFREG) { - pakfire_file_unref(file); - continue; - } - - path = pakfire_file_get_abspath(file); + // Scan all packages + for (int i = 0; i < num_archives; i++) { + r = pakfire_path_append(archive, path, archives[i]->d_name); + if (r < 0) + goto ERROR; - // Scan the file - r = pakfire_repo_scan_file(repo, path); - if (r) { - pakfire_file_unref(file); + r = pakfire_repo_scan_archive(repo, archive); + if (r < 0) goto ERROR; - } - pakfire_file_unref(file); + // Increment progress bar + pakfire_progress_increment(progress, 1); } // Mark repository data as changed @@ -1636,8 +1644,8 @@ PAKFIRE_EXPORT int pakfire_repo_scan(struct pakfire_repo* repo, int flags) { ERROR: if (progress) pakfire_progress_unref(progress); - if (filelist) - pakfire_filelist_unref(filelist); + if (fd >= 0) + close(fd); return r; } -- 2.39.5