#############################################################################*/
#include <ctype.h>
+#include <dirent.h>
#include <errno.h>
-#include <fts.h>
#include <linux/limits.h>
#include <pwd.h>
#include <stddef.h>
return 0;
}
+static int pakfire_read_one_repo_config(struct pakfire* pakfire, DIR* dir, const char* path) {
+ FILE* f = NULL;
+ int fd = -1;
+ int r;
+
+ // Open the file
+ fd = openat(dirfd(dir), path, O_CLOEXEC);
+ if (fd < 0)
+ return -errno;
+
+ // Re-open as file handle
+ f = fdopen(fd, "r");
+ if (!f)
+ return -errno;
+
+ // Read the configuration
+ r = pakfire_config_read(pakfire->config, f);
+
+ // Cleanup
+ fclose(f);
+
+ return r;
+}
+
static int pakfire_read_repo_config(struct pakfire* pakfire) {
+ struct dirent* entry = NULL;
char path[PATH_MAX];
int r;
DEBUG(pakfire, "Reading repository configuration from %s\n", path);
- char* paths[2] = {
- path, NULL,
- };
- r = 1;
+ // Open path
+ DIR* dir = opendir(path);
+ if (!dir) {
+ switch (errno) {
+ case ENOENT:
+ return 0;
- FTS* d = fts_open(paths, FTS_NOCHDIR|FTS_NOSTAT, NULL);
- if (!d)
- goto ERROR;
+ default:
+ ERROR(pakfire, "Could not open %s: %m\n", path);
+ return -errno;
+ }
+ }
for (;;) {
- FTSENT* fent = fts_read(d);
- if (!fent)
+ entry = readdir(dir);
+ if (!entry)
break;
- // Only handle files
- if (fent->fts_info & FTS_F) {
- // Skip everything that doesn't end in .repo
- if (!pakfire_string_endswith(fent->fts_name, ".repo"))
- continue;
-
- DEBUG(pakfire, "Reading %s\n", fent->fts_path);
+ // Skip anything that isn't a regular file
+ if (entry->d_type & DT_REG)
+ continue;
- FILE* f = fopen(fent->fts_path, "r");
- if (!f)
- goto ERROR;
+ // Skip any files that don't end on .repo
+ if (!pakfire_path_match("*.repo", entry->d_name))
+ continue;
- // Parse the configuration file
- r = pakfire_config_read(pakfire->config, f);
- fclose(f);
+ // Read the configuration
+ r = pakfire_read_one_repo_config(pakfire, dir, entry->d_name);
+ if (r)
+ goto ERROR;
- if (r)
- goto ERROR;
- }
}
// Success
r = 0;
ERROR:
- if (d)
- fts_close(d);
+ if (dir)
+ closedir(dir);
return r;
}