summaryrefslogtreecommitdiffstats
path: root/src/basic/unit-file.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/basic/unit-file.c')
-rw-r--r--src/basic/unit-file.c54
1 files changed, 44 insertions, 10 deletions
diff --git a/src/basic/unit-file.c b/src/basic/unit-file.c
index 00be0601dc..bbe439da05 100644
--- a/src/basic/unit-file.c
+++ b/src/basic/unit-file.c
@@ -275,8 +275,8 @@ int unit_file_build_name_map(
}
STRV_FOREACH(dir, (char**) lp->search_path) {
- struct dirent *de;
_cleanup_closedir_ DIR *d = NULL;
+ struct dirent *de;
d = opendir(*dir);
if (!d) {
@@ -286,18 +286,53 @@ int unit_file_build_name_map(
}
FOREACH_DIRENT_ALL(de, d, log_warning_errno(errno, "Failed to read \"%s\", ignoring: %m", *dir)) {
- char *filename;
_unused_ _cleanup_free_ char *_filename_free = NULL;
_cleanup_free_ char *simplified = NULL;
- const char *suffix, *dst = NULL;
- bool valid_unit_name;
-
- valid_unit_name = unit_name_is_valid(de->d_name, UNIT_NAME_ANY);
+ const char *dst = NULL;
+ char *filename;
/* We only care about valid units and dirs with certain suffixes, let's ignore the
* rest. */
- if (!valid_unit_name &&
- !ENDSWITH_SET(de->d_name, ".wants", ".requires", ".d"))
+
+ if (IN_SET(de->d_type, DT_REG, DT_LNK)) {
+
+ if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
+ continue;
+
+ /* Accept a regular file or symlink whose name is a valid unit file name. */
+
+ } else if (de->d_type == DT_DIR) {
+ bool valid_dir_name = false;
+ const char *suffix;
+
+ /* Also accept a directory whose name is a valid unit file name ending in
+ * .wants/, .requires/ or .d/ */
+
+ if (!paths) /* Skip directories early unless path_cache is requested */
+ continue;
+
+ FOREACH_STRING(suffix, ".wants", ".requires", ".d") {
+ _cleanup_free_ char *chopped = NULL;
+ const char *e;
+
+ e = endswith(de->d_name, suffix);
+ if (!e)
+ continue;
+
+ chopped = strndup(de->d_name, e - de->d_name);
+ if (!chopped)
+ return log_oom();
+
+ if (unit_name_is_valid(chopped, UNIT_NAME_ANY) ||
+ unit_type_from_string(chopped) >= 0) {
+ valid_dir_name = true;
+ break;
+ }
+ }
+
+ if (!valid_dir_name)
+ continue;
+ } else
continue;
filename = path_join(*dir, de->d_name);
@@ -313,9 +348,8 @@ int unit_file_build_name_map(
} else
_filename_free = filename; /* Make sure we free the filename. */
- if (!valid_unit_name)
+ if (!IN_SET(de->d_type, DT_REG, DT_LNK))
continue;
- assert_se(suffix = strrchr(de->d_name, '.'));
/* search_path is ordered by priority (highest first). If the name is already mapped
* to something (incl. itself), it means that we have already seen it, and we should