mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
Merge pull request #8824 from keszybz/analyze-show-config
systemd-analyze show-config
This commit is contained in:
commit
81321f51cf
@ -50,4 +50,13 @@
|
||||
footer with hints.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry id='cat-config'>
|
||||
<term><option>--cat-config</option></term>
|
||||
|
||||
<listitem>
|
||||
<para>Copy the contents of config files to standard output.
|
||||
Before each file, the filename is printed as a comment.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
@ -78,6 +78,12 @@
|
||||
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||
<arg choice="plain">dump</arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>systemd-analyze</command>
|
||||
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||
<arg choice="plain">cat-config</arg>
|
||||
<arg choice="plain" rep="repeat"><replaceable>NAME</replaceable>|<replaceable>PATH</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>systemd-analyze</command>
|
||||
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||
@ -184,6 +190,34 @@
|
||||
state. Its format is subject to change without notice and should
|
||||
not be parsed by applications.</para>
|
||||
|
||||
<para><command>systemd-analyze cat-config</command> is similar
|
||||
to <command>systemctl cat</command>, but operates on config files.
|
||||
It will copy the contents of a config file and any drop-ins to standard
|
||||
output, using the usual systemd set of directories and rules for
|
||||
precedence. Each argument must be either an absolute path including
|
||||
the prefix (such as <filename>/etc/systemd/logind.conf</filename> or
|
||||
<filename>/usr/lib/systemd/logind.conf</filename>), or a name
|
||||
relative to the prefix (such as <filename>systemd/logind.conf</filename>).
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Showing logind configuration</title>
|
||||
<programlisting>$ systemd-analyze cat-config systemd/logind.conf
|
||||
# /etc/systemd/logind.conf
|
||||
# This file is part of systemd.
|
||||
...
|
||||
[Login]
|
||||
NAutoVTs=8
|
||||
...
|
||||
|
||||
# /usr/lib/systemd/logind.conf.d/20-test.conf
|
||||
... some override from another package
|
||||
|
||||
# /etc/systemd/logind.conf.d/50-override.conf
|
||||
... some adminstrator override
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para><command>systemd-analyze unit-paths</command> outputs a list of all
|
||||
directories from which unit files, <filename>.d</filename> overrides, and
|
||||
<filename>.wants</filename>, <filename>.requires</filename> symlinks may be
|
||||
@ -341,6 +375,13 @@
|
||||
generators enabled will generally result in some warnings.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--root=<replaceable>PATH</replaceable></option></term>
|
||||
|
||||
<listitem><para>With <command>cat-files</command>, show config files underneath
|
||||
the specified root path <replaceable>PATH</replaceable>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="user-system-options.xml" xpointer="host" />
|
||||
<xi:include href="user-system-options.xml" xpointer="machine" />
|
||||
|
||||
|
@ -8,7 +8,8 @@
|
||||
|
||||
Copyright 2012 Lennart Poettering
|
||||
-->
|
||||
<refentry id="systemd-binfmt.service" conditional='ENABLE_BINFMT'>
|
||||
<refentry id="systemd-binfmt.service" conditional='ENABLE_BINFMT'
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
|
||||
<refentryinfo>
|
||||
<title>systemd-binfmt.service</title>
|
||||
@ -52,6 +53,14 @@
|
||||
for information about the configuration of this service.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1><title>Options</title>
|
||||
<variablelist>
|
||||
<xi:include href="standard-options.xml" xpointer="cat-config" />
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>See Also</title>
|
||||
<para>
|
||||
|
@ -79,6 +79,7 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="cat-config" />
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
|
||||
|
@ -124,6 +124,7 @@
|
||||
line instead of a file name.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="cat-config" />
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
</variablelist>
|
||||
|
@ -183,6 +183,7 @@
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="cat-config" />
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
</variablelist>
|
||||
|
@ -19,12 +19,15 @@
|
||||
#include "bus-unit-util.h"
|
||||
#include "bus-util.h"
|
||||
#include "calendarspec.h"
|
||||
#include "def.h"
|
||||
#include "conf-files.h"
|
||||
#include "glob-util.h"
|
||||
#include "hashmap.h"
|
||||
#include "locale-util.h"
|
||||
#include "log.h"
|
||||
#include "pager.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#if HAVE_SECCOMP
|
||||
#include "seccomp-util.h"
|
||||
#endif
|
||||
@ -70,6 +73,7 @@ static const char *arg_host = NULL;
|
||||
static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
|
||||
static bool arg_man = true;
|
||||
static bool arg_generators = false;
|
||||
static const char *arg_root = NULL;
|
||||
|
||||
struct boot_times {
|
||||
usec_t firmware_time;
|
||||
@ -1308,6 +1312,45 @@ static int dump(int argc, char *argv[], void *userdata) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cat_config(int argc, char *argv[], void *userdata) {
|
||||
char **arg;
|
||||
int r;
|
||||
|
||||
(void) pager_open(arg_no_pager, false);
|
||||
|
||||
STRV_FOREACH(arg, argv + 1) {
|
||||
const char *t = NULL;
|
||||
|
||||
if (arg != argv + 1)
|
||||
printf("%s%*s%s\n\n",
|
||||
ansi_underline(),
|
||||
columns(), "",
|
||||
ansi_normal());
|
||||
|
||||
if (path_is_absolute(*arg)) {
|
||||
const char *dir;
|
||||
|
||||
NULSTR_FOREACH(dir, CONF_PATHS_NULSTR("")) {
|
||||
t = path_startswith(*arg, dir);
|
||||
if (t)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!t) {
|
||||
log_error("Path %s does not start with any known prefix.", *arg);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else
|
||||
t = *arg;
|
||||
|
||||
r = conf_files_cat(arg_root, t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_log_level(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
@ -1639,6 +1682,7 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||
" log-level [LEVEL] Get/set logging threshold for manager\n"
|
||||
" log-target [TARGET] Get/set logging target for manager\n"
|
||||
" dump Output state serialization of service manager\n"
|
||||
" cat-config Show configuration file and drop-ins\n"
|
||||
" unit-paths List load directories for units\n"
|
||||
" syscall-filter [NAME...] Print list of syscalls in seccomp filter\n"
|
||||
" verify FILE... Check unit files for correctness\n"
|
||||
@ -1658,6 +1702,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_ORDER,
|
||||
ARG_REQUIRE,
|
||||
ARG_ROOT,
|
||||
ARG_SYSTEM,
|
||||
ARG_USER,
|
||||
ARG_GLOBAL,
|
||||
@ -1674,6 +1719,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "order", no_argument, NULL, ARG_ORDER },
|
||||
{ "require", no_argument, NULL, ARG_REQUIRE },
|
||||
{ "root", required_argument, NULL, ARG_ROOT },
|
||||
{ "system", no_argument, NULL, ARG_SYSTEM },
|
||||
{ "user", no_argument, NULL, ARG_USER },
|
||||
{ "global", no_argument, NULL, ARG_GLOBAL },
|
||||
@ -1702,6 +1748,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
case ARG_VERSION:
|
||||
return version();
|
||||
|
||||
case ARG_ROOT:
|
||||
arg_root = optarg;
|
||||
break;
|
||||
|
||||
case ARG_SYSTEM:
|
||||
arg_scope = UNIT_FILE_SYSTEM;
|
||||
break;
|
||||
@ -1795,6 +1845,11 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (arg_root && !streq_ptr(argv[optind], "cat-config")) {
|
||||
log_error("Option --root is only supported for cat-config right now.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 1; /* work to do */
|
||||
}
|
||||
|
||||
@ -1815,6 +1870,7 @@ int main(int argc, char *argv[]) {
|
||||
{ "set-log-target", 2, 2, 0, set_log_target },
|
||||
{ "get-log-target", VERB_ANY, 1, 0, get_log_target },
|
||||
{ "dump", VERB_ANY, 1, 0, dump },
|
||||
{ "cat-config", 2, VERB_ANY, 0, cat_config },
|
||||
{ "unit-paths", 1, 1, 0, dump_unit_paths },
|
||||
{ "syscall-filter", VERB_ANY, VERB_ANY, 0, dump_syscall_filters },
|
||||
{ "verify", 2, VERB_ANY, 0, do_verify },
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "conf-files.h"
|
||||
#include "def.h"
|
||||
#include "dirent-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "hashmap.h"
|
||||
@ -23,6 +24,7 @@
|
||||
#include "stat-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static int files_add(Hashmap *h, const char *suffix, const char *root, unsigned flags, const char *path) {
|
||||
@ -256,3 +258,71 @@ int conf_files_list_nulstr(char ***strv, const char *suffix, const char *root, u
|
||||
|
||||
return conf_files_list_strv_internal(strv, suffix, root, flags, d);
|
||||
}
|
||||
|
||||
int conf_files_list_with_replacement(
|
||||
const char *root,
|
||||
char **config_dirs,
|
||||
const char *replacement,
|
||||
char ***files,
|
||||
char **replace_file) {
|
||||
|
||||
_cleanup_strv_free_ char **f = NULL;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
int r;
|
||||
|
||||
assert(config_dirs);
|
||||
assert(files);
|
||||
assert(replace_file || !replacement);
|
||||
|
||||
r = conf_files_list_strv(&f, ".conf", root, 0, (const char* const*) config_dirs);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate config files: %m");
|
||||
|
||||
if (replacement) {
|
||||
r = conf_files_insert(&f, root, config_dirs, replacement);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to extend config file list: %m");
|
||||
|
||||
p = path_join(root, replacement, NULL);
|
||||
if (!p)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
*files = TAKE_PTR(f);
|
||||
if (replace_file)
|
||||
*replace_file = TAKE_PTR(p);
|
||||
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 **t;
|
||||
int r;
|
||||
|
||||
NULSTR_FOREACH(dir, CONF_PATHS_NULSTR("")) {
|
||||
assert(endswith(dir, "/"));
|
||||
r = strv_extendf(&dirs, "%s%s.d", dir, name);
|
||||
if (r < 0)
|
||||
return log_error("Failed to build directory list: %m");
|
||||
}
|
||||
|
||||
r = conf_files_list_strv(&files, ".conf", 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 (DEBUG_LOGGING) {
|
||||
log_debug("Looking for configuration in:");
|
||||
log_debug(" %s", path);
|
||||
STRV_FOREACH(t, dirs)
|
||||
log_debug(" %s/*.conf", *t);
|
||||
}
|
||||
|
||||
/* show */
|
||||
return cat_files(path, files, CAT_FLAGS_MAIN_FILE_OPTIONAL);
|
||||
}
|
||||
|
@ -17,3 +17,10 @@ int conf_files_list_strv(char ***ret, const char *suffix, const char *root, unsi
|
||||
int conf_files_list_nulstr(char ***ret, const char *suffix, const char *root, unsigned flags, const char *dirs);
|
||||
int conf_files_insert(char ***strv, const char *root, char **dirs, const char *path);
|
||||
int conf_files_insert_nulstr(char ***strv, const char *root, const char *dirs, const char *path);
|
||||
int conf_files_list_with_replacement(
|
||||
const char *root,
|
||||
char **config_dirs,
|
||||
const char *replacement,
|
||||
char ***files,
|
||||
char **replace_file);
|
||||
int conf_files_cat(const char *root, const char *name);
|
||||
|
@ -54,8 +54,10 @@
|
||||
#define NOTIFY_BUFFER_MAX PIPE_BUF
|
||||
|
||||
#if HAVE_SPLIT_USR
|
||||
# define _CONF_PATHS_SPLIT_USR(n) "/lib/" n "\0"
|
||||
# define _CONF_PATHS_SPLIT_USR_NULSTR(n) "/lib/" n "\0"
|
||||
# define _CONF_PATHS_SPLIT_USR(n) , "/lib/" n
|
||||
#else
|
||||
# define _CONF_PATHS_SPLIT_USR_NULSTR(n)
|
||||
# define _CONF_PATHS_SPLIT_USR(n)
|
||||
#endif
|
||||
|
||||
@ -68,6 +70,14 @@
|
||||
"/run/" n "\0" \
|
||||
"/usr/local/lib/" n "\0" \
|
||||
"/usr/lib/" n "\0" \
|
||||
_CONF_PATHS_SPLIT_USR(n)
|
||||
_CONF_PATHS_SPLIT_USR_NULSTR(n)
|
||||
|
||||
#define CONF_PATHS_STRV(n) \
|
||||
STRV_MAKE( \
|
||||
"/etc/" n, \
|
||||
"/run/" n, \
|
||||
"/usr/local/lib/" n, \
|
||||
"/usr/lib/" n \
|
||||
_CONF_PATHS_SPLIT_USR(n))
|
||||
|
||||
#define LONG_LINE_MAX (1U*1024U*1024U)
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "copy.h"
|
||||
#include "def.h"
|
||||
#include "env-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
@ -1362,3 +1364,57 @@ int terminal_urlify_path(const char *path, const char *text, char **ret) {
|
||||
|
||||
return terminal_urlify(url, text, ret);
|
||||
}
|
||||
|
||||
static int cat_file(const char *filename, bool newline) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int r;
|
||||
|
||||
f = fopen(filename, "re");
|
||||
if (!f)
|
||||
return -errno;
|
||||
|
||||
printf("%s%s# %s%s\n",
|
||||
newline ? "\n" : "",
|
||||
ansi_highlight_blue(),
|
||||
filename,
|
||||
ansi_normal());
|
||||
fflush(stdout);
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *line = NULL;
|
||||
|
||||
r = read_line(f, LONG_LINE_MAX, &line);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to read \"%s\": %m", filename);
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
puts(line);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cat_files(const char *file, char **dropins, CatFlags flags) {
|
||||
char **path;
|
||||
int r;
|
||||
|
||||
if (file) {
|
||||
r = cat_file(file, false);
|
||||
if (r == -ENOENT && (flags & CAT_FLAGS_MAIN_FILE_OPTIONAL))
|
||||
printf("%s# config file %s not found%s\n",
|
||||
ansi_highlight_magenta(),
|
||||
file,
|
||||
ansi_normal());
|
||||
else 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);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to cat %s: %m", *path);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -133,6 +133,7 @@ DEFINE_ANSI_FUNC(highlight_red, HIGHLIGHT_RED);
|
||||
DEFINE_ANSI_FUNC(highlight_green, HIGHLIGHT_GREEN);
|
||||
DEFINE_ANSI_FUNC(highlight_yellow, HIGHLIGHT_YELLOW);
|
||||
DEFINE_ANSI_FUNC(highlight_blue, HIGHLIGHT_BLUE);
|
||||
DEFINE_ANSI_FUNC(highlight_magenta, HIGHLIGHT_MAGENTA);
|
||||
DEFINE_ANSI_FUNC(normal, NORMAL);
|
||||
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(underline, UNDERLINE, NORMAL);
|
||||
@ -159,3 +160,9 @@ int vt_reset_keyboard(int fd);
|
||||
|
||||
int terminal_urlify(const char *url, const char *text, char **ret);
|
||||
int terminal_urlify_path(const char *path, const char *text, char **ret);
|
||||
|
||||
typedef enum CatFlags {
|
||||
CAT_FLAGS_MAIN_FILE_OPTIONAL = 1 << 1,
|
||||
} CatFlags;
|
||||
|
||||
int cat_files(const char *file, char **dropins, CatFlags flags);
|
||||
|
@ -21,9 +21,10 @@
|
||||
#include "log.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static const char conf_file_dirs[] = CONF_PATHS_NULSTR("binfmt.d");
|
||||
static bool arg_cat_config = false;
|
||||
|
||||
static int delete_rule(const char *rule) {
|
||||
_cleanup_free_ char *x = NULL, *fn = NULL;
|
||||
@ -63,7 +64,7 @@ static int apply_file(const char *path, bool ignore_enoent) {
|
||||
|
||||
assert(path);
|
||||
|
||||
r = search_and_fopen_nulstr(path, "re", NULL, conf_file_dirs, &f);
|
||||
r = search_and_fopen(path, "re", NULL, (const char**) CONF_PATHS_STRV("binfmt.d"), &f);
|
||||
if (r < 0) {
|
||||
if (ignore_enoent && r == -ENOENT)
|
||||
return 0;
|
||||
@ -102,6 +103,7 @@ static void help(void) {
|
||||
"Registers binary formats.\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Show package version\n"
|
||||
" --cat-config Show configuration files\n"
|
||||
, program_invocation_short_name);
|
||||
}
|
||||
|
||||
@ -109,11 +111,13 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
enum {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_CAT_CONFIG,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "cat-config", no_argument, NULL, ARG_CAT_CONFIG },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -133,6 +137,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
case ARG_VERSION:
|
||||
return version();
|
||||
|
||||
case ARG_CAT_CONFIG:
|
||||
arg_cat_config = true;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
@ -140,6 +148,11 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
assert_not_reached("Unhandled option");
|
||||
}
|
||||
|
||||
if (arg_cat_config && argc > optind) {
|
||||
log_error("Positional arguments are not allowed with --cat-config");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -170,12 +183,17 @@ int main(int argc, char *argv[]) {
|
||||
_cleanup_strv_free_ char **files = NULL;
|
||||
char **f;
|
||||
|
||||
r = conf_files_list_nulstr(&files, ".conf", NULL, 0, conf_file_dirs);
|
||||
r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char**) CONF_PATHS_STRV("binfmt.d"));
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to enumerate binfmt.d files: %m");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (arg_cat_config) {
|
||||
r = cat_files(NULL, files, 0);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* Flush out all rules */
|
||||
write_string_file("/proc/sys/fs/binfmt_misc/status", "-1", 0);
|
||||
|
||||
|
@ -23,11 +23,11 @@
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "sysctl-util.h"
|
||||
#include "terminal-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static char **arg_prefixes = NULL;
|
||||
|
||||
static const char conf_file_dirs[] = CONF_PATHS_NULSTR("sysctl.d");
|
||||
static bool arg_cat_config = false;
|
||||
|
||||
static int apply_all(OrderedHashmap *sysctl_options) {
|
||||
char *property, *value;
|
||||
@ -83,7 +83,7 @@ static int parse_file(OrderedHashmap *sysctl_options, const char *path, bool ign
|
||||
|
||||
assert(path);
|
||||
|
||||
r = search_and_fopen_nulstr(path, "re", NULL, conf_file_dirs, &f);
|
||||
r = search_and_fopen(path, "re", NULL, (const char**) CONF_PATHS_STRV("sysctl.d"), &f);
|
||||
if (r < 0) {
|
||||
if (ignore_enoent && r == -ENOENT)
|
||||
return 0;
|
||||
@ -168,6 +168,7 @@ static void help(void) {
|
||||
"Applies kernel sysctl settings.\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Show package version\n"
|
||||
" --cat-config Show configuration files\n"
|
||||
" --prefix=PATH Only apply rules with the specified prefix\n"
|
||||
, program_invocation_short_name);
|
||||
}
|
||||
@ -176,13 +177,15 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
enum {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_PREFIX
|
||||
ARG_CAT_CONFIG,
|
||||
ARG_PREFIX,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "prefix", required_argument, NULL, ARG_PREFIX },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "cat-config", no_argument, NULL, ARG_CAT_CONFIG },
|
||||
{ "prefix", required_argument, NULL, ARG_PREFIX },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -202,6 +205,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
case ARG_VERSION:
|
||||
return version();
|
||||
|
||||
case ARG_CAT_CONFIG:
|
||||
arg_cat_config = true;
|
||||
break;
|
||||
|
||||
case ARG_PREFIX: {
|
||||
char *p;
|
||||
|
||||
@ -231,6 +238,11 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
assert_not_reached("Unhandled option");
|
||||
}
|
||||
|
||||
if (arg_cat_config && argc > optind) {
|
||||
log_error("Positional arguments are not allowed with --cat-config");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -268,12 +280,17 @@ int main(int argc, char *argv[]) {
|
||||
_cleanup_strv_free_ char **files = NULL;
|
||||
char **f;
|
||||
|
||||
r = conf_files_list_nulstr(&files, ".conf", NULL, 0, conf_file_dirs);
|
||||
r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char**) CONF_PATHS_STRV("sysctl.d"));
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to enumerate sysctl.d files: %m");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (arg_cat_config) {
|
||||
r = cat_files(NULL, files, 0);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
STRV_FOREACH(f, files) {
|
||||
k = parse_file(sysctl_options, *f, true);
|
||||
if (k < 0 && r == 0)
|
||||
|
@ -5314,23 +5314,6 @@ static int show(int argc, char *argv[], void *userdata) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cat_file(const char *filename, bool newline) {
|
||||
_cleanup_close_ int fd;
|
||||
|
||||
fd = open(filename, O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
printf("%s%s# %s%s\n",
|
||||
newline ? "\n" : "",
|
||||
ansi_highlight_blue(),
|
||||
filename,
|
||||
ansi_normal());
|
||||
fflush(stdout);
|
||||
|
||||
return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, 0);
|
||||
}
|
||||
|
||||
static int cat(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_(lookup_paths_free) LookupPaths lp = {};
|
||||
_cleanup_strv_free_ char **names = NULL;
|
||||
@ -5361,7 +5344,6 @@ static int cat(int argc, char *argv[], void *userdata) {
|
||||
STRV_FOREACH(name, names) {
|
||||
_cleanup_free_ char *fragment_path = NULL;
|
||||
_cleanup_strv_free_ char **dropin_paths = NULL;
|
||||
char **path;
|
||||
|
||||
r = unit_find_paths(bus, *name, &lp, &fragment_path, &dropin_paths);
|
||||
if (r < 0)
|
||||
@ -5388,17 +5370,9 @@ static int cat(int argc, char *argv[], void *userdata) {
|
||||
arg_scope == UNIT_FILE_SYSTEM ? "" : " --user",
|
||||
ansi_normal());
|
||||
|
||||
if (fragment_path) {
|
||||
r = cat_file(fragment_path, false);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
|
||||
}
|
||||
|
||||
STRV_FOREACH(path, dropin_paths) {
|
||||
r = cat_file(*path, path == dropin_paths);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to cat %s: %m", *path);
|
||||
}
|
||||
r = cat_files(fragment_path, dropin_paths, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "specifier.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "uid-range.h"
|
||||
#include "user-util.h"
|
||||
#include "utf8.h"
|
||||
@ -61,11 +62,10 @@ typedef struct Item {
|
||||
} Item;
|
||||
|
||||
static char *arg_root = NULL;
|
||||
static bool arg_cat_config = false;
|
||||
static const char *arg_replace = NULL;
|
||||
static bool arg_inline = false;
|
||||
|
||||
static const char conf_file_dirs[] = CONF_PATHS_NULSTR("sysusers.d");
|
||||
|
||||
static OrderedHashmap *users = NULL, *groups = NULL;
|
||||
static OrderedHashmap *todo_uids = NULL, *todo_gids = NULL;
|
||||
static OrderedHashmap *members = NULL;
|
||||
@ -1688,7 +1688,7 @@ static int read_config_file(const char *fn, bool ignore_enoent) {
|
||||
if (streq(fn, "-"))
|
||||
f = stdin;
|
||||
else {
|
||||
r = search_and_fopen_nulstr(fn, "re", arg_root, conf_file_dirs, &rf);
|
||||
r = search_and_fopen(fn, "re", arg_root, (const char**) CONF_PATHS_STRV("sysusers.d"), &rf);
|
||||
if (r < 0) {
|
||||
if (ignore_enoent && r == -ENOENT)
|
||||
return 0;
|
||||
@ -1744,11 +1744,24 @@ static void free_database(Hashmap *by_name, Hashmap *by_id) {
|
||||
hashmap_free(by_id);
|
||||
}
|
||||
|
||||
static int cat_config(void) {
|
||||
_cleanup_strv_free_ char **files = NULL;
|
||||
_cleanup_free_ char *replace_file = NULL;
|
||||
int r;
|
||||
|
||||
r = conf_files_list_with_replacement(arg_root, CONF_PATHS_STRV("sysusers.d"), arg_replace, &files, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return cat_files(NULL, files, 0);
|
||||
}
|
||||
|
||||
static void help(void) {
|
||||
printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
|
||||
"Creates system user accounts.\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Show package version\n"
|
||||
" --cat-config Show configuration files\n"
|
||||
" --root=PATH Operate on an alternate filesystem root\n"
|
||||
" --replace=PATH Treat arguments as replacement for PATH\n"
|
||||
" --inline Treat arguments as configuration lines\n"
|
||||
@ -1759,17 +1772,19 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
enum {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_CAT_CONFIG,
|
||||
ARG_ROOT,
|
||||
ARG_REPLACE,
|
||||
ARG_INLINE,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "root", required_argument, NULL, ARG_ROOT },
|
||||
{ "replace", required_argument, NULL, ARG_REPLACE },
|
||||
{ "inline", no_argument, NULL, ARG_INLINE },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "cat-config", no_argument, NULL, ARG_CAT_CONFIG },
|
||||
{ "root", required_argument, NULL, ARG_ROOT },
|
||||
{ "replace", required_argument, NULL, ARG_REPLACE },
|
||||
{ "inline", no_argument, NULL, ARG_INLINE },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -1789,6 +1804,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
case ARG_VERSION:
|
||||
return version();
|
||||
|
||||
case ARG_CAT_CONFIG:
|
||||
arg_cat_config = true;
|
||||
break;
|
||||
|
||||
case ARG_ROOT:
|
||||
r = parse_path_argument_and_warn(optarg, true, &arg_root);
|
||||
if (r < 0)
|
||||
@ -1816,6 +1835,11 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
assert_not_reached("Unhandled option");
|
||||
}
|
||||
|
||||
if (arg_replace && arg_cat_config) {
|
||||
log_error("Option --replace= is not supported with --cat-config");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (arg_replace && optind >= argc) {
|
||||
log_error("When --replace= is given, some configuration items must be specified");
|
||||
return -EINVAL;
|
||||
@ -1844,25 +1868,15 @@ static int parse_arguments(char **args) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_config_files(const char* dirs, char **args) {
|
||||
static int read_config_files(char **args) {
|
||||
_cleanup_strv_free_ char **files = NULL;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
char **f;
|
||||
int r;
|
||||
|
||||
r = conf_files_list_nulstr(&files, ".conf", arg_root, 0, dirs);
|
||||
r = conf_files_list_with_replacement(arg_root, CONF_PATHS_STRV("sysusers.d"), arg_replace, &files, &p);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate sysusers.d files: %m");
|
||||
|
||||
if (arg_replace) {
|
||||
r = conf_files_insert_nulstr(&files, arg_root, dirs, arg_replace);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to extend sysusers.d file list: %m");
|
||||
|
||||
p = path_join(arg_root, arg_replace, NULL);
|
||||
if (!p)
|
||||
return log_oom();
|
||||
}
|
||||
return r;
|
||||
|
||||
STRV_FOREACH(f, files)
|
||||
if (p && path_equal(*f, p)) {
|
||||
@ -1882,7 +1896,6 @@ static int read_config_files(const char* dirs, char **args) {
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
_cleanup_close_ int lock = -1;
|
||||
Iterator iterator;
|
||||
int r;
|
||||
@ -1897,6 +1910,11 @@ int main(int argc, char *argv[]) {
|
||||
log_parse_environment();
|
||||
log_open();
|
||||
|
||||
if (arg_cat_config) {
|
||||
r = cat_config();
|
||||
goto finish;
|
||||
}
|
||||
|
||||
umask(0022);
|
||||
|
||||
r = mac_selinux_init();
|
||||
@ -1912,7 +1930,7 @@ int main(int argc, char *argv[]) {
|
||||
* read configuration and execute it.
|
||||
*/
|
||||
if (arg_replace || optind >= argc)
|
||||
r = read_config_files(conf_file_dirs, argv + optind);
|
||||
r = read_config_files(argv + optind);
|
||||
else
|
||||
r = parse_arguments(argv + optind);
|
||||
if (r < 0)
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "fileio.h"
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "util.h"
|
||||
|
||||
@ -76,6 +77,14 @@ static void test_terminal_urlify(void) {
|
||||
printf("Or click on %s to have a look at it!\n", formatted);
|
||||
}
|
||||
|
||||
static void test_cat_files(void) {
|
||||
assert_se(cat_files("/no/such/file", NULL, 0) == -ENOENT);
|
||||
assert_se(cat_files("/no/such/file", NULL, CAT_FLAGS_MAIN_FILE_OPTIONAL) == 0);
|
||||
|
||||
if (access("/etc/fstab", R_OK) >= 0)
|
||||
assert_se(cat_files("/etc/fstab", STRV_MAKE("/etc/fstab", "/etc/fstab"), 0) == 0);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
log_parse_environment();
|
||||
log_open();
|
||||
@ -83,6 +92,7 @@ int main(int argc, char *argv[]) {
|
||||
test_default_term_for_tty();
|
||||
test_read_one_char();
|
||||
test_terminal_urlify();
|
||||
test_cat_files();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "umask-util.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
@ -149,6 +150,7 @@ typedef enum DirectoryType {
|
||||
_DIRECTORY_TYPE_MAX,
|
||||
} DirectoryType;
|
||||
|
||||
static bool arg_cat_config = false;
|
||||
static bool arg_user = false;
|
||||
static bool arg_create = false;
|
||||
static bool arg_clean = false;
|
||||
@ -2441,12 +2443,24 @@ static int parse_line(const char *fname, unsigned line, const char *buffer, bool
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cat_config(char **config_dirs, char **args) {
|
||||
_cleanup_strv_free_ char **files = NULL;
|
||||
int r;
|
||||
|
||||
r = conf_files_list_with_replacement(arg_root, config_dirs, arg_replace, &files, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return cat_files(NULL, files, 0);
|
||||
}
|
||||
|
||||
static void help(void) {
|
||||
printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
|
||||
"Creates, deletes and cleans up volatile and temporary files and directories.\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" --user Execute user configuration\n"
|
||||
" --version Show package version\n"
|
||||
" --cat-config Show configuration files\n"
|
||||
" --create Create marked files/directories\n"
|
||||
" --clean Clean up marked directories\n"
|
||||
" --remove Remove marked files/directories\n"
|
||||
@ -2462,6 +2476,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
enum {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_CAT_CONFIG,
|
||||
ARG_USER,
|
||||
ARG_CREATE,
|
||||
ARG_CLEAN,
|
||||
@ -2477,6 +2492,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "user", no_argument, NULL, ARG_USER },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "cat-config", no_argument, NULL, ARG_CAT_CONFIG },
|
||||
{ "create", no_argument, NULL, ARG_CREATE },
|
||||
{ "clean", no_argument, NULL, ARG_CLEAN },
|
||||
{ "remove", no_argument, NULL, ARG_REMOVE },
|
||||
@ -2504,6 +2520,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
case ARG_VERSION:
|
||||
return version();
|
||||
|
||||
case ARG_CAT_CONFIG:
|
||||
arg_cat_config = true;
|
||||
break;
|
||||
|
||||
case ARG_USER:
|
||||
arg_user = true;
|
||||
break;
|
||||
@ -2557,11 +2577,16 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
assert_not_reached("Unhandled option");
|
||||
}
|
||||
|
||||
if (!arg_clean && !arg_create && !arg_remove) {
|
||||
if (!arg_clean && !arg_create && !arg_remove && !arg_cat_config) {
|
||||
log_error("You need to specify at least one of --clean, --create or --remove.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (arg_replace && arg_cat_config) {
|
||||
log_error("Option --replace= is not supported with --cat-config");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (arg_replace && optind >= argc) {
|
||||
log_error("When --replace= is given, some configuration items must be specified");
|
||||
return -EINVAL;
|
||||
@ -2677,19 +2702,9 @@ static int read_config_files(char **config_dirs, char **args, bool *invalid_conf
|
||||
char **f;
|
||||
int r;
|
||||
|
||||
r = conf_files_list_strv(&files, ".conf", arg_root, 0, (const char* const*) config_dirs);
|
||||
r = conf_files_list_with_replacement(arg_root, config_dirs, arg_replace, &files, &p);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate tmpfiles.d files: %m");
|
||||
|
||||
if (arg_replace) {
|
||||
r = conf_files_insert(&files, arg_root, config_dirs, arg_replace);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to extend tmpfiles.d file list: %m");
|
||||
|
||||
p = path_join(arg_root, arg_replace, NULL);
|
||||
if (!p)
|
||||
return log_oom();
|
||||
}
|
||||
return r;
|
||||
|
||||
STRV_FOREACH(f, files)
|
||||
if (p && path_equal(*f, p)) {
|
||||
@ -2721,20 +2736,6 @@ int main(int argc, char *argv[]) {
|
||||
log_parse_environment();
|
||||
log_open();
|
||||
|
||||
umask(0022);
|
||||
|
||||
mac_selinux_init();
|
||||
|
||||
items = ordered_hashmap_new(&string_hash_ops);
|
||||
globs = ordered_hashmap_new(&string_hash_ops);
|
||||
|
||||
if (!items || !globs) {
|
||||
r = log_oom();
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = 0;
|
||||
|
||||
if (arg_user) {
|
||||
r = user_config_paths(&config_dirs);
|
||||
if (r < 0) {
|
||||
@ -2757,6 +2758,23 @@ int main(int argc, char *argv[]) {
|
||||
log_debug("Looking for configuration files in (higher priority first):\n\t%s", t);
|
||||
}
|
||||
|
||||
if (arg_cat_config) {
|
||||
r = cat_config(config_dirs, argv + optind);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
umask(0022);
|
||||
|
||||
mac_selinux_init();
|
||||
|
||||
items = ordered_hashmap_new(&string_hash_ops);
|
||||
globs = ordered_hashmap_new(&string_hash_ops);
|
||||
|
||||
if (!items || !globs) {
|
||||
r = log_oom();
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* If command line arguments are specified along with --replace, read all
|
||||
* configuration files and insert the positional arguments at the specified
|
||||
* place. Otherwise, if command line arguments are specified, execute just
|
||||
|
Loading…
Reference in New Issue
Block a user