conf-files: several cleanups and fixlets (#40290)
Fixes #40313. Closes #40285.
This commit is contained in:
@@ -78,7 +78,7 @@ int verb_nvpcrs(int argc, char *argv[], void *userdata) {
|
||||
&l,
|
||||
".nvpcr",
|
||||
/* root= */ NULL,
|
||||
CONF_FILES_REGULAR|CONF_FILES_BASENAME|CONF_FILES_FILTER_MASKED|CONF_FILES_TRUNCATE_SUFFIX,
|
||||
CONF_FILES_REGULAR|CONF_FILES_BASENAME|CONF_FILES_FILTER_MASKED|CONF_FILES_TRUNCATE_SUFFIX|CONF_FILES_WARN,
|
||||
CONF_PATHS_NULSTR("nvpcr"));
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to find .nvpcr files: %m");
|
||||
|
||||
@@ -86,6 +86,7 @@ union sockaddr_union;
|
||||
typedef enum CGroupFlags CGroupFlags;
|
||||
typedef enum CGroupMask CGroupMask;
|
||||
typedef enum ChaseFlags ChaseFlags;
|
||||
typedef enum ConfFilesFlags ConfFilesFlags;
|
||||
typedef enum ExtractFlags ExtractFlags;
|
||||
typedef enum ForkFlags ForkFlags;
|
||||
typedef enum Glyph Glyph;
|
||||
|
||||
+254
-166
@@ -40,7 +40,11 @@ void conf_file_free_many(ConfFile **array, size_t n) {
|
||||
free(array);
|
||||
}
|
||||
|
||||
static int prepare_dirs(const char *root, char * const *dirs, int *ret_rfd, char **ret_root, char ***ret_dirs) {
|
||||
static int conf_files_log_level(ConfFilesFlags flags) {
|
||||
return FLAGS_SET(flags, CONF_FILES_WARN) ? LOG_WARNING : LOG_DEBUG;
|
||||
}
|
||||
|
||||
static int prepare_dirs(const char *root, ConfFilesFlags flags, char * const *dirs, int *ret_rfd, char **ret_root, char ***ret_dirs) {
|
||||
_cleanup_free_ char *root_abs = NULL;
|
||||
_cleanup_strv_free_ char **dirs_abs = NULL;
|
||||
int r;
|
||||
@@ -49,14 +53,16 @@ static int prepare_dirs(const char *root, char * const *dirs, int *ret_rfd, char
|
||||
assert(ret_root);
|
||||
assert(ret_dirs || strv_isempty(dirs));
|
||||
|
||||
int log_level = conf_files_log_level(flags);
|
||||
|
||||
r = empty_or_root_harder_to_null(&root);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to determine if '%s' points to the root directory: %m", strempty(root));
|
||||
return log_full_errno(log_level, r, "Failed to determine if '%s' points to the root directory: %m", strempty(root));
|
||||
|
||||
if (ret_dirs) {
|
||||
dirs_abs = strv_copy(dirs);
|
||||
if (!dirs_abs)
|
||||
return log_oom();
|
||||
return log_oom_full(log_level);
|
||||
}
|
||||
|
||||
if (root) {
|
||||
@@ -64,7 +70,7 @@ static int prepare_dirs(const char *root, char * const *dirs, int *ret_rfd, char
|
||||
* necessary to modify each config directories here. but needs to normalize the root directory. */
|
||||
r = path_make_absolute_cwd(root, &root_abs);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to make '%s' absolute: %m", root);
|
||||
return log_full_errno(log_level, r, "Failed to make '%s' absolute: %m", root);
|
||||
|
||||
path_simplify(root_abs);
|
||||
} else if (ret_dirs) {
|
||||
@@ -72,12 +78,12 @@ static int prepare_dirs(const char *root, char * const *dirs, int *ret_rfd, char
|
||||
* each config directory absolute if relative. */
|
||||
r = path_strv_make_absolute_cwd(dirs_abs);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to make directories absolute: %m");
|
||||
return log_full_errno(log_level, r, "Failed to make directories absolute: %m");
|
||||
}
|
||||
|
||||
_cleanup_close_ int rfd = open(empty_to_root(root_abs), O_CLOEXEC|O_DIRECTORY|O_PATH);
|
||||
if (rfd < 0)
|
||||
return log_debug_errno(errno, "Failed to open '%s': %m", empty_to_root(root_abs));
|
||||
return log_full_errno(log_level, errno, "Failed to open '%s': %m", empty_to_root(root_abs));
|
||||
|
||||
*ret_rfd = TAKE_FD(rfd);
|
||||
*ret_root = TAKE_PTR(root_abs);
|
||||
@@ -86,46 +92,191 @@ static int prepare_dirs(const char *root, char * const *dirs, int *ret_rfd, char
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int conf_file_prefix_root(ConfFile *c, const char *root) {
|
||||
static int conf_file_prefix_root(ConfFile *c, const char *root, ConfFilesFlags flags) {
|
||||
char *p;
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
|
||||
int log_level = conf_files_log_level(flags);
|
||||
|
||||
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);
|
||||
return log_full_errno(log_level, r, "Failed to prefix '%s' with root '%s': %m", c->result, root);
|
||||
free_and_replace(c->result, p);
|
||||
|
||||
r = chaseat_prefix_root(c->resolved_path, root, &p);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to prefix '%s' with root '%s': %m", c->resolved_path, root);
|
||||
return log_full_errno(log_level, r, "Failed to prefix '%s' with root '%s': %m", c->resolved_path, root);
|
||||
free_and_replace(c->resolved_path, p);
|
||||
|
||||
/* Do not use chaseat_prefix_root(), as it is for the result of chaseat(), but the path is not chased. */
|
||||
p = path_join(empty_to_root(root), skip_leading_slash(c->original_path));
|
||||
if (!p)
|
||||
return log_oom_debug();
|
||||
return log_oom_full(log_level);
|
||||
|
||||
path_simplify(p);
|
||||
free_and_replace(c->original_path, p);
|
||||
return free_and_replace(c->original_path, p);
|
||||
}
|
||||
|
||||
static bool conf_files_need_stat(ConfFilesFlags flags) {
|
||||
return (flags & (CONF_FILES_FILTER_MASKED | CONF_FILES_REGULAR | CONF_FILES_DIRECTORY | CONF_FILES_EXECUTABLE)) != 0;
|
||||
}
|
||||
|
||||
static ChaseFlags conf_files_chase_flags(ConfFilesFlags flags) {
|
||||
ChaseFlags chase_flags = CHASE_AT_RESOLVE_IN_ROOT;
|
||||
|
||||
if (!conf_files_need_stat(flags) || FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_SYMLINK))
|
||||
/* Even if no verification is requested, let's unconditionally call chaseat(),
|
||||
* to drop unsafe symlinks. */
|
||||
chase_flags |= CHASE_NONEXISTENT;
|
||||
|
||||
return chase_flags;
|
||||
}
|
||||
|
||||
static int conf_file_chase_and_verify(
|
||||
int rfd,
|
||||
const char *root, /* for logging, can be NULL */
|
||||
const char *original_path, /* for logging */
|
||||
const char *path,
|
||||
const char *name,
|
||||
Set **masked, /* optional */
|
||||
ConfFilesFlags flags,
|
||||
char **ret_path,
|
||||
int *ret_fd,
|
||||
struct stat *ret_stat) {
|
||||
|
||||
_cleanup_free_ char *resolved_path = NULL;
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
struct stat st = {};
|
||||
int r;
|
||||
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(original_path);
|
||||
assert(path);
|
||||
assert(name);
|
||||
|
||||
int log_level = conf_files_log_level(flags);
|
||||
|
||||
root = empty_to_root(root);
|
||||
|
||||
r = chaseat(rfd, path, conf_files_chase_flags(flags), &resolved_path, &fd);
|
||||
if (r < 0)
|
||||
return log_full_errno(log_level, r, "Failed to chase '%s%s': %m",
|
||||
root, skip_leading_slash(original_path));
|
||||
if (r == 0) {
|
||||
if (FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_SYMLINK)) {
|
||||
/* If the path points to /dev/null in a image or so, then the device node may not exist. */
|
||||
if (path_equal(skip_leading_slash(resolved_path), "dev/null")) {
|
||||
if (masked) {
|
||||
/* Mark this one as masked */
|
||||
r = set_put_strdup(masked, name);
|
||||
if (r < 0)
|
||||
return log_oom_full(log_level);
|
||||
}
|
||||
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ERFKILL),
|
||||
"File '%s%s' is a mask (symlink to /dev/null).",
|
||||
root, skip_leading_slash(original_path));
|
||||
}
|
||||
}
|
||||
|
||||
if (conf_files_need_stat(flags))
|
||||
/* If we need to have stat, skip the entry. */
|
||||
return log_full_errno(log_level, SYNTHETIC_ERRNO(ENOENT), "Failed to chase '%s%s': %m",
|
||||
root, skip_leading_slash(original_path));
|
||||
}
|
||||
|
||||
/* Even if we do not need stat, let's take stat now. The caller may use the info later. */
|
||||
if (fd >= 0 && fstat(fd, &st) < 0)
|
||||
return log_full_errno(log_level, errno, "Failed to stat '%s%s': %m",
|
||||
root, skip_leading_slash(original_path));
|
||||
|
||||
/* Is this a masking entry? */
|
||||
if (FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_SYMLINK) && stat_may_be_dev_null(&st)) {
|
||||
if (masked) {
|
||||
/* Mark this one as masked */
|
||||
r = set_put_strdup(masked, name);
|
||||
if (r < 0)
|
||||
return log_oom_full(log_level);
|
||||
}
|
||||
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ERFKILL),
|
||||
"File '%s%s' is a mask (symlink to /dev/null).",
|
||||
root, skip_leading_slash(original_path));
|
||||
}
|
||||
|
||||
if (FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_EMPTY) && stat_is_empty(&st)) {
|
||||
if (masked) {
|
||||
/* Mark this one as masked */
|
||||
r = set_put_strdup(masked, name);
|
||||
if (r < 0)
|
||||
return log_oom_full(log_level);
|
||||
}
|
||||
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ERFKILL),
|
||||
"File '%s%s' is a mask (an empty file).",
|
||||
root, skip_leading_slash(original_path));
|
||||
}
|
||||
|
||||
if (FLAGS_SET(flags, CONF_FILES_REGULAR|CONF_FILES_DIRECTORY)) {
|
||||
if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EBADFD),
|
||||
"File '%s%s' is neither a regular file or directory.",
|
||||
root, skip_leading_slash(original_path));
|
||||
} else {
|
||||
/* Is this node a regular file? */
|
||||
if (FLAGS_SET(flags, CONF_FILES_REGULAR)) {
|
||||
r = stat_verify_regular(&st);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "File '%s%s' is not a regular file: %m",
|
||||
root, skip_leading_slash(original_path));
|
||||
}
|
||||
|
||||
/* Is this node a directory? */
|
||||
if (FLAGS_SET(flags, CONF_FILES_DIRECTORY)) {
|
||||
r = stat_verify_directory(&st);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "File '%s%s' is not a directory: %m",
|
||||
root, skip_leading_slash(original_path));
|
||||
}
|
||||
}
|
||||
|
||||
/* Does this node have the executable bit set?
|
||||
* As requested: check if the file is marked executable. Note that we don't check access(X_OK) here,
|
||||
* as we care about whether the file is marked executable at all, and not whether it is executable
|
||||
* for us, because if so, such errors are stuff we should log about. */
|
||||
if (FLAGS_SET(flags, CONF_FILES_EXECUTABLE) && (st.st_mode & 0111) == 0)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ENOEXEC),
|
||||
"File '%s%s' is not marked executable.",
|
||||
root, skip_leading_slash(original_path));
|
||||
|
||||
if (ret_path)
|
||||
*ret_path = TAKE_PTR(resolved_path);
|
||||
if (ret_fd)
|
||||
*ret_fd = TAKE_FD(fd);
|
||||
if (ret_stat)
|
||||
*ret_stat = st;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int conf_file_new_at(const char *path, int rfd, ChaseFlags chase_flags, ConfFile **ret) {
|
||||
int conf_file_new_at(const char *path, int rfd, ConfFilesFlags flags, ConfFile **ret) {
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(ret);
|
||||
|
||||
int log_level = conf_files_log_level(flags);
|
||||
|
||||
_cleanup_free_ char *root = NULL;
|
||||
if (rfd >= 0 && DEBUG_LOGGING)
|
||||
if (rfd >= 0)
|
||||
(void) fd_get_path(rfd, &root);
|
||||
|
||||
_cleanup_(conf_file_freep) ConfFile *c = new(ConfFile, 1);
|
||||
if (!c)
|
||||
return log_oom_debug();
|
||||
return log_oom_full(log_level);
|
||||
|
||||
*c = (ConfFile) {
|
||||
.original_path = strdup(path),
|
||||
@@ -133,51 +284,55 @@ int conf_file_new_at(const char *path, int rfd, ChaseFlags chase_flags, ConfFile
|
||||
};
|
||||
|
||||
if (!c->original_path)
|
||||
return log_oom_debug();
|
||||
return log_oom_full(log_level);
|
||||
|
||||
r = path_extract_filename(path, &c->name);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to extract filename from '%s': %m", path);
|
||||
return log_full_errno(log_level, r, "Failed to extract filename from '%s': %m", path);
|
||||
|
||||
_cleanup_free_ char *dirpath = NULL, *resolved_dirpath = NULL;
|
||||
r = path_extract_directory(path, &dirpath);
|
||||
if (r < 0 && r != -EDESTADDRREQ)
|
||||
return log_debug_errno(r, "Failed to extract directory from '%s': %m", path);
|
||||
return log_full_errno(log_level, r, "Failed to extract directory from '%s': %m", path);
|
||||
if (r >= 0) {
|
||||
r = chaseat(rfd, dirpath,
|
||||
CHASE_AT_RESOLVE_IN_ROOT |
|
||||
CHASE_MUST_BE_DIRECTORY |
|
||||
(FLAGS_SET(chase_flags, CHASE_NONEXISTENT) ? CHASE_NONEXISTENT : 0),
|
||||
CHASE_MUST_BE_DIRECTORY | conf_files_chase_flags(flags),
|
||||
&resolved_dirpath, /* ret_fd= */ NULL);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to chase '%s%s': %m", empty_to_root(root), skip_leading_slash(dirpath));
|
||||
return log_full_errno(log_level, r, "Failed to chase '%s%s': %m", empty_to_root(root), skip_leading_slash(dirpath));
|
||||
}
|
||||
|
||||
c->result = path_join(resolved_dirpath, c->name);
|
||||
if (!c->result)
|
||||
return log_oom_debug();
|
||||
return log_oom_full(log_level);
|
||||
|
||||
r = chaseat(rfd, c->result, CHASE_AT_RESOLVE_IN_ROOT | chase_flags, &c->resolved_path, &c->fd);
|
||||
r = conf_file_chase_and_verify(
|
||||
rfd,
|
||||
root,
|
||||
c->original_path,
|
||||
c->result,
|
||||
c->name,
|
||||
/* masked= */ NULL,
|
||||
flags,
|
||||
&c->resolved_path,
|
||||
&c->fd,
|
||||
&c->st);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to chase '%s%s': %m", empty_to_root(root), skip_leading_slash(c->original_path));
|
||||
|
||||
if (c->fd >= 0 && fstat(c->fd, &c->st) < 0)
|
||||
return log_debug_errno(r, "Failed to stat '%s%s': %m", empty_to_root(root), skip_leading_slash(c->resolved_path));
|
||||
return r;
|
||||
|
||||
*ret = TAKE_PTR(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int conf_file_new(const char *path, const char *root, ChaseFlags chase_flags, ConfFile **ret) {
|
||||
int conf_file_new(const char *path, const char *root, ConfFilesFlags flags, ConfFile **ret) {
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
assert((chase_flags & (CHASE_PREFIX_ROOT | CHASE_STEP)) == 0);
|
||||
assert(ret);
|
||||
|
||||
_cleanup_free_ char *root_abs = NULL;
|
||||
_cleanup_close_ int rfd = -EBADF;
|
||||
r = prepare_dirs(root, /* dirs= */ NULL, &rfd, &root_abs, /* ret_dirs= */ NULL);
|
||||
r = prepare_dirs(root, flags, /* dirs= */ NULL, &rfd, &root_abs, /* ret_dirs= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -185,17 +340,17 @@ int conf_file_new(const char *path, const char *root, ChaseFlags chase_flags, Co
|
||||
if (!root_abs) {
|
||||
r = path_make_absolute_cwd(path, &path_abs);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to make '%s' absolute: %m", path);
|
||||
return log_full_errno(conf_files_log_level(flags), r, "Failed to make '%s' absolute: %m", path);
|
||||
|
||||
path = path_abs;
|
||||
}
|
||||
|
||||
_cleanup_(conf_file_freep) ConfFile *c = NULL;
|
||||
r = conf_file_new_at(path, rfd, chase_flags, &c);
|
||||
r = conf_file_new_at(path, rfd, flags, &c);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = conf_file_prefix_root(c, root_abs);
|
||||
r = conf_file_prefix_root(c, root_abs, flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -228,137 +383,61 @@ static int files_add(
|
||||
assert(files);
|
||||
assert(masked);
|
||||
|
||||
root = strempty(root);
|
||||
int log_level = conf_files_log_level(flags);
|
||||
|
||||
FOREACH_DIRENT(de, dir, return log_debug_errno(errno, "Failed to read directory '%s/%s': %m",
|
||||
root, skip_leading_slash(original_dirpath))) {
|
||||
root = empty_to_root(root);
|
||||
|
||||
FOREACH_DIRENT(de, dir, return log_full_errno(log_level, errno, "Failed to read directory '%s%s': %m",
|
||||
root, skip_leading_slash(original_dirpath))) {
|
||||
|
||||
_cleanup_free_ char *original_path = path_join(original_dirpath, de->d_name);
|
||||
if (!original_path)
|
||||
return log_oom_debug();
|
||||
return log_oom_full(log_level);
|
||||
|
||||
/* Does this match the suffix? */
|
||||
if (suffix && !endswith(de->d_name, suffix)) {
|
||||
log_debug("Skipping file '%s/%s', suffix is not '%s'.", root, skip_leading_slash(original_path), suffix);
|
||||
log_debug("Skipping file '%s%s', suffix is not '%s'.", root, skip_leading_slash(original_path), suffix);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Has this file already been found in an earlier directory? */
|
||||
if (hashmap_contains(*files, de->d_name)) {
|
||||
log_debug("Skipping overridden file '%s/%s'.", root, skip_leading_slash(original_path));
|
||||
log_debug("Skipping overridden file '%s%s'.", root, skip_leading_slash(original_path));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Has this been masked in an earlier directory? */
|
||||
if ((flags & CONF_FILES_FILTER_MASKED) != 0 && set_contains(*masked, de->d_name)) {
|
||||
log_debug("File '%s/%s' is masked by previous entry.", root, skip_leading_slash(original_path));
|
||||
log_debug("File '%s%s' is masked by previous entry.", root, skip_leading_slash(original_path));
|
||||
continue;
|
||||
}
|
||||
|
||||
_cleanup_free_ char *p = path_join(resolved_dirpath, de->d_name);
|
||||
if (!p)
|
||||
return log_oom_debug();
|
||||
return log_oom_full(log_level);
|
||||
|
||||
_cleanup_free_ char *resolved_path = NULL;
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
bool need_stat = (flags & (CONF_FILES_FILTER_MASKED | CONF_FILES_REGULAR | CONF_FILES_DIRECTORY | CONF_FILES_EXECUTABLE)) != 0;
|
||||
ChaseFlags chase_flags = CHASE_AT_RESOLVE_IN_ROOT;
|
||||
|
||||
if (!need_stat || FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_SYMLINK))
|
||||
/* Even if no verification is requested, let's unconditionally call chaseat(),
|
||||
* to drop unsafe symlinks. */
|
||||
chase_flags |= CHASE_NONEXISTENT;
|
||||
|
||||
r = chaseat(rfd, p, chase_flags, &resolved_path, &fd);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to chase '%s/%s', ignoring: %m",
|
||||
root, skip_leading_slash(original_path));
|
||||
struct stat st;
|
||||
r = conf_file_chase_and_verify(
|
||||
rfd,
|
||||
root,
|
||||
original_path,
|
||||
p,
|
||||
de->d_name,
|
||||
masked,
|
||||
flags,
|
||||
&resolved_path,
|
||||
&fd,
|
||||
&st);
|
||||
if (r == -ENOMEM)
|
||||
return r;
|
||||
if (r < 0)
|
||||
continue;
|
||||
}
|
||||
if (r == 0) {
|
||||
if (FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_SYMLINK)) {
|
||||
|
||||
/* If the path points to /dev/null in a image or so, then the device node may not exist. */
|
||||
if (path_equal(skip_leading_slash(resolved_path), "dev/null")) {
|
||||
/* Mark this one as masked */
|
||||
r = set_put_strdup(masked, de->d_name);
|
||||
if (r < 0)
|
||||
return log_oom_debug();
|
||||
|
||||
log_debug("File '%s/%s' is a mask (symlink to /dev/null).",
|
||||
root, skip_leading_slash(original_path));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (need_stat) {
|
||||
/* If we need to have stat, skip the entry. */
|
||||
log_debug_errno(SYNTHETIC_ERRNO(ENOENT), "Failed to chase '%s/%s', ignoring.",
|
||||
root, skip_leading_slash(original_path));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Even if we do not need stat, let's take stat now. The caller may use the info later. */
|
||||
struct stat st = {};
|
||||
if (fd >= 0 && fstat(fd, &st) < 0) {
|
||||
log_debug_errno(errno, "Failed to stat '%s/%s', ignoring: %m",
|
||||
root, skip_leading_slash(original_path));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Is this a masking entry? */
|
||||
if (FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_SYMLINK) && stat_may_be_dev_null(&st)) {
|
||||
/* Mark this one as masked */
|
||||
r = set_put_strdup(masked, de->d_name);
|
||||
if (r < 0)
|
||||
return log_oom_debug();
|
||||
|
||||
log_debug("File '%s/%s' is a mask (symlink to /dev/null).", root, skip_leading_slash(original_path));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_EMPTY) && stat_is_empty(&st)) {
|
||||
/* Mark this one as masked */
|
||||
r = set_put_strdup(masked, de->d_name);
|
||||
if (r < 0)
|
||||
return log_oom_debug();
|
||||
|
||||
log_debug("File '%s/%s' is a mask (an empty file).", root, skip_leading_slash(original_path));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(flags, CONF_FILES_REGULAR|CONF_FILES_DIRECTORY)) {
|
||||
if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) {
|
||||
log_debug("Ignoring '%s/%s', as it is neither a regular file or directory.", root, skip_leading_slash(original_path));
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
/* Is this node a regular file? */
|
||||
if (FLAGS_SET(flags, CONF_FILES_REGULAR) && !S_ISREG(st.st_mode)) {
|
||||
log_debug("Ignoring '%s/%s', as it is not a regular file.", root, skip_leading_slash(original_path));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Is this node a directory? */
|
||||
if (FLAGS_SET(flags, CONF_FILES_DIRECTORY) && !S_ISDIR(st.st_mode)) {
|
||||
log_debug("Ignoring '%s/%s', as it is not a directory.", root, skip_leading_slash(original_path));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Does this node have the executable bit set?
|
||||
* As requested: check if the file is marked executable. Note that we don't check access(X_OK)
|
||||
* here, as we care about whether the file is marked executable at all, and not whether it is
|
||||
* executable for us, because if so, such errors are stuff we should log about. */
|
||||
if (FLAGS_SET(flags, CONF_FILES_EXECUTABLE) && (st.st_mode & 0111) == 0) {
|
||||
log_debug("Ignoring '%s/%s', as it is not marked executable.", root, skip_leading_slash(original_path));
|
||||
continue;
|
||||
}
|
||||
|
||||
_cleanup_(conf_file_freep) ConfFile *c = new(ConfFile, 1);
|
||||
if (!c)
|
||||
return log_oom_debug();
|
||||
return log_oom_full(log_level);
|
||||
|
||||
*c = (ConfFile) {
|
||||
.name = strdup(de->d_name),
|
||||
@@ -370,12 +449,12 @@ static int files_add(
|
||||
};
|
||||
|
||||
if (!c->name)
|
||||
return log_oom_debug();
|
||||
return log_oom_full(log_level);
|
||||
|
||||
r = hashmap_ensure_put(files, &conf_file_hash_ops, c->name, c);
|
||||
if (r < 0) {
|
||||
assert(r == -ENOMEM);
|
||||
return log_oom_debug();
|
||||
return log_oom_full(log_level);
|
||||
}
|
||||
assert(r > 0);
|
||||
|
||||
@@ -385,7 +464,7 @@ static int files_add(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dump_files(Hashmap *fh, const char *root, ConfFile ***ret_files, size_t *ret_n_files) {
|
||||
static int dump_files(Hashmap *fh, const char *root, ConfFilesFlags flags, ConfFile ***ret_files, size_t *ret_n_files) {
|
||||
ConfFile **files = NULL;
|
||||
size_t n_files = 0;
|
||||
int r;
|
||||
@@ -398,7 +477,7 @@ static int dump_files(Hashmap *fh, const char *root, ConfFile ***ret_files, size
|
||||
/* The entries in the array given by hashmap_dump_sorted() are still owned by the hashmap. */
|
||||
r = hashmap_dump_sorted(fh, (void***) &files, &n_files);
|
||||
if (r < 0)
|
||||
return log_oom_debug();
|
||||
return log_oom_full(conf_files_log_level(flags));
|
||||
|
||||
/* Hence, we need to remove them from the hashmap. */
|
||||
FOREACH_ARRAY(i, files, n_files)
|
||||
@@ -406,7 +485,7 @@ static int dump_files(Hashmap *fh, const char *root, ConfFile ***ret_files, size
|
||||
|
||||
if (root)
|
||||
FOREACH_ARRAY(i, files, n_files) {
|
||||
r = conf_file_prefix_root(*i, root);
|
||||
r = conf_file_prefix_root(*i, root, flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@@ -430,11 +509,13 @@ static int copy_and_sort_files_from_hashmap(
|
||||
|
||||
assert(ret);
|
||||
|
||||
int log_level = conf_files_log_level(flags);
|
||||
|
||||
/* The entries in the array given by hashmap_dump_sorted() are still owned by the hashmap.
|
||||
* Hence, do not use conf_file_free_many() for 'entries' */
|
||||
r = hashmap_dump_sorted(fh, (void***) &files, &n_files);
|
||||
if (r < 0)
|
||||
return log_oom_debug();
|
||||
return log_oom_full(log_level);
|
||||
|
||||
FOREACH_ARRAY(i, files, n_files) {
|
||||
ConfFile *c = *i;
|
||||
@@ -447,7 +528,7 @@ static int copy_and_sort_files_from_hashmap(
|
||||
|
||||
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);
|
||||
return log_full_errno(log_level, r, "Failed to prefix '%s' with root '%s': %m", c->result, root);
|
||||
|
||||
if (FLAGS_SET(flags, CONF_FILES_TRUNCATE_SUFFIX) && suffix) {
|
||||
char *e = endswith(p, suffix);
|
||||
@@ -458,7 +539,7 @@ static int copy_and_sort_files_from_hashmap(
|
||||
}
|
||||
|
||||
if (strv_consume_with_size(&results, &n_results, TAKE_PTR(p)) < 0)
|
||||
return log_oom_debug();
|
||||
return log_oom_full(log_level);
|
||||
|
||||
continue;
|
||||
} else
|
||||
@@ -471,20 +552,20 @@ static int copy_and_sort_files_from_hashmap(
|
||||
|
||||
_cleanup_free_ char *n = strndup(add, e - add);
|
||||
if (!n)
|
||||
return log_oom_debug();
|
||||
return log_oom_full(log_level);
|
||||
|
||||
r = strv_consume_with_size(&results, &n_results, TAKE_PTR(n));
|
||||
} else
|
||||
r = strv_extend_with_size(&results, &n_results, add);
|
||||
if (r < 0)
|
||||
return log_oom_debug();
|
||||
return log_oom_full(log_level);
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(results);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int insert_replacement(Hashmap **fh, ConfFile *replacement, const ConfFile **ret) {
|
||||
static int insert_replacement(Hashmap **fh, ConfFile *replacement, ConfFilesFlags flags, const ConfFile **ret) {
|
||||
_cleanup_(conf_file_freep) ConfFile *c = ASSERT_PTR(replacement);
|
||||
int r;
|
||||
|
||||
@@ -504,7 +585,7 @@ static int insert_replacement(Hashmap **fh, ConfFile *replacement, const ConfFil
|
||||
r = hashmap_ensure_put(fh, &conf_file_hash_ops, c->name, c);
|
||||
if (r < 0) {
|
||||
assert(r == -ENOMEM);
|
||||
return log_oom_debug();
|
||||
return log_oom_full(conf_files_log_level(flags));
|
||||
}
|
||||
assert(r > 0);
|
||||
|
||||
@@ -533,8 +614,10 @@ static int conf_files_list_impl(
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(ret);
|
||||
|
||||
root = empty_to_root(root);
|
||||
|
||||
if (replacement) {
|
||||
r = conf_file_new_at(replacement, rfd, CHASE_NONEXISTENT, &c);
|
||||
r = conf_file_new_at(replacement, rfd, flags & CONF_FILES_WARN, &c);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@@ -546,12 +629,14 @@ static int conf_files_list_impl(
|
||||
r = chase_and_opendirat(rfd, *p, CHASE_AT_RESOLVE_IN_ROOT, &path, &dir);
|
||||
if (r < 0) {
|
||||
if (r != -ENOENT)
|
||||
log_debug_errno(r, "Failed to chase and open directory '%s/%s', ignoring: %m", strempty(root), skip_leading_slash(*p));
|
||||
log_full_errno(conf_files_log_level(flags), r,
|
||||
"Failed to chase and open directory '%s%s', ignoring: %m",
|
||||
root, skip_leading_slash(*p));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c && streq_ptr(path_startswith(c->result, path), c->name)) {
|
||||
r = insert_replacement(&fh, TAKE_PTR(c), &inserted);
|
||||
r = insert_replacement(&fh, TAKE_PTR(c), flags, &inserted);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@@ -562,7 +647,7 @@ static int conf_files_list_impl(
|
||||
}
|
||||
|
||||
if (c) {
|
||||
r = insert_replacement(&fh, TAKE_PTR(c), &inserted);
|
||||
r = insert_replacement(&fh, TAKE_PTR(c), flags, &inserted);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@@ -588,7 +673,7 @@ int conf_files_list_strv(
|
||||
|
||||
assert(ret);
|
||||
|
||||
r = prepare_dirs(root, (char**) dirs, &rfd, &root_abs, &dirs_abs);
|
||||
r = prepare_dirs(root, flags, (char**) dirs, &rfd, &root_abs, &dirs_abs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -617,7 +702,7 @@ int conf_files_list_strv_full(
|
||||
assert(ret_files);
|
||||
assert(ret_n_files);
|
||||
|
||||
r = prepare_dirs(root, (char**) dirs, &rfd, &root_abs, &dirs_abs);
|
||||
r = prepare_dirs(root, flags, (char**) dirs, &rfd, &root_abs, &dirs_abs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -626,7 +711,7 @@ int conf_files_list_strv_full(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return dump_files(fh, empty_to_root(root_abs), ret_files, ret_n_files);
|
||||
return dump_files(fh, empty_to_root(root_abs), flags, ret_files, ret_n_files);
|
||||
}
|
||||
|
||||
int conf_files_list_strv_at(
|
||||
@@ -643,7 +728,7 @@ int conf_files_list_strv_at(
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
assert(ret);
|
||||
|
||||
if (rfd >= 0 && DEBUG_LOGGING)
|
||||
if (rfd >= 0)
|
||||
(void) fd_get_path(rfd, &root); /* for logging */
|
||||
|
||||
r = conf_files_list_impl(suffix, rfd, root, flags, dirs, /* replacement= */ NULL, &fh, /* ret_inserted= */ NULL);
|
||||
@@ -669,14 +754,14 @@ int conf_files_list_strv_at_full(
|
||||
assert(ret_files);
|
||||
assert(ret_n_files);
|
||||
|
||||
if (rfd >= 0 && DEBUG_LOGGING)
|
||||
if (rfd >= 0)
|
||||
(void) fd_get_path(rfd, &root); /* for logging */
|
||||
|
||||
r = conf_files_list_impl(suffix, rfd, root, flags, dirs, /* replacement= */ NULL, &fh, /* ret_inserted= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return dump_files(fh, /* root= */ NULL, ret_files, ret_n_files);
|
||||
return dump_files(fh, /* root= */ NULL, flags, ret_files, ret_n_files);
|
||||
}
|
||||
|
||||
int conf_files_list(char ***ret, const char *suffix, const char *root, ConfFilesFlags flags, const char *dir) {
|
||||
@@ -702,7 +787,7 @@ int conf_files_list_nulstr(char ***ret, const char *suffix, const char *root, Co
|
||||
|
||||
d = strv_split_nulstr(dirs);
|
||||
if (!d)
|
||||
return -ENOMEM;
|
||||
return log_oom_full(conf_files_log_level(flags));
|
||||
|
||||
return conf_files_list_strv(ret, suffix, root, flags, (const char**) d);
|
||||
}
|
||||
@@ -715,7 +800,7 @@ int conf_files_list_nulstr_full(const char *suffix, const char *root, ConfFilesF
|
||||
|
||||
d = strv_split_nulstr(dirs);
|
||||
if (!d)
|
||||
return -ENOMEM;
|
||||
return log_oom_full(conf_files_log_level(flags));
|
||||
|
||||
return conf_files_list_strv_full(suffix, root, flags, (const char**) d, ret_files, ret_n_files);
|
||||
}
|
||||
@@ -727,7 +812,7 @@ int conf_files_list_nulstr_at(char ***ret, const char *suffix, int rfd, ConfFile
|
||||
|
||||
d = strv_split_nulstr(dirs);
|
||||
if (!d)
|
||||
return -ENOMEM;
|
||||
return log_oom_full(conf_files_log_level(flags));
|
||||
|
||||
return conf_files_list_strv_at(ret, suffix, rfd, flags, (const char**) d);
|
||||
}
|
||||
@@ -740,7 +825,7 @@ int conf_files_list_nulstr_at_full(const char *suffix, int rfd, ConfFilesFlags f
|
||||
|
||||
d = strv_split_nulstr(dirs);
|
||||
if (!d)
|
||||
return -ENOMEM;
|
||||
return log_oom_full(conf_files_log_level(flags));
|
||||
|
||||
return conf_files_list_strv_at_full(suffix, rfd, flags, (const char**) d, ret_files, ret_n_files);
|
||||
}
|
||||
@@ -754,7 +839,7 @@ int conf_files_list_with_replacement(
|
||||
|
||||
_cleanup_hashmap_free_ Hashmap *fh = NULL;
|
||||
_cleanup_free_ char *inserted = NULL;
|
||||
ConfFilesFlags flags = CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED_BY_SYMLINK;
|
||||
ConfFilesFlags flags = CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED_BY_SYMLINK | CONF_FILES_WARN;
|
||||
_cleanup_close_ int rfd = -EBADF;
|
||||
_cleanup_free_ char *root_abs = NULL;
|
||||
_cleanup_strv_free_ char **dirs_abs = NULL;
|
||||
@@ -763,7 +848,7 @@ int conf_files_list_with_replacement(
|
||||
|
||||
assert(ret_files);
|
||||
|
||||
r = prepare_dirs(root, config_dirs, &rfd, &root_abs, &dirs_abs);
|
||||
r = prepare_dirs(root, flags, config_dirs, &rfd, &root_abs, &dirs_abs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -775,7 +860,9 @@ int conf_files_list_with_replacement(
|
||||
if (c) {
|
||||
r = chaseat_prefix_root(c->result, root_abs, &inserted);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to prefix '%s' with root '%s': %m", c->result, empty_to_root(root_abs));
|
||||
return log_full_errno(conf_files_log_level(flags), r,
|
||||
"Failed to prefix '%s' with root '%s': %m",
|
||||
c->result, empty_to_root(root_abs));
|
||||
}
|
||||
|
||||
r = copy_and_sort_files_from_hashmap(fh, ".conf", empty_to_root(root_abs), flags, ret_files);
|
||||
@@ -791,6 +878,7 @@ int conf_files_list_dropins(
|
||||
char ***ret,
|
||||
const char *dropin_dirname,
|
||||
const char *root,
|
||||
ConfFilesFlags flags,
|
||||
const char * const *dirs) {
|
||||
|
||||
_cleanup_strv_free_ char **dropin_dirs = NULL;
|
||||
@@ -804,9 +892,9 @@ int conf_files_list_dropins(
|
||||
suffix = strjoina("/", dropin_dirname);
|
||||
r = strv_extend_strv_concat(&dropin_dirs, dirs, suffix);
|
||||
if (r < 0)
|
||||
return r;
|
||||
return log_oom_full(conf_files_log_level(flags));
|
||||
|
||||
return conf_files_list_strv(ret, ".conf", root, 0, (const char* const*) dropin_dirs);
|
||||
return conf_files_list_strv(ret, ".conf", root, flags, (const char* const*) dropin_dirs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,6 +14,7 @@ typedef enum ConfFilesFlags {
|
||||
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 */
|
||||
CONF_FILES_WARN = 1 << 7, /* warn on some errors */
|
||||
} ConfFilesFlags;
|
||||
|
||||
typedef struct ConfFile {
|
||||
@@ -29,8 +30,8 @@ ConfFile* conf_file_free(ConfFile *c);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(ConfFile*, conf_file_free);
|
||||
void conf_file_free_many(ConfFile **array, size_t n);
|
||||
|
||||
int conf_file_new_at(const char *path, int rfd, ChaseFlags chase_flags, ConfFile **ret);
|
||||
int conf_file_new(const char *path, const char *root, ChaseFlags chase_flags, ConfFile **ret);
|
||||
int conf_file_new_at(const char *path, int rfd, ConfFilesFlags flags, ConfFile **ret);
|
||||
int conf_file_new(const char *path, const char *root, ConfFilesFlags flags, ConfFile **ret);
|
||||
|
||||
int conf_files_list(char ***ret, const char *suffix, const char *root, ConfFilesFlags flags, const char *dir);
|
||||
int conf_files_list_at(char ***ret, const char *suffix, int rfd, ConfFilesFlags flags, const char *dir);
|
||||
@@ -56,6 +57,7 @@ int conf_files_list_dropins(
|
||||
char ***ret,
|
||||
const char *dropin_dirname,
|
||||
const char *root,
|
||||
ConfFilesFlags flags,
|
||||
const char * const *dirs);
|
||||
|
||||
typedef int parse_line_t(
|
||||
|
||||
+1
-1
@@ -232,7 +232,7 @@ static int run(int argc, char *argv[]) {
|
||||
} else {
|
||||
_cleanup_strv_free_ char **files = NULL;
|
||||
|
||||
r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char**) CONF_PATHS_STRV("binfmt.d"));
|
||||
r = conf_files_list_strv(&files, ".conf", /* root= */ NULL, CONF_FILES_WARN, (const char**) CONF_PATHS_STRV("binfmt.d"));
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate binfmt.d files: %m");
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ int ipe_setup(void) {
|
||||
&policies,
|
||||
".p7b",
|
||||
/* root= */ NULL,
|
||||
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED,
|
||||
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN,
|
||||
CONF_PATHS_NULSTR("ipe"));
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to assemble list of IPE policies: %m");
|
||||
|
||||
@@ -52,7 +52,7 @@ static int load_and_print(void) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char **) dirs);
|
||||
r = conf_files_list_strv(&files, ".conf", /* root= */ NULL, CONF_FILES_WARN, (const char **) dirs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -1521,7 +1521,7 @@ static int manager_load_public_keys(Manager *m) {
|
||||
&files,
|
||||
".public",
|
||||
NULL,
|
||||
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED,
|
||||
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN,
|
||||
KEY_PATHS_NULSTR);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to assemble list of public key directories: %m");
|
||||
|
||||
@@ -685,7 +685,7 @@ static int context_load_plugins(Context *c) {
|
||||
&c->plugins,
|
||||
".install",
|
||||
c->rfd,
|
||||
CONF_FILES_EXECUTABLE | CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED,
|
||||
CONF_FILES_EXECUTABLE | CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED | CONF_FILES_WARN,
|
||||
STRV_MAKE_CONST("/etc/kernel/install.d", "/usr/lib/kernel/install.d"));
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to find plugins: %m");
|
||||
|
||||
@@ -453,7 +453,9 @@ int catalog_update(const char *database, const char *root, const char* const *di
|
||||
|
||||
CLEANUP_ARRAY(files, n_files, conf_file_free_many);
|
||||
|
||||
r = conf_files_list_strv_full(".catalog", root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED, dirs, &files, &n_files);
|
||||
r = conf_files_list_strv_full(".catalog", root,
|
||||
CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED | CONF_FILES_WARN,
|
||||
dirs, &files, &n_files);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get catalog files: %m");
|
||||
|
||||
|
||||
@@ -423,7 +423,7 @@ static int run(int argc, char *argv[]) {
|
||||
RET_GATHER(ret, modules_list_append_dup(&module_set, *i));
|
||||
|
||||
r = conf_files_list_nulstr_full(".conf", /* root= */ NULL,
|
||||
CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED,
|
||||
CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED | CONF_FILES_WARN,
|
||||
conf_file_dirs, &files, &n_files);
|
||||
if (r < 0)
|
||||
RET_GATHER(ret, log_error_errno(r, "Failed to enumerate modules-load.d files: %m"));
|
||||
|
||||
@@ -1098,7 +1098,7 @@ int netdev_load(Manager *manager) {
|
||||
|
||||
assert(manager);
|
||||
|
||||
r = conf_files_list_strv(&files, ".netdev", NULL, 0, NETWORK_DIRS);
|
||||
r = conf_files_list_strv(&files, ".netdev", /* root= */ NULL, CONF_FILES_WARN, NETWORK_DIRS);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate netdev files: %m");
|
||||
|
||||
@@ -1127,7 +1127,7 @@ int netdev_reload(Manager *manager) {
|
||||
|
||||
assert(manager);
|
||||
|
||||
r = conf_files_list_strv(&files, ".netdev", NULL, 0, NETWORK_DIRS);
|
||||
r = conf_files_list_strv(&files, ".netdev", /* root= */ NULL, CONF_FILES_WARN, NETWORK_DIRS);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate netdev files: %m");
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ static int get_config_files_by_name(
|
||||
if (!dropin_dirname)
|
||||
return -ENOMEM;
|
||||
|
||||
r = conf_files_list_dropins(ret_dropins, dropin_dirname, /* root= */ NULL, NETWORK_DIRS);
|
||||
r = conf_files_list_dropins(ret_dropins, dropin_dirname, /* root= */ NULL, CONF_FILES_WARN, NETWORK_DIRS);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -612,7 +612,7 @@ int network_load(Manager *manager, OrderedHashmap **ret) {
|
||||
assert(manager);
|
||||
assert(ret);
|
||||
|
||||
r = conf_files_list_strv(&files, ".network", NULL, 0, NETWORK_DIRS);
|
||||
r = conf_files_list_strv(&files, ".network", /* root= */ NULL, CONF_FILES_WARN, NETWORK_DIRS);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate network files: %m");
|
||||
|
||||
|
||||
@@ -1802,7 +1802,9 @@ static int event_log_add_component_dir(EventLog *el, const char *path, char **ba
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
r = conf_files_list_strv(&files, ".pcrlock", /* root= */ NULL, CONF_FILES_REGULAR, (const char*const*) search);
|
||||
r = conf_files_list_strv(&files, ".pcrlock", /* root= */ NULL,
|
||||
CONF_FILES_REGULAR|CONF_FILES_WARN,
|
||||
(const char*const*) search);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate .pcrlock files for component '%s': %m", id);
|
||||
|
||||
@@ -1829,7 +1831,9 @@ static int event_log_load_components(EventLog *el) {
|
||||
"/usr/local/lib/pcrlock.d",
|
||||
"/usr/lib/pcrlock.d");
|
||||
|
||||
r = conf_files_list_strv(&files, NULL, NULL, CONF_FILES_REGULAR|CONF_FILES_DIRECTORY|CONF_FILES_FILTER_MASKED, (const char*const*) dirs);
|
||||
r = conf_files_list_strv(&files, /* suffix= */ NULL, /* root= */ NULL,
|
||||
CONF_FILES_REGULAR|CONF_FILES_DIRECTORY|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN,
|
||||
(const char*const*) dirs);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate .pcrlock files: %m");
|
||||
|
||||
|
||||
+1
-1
@@ -3375,7 +3375,7 @@ static int context_read_definitions(Context *context) {
|
||||
&files,
|
||||
".conf",
|
||||
context->definitions ? NULL : arg_root,
|
||||
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED,
|
||||
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN,
|
||||
dirs);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate *.conf files: %m");
|
||||
|
||||
@@ -211,7 +211,7 @@ int manager_load_delegates(Manager *m) {
|
||||
|
||||
assert(m);
|
||||
|
||||
r = conf_files_list_strv(&files, ".dns-delegate", /* root= */ NULL, /* flags= */ 0, DNS_DELEGATE_SEARCH_DIRS);
|
||||
r = conf_files_list_strv(&files, ".dns-delegate", /* root= */ NULL, CONF_FILES_WARN, DNS_DELEGATE_SEARCH_DIRS);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate .dns-delegate files: %m");
|
||||
|
||||
|
||||
@@ -437,7 +437,7 @@ static int dns_trust_anchor_load_files(
|
||||
assert(suffix);
|
||||
assert(loader);
|
||||
|
||||
r = conf_files_list_nulstr(&files, suffix, NULL, 0, trust_anchor_dirs);
|
||||
r = conf_files_list_nulstr(&files, suffix, /* root= */ NULL, CONF_FILES_WARN, trust_anchor_dirs);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate %s trust anchor files: %m", suffix);
|
||||
|
||||
|
||||
@@ -225,7 +225,7 @@ int dnssd_load(Manager *manager) {
|
||||
if (manager->mdns_support != RESOLVE_SUPPORT_YES)
|
||||
return 0;
|
||||
|
||||
r = conf_files_list_strv(&files, ".dnssd", NULL, 0, DNSSD_SERVICE_DIRS);
|
||||
r = conf_files_list_strv(&files, ".dnssd", /* root= */ NULL, CONF_FILES_WARN, DNSSD_SERVICE_DIRS);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate .dnssd files: %m");
|
||||
|
||||
|
||||
@@ -615,7 +615,9 @@ int config_parse_many(
|
||||
assert(dropin_dirname);
|
||||
assert(table);
|
||||
|
||||
r = conf_files_list_dropins(&files, dropin_dirname, root, conf_file_dirs);
|
||||
r = conf_files_list_dropins(&files, dropin_dirname, root,
|
||||
FLAGS_SET(flags, CONFIG_PARSE_WARN) ? CONF_FILES_WARN : 0,
|
||||
conf_file_dirs);
|
||||
if (r < 0)
|
||||
return log_full_errno(FLAGS_SET(flags, CONFIG_PARSE_WARN) ? LOG_WARNING : LOG_DEBUG, r,
|
||||
"Failed to list drop-ins in %s: %m", dropin_dirname);
|
||||
@@ -690,7 +692,7 @@ static int dropins_get_stats_by_path(
|
||||
if (!strextend(&dropin_dirname, ".d"))
|
||||
return -ENOMEM;
|
||||
|
||||
r = conf_files_list_dropins(&files, dropin_dirname, /* root= */ NULL, conf_file_dirs);
|
||||
r = conf_files_list_dropins(&files, dropin_dirname, /* root= */ NULL, /* flags= */ 0, conf_file_dirs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -715,7 +717,7 @@ static int dropins_get_stats_by_path(
|
||||
int config_get_stats_by_path(
|
||||
const char *suffix,
|
||||
const char *root,
|
||||
unsigned flags,
|
||||
ConfFilesFlags flags,
|
||||
const char* const* dirs,
|
||||
bool check_dropins,
|
||||
Hashmap **ret) {
|
||||
|
||||
@@ -112,7 +112,7 @@ static inline int config_parse_standard_file_with_dropins(
|
||||
int config_get_stats_by_path(
|
||||
const char *suffix,
|
||||
const char *root,
|
||||
unsigned flags,
|
||||
ConfFilesFlags flags,
|
||||
const char* const* dirs,
|
||||
bool check_dropins,
|
||||
Hashmap **ret);
|
||||
|
||||
+1
-1
@@ -287,7 +287,7 @@ int unit_file_find_dropin_paths(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = conf_files_list_strv(ret, file_suffix, NULL, 0, (const char**) dirs);
|
||||
r = conf_files_list_strv(ret, file_suffix, /* root= */ NULL, CONF_FILES_WARN, (const char**) dirs);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to create the list of configuration files: %m");
|
||||
|
||||
|
||||
@@ -323,7 +323,7 @@ int execute_directories(
|
||||
&paths,
|
||||
/* suffix= */ NULL,
|
||||
/* root= */ NULL,
|
||||
CONF_FILES_EXECUTABLE|CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED,
|
||||
CONF_FILES_EXECUTABLE|CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN,
|
||||
directories);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "%s: failed to enumerate executables: %m", name);
|
||||
|
||||
@@ -610,7 +610,9 @@ int hwdb_update(const char *root, const char *hwdb_bin_dir, bool strict, bool co
|
||||
|
||||
CLEANUP_ARRAY(files, n_files, conf_file_free_many);
|
||||
|
||||
r = conf_files_list_strv_full(".hwdb", root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED, conf_file_dirs, &files, &n_files);
|
||||
r = conf_files_list_strv_full(".hwdb", root,
|
||||
CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED | CONF_FILES_WARN,
|
||||
conf_file_dirs, &files, &n_files);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate hwdb files: %m");
|
||||
|
||||
|
||||
@@ -418,7 +418,7 @@ static int relabel_extra(void) {
|
||||
*/
|
||||
|
||||
r = conf_files_list(&files, ".relabel", NULL,
|
||||
CONF_FILES_FILTER_MASKED | CONF_FILES_REGULAR,
|
||||
CONF_FILES_FILTER_MASKED | CONF_FILES_REGULAR | CONF_FILES_WARN,
|
||||
"/run/systemd/relabel-extra.d/");
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate /run/systemd/relabel-extra.d/, ignoring: %m");
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "chase.h"
|
||||
#include "color-util.h"
|
||||
#include "conf-files.h"
|
||||
#include "constants.h"
|
||||
@@ -325,9 +324,22 @@ static int cat_file_by_path(const char *p, bool *newline, CatFlags flags) {
|
||||
|
||||
assert(p);
|
||||
|
||||
r = conf_file_new(p, /* root= */ NULL, CHASE_MUST_BE_REGULAR, &c);
|
||||
r = conf_file_new(p, /* root= */ NULL, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED | CONF_FILES_WARN, &c);
|
||||
if (r == -ERFKILL) { /* masked */
|
||||
if (newline) {
|
||||
if (*newline)
|
||||
putc('\n', stdout);
|
||||
*newline = true;
|
||||
}
|
||||
|
||||
printf("%s# %s is a mask.%s\n",
|
||||
ansi_highlight_magenta(),
|
||||
p,
|
||||
ansi_normal());
|
||||
return 0;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to chase '%s': %m", p);
|
||||
return r;
|
||||
|
||||
return cat_file(c, newline, flags);
|
||||
}
|
||||
@@ -458,7 +470,8 @@ int conf_files_cat(const char *root, const char *name, CatFlags flags) {
|
||||
if (!p)
|
||||
return log_oom();
|
||||
|
||||
if (conf_file_new(p, root, CHASE_MUST_BE_REGULAR, &c) >= 0)
|
||||
r = conf_file_new(p, root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED, &c);
|
||||
if (r >= 0 || r == -ERFKILL) /* Found a regular file or masked file */
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -473,7 +486,7 @@ int conf_files_cat(const char *root, const char *name, CatFlags flags) {
|
||||
ConfFile **dropins = NULL;
|
||||
size_t n_dropins = 0;
|
||||
CLEANUP_ARRAY(dropins, n_dropins, conf_file_free_many);
|
||||
r = conf_files_list_strv_full(extension, root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED, (const char* const*) dirs, &dropins, &n_dropins);
|
||||
r = conf_files_list_strv_full(extension, root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED | CONF_FILES_WARN, (const char* const*) dirs, &dropins, &n_dropins);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to query file list: %m");
|
||||
|
||||
|
||||
+2
-1
@@ -461,7 +461,8 @@ static int run(int argc, char *argv[]) {
|
||||
} else {
|
||||
_cleanup_strv_free_ char **files = NULL;
|
||||
|
||||
r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char**) CONF_PATHS_STRV("sysctl.d"));
|
||||
r = conf_files_list_strv(&files, ".conf", /* root= */ NULL, CONF_FILES_WARN,
|
||||
(const char**) CONF_PATHS_STRV("sysctl.d"));
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate sysctl.d files: %m");
|
||||
|
||||
|
||||
@@ -136,7 +136,9 @@ static int read_definitions(
|
||||
assert(dirs);
|
||||
assert(suffix);
|
||||
|
||||
r = conf_files_list_strv_full(suffix, arg_root, CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED, dirs, &files, &n_files);
|
||||
r = conf_files_list_strv_full(suffix, arg_root,
|
||||
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN,
|
||||
dirs, &files, &n_files);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate sysupdate.d/*%s definitions: %m", suffix);
|
||||
|
||||
@@ -209,7 +211,7 @@ static int context_read_definitions(Context *c, const char* node, bool requires_
|
||||
CLEANUP_ARRAY(files, n_files, conf_file_free_many);
|
||||
|
||||
r = conf_files_list_strv_full(".feature", arg_root,
|
||||
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED,
|
||||
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN,
|
||||
(const char**) dirs, &files, &n_files);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate sysupdate.d/*.feature definitions: %m");
|
||||
@@ -1558,7 +1560,8 @@ static int verb_components(int argc, char **argv, void *userdata) {
|
||||
|
||||
CLEANUP_ARRAY(directories, n_directories, conf_file_free_many);
|
||||
|
||||
r = conf_files_list_strv_full(".d", arg_root, CONF_FILES_DIRECTORY, (const char * const *) CONF_PATHS_STRV(""), &directories, &n_directories);
|
||||
r = conf_files_list_strv_full(".d", arg_root, CONF_FILES_DIRECTORY|CONF_FILES_WARN,
|
||||
(const char * const *) CONF_PATHS_STRV(""), &directories, &n_directories);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate directories: %m");
|
||||
|
||||
|
||||
@@ -4,8 +4,11 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "path-util.h"
|
||||
#include "pretty-print.h"
|
||||
#include "rm-rf.h"
|
||||
#include "tests.h"
|
||||
#include "tmpfile-util.h"
|
||||
|
||||
#define CYLON_WIDTH 6
|
||||
|
||||
@@ -53,6 +56,13 @@ TEST(cat_files) {
|
||||
|
||||
if (access("/etc/fstab", R_OK) >= 0)
|
||||
assert_se(cat_files("/etc/fstab", STRV_MAKE("/etc/fstab", "/etc/fstab"), 0) == 0);
|
||||
|
||||
/* Test masked file (symlink to /dev/null) - should succeed with exit code 0 */
|
||||
_cleanup_(rm_rf_physical_and_freep) char *tmp = NULL;
|
||||
ASSERT_OK(mkdtemp_malloc("/tmp/test-cat-files-XXXXXX", &tmp));
|
||||
_cleanup_free_ char *masked_file = ASSERT_NOT_NULL(path_join(tmp, "masked.conf"));
|
||||
ASSERT_OK_ERRNO(symlink("/dev/null", masked_file));
|
||||
ASSERT_OK(cat_files(masked_file, /* dropins= */ NULL, /* flags= */ 0));
|
||||
}
|
||||
|
||||
TEST(red_green_cross_check_mark) {
|
||||
|
||||
@@ -184,7 +184,9 @@ static int context_parse_ntp_services_from_disk(Context *c) {
|
||||
_cleanup_strv_free_ char **files = NULL;
|
||||
int r;
|
||||
|
||||
r = conf_files_list_strv(&files, ".list", NULL, CONF_FILES_FILTER_MASKED, UNIT_LIST_DIRS);
|
||||
r = conf_files_list_strv(&files, ".list", /* root= */ NULL,
|
||||
CONF_FILES_FILTER_MASKED | CONF_FILES_WARN,
|
||||
UNIT_LIST_DIRS);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate .list files: %m");
|
||||
|
||||
|
||||
@@ -450,7 +450,7 @@ static int setup_nvpcr(void) {
|
||||
&l,
|
||||
".nvpcr",
|
||||
/* root= */ NULL,
|
||||
CONF_FILES_REGULAR|CONF_FILES_BASENAME|CONF_FILES_FILTER_MASKED|CONF_FILES_TRUNCATE_SUFFIX,
|
||||
CONF_FILES_REGULAR|CONF_FILES_BASENAME|CONF_FILES_FILTER_MASKED|CONF_FILES_TRUNCATE_SUFFIX|CONF_FILES_WARN,
|
||||
CONF_PATHS_NULSTR("nvpcr"));
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to find .nvpcr files: %m");
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "chase.h"
|
||||
#include "conf-files.h"
|
||||
#include "fd-util.h"
|
||||
#include "fuzz.h"
|
||||
@@ -29,7 +28,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
assert_se(rules = udev_rules_new(RESOLVE_NAME_EARLY));
|
||||
|
||||
_cleanup_(conf_file_freep) ConfFile *c = NULL;
|
||||
ASSERT_OK(conf_file_new(filename, /* root= */ NULL, CHASE_MUST_BE_REGULAR, &c));
|
||||
ASSERT_OK(conf_file_new(filename, /* root= */ NULL, CONF_FILES_REGULAR, &c));
|
||||
|
||||
r = udev_rules_parse_file(rules, c, /* extra_checks= */ false, /* ret= */ NULL);
|
||||
log_info_errno(r, "Parsing %s: %m", filename);
|
||||
|
||||
@@ -342,7 +342,7 @@ int link_config_load(LinkConfigContext *ctx) {
|
||||
|
||||
link_configs_free(ctx);
|
||||
|
||||
r = conf_files_list_strv(&files, ".link", NULL, 0, NETWORK_DIRS);
|
||||
r = conf_files_list_strv(&files, ".link", /* root= */ NULL, CONF_FILES_WARN, NETWORK_DIRS);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "failed to enumerate link files: %m");
|
||||
|
||||
|
||||
+15
-8
@@ -7,7 +7,6 @@
|
||||
#include "alloc-util.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-util.h"
|
||||
#include "chase.h"
|
||||
#include "conf-files.h"
|
||||
#include "constants.h"
|
||||
#include "device-private.h"
|
||||
@@ -249,11 +248,15 @@ static int search_rules_file_in_conf_dirs(const char *s, const char *root, ConfF
|
||||
return log_oom();
|
||||
|
||||
_cleanup_(conf_file_freep) ConfFile *c = NULL;
|
||||
r = conf_file_new(path, root, CHASE_MUST_BE_REGULAR, &c);
|
||||
r = conf_file_new(path, root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED, &c);
|
||||
if (r == -ERFKILL) {
|
||||
log_warning_errno(r, "File '%s%s' is a mask, ignoring.", empty_to_root(root), skip_leading_slash(path));
|
||||
return 1; /* Found masked file. */
|
||||
}
|
||||
if (r == -ENOENT)
|
||||
continue;
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to chase \"%s\": %m", path);
|
||||
return log_error_errno(r, "Failed to chase '%s%s': %m", empty_to_root(root), skip_leading_slash(path));
|
||||
|
||||
if (!GREEDY_REALLOC_APPEND(*files, *n_files, &c, 1))
|
||||
return log_oom();
|
||||
@@ -279,7 +282,11 @@ static int search_rules_file(const char *s, const char *root, ConfFile ***files,
|
||||
|
||||
/* If not found, or if it is a path, then chase it. */
|
||||
_cleanup_(conf_file_freep) ConfFile *c = NULL;
|
||||
r = conf_file_new(s, root, CHASE_MUST_BE_REGULAR, &c);
|
||||
r = conf_file_new(s, root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED, &c);
|
||||
if (r == -ERFKILL) {
|
||||
log_warning_errno(r, "File '%s%s' is a mask, ignoring.", empty_to_root(root), skip_leading_slash(s));
|
||||
return 0; /* Found masked file. */
|
||||
}
|
||||
if (r >= 0) {
|
||||
if (!GREEDY_REALLOC_APPEND(*files, *n_files, &c, 1))
|
||||
return log_oom();
|
||||
@@ -289,7 +296,7 @@ static int search_rules_file(const char *s, const char *root, ConfFile ***files,
|
||||
}
|
||||
|
||||
if (r != -EISDIR)
|
||||
return log_error_errno(r, "Failed to chase \"%s\": %m", s);
|
||||
return log_error_errno(r, "Failed to chase '%s%s': %m", empty_to_root(root), skip_leading_slash(s));
|
||||
|
||||
/* If a directory is specified, then find all rules file in the directory. */
|
||||
ConfFile **f = NULL;
|
||||
@@ -297,9 +304,9 @@ static int search_rules_file(const char *s, const char *root, ConfFile ***files,
|
||||
|
||||
CLEANUP_ARRAY(f, n, conf_file_free_many);
|
||||
|
||||
r = conf_files_list_strv_full(".rules", root, CONF_FILES_REGULAR, (const char* const*) STRV_MAKE_CONST(s), &f, &n);
|
||||
r = conf_files_list_strv_full(".rules", root, CONF_FILES_REGULAR | CONF_FILES_WARN, (const char* const*) STRV_MAKE_CONST(s), &f, &n);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate rules files in '%s': %m", s);
|
||||
return log_error_errno(r, "Failed to enumerate rules files in '%s%s': %m", empty_to_root(root), skip_leading_slash(s));
|
||||
|
||||
if (!GREEDY_REALLOC_APPEND(*files, *n_files, f, n))
|
||||
return log_oom();
|
||||
@@ -320,7 +327,7 @@ int search_rules_files(char * const *a, const char *root, ConfFile ***ret_files,
|
||||
assert(ret_n_files);
|
||||
|
||||
if (strv_isempty(a)) {
|
||||
r = conf_files_list_strv_full(".rules", root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED,
|
||||
r = conf_files_list_strv_full(".rules", root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED | CONF_FILES_WARN,
|
||||
(const char* const*) CONF_PATHS_STRV("udev/rules.d"), &files, &n_files);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate rules files: %m");
|
||||
|
||||
@@ -38,7 +38,7 @@ udevadm cat 99-systemd
|
||||
udevadm cat 99-systemd.rules
|
||||
udevadm cat /usr/lib/udev/rules.d/99-systemd.rules
|
||||
udevadm cat /usr/lib/udev/rules.d
|
||||
(! udevadm cat /dev/null)
|
||||
udevadm cat /dev/null
|
||||
udevadm cat --config
|
||||
udevadm cat -h
|
||||
|
||||
|
||||
@@ -118,8 +118,7 @@ assert_1 --resolve-names=now
|
||||
assert_1 ./nosuchfile
|
||||
# Failed to parse rules file ./nosuchfile: No such file or directory
|
||||
assert_1 ./nosuchfile /dev/null
|
||||
# '/dev/null' is neither a regular file nor a directory: File descriptor in bad state
|
||||
assert_1 /dev/null
|
||||
assert_0 /dev/null
|
||||
|
||||
rules_dir='etc/udev/rules.d'
|
||||
mkdir -p "${rules_dir}"
|
||||
|
||||
Reference in New Issue
Block a user