chiark / gitweb /
bootctl: add boot loader and firmware interface tool
[elogind.git] / src / shared / conf-files.c
index 487c9a5e6861f966f769185fa49adad1961de207..5bbd2388d3d03084663b118becac7d7d77094958 100644 (file)
 #include "hashmap.h"
 #include "conf-files.h"
 
-static int files_add(Hashmap *h, const char *path, const char *suffix) {
-        DIR *dir;
-        struct dirent buffer, *de;
-        int r = 0;
+static int files_add(Hashmap *h, const char *root, const char *path, const char *suffix) {
+        _cleanup_closedir_ DIR *dir;
+        _cleanup_free_ char *dirpath = NULL;
 
-        dir = opendir(path);
+        if (asprintf(&dirpath, "%s%s", root ? root : "", path) < 0)
+                return -ENOMEM;
+
+        dir = opendir(dirpath);
         if (!dir) {
                 if (errno == ENOENT)
                         return 0;
@@ -50,14 +52,14 @@ static int files_add(Hashmap *h, const char *path, const char *suffix) {
         }
 
         for (;;) {
-                int k;
+                struct dirent *de;
+                union dirent_storage buf;
                 char *p;
+                int err;
 
-                k = readdir_r(dir, &buffer, &de);
-                if (k != 0) {
-                        r = -k;
-                        goto finish;
-                }
+                err = readdir_r(dir, &buf.de, &de);
+                if (err != 0)
+                        return err;
 
                 if (!de)
                         break;
@@ -65,10 +67,8 @@ static int files_add(Hashmap *h, const char *path, const char *suffix) {
                 if (!dirent_is_file_with_suffix(de, suffix))
                         continue;
 
-                if (asprintf(&p, "%s/%s", path, de->d_name) < 0) {
-                        r = -ENOMEM;
-                        goto finish;
-                }
+                if (asprintf(&p, "%s/%s", dirpath, de->d_name) < 0)
+                        return -ENOMEM;
 
                 if (hashmap_put(h, path_get_file_name(p), p) <= 0) {
                         log_debug("Skip overridden file: %s.", p);
@@ -76,9 +76,7 @@ static int files_add(Hashmap *h, const char *path, const char *suffix) {
                 }
         }
 
-finish:
-        closedir(dir);
-        return r;
+        return 0;
 }
 
 static int base_cmp(const void *a, const void *b) {
@@ -89,11 +87,11 @@ static int base_cmp(const void *a, const void *b) {
         return strcmp(path_get_file_name(s1), path_get_file_name(s2));
 }
 
-int conf_files_list_strv(char ***strv, const char *suffix, const char **dirs) {
+int conf_files_list_strv(char ***strv, const char *suffix, const char *root, const char **dirs) {
         Hashmap *fh = NULL;
         char **files = NULL;
         const char **p;
-        int r = 0;
+        int r;
 
         assert(dirs);
 
@@ -104,11 +102,10 @@ int conf_files_list_strv(char ***strv, const char *suffix, const char **dirs) {
         }
 
         STRV_FOREACH(p, dirs) {
-                if (files_add(fh, *p, suffix) < 0) {
-                        log_error("Failed to search for files.");
-                        r = -EINVAL;
-                        goto finish;
-                }
+                r = files_add(fh, root, *p, suffix);
+                if (r < 0)
+                        log_warning("Failed to search for files in %s: %s",
+                                    *p, strerror(-r));
         }
 
         files = hashmap_get_strv(fh);
@@ -118,6 +115,7 @@ int conf_files_list_strv(char ***strv, const char *suffix, const char **dirs) {
                 goto finish;
         }
         qsort(files, hashmap_size(fh), sizeof(char *), base_cmp);
+        r = 0;
 
 finish:
         hashmap_free(fh);
@@ -125,7 +123,7 @@ finish:
         return r;
 }
 
-int conf_files_list(char ***strv, const char *suffix, const char *dir, ...) {
+int conf_files_list(char ***strv, const char *suffix, const char *root, const char *dir, ...) {
         char **dirs = NULL;
         va_list ap;
         int r;
@@ -144,7 +142,7 @@ int conf_files_list(char ***strv, const char *suffix, const char *dir, ...) {
         }
         strv_uniq(dirs);
 
-        r = conf_files_list_strv(strv, suffix, (const char **)dirs);
+        r = conf_files_list_strv(strv, suffix, root, (const char **)dirs);
 
 finish:
         strv_free(dirs);