summaryrefslogtreecommitdiff
path: root/src/shared/pretty-print.c
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-01-03 11:34:22 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-02-18 10:29:33 +0100
commitf1d9d36ac5958006bbd464944ef490a198d38189 (patch)
treeae1db00b1a688670bb9a9d969b5af4fa3e39b7b6 /src/shared/pretty-print.c
parentc2953e0808204eaf34fda095dbafa1c1ecc3b419 (diff)
downloadsystemd-f1d9d36ac5958006bbd464944ef490a198d38189.tar.gz
analyze: generalize cat-config to apply to tmpfiles, presets, hwdb.d, etc.
Fixes #10256. What works: systemd-analyze cat-config systemd/system-preset systemd-analyze cat-config systemd/user-preset systemd-analyze cat-config tmpfiles.d systemd-analyze cat-config sysusers.d systemd-analyze cat-config systemd/sleep.conf systemd-analyze cat-config systemd/user.conf systemd-analyze cat-config systemd/system.conf systemd-analyze cat-config udev/udev.conf (and other .conf files) systemd-analyze cat-config udev/rules.d systemd-analyze cat-config environment.d systemd-analyze cat-config environment Directories may be specified with the trailing dash or not. The caveat is that for user configuration, systemd and other tools also look at ~/.config/. It would be nice to support this, but this patch doesn't. "cat-config --user" is rejected, and we may allow it in the future and then extend the search path with directories under ~/.config. What doesn't work (and probably shouldn't because those files cannot be meaningfully concatenated): systemd-analyze cat-config systemd/system (.service, .slice, .socket, ...) systemd-analyze cat-config systemd/user systemd-analyze cat-config systemd/network (.network, .link, and .dnssd) The hardcoding of information about paths in this manner is a bit ugly, but OTOH, it is not too onerous, and at least we have one place where all the schemes are "documented" through code. It'll make us think twice before adding yet another slightly different scheme.
Diffstat (limited to 'src/shared/pretty-print.c')
-rw-r--r--src/shared/pretty-print.c75
1 files changed, 65 insertions, 10 deletions
diff --git a/src/shared/pretty-print.c b/src/shared/pretty-print.c
index de6274a3da..ce71a7ef60 100644
--- a/src/shared/pretty-print.c
+++ b/src/shared/pretty-print.c
@@ -213,33 +213,88 @@ void print_separator(void) {
fputs("\n\n", stdout);
}
+static int guess_type(const char **name, bool *is_usr, bool *is_collection, const char **extension) {
+ /* Try to figure out if name is like tmpfiles.d/ or systemd/system-presets/,
+ * i.e. a collection of directories without a main config file. */
+
+ _cleanup_free_ char *n = NULL;
+ bool usr = false, coll = false;
+ const char *ext = ".conf";
+
+ if (path_equal(*name, "environment.d"))
+ /* Special case: we need to include /etc/environment in the search path, even
+ * though the whole concept is called environment.d. */
+ *name = "environment";
+
+ n = strdup(*name);
+ if (!n)
+ return log_oom();
+
+ delete_trailing_chars(n, "/");
+
+ if (endswith(n, ".d"))
+ coll = true;
+
+ if (path_equal(n, "environment"))
+ usr = true;
+
+ if (path_equal(n, "udev/hwdb.d"))
+ ext = ".hwdb";
+
+ if (path_equal(n, "udev/rules.d"))
+ ext = ".rules";
+
+ if (PATH_IN_SET(n, "systemd/system-preset", "systemd/user-preset")) {
+ coll = true;
+ ext = ".preset";
+ }
+
+ if (path_equal(n, "systemd/user-preset"))
+ usr = true;
+
+ *is_usr = usr;
+ *is_collection = coll;
+ *extension = ext;
+ return 0;
+}
+
int conf_files_cat(const char *root, const char *name) {
_cleanup_strv_free_ char **dirs = NULL, **files = NULL;
_cleanup_free_ char *path = NULL;
- const char *dir;
+ char **dir;
+ bool is_usr, is_collection;
+ const char *extension;
char **t;
int r;
- NULSTR_FOREACH(dir, CONF_PATHS_NULSTR("")) {
- assert(endswith(dir, "/"));
- r = strv_extendf(&dirs, "%s%s.d", dir, name);
+ r = guess_type(&name, &is_usr, &is_collection, &extension);
+ if (r < 0)
+ return r;
+
+ STRV_FOREACH(dir, is_usr ? CONF_PATHS_USR_STRV("") : CONF_PATHS_STRV("")) {
+ assert(endswith(*dir, "/"));
+ r = strv_extendf(&dirs, "%s%s%s", *dir, name,
+ is_collection ? "" : ".d");
if (r < 0)
return log_error_errno(r, "Failed to build directory list: %m");
}
- r = conf_files_list_strv(&files, ".conf", root, 0, (const char* const*) dirs);
+ r = conf_files_list_strv(&files, extension, root, 0, (const char* const*) dirs);
if (r < 0)
return log_error_errno(r, "Failed to query file list: %m");
- path = path_join(root, "/etc", name);
- if (!path)
- return log_oom();
+ if (!is_collection) {
+ path = path_join(root, "/etc", name);
+ if (!path)
+ return log_oom();
+ }
if (DEBUG_LOGGING) {
log_debug("Looking for configuration in:");
- log_debug(" %s", path);
+ if (path)
+ log_debug(" %s", path);
STRV_FOREACH(t, dirs)
- log_debug(" %s/*.conf", *t);
+ log_debug(" %s/*%s", *t, extension);
}
/* show */