]> git.ipfire.org Git - pakfire.git/commitdiff
repo: Refactor scanning for archives
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 25 Oct 2024 09:52:36 +0000 (09:52 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 25 Oct 2024 09:52:36 +0000 (09:52 +0000)
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 <michael.tremer@ipfire.org>
src/libpakfire/repo.c

index c9b92a4e2b52b0deee747e534398c51338100e4b..9e133c9685168c403aea0be0428e550f41426923 100644 (file)
@@ -18,7 +18,9 @@
 #                                                                             #
 #############################################################################*/
 
+#include <dirent.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <linux/limits.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -39,9 +41,6 @@
 #include <pakfire/config.h>
 #include <pakfire/constants.h>
 #include <pakfire/ctx.h>
-#include <pakfire/httpclient.h>
-#include <pakfire/file.h>
-#include <pakfire/filelist.h>
 #include <pakfire/i18n.h>
 #include <pakfire/logging.h>
 #include <pakfire/package.h>
@@ -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;
 }