]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
conf-files: optionally truncate suffix from discovered files
authorLennart Poettering <lennart@poettering.net>
Mon, 27 Oct 2025 11:22:02 +0000 (12:22 +0100)
committerLennart Poettering <lennart@poettering.net>
Sun, 2 Nov 2025 20:14:35 +0000 (21:14 +0100)
src/basic/conf-files.c
src/basic/conf-files.h

index c00325f2e4443e1ffb66637726d3780d8bd4a12a..77affe269cd2d7bc38a9f457212472e5f09a2801 100644 (file)
@@ -416,7 +416,13 @@ static int dump_files(Hashmap *fh, const char *root, ConfFile ***ret_files, size
         return 0;
 }
 
-static int copy_and_sort_files_from_hashmap(Hashmap *fh, const char *root, ConfFilesFlags flags, char ***ret) {
+static int copy_and_sort_files_from_hashmap(
+                Hashmap *fh,
+                const char *suffix,
+                const char *root,
+                ConfFilesFlags flags,
+                char ***ret) {
+
         _cleanup_strv_free_ char **results = NULL;
         _cleanup_free_ ConfFile **files = NULL;
         size_t n_files = 0, n_results = 0;
@@ -432,19 +438,44 @@ static int copy_and_sort_files_from_hashmap(Hashmap *fh, const char *root, ConfF
 
         FOREACH_ARRAY(i, files, n_files) {
                 ConfFile *c = *i;
+                const char *add = NULL;
 
                 if (FLAGS_SET(flags, CONF_FILES_BASENAME))
-                        r = strv_extend_with_size(&results, &n_results, c->name);
+                        add = c->name;
                 else if (root) {
-                        char *p;
+                        _cleanup_free_ char *p = NULL;
 
                         r = chaseat_prefix_root(c->result, root, &p);
                         if (r < 0)
                                 return log_debug_errno(r, "Failed to prefix '%s' with root '%s': %m", c->result, root);
 
-                        r = strv_consume_with_size(&results, &n_results, TAKE_PTR(p));
+                        if (FLAGS_SET(flags, CONF_FILES_TRUNCATE_SUFFIX) && suffix) {
+                                char *e = endswith(p, suffix);
+                                if (!e)
+                                        continue;
+
+                                *e = 0;
+                        }
+
+                        if (strv_consume_with_size(&results, &n_results, TAKE_PTR(p)) < 0)
+                                return log_oom_debug();
+
+                        continue;
+                } else
+                        add = c->result;
+
+                if (FLAGS_SET(flags, CONF_FILES_TRUNCATE_SUFFIX)) {
+                        const char *e = endswith(add, suffix);
+                        if (!e)
+                                continue;
+
+                        _cleanup_free_ char *n = strndup(add, e - add);
+                        if (!n)
+                                return log_oom_debug();
+
+                        r = strv_consume_with_size(&results, &n_results, TAKE_PTR(n));
                 } else
-                        r = strv_extend_with_size(&results, &n_results, c->result);
+                        r = strv_extend_with_size(&results, &n_results, add);
                 if (r < 0)
                         return log_oom_debug();
         }
@@ -566,7 +597,7 @@ int conf_files_list_strv(
         if (r < 0)
                 return r;
 
-        return copy_and_sort_files_from_hashmap(fh, empty_to_root(root_abs), flags, ret);
+        return copy_and_sort_files_from_hashmap(fh, suffix, empty_to_root(root_abs), flags, ret);
 }
 
 int conf_files_list_strv_full(
@@ -619,7 +650,7 @@ int conf_files_list_strv_at(
         if (r < 0)
                 return r;
 
-        return copy_and_sort_files_from_hashmap(fh, /* root = */ NULL, flags, ret);
+        return copy_and_sort_files_from_hashmap(fh, suffix, /* root = */ NULL, flags, ret);
 }
 
 int conf_files_list_strv_at_full(
@@ -747,7 +778,7 @@ int conf_files_list_with_replacement(
                         return log_debug_errno(r, "Failed to prefix '%s' with root '%s': %m", c->result, empty_to_root(root_abs));
         }
 
-        r = copy_and_sort_files_from_hashmap(fh, empty_to_root(root_abs), flags, ret_files);
+        r = copy_and_sort_files_from_hashmap(fh, ".conf", empty_to_root(root_abs), flags, ret_files);
         if (r < 0)
                 return r;
 
index f6e63120e5712a55e29b744fce8105edc89d04ef..05a2966e216eac140ea7004182330a79d4c0037d 100644 (file)
@@ -6,13 +6,14 @@
 #include "basic-forward.h"
 
 typedef enum ConfFilesFlags {
-        CONF_FILES_EXECUTABLE               = 1 << 0,
-        CONF_FILES_REGULAR                  = 1 << 1,
-        CONF_FILES_DIRECTORY                = 1 << 2,
-        CONF_FILES_BASENAME                 = 1 << 3,
-        CONF_FILES_FILTER_MASKED_BY_SYMLINK = 1 << 4,
-        CONF_FILES_FILTER_MASKED_BY_EMPTY   = 1 << 5,
+        CONF_FILES_EXECUTABLE               = 1 << 0, /* inode must be marked executable */
+        CONF_FILES_REGULAR                  = 1 << 1, /* inode must be regular file */
+        CONF_FILES_DIRECTORY                = 1 << 2, /* inode must be directory */
+        CONF_FILES_BASENAME                 = 1 << 3, /* only return basename of file, not full path */
+        CONF_FILES_FILTER_MASKED_BY_SYMLINK = 1 << 4, /* implement /dev/null symlink based masking */
+        CONF_FILES_FILTER_MASKED_BY_EMPTY   = 1 << 5, /* implement masking by empty file */
         CONF_FILES_FILTER_MASKED            = CONF_FILES_FILTER_MASKED_BY_SYMLINK | CONF_FILES_FILTER_MASKED_BY_EMPTY,
+        CONF_FILES_TRUNCATE_SUFFIX          = 1 << 6, /* truncate specified suffix from return filename or path */
 } ConfFilesFlags;
 
 typedef struct ConfFile {