# #
#############################################################################*/
+#include <dirent.h>
#include <errno.h>
+#include <fcntl.h>
#include <linux/limits.h>
#include <stdint.h>
#include <stdio.h>
#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>
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)
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
ERROR:
if (progress)
pakfire_progress_unref(progress);
- if (filelist)
- pakfire_filelist_unref(filelist);
+ if (fd >= 0)
+ close(fd);
return r;
}