diff --git a/man/systemd-makefs@.service.xml b/man/systemd-makefs@.service.xml
index a084f9d08c..ca5a99d806 100644
--- a/man/systemd-makefs@.service.xml
+++ b/man/systemd-makefs@.service.xml
@@ -30,8 +30,8 @@
systemd-mkswap@device.service
systemd-growfs@mountpoint.service
systemd-growfs-root.service
- /usr/lib/systemd/systemd-makefs
- /usr/lib/systemd/systemd-growfs
+ /usr/lib/systemd/systemd-makefs FSTYPE DEVICE
+ /usr/lib/systemd/systemd-growfs MOUNTPOINT
diff --git a/man/systemd-pcrphase.service.xml b/man/systemd-pcrphase.service.xml
index c604a8465a..c75ab4d0ac 100644
--- a/man/systemd-pcrphase.service.xml
+++ b/man/systemd-pcrphase.service.xml
@@ -46,7 +46,11 @@
systemd-pcrnvdone.service
systemd-pcrphase-factory-reset.service
systemd-pcrphase-storage-target-mode.service
- /usr/lib/systemd/systemd-pcrextend STRING
+ /usr/lib/systemd/systemd-pcrextend WORD
+ /usr/lib/systemd/systemd-pcrextend
+ /usr/lib/systemd/systemd-pcrextend
+ /usr/lib/systemd/systemd-pcrextend
+ /usr/lib/systemd/systemd-pcrextend
diff --git a/man/systemd-storagetm.service.xml b/man/systemd-storagetm.service.xml
index 6172190157..b49a27feb0 100644
--- a/man/systemd-storagetm.service.xml
+++ b/man/systemd-storagetm.service.xml
@@ -28,7 +28,17 @@
/usr/lib/systemd/systemd-storagetm
OPTIONS
- DEVICE
+ DEVICE
+
+
+ /usr/lib/systemd/systemd-storagetm
+ OPTIONS
+ --all
+
+
+ /usr/lib/systemd/systemd-storagetm
+ OPTIONS
+ --list-devices
@@ -53,8 +63,8 @@
ip=dhcp to assign routable addresses too. For further details see
systemd-network-generator.service8.
- Unless the switch is used expects one or more block devices or regular files to expose
- via NVMe-TCP as argument.
+ Unless the or switches are used, one or more
+ block devices or regular files to expose via NVMe-TCP must be specified as arguments.
diff --git a/man/systemd-validatefs@.service.xml b/man/systemd-validatefs@.service.xml
index 85554a30de..030078e1e2 100644
--- a/man/systemd-validatefs@.service.xml
+++ b/man/systemd-validatefs@.service.xml
@@ -23,7 +23,7 @@
systemd-validatefs@.service
- /usr/lib/systemd/systemd-validatefs DEVICE
+ /usr/lib/systemd/systemd-validatefs MOUNTPOINT
diff --git a/src/bless-boot/boot-check-no-failures.c b/src/bless-boot/boot-check-no-failures.c
index 9fa42a7ed6..a54bd62096 100644
--- a/src/bless-boot/boot-check-no-failures.c
+++ b/src/bless-boot/boot-check-no-failures.c
@@ -1,44 +1,19 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#include
-
#include "sd-bus.h"
+#include "sd-json.h"
-#include "alloc-util.h"
#include "build.h"
#include "bus-error.h"
-#include "format-table.h"
#include "log.h"
#include "main-func.h"
-#include "options.h"
-#include "pretty-print.h"
+#include "verbs.h"
-static int help(void) {
- _cleanup_free_ char *link = NULL;
- _cleanup_(table_unrefp) Table *options = NULL;
- int r;
-
- r = terminal_urlify_man("systemd-boot-check-no-failures.service", "8", &link);
- if (r < 0)
- return log_oom();
-
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- printf("%s [OPTIONS...]\n"
- "\n%sVerify system operational state.%s\n\n",
- program_invocation_short_name,
- ansi_highlight(),
- ansi_normal());
-
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- printf("\nSee the %s for details.\n", link);
- return 0;
-}
+COMMAND(
+ "systemd-boot-check-no-failures\0",
+ "Verify system operational state.",
+ .man_pages = "systemd-boot-check-no-failures.service.8\0",
+);
static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
@@ -50,10 +25,13 @@ static int parse_argv(int argc, char *argv[]) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-boot-check-no-failures");
OPTION_COMMON_VERSION:
return version();
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
return 1;
diff --git a/src/clonesetup/clonesetup.c b/src/clonesetup/clonesetup.c
index debd10590a..569aa4f245 100644
--- a/src/clonesetup/clonesetup.c
+++ b/src/clonesetup/clonesetup.c
@@ -1,16 +1,15 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include
+#include "sd-json.h"
+
#include "alloc-util.h"
#include "build.h"
#include "clonesetup-ioctl.h"
#include "clonesetup-util.h"
#include "extract-word.h"
-#include "format-table.h"
-#include "help-util.h"
#include "log.h"
#include "main-func.h"
-#include "options.h"
#include "parse-util.h"
#include "string-util.h"
#include "strv.h" /* strv_skip */
@@ -22,6 +21,12 @@
#define CLONE_REGION_SIZE_MIN_BYTES (UINT64_C(1) << 12) /* 4 KiB */
#define CLONE_REGION_SIZE_MAX_BYTES (UINT64_C(1) << 30) /* 1 GiB */
+COMMAND(
+ "systemd-clonesetup\0",
+ "Add or remove a dm-clone device.",
+ .man_pages = "systemd-clonesetup.8\0",
+);
+
static int parse_clone_options(const char *options, uint64_t *ret_region_size_bytes) {
uint64_t region_size_bytes = CLONE_REGION_SIZE_DEFAULT_BYTES;
@@ -136,26 +141,6 @@ static int verb_remove(int argc, char *argv[], uintptr_t data, void *userdata) {
return 0;
}
-static int help(void) {
- _cleanup_(table_unrefp) Table *options = NULL;
- int r;
-
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- help_cmdline("add NAME SOURCE DEST METADATA [OPTIONS]");
- help_cmdline("remove NAME");
- help_abstract("Add or remove a dm-clone device.");
- help_section("Options");
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- help_man_page_reference("systemd-clonesetup", "8");
- return 0;
-}
-
static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
@@ -165,10 +150,13 @@ static int parse_argv(int argc, char *argv[]) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-clonesetup");
OPTION_COMMON_VERSION:
return version();
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
return 1;
diff --git a/src/growfs/growfs.c b/src/growfs/growfs.c
index 8b1bb9b759..15077f1bd7 100644
--- a/src/growfs/growfs.c
+++ b/src/growfs/growfs.c
@@ -3,6 +3,8 @@
#include
#include
+#include "sd-json.h"
+
#include "alloc-util.h"
#include "blockdev-util.h"
#include "btrfs-util.h"
@@ -13,19 +15,24 @@
#include "dissect-image.h"
#include "dlopen-note.h"
#include "fd-util.h"
-#include "format-table.h"
#include "format-util.h"
#include "log.h"
#include "main-func.h"
#include "mountpoint-util.h"
-#include "options.h"
-#include "pretty-print.h"
#include "resize-fs.h"
#include "string-util.h"
+#include "verbs.h"
static const char *arg_target = NULL;
static bool arg_dry_run = false;
+COMMAND(
+ "systemd-growfs\0",
+ "Grow filesystem or encrypted payload to device size.",
+ .argspec = "MOUNTPOINT\0",
+ .man_pages = "systemd-growfs@.service.8\0",
+);
+
#if HAVE_LIBCRYPTSETUP
static int resize_crypt_luks_device(dev_t devno, const char *fstype, dev_t main_devno) {
_cleanup_free_ char *devpath = NULL, *main_devpath = NULL;
@@ -128,35 +135,6 @@ static int maybe_resize_underlying_device(
return 0;
}
-static int help(void) {
- _cleanup_free_ char *link = NULL;
- _cleanup_(table_unrefp) Table *options = NULL;
- int r;
-
- r = terminal_urlify_man("systemd-growfs@.service", "8", &link);
- if (r < 0)
- return log_oom();
-
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- printf("%s [OPTIONS...] /path/to/mountpoint\n\n"
- "Grow filesystem or encrypted payload to device size.\n",
- program_invocation_short_name);
-
- printf("\n%sOptions:%s\n",
- ansi_underline(),
- ansi_normal());
-
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- printf("\nSee the %s for details.\n", link);
- return 0;
-}
-
static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
@@ -167,7 +145,7 @@ static int parse_argv(int argc, char *argv[]) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-growfs");
OPTION_COMMON_VERSION:
return version();
@@ -175,6 +153,9 @@ static int parse_argv(int argc, char *argv[]) {
OPTION('n', "dry-run", NULL, "Just print what would be done"):
arg_dry_run = true;
break;
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
if (option_parser_get_n_args(&opts) != 1)
diff --git a/src/hibernate-resume/hibernate-resume.c b/src/hibernate-resume/hibernate-resume.c
index d2dccd59bd..fa7f9bdbaa 100644
--- a/src/hibernate-resume/hibernate-resume.c
+++ b/src/hibernate-resume/hibernate-resume.c
@@ -2,53 +2,34 @@
#include
-#include "alloc-util.h"
+#include "sd-json.h"
+
#include "build.h"
#include "devnum-util.h"
-#include "format-table.h"
#include "hibernate-resume-config.h"
#include "hibernate-util.h"
#include "initrd-util.h"
#include "log.h"
#include "main-func.h"
-#include "options.h"
#include "parse-util.h"
-#include "pretty-print.h"
#include "stat-util.h"
#include "static-destruct.h"
#include "strv.h"
+#include "verbs.h"
static HibernateInfo arg_info = {};
static bool arg_clear = false;
STATIC_DESTRUCTOR_REGISTER(arg_info, hibernate_info_done);
-static int help(void) {
- _cleanup_free_ char *link = NULL;
- _cleanup_(table_unrefp) Table *options = NULL;
- int r;
-
- r = terminal_urlify_man("systemd-hibernate-resume", "8", &link);
- if (r < 0)
- return log_oom();
-
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- printf("%s [OPTIONS...] [DEVICE [OFFSET]]\n\n"
- "%sInitiate resume from hibernation.%s\n\n",
- program_invocation_short_name,
- ansi_highlight(),
- ansi_normal());
-
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- printf("\nSee the %s for details.\n", link);
- return 0;
-}
+COMMAND(
+ "systemd-hibernate-resume\0",
+ "Initiate resume from hibernation.",
+ .argspec =
+ "[DEVICE [OFFSET]]\0"
+ "--clear\0",
+ .man_pages = "systemd-hibernate-resume.8\0",
+);
static int parse_argv(int argc, char *argv[], char ***ret_args) {
assert(argc >= 0);
@@ -61,7 +42,7 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-hibernate-resume");
OPTION_COMMON_VERSION:
return version();
@@ -70,6 +51,9 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
"Clear hibernation storage information from EFI and exit"):
arg_clear = true;
break;
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
if (option_parser_get_n_args(&opts) > 0 && arg_clear)
diff --git a/src/journal-remote/journal-gatewayd.c b/src/journal-remote/journal-gatewayd.c
index f2fd083c8a..e135bf1c9b 100644
--- a/src/journal-remote/journal-gatewayd.c
+++ b/src/journal-remote/journal-gatewayd.c
@@ -9,6 +9,7 @@
#include "sd-bus.h"
#include "sd-daemon.h"
#include "sd-journal.h"
+#include "sd-json.h"
#include "alloc-util.h"
#include "build.h"
@@ -16,7 +17,6 @@
#include "errno-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "format-table.h"
#include "glob-util.h"
#include "hostname-setup.h"
#include "hostname-util.h"
@@ -27,15 +27,14 @@
#include "main-func.h"
#include "memory-util.h"
#include "microhttpd-util.h"
-#include "options.h"
#include "os-util.h"
#include "output-mode.h"
#include "parse-util.h"
-#include "pretty-print.h"
#include "signal-util.h"
#include "string-util.h"
#include "time-util.h"
#include "tmpfile-util.h"
+#include "verbs.h"
#define JOURNAL_WAIT_TIMEOUT (10*USEC_PER_SEC)
@@ -53,6 +52,12 @@ STATIC_DESTRUCTOR_REGISTER(arg_trust_pem, freep);
STATIC_DESTRUCTOR_REGISTER(arg_directory, freep);
STATIC_DESTRUCTOR_REGISTER(arg_file, strv_freep);
+COMMAND(
+ "systemd-journal-gatewayd\0",
+ "Serve journal events over HTTP.",
+ .man_pages = "systemd-journal-gatewayd.service.8\0",
+);
+
typedef struct RequestMeta {
sd_journal *journal;
@@ -1096,31 +1101,6 @@ static mhd_result request_handler(
return mhd_respond(connection, MHD_HTTP_NOT_FOUND, "Not found.");
}
-static int help(void) {
- _cleanup_free_ char *link = NULL;
- _cleanup_(table_unrefp) Table *options = NULL;
- int r;
-
- r = terminal_urlify_man("systemd-journal-gatewayd.service", "8", &link);
- if (r < 0)
- return log_oom();
-
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- printf("%s [OPTIONS...] ...\n\n"
- "HTTP server for journal events.\n\n",
- program_invocation_short_name);
-
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- printf("\nSee the %s for details.\n", link);
- return 0;
-}
-
static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
@@ -1132,7 +1112,7 @@ static int parse_argv(int argc, char *argv[]) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-journal-gatewayd");
OPTION_COMMON_VERSION:
return version();
@@ -1207,6 +1187,9 @@ static int parse_argv(int argc, char *argv[]) {
if (r < 0)
return log_error_errno(r, "Failed to add paths: %m");
break;
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
if (option_parser_get_n_args(&opts) > 0)
diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c
index 30757201f3..09f010728d 100644
--- a/src/journal-remote/journal-remote-main.c
+++ b/src/journal-remote/journal-remote-main.c
@@ -4,6 +4,7 @@
#include "sd-daemon.h"
#include "sd-event.h"
+#include "sd-json.h"
#include "alloc-util.h"
#include "build.h"
@@ -12,9 +13,8 @@
#include "dlopen-note.h"
#include "extract-word.h"
#include "fd-util.h"
-#include "format-table.h"
-#include "format-util.h"
#include "fileio.h"
+#include "format-util.h"
#include "hashmap.h"
#include "journal-authenticate.h"
#include "journal-compression-util.h"
@@ -23,12 +23,10 @@
#include "logs-show.h"
#include "main-func.h"
#include "microhttpd-util.h"
-#include "options.h"
#include "parse-argument.h"
#include "parse-helpers.h"
#include "parse-util.h"
#include "path-util.h"
-#include "pretty-print.h"
#include "process-util.h"
#include "socket-netlink.h"
#include "socket-util.h"
@@ -36,6 +34,7 @@
#include "string-table.h"
#include "string-util.h"
#include "strv.h"
+#include "verbs.h"
#define PRIV_KEY_FILE CERTIFICATE_ROOT "/private/journal-remote.pem"
#define CERT_FILE CERTIFICATE_ROOT "/certs/journal-remote.pem"
@@ -84,6 +83,14 @@ STATIC_DESTRUCTOR_REGISTER(arg_trust, freep);
STATIC_DESTRUCTOR_REGISTER(arg_output, freep);
STATIC_DESTRUCTOR_REGISTER(arg_compression, ordered_hashmap_freep);
+COMMAND(
+ "systemd-journal-remote\0",
+ "Write external journal events to journal files.",
+ .argspec = "[{FILE|-}…]\0",
+ .footer = "Note: file descriptors from sd_listen_fds() will be consumed, too.",
+ .man_pages = "systemd-journal-remote.service.8\0",
+);
+
static const char* const journal_write_split_mode_table[_JOURNAL_WRITE_SPLIT_MAX] = {
[JOURNAL_WRITE_SPLIT_NONE] = "none",
[JOURNAL_WRITE_SPLIT_HOST] = "host",
@@ -869,39 +876,6 @@ static int parse_config(void) {
/* userdata= */ NULL);
}
-static int help(void) {
- _cleanup_free_ char *link = NULL;
- _cleanup_(table_unrefp) Table *options = NULL;
- int r;
-
- r = terminal_urlify_man("systemd-journal-remote.service", "8", &link);
- if (r < 0)
- return log_oom();
-
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- printf("%s [OPTIONS...] {FILE|-}...\n"
- "\n%sWrite external journal events to journal file(s).%s\n"
- "\n%sOptions:%s\n",
- program_invocation_short_name,
- ansi_highlight(),
- ansi_normal(),
- ansi_underline(),
- ansi_normal());
-
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- printf("\nNote: file descriptors from sd_listen_fds() will be consumed, too.\n"
- "\nSee the %s for details.\n",
- link);
-
- return 0;
-}
-
static int parse_argv(int argc, char *argv[]) {
int r;
bool type_a, type_b;
@@ -915,7 +889,7 @@ static int parse_argv(int argc, char *argv[]) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-journal-remote");
OPTION_COMMON_VERSION:
return version();
@@ -1059,6 +1033,9 @@ static int parse_argv(int argc, char *argv[]) {
if (r < 0)
return log_error_errno(r, "Failed to parse --max-files= value: %s", opts.arg);
break;
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
arg_files = strv_copy(option_parser_get_args(&opts));
diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c
index d680a4c02b..2516d3fa6c 100644
--- a/src/journal-remote/journal-upload.c
+++ b/src/journal-remote/journal-upload.c
@@ -6,6 +6,7 @@
#include "sd-daemon.h"
#include "sd-event.h"
+#include "sd-json.h"
#include "alloc-util.h"
#include "build.h"
@@ -17,12 +18,10 @@
#include "extract-word.h"
#include "fd-util.h"
#include "fileio.h"
-#include "format-table.h"
#include "format-util.h"
#include "fs-util.h"
#include "glob-util.h"
#include "hashmap.h"
-#include "help-util.h"
#include "journal-header-util.h"
#include "journal-upload.h"
#include "journal-util.h"
@@ -30,7 +29,6 @@
#include "logs-show.h"
#include "main-func.h"
#include "mkdir.h"
-#include "options.h"
#include "parse-argument.h"
#include "parse-helpers.h"
#include "process-util.h"
@@ -38,6 +36,7 @@
#include "strv.h"
#include "time-util.h"
#include "tmpfile-util.h"
+#include "verbs.h"
#include "version.h"
#define PRIV_KEY_FILE CERTIFICATE_ROOT "/private/journal-upload.pem"
@@ -78,6 +77,13 @@ STATIC_DESTRUCTOR_REGISTER(arg_save_state, freep);
STATIC_DESTRUCTOR_REGISTER(arg_compression, ordered_hashmap_freep);
STATIC_DESTRUCTOR_REGISTER(arg_headers, ordered_hashmap_freep);
+COMMAND(
+ "systemd-journal-upload\0",
+ "Upload journal events to a remote server.",
+ .argspec = "[-u URL] [{FILE|-}…]\0",
+ .man_pages = "systemd-journal-upload.service.8\0",
+);
+
static void close_fd_input(Uploader *u);
#define SERVER_ANSWER_KEEP 2048
@@ -684,26 +690,6 @@ static int parse_config(void) {
/* userdata= */ NULL);
}
-static int help(void) {
- _cleanup_(table_unrefp) Table *options = NULL;
- int r;
-
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- help_cmdline("-u URL {FILE|-}...");
- help_abstract("Upload journal events to a remote server.");
-
- help_section("Options");
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- help_man_page_reference("systemd-journal-upload.service", "8");
- return 0;
-}
-
static int parse_argv(int argc, char *argv[], char ***ret_args) {
int r;
@@ -717,7 +703,7 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-journal-upload");
OPTION_COMMON_VERSION:
return version();
@@ -824,6 +810,9 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
if (r < 0)
return r;
break;
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
if (!arg_url)
diff --git a/src/modules-load/modules-load.c b/src/modules-load/modules-load.c
index 85452f62a5..9ae6531472 100644
--- a/src/modules-load/modules-load.c
+++ b/src/modules-load/modules-load.c
@@ -6,6 +6,8 @@
#include
#include
+#include "sd-json.h"
+
#include "alloc-util.h"
#include "assert.h"
#include "build.h"
@@ -16,18 +18,16 @@
#include "errno-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "format-table.h"
#include "log.h"
#include "macro.h"
#include "main-func.h"
#include "module-util.h"
-#include "options.h"
#include "ordered-set.h"
#include "parse-util.h"
-#include "pretty-print.h"
#include "proc-cmdline.h"
#include "string-util.h"
#include "strv.h"
+#include "verbs.h"
#define MODULE_NAME_MAX_LEN (4096UL)
@@ -36,6 +36,13 @@ static const char conf_file_dirs[] = CONF_PATHS_NULSTR("modules-load.d");
STATIC_DESTRUCTOR_REGISTER(arg_proc_cmdline_modules, strv_freep);
+COMMAND(
+ "systemd-modules-load\0",
+ "Load statically configured kernel modules.",
+ .argspec = "[CONFIGURATION FILE…]\0",
+ .man_pages = "systemd-modules-load.service.8\0",
+);
+
static int modules_list_append_suffix(OrderedSet **module_set, char *modp) {
/* take possession of string no matter what */
_cleanup_free_ char *mod = modp;
@@ -332,30 +339,6 @@ static unsigned determine_num_worker_threads(unsigned n_modules) {
return n_threads - 1U;
}
-static int help(void) {
- _cleanup_free_ char *link = NULL;
- _cleanup_(table_unrefp) Table *options = NULL;
- int r;
-
- if (terminal_urlify_man("systemd-modules-load.service", "8", &link) < 0)
- return log_oom();
-
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
- "Loads statically configured kernel modules.\n\n",
- program_invocation_short_name);
-
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- printf("\nSee the %s for details.\n", link);
- return 0;
-}
-
static int parse_argv(int argc, char *argv[], char ***ret_args) {
assert(argc >= 0);
assert(argv);
@@ -367,10 +350,13 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-modules-load");
OPTION_COMMON_VERSION:
return version();
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
*ret_args = option_parser_get_args(&opts);
diff --git a/src/network/generator/network-generator-main.c b/src/network/generator/network-generator-main.c
index ae15dff2b1..fb5c54bd13 100644
--- a/src/network/generator/network-generator-main.c
+++ b/src/network/generator/network-generator-main.c
@@ -2,29 +2,37 @@
#include
+#include "sd-json.h"
+
#include "alloc-util.h"
#include "build.h"
#include "creds-util.h"
#include "dlopen-note.h"
#include "errno-util.h"
#include "fd-util.h"
-#include "format-table.h"
#include "fs-util.h"
#include "generator.h"
#include "log.h"
#include "main-func.h"
#include "mkdir.h"
#include "network-generator.h"
-#include "options.h"
#include "path-util.h"
#include "proc-cmdline.h"
#include "string-util.h"
#include "strv.h"
+#include "verbs.h"
#define NETWORK_UNIT_DIRECTORY "/run/systemd/network/"
static const char *arg_root = NULL;
+COMMAND(
+ "systemd-network-generator\0",
+ "Generate network configuration from the kernel command line.",
+ .argspec = "[-- KERNEL_CMDLINE]\0",
+ .man_pages = "systemd-network-generator.service.8\0",
+);
+
static int network_save(Network *network, const char *dest_dir) {
_cleanup_(unlink_and_freep) char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
@@ -150,24 +158,6 @@ static int context_save(Context *context) {
return r;
}
-static int help(void) {
- _cleanup_(table_unrefp) Table *options = NULL;
- int r;
-
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- printf("%s [OPTIONS...] [-- KERNEL_CMDLINE]\n\n",
- program_invocation_short_name);
-
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- return 0;
-}
-
static int parse_argv(int argc, char *argv[], char ***ret_args) {
assert(argc >= 0);
assert(argv);
@@ -179,7 +169,7 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-network-generator");
OPTION_COMMON_VERSION:
return version();
@@ -188,6 +178,9 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
"Operate on an alternate filesystem root"):
arg_root = opts.arg;
break;
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
*ret_args = option_parser_get_args(&opts);
diff --git a/src/network/wait-online/wait-online.c b/src/network/wait-online/wait-online.c
index e566f89d02..7f6b315bf2 100644
--- a/src/network/wait-online/wait-online.c
+++ b/src/network/wait-online/wait-online.c
@@ -3,20 +3,19 @@
#include
#include "sd-event.h"
+#include "sd-json.h"
#include "alloc-util.h"
#include "build.h"
#include "daemon-util.h"
-#include "format-table.h"
#include "hashmap.h"
-#include "help-util.h"
#include "log.h"
#include "main-func.h"
-#include "options.h"
#include "parse-argument.h"
#include "socket-util.h"
#include "strv.h"
#include "time-util.h"
+#include "verbs.h"
#include "wait-online-manager.h"
static bool arg_quiet = false;
@@ -31,25 +30,11 @@ static bool arg_requires_dns = false;
STATIC_DESTRUCTOR_REGISTER(arg_interfaces, hashmap_freep);
STATIC_DESTRUCTOR_REGISTER(arg_ignore, strv_freep);
-static int help(void) {
- _cleanup_(table_unrefp) Table *options = NULL;
- int r;
-
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- help_cmdline("[OPTIONS...]");
- help_abstract("Block until network is configured.");
-
- help_section("Options");
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- help_man_page_reference("systemd-networkd-wait-online.service", "8");
- return 0;
-}
+COMMAND(
+ "systemd-networkd-wait-online\0",
+ "Block until network is configured.",
+ .man_pages = "systemd-networkd-wait-online.service.8\0",
+);
static int parse_interface_with_operstate_range(const char *str) {
_cleanup_free_ char *ifname = NULL;
@@ -107,7 +92,7 @@ static int parse_argv(int argc, char *argv[]) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-networkd-wait-online");
OPTION_COMMON_VERSION:
return version();
@@ -160,6 +145,9 @@ static int parse_argv(int argc, char *argv[]) {
if (r < 0)
return r;
break;
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
return 1;
diff --git a/src/pcrextend/pcrextend.c b/src/pcrextend/pcrextend.c
index 06cc7dc5a7..0ec2943042 100644
--- a/src/pcrextend/pcrextend.c
+++ b/src/pcrextend/pcrextend.c
@@ -10,11 +10,8 @@
#include "dlopen-note.h"
#include "efi-loader.h"
#include "escape.h"
-#include "format-table.h"
-#include "help-util.h"
#include "json-util.h"
#include "main-func.h"
-#include "options.h"
#include "parse-argument.h"
#include "pcrextend-util.h"
#include "string-table.h"
@@ -26,6 +23,7 @@
#include "userdb.h"
#include "varlink-io.systemd.PCRExtend.h"
#include "varlink-util.h"
+#include "verbs.h"
static bool arg_graceful = false;
static char *arg_tpm2_device = NULL;
@@ -45,32 +43,20 @@ STATIC_DESTRUCTOR_REGISTER(arg_file_system, freep);
STATIC_DESTRUCTOR_REGISTER(arg_nvpcr_name, freep);
STATIC_DESTRUCTOR_REGISTER(arg_login, user_record_unrefp);
+COMMAND(
+ "systemd-pcrextend\0",
+ "Extend a TPM2 PCR with boot phase, machine ID, file system ID or user record.",
+ .argspec =
+ "WORD\0"
+ "--file-system=PATH\0"
+ "--machine-id\0"
+ "--product-id\0"
+ "--login=UID|USER\0",
+ .man_pages = "systemd-pcrextend.8\0",
+);
+
#define EXTENSION_STRING_SAFE_LIMIT 1024
-static int help(void) {
- _cleanup_(table_unrefp) Table *options = NULL;
- int r;
-
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- help_cmdline("[OPTIONS...] WORD");
- help_cmdline("[OPTIONS...] --file-system=PATH");
- help_cmdline("[OPTIONS...] --machine-id");
- help_cmdline("[OPTIONS...] --product-id");
- help_cmdline("[OPTIONS...] --login=UID|USER");
- help_abstract("Extend a TPM2 PCR with boot phase, machine ID, file system ID or user record.");
-
- help_section("Options");
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- help_man_page_reference("systemd-pcrextend", "8");
- return 0;
-}
-
static int parse_argv(int argc, char *argv[], char ***ret_args) {
assert(argc >= 0);
assert(argv);
@@ -82,7 +68,7 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-pcrextend");
OPTION_COMMON_VERSION:
return version();
@@ -185,6 +171,9 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
if (arg_event_type < 0)
return log_error_errno(arg_event_type, "Failed to parse --event-type= argument: %s", opts.arg);
break;
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
if (!!arg_file_system + arg_machine_id + arg_product_id + !!arg_login > 1)
diff --git a/src/socket-proxy/socket-proxyd.c b/src/socket-proxy/socket-proxyd.c
index 8be25f176e..aa101e9f65 100644
--- a/src/socket-proxy/socket-proxyd.c
+++ b/src/socket-proxy/socket-proxyd.c
@@ -6,6 +6,7 @@
#include "sd-daemon.h"
#include "sd-event.h"
+#include "sd-json.h"
#include "sd-resolve.h"
#include "alloc-util.h"
@@ -14,14 +15,11 @@
#include "errno-util.h"
#include "event-util.h"
#include "fd-util.h"
-#include "format-table.h"
#include "in-addr-util.h"
#include "io-util.h"
#include "log.h"
#include "main-func.h"
-#include "options.h"
#include "parse-util.h"
-#include "pretty-print.h"
#include "resolve-private.h"
#include "set.h"
#include "socket-forward.h"
@@ -30,6 +28,7 @@
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
+#include "verbs.h"
static unsigned arg_connections_max = 256;
static const char *arg_remote_host = NULL;
@@ -50,6 +49,16 @@ static ProxyProtocol arg_proxy_protocol = PROXY_NONE;
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(proxy_protocol, ProxyProtocol);
+COMMAND(
+ "systemd-socket-proxyd\0",
+ "Bidirectionally proxy local sockets to another (possibly remote) socket.",
+ .argspec =
+ "HOST:PORT\0"
+ "SOCKET\0",
+ .footer = "See systemd.time(7) for the --exit-idle-time= time span format.",
+ .man_pages = "systemd-socket-proxyd.8\0",
+);
+
typedef struct Context {
sd_event *event;
sd_resolve *resolve;
@@ -486,39 +495,6 @@ static int add_listen_socket(Context *context, int fd) {
return 0;
}
-static int help(void) {
- _cleanup_free_ char *link = NULL, *time_link = NULL;
- _cleanup_(table_unrefp) Table *options = NULL;
- int r;
-
- r = terminal_urlify_man("systemd-socket-proxyd", "8", &link);
- if (r < 0)
- return log_oom();
- r = terminal_urlify_man("systemd.time", "7", &time_link);
- if (r < 0)
- return log_oom();
-
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- printf("%1$s [HOST:PORT]\n"
- "%1$s [SOCKET]\n"
- "\n%2$sBidirectionally proxy local sockets to another (possibly remote) socket.%3$s\n\n",
- program_invocation_short_name,
- ansi_highlight(),
- ansi_normal());
-
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- printf("\nSee %s for --exit-idle-time= time span format.\n"
- "See the %s for details.\n",
- time_link, link);
- return 0;
-}
-
static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
@@ -530,7 +506,7 @@ static int parse_argv(int argc, char *argv[]) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-socket-proxyd");
OPTION_COMMON_VERSION:
return version();
@@ -560,6 +536,9 @@ static int parse_argv(int argc, char *argv[]) {
if (arg_proxy_protocol < 0)
return log_error_errno(arg_proxy_protocol, "Failed to parse --proxy-protocol= argument: %s", opts.arg);
break;
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
char **args = option_parser_get_args(&opts);
diff --git a/src/stdio-bridge/stdio-bridge.c b/src/stdio-bridge/stdio-bridge.c
index 01686d2cd6..25e6f49a35 100644
--- a/src/stdio-bridge/stdio-bridge.c
+++ b/src/stdio-bridge/stdio-bridge.c
@@ -5,42 +5,29 @@
#include "sd-bus.h"
#include "sd-daemon.h"
+#include "sd-json.h"
#include "build.h"
#include "bus-internal.h"
#include "bus-util.h"
#include "errno-util.h"
-#include "format-table.h"
#include "io-util.h"
#include "log.h"
#include "main-func.h"
-#include "options.h"
#include "parse-argument.h"
#include "time-util.h"
+#include "verbs.h"
static const char *arg_bus_path = NULL;
static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
static RuntimeScope arg_runtime_scope = RUNTIME_SCOPE_SYSTEM;
static bool arg_quiet = false;
-static int help(void) {
- _cleanup_(table_unrefp) Table *options = NULL;
- int r;
-
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- printf("%s [OPTIONS...]\n"
- "\nForward messages between a pipe or socket and a D-Bus bus.\n\n",
- program_invocation_short_name);
-
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- return 0;
-}
+COMMAND(
+ "systemd-stdio-bridge\0",
+ "Forward messages between a pipe or socket and a D-Bus bus.",
+ .man_pages = "systemd-stdio-bridge.1\0",
+);
static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
@@ -53,7 +40,7 @@ static int parse_argv(int argc, char *argv[]) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-stdio-bridge");
OPTION_COMMON_VERSION:
return version();
@@ -80,6 +67,9 @@ static int parse_argv(int argc, char *argv[]) {
OPTION('q', "quiet", NULL, "Fail silently instead of logging errors"):
arg_quiet = true;
break;
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
if (option_parser_get_n_args(&opts) > 0)
diff --git a/src/storage/storage-block.c b/src/storage/storage-block.c
index b33bf9ce40..363fad66da 100644
--- a/src/storage/storage-block.c
+++ b/src/storage/storage-block.c
@@ -13,18 +13,22 @@
#include "device-util.h"
#include "errno-util.h"
#include "fd-util.h"
-#include "format-table.h"
#include "hashmap.h"
-#include "help-util.h"
#include "json-util.h"
#include "log.h"
#include "main-func.h"
-#include "options.h"
#include "path-util.h"
#include "storage-util.h"
#include "strv.h"
#include "varlink-io.systemd.StorageProvider.h"
#include "varlink-util.h"
+#include "verbs.h"
+
+COMMAND(
+ "systemd-storage-block\0",
+ "Expose local block devices as storage volumes.",
+ .man_pages = "systemd-storage-block.8\0",
+);
static int block_device_pick_name(
const BlockDevice *d,
@@ -382,27 +386,6 @@ static int vl_server(void) {
return 0;
}
-static int help(void) {
- int r;
-
- help_cmdline("[OPTIONS...]");
- help_abstract("Simple block device backed storage provider");
-
- _cleanup_(table_unrefp) Table *options = NULL;
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- help_section("Options");
-
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- help_man_page_reference("systemd-storage-block", "8");
- return 0;
-}
-
static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
@@ -412,10 +395,13 @@ static int parse_argv(int argc, char *argv[]) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-storage-block");
OPTION_COMMON_VERSION:
return version();
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
if (option_parser_get_n_args(&opts) > 0)
diff --git a/src/storage/storage-fs.c b/src/storage/storage-fs.c
index 5b2bc415fb..ef0cc7b66c 100644
--- a/src/storage/storage-fs.c
+++ b/src/storage/storage-fs.c
@@ -18,14 +18,11 @@
#include "device-util.h"
#include "errno-util.h"
#include "fd-util.h"
-#include "format-table.h"
#include "fs-util.h"
#include "hashmap.h"
-#include "help-util.h"
#include "log.h"
#include "main-func.h"
#include "mount-util.h"
-#include "options.h"
#include "path-lookup.h"
#include "path-util.h"
#include "recurse-dir.h"
@@ -37,9 +34,16 @@
#include "uid-classification.h"
#include "varlink-io.systemd.StorageProvider.h"
#include "varlink-util.h"
+#include "verbs.h"
static RuntimeScope arg_runtime_scope = RUNTIME_SCOPE_SYSTEM;
+COMMAND(
+ "systemd-storage-fs\0",
+ "Expose regular files and directories as storage volumes.",
+ .man_pages = "systemd-storage-fs.8\0",
+);
+
/* For now we maintain a simple, compiled-in list of templates. One of those days we might want to move these
* into configurable drop-in files on disk. */
typedef enum Template {
@@ -742,27 +746,6 @@ static int vl_server(void) {
return 0;
}
-static int help(void) {
- int r;
-
- help_cmdline("[OPTIONS...]");
- help_abstract("Simple file system backed storage provider");
-
- _cleanup_(table_unrefp) Table *options = NULL;
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- help_section("Options");
-
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- help_man_page_reference("systemd-storage-fs", "8");
- return 0;
-}
-
static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
@@ -772,7 +755,7 @@ static int parse_argv(int argc, char *argv[]) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-storage-fs");
OPTION_COMMON_VERSION:
return version();
@@ -784,6 +767,9 @@ static int parse_argv(int argc, char *argv[]) {
OPTION_COMMON_USER:
arg_runtime_scope = RUNTIME_SCOPE_USER;
break;
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
if (option_parser_get_n_args(&opts) > 0)
diff --git a/src/storagetm/storagetm.c b/src/storagetm/storagetm.c
index 2d59ab1408..91a4763307 100644
--- a/src/storagetm/storagetm.c
+++ b/src/storagetm/storagetm.c
@@ -5,6 +5,7 @@
#include
#include "sd-event.h"
+#include "sd-json.h"
#include "sd-netlink.h"
#include "af-list.h"
@@ -16,18 +17,16 @@
#include "device-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "format-table.h"
#include "fs-util.h"
+#include "glyph-util.h"
#include "hashmap.h"
#include "id128-util.h"
#include "local-addresses.h"
#include "main-func.h"
#include "mountpoint-util.h"
-#include "options.h"
#include "os-util.h"
#include "path-util.h"
#include "plymouth-util.h"
-#include "pretty-print.h"
#include "random-util.h"
#include "recurse-dir.h"
#include "siphash24.h"
@@ -38,6 +37,7 @@
#include "terminal-util.h"
#include "time-util.h"
#include "udev-util.h"
+#include "verbs.h"
static char **arg_devices = NULL;
static char *arg_nqn = NULL;
@@ -46,32 +46,15 @@ static int arg_all = 0;
STATIC_DESTRUCTOR_REGISTER(arg_devices, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_nqn, freep);
-static int help(void) {
- _cleanup_free_ char *link = NULL;
- _cleanup_(table_unrefp) Table *options = NULL;
- int r;
-
- r = terminal_urlify_man("systemd-storagetm", "8", &link);
- if (r < 0)
- return log_oom();
-
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- printf("%s [OPTIONS...] [DEVICE...]\n"
- "\n%sExpose a block device or regular file as NVMe-TCP volume.%s\n\n",
- program_invocation_short_name,
- ansi_highlight(),
- ansi_normal());
-
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- printf("\nSee the %s for details.\n", link);
- return 0;
-}
+COMMAND(
+ "systemd-storagetm\0",
+ "Expose a block device or regular file as NVMe-TCP volume.",
+ .argspec =
+ "DEVICE…\0"
+ "--all\0"
+ "--list-devices\0",
+ .man_pages = "systemd-storagetm.8\0",
+);
static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
@@ -84,7 +67,7 @@ static int parse_argv(int argc, char *argv[]) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-storagetm");
OPTION_COMMON_VERSION:
return version();
@@ -110,6 +93,9 @@ static int parse_argv(int argc, char *argv[]) {
return r;
return 0;
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
char **args = option_parser_get_args(&opts);
diff --git a/src/sysinstall/sysinstall.c b/src/sysinstall/sysinstall.c
index b3b730b914..13269999a2 100644
--- a/src/sysinstall/sysinstall.c
+++ b/src/sysinstall/sysinstall.c
@@ -4,6 +4,7 @@
#include
#include
+#include "sd-json.h"
#include "sd-varlink.h"
#include "alloc-util.h"
@@ -27,7 +28,6 @@
#include "fs-util.h"
#include "glyph-util.h"
#include "hashmap.h"
-#include "help-util.h"
#include "image-policy.h"
#include "json-util.h"
#include "locale-setup.h"
@@ -36,7 +36,6 @@
#include "machine-credential.h"
#include "main-func.h"
#include "mount-util.h"
-#include "options.h"
#include "os-util.h"
#include "parse-argument.h"
#include "parse-util.h"
@@ -47,6 +46,7 @@
#include "terminal-util.h"
#include "varlink-io.systemd.SysInstall.h"
#include "varlink-util.h"
+#include "verbs.h"
static char *arg_node = NULL;
static bool arg_welcome = true;
@@ -70,6 +70,13 @@ STATIC_DESTRUCTOR_REGISTER(arg_definitions, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_kernel_image, freep);
STATIC_DESTRUCTOR_REGISTER(arg_credentials, machine_credential_context_done);
+COMMAND(
+ "systemd-sysinstall\0",
+ "Install the OS to another block device.",
+ .argspec = "[DEVICE]\0",
+ .man_pages = "systemd-sysinstall.8\0",
+);
+
typedef enum ProgressPhase {
PROGRESS_ENCRYPT_CREDENTIALS,
PROGRESS_INSTALL_PARTITIONS,
@@ -155,27 +162,6 @@ static void sysinstall_context_done(SysInstallContext *c) {
sd_varlink_unref(c->link);
}
-static int help(void) {
- int r;
-
- _cleanup_(table_unrefp) Table *options = NULL;
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- help_cmdline("[OPTIONS...] [DEVICE]");
- help_abstract("Installs the OS to another block device.");
- help_section("Options:");
-
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- help_man_page_reference("systemd-sysinstall", "8");
-
- return 0;
-}
-
static int parse_argv(int argc, char *argv[]) {
int r;
@@ -188,7 +174,7 @@ static int parse_argv(int argc, char *argv[]) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-sysinstall");
OPTION_COMMON_VERSION:
return version();
@@ -289,6 +275,9 @@ static int parse_argv(int argc, char *argv[]) {
if (r < 0)
return r;
break;
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
char **args = option_parser_get_args(&opts);
diff --git a/src/tpm2-setup/tpm2-clear.c b/src/tpm2-setup/tpm2-clear.c
index fcef2b76bb..de0959572b 100644
--- a/src/tpm2-setup/tpm2-clear.c
+++ b/src/tpm2-setup/tpm2-clear.c
@@ -1,51 +1,25 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#include "sd-json.h"
#include "sd-messages.h"
-#include "alloc-util.h"
#include "build.h"
#include "dlopen-note.h"
#include "env-util.h"
#include "fileio.h"
-#include "format-table.h"
#include "log.h"
#include "main-func.h"
-#include "options.h"
-#include "pretty-print.h"
#include "proc-cmdline.h"
#include "tpm2-util.h"
+#include "verbs.h"
static bool arg_graceful = false;
-static int help(void) {
- _cleanup_free_ char *link = NULL;
- _cleanup_(table_unrefp) Table *options = NULL;
- int r;
-
- r = terminal_urlify_man("systemd-tpm2-clear", "8", &link);
- if (r < 0)
- return log_oom();
-
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- printf("%s [OPTIONS...]\n"
- "\n%sRequest clearing of the TPM2 from PC firmware.%s\n"
- "\n%sOptions:%s\n",
- program_invocation_short_name,
- ansi_highlight(),
- ansi_normal(),
- ansi_underline(),
- ansi_normal());
-
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- printf("\nSee the %s for details.\n", link);
- return 0;
-}
+COMMAND(
+ "systemd-tpm2-clear\0",
+ "Request clearing of the TPM2 from PC firmware.",
+ .man_pages = "systemd-tpm2-clear.service.8\0",
+);
static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
@@ -57,7 +31,7 @@ static int parse_argv(int argc, char *argv[]) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-tpm2-clear");
OPTION_COMMON_VERSION:
return version();
@@ -65,6 +39,9 @@ static int parse_argv(int argc, char *argv[]) {
OPTION_LONG("graceful", NULL, "Exit gracefully if no TPM2 device is found"):
arg_graceful = true;
break;
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
if (option_parser_get_n_args(&opts) != 0)
diff --git a/src/tpm2-setup/tpm2-setup.c b/src/tpm2-setup/tpm2-setup.c
index 2b247efd23..9435147778 100644
--- a/src/tpm2-setup/tpm2-setup.c
+++ b/src/tpm2-setup/tpm2-setup.c
@@ -4,6 +4,8 @@
#include
#include
+#include "sd-id128.h"
+#include "sd-json.h"
#include "sd-messages.h"
#include "alloc-util.h"
@@ -17,23 +19,20 @@
#include "errno-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "format-table.h"
#include "fs-util.h"
#include "hexdecoct.h"
#include "log.h"
#include "main-func.h"
#include "mkdir.h"
-#include "options.h"
#include "parse-util.h"
#include "path-util.h"
-#include "pretty-print.h"
-#include "sd-id128.h"
#include "set.h"
#include "sort-util.h"
#include "string-util.h"
#include "strv.h"
#include "tmpfile-util.h"
#include "tpm2-util.h"
+#include "verbs.h"
static char *arg_tpm2_device = NULL;
static bool arg_early = false;
@@ -41,42 +40,18 @@ static bool arg_graceful = false;
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep);
+COMMAND(
+ "systemd-tpm2-setup\0",
+ "Set up the TPM2 Storage Root Key (SRK) and Endorsement Key (EK), and initialize NvPCRs.",
+ .man_pages = "systemd-tpm2-setup.8\0",
+);
+
#define TPM2_SRK_PEM_PERSISTENT_PATH "/var/lib/systemd/tpm2-srk-public-key.pem"
#define TPM2_SRK_PEM_RUNTIME_PATH "/run/systemd/tpm2-srk-public-key.pem"
#define TPM2_SRK_TPM2B_PUBLIC_PERSISTENT_PATH "/var/lib/systemd/tpm2-srk-public-key.tpm2b_public"
#define TPM2_SRK_TPM2B_PUBLIC_RUNTIME_PATH "/run/systemd/tpm2-srk-public-key.tpm2b_public"
-static int help(void) {
- _cleanup_free_ char *link = NULL;
- _cleanup_(table_unrefp) Table *options = NULL;
- int r;
-
- r = terminal_urlify_man("systemd-tpm2-setup", "8", &link);
- if (r < 0)
- return log_oom();
-
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- printf("%s [OPTIONS...]\n"
- "\n%sSet up the TPM2 Storage Root Key (SRK) and Endorsement Key (EK), and initialize NvPCRs.%s\n"
- "\n%sOptions:%s\n",
- program_invocation_short_name,
- ansi_highlight(),
- ansi_normal(),
- ansi_underline(),
- ansi_normal());
-
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- printf("\nSee the %s for details.\n", link);
- return 0;
-}
-
static int parse_argv(int argc, char *argv[]) {
int r;
@@ -89,7 +64,7 @@ static int parse_argv(int argc, char *argv[]) {
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-tpm2-setup");
OPTION_COMMON_VERSION:
return version();
@@ -113,6 +88,9 @@ static int parse_argv(int argc, char *argv[]) {
OPTION_LONG("graceful", NULL, "Exit gracefully if no TPM2 device is found"):
arg_graceful = true;
break;
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
if (option_parser_get_n_args(&opts) != 0)
diff --git a/src/update-done/update-done.c b/src/update-done/update-done.c
index ceb8337495..c3545e1b57 100644
--- a/src/update-done/update-done.c
+++ b/src/update-done/update-done.c
@@ -2,6 +2,8 @@
#include
+#include "sd-json.h"
+
#include "alloc-util.h"
#include "build.h"
#include "chase.h"
@@ -9,20 +11,24 @@
#include "errno-util.h"
#include "fd-util.h"
#include "fileio.h"
-#include "format-table.h"
#include "label-util.h"
#include "log.h"
#include "main-func.h"
-#include "options.h"
#include "parse-argument.h"
-#include "pretty-print.h"
#include "string-util.h"
#include "time-util.h"
+#include "verbs.h"
static char *arg_root = NULL;
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
+COMMAND(
+ "systemd-update-done\0",
+ "Mark /etc/ and /var/ as fully updated.",
+ .man_pages = "systemd-update-done.8\0",
+);
+
static int save_timestamp(const char *dir, struct timespec *ts) {
_cleanup_free_ char *message = NULL, *dirpath = NULL;
_cleanup_close_ int fd = -EBADF;
@@ -62,35 +68,6 @@ static int save_timestamp(const char *dir, struct timespec *ts) {
return 0;
}
-static int help(void) {
- _cleanup_free_ char *link = NULL;
- _cleanup_(table_unrefp) Table *options = NULL;
- int r;
-
- r = terminal_urlify_man("systemd-update-done", "8", &link);
- if (r < 0)
- return log_oom();
-
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- printf("%s [OPTIONS...]\n"
- "\n%sMark /etc/ and /var/ as fully updated.%s\n"
- "\n%sOptions:%s\n",
- program_invocation_short_name,
- ansi_highlight(),
- ansi_normal(),
- ansi_underline(),
- ansi_normal());
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- printf("\nSee the %s for details.\n", link);
- return 0;
-}
-
static int parse_argv(int argc, char *argv[]) {
int r;
@@ -102,7 +79,7 @@ static int parse_argv(int argc, char *argv[]) {
FOREACH_OPTION_OR_RETURN(c, &opts)
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-update-done");
OPTION_COMMON_VERSION:
return version();
@@ -112,6 +89,9 @@ static int parse_argv(int argc, char *argv[]) {
if (r < 0)
return r;
break;
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
if (option_parser_get_n_args(&opts) > 0)
diff --git a/src/validatefs/validatefs.c b/src/validatefs/validatefs.c
index 1ac025b74d..179274b43d 100644
--- a/src/validatefs/validatefs.c
+++ b/src/validatefs/validatefs.c
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "sd-device.h"
+#include "sd-json.h"
#include "alloc-util.h"
#include "blkid-util.h"
@@ -11,19 +12,17 @@
#include "dlopen-note.h"
#include "errno-util.h"
#include "fd-util.h"
-#include "format-table.h"
#include "gpt.h"
#include "initrd-util.h"
#include "log.h"
#include "main-func.h"
#include "mountpoint-util.h"
-#include "options.h"
#include "parse-argument.h"
#include "path-util.h"
-#include "pretty-print.h"
#include "string-util.h"
#include "strv.h"
#include "utf8.h"
+#include "verbs.h"
#include "xattr-util.h"
static char *arg_target = NULL;
@@ -32,32 +31,12 @@ static char *arg_root = NULL;
STATIC_DESTRUCTOR_REGISTER(arg_target, freep);
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
-static int help(void) {
- _cleanup_free_ char *link = NULL;
- _cleanup_(table_unrefp) Table *options = NULL;
- int r;
-
- r = terminal_urlify_man("systemd-validatefs@.service", "8", &link);
- if (r < 0)
- return log_oom();
-
- r = option_parser_get_help_table(&options);
- if (r < 0)
- return r;
-
- printf("%s [OPTIONS...] /path/to/mountpoint\n"
- "\n%sCheck file system validation constraints.%s\n"
- "\nOptions:\n",
- program_invocation_short_name,
- ansi_highlight(),
- ansi_normal());
- r = table_print_or_warn(options);
- if (r < 0)
- return r;
-
- printf("\nSee the %s for details.\n", link);
- return 0;
-}
+COMMAND(
+ "systemd-validatefs\0",
+ "Check file system validation constraints.",
+ .argspec = "MOUNTPOINT\0",
+ .man_pages = "systemd-validatefs@.service.8\0",
+);
static int parse_argv(int argc, char *argv[]) {
int r;
@@ -70,7 +49,7 @@ static int parse_argv(int argc, char *argv[]) {
FOREACH_OPTION_OR_RETURN(c, &opts)
switch (c) {
OPTION_COMMON_HELP:
- return help();
+ return command_print_help("systemd-validatefs");
OPTION_COMMON_VERSION:
return version();
@@ -88,6 +67,9 @@ static int parse_argv(int argc, char *argv[]) {
if (r < 0)
return r;
break;
+
+ OPTION_COMMON_INTROSPECT_CLI:
+ return introspect_cli(SD_JSON_FORMAT_OFF);
}
char **args = option_parser_get_args(&opts);
diff --git a/test/units/TEST-74-AUX-UTILS.introspect-cli.sh b/test/units/TEST-74-AUX-UTILS.introspect-cli.sh
index f7a880859c..a2b8983efa 100755
--- a/test/units/TEST-74-AUX-UTILS.introspect-cli.sh
+++ b/test/units/TEST-74-AUX-UTILS.introspect-cli.sh
@@ -7,6 +7,8 @@ set -o pipefail
# Check the other location too.
PATH=$PATH:/usr/lib/systemd
+export SYSTEMD_PAGER=cat
+
# A smoke test for the introspection code
INTROSPECTABLE=(
homectl
@@ -17,26 +19,47 @@ INTROSPECTABLE=(
systemd-backlight
systemd-battery-check
systemd-binfmt
+ systemd-boot-check-no-failures
systemd-bsod
systemd-cat
systemd-cgls
systemd-cgtop
+ systemd-clonesetup
systemd-delta
systemd-detect-virt
systemd-dissect
systemd-escape
systemd-firstboot
+ systemd-growfs
+ systemd-hibernate-resume
systemd-hwdb
systemd-id128
systemd-imds
systemd-inhibit
+ systemd-journal-gatewayd
+ systemd-journal-remote
+ systemd-journal-upload
+ systemd-modules-load
systemd-mute-console
+ systemd-network-generator
+ systemd-networkd-wait-online
systemd-notify
systemd-oomd
systemd-path
+ systemd-pcrextend
systemd-pty-forward
systemd-socket-activate
+ systemd-socket-proxyd
+ systemd-stdio-bridge
+ systemd-storage-block
+ systemd-storage-fs
+ systemd-storagetm
+ systemd-sysinstall
+ systemd-tpm2-clear
+ systemd-tpm2-setup
systemd-tty-ask-password-agent
+ systemd-update-done
+ systemd-validatefs
systemd-veritysetup
timedatectl
varlinkctl
@@ -45,6 +68,8 @@ INTROSPECTABLE=(
for i in "${INTROSPECTABLE[@]}"; do
command -v "$i" >/dev/null || continue
+ $i --help >/dev/null
+
$i --introspect-cli | jq -e \
'.mediaType == "application/vnd.io.systemd.cli-introspection-0"'
$i --introspect-cli | jq -e --arg name "$i" \
@@ -57,13 +82,17 @@ done
# systemd-hwdb defines verbs, check that they are described
if command -v systemd-hwdb >/dev/null; then
systemd-hwdb --introspect-cli | jq -e \
- '.commands[0].verbs | map(.names[0]) | contains(["query", "update"])'
+ '.commands[0].verbs | map(.names[0]) | sort == ["help", "query", "update"]'
fi
-# systemd-id128 defines verbs, check that they are described
+# systemd-id128 defines many verbs, check that some are described
systemd-id128 --introspect-cli | jq -e \
'.commands[0].verbs | map(.names[0]) | contains(["new", "machine-id", "show", "help"])'
+# systemd-clonesetup defines verbs, check that they are described
+systemd-clonesetup --introspect-cli | jq -e \
+ '.commands[0].verbs | map(.names[0]) | sort == ["add", "remove"]'
+
# resolvectl is a multicall binary, check that both commands are described
resolvectl --introspect-cli | jq -e \
'[.commands[].names[0]] | sort == ["resolvconf", "resolvectl", "systemd-resolve"]'