summaryrefslogtreecommitdiffstats
path: root/src/shared/pretty-print.c
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2023-10-12 16:33:01 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2023-10-24 15:59:34 +0200
commit063c8382068b4cb8661aa5a77b6c7d117d0bd117 (patch)
tree6523e23b3f97d4da1b81da14c8f2086132d25644 /src/shared/pretty-print.c
parentshared/pretty-print: drop unused flag (diff)
downloadsystemd-063c8382068b4cb8661aa5a77b6c7d117d0bd117.tar.xz
systemd-063c8382068b4cb8661aa5a77b6c7d117d0bd117.zip
analyze/cat-config: add switch to print only "interesting" parts of config files
When looking at configuration, often a user wants to suppress the comments and just look at the parts that actually configure something, roughly equivalent to systemd-analyze cat-config … | rg -v '^(#|;|$) This switch implements this natively, skipping lines that start with a comment character or only contain whitespace. For formats that have section headers, section headers are skipped, if only followed by stuff that would be skipped. (The last section header is printed when we're about to print some actual output.) Note that the caller doesn't know if the format has headers or not. We do format type detection in pretty-print.c. So the caller only specifies tldr=true|false, and conf_files_cat() figures out if the format has headers and whether those should be handled specially. The comments that show the file name are always printed, even if all of the file is suppressed. This is a partial answer to the discussions in https://github.com/systemd/systemd/pull/28919, https://github.com/systemd/systemd/pull/29248. If the default config is shown in config files, the user can conveniently use '--tldr' to show the relevant parts.
Diffstat (limited to 'src/shared/pretty-print.c')
-rw-r--r--src/shared/pretty-print.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/src/shared/pretty-print.c b/src/shared/pretty-print.c
index 55a2570ddf..ae5b9d8604 100644
--- a/src/shared/pretty-print.c
+++ b/src/shared/pretty-print.c
@@ -131,9 +131,9 @@ int terminal_urlify_man(const char *page, const char *section, char **ret) {
return terminal_urlify(url, text, ret);
}
-static int cat_file(const char *filename, bool newline) {
+static int cat_file(const char *filename, bool newline, CatFlags flags) {
_cleanup_fclose_ FILE *f = NULL;
- _cleanup_free_ char *urlified = NULL;
+ _cleanup_free_ char *urlified = NULL, *section = NULL;
int r;
f = fopen(filename, "re");
@@ -160,6 +160,25 @@ static int cat_file(const char *filename, bool newline) {
if (r == 0)
break;
+ if (flags & CAT_TLDR) {
+ const char *t = skip_leading_chars(line, WHITESPACE);
+
+ if ((flags & CAT_FORMAT_HAS_SECTIONS) && *t == '[') {
+ /* The start of a section, let's not print it yet. */
+ free_and_replace(section, line);
+ continue;
+ }
+
+ if (IN_SET(*t, '#', ';', '\0'))
+ continue;
+
+ /* Before we print the actual line, print the last section header */
+ if (section) {
+ puts(section);
+ section = mfree(section);
+ }
+ }
+
puts(line);
}
@@ -170,13 +189,13 @@ int cat_files(const char *file, char **dropins, CatFlags flags) {
int r;
if (file) {
- r = cat_file(file, false);
+ r = cat_file(file, /* newline= */ false, flags);
if (r < 0)
return log_warning_errno(r, "Failed to cat %s: %m", file);
}
STRV_FOREACH(path, dropins) {
- r = cat_file(*path, file || path != dropins);
+ r = cat_file(*path, /* newline= */ file || path != dropins, flags);
if (r < 0)
return log_warning_errno(r, "Failed to cat %s: %m", *path);
}
@@ -208,7 +227,10 @@ void print_separator(void) {
static int guess_type(const char **name, char ***prefixes, 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. */
+ * i.e. a collection of directories without a main config file.
+ * Incidentally, all those formats don't use sections. So we return a single
+ * is_collection boolean, which also means that the format doesn't use sections.
+ */
_cleanup_free_ char *n = NULL;
bool usr = false, run = false, coll = false;
@@ -274,7 +296,7 @@ static int guess_type(const char **name, char ***prefixes, bool *is_collection,
return 0;
}
-int conf_files_cat(const char *root, const char *name) {
+int conf_files_cat(const char *root, const char *name, CatFlags flags) {
_cleanup_strv_free_ char **dirs = NULL, **files = NULL;
_cleanup_free_ char *path = NULL;
char **prefixes = NULL; /* explicit initialization to appease gcc */
@@ -330,5 +352,8 @@ int conf_files_cat(const char *root, const char *name) {
return log_error_errno(r, "Failed to query file list: %m");
/* Show */
- return cat_files(path, files, 0);
+ if (is_collection)
+ flags |= CAT_FORMAT_HAS_SECTIONS;
+
+ return cat_files(path, files, flags);
}