chiark / gitweb /
util: include `stdarg.h`
[elogind.git] / src / util.c
index 5029896ef0635d507fcb9bc8e6e10dab537c81d3..f0051ee28581f1aaa040cce6be46e1e7037c3ee9 100644 (file)
@@ -1209,6 +1209,26 @@ char **strv_path_canonicalize(char **l) {
         return l;
 }
 
+char **strv_path_remove_empty(char **l) {
+        char **f, **t;
+
+        if (!l)
+                return NULL;
+
+        for (f = t = l; *f; f++) {
+
+                if (dir_is_empty(*f) > 0) {
+                        free(*f);
+                        continue;
+                }
+
+                *(t++) = *f;
+        }
+
+        *t = NULL;
+        return l;
+}
+
 int reset_all_signal_handlers(void) {
         int sig;
 
@@ -3991,7 +4011,7 @@ int detect_vm(const char **id) {
                 : "0" (eax)
         );
 
-        hypervisor = !!(ecx & ecx & 0x80000000U);
+        hypervisor = !!(ecx & 0x80000000U);
 
         if (hypervisor) {
 
@@ -4556,17 +4576,25 @@ static int files_add(Hashmap *h, const char *path, const char *suffix) {
         }
 
         for (de = readdir(dir); de; de = readdir(dir)) {
-                char *f;
+                char *p, *f;
                 const char *base;
 
                 if (!file_is_conf(de, suffix))
                         continue;
 
-                if (asprintf(&f, "%s/%s", path, de->d_name) < 0) {
+                if (asprintf(&p, "%s/%s", path, de->d_name) < 0) {
                         r = -ENOMEM;
                         goto finish;
                 }
 
+                f = canonicalize_file_name(p);
+                if (!f) {
+                        log_error("Failed to canonicalize file name '%s': %m", p);
+                        free(p);
+                        continue;
+                }
+                free(p);
+
                 log_debug("found: %s\n", f);
                 base = f + strlen(path) + 1;
                 if (hashmap_put(h, base, f) <= 0)
@@ -4586,39 +4614,55 @@ static int base_cmp(const void *a, const void *b) {
         return strcmp(file_name_from_path(s1), file_name_from_path(s2));
 }
 
-char **conf_files_list(const char *suffix, const char *dir, ...) {
-        Hashmap *fh;
+int conf_files_list(char ***strv, const char *suffix, const char *dir, ...) {
+        Hashmap *fh = NULL;
+        char **dirs = NULL;
         char **files = NULL;
+        char **p;
         va_list ap;
-        int e = 0;
+        int r = 0;
+
+        va_start(ap, dir);
+        dirs = strv_new_ap(dir, ap);
+        va_end(ap);
+        if (!dirs) {
+                r = -ENOMEM;
+                goto finish;
+        }
+        if (!strv_path_canonicalize(dirs)) {
+                r = -ENOMEM;
+                goto finish;
+        }
+        if (!strv_uniq(dirs)) {
+                r = -ENOMEM;
+                goto finish;
+        }
 
         fh = hashmap_new(string_hash_func, string_compare_func);
         if (!fh) {
-                e = ENOMEM;
+                r = -ENOMEM;
                 goto finish;
         }
 
-        va_start(ap, dir);
-        while (dir) {
-                if (files_add(fh, dir, suffix) < 0) {
+        STRV_FOREACH(p, dirs) {
+                if (files_add(fh, *p, suffix) < 0) {
                         log_error("Failed to search for files.");
-                        e = EINVAL;
+                        r = -EINVAL;
                         goto finish;
                 }
-                dir = va_arg(ap, const char *);
         }
-        va_end(ap);
 
         files = hashmap_get_strv(fh);
         if (files == NULL) {
                 log_error("Failed to compose list of files.");
-                e = ENOMEM;
+                r = -ENOMEM;
                 goto finish;
         }
 
         qsort(files, hashmap_size(fh), sizeof(char *), base_cmp);
 finish:
+        strv_free(dirs);
         hashmap_free(fh);
-        errno = e;
-        return files;
+        *strv = files;
+        return r;
 }