summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2021-02-17 23:40:04 +0100
committerGitHub <noreply@github.com>2021-02-17 23:40:04 +0100
commitdc288ffeabebd72a686dbd530e2aa169472f7fe4 (patch)
tree679d9dcd235e0e19408deb2be99b195dea618212
parenta63b54eda5cb7997b26f574147e0106f9ce458d9 (diff)
parentd60bd2ffb7ac3122fd56048518b1f4a70aa4fe93 (diff)
downloadsystemd-dc288ffeabebd72a686dbd530e2aa169472f7fe4.tar.gz
Merge pull request #18596 from keszybz/systemctl-quiet-legend
systemctl: hide legends with --quiet, allow overriding
-rw-r--r--man/standard-options.xml9
-rw-r--r--man/systemctl.xml2
-rw-r--r--shell-completion/bash/systemctl.in4
-rw-r--r--shell-completion/zsh/_systemctl.in4
-rw-r--r--src/analyze/analyze.c27
-rw-r--r--src/busctl/busctl.c31
-rw-r--r--src/cgtop/cgtop.c8
-rw-r--r--src/core/main.c42
-rw-r--r--src/delta/delta.c19
-rw-r--r--src/journal-remote/journal-remote-main.c36
-rw-r--r--src/journal-remote/journal-upload.c19
-rw-r--r--src/journal/cat.c16
-rw-r--r--src/mount/mount-tool.c11
-rw-r--r--src/partition/repart.c24
-rw-r--r--src/resolve/resolvectl.c69
-rw-r--r--src/shared/parse-argument.c21
-rw-r--r--src/shared/parse-argument.h1
-rw-r--r--src/systemctl/systemctl-list-jobs.c6
-rw-r--r--src/systemctl/systemctl-list-machines.c4
-rw-r--r--src/systemctl/systemctl-list-unit-files.c4
-rw-r--r--src/systemctl/systemctl-list-units.c12
-rw-r--r--src/systemctl/systemctl.c61
-rw-r--r--src/systemctl/systemctl.h2
-rw-r--r--src/userdb/userdbctl.c9
-rw-r--r--test/fuzz/fuzz-systemctl-parse-argv/help.inputbin997 -> 1019 bytes
25 files changed, 202 insertions, 239 deletions
diff --git a/man/standard-options.xml b/man/standard-options.xml
index 4565a43b24..d42f3296ca 100644
--- a/man/standard-options.xml
+++ b/man/standard-options.xml
@@ -35,6 +35,15 @@
<listitem><para>Do not query the user for authentication for privileged operations.</para></listitem>
</varlistentry>
+ <varlistentry id='legend'>
+ <term><option>--legend=</option><replaceable>BOOL</replaceable></term>
+
+ <listitem>
+ <para>Enable or disable printing of the legend, i.e. column headers and the footer with hints. The
+ legend is printed by default, unless disabled with <option>--quiet</option> or similar.</para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id='no-legend'>
<term><option>--no-legend</option></term>
diff --git a/man/systemctl.xml b/man/systemctl.xml
index be414ebb1e..73ca3a6be0 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -2326,7 +2326,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<xi:include href="user-system-options.xml" xpointer="machine" />
<xi:include href="standard-options.xml" xpointer="no-pager" />
- <xi:include href="standard-options.xml" xpointer="no-legend" />
+ <xi:include href="standard-options.xml" xpointer="legend" />
<xi:include href="standard-options.xml" xpointer="help" />
<xi:include href="standard-options.xml" xpointer="version" />
</variablelist>
diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in
index 6c5717d8cc..c25a8d94c2 100644
--- a/shell-completion/bash/systemctl.in
+++ b/shell-completion/bash/systemctl.in
@@ -7,7 +7,7 @@
__systemctl() {
local mode=$1; shift 1
- systemctl $mode --full --no-legend --no-pager --plain "$@" 2>/dev/null
+ systemctl $mode --full --legend=no --no-pager --plain "$@" 2>/dev/null
}
__systemd_properties() {
@@ -123,7 +123,7 @@ _systemctl () {
local -A OPTS=(
[STANDALONE]='--all -a --reverse --after --before --defaults --force -f --full -l --global
- --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall --now
+ --help -h --no-ask-password --no-block --legend=no --no-pager --no-reload --no-wall --now
--quiet -q --system --user --version --runtime --recursive -r --firmware-setup
--show-types --plain --failed --value --fail --dry-run --wait'
[ARG]='--host -H --kill-who --property -p --signal -s --type -t --state --job-mode --root
diff --git a/shell-completion/zsh/_systemctl.in b/shell-completion/zsh/_systemctl.in
index 03586de9fd..5e82ef7e1f 100644
--- a/shell-completion/zsh/_systemctl.in
+++ b/shell-completion/zsh/_systemctl.in
@@ -147,7 +147,7 @@
# @todo _systemd-run has a helper with the same name, so we must redefine
__systemctl()
{
- systemctl $_sys_service_mgr --full --no-legend --no-pager --plain "$@" 2>/dev/null
+ systemctl $_sys_service_mgr --full --legend=no --no-pager --plain "$@" 2>/dev/null
}
@@ -480,7 +480,7 @@ _arguments -s \
'--check-inhibitors[Specify if inhibitors should be checked]:mode:_systemctl_check_inhibitors' \
{-q,--quiet}'[Suppress output]' \
'--no-block[Do not wait until operation finished]' \
- '--no-legend[Do not print a legend, i.e. the column headers and the footer with hints]' \
+ '--legend=no[Do not print a legend, i.e. the column headers and the footer with hints]' \
'--no-pager[Do not pipe output into a pager]' \
'--system[Connect to system manager]' \
'--user[Connect to user service manager]' \
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
index 3bd0cd5b98..ae2d9fc752 100644
--- a/src/analyze/analyze.c
+++ b/src/analyze/analyze.c
@@ -37,6 +37,7 @@
#include "main-func.h"
#include "nulstr-util.h"
#include "pager.h"
+#include "parse-argument.h"
#include "parse-util.h"
#include "path-util.h"
#include "pretty-print.h"
@@ -2340,29 +2341,15 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_MAN:
- if (optarg) {
- r = parse_boolean(optarg);
- if (r < 0)
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "Failed to parse --man= argument.");
-
- arg_man = r;
- } else
- arg_man = true;
-
+ r = parse_boolean_argument("--man", optarg, &arg_man);
+ if (r < 0)
+ return r;
break;
case ARG_GENERATORS:
- if (optarg) {
- r = parse_boolean(optarg);
- if (r < 0)
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "Failed to parse --generators= argument.");
-
- arg_generators = r;
- } else
- arg_generators = true;
-
+ r = parse_boolean_argument("--generators", optarg, &arg_generators);
+ if (r < 0)
+ return r;
break;
case ARG_ITERATIONS:
diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c
index fde9240749..71a6d7e050 100644
--- a/src/busctl/busctl.c
+++ b/src/busctl/busctl.c
@@ -2471,27 +2471,22 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_EXPECT_REPLY:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--expect-reply=", optarg, &arg_expect_reply);
if (r < 0)
- return log_error_errno(r, "Failed to parse --expect-reply= parameter '%s': %m", optarg);
-
- arg_expect_reply = r;
+ return r;
break;
case ARG_AUTO_START:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--auto-start=", optarg, &arg_auto_start);
if (r < 0)
- return log_error_errno(r, "Failed to parse --auto-start= parameter '%s': %m", optarg);
-
- arg_auto_start = r;
+ return r;
break;
case ARG_ALLOW_INTERACTIVE_AUTHORIZATION:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--allow-interactive-authorization=", optarg,
+ &arg_allow_interactive_authorization);
if (r < 0)
- return log_error_errno(r, "Failed to parse --allow-interactive-authorization= parameter '%s': %m", optarg);
-
- arg_allow_interactive_authorization = r;
+ return r;
break;
case ARG_TIMEOUT:
@@ -2502,19 +2497,15 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_AUGMENT_CREDS:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--augment-creds=", optarg, &arg_augment_creds);
if (r < 0)
- return log_error_errno(r, "Failed to parse --augment-creds= parameter '%s': %m", optarg);
-
- arg_augment_creds = r;
+ return r;
break;
case ARG_WATCH_BIND:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--watch-bind=", optarg, &arg_watch_bind);
if (r < 0)
- return log_error_errno(r, "Failed to parse --watch-bind= parameter '%s': %m", optarg);
-
- arg_watch_bind = r;
+ return r;
break;
case 'j':
diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c
index d0fa69ff88..cbae9897a5 100644
--- a/src/cgtop/cgtop.c
+++ b/src/cgtop/cgtop.c
@@ -19,6 +19,7 @@
#include "hashmap.h"
#include "main-func.h"
#include "missing_sched.h"
+#include "parse-argument.h"
#include "parse-util.h"
#include "path-util.h"
#include "pretty-print.h"
@@ -867,12 +868,11 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_RECURSIVE:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--recursive=", optarg, &arg_recursive);
if (r < 0)
- return log_error_errno(r, "Failed to parse --recursive= argument '%s': %m", optarg);
+ return r;
- arg_recursive = r;
- arg_recursive_unset = r == 0;
+ arg_recursive_unset = !r;
break;
case 'M':
diff --git a/src/core/main.c b/src/core/main.c
index 9a81c5b8db..f29449d691 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -937,15 +937,9 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_DUMP_CORE:
- if (!optarg)
- arg_dump_core = true;
- else {
- r = parse_boolean(optarg);
- if (r < 0)
- return log_error_errno(r, "Failed to parse dump core boolean: \"%s\": %m",
- optarg);
- arg_dump_core = r;
- }
+ r = parse_boolean_argument("--dump-core", optarg, &arg_dump_core);
+ if (r < 0)
+ return r;
break;
case ARG_CRASH_CHVT:
@@ -956,27 +950,15 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_CRASH_SHELL:
- if (!optarg)
- arg_crash_shell = true;
- else {
- r = parse_boolean(optarg);
- if (r < 0)
- return log_error_errno(r, "Failed to parse crash shell boolean: \"%s\": %m",
- optarg);
- arg_crash_shell = r;
- }
+ r = parse_boolean_argument("--crash-shell", optarg, &arg_crash_shell);
+ if (r < 0)
+ return r;
break;
case ARG_CRASH_REBOOT:
- if (!optarg)
- arg_crash_reboot = true;
- else {
- r = parse_boolean(optarg);
- if (r < 0)
- return log_error_errno(r, "Failed to parse crash shell boolean: \"%s\": %m",
- optarg);
- arg_crash_reboot = r;
- }
+ r = parse_boolean_argument("--crash-reboot", optarg, &arg_crash_reboot);
+ if (r < 0)
+ return r;
break;
case ARG_CONFIRM_SPAWN:
@@ -989,11 +971,9 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_SERVICE_WATCHDOGS:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--service-watchdogs=", optarg, &arg_service_watchdogs);
if (r < 0)
- return log_error_errno(r, "Failed to parse service watchdogs boolean: \"%s\": %m",
- optarg);
- arg_service_watchdogs = r;
+ return r;
break;
case ARG_SHOW_STATUS:
diff --git a/src/delta/delta.c b/src/delta/delta.c
index 21be1b8f54..bb38db54a4 100644
--- a/src/delta/delta.c
+++ b/src/delta/delta.c
@@ -15,6 +15,7 @@
#include "main-func.h"
#include "nulstr-util.h"
#include "pager.h"
+#include "parse-argument.h"
#include "parse-util.h"
#include "path-util.h"
#include "pretty-print.h"
@@ -586,7 +587,7 @@ static int parse_argv(int argc, char *argv[]) {
{}
};
- int c;
+ int c, r;
assert(argc >= 1);
assert(argv);
@@ -616,18 +617,10 @@ static int parse_argv(int argc, char *argv[]) {
}
case ARG_DIFF:
- if (!optarg)
- arg_diff = 1;
- else {
- int b;
-
- b = parse_boolean(optarg);
- if (b < 0)
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "Failed to parse diff boolean.");
-
- arg_diff = b;
- }
+ r = parse_boolean_argument("--diff", optarg, NULL);
+ if (r < 0)
+ return r;
+ arg_diff = r;
break;
case '?':
diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c
index b9e793c08c..3e84c3dd7b 100644
--- a/src/journal-remote/journal-remote-main.c
+++ b/src/journal-remote/journal-remote-main.c
@@ -14,6 +14,7 @@
#include "journal-remote.h"
#include "main-func.h"
#include "memory-util.h"
+#include "parse-argument.h"
#include "pretty-print.h"
#include "process-util.h"
#include "rlimit-util.h"
@@ -34,8 +35,8 @@ static const char* arg_listen_raw = NULL;
static const char* arg_listen_http = NULL;
static const char* arg_listen_https = NULL;
static char** arg_files = NULL; /* Do not free this. */
-static int arg_compress = true;
-static int arg_seal = false;
+static bool arg_compress = true;
+static bool arg_seal = false;
static int http_socket = -1, https_socket = -1;
static char** arg_gnutls_log = NULL;
@@ -965,34 +966,20 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_COMPRESS:
- if (optarg) {
- r = parse_boolean(optarg);
- if (r < 0)
- return log_error_errno(r, "Failed to parse --compress= parameter.");
-
- arg_compress = !!r;
- } else
- arg_compress = true;
-
+ r = parse_boolean_argument("--compress", optarg, &arg_compress);
+ if (r < 0)
+ return r;
break;
case ARG_SEAL:
- if (optarg) {
- r = parse_boolean(optarg);
- if (r < 0)
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "Failed to parse --seal= parameter.");
-
- arg_seal = !!r;
- } else
- arg_seal = true;
-
+ r = parse_boolean_argument("--seal", optarg, &arg_seal);
+ if (r < 0)
+ return r;
break;
- case ARG_GNUTLS_LOG: {
+ case ARG_GNUTLS_LOG:
#if HAVE_GNUTLS
- const char* p = optarg;
- for (;;) {
+ for (const char* p = optarg;;) {
_cleanup_free_ char *word = NULL;
r = extract_first_word(&p, &word, ",", 0);
@@ -1011,7 +998,6 @@ static int parse_argv(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Option --gnutls-log is not available.");
#endif
- }
case '?':
return -EINVAL;
diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c
index 4d6041e911..e56e336b4f 100644
--- a/src/journal-remote/journal-upload.c
+++ b/src/journal-remote/journal-upload.c
@@ -22,6 +22,7 @@
#include "log.h"
#include "main-func.h"
#include "mkdir.h"
+#include "parse-argument.h"
#include "parse-util.h"
#include "path-util.h"
#include "pretty-print.h"
@@ -356,7 +357,7 @@ static int open_file_for_upload(Uploader *u, const char *filename) {
u->input = fd;
- if (arg_follow) {
+ if (arg_follow != 0) {
r = sd_event_add_io(u->events, &u->input_event,
fd, EPOLLIN, dispatch_fd_input, u);
if (r < 0) {
@@ -747,16 +748,10 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_FOLLOW:
- if (optarg) {
- r = parse_boolean(optarg);
- if (r < 0)
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "Failed to parse --follow= parameter.");
-
- arg_follow = !!r;
- } else
- arg_follow = true;
-
+ r = parse_boolean_argument("--follow", optarg, NULL);
+ if (r < 0)
+ return r;
+ arg_follow = r;
break;
case ARG_SAVE_STATE:
@@ -857,7 +852,7 @@ static int run(int argc, char **argv) {
r = open_journal_for_upload(&u, j,
arg_cursor ?: u.last_cursor,
arg_cursor ? arg_after_cursor : true,
- !!arg_follow);
+ arg_follow != 0);
if (r < 0)
return r;
}
diff --git a/src/journal/cat.c b/src/journal/cat.c
index 6599e64296..4ccc5e0a33 100644
--- a/src/journal/cat.c
+++ b/src/journal/cat.c
@@ -12,6 +12,7 @@
#include "alloc-util.h"
#include "fd-util.h"
#include "main-func.h"
+#include "parse-argument.h"
#include "parse-util.h"
#include "pretty-print.h"
#include "string-util.h"
@@ -67,7 +68,7 @@ static int parse_argv(int argc, char *argv[]) {
{}
};
- int c;
+ int c, r;
assert(argc >= 0);
assert(argv);
@@ -104,16 +105,11 @@ static int parse_argv(int argc, char *argv[]) {
"Failed to parse stderr priority value.");
break;
- case ARG_LEVEL_PREFIX: {
- int k;
-
- k = parse_boolean(optarg);
- if (k < 0)
- return log_error_errno(k, "Failed to parse level prefix value.");
-
- arg_level_prefix = k;
+ case ARG_LEVEL_PREFIX:
+ r = parse_boolean_argument("--level-prefix=", optarg, &arg_level_prefix);
+ if (r < 0)
+ return r;
break;
- }
case '?':
return -EINVAL;
diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c
index 8b6fc520c5..f30061dac7 100644
--- a/src/mount/mount-tool.c
+++ b/src/mount/mount-tool.c
@@ -23,6 +23,7 @@
#include "mount-util.h"
#include "mountpoint-util.h"
#include "pager.h"
+#include "parse-argument.h"
#include "parse-util.h"
#include "path-util.h"
#include "pretty-print.h"
@@ -265,11 +266,9 @@ static int parse_argv(int argc, char *argv[]) {
}
case ARG_FSCK:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--fsck=", optarg, &arg_fsck);
if (r < 0)
- return log_error_errno(r, "Failed to parse --fsck= argument: %s", optarg);
-
- arg_fsck = r;
+ return r;
break;
case ARG_DESCRIPTION:
@@ -289,9 +288,9 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_AUTOMOUNT:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--automount=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "--automount= expects a valid boolean parameter: %s", optarg);
+ return r;
arg_action = r ? ACTION_AUTOMOUNT : ACTION_MOUNT;
break;
diff --git a/src/partition/repart.c b/src/partition/repart.c
index 01e60e2133..45e82cd0eb 100644
--- a/src/partition/repart.c
+++ b/src/partition/repart.c
@@ -44,8 +44,8 @@
#include "mkdir.h"
#include "mkfs-util.h"
#include "mount-util.h"
-#include "parse-util.h"
#include "parse-argument.h"
+#include "parse-util.h"
#include "path-util.h"
#include "pretty-print.h"
#include "proc-cmdline.h"
@@ -3575,11 +3575,9 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_DRY_RUN:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--dry-run=", optarg, &arg_dry_run);
if (r < 0)
- return log_error_errno(r, "Failed to parse --dry-run= parameter: %s", optarg);
-
- dry_run = r;
+ return r;
break;
case ARG_EMPTY:
@@ -3604,18 +3602,15 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_DISCARD:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--discard=", optarg, &arg_discard);
if (r < 0)
- return log_error_errno(r, "Failed to parse --discard= parameter: %s", optarg);
-
- arg_discard = r;
+ return r;
break;
case ARG_FACTORY_RESET:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--factory-reset=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to parse --factory-reset= parameter: %s", optarg);
-
+ return r;
arg_factory_reset = r;
break;
@@ -3646,10 +3641,9 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_PRETTY:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--pretty=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to parse --pretty= parameter: %s", optarg);
-
+ return r;
arg_pretty = r;
break;
diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c
index 2302ca48ba..b645147fd8 100644
--- a/src/resolve/resolvectl.c
+++ b/src/resolve/resolvectl.c
@@ -23,6 +23,7 @@
#include "missing_network.h"
#include "netlink-util.h"
#include "pager.h"
+#include "parse-argument.h"
#include "parse-util.h"
#include "pretty-print.h"
#include "resolvconf-compat.h"
@@ -2811,11 +2812,9 @@ static int compat_parse_argv(int argc, char *argv[]) {
break;
case ARG_LEGEND:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--legend=", optarg, &arg_legend);
if (r < 0)
- return log_error_errno(r, "Failed to parse --legend= argument");
-
- arg_legend = r;
+ return r;
break;
case 'p':
@@ -2877,30 +2876,30 @@ static int compat_parse_argv(int argc, char *argv[]) {
break;
case ARG_CNAME:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--cname=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to parse --cname= argument.");
+ return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_CNAME, r == 0);
break;
case ARG_SERVICE_ADDRESS:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--service-address=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to parse --service-address= argument.");
+ return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_ADDRESS, r == 0);
break;
case ARG_SERVICE_TXT:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--service-txt=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to parse --service-txt= argument.");
+ return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_TXT, r == 0);
break;
case ARG_SEARCH:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--search=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to parse --search argument.");
+ return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_SEARCH, r == 0);
break;
@@ -3107,11 +3106,9 @@ static int native_parse_argv(int argc, char *argv[]) {
break;
case ARG_LEGEND:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--legend=", optarg, &arg_legend);
if (r < 0)
- return log_error_errno(r, "Failed to parse --legend= argument");
-
- arg_legend = r;
+ return r;
break;
case 'p':
@@ -3157,72 +3154,72 @@ static int native_parse_argv(int argc, char *argv[]) {
break;
case ARG_CNAME:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--cname=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to parse --cname= argument.");
+ return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_CNAME, r == 0);
break;
case ARG_VALIDATE:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--validate=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to parse --validate= argument.");
+ return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_VALIDATE, r == 0);
break;
case ARG_SYNTHESIZE:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--synthesize=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to parse --synthesize= argument.");
+ return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_SYNTHESIZE, r == 0);
break;
case ARG_CACHE:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--cache=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to parse --cache= argument.");
+ return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_CACHE, r == 0);
break;
case ARG_ZONE:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--zone=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to parse --zone= argument.");
+ return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_ZONE, r == 0);
break;
case ARG_TRUST_ANCHOR:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--trust-anchor=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to parse --trust-anchor= argument.");
+ return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_TRUST_ANCHOR, r == 0);
break;
case ARG_NETWORK:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--network=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to parse --network= argument.");
+ return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_NETWORK, r == 0);
break;
case ARG_SERVICE_ADDRESS:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--service-address=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to parse --service-address= argument.");
+ return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_ADDRESS, r == 0);
break;
case ARG_SERVICE_TXT:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--service-txt=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to parse --service-txt= argument.");
+ return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_TXT, r == 0);
break;
case ARG_SEARCH:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--search=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to parse --search argument.");
+ return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_SEARCH, r == 0);
break;
diff --git a/src/shared/parse-argument.c b/src/shared/parse-argument.c
index cd1d0dde21..db182e4bcb 100644
--- a/src/shared/parse-argument.c
+++ b/src/shared/parse-argument.c
@@ -10,6 +10,27 @@
/* All functions in this file emit warnigs. */
+int parse_boolean_argument(const char *optname, const char *s, bool *ret) {
+ int r;
+
+ /* Returns the result through *ret and the return value. */
+
+ if (s) {
+ r = parse_boolean(s);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse boolean argument to %s: %s.", optname, s);
+
+ if (ret)
+ *ret = r;
+ return r;
+ } else {
+ /* s may be NULL. This is controlled by getopt_long() parameters. */
+ if (ret)
+ *ret = true;
+ return true;
+ }
+}
+
int parse_json_argument(const char *s, JsonFormatFlags *ret) {
assert(s);
assert(ret);
diff --git a/src/shared/parse-argument.h b/src/shared/parse-argument.h
index 28b58cc2e2..adad65e902 100644
--- a/src/shared/parse-argument.h
+++ b/src/shared/parse-argument.h
@@ -3,6 +3,7 @@
#include "json.h"
+int parse_boolean_argument(const char *optname, const char *s, bool *ret);
int parse_json_argument(const char *s, JsonFormatFlags *ret);
int parse_path_argument(const char *path, bool suppress_root, char **arg);
int parse_signal_argument(const char *s, int *ret);
diff --git a/src/systemctl/systemctl-list-jobs.c b/src/systemctl/systemctl-list-jobs.c
index 27eecb548c..7ac0496382 100644
--- a/src/systemctl/systemctl-list-jobs.c
+++ b/src/systemctl/systemctl-list-jobs.c
@@ -64,7 +64,7 @@ static int output_jobs_list(sd_bus *bus, const struct job_info* jobs, unsigned n
assert(n == 0 || jobs);
if (n == 0) {
- if (!arg_no_legend) {
+ if (arg_legend != 0) {
on = ansi_highlight_green();
off = ansi_normal();
@@ -79,7 +79,7 @@ static int output_jobs_list(sd_bus *bus, const struct job_info* jobs, unsigned n
if (!table)
return log_oom();
- table_set_header(table, !arg_no_legend);
+ table_set_header(table, arg_legend != 0);
if (arg_full)
table_set_width(table, 0);
@@ -111,7 +111,7 @@ static int output_jobs_list(sd_bus *bus, const struct job_info* jobs, unsigned n
if (r < 0)
return log_error_errno(r, "Failed to print the table: %m");
- if (!arg_no_legend) {
+ if (arg_legend != 0) {
on = ansi_highlight();
off = ansi_normal();
diff --git a/src/systemctl/systemctl-list-machines.c b/src/systemctl/systemctl-list-machines.c
index 63adcec5f3..2e891b103c 100644
--- a/src/systemctl/systemctl-list-machines.c
+++ b/src/systemctl/systemctl-list-machines.c
@@ -157,7 +157,7 @@ static int output_machines_list(struct machine_info *machine_infos, unsigned n)
if (!table)
return log_oom();
- table_set_header(table, !arg_no_legend);
+ table_set_header(table, arg_legend != 0);
if (arg_plain) {
/* Hide the 'glyph' column when --plain is requested */
r = table_hide_column_from_display(table, 0);
@@ -210,7 +210,7 @@ static int output_machines_list(struct machine_info *machine_infos, unsigned n)
if (r < 0)
return r;
- if (!arg_no_legend) {
+ if (arg_legend != 0) {
printf("\n");
if (state_missing && geteuid() != 0)
printf("Notice: some information only available to privileged users was not shown.\n");
diff --git a/src/systemctl/systemctl-list-unit-files.c b/src/systemctl/systemctl-list-unit-files.c
index 6da2914eff..1bf2fc18f3 100644
--- a/src/systemctl/systemctl-list-unit-files.c
+++ b/src/systemctl/systemctl-list-unit-files.c
@@ -58,7 +58,7 @@ static int output_unit_file_list(const UnitFileList *units, unsigned c) {
if (!table)
return log_oom();
- table_set_header(table, !arg_no_legend);
+ table_set_header(table, arg_legend != 0);
if (arg_full)
table_set_width(table, 0);
@@ -127,7 +127,7 @@ static int output_unit_file_list(const UnitFileList *units, unsigned c) {
if (r < 0)
return r;
- if (!arg_no_legend)
+ if (arg_legend != 0)
printf("\n%u unit files listed.\n", c);
return 0;
diff --git a/src/systemctl/systemctl-list-units.c b/src/systemctl/systemctl-list-units.c
index a413ef6d5b..3f5b42f037 100644
--- a/src/systemctl/systemctl-list-units.c
+++ b/src/systemctl/systemctl-list-units.c
@@ -97,7 +97,7 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
if (!table)
return log_oom();
- table_set_header(table, !arg_no_legend);
+ table_set_header(table, arg_legend != 0);
if (arg_plain) {
/* Hide the 'glyph' column when --plain is requested */
r = table_hide_column_from_display(table, 0);
@@ -177,7 +177,7 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
if (r < 0)
return r;
- if (!arg_no_legend) {
+ if (arg_legend != 0) {
const char *on, *off;
size_t records = table_get_rows(table) - 1;
@@ -365,7 +365,7 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
return log_error_errno(r, "Failed to set columns to display: %m");
}
- table_set_header(table, !arg_no_legend);
+ table_set_header(table, arg_legend != 0);
if (arg_full)
table_set_width(table, 0);
@@ -416,7 +416,7 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
if (r < 0)
return r;
- if (!arg_no_legend) {
+ if (arg_legend != 0) {
printf("\n%s%u sockets listed.%s\n", on, cs, off);
if (!arg_all)
printf("Pass --all to see loaded but inactive sockets, too.\n");
@@ -610,7 +610,7 @@ static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
if (!table)
return log_oom();
- table_set_header(table, !arg_no_legend);
+ table_set_header(table, arg_legend != 0);
if (arg_full)
table_set_width(table, 0);
@@ -655,7 +655,7 @@ static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
if (r < 0)
return r;
- if (!arg_no_legend) {
+ if (arg_legend != 0) {
printf("\n%s%u timers listed.%s\n", on, n, off);
if (!arg_all)
printf("Pass --all to see loaded but inactive timers, too.\n");
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index b27da5dad9..f92598a7bb 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -68,7 +68,7 @@ const char *arg_job_mode = "replace";
UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
bool arg_wait = false;
bool arg_no_block = false;
-bool arg_no_legend = false;
+int arg_legend = -1; /* -1: true, unless --quiet is passed, 1: true */
PagerFlags arg_pager_flags = 0;
bool arg_no_wtmp = false;
bool arg_no_sync = false;
@@ -268,7 +268,7 @@ static int systemctl_help(void) {
" --no-block Do not wait until operation finished\n"
" --no-wall Don't send wall message before halt/power-off/reboot\n"
" --no-reload Don't reload daemon after en-/dis-abling unit files\n"
- " --no-legend Do not print a legend (column headers and hints)\n"
+ " --legend=BOOL Enable/disable the legend (column headers and hints)\n"
" --no-pager Do not pipe output into a pager\n"
" --no-ask-password Do not ask for system passwords\n"
" --global Enable/disable/mask unit files globally\n"
@@ -310,88 +310,89 @@ static int systemctl_help(void) {
}
static void help_types(void) {
- if (!arg_no_legend)
+ if (arg_legend != 0)
puts("Available unit types:");
DUMP_STRING_TABLE(unit_type, UnitType, _UNIT_TYPE_MAX);
}
static void help_states(void) {
- if (!arg_no_legend)
+ if (arg_legend != 0)
puts("Available unit load states:");
DUMP_STRING_TABLE(unit_load_state, UnitLoadState, _UNIT_LOAD_STATE_MAX);
- if (!arg_no_legend)
+ if (arg_legend != 0)
puts("\nAvailable unit active states:");
DUMP_STRING_TABLE(unit_active_state, UnitActiveState, _UNIT_ACTIVE_STATE_MAX);
- if (!arg_no_legend)
+ if (arg_legend != 0)
puts("\nAvailable unit file states:");
DUMP_STRING_TABLE(unit_file_state, UnitFileState, _UNIT_FILE_STATE_MAX);
- if (!arg_no_legend)
+ if (arg_legend != 0)
puts("\nAvailable automount unit substates:");
DUMP_STRING_TABLE(automount_state, AutomountState, _AUTOMOUNT_STATE_MAX);
- if (!arg_no_legend)
+ if (arg_legend != 0)
puts("\nAvailable device unit substates:");
DUMP_STRING_TABLE(device_state, DeviceState, _DEVICE_STATE_MAX);
- if (!arg_no_legend)
+ if (arg_legend != 0)
puts("\nAvailable mount unit substates:");
DUMP_STRING_TABLE(mount_state, MountState, _MOUNT_STATE_MAX);
- if (!arg_no_legend)
+ if (arg_legend != 0)
puts("\nAvailable path unit substates:");
DUMP_STRING_TABLE(path_state, PathState, _PATH_STATE_MAX);
- if (!arg_no_legend)
+ if (arg_legend != 0)
puts("\nAvailable scope unit substates:");
DUMP_STRING_TABLE(scope_state, ScopeState, _SCOPE_STATE_MAX);
- if (!arg_no_legend)
+ if (arg_legend != 0)
puts("\nAvailable service unit substates:");
DUMP_STRING_TABLE(service_state, ServiceState, _SERVICE_STATE_MAX);
- if (!arg_no_legend)
+ if (arg_legend != 0)
puts("\nAvailable slice unit substates:");
DUMP_STRING_TABLE(slice_state, SliceState, _SLICE_STATE_MAX);
- if (!arg_no_legend)
+ if (arg_legend != 0)
puts("\nAvailable socket unit substates:");
DUMP_STRING_TABLE(socket_state, SocketState, _SOCKET_STATE_MAX);
- if (!arg_no_legend)
+ if (arg_legend != 0)
puts("\nAvailable swap unit substates:");
DUMP_STRING_TABLE(swap_state, SwapState, _SWAP_STATE_MAX);
- if (!arg_no_legend)
+ if (arg_legend != 0)
puts("\nAvailable target unit substates:");
DUMP_STRING_TABLE(target_state, TargetState, _TARGET_STATE_MAX);
- if (!arg_no_legend)
+ if (arg_legend != 0)
puts("\nAvailable timer unit substates:");
DUMP_STRING_TABLE(timer_state, TimerState, _TIMER_STATE_MAX);
}
static int systemctl_parse_argv(int argc, char *argv[]) {
enum {
- ARG_FAIL = 0x100,
+ ARG_FAIL = 0x100, /* compatibility only */
ARG_REVERSE,
ARG_AFTER,
ARG_BEFORE,
ARG_CHECK_INHIBITORS,
ARG_DRY_RUN,
ARG_SHOW_TYPES,
- ARG_IRREVERSIBLE,
- ARG_IGNORE_DEPENDENCIES,
+ ARG_IRREVERSIBLE, /* compatibility only */
+ ARG_IGNORE_DEPENDENCIES, /* compatibility only */
ARG_VALUE,
ARG_VERSION,
ARG_USER,
ARG_SYSTEM,
ARG_GLOBAL,
ARG_NO_BLOCK,
- ARG_NO_LEGEND,
+ ARG_LEGEND,
+ ARG_NO_LEGEND, /* compatibility only */
ARG_NO_PAGER,
ARG_NO_WALL,
ARG_ROOT,
@@ -443,7 +444,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
{ "global", no_argument, NULL, ARG_GLOBAL },
{ "wait", no_argument, NULL, ARG_WAIT },
{ "no-block", no_argument, NULL, ARG_NO_BLOCK },
- { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
+ { "legend", required_argument, NULL, ARG_LEGEND },
+ { "no-legend", no_argument, NULL, ARG_NO_LEGEND }, /* compatibility only */
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
{ "no-wall", no_argument, NULL, ARG_NO_WALL },
{ "dry-run", no_argument, NULL, ARG_DRY_RUN },
@@ -630,7 +632,14 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
break;
case ARG_NO_LEGEND:
- arg_no_legend = true;
+ arg_legend = false;
+ break;
+
+ case ARG_LEGEND:
+ r = parse_boolean_argument("--legend", optarg, NULL);
+ if (r < 0)
+ return r;
+ arg_legend = r;
break;
case ARG_NO_PAGER:
@@ -663,6 +672,10 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
case 'q':
arg_quiet = true;
+
+ if (arg_legend < 0)
+ arg_legend = false;
+
break;
case 'f':
@@ -721,7 +734,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
optarg);
if (OUTPUT_MODE_IS_JSON(arg_output)) {
- arg_no_legend = true;
+ arg_legend = false;
arg_plain = true;
}
break;
diff --git a/src/systemctl/systemctl.h b/src/systemctl/systemctl.h
index 3c5a4023a9..3a3ff9ac10 100644
--- a/src/systemctl/systemctl.h
+++ b/src/systemctl/systemctl.h
@@ -52,7 +52,7 @@ extern const char *arg_job_mode;
extern UnitFileScope arg_scope;
extern bool arg_wait;
extern bool arg_no_block;
-extern bool arg_no_legend;
+extern int arg_legend;
extern PagerFlags arg_pager_flags;
extern bool arg_no_wtmp;
extern bool arg_no_sync;
diff --git a/src/userdb/userdbctl.c b/src/userdb/userdbctl.c
index f4204759db..102721dd50 100644
--- a/src/userdb/userdbctl.c
+++ b/src/userdb/userdbctl.c
@@ -10,6 +10,7 @@
#include "format-util.h"
#include "main-func.h"
#include "pager.h"
+#include "parse-argument.h"
#include "parse-util.h"
#include "pretty-print.h"
#include "socket-util.h"
@@ -720,17 +721,17 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_WITH_NSS:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--with-nss=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to parse --with-nss= parameter: %s", optarg);
+ return r;
SET_FLAG(arg_userdb_flags, USERDB_AVOID_NSS, !r);
break;
case ARG_SYNTHESIZE:
- r = parse_boolean(optarg);
+ r = parse_boolean_argument("--synthesize=", optarg, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to parse --synthesize= parameter: %s", optarg);
+ return r;
SET_FLAG(arg_userdb_flags, USERDB_DONT_SYNTHESIZE, !r);
break;
diff --git a/test/fuzz/fuzz-systemctl-parse-argv/help.input b/test/fuzz/fuzz-systemctl-parse-argv/help.input
index be0631301b..db9d80a09f 100644
--- a/test/fuzz/fuzz-systemctl-parse-argv/help.input
+++ b/test/fuzz/fuzz-systemctl-parse-argv/help.input
Binary files differ