From d2d1fc59b4e7eae5eeb1e50c6ad42e8d5969daa2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 27 Oct 2025 12:22:02 +0100 Subject: [PATCH] conf-files: optionally truncate suffix from discovered files --- src/basic/conf-files.c | 47 +++++++++++++++++++++++++++++++++++------- src/basic/conf-files.h | 13 ++++++------ 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/basic/conf-files.c b/src/basic/conf-files.c index c00325f2e44..77affe269cd 100644 --- a/src/basic/conf-files.c +++ b/src/basic/conf-files.c @@ -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; diff --git a/src/basic/conf-files.h b/src/basic/conf-files.h index f6e63120e57..05a2966e216 100644 --- a/src/basic/conf-files.h +++ b/src/basic/conf-files.h @@ -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 { -- 2.47.3