diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index b8b1119216..a2db0061ec 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -213,19 +213,19 @@ VERB_SCOPE(, verb_time, "time", NULL, VERB_ANY, 1, VERB_DEFAULT, "Print time required to boot the machine"); VERB_SCOPE(, verb_blame, "blame", NULL, VERB_ANY, 1, 0, "Print list of running units ordered by time to init"); -VERB_SCOPE(, verb_critical_chain, "critical-chain", "[UNIT...]", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_critical_chain, "critical-chain", "[UNIT...]\0", VERB_ANY, VERB_ANY, 0, "Print a tree of the time critical chain of units"); VERB_GROUP("Dependency Analysis"); VERB_SCOPE(, verb_plot, "plot", NULL, VERB_ANY, 1, 0, "Output SVG graphic showing service initialization"); -VERB_SCOPE(, verb_dot, "dot", "[UNIT...]", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_dot, "dot", "[UNIT...]\0", VERB_ANY, VERB_ANY, 0, "Output dependency graph in dot(1) format"); -VERB_SCOPE(, verb_dump, "dump", "[PATTERN...]", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_dump, "dump", "[PATTERN...]\0", VERB_ANY, VERB_ANY, 0, "Output state serialization of service manager"); VERB_GROUP("Configuration Files and Search Paths"); -VERB_SCOPE(, verb_cat_config, "cat-config", "NAME|PATH...", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_cat_config, "cat-config", "NAME|PATH...\0", 2, VERB_ANY, 0, "Show configuration file and drop-ins"); VERB_SCOPE(, verb_unit_files, "unit-files", NULL, VERB_ANY, VERB_ANY, 0, "List files and symlinks for units"); @@ -233,57 +233,57 @@ VERB_SCOPE(, verb_unit_paths, "unit-paths", NULL, 1, 1, 0, "List load directories for units"); VERB_GROUP("Enumerate OS Concepts"); -VERB_SCOPE(, verb_exit_status, "exit-status", "[STATUS...]", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_exit_status, "exit-status", "[STATUS...]\0", VERB_ANY, VERB_ANY, 0, "List exit status definitions"); -VERB_SCOPE(, verb_capabilities, "capability", "[CAP...]", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_capabilities, "capability", "[CAP...]\0", VERB_ANY, VERB_ANY, 0, "List capability definitions"); -VERB_SCOPE(, verb_syscall_filters, "syscall-filter", "[NAME...]", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_syscall_filters, "syscall-filter", "[NAME...]\0", VERB_ANY, VERB_ANY, 0, "List syscalls in seccomp filters"); -VERB_SCOPE(, verb_filesystems, "filesystems", "[NAME...]", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_filesystems, "filesystems", "[NAME...]\0", VERB_ANY, VERB_ANY, 0, "List known filesystems"); -VERB_SCOPE(, verb_architectures, "architectures", "[NAME...]", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_architectures, "architectures", "[NAME...]\0", VERB_ANY, VERB_ANY, 0, "List known architectures"); VERB_SCOPE(, verb_smbios11, "smbios11", NULL, VERB_ANY, 1, 0, "List strings passed via SMBIOS Type #11"); VERB_SCOPE(, verb_chid, "chid", NULL, VERB_ANY, VERB_ANY, 0, "List local CHIDs"); -VERB(verb_transient_settings, "transient-settings", "TYPE...", 2, VERB_ANY, 0, +VERB(verb_transient_settings, "transient-settings", "TYPE...\0", 2, VERB_ANY, 0, "List transient settings for unit TYPE"); VERB_GROUP("Expression Evaluation"); -VERB_SCOPE(, verb_condition, "condition", "CONDITION...", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_condition, "condition", "CONDITION...\0", VERB_ANY, VERB_ANY, 0, "Evaluate conditions and asserts"); -VERB_SCOPE(, verb_compare_versions, "compare-versions", "V1 [OP] V2", 3, 4, 0, +VERB_SCOPE(, verb_compare_versions, "compare-versions", "V1 [OP] V2\0", 3, 4, 0, "Compare two version strings"); -VERB_SCOPE(, verb_image_policy, "image-policy", "POLICY...", 2, 2, 0, +VERB_SCOPE(, verb_image_policy, "image-policy", "POLICY...\0", 2, 2, 0, "Analyze image policy string"); VERB_GROUP("Clock & Time"); -VERB_SCOPE(, verb_calendar, "calendar", "SPEC...", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_calendar, "calendar", "SPEC...\0", 2, VERB_ANY, 0, "Validate repetitive calendar time events"); -VERB_SCOPE(, verb_timestamp, "timestamp", "TIMESTAMP...", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_timestamp, "timestamp", "TIMESTAMP...\0", 2, VERB_ANY, 0, "Validate a timestamp"); -VERB_SCOPE(, verb_timespan, "timespan", "SPAN...", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_timespan, "timespan", "SPAN...\0", 2, VERB_ANY, 0, "Validate a time span"); VERB_GROUP("Unit & Service Analysis"); -VERB_SCOPE(, verb_verify, "verify", "FILE...", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_verify, "verify", "FILE...\0", 2, VERB_ANY, 0, "Check unit files for correctness"); -VERB_SCOPE(, verb_security, "security", "[UNIT...]", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_security, "security", "[UNIT...]\0", VERB_ANY, VERB_ANY, 0, "Analyze security of unit"); -VERB_SCOPE(, verb_fdstore, "fdstore", "SERVICE...", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_fdstore, "fdstore", "SERVICE...\0", 2, VERB_ANY, 0, "Show file descriptor store contents of service"); -VERB_SCOPE(, verb_malloc, "malloc", "[D-BUS SERVICE...]", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_malloc, "malloc", "[D-BUS SERVICE...]\0", VERB_ANY, VERB_ANY, 0, "Dump malloc stats of a D-Bus service"); -VERB_SCOPE(, verb_unit_gdb, "unit-gdb", "SERVICE", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_unit_gdb, "unit-gdb", "SERVICE\0", 2, VERB_ANY, 0, "Attach a debugger to the given running service"); -VERB_SCOPE(, verb_unit_shell, "unit-shell", "SERVICE [COMMAND ...]", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_unit_shell, "unit-shell", "SERVICE [COMMAND ...]\0", 2, VERB_ANY, 0, "Run command on the namespace of the service"); VERB_GROUP("Executable Analysis"); -VERB_SCOPE(, verb_elf_inspection, "inspect-elf", "FILE...", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_elf_inspection, "inspect-elf", "FILE...\0", 2, VERB_ANY, 0, "Parse and print ELF package metadata"); -VERB_SCOPE(, verb_dlopen_metadata, "dlopen-metadata", "FILE", 2, 2, 0, +VERB_SCOPE(, verb_dlopen_metadata, "dlopen-metadata", "FILE\0", 2, 2, 0, "Parse and print ELF dlopen metadata"); VERB_GROUP("TPM Operations"); @@ -291,11 +291,11 @@ VERB_SCOPE(, verb_has_tpm2, "has-tpm2", NULL, VERB_ANY, 1, 0, "Report whether TPM2 support is available"); VERB_SCOPE(, verb_identify_tpm2, "identify-tpm2", NULL, VERB_ANY, 1, 0, "Show TPM2 vendor information"); -VERB_SCOPE(, verb_pcrs, "pcrs", "[PCR...]", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_pcrs, "pcrs", "[PCR...]\0", VERB_ANY, VERB_ANY, 0, "Show TPM2 PCRs and their names"); -VERB_SCOPE(, verb_nvpcrs, "nvpcrs", "[NVPCR...]", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_nvpcrs, "nvpcrs", "[NVPCR...]\0", VERB_ANY, VERB_ANY, 0, "Show additional TPM2 PCRs stored in NV indexes"); -VERB_SCOPE(, verb_srk, "srk", "[>FILE]", VERB_ANY, 1, 0, +VERB_SCOPE(, verb_srk, "srk", "[>FILE]\0", VERB_ANY, 1, 0, "Write TPM2 SRK (to FILE)"); /* The following are deprecated and not shown in --help. */ diff --git a/src/backlight/backlight.c b/src/backlight/backlight.c index 6aad85a024..175a773dd7 100644 --- a/src/backlight/backlight.c +++ b/src/backlight/backlight.c @@ -530,7 +530,7 @@ static int device_new_from_arg(const char *s, sd_device **ret) { return 1; /* Found. */ } -VERB(verb_load, "load", "[backlight|leds]:DEVICE", 2, 2, VERB_ONLINE_ONLY, +VERB(verb_load, "load", "[backlight|leds]:DEVICE\0", 2, 2, VERB_ONLINE_ONLY, "Set brightness to be the previously saved value"); static int verb_load(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_device_unrefp) sd_device *device = NULL; @@ -582,7 +582,7 @@ static int verb_load(int argc, char *argv[], uintptr_t _data, void *userdata) { return 0; } -VERB(verb_save, "save", "[backlight|leds]:DEVICE", 2, 2, VERB_ONLINE_ONLY, +VERB(verb_save, "save", "[backlight|leds]:DEVICE\0", 2, 2, VERB_ONLINE_ONLY, "Save current brightness"); static int verb_save(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_device_unrefp) sd_device *device = NULL; diff --git a/src/bootctl/bootctl.c b/src/bootctl/bootctl.c index 5e41b46b10..a99ca237e9 100644 --- a/src/bootctl/bootctl.c +++ b/src/bootctl/bootctl.c @@ -302,7 +302,7 @@ VERB_GROUP("Generic EFI Firmware/Boot Loader Commands"); VERB_SCOPE(, verb_status, "status", NULL, VERB_ANY, 1, VERB_DEFAULT, "Show status of installed boot loader and EFI variables"); -VERB_SCOPE(, verb_reboot_to_firmware, "reboot-to-firmware", "[BOOL]", VERB_ANY, 2, 0, +VERB_SCOPE(, verb_reboot_to_firmware, "reboot-to-firmware", "[BOOL]\0", VERB_ANY, 2, 0, "Query or set reboot-to-firmware EFI flag"); VERB_GROUP("Boot Loader Specification Commands"); @@ -310,10 +310,10 @@ VERB_GROUP("Boot Loader Specification Commands"); VERB_SCOPE_NOARG(, verb_list, "list", "List boot loader entries"); -VERB_SCOPE(, verb_unlink, "unlink", "ID", VERB_ANY, 2, 0, +VERB_SCOPE(, verb_unlink, "unlink", "ID\0", VERB_ANY, 2, 0, "Remove boot loader entry"); -VERB_SCOPE(, verb_link, "link", "KERNEL", 2, 2, 0, +VERB_SCOPE(, verb_link, "link", "KERNEL\0", 2, 2, 0, "Create boot loader entry for specified kernel"); VERB_SCOPE_NOARG(, verb_link_auto, "link-auto", @@ -324,22 +324,22 @@ VERB_SCOPE_NOARG(, verb_cleanup, "cleanup", VERB_GROUP("Boot Loader Interface Commands"); -VERB_SCOPE(, verb_set_efivar, "set-default", "ID", 2, 2, 0, +VERB_SCOPE(, verb_set_efivar, "set-default", "ID\0", 2, 2, 0, "Set default boot loader entry"); -VERB_SCOPE(, verb_set_efivar, "set-oneshot", "ID", 2, 2, 0, +VERB_SCOPE(, verb_set_efivar, "set-oneshot", "ID\0", 2, 2, 0, "Set default boot loader entry, for next boot only"); -VERB_SCOPE(, verb_set_efivar, "set-sysfail", "ID", 2, 2, 0, +VERB_SCOPE(, verb_set_efivar, "set-sysfail", "ID\0", 2, 2, 0, "Set boot loader entry used in case of a system failure"); -VERB_SCOPE(, verb_set_efivar, "set-timeout", "SECONDS", 2, 2, 0, +VERB_SCOPE(, verb_set_efivar, "set-timeout", "SECONDS\0", 2, 2, 0, "Set the menu timeout"); -VERB_SCOPE(, verb_set_efivar, "set-timeout-oneshot", "SECONDS", 2, 2, 0, +VERB_SCOPE(, verb_set_efivar, "set-timeout-oneshot", "SECONDS\0", 2, 2, 0, "Set the menu timeout for the next boot only"); -VERB_SCOPE(, verb_set_efivar, "set-preferred", "ID", 2, 2, 0, +VERB_SCOPE(, verb_set_efivar, "set-preferred", "ID\0", 2, 2, 0, /* help= */ NULL); VERB_GROUP("systemd-boot Commands"); @@ -361,10 +361,10 @@ VERB_SCOPE_NOARG(, verb_random_seed, "random-seed", VERB_GROUP("Kernel Image Commands"); -VERB_SCOPE(, verb_kernel_identify, "kernel-identify", "KERNEL-IMAGE", 2, 2, 0, +VERB_SCOPE(, verb_kernel_identify, "kernel-identify", "KERNEL-IMAGE\0", 2, 2, 0, "Identify kernel image type"); -VERB_SCOPE(, verb_kernel_inspect, "kernel-inspect", "KERNEL-IMAGE", 2, 2, 0, +VERB_SCOPE(, verb_kernel_inspect, "kernel-inspect", "KERNEL-IMAGE\0", 2, 2, 0, "Prints details about the kernel image"); static int parse_argv(int argc, char *argv[], char ***ret_args) { diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c index ab784e2cdb..88eba5a512 100644 --- a/src/busctl/busctl.c +++ b/src/busctl/busctl.c @@ -547,7 +547,7 @@ static int tree_one(sd_bus *bus, const char *service) { return r; } -VERB(verb_tree, "tree", "[SERVICE…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_tree, "tree", "[SERVICE…]\0", VERB_ANY, VERB_ANY, 0, "Show object tree of service"); static int verb_tree(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -1008,7 +1008,7 @@ static int members_flags_to_string(const Member *m, char **ret) { return 0; } -VERB(verb_introspect, "introspect", "SERVICE OBJECT [INTERFACE]", 3, 4, 0, +VERB(verb_introspect, "introspect", "SERVICE OBJECT [INTERFACE]\0", 3, 4, 0, "Introspect an object"); static int verb_introspect(int argc, char *argv[], uintptr_t _data, void *userdata) { static const XMLIntrospectOps ops = { @@ -1391,13 +1391,13 @@ static int monitor(int argc, char **argv, int (*dump)(sd_bus_message *m, FILE *f } } -VERB(verb_monitor, "monitor", "[SERVICE…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_monitor, "monitor", "[SERVICE…]\0", VERB_ANY, VERB_ANY, 0, "Show bus traffic"); static int verb_monitor(int argc, char *argv[], uintptr_t _data, void *userdata) { return monitor(argc, argv, sd_json_format_enabled(arg_json_format_flags) ? message_json : message_dump); } -VERB(verb_capture, "capture", "[SERVICE…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_capture, "capture", "[SERVICE…]\0", VERB_ANY, VERB_ANY, 0, "Capture bus traffic as pcap"); static int verb_capture(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_free_ char *osname = NULL; @@ -1426,7 +1426,7 @@ static int verb_capture(int argc, char *argv[], uintptr_t _data, void *userdata) return r; } -VERB(verb_status, "status", "[SERVICE]", VERB_ANY, 2, 0, +VERB(verb_status, "status", "[SERVICE]\0", VERB_ANY, 2, 0, "Show bus service, process, or bus owner credentials"); static int verb_status(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -1798,7 +1798,7 @@ static int bus_message_dump(sd_bus_message *m, uint64_t flags) { return 0; } -VERB(verb_call, "call", "SERVICE OBJECT INTERFACE METHOD [SIGNATURE [ARGUMENT…]]", 5, VERB_ANY, 0, +VERB(verb_call, "call", "SERVICE OBJECT INTERFACE METHOD [SIGNATURE [ARGUMENT…]]\0", 5, VERB_ANY, 0, "Call a method"); static int verb_call(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -1867,7 +1867,7 @@ static int verb_call(int argc, char *argv[], uintptr_t _data, void *userdata) { return bus_message_dump(reply, /* flags= */ 0); } -VERB(verb_emit, "emit", "OBJECT INTERFACE SIGNAL [SIGNATURE [ARGUMENT…]]", 4, VERB_ANY, 0, +VERB(verb_emit, "emit", "OBJECT INTERFACE SIGNAL [SIGNATURE [ARGUMENT…]]\0", 4, VERB_ANY, 0, "Emit a signal"); static int verb_emit(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -1914,7 +1914,7 @@ static int verb_emit(int argc, char *argv[], uintptr_t _data, void *userdata) { return 0; } -VERB(verb_get_property, "get-property", "SERVICE OBJECT INTERFACE PROPERTY…", 5, VERB_ANY, 0, +VERB(verb_get_property, "get-property", "SERVICE OBJECT INTERFACE PROPERTY…\0", 5, VERB_ANY, 0, "Get property value"); static int verb_get_property(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -1974,7 +1974,7 @@ static int on_bus_signal(sd_bus_message *msg, void *userdata, sd_bus_error *ret_ return 0; } -VERB(verb_wait, "wait", "[SERVICE] OBJECT INTERFACE SIGNAL", 4, 5, 0, +VERB(verb_wait, "wait", "[SERVICE] OBJECT INTERFACE SIGNAL\0", 4, 5, 0, "Wait for a signal"); static int verb_wait(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -2024,7 +2024,7 @@ static int verb_wait(int argc, char *argv[], uintptr_t _data, void *userdata) { return sd_event_loop(e); } -VERB(verb_set_property, "set-property", "SERVICE OBJECT INTERFACE PROPERTY SIGNATURE ARGUMENT…", 6, VERB_ANY, 0, +VERB(verb_set_property, "set-property", "SERVICE OBJECT INTERFACE PROPERTY SIGNATURE ARGUMENT…\0", 6, VERB_ANY, 0, "Set property value"); static int verb_set_property(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; diff --git a/src/clonesetup/clonesetup.c b/src/clonesetup/clonesetup.c index 8827dfb98f..e84728534d 100644 --- a/src/clonesetup/clonesetup.c +++ b/src/clonesetup/clonesetup.c @@ -103,7 +103,7 @@ static int clone_device( return 0; } -VERB(verb_add, "add", "NAME SOURCE DEST METADATA [OPTIONS]", 5, 6, 0, "Create a dm-clone device"); +VERB(verb_add, "add", "NAME SOURCE DEST METADATA [OPTIONS]\0", 5, 6, 0, "Create a dm-clone device"); /* Arguments: systemd-clonesetup add NAME SOURCE DEST METADATA [OPTIONS] */ static int verb_add(int argc, char *argv[], uintptr_t data, void *userdata) { @@ -126,7 +126,7 @@ static int verb_add(int argc, char *argv[], uintptr_t data, void *userdata) { return clone_device(name, src, dst, meta, options); } -VERB(verb_remove, "remove", "NAME", 2, 2, 0, "Remove a dm-clone device"); +VERB(verb_remove, "remove", "NAME\0", 2, 2, 0, "Remove a dm-clone device"); static int verb_remove(int argc, char *argv[], uintptr_t data, void *userdata) { const char *name = ASSERT_PTR(argv[1]); diff --git a/src/coredump/coredumpctl.c b/src/coredump/coredumpctl.c index 1ceddf33de..14f2b33b9c 100644 --- a/src/coredump/coredumpctl.c +++ b/src/coredump/coredumpctl.c @@ -214,15 +214,15 @@ static int parse_argv(int argc, char *argv[], char ***remaining_args) { return 1; } -VERB_SCOPE(, verb_dump_list, "list", "[MATCHES…]", VERB_ANY, VERB_ANY, VERB_DEFAULT, +VERB_SCOPE(, verb_dump_list, "list", "[MATCHES…]\0", VERB_ANY, VERB_ANY, VERB_DEFAULT, "List available coredumps"); -VERB_SCOPE(, verb_dump_list, "info", "[MATCHES…]", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_dump_list, "info", "[MATCHES…]\0", VERB_ANY, VERB_ANY, 0, "Show detailed information about one or more coredumps"); -VERB_SCOPE(, verb_dump_core, "dump", "[MATCHES…]", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_dump_core, "dump", "[MATCHES…]\0", VERB_ANY, VERB_ANY, 0, "Print first matching coredump to stdout"); -VERB_SCOPE(, verb_run_debug, "debug", "[MATCHES…]", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_run_debug, "debug", "[MATCHES…]\0", VERB_ANY, VERB_ANY, 0, "Start a debugger for the first matching coredump"); -VERB_SCOPE(, verb_run_debug, "gdb", "[MATCHES…]", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_run_debug, "gdb", "[MATCHES…]\0", VERB_ANY, VERB_ANY, 0, /* help= */ NULL); static int check_units_active(void) { diff --git a/src/creds/creds.c b/src/creds/creds.c index 97143030cb..cc6906ae1b 100644 --- a/src/creds/creds.c +++ b/src/creds/creds.c @@ -473,7 +473,7 @@ static int write_blob(FILE *f, const void *data, size_t size) { return 0; } -VERB(verb_cat, "cat", "CREDENTIAL...", 2, VERB_ANY, 0, +VERB(verb_cat, "cat", "CREDENTIAL...\0", 2, VERB_ANY, 0, "Show contents of specified credentials"); static int verb_cat(int argc, char *argv[], uintptr_t _data, void *userdata) { usec_t timestamp; @@ -561,7 +561,7 @@ static int verb_cat(int argc, char *argv[], uintptr_t _data, void *userdata) { return ret; } -VERB(verb_encrypt, "encrypt", "INPUT OUTPUT", 3, 3, 0, +VERB(verb_encrypt, "encrypt", "INPUT OUTPUT\0", 3, 3, 0, "Encrypt plaintext credential file and write to ciphertext credential file"); static int verb_encrypt(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(iovec_done_erase) struct iovec plaintext = {}, output = {}; @@ -671,7 +671,7 @@ static int verb_encrypt(int argc, char *argv[], uintptr_t _data, void *userdata) return EXIT_SUCCESS; } -VERB(verb_decrypt, "decrypt", "INPUT [OUTPUT]", 2, 3, 0, +VERB(verb_decrypt, "decrypt", "INPUT [OUTPUT]\0", 2, 3, 0, "Decrypt ciphertext credential file and write to plaintext credential file"); static int verb_decrypt(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(iovec_done_erase) struct iovec input = {}, plaintext = {}; diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index 7f1ad550b3..fb616a3426 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -2484,7 +2484,7 @@ static int discover_key(const char *key_file, const char *volume, TokenType toke return r; } -VERB(verb_attach, "attach", "VOLUME SOURCE-DEVICE [KEY-FILE] [CONFIG]", 3, 5, 0, +VERB(verb_attach, "attach", "VOLUME SOURCE-DEVICE [KEY-FILE] [CONFIG]\0", 3, 5, 0, "Attach an encrypted block device"); static int verb_attach(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(crypt_freep) struct crypt_device *cd = NULL; @@ -2731,7 +2731,7 @@ static int verb_attach(int argc, char *argv[], uintptr_t _data, void *userdata) return 0; } -VERB(verb_detach, "detach", "VOLUME", 2, 2, 0, +VERB(verb_detach, "detach", "VOLUME\0", 2, 2, 0, "Detach an encrypted block device"); static int verb_detach(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(crypt_freep) struct crypt_device *cd = NULL; diff --git a/src/home/homectl.c b/src/home/homectl.c index 5fd6b18f62..0fcf210f93 100644 --- a/src/home/homectl.c +++ b/src/home/homectl.c @@ -711,7 +711,7 @@ static int inspect_home(sd_bus *bus, const char *name) { return 0; } -VERB(verb_inspect_homes, "inspect", "USER…", VERB_ANY, VERB_ANY, 0, +VERB(verb_inspect_homes, "inspect", "USER…\0", VERB_ANY, VERB_ANY, 0, "Inspect a home area"); static int verb_inspect_homes(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -1459,7 +1459,7 @@ static int create_home_common(sd_json_variant *input, bool show_enforce_password return 0; } -VERB(verb_create_home, "create", "USER", VERB_ANY, 2, 0, +VERB(verb_create_home, "create", "USER\0", VERB_ANY, 2, 0, "Create a home area"); static int verb_create_home(int argc, char *argv[], uintptr_t _data, void *userdata) { int r; @@ -1641,7 +1641,7 @@ static int home_record_reset_human_interaction_permission(UserRecord *hr) { return 0; } -VERB(verb_update_home, "update", "USER", VERB_ANY, 2, 0, +VERB(verb_update_home, "update", "USER\0", VERB_ANY, 2, 0, "Update a home area"); static int verb_update_home(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -1824,7 +1824,7 @@ static int verb_update_home(int argc, char *argv[], uintptr_t _data, void *userd return 0; } -VERB(verb_passwd_home, "passwd", "USER", VERB_ANY, 2, 0, +VERB(verb_passwd_home, "passwd", "USER\0", VERB_ANY, 2, 0, "Change password of a home area"); static int verb_passwd_home(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(user_record_unrefp) UserRecord *old_secret = NULL, *new_secret = NULL; @@ -1943,7 +1943,7 @@ static int parse_disk_size(const char *t, uint64_t *ret) { return 0; } -VERB(verb_resize_home, "resize", "USER SIZE", 2, 3, 0, +VERB(verb_resize_home, "resize", "USER SIZE\0", 2, 3, 0, "Resize a home area"); static int verb_resize_home(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -2007,7 +2007,7 @@ static int verb_resize_home(int argc, char *argv[], uintptr_t _data, void *userd return 0; } -VERB(verb_remove_home, "remove", "USER…", 2, VERB_ANY, 0, +VERB(verb_remove_home, "remove", "USER…\0", 2, VERB_ANY, 0, "Remove a home area"); static int verb_remove_home(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -2043,7 +2043,7 @@ static int verb_remove_home(int argc, char *argv[], uintptr_t _data, void *userd } VERB_GROUP("Advanced User Manipulation Commands"); -VERB(verb_activate_home, "activate", "USER…", 2, VERB_ANY, 0, +VERB(verb_activate_home, "activate", "USER…\0", 2, VERB_ANY, 0, "Activate a home area"); static int verb_activate_home(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -2093,7 +2093,7 @@ static int verb_activate_home(int argc, char *argv[], uintptr_t _data, void *use return ret; } -VERB(verb_deactivate_home, "deactivate", "USER…", 2, VERB_ANY, 0, +VERB(verb_deactivate_home, "deactivate", "USER…\0", 2, VERB_ANY, 0, "Deactivate a home area"); static int verb_deactivate_home(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -2168,7 +2168,7 @@ static int verb_deactivate_all_homes(int argc, char *argv[], uintptr_t _data, vo return 0; } -VERB(verb_with_home, "with", "USER [COMMAND…]", 2, VERB_ANY, 0, +VERB(verb_with_home, "with", "USER [COMMAND…]\0", 2, VERB_ANY, 0, "Run shell or command with access to a home area"); static int verb_with_home(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -2327,7 +2327,7 @@ static int authenticate_home(sd_bus *bus, const char *name) { } } -VERB(verb_authenticate_homes, "authenticate", "USER…", VERB_ANY, VERB_ANY, 0, +VERB(verb_authenticate_homes, "authenticate", "USER…\0", VERB_ANY, VERB_ANY, 0, "Authenticate a home area"); static int verb_authenticate_homes(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -2355,7 +2355,7 @@ static int verb_authenticate_homes(int argc, char *argv[], uintptr_t _data, void } VERB_GROUP("User Migration Commands"); -VERB(verb_adopt_home, "adopt", "PATH…", VERB_ANY, VERB_ANY, 0, +VERB(verb_adopt_home, "adopt", "PATH…\0", VERB_ANY, VERB_ANY, 0, "Add an existing home area on this system"); static int verb_adopt_home(int argc, char *argv[], uintptr_t _data, void *userdata) { int r, ret = 0; @@ -2439,7 +2439,7 @@ static int register_home_one(sd_bus *bus, FILE *f, const char *path) { return register_home_common(bus, v); } -VERB(verb_register_home, "register", "PATH…", VERB_ANY, VERB_ANY, 0, +VERB(verb_register_home, "register", "PATH…\0", VERB_ANY, VERB_ANY, 0, "Register a user record locally"); static int verb_register_home(int argc, char *argv[], uintptr_t _data, void *userdata) { int r; @@ -2472,7 +2472,7 @@ static int verb_register_home(int argc, char *argv[], uintptr_t _data, void *use return r; } -VERB(verb_unregister_home, "unregister", "USER…", 2, VERB_ANY, 0, +VERB(verb_unregister_home, "unregister", "USER…\0", 2, VERB_ANY, 0, "Unregister a user record locally"); static int verb_unregister_home(int argc, char *argv[], uintptr_t _data, void *userdata) { int r; @@ -2597,7 +2597,7 @@ static int verb_list_signing_keys(int argc, char *argv[], uintptr_t _data, void return 0; } -VERB(verb_get_signing_key, "get-signing-key", "[NAME…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_get_signing_key, "get-signing-key", "[NAME…]\0", VERB_ANY, VERB_ANY, 0, "Get a named home signing key"); static int verb_get_signing_key(int argc, char *argv[], uintptr_t _data, void *userdata) { int r; @@ -2655,7 +2655,7 @@ static int add_signing_key_one(sd_bus *bus, const char *fn, FILE *key) { return 0; } -VERB(verb_add_signing_key, "add-signing-key", "FILE…", VERB_ANY, VERB_ANY, 0, +VERB(verb_add_signing_key, "add-signing-key", "FILE…\0", VERB_ANY, VERB_ANY, 0, "Add home signing key"); static int verb_add_signing_key(int argc, char *argv[], uintptr_t _data, void *userdata) { int r; @@ -2764,7 +2764,7 @@ static int remove_signing_key_one(sd_bus *bus, const char *fn) { return 0; } -VERB(verb_remove_signing_key, "remove-signing-key", "NAME…", 2, VERB_ANY, 0, +VERB(verb_remove_signing_key, "remove-signing-key", "NAME…\0", 2, VERB_ANY, 0, "Remove home signing key"); static int verb_remove_signing_key(int argc, char *argv[], uintptr_t _data, void *userdata) { int r; @@ -2782,7 +2782,7 @@ static int verb_remove_signing_key(int argc, char *argv[], uintptr_t _data, void } VERB_GROUP("Lock/Unlock Commands"); -VERB(verb_lock_home, "lock", "USER…", 2, VERB_ANY, 0, +VERB(verb_lock_home, "lock", "USER…\0", 2, VERB_ANY, 0, "Temporarily lock an active home area"); static int verb_lock_home(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -2815,7 +2815,7 @@ static int verb_lock_home(int argc, char *argv[], uintptr_t _data, void *userdat return ret; } -VERB(verb_unlock_home, "unlock", "USER…", 2, VERB_ANY, 0, +VERB(verb_unlock_home, "unlock", "USER…\0", 2, VERB_ANY, 0, "Unlock a temporarily locked home area"); static int verb_unlock_home(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; diff --git a/src/home/test-homectl-prompts.c b/src/home/test-homectl-prompts.c index 59bff32c44..5429eaaa5e 100644 --- a/src/home/test-homectl-prompts.c +++ b/src/home/test-homectl-prompts.c @@ -37,7 +37,7 @@ static int help(void) { return table_print_or_warn(options); } -VERB(verb_groups, "groups", "[USER]", VERB_ANY, 2, 0, "Select groups"); +VERB(verb_groups, "groups", "[USER]\0", VERB_ANY, 2, 0, "Select groups"); static int verb_groups(int argc, char *argv[], uintptr_t _data, void *userdata) { assert(argv); @@ -55,7 +55,7 @@ static int verb_groups(int argc, char *argv[], uintptr_t _data, void *userdata) return 0; } -VERB(verb_shell, "shell", "[USER]", VERB_ANY, 2, 0, "Select shell"); +VERB(verb_shell, "shell", "[USER]\0", VERB_ANY, 2, 0, "Select shell"); static int verb_shell(int argc, char *argv[], uintptr_t _data, void *userdata) { assert(argv); diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c index 6bc4d36217..274a2302da 100644 --- a/src/hostname/hostnamectl.c +++ b/src/hostname/hostnamectl.c @@ -710,42 +710,42 @@ static int verb_set_hostname(int argc, char *argv[], uintptr_t _data, void *user return ret; } -VERB(verb_get_or_set_hostname, "hostname", "[NAME]", VERB_ANY, 2, 0, "Get/set system hostname"); -VERB(verb_get_or_set_hostname, "set-hostname", "NAME", 2, 2, 0, NULL); /* obsolete */ +VERB(verb_get_or_set_hostname, "hostname", "[NAME]\0", VERB_ANY, 2, 0, "Get/set system hostname"); +VERB(verb_get_or_set_hostname, "set-hostname", "NAME\0", 2, 2, 0, NULL); /* obsolete */ static int verb_get_or_set_hostname(int argc, char *argv[], uintptr_t data, void *userdata) { return argc == 1 ? get_hostname_based_on_flag(userdata) : verb_set_hostname(argc, argv, data, userdata); } -VERB(verb_get_or_set_icon_name, "icon-name", "[NAME]", VERB_ANY, 2, 0, "Get/set icon name for host"); -VERB(verb_get_or_set_icon_name, "set-icon-name", "NAME", 2, 2, 0, NULL); /* obsolete */ +VERB(verb_get_or_set_icon_name, "icon-name", "[NAME]\0", VERB_ANY, 2, 0, "Get/set icon name for host"); +VERB(verb_get_or_set_icon_name, "set-icon-name", "NAME\0", 2, 2, 0, NULL); /* obsolete */ static int verb_get_or_set_icon_name(int argc, char *argv[], uintptr_t _data, void *userdata) { return argc == 1 ? get_one_name(userdata, "IconName", NULL) : set_simple_string(userdata, "icon", "SetIconName", argv[1]); } -VERB(verb_get_or_set_chassis, "chassis", "[NAME]", VERB_ANY, 2, 0, "Get/set chassis type for host"); -VERB(verb_get_or_set_chassis, "set-chassis", "NAME", 2, 2, 0, NULL); /* obsolete */ +VERB(verb_get_or_set_chassis, "chassis", "[NAME]\0", VERB_ANY, 2, 0, "Get/set chassis type for host"); +VERB(verb_get_or_set_chassis, "set-chassis", "NAME\0", 2, 2, 0, NULL); /* obsolete */ static int verb_get_or_set_chassis(int argc, char *argv[], uintptr_t _data, void *userdata) { return argc == 1 ? get_one_name(userdata, "Chassis", NULL) : set_simple_string(userdata, "chassis", "SetChassis", argv[1]); } -VERB(verb_get_or_set_deployment, "deployment", "[NAME]", VERB_ANY, 2, 0, "Get/set deployment environment for host"); -VERB(verb_get_or_set_deployment, "set-deployment", "NAME", 2, 2, 0, NULL); /* obsolete */ +VERB(verb_get_or_set_deployment, "deployment", "[NAME]\0", VERB_ANY, 2, 0, "Get/set deployment environment for host"); +VERB(verb_get_or_set_deployment, "set-deployment", "NAME\0", 2, 2, 0, NULL); /* obsolete */ static int verb_get_or_set_deployment(int argc, char *argv[], uintptr_t _data, void *userdata) { return argc == 1 ? get_one_name(userdata, "Deployment", NULL) : set_simple_string(userdata, "deployment", "SetDeployment", argv[1]); } -VERB(verb_get_or_set_location, "location", "[NAME]", VERB_ANY, 2, 0, "Get/set location for host"); -VERB(verb_get_or_set_location, "set-location", "NAME", 2, 2, 0, NULL); /* obsolete */ +VERB(verb_get_or_set_location, "location", "[NAME]\0", VERB_ANY, 2, 0, "Get/set location for host"); +VERB(verb_get_or_set_location, "set-location", "NAME\0", 2, 2, 0, NULL); /* obsolete */ static int verb_get_or_set_location(int argc, char *argv[], uintptr_t _data, void *userdata) { return argc == 1 ? get_one_name(userdata, "Location", NULL) : set_simple_string(userdata, "location", "SetLocation", argv[1]); } -VERB(verb_get_or_set_tags, "tags", "[TAG …]", VERB_ANY, VERB_ANY, 0, "Get/set machine tags for host"); +VERB(verb_get_or_set_tags, "tags", "[TAG …]\0", VERB_ANY, VERB_ANY, 0, "Get/set machine tags for host"); static int verb_get_or_set_tags(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus *bus = ASSERT_PTR(userdata); diff --git a/src/hwdb/hwdb.c b/src/hwdb/hwdb.c index d0b94493bc..68dbc5116e 100644 --- a/src/hwdb/hwdb.c +++ b/src/hwdb/hwdb.c @@ -20,7 +20,7 @@ COMMAND( .man_pages = "systemd-hwdb(8)\0", ); -VERB(verb_query, "query", "MODALIAS", 2, 2, 0, +VERB(verb_query, "query", "MODALIAS\0", 2, 2, 0, "Query database and print result"); static int verb_query(int argc, char *argv[], uintptr_t _data, void *userdata) { return hwdb_query(argv[1], arg_root); diff --git a/src/id128/id128.c b/src/id128/id128.c index defb4f756f..45f66c2782 100644 --- a/src/id128/id128.c +++ b/src/id128/id128.c @@ -175,7 +175,7 @@ static int show_one(Table **table, const char *name, sd_id128_t uuid, bool first arg_mode == ID128_PRINT_ID128 ? TABLE_ID128 : TABLE_UUID, uuid); } -VERB(verb_show, "show", "[NAME|UUID]", VERB_ANY, VERB_ANY, 0, "Print one or more UUIDs"); +VERB(verb_show, "show", "[NAME|UUID]\0", VERB_ANY, VERB_ANY, 0, "Print one or more UUIDs"); static int verb_show(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(table_unrefp) Table *table = NULL; int r; diff --git a/src/import/export.c b/src/import/export.c index 41d3d247e1..91949ae54c 100644 --- a/src/import/export.c +++ b/src/import/export.c @@ -49,7 +49,7 @@ static void on_tar_finished(TarExport *export, int error, void *userdata) { sd_event_exit(event, ABS(error)); } -VERB(verb_export_tar, "tar", "NAME [FILE]", 2, 3, 0, +VERB(verb_export_tar, "tar", "NAME [FILE]\0", 2, 3, 0, "Export a TAR image"); static int verb_export_tar(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(tar_export_unrefp) TarExport *export = NULL; @@ -132,7 +132,7 @@ static void on_raw_finished(RawExport *export, int error, void *userdata) { sd_event_exit(event, ABS(error)); } -VERB(verb_export_raw, "raw", "NAME [FILE]", 2, 3, 0, +VERB(verb_export_raw, "raw", "NAME [FILE]\0", 2, 3, 0, "Export a RAW image"); static int verb_export_raw(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(raw_export_unrefp) RawExport *export = NULL; diff --git a/src/import/import-fs.c b/src/import/import-fs.c index b1b9b637aa..d5cad89956 100644 --- a/src/import/import-fs.c +++ b/src/import/import-fs.c @@ -113,7 +113,7 @@ static int progress_bytes(uint64_t nbytes, uint64_t bps, void *userdata) { return 0; } -VERB(verb_import_fs, "run", "DIRECTORY [NAME]", 2, 3, 0, +VERB(verb_import_fs, "run", "DIRECTORY [NAME]\0", 2, 3, 0, "Import a directory"); static int verb_import_fs(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(rm_rf_subvolume_and_freep) char *temp_path = NULL; diff --git a/src/import/import.c b/src/import/import.c index 37eda8711f..190ad6079f 100644 --- a/src/import/import.c +++ b/src/import/import.c @@ -143,7 +143,7 @@ static void on_tar_finished(TarImport *import, int error, void *userdata) { sd_event_exit(event, ABS(error)); } -VERB(verb_tar, "tar", "FILE [NAME]", 2, 3, 0, "Import a TAR image"); +VERB(verb_tar, "tar", "FILE [NAME]\0", 2, 3, 0, "Import a TAR image"); static int verb_tar(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(tar_import_unrefp) TarImport *import = NULL; _cleanup_free_ char *ll = NULL, *normalized = NULL; @@ -213,7 +213,7 @@ static void on_raw_finished(RawImport *import, int error, void *userdata) { sd_event_exit(event, ABS(error)); } -VERB(verb_raw, "raw", "FILE [NAME]", 2, 3, 0, "Import a RAW image"); +VERB(verb_raw, "raw", "FILE [NAME]\0", 2, 3, 0, "Import a RAW image"); static int verb_raw(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(raw_import_unrefp) RawImport *import = NULL; _cleanup_free_ char *ll = NULL, *normalized = NULL; diff --git a/src/import/importctl.c b/src/import/importctl.c index 911799d188..59bfb89c11 100644 --- a/src/import/importctl.c +++ b/src/import/importctl.c @@ -268,7 +268,7 @@ static int transfer_image_common(sd_bus *bus, sd_bus_message *m) { return -r; } -VERB(verb_pull_tar, "pull-tar", "URL [NAME]", 2, 3, 0, "Download a TAR container image"); +VERB(verb_pull_tar, "pull-tar", "URL [NAME]\0", 2, 3, 0, "Download a TAR container image"); static int verb_pull_tar(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; _cleanup_free_ char *l = NULL, *ll = NULL; @@ -342,7 +342,7 @@ static int verb_pull_tar(int argc, char *argv[], uintptr_t _data, void *userdata return transfer_image_common(bus, m); } -VERB(verb_pull_raw, "pull-raw", "URL [NAME]", 2, 3, 0, "Download a RAW container or VM image"); +VERB(verb_pull_raw, "pull-raw", "URL [NAME]\0", 2, 3, 0, "Download a RAW container or VM image"); static int verb_pull_raw(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; _cleanup_free_ char *l = NULL, *ll = NULL; @@ -416,7 +416,7 @@ static int verb_pull_raw(int argc, char *argv[], uintptr_t _data, void *userdata return transfer_image_common(bus, m); } -VERB(verb_pull_oci, "pull-oci", "REF [NAME]", 2, 3, 0, "Download an OCI container image"); +VERB(verb_pull_oci, "pull-oci", "REF [NAME]\0", 2, 3, 0, "Download an OCI container image"); static int verb_pull_oci(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; _cleanup_free_ char *l = NULL; @@ -472,7 +472,7 @@ static int verb_pull_oci(int argc, char *argv[], uintptr_t _data, void *userdata return transfer_image_common(bus, m); } -VERB(verb_import_tar, "import-tar", "FILE [NAME]", 2, 3, 0, "Import a local TAR container image"); +VERB(verb_import_tar, "import-tar", "FILE [NAME]\0", 2, 3, 0, "Import a local TAR container image"); static int verb_import_tar(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; _cleanup_free_ char *ll = NULL, *fn = NULL; @@ -552,7 +552,7 @@ static int verb_import_tar(int argc, char *argv[], uintptr_t _data, void *userda return transfer_image_common(bus, m); } -VERB(verb_import_raw, "import-raw", "FILE [NAME]", 2, 3, 0, "Import a local RAW container or VM image"); +VERB(verb_import_raw, "import-raw", "FILE [NAME]\0", 2, 3, 0, "Import a local RAW container or VM image"); static int verb_import_raw(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; _cleanup_free_ char *ll = NULL, *fn = NULL; @@ -632,7 +632,7 @@ static int verb_import_raw(int argc, char *argv[], uintptr_t _data, void *userda return transfer_image_common(bus, m); } -VERB(verb_import_fs, "import-fs", "DIRECTORY [NAME]", 2, 3, 0, "Import a local directory container image"); +VERB(verb_import_fs, "import-fs", "DIRECTORY [NAME]\0", 2, 3, 0, "Import a local directory container image"); static int verb_import_fs(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; const char *local = NULL, *path = NULL; @@ -720,7 +720,7 @@ static void determine_compression_from_filename(const char *p) { arg_format = "zstd"; } -VERB(verb_export_tar, "export-tar", "NAME [FILE]", 2, 3, 0, "Export a TAR container image locally"); +VERB(verb_export_tar, "export-tar", "NAME [FILE]\0", 2, 3, 0, "Export a TAR container image locally"); static int verb_export_tar(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; _cleanup_close_ int fd = -EBADF; @@ -780,7 +780,7 @@ static int verb_export_tar(int argc, char *argv[], uintptr_t _data, void *userda return transfer_image_common(bus, m); } -VERB(verb_export_raw, "export-raw", "NAME [FILE]", 2, 3, 0, "Export a RAW container or VM image locally"); +VERB(verb_export_raw, "export-raw", "NAME [FILE]\0", 2, 3, 0, "Export a RAW container or VM image locally"); static int verb_export_raw(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; _cleanup_close_ int fd = -EBADF; @@ -945,7 +945,7 @@ static int verb_list_transfers(int argc, char *argv[], uintptr_t _data, void *us return 0; } -VERB(verb_cancel_transfer, "cancel-transfer", "[ID...]", 2, VERB_ANY, 0, "Cancel a transfer"); +VERB(verb_cancel_transfer, "cancel-transfer", "[ID...]\0", 2, VERB_ANY, 0, "Cancel a transfer"); static int verb_cancel_transfer(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus *bus = ASSERT_PTR(userdata); diff --git a/src/import/pull.c b/src/import/pull.c index 3960a6e683..7f5a90196f 100644 --- a/src/import/pull.c +++ b/src/import/pull.c @@ -123,7 +123,7 @@ static void on_tar_finished(TarPull *pull, int error, void *userdata) { sd_event_exit(event, ABS(error)); } -VERB(verb_tar, "tar", "URL [NAME]", 2, 3, 0, "Download a TAR image"); +VERB(verb_tar, "tar", "URL [NAME]\0", 2, 3, 0, "Download a TAR image"); static int verb_tar(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_free_ char *ll = NULL, *normalized = NULL; _cleanup_(sd_event_unrefp) sd_event *event = NULL; @@ -194,7 +194,7 @@ static void on_raw_finished(RawPull *pull, int error, void *userdata) { sd_event_exit(event, ABS(error)); } -VERB(verb_raw, "raw", "URL [NAME]", 2, 3, 0, "Download a RAW image"); +VERB(verb_raw, "raw", "URL [NAME]\0", 2, 3, 0, "Download a RAW image"); static int verb_raw(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_free_ char *ll = NULL, *normalized = NULL; _cleanup_(sd_event_unrefp) sd_event *event = NULL; @@ -264,7 +264,7 @@ static void on_oci_finished(OciPull *pull, int error, void *userdata) { sd_event_exit(event, ABS(error)); } -VERB(verb_oci, "oci", "REF [NAME]", 2, 3, 0, "Download an OCI image"); +VERB(verb_oci, "oci", "REF [NAME]\0", 2, 3, 0, "Download an OCI image"); static int verb_oci(int argc, char *argv[], uintptr_t _data, void *userdata) { int r; diff --git a/src/integritysetup/integritysetup.c b/src/integritysetup/integritysetup.c index 742c1c7e05..0160b62ef4 100644 --- a/src/integritysetup/integritysetup.c +++ b/src/integritysetup/integritysetup.c @@ -82,7 +82,7 @@ static const char *integrity_algorithm_select(const void *key_file_buf) { return dm_integrity_algorithm_to_string(a); } -VERB(verb_attach, "attach", "VOLUME DEVICE [HMAC_KEY_FILE|-] [OPTIONS]", 3, 5, 0, +VERB(verb_attach, "attach", "VOLUME DEVICE [HMAC_KEY_FILE|-] [OPTIONS]\0", 3, 5, 0, "Attach an integrity protected block device"); static int verb_attach(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(crypt_freep) struct crypt_device *cd = NULL; @@ -151,7 +151,7 @@ static int verb_attach(int argc, char *argv[], uintptr_t _data, void *userdata) return 0; } -VERB(verb_detach, "detach", "VOLUME", 2, 2, 0, +VERB(verb_detach, "detach", "VOLUME\0", 2, 2, 0, "Detach an integrity protected block device"); static int verb_detach(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(crypt_freep) struct crypt_device *cd = NULL; diff --git a/src/kernel-install/kernel-install.c b/src/kernel-install/kernel-install.c index 4bae8cb1e5..0fb3a4034e 100644 --- a/src/kernel-install/kernel-install.c +++ b/src/kernel-install/kernel-install.c @@ -1281,7 +1281,7 @@ static int do_add( return context_execute(c); } -VERB(verb_add, "add", "[[[KERNEL-VERSION] KERNEL-IMAGE] [INITRD ...]]", 1, VERB_ANY, 0, +VERB(verb_add, "add", "[[[KERNEL-VERSION] KERNEL-IMAGE] [INITRD ...]]\0", 1, VERB_ANY, 0, "Add a kernel and initrd images to the boot partition"); static int verb_add(int argc, char *argv[], uintptr_t _data, void *userdata) { const char *version, *kernel; @@ -1394,7 +1394,7 @@ static int run_as_installkernel(char **args) { return verb_add(3, STRV_MAKE("add", args[0], args[1]), /* data= */ 0, /* userdata= */ NULL); } -VERB(verb_remove, "remove", "KERNEL-VERSION", 2, VERB_ANY, 0, +VERB(verb_remove, "remove", "KERNEL-VERSION\0", 2, VERB_ANY, 0, "Remove a kernel from the boot partition"); static int verb_remove(int argc, char *argv[], uintptr_t _data, void *userdata) { int r; @@ -1432,7 +1432,7 @@ static int verb_remove(int argc, char *argv[], uintptr_t _data, void *userdata) return context_execute(&c); } -VERB(verb_inspect, "inspect", "[[[KERNEL-VERSION] KERNEL-IMAGE] [INITRD ...]]", 1, VERB_ANY, VERB_DEFAULT, +VERB(verb_inspect, "inspect", "[[[KERNEL-VERSION] KERNEL-IMAGE] [INITRD ...]]\0", 1, VERB_ANY, VERB_DEFAULT, "Print details about the installation"); static int verb_inspect(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(table_unrefp) Table *t = NULL; diff --git a/src/locale/localectl.c b/src/locale/localectl.c index 09c706553e..b8e434ec0d 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -186,7 +186,7 @@ static int verb_show_status(int argc, char *argv[], uintptr_t _data, void *userd return print_status_info(&info); } -VERB(verb_set_locale, "set-locale", "LOCALE...", 2, VERB_ANY, 0, +VERB(verb_set_locale, "set-locale", "LOCALE...\0", 2, VERB_ANY, 0, "Set system locale"); static int verb_set_locale(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; @@ -232,7 +232,7 @@ static int verb_list_locales(int argc, char *argv[], uintptr_t _data, void *user return 0; } -VERB(verb_set_vconsole_keymap, "set-keymap", "MAP [MAP]", 2, 3, 0, +VERB(verb_set_vconsole_keymap, "set-keymap", "MAP [MAP]\0", 2, 3, 0, "Set console and X11 keyboard mappings"); static int verb_set_vconsole_keymap(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -275,7 +275,7 @@ static int verb_list_vconsole_keymaps(int argc, char *argv[], uintptr_t _data, v return 0; } -VERB(verb_set_x11_keymap, "set-x11-keymap", "LAYOUT [MODEL [VARIANT [OPTIONS]]]", 2, 5, 0, +VERB(verb_set_x11_keymap, "set-x11-keymap", "LAYOUT [MODEL [VARIANT [OPTIONS]]]\0", 2, 5, 0, "Set X11 and console keyboard mappings"); static int verb_set_x11_keymap(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -316,7 +316,7 @@ VERB_NOARG(verb_list_x11_keymaps, "list-x11-keymap-models", "Show known X11 keyboard mapping models"); VERB_NOARG(verb_list_x11_keymaps, "list-x11-keymap-layouts", "Show known X11 keyboard mapping layouts"); -VERB(verb_list_x11_keymaps, "list-x11-keymap-variants", "[LAYOUT]", VERB_ANY, 2, 0, +VERB(verb_list_x11_keymaps, "list-x11-keymap-variants", "[LAYOUT]\0", VERB_ANY, 2, 0, "Show known X11 keyboard mapping variants"); VERB_NOARG(verb_list_x11_keymaps, "list-x11-keymap-options", "Show known X11 keyboard mapping options"); diff --git a/src/login/loginctl.c b/src/login/loginctl.c index 67d7429749..8814b20234 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -930,9 +930,9 @@ static int get_bus_path_by_id( return strdup_to(ret, path); } -VERB(verb_show_session, "session-status", "[ID…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_show_session, "session-status", "[ID…]\0", VERB_ANY, VERB_ANY, 0, "Show session status"); -VERB(verb_show_session, "show-session", "[ID…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_show_session, "show-session", "[ID…]\0", VERB_ANY, VERB_ANY, 0, "Show properties of sessions or the manager"); static int verb_show_session(int argc, char *argv[], uintptr_t _data, void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); @@ -980,11 +980,11 @@ static int verb_show_session(int argc, char *argv[], uintptr_t _data, void *user return 0; } -VERB(verb_activate, "activate", "[ID]", VERB_ANY, 2, 0, +VERB(verb_activate, "activate", "[ID]\0", VERB_ANY, 2, 0, "Activate a session"); -VERB(verb_activate, "lock-session", "[ID…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_activate, "lock-session", "[ID…]\0", VERB_ANY, VERB_ANY, 0, "Screen lock one or more sessions"); -VERB(verb_activate, "unlock-session", "[ID…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_activate, "unlock-session", "[ID…]\0", VERB_ANY, VERB_ANY, 0, "Screen unlock one or more sessions"); static int verb_activate(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -1053,10 +1053,10 @@ static int verb_lock_sessions(int argc, char *argv[], uintptr_t _data, void *use } /* The implementation is above, but we put this here to preserve the logical order in --help. */ -VERB(verb_activate, "terminate-session", "ID…", 2, VERB_ANY, 0, +VERB(verb_activate, "terminate-session", "ID…\0", 2, VERB_ANY, 0, "Terminate one or more sessions"); -VERB(verb_kill_session, "kill-session", "ID…", 2, VERB_ANY, 0, +VERB(verb_kill_session, "kill-session", "ID…\0", 2, VERB_ANY, 0, "Send signal to processes of a session"); static int verb_kill_session(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -1163,9 +1163,9 @@ static int verb_list_users(int argc, char *argv[], uintptr_t _data, void *userda return list_table_print(table, "users"); } -VERB(verb_show_user, "user-status", "[USER…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_show_user, "user-status", "[USER…]\0", VERB_ANY, VERB_ANY, 0, "Show user status"); -VERB(verb_show_user, "show-user", "[USER…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_show_user, "show-user", "[USER…]\0", VERB_ANY, VERB_ANY, 0, "Show properties of users or the manager"); static int verb_show_user(int argc, char *argv[], uintptr_t _data, void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); @@ -1218,9 +1218,9 @@ static int verb_show_user(int argc, char *argv[], uintptr_t _data, void *userdat return 0; } -VERB(verb_enable_linger, "enable-linger", "[USER…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_enable_linger, "enable-linger", "[USER…]\0", VERB_ANY, VERB_ANY, 0, "Enable linger state of one or more users"); -VERB(verb_enable_linger, "disable-linger", "[USER…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_enable_linger, "disable-linger", "[USER…]\0", VERB_ANY, VERB_ANY, 0, "Disable linger state of one or more users"); static int verb_enable_linger(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -1270,7 +1270,7 @@ static int verb_enable_linger(int argc, char *argv[], uintptr_t _data, void *use return 0; } -VERB(verb_terminate_user, "terminate-user", "USER…", 2, VERB_ANY, 0, +VERB(verb_terminate_user, "terminate-user", "USER…\0", 2, VERB_ANY, 0, "Terminate all sessions of one or more users"); static int verb_terminate_user(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -1300,7 +1300,7 @@ static int verb_terminate_user(int argc, char *argv[], uintptr_t _data, void *us return 0; } -VERB(verb_kill_user, "kill-user", "USER…", 2, VERB_ANY, 0, +VERB(verb_kill_user, "kill-user", "USER…\0", 2, VERB_ANY, 0, "Send signal to processes of a user"); static int verb_kill_user(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -1385,9 +1385,9 @@ static int verb_list_seats(int argc, char *argv[], uintptr_t _data, void *userda return list_table_print(table, "seats"); } -VERB(verb_show_seat, "seat-status", "[NAME…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_show_seat, "seat-status", "[NAME…]\0", VERB_ANY, VERB_ANY, 0, "Show seat status"); -VERB(verb_show_seat, "show-seat", "[NAME…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_show_seat, "show-seat", "[NAME…]\0", VERB_ANY, VERB_ANY, 0, "Show properties of seats or the manager"); static int verb_show_seat(int argc, char *argv[], uintptr_t _data, void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); @@ -1435,7 +1435,7 @@ static int verb_show_seat(int argc, char *argv[], uintptr_t _data, void *userdat return 0; } -VERB(verb_attach, "attach", "NAME DEVICE…", 3, VERB_ANY, 0, +VERB(verb_attach, "attach", "NAME DEVICE…\0", 3, VERB_ANY, 0, "Attach one or more devices to a seat"); static int verb_attach(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -1478,7 +1478,7 @@ static int verb_flush_devices(int argc, char *argv[], uintptr_t _data, void *use return 0; } -VERB(verb_terminate_seat, "terminate-seat", "NAME…", 2, VERB_ANY, 0, +VERB(verb_terminate_seat, "terminate-seat", "NAME…\0", 2, VERB_ANY, 0, "Terminate all sessions on one or more seats"); static int verb_terminate_seat(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index 34111e3a5d..716f23c6de 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -702,9 +702,9 @@ static int show_machine_properties(sd_bus *bus, const char *path, bool *new_line return r; } -VERB(verb_show_machine, "status", "NAME…", 2, VERB_ANY, 0, +VERB(verb_show_machine, "status", "NAME…\0", 2, VERB_ANY, 0, "Show VM/container details"); -VERB(verb_show_machine, "show", "[NAME…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_show_machine, "show", "[NAME…]\0", VERB_ANY, VERB_ANY, 0, "Show properties of one or more VMs/containers"); static int verb_show_machine(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -782,7 +782,7 @@ static int image_exists(sd_bus *bus, const char *name) { return 1; } -VERB(verb_start_machine, "start", "NAME…", 2, VERB_ANY, 0, +VERB(verb_start_machine, "start", "NAME…\0", 2, VERB_ANY, 0, "Start container as a service"); static int verb_start_machine(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -951,7 +951,7 @@ static int on_machine_removed(sd_bus_message *m, void *userdata, sd_bus_error *r return 0; } -VERB(verb_login_machine, "login", "[NAME]", VERB_ANY, 2, 0, +VERB(verb_login_machine, "login", "[NAME]\0", VERB_ANY, 2, 0, "Get a login prompt in a container or on the local host"); static int verb_login_machine(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; @@ -1004,7 +1004,7 @@ static int verb_login_machine(int argc, char *argv[], uintptr_t _data, void *use return process_forward(event, slot, master, PTY_FORWARD_IGNORE_VHANGUP, machine); } -VERB(verb_shell_machine, "shell", "[[USER@]NAME [COMMAND…]]", VERB_ANY, VERB_ANY, 0, +VERB(verb_shell_machine, "shell", "[[USER@]NAME [COMMAND…]]\0", VERB_ANY, VERB_ANY, 0, "Invoke a shell (or other command) in a container or on the local host"); static int verb_shell_machine(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL, *m = NULL; @@ -1096,9 +1096,9 @@ static int verb_shell_machine(int argc, char *argv[], uintptr_t _data, void *use static int verb_poweroff_machine(int argc, char *argv[], uintptr_t data, void *userdata); -VERB(verb_enable_machine, "enable", "NAME…", 2, VERB_ANY, 0, +VERB(verb_enable_machine, "enable", "NAME…\0", 2, VERB_ANY, 0, "Enable automatic container start at boot"); -VERB(verb_enable_machine, "disable", "NAME…", 2, VERB_ANY, 0, +VERB(verb_enable_machine, "disable", "NAME…\0", 2, VERB_ANY, 0, "Disable automatic container start at boot"); static int verb_enable_machine(int argc, char *argv[], uintptr_t data, void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; @@ -1267,9 +1267,9 @@ static int verb_machine_control_one(const char *machine_name, const char *method return 0; } -VERB(verb_poweroff_machine, "poweroff", "NAME…", 2, VERB_ANY, 0, +VERB(verb_poweroff_machine, "poweroff", "NAME…\0", 2, VERB_ANY, 0, "Power off one or more machines"); -VERB(verb_poweroff_machine, "stop", "NAME…", 2, VERB_ANY, 0, +VERB(verb_poweroff_machine, "stop", "NAME…\0", 2, VERB_ANY, 0, /* help= */ NULL); /* Convenience alias */ static int verb_poweroff_machine(int argc, char *argv[], uintptr_t data, void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); @@ -1296,9 +1296,9 @@ static int verb_poweroff_machine(int argc, char *argv[], uintptr_t data, void *u return 0; } -VERB(verb_reboot_machine, "reboot", "NAME…", 2, VERB_ANY, 0, +VERB(verb_reboot_machine, "reboot", "NAME…\0", 2, VERB_ANY, 0, "Reboot one or more machines"); -VERB(verb_reboot_machine, "restart", "NAME…", 2, VERB_ANY, 0, +VERB(verb_reboot_machine, "restart", "NAME…\0", 2, VERB_ANY, 0, /* help= */ NULL); /* Convenience alias */ static int verb_reboot_machine(int argc, char *argv[], uintptr_t data, void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); @@ -1338,19 +1338,19 @@ static int verb_vm_control(int argc, char *argv[], const char *method) { return 0; } -VERB(verb_pause, "pause", "NAME…", 2, VERB_ANY, 0, +VERB(verb_pause, "pause", "NAME…\0", 2, VERB_ANY, 0, "Pause one or more machines"); static int verb_pause(int argc, char *argv[], uintptr_t _data, void *userdata) { return verb_vm_control(argc, argv, "io.systemd.MachineInstance.Pause"); } -VERB(verb_resume, "resume", "NAME…", 2, VERB_ANY, 0, +VERB(verb_resume, "resume", "NAME…\0", 2, VERB_ANY, 0, "Resume one or more paused machines"); static int verb_resume(int argc, char *argv[], uintptr_t _data, void *userdata) { return verb_vm_control(argc, argv, "io.systemd.MachineInstance.Resume"); } -VERB(verb_terminate_machine, "terminate", "NAME…", 2, VERB_ANY, 0, +VERB(verb_terminate_machine, "terminate", "NAME…\0", 2, VERB_ANY, 0, "Terminate one or more machines"); static int verb_terminate_machine(int argc, char *argv[], uintptr_t _data, void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); @@ -1376,7 +1376,7 @@ static int verb_terminate_machine(int argc, char *argv[], uintptr_t _data, void return 0; } -VERB(verb_kill_machine, "kill", "NAME…", 2, VERB_ANY, 0, +VERB(verb_kill_machine, "kill", "NAME…\0", 2, VERB_ANY, 0, "Send signal to processes of a machine"); static int verb_kill_machine(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -1410,9 +1410,9 @@ static const char* select_copy_method(bool copy_from, bool force) { return copy_from ? "CopyFromMachine" : "CopyToMachine"; } -VERB(verb_copy_files, "copy-to", "NAME PATH [PATH]", 3, 4, 0, +VERB(verb_copy_files, "copy-to", "NAME PATH [PATH]\0", 3, 4, 0, "Copy files from the host to a container"); -VERB(verb_copy_files, "copy-from", "NAME PATH [PATH]", 3, 4, 0, +VERB(verb_copy_files, "copy-from", "NAME PATH [PATH]\0", 3, 4, 0, "Copy files from a container to the host"); static int verb_copy_files(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -1469,7 +1469,7 @@ static int verb_copy_files(int argc, char *argv[], uintptr_t _data, void *userda return 0; } -VERB(verb_bind_mount, "bind", "NAME PATH [PATH]", 3, 4, 0, +VERB(verb_bind_mount, "bind", "NAME PATH [PATH]\0", 3, 4, 0, "Bind mount a path from the host into a container"); static int verb_bind_mount(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -1808,9 +1808,9 @@ static int show_image_properties(sd_bus *bus, const char *path, bool *new_line) return r; } -VERB(verb_show_image, "image-status", "[NAME…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_show_image, "image-status", "[NAME…]\0", VERB_ANY, VERB_ANY, 0, "Show image details"); -VERB(verb_show_image, "show-image", "[NAME…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_show_image, "show-image", "[NAME…]\0", VERB_ANY, VERB_ANY, 0, "Show properties of image"); static int verb_show_image(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -1896,7 +1896,7 @@ static int get_settings_path(const char *name, char **ret_path) { return -ENOENT; } -VERB(verb_edit_settings, "edit", "NAME|FILE…", 2, VERB_ANY, 0, +VERB(verb_edit_settings, "edit", "NAME|FILE…\0", 2, VERB_ANY, 0, "Edit settings of one or more VMs/containers"); static int verb_edit_settings(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(edit_file_context_done) EditFileContext context = {}; @@ -1968,7 +1968,7 @@ static int verb_edit_settings(int argc, char *argv[], uintptr_t _data, void *use return do_edit_files_and_install(&context); } -VERB(verb_cat_settings, "cat", "NAME|FILE…", 2, VERB_ANY, 0, +VERB(verb_cat_settings, "cat", "NAME|FILE…\0", 2, VERB_ANY, 0, "Show settings of one or more VMs/containers"); static int verb_cat_settings(int argc, char *argv[], uintptr_t _data, void *userdata) { int r = 0; @@ -2021,7 +2021,7 @@ static int verb_cat_settings(int argc, char *argv[], uintptr_t _data, void *user return r; } -VERB(verb_clone_image, "clone", "NAME NAME", 3, 3, 0, +VERB(verb_clone_image, "clone", "NAME NAME\0", 3, 3, 0, "Clone an image"); static int verb_clone_image(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -2047,7 +2047,7 @@ static int verb_clone_image(int argc, char *argv[], uintptr_t _data, void *userd return 0; } -VERB(verb_rename_image, "rename", "NAME NAME", 3, 3, 0, +VERB(verb_rename_image, "rename", "NAME NAME\0", 3, 3, 0, "Rename an image"); static int verb_rename_image(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -2069,7 +2069,7 @@ static int verb_rename_image(int argc, char *argv[], uintptr_t _data, void *user return 0; } -VERB(verb_read_only_image, "read-only", "NAME [BOOL]", 2, 3, 0, +VERB(verb_read_only_image, "read-only", "NAME [BOOL]\0", 2, 3, 0, "Mark or unmark image read-only"); static int verb_read_only_image(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -2093,7 +2093,7 @@ static int verb_read_only_image(int argc, char *argv[], uintptr_t _data, void *u return 0; } -VERB(verb_remove_image, "remove", "NAME…", 2, VERB_ANY, 0, +VERB(verb_remove_image, "remove", "NAME…\0", 2, VERB_ANY, 0, "Remove an image"); static int verb_remove_image(int argc, char *argv[], uintptr_t _data, void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); @@ -2122,7 +2122,7 @@ static int verb_remove_image(int argc, char *argv[], uintptr_t _data, void *user return 0; } -VERB(verb_set_limit, "set-limit", "[NAME] BYTES", 2, 3, 0, +VERB(verb_set_limit, "set-limit", "[NAME] BYTES\0", 2, 3, 0, "Set image or pool size limit (disk quota)"); static int verb_set_limit(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -2210,7 +2210,7 @@ static int verb_clean_images(int argc, char *argv[], uintptr_t _data, void *user return 0; } -VERB(verb_bind_volume, "bind-volume", "MACHINE PROVIDER:VOLUME[:…]", 3, 3, 0, +VERB(verb_bind_volume, "bind-volume", "MACHINE PROVIDER:VOLUME[:…]\0", 3, 3, 0, "Attach a volume to a running machine"); static int verb_bind_volume(int argc, char *argv[], uintptr_t _data, void *userdata) { int r; @@ -2282,7 +2282,7 @@ static int verb_bind_volume(int argc, char *argv[], uintptr_t _data, void *userd return 0; } -VERB(verb_unbind_volume, "unbind-volume", "MACHINE PROVIDER:VOLUME", 3, 3, 0, +VERB(verb_unbind_volume, "unbind-volume", "MACHINE PROVIDER:VOLUME\0", 3, 3, 0, "Detach a volume from a running machine"); static int verb_unbind_volume(int argc, char *argv[], uintptr_t _data, void *userdata) { int r; diff --git a/src/network/networkctl.c b/src/network/networkctl.c index 0268471392..3785664ea6 100644 --- a/src/network/networkctl.c +++ b/src/network/networkctl.c @@ -45,39 +45,39 @@ COMMAND( .pager_flags = &arg_pager_flags, ); -VERB_SCOPE(, verb_list_links, "list", "[PATTERN...]", VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_list_links, "list", "[PATTERN...]\0", VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, "List links"); -VERB_SCOPE(, verb_link_status, "status", "[PATTERN...]", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_link_status, "status", "[PATTERN...]\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "Show link status"); -VERB_SCOPE(, verb_dhcp_lease, "dhcp-lease", "INTERFACE [CODE[:FORMAT]...]", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_dhcp_lease, "dhcp-lease", "INTERFACE [CODE[:FORMAT]...]\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Show DHCP lease"); -VERB_SCOPE(, verb_link_lldp_status, "lldp", "[PATTERN...]", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_link_lldp_status, "lldp", "[PATTERN...]\0", VERB_ANY, VERB_ANY, 0, "Show LLDP neighbors"); VERB_SCOPE(, verb_list_address_labels, "label", NULL, 1, 1, 0, "Show current address label entries in the kernel"); -VERB_SCOPE(, verb_link_delete, "delete", "DEVICES...", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_link_delete, "delete", "DEVICES...\0", 2, VERB_ANY, 0, "Delete virtual netdevs"); -VERB_SCOPE(, verb_link_varlink_simple_method, "up", "DEVICES...", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_link_varlink_simple_method, "up", "DEVICES...\0", 2, VERB_ANY, 0, "Bring devices up"); -VERB_SCOPE(, verb_link_varlink_simple_method, "down", "DEVICES...", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_link_varlink_simple_method, "down", "DEVICES...\0", 2, VERB_ANY, 0, "Bring devices down"); -VERB_SCOPE(, verb_link_varlink_simple_method, "renew", "DEVICES...", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_link_varlink_simple_method, "renew", "DEVICES...\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Renew dynamic configurations"); -VERB_SCOPE(, verb_link_varlink_simple_method, "forcerenew", "DEVICES...", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_link_varlink_simple_method, "forcerenew", "DEVICES...\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Trigger DHCP reconfiguration of all connected clients"); -VERB_SCOPE(, verb_link_varlink_simple_method, "reconfigure", "DEVICES...", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_link_varlink_simple_method, "reconfigure", "DEVICES...\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Reconfigure interfaces"); VERB_SCOPE(, verb_reload, "reload", NULL, 1, 1, VERB_ONLINE_ONLY, "Reload .network and .netdev files"); -VERB_SCOPE(, verb_edit, "edit", "FILES|DEVICES...", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_edit, "edit", "FILES|DEVICES...\0", 2, VERB_ANY, 0, "Edit network configuration files"); -VERB_SCOPE(, verb_cat, "cat", "[FILES|DEVICES...]", 1, VERB_ANY, 0, +VERB_SCOPE(, verb_cat, "cat", "[FILES|DEVICES...]\0", 1, VERB_ANY, 0, "Show network configuration files"); -VERB_SCOPE(, verb_mask, "mask", "FILES...", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_mask, "mask", "FILES...\0", 2, VERB_ANY, 0, "Mask network configuration files"); -VERB_SCOPE(, verb_unmask, "unmask", "FILES...", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_unmask, "unmask", "FILES...\0", 2, VERB_ANY, 0, "Unmask network configuration files"); -VERB_SCOPE(, verb_persistent_storage, "persistent-storage", "BOOL", 2, 2, 0, +VERB_SCOPE(, verb_persistent_storage, "persistent-storage", "BOOL\0", 2, 2, 0, "Notify systemd-networkd if persistent storage is ready"); VERB_COMMON_HELP_AUTO_HIDDEN(); diff --git a/src/pcrlock/pcrlock.c b/src/pcrlock/pcrlock.c index 8803d087f3..4f5a384072 100644 --- a/src/pcrlock/pcrlock.c +++ b/src/pcrlock/pcrlock.c @@ -4733,7 +4733,7 @@ static int verb_unlock_secureboot_authority(int argc, char *argv[], uintptr_t _d return unlink_pcrlock(PCRLOCK_SECUREBOOT_AUTHORITY_PATH); } -VERB(verb_lock_gpt, "lock-gpt", "[DISK]", VERB_ANY, 2, 0, +VERB(verb_lock_gpt, "lock-gpt", "[DISK]\0", VERB_ANY, 2, 0, "Generate a .pcrlock file from GPT header"); static int verb_lock_gpt(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *array = NULL, *record = NULL; @@ -4912,7 +4912,7 @@ static int acquire_pe_fd(const char *path) { return acquire_stdin_pe_fd(); } -VERB(verb_lock_pe, "lock-pe", "[BINARY]", VERB_ANY, 2, 0, +VERB(verb_lock_pe, "lock-pe", "[BINARY]\0", VERB_ANY, 2, 0, "Generate a .pcrlock file from PE binary"); static int verb_lock_pe(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *array = NULL; @@ -4982,7 +4982,7 @@ static void section_hashes_array_done(SectionHashArray *array) { free((*array)[i]); } -VERB(verb_lock_uki, "lock-uki", "[UKI]", VERB_ANY, 2, 0, +VERB(verb_lock_uki, "lock-uki", "[UKI]\0", VERB_ANY, 2, 0, "Generate a .pcrlock file from UKI PE binary"); static int verb_lock_uki(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *array = NULL, *pe_digests = NULL; @@ -5136,7 +5136,7 @@ static int pcrlock_file_system_path(const char *normalized_path, char **ret) { return 0; } -VERB(verb_lock_file_system, "lock-file-system", "[PATH]", VERB_ANY, 2, 0, +VERB(verb_lock_file_system, "lock-file-system", "[PATH]\0", VERB_ANY, 2, 0, "Generate a .pcrlock file from current root fs + /var/"); static int verb_lock_file_system(int argc, char *argv[], uintptr_t _data, void *userdata) { const char* paths[3] = {}; @@ -5191,7 +5191,7 @@ static int verb_lock_file_system(int argc, char *argv[], uintptr_t _data, void * return 0; } -VERB(verb_unlock_file_system, "unlock-file-system", "[PATH]", VERB_ANY, 2, 0, +VERB(verb_unlock_file_system, "unlock-file-system", "[PATH]\0", VERB_ANY, 2, 0, "Remove .pcrlock file for root fs + /var/"); static int verb_unlock_file_system(int argc, char *argv[], uintptr_t _data, void *userdata) { const char* paths[3] = {}; @@ -5223,7 +5223,7 @@ static int verb_unlock_file_system(int argc, char *argv[], uintptr_t _data, void return 0; } -VERB(verb_lock_kernel_cmdline, "lock-kernel-cmdline", "[FILE]", VERB_ANY, 2, 0, +VERB(verb_lock_kernel_cmdline, "lock-kernel-cmdline", "[FILE]\0", VERB_ANY, 2, 0, "Generate a .pcrlock file from kernel command line"); static int verb_lock_kernel_cmdline(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *record = NULL, *array = NULL; @@ -5268,7 +5268,7 @@ static int verb_unlock_kernel_cmdline(int argc, char *argv[], uintptr_t _data, v return unlink_pcrlock(PCRLOCK_KERNEL_CMDLINE_PATH); } -VERB(verb_lock_kernel_initrd, "lock-kernel-initrd", "FILE", VERB_ANY, 2, 0, +VERB(verb_lock_kernel_initrd, "lock-kernel-initrd", "FILE\0", VERB_ANY, 2, 0, "Generate a .pcrlock file from an initrd file"); static int verb_lock_kernel_initrd(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *records = NULL; @@ -5299,7 +5299,7 @@ static int verb_unlock_kernel_initrd(int argc, char *argv[], uintptr_t _data, vo return unlink_pcrlock(PCRLOCK_KERNEL_INITRD_PATH); } -VERB(verb_lock_raw, "lock-raw", "[FILE]", VERB_ANY, 2, 0, +VERB(verb_lock_raw, "lock-raw", "[FILE]\0", VERB_ANY, 2, 0, "Generate a .pcrlock file from raw data"); static int verb_lock_raw(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *records = NULL; diff --git a/src/portable/portablectl.c b/src/portable/portablectl.c index d544b3022a..2aa0157b2a 100644 --- a/src/portable/portablectl.c +++ b/src/portable/portablectl.c @@ -474,7 +474,7 @@ static bool image_metadata_error_is_no_match(const sd_bus_error *error) { return sd_bus_error_has_name(error, BUS_ERROR_NO_MATCHING_UNIT_FILES); } -VERB(verb_inspect_image, "inspect", "NAME|PATH [PREFIX…]", 2, VERB_ANY, 0, +VERB(verb_inspect_image, "inspect", "NAME|PATH [PREFIX…]\0", 2, VERB_ANY, 0, "Show details of specified portable service image"); static int verb_inspect_image(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; @@ -1283,13 +1283,13 @@ static int attach_reattach_image(int argc, char *argv[], const char *method) { return 0; } -VERB(verb_attach_image, "attach", "NAME|PATH [PREFIX…]", 2, VERB_ANY, 0, +VERB(verb_attach_image, "attach", "NAME|PATH [PREFIX…]\0", 2, VERB_ANY, 0, "Attach the specified portable service image"); static int verb_attach_image(int argc, char *argv[], uintptr_t _data, void *userdata) { return attach_reattach_image(argc, argv, strv_isempty(arg_extension_images) && !arg_force ? "AttachImage" : "AttachImageWithExtensions"); } -VERB(verb_detach_image, "detach", "NAME|PATH [PREFIX…]", 2, VERB_ANY, 0, +VERB(verb_detach_image, "detach", "NAME|PATH [PREFIX…]\0", 2, VERB_ANY, 0, "Detach the specified portable service image"); static int verb_detach_image(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; @@ -1345,13 +1345,13 @@ static int verb_detach_image(int argc, char *argv[], uintptr_t _data, void *user return 0; } -VERB(verb_reattach_image, "reattach", "NAME|PATH [PREFIX…]", 2, VERB_ANY, 0, +VERB(verb_reattach_image, "reattach", "NAME|PATH [PREFIX…]\0", 2, VERB_ANY, 0, "Reattach the specified portable service image"); static int verb_reattach_image(int argc, char *argv[], uintptr_t _data, void *userdata) { return attach_reattach_image(argc, argv, strv_isempty(arg_extension_images) && !arg_force ? "ReattachImage" : "ReattachImageWithExtensions"); } -VERB(verb_is_image_attached, "is-attached", "NAME|PATH", 2, 2, 0, +VERB(verb_is_image_attached, "is-attached", "NAME|PATH\0", 2, 2, 0, "Query if portable service image is attached"); static int verb_is_image_attached(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; @@ -1403,7 +1403,7 @@ static int verb_is_image_attached(int argc, char *argv[], uintptr_t _data, void return streq(state, "detached"); } -VERB(verb_read_only_image, "read-only", "NAME|PATH [BOOL]", 2, 3, 0, +VERB(verb_read_only_image, "read-only", "NAME|PATH [BOOL]\0", 2, 3, 0, "Mark or unmark portable service image read-only"); static int verb_read_only_image(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -1434,7 +1434,7 @@ static int verb_read_only_image(int argc, char *argv[], uintptr_t _data, void *u return 0; } -VERB(verb_remove_image, "remove", "NAME|PATH…", 2, VERB_ANY, 0, +VERB(verb_remove_image, "remove", "NAME|PATH…\0", 2, VERB_ANY, 0, "Remove a portable service image"); static int verb_remove_image(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -1472,7 +1472,7 @@ static int verb_remove_image(int argc, char *argv[], uintptr_t _data, void *user return 0; } -VERB(verb_set_limit, "set-limit", "[NAME|PATH] LIMIT", 2, 3, 0, +VERB(verb_set_limit, "set-limit", "[NAME|PATH] LIMIT\0", 2, 3, 0, "Set image or pool size limit (disk quota)"); static int verb_set_limit(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; diff --git a/src/report/report.c b/src/report/report.c index bb4b0329d6..f7c0c35207 100644 --- a/src/report/report.c +++ b/src/report/report.c @@ -650,13 +650,13 @@ static int context_collect_metrics(Context *context) { return 1; } -VERB_FULL(verb_metrics, "metrics", "[MATCH…]", VERB_ANY, VERB_ANY, 0, ACTION_LIST_METRICS, +VERB_FULL(verb_metrics, "metrics", "[MATCH…]\0", VERB_ANY, VERB_ANY, 0, ACTION_LIST_METRICS, "Acquire list of metrics and their values"); -VERB_FULL(verb_metrics, "describe", "[MATCH…]", VERB_ANY, VERB_ANY, 0, ACTION_DESCRIBE_METRICS, +VERB_FULL(verb_metrics, "describe", "[MATCH…]\0", VERB_ANY, VERB_ANY, 0, ACTION_DESCRIBE_METRICS, "Describe available metrics"); -VERB_FULL(verb_metrics, "generate", "[MATCH…]", VERB_ANY, VERB_ANY, 0, ACTION_GENERATE, +VERB_FULL(verb_metrics, "generate", "[MATCH…]\0", VERB_ANY, VERB_ANY, 0, ACTION_GENERATE, "Build a report with metrics"); -VERB_FULL(verb_metrics, "upload", "[MATCH…]", VERB_ANY, VERB_ANY, 0, ACTION_UPLOAD, +VERB_FULL(verb_metrics, "upload", "[MATCH…]\0", VERB_ANY, VERB_ANY, 0, ACTION_UPLOAD, "Upload a report with metrics"); static int verb_metrics(int argc, char *argv[], uintptr_t data, void *userdata) { Action action = data; diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index aa8df3cdfb..149f229a7d 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -881,7 +881,7 @@ invalid: "Invalid DNS URI: %s", name); } -VERB(verb_query, "query", "HOSTNAME|ADDRESS…", 2, VERB_ANY, 0, +VERB(verb_query, "query", "HOSTNAME|ADDRESS…\0", 2, VERB_ANY, 0, "Resolve domain names, IPv4 and IPv6 addresses"); static int verb_query(int argc, char *argv[], uintptr_t _data, void *userdata) { int ret = 0, r; @@ -1025,7 +1025,7 @@ static int resolve_service(const char *name, const char *type, const char *domai return 0; } -VERB(verb_service, "service", "[[NAME] TYPE] DOMAIN", 2, 4, 0, +VERB(verb_service, "service", "[[NAME] TYPE] DOMAIN\0", 2, 4, 0, "Resolve service (SRV)"); static int verb_service(int argc, char *argv[], uintptr_t _data, void *userdata) { uint64_t flags = arg_flags; @@ -1104,7 +1104,7 @@ static int resolve_openpgp(const char *address) { } #endif -VERB(verb_openpgp, "openpgp", "EMAIL@DOMAIN…", 2, VERB_ANY, 0, +VERB(verb_openpgp, "openpgp", "EMAIL@DOMAIN…\0", 2, VERB_ANY, 0, "Query OpenPGP public key"); static int verb_openpgp(int argc, char *argv[], uintptr_t _data, void *userdata) { #if HAVE_OPENSSL @@ -1157,7 +1157,7 @@ static bool service_family_is_valid(const char *s) { return STR_IN_SET(s, "tcp", "udp", "sctp"); } -VERB(verb_tlsa, "tlsa", "DOMAIN[:PORT]…", 2, VERB_ANY, 0, +VERB(verb_tlsa, "tlsa", "DOMAIN[:PORT]…\0", 2, VERB_ANY, 0, "Query TLS public key"); static int verb_tlsa(int argc, char *argv[], uintptr_t _data, void *userdata) { const char *family = "tcp"; @@ -1770,7 +1770,7 @@ static int status_ifindex(int ifindex, StatusMode mode) { return status_full(mode, STRV_MAKE(ifname)); } -VERB(verb_status, "status", "[LINK…]", VERB_ANY, VERB_ANY, VERB_DEFAULT, +VERB(verb_status, "status", "[LINK…]\0", VERB_ANY, VERB_ANY, VERB_DEFAULT, "Show link and server status"); static int verb_status(int argc, char *argv[], uintptr_t _data, void *userdata) { return status_full(STATUS_ALL, strv_skip(argv, 1)); @@ -2658,7 +2658,7 @@ static int verb_show_server_state(int argc, char *argv[], uintptr_t _data, void return sd_json_variant_dump(d, arg_json_format_flags, NULL, NULL); } -VERB(verb_dns, "dns", "[LINK [SERVER…]]", VERB_ANY, VERB_ANY, 0, +VERB(verb_dns, "dns", "[LINK [SERVER…]]\0", VERB_ANY, VERB_ANY, 0, "Get/set per-interface DNS server address"); static int verb_dns(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -2745,7 +2745,7 @@ static int call_domain(sd_bus *bus, char **domain, const BusLocator *locator, sd return sd_bus_call(bus, req, 0, error, NULL); } -VERB(verb_domain, "domain", "[LINK [DOMAIN…]]", VERB_ANY, VERB_ANY, 0, +VERB(verb_domain, "domain", "[LINK [DOMAIN…]]\0", VERB_ANY, VERB_ANY, 0, "Get/set per-interface search domain"); static int verb_domain(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -2786,7 +2786,7 @@ static int verb_domain(int argc, char *argv[], uintptr_t _data, void *userdata) return 0; } -VERB(verb_default_route, "default-route", "[LINK [BOOL]]", VERB_ANY, 3, 0, +VERB(verb_default_route, "default-route", "[LINK [BOOL]]\0", VERB_ANY, 3, 0, "Get/set per-interface default route flag"); static int verb_default_route(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -2832,7 +2832,7 @@ static int verb_default_route(int argc, char *argv[], uintptr_t _data, void *use return 0; } -VERB(verb_llmnr, "llmnr", "[LINK [MODE]]", VERB_ANY, 3, 0, +VERB(verb_llmnr, "llmnr", "[LINK [MODE]]\0", VERB_ANY, 3, 0, "Get/set per-interface LLMNR mode"); static int verb_llmnr(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -2892,7 +2892,7 @@ static int verb_llmnr(int argc, char *argv[], uintptr_t _data, void *userdata) { return 0; } -VERB(verb_mdns, "mdns", "[LINK [MODE]]", VERB_ANY, 3, 0, +VERB(verb_mdns, "mdns", "[LINK [MODE]]\0", VERB_ANY, 3, 0, "Get/set per-interface MulticastDNS mode"); static int verb_mdns(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -2958,7 +2958,7 @@ static int verb_mdns(int argc, char *argv[], uintptr_t _data, void *userdata) { return 0; } -VERB(verb_dns_over_tls, "dnsovertls", "[LINK [MODE]]", VERB_ANY, 3, 0, +VERB(verb_dns_over_tls, "dnsovertls", "[LINK [MODE]]\0", VERB_ANY, 3, 0, "Get/set per-interface DNS-over-TLS mode"); static int verb_dns_over_tls(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -3006,7 +3006,7 @@ static int verb_dns_over_tls(int argc, char *argv[], uintptr_t _data, void *user return 0; } -VERB(verb_dnssec, "dnssec", "[LINK [MODE]]", VERB_ANY, 3, 0, +VERB(verb_dnssec, "dnssec", "[LINK [MODE]]\0", VERB_ANY, 3, 0, "Get/set per-interface DNSSEC mode"); static int verb_dnssec(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -3069,7 +3069,7 @@ static int call_nta(sd_bus *bus, char **nta, const BusLocator *locator, sd_bus_ return sd_bus_call(bus, req, 0, error, NULL); } -VERB(verb_nta, "nta", "[LINK [DOMAIN…]]", VERB_ANY, VERB_ANY, 0, +VERB(verb_nta, "nta", "[LINK [DOMAIN…]]\0", VERB_ANY, VERB_ANY, 0, "Get/set per-interface DNSSEC NTA"); static int verb_nta(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -3129,7 +3129,7 @@ static int verb_nta(int argc, char *argv[], uintptr_t _data, void *userdata) { return 0; } -VERB(verb_revert_link, "revert", "LINK", VERB_ANY, 2, 0, +VERB(verb_revert_link, "revert", "LINK\0", VERB_ANY, 2, 0, "Revert per-interface configuration"); static int verb_revert_link(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -3168,7 +3168,7 @@ static int verb_revert_link(int argc, char *argv[], uintptr_t _data, void *userd return 0; } -VERB(verb_log_level, "log-level", "[LEVEL]", VERB_ANY, 2, 0, +VERB(verb_log_level, "log-level", "[LEVEL]\0", VERB_ANY, 2, 0, "Get/set logging threshold for systemd-resolved"); static int verb_log_level(int argc, char *argv[], uintptr_t _data, void *userdata) { int r; diff --git a/src/sbsign/sbsign.c b/src/sbsign/sbsign.c index e6729dade2..f5c6b96b68 100644 --- a/src/sbsign/sbsign.c +++ b/src/sbsign/sbsign.c @@ -365,7 +365,7 @@ static int pkcs7_add_digest_attribute(PKCS7 *p7, BIO *data, PKCS7_SIGNER_INFO *s return 0; } -VERB(verb_sign, "sign", "EXEFILE", 2, 2, 0, +VERB(verb_sign, "sign", "EXEFILE\0", 2, 2, 0, "Sign the given binary for EFI Secure Boot"); static int verb_sign(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(openssl_ask_password_ui_freep) OpenSSLAskPasswordUI *ui = NULL; diff --git a/src/shared/verbs.c b/src/shared/verbs.c index 4d4eca9c95..920b4e0458 100644 --- a/src/shared/verbs.c +++ b/src/shared/verbs.c @@ -175,41 +175,57 @@ static int verb_add_help_one(Table *table, const Verb *verb) { assert(table); assert(verb); - bool is_default = FLAGS_SET(verb->flags, VERB_DEFAULT); + _cleanup_free_ char *cell = NULL; int r; - /* We indent the option string by two spaces. We could set the minimum cell width and - * right-align for a similar result, but that'd be more work. This is only used for - * display. */ - _cleanup_free_ char *s = strjoin(" ", - is_default ? "[" : "", - verb->verb, - verb->argspec ? " " : "", - strempty(verb->argspec), - is_default ? "]" : ""); - if (!s) - return log_oom(); + bool is_default = FLAGS_SET(verb->flags, VERB_DEFAULT); - const char *ss = NULL; - if (columns() < VERB_SYNOPSIS_WIDTH_SANE * 4) { - /* If the synopsis is very wide, try to split it up. But do this only if the terminal - * is not very wide. If it _is_ wide, the broken up synopsis would look silly. */ - const char *p = find_point_to_break(s, VERB_SYNOPSIS_WIDTH_SANE), *p2 = NULL; - if (p) { - const char *s1 = strndupa_safe(s, p - s), *s2 = NULL; + /* The synopsis cell contains one line per entry in the argspec nulstr. An unset argspec is + * equivalent to a single empty specification. */ + for (const char *spec = empty_to_null(verb->argspec);;) { + /* We indent the option string by two spaces. We could set the minimum cell width and + * right-align for a similar result, but that'd be more work. This is only used for + * display. */ + _cleanup_free_ char *s = strjoin(" ", + is_default ? "[" : "", + verb->verb, + spec ? " " : "", + strempty(spec), + is_default ? "]" : "", + FLAGS_SET(verb->flags, VERB_OPTION_REQUIRED) ? " OPTION" : ""); + if (!s) + return log_oom(); - p2 = find_point_to_break(p, VERB_SYNOPSIS_WIDTH_SANE - 4); /* we indent by two spaces more */ - if (p2) - s2 = strndupa_safe(p, p2 - p); + const char *ss = NULL; + if (columns() < VERB_SYNOPSIS_WIDTH_SANE * 4) { + /* If the synopsis is very wide, try to split it up. But do this only if the terminal + * is not very wide. If it _is_ wide, the broken up synopsis would look silly. */ + const char *p = find_point_to_break(s, VERB_SYNOPSIS_WIDTH_SANE), *p2 = NULL; + if (p) { + const char *s1 = strndupa_safe(s, p - s), *s2 = NULL; - if (s2) - ss = strjoina(s1, "\n ", s2, "\n ", p2); - else - ss = strjoina(s1, "\n ", p); + p2 = find_point_to_break(p, VERB_SYNOPSIS_WIDTH_SANE - 4); /* we indent by two spaces more */ + if (p2) + s2 = strndupa_safe(p, p2 - p); + + if (s2) + ss = strjoina(s1, "\n ", s2, "\n ", p2); + else + ss = strjoina(s1, "\n ", p); + } } + + if (!strextend_with_separator(&cell, "\n", ss ?: s)) + return log_oom(); + + if (!spec) + break; + spec += strlen(spec) + 1; /* Advance to the next entry in the nulstr */ + if (isempty(spec)) + break; } - r = table_add_cell(table, NULL, TABLE_STRING, ss ?: s); + r = table_add_cell(table, NULL, TABLE_STRING, cell); if (r < 0) return table_log_add_error(r); @@ -296,8 +312,8 @@ int _verbs_get_help_table( if (group_marker) break; /* End of group */ - if (!verb->help) - /* No help string — we do not show the verb */ + if (FLAGS_SET(verb->flags, VERB_DEPRECATED) || !verb->help) + /* Marked as deprecated or no help string — we do not show the verb */ continue; r = verb_add_help_one(table, verb); @@ -550,7 +566,88 @@ int _command_print_help_full( return 0; } -static int verb_build_json(const Verb *verb, sd_json_variant **ret) { +int _command_print_verb_help( + const Verb verbs[], + const Verb verbs_end[], + const Option options[], + const Option options_end[], + const char *name) { + + int r; + + assert(name); + + const Verb *verb = ASSERT_PTR(_verbs_find_verb(verbs, verbs_end, name)); + + /* The owning command is described by the closest preceding VERB_COMMAND_MARKER entry. */ + const Verb *cmdverb = verb; + while (!FLAGS_SET(cmdverb->flags, VERB_COMMAND_MARKER)) { + assert(cmdverb > verbs); + cmdverb--; + } + const CommandDescription *cmd = (const CommandDescription*) ASSERT_PTR(cmdverb->data); + + if (cmd->pager_flags) + pager_open(*cmd->pager_flags); + + const char *optionspec = + FLAGS_SET(verb->flags, VERB_OPTION_REQUIRED) ? + " OPTION…" : verb->option_namespace ? " [OPTION…]" : ""; + + /* If argspec is empty, print one line with no argspec. Use " " as placeholder for the empty spec. */ + NULSTR_FOREACH(spec, verb->argspec ?: " \0") { + bool some = !streq(spec, " "); + _cleanup_free_ char *line = strjoin( + "[OPTION…] ", verb->verb, + optionspec, + some ? " " : NULL, + some ? spec : NULL); + if (!line) + return log_oom(); + help_cmdline(line); + }; + + if (verb->help) { + const char *s = strjoina(ansi_highlight(), ansi_add_italics()), + *t = strjoina(verb->help, "."); + + r = print_wrapped(t, s); + if (r < 0) + return r; + } + + if (verb->option_namespace) { + _cleanup_(table_unrefp) Table *table = NULL; + r = _option_parser_get_help_table_full(options, options_end, verb->option_namespace, + /* group= */ NULL, &table); + if (r < 0) + return r; + + help_section("Options"); + r = table_print_or_warn(table); + if (r < 0) + return r; + } + + r = print_wrapped(verb->footer, + FLAGS_SET(verb->flags, VERB_DEPRECATED) ? ansi_highlight_red() : NULL); + if (r < 0) + return r; + + r = print_man_links(cmd->man_pages); + if (r < 0) + return log_error_errno(r, "Failed to print man page links: %m"); + + return 0; +} + +static int verb_build_json( + const Verb *verb, + const Option options[], + const Option options_end[], + sd_json_variant **ret) { + + _cleanup_(sd_json_variant_unrefp) sd_json_variant *opts = NULL; int r; assert(verb); @@ -559,17 +656,30 @@ static int verb_build_json(const Verb *verb, sd_json_variant **ret) { /* Verbs are represented as command objects, as described in the CLI-Introspection * Specification (https://uapi-group.org/specifications/specs/cli_introspection/). + * In particular, a verb which declares an option namespace carries its own "options" + * array, just like the top-level command object. * * The "minArguments", "maxArguments", "isDefault", and "isOnlineOnly" fields * are extensions not (yet) covered by the specification. Note that the argument * counts include the verb itself. */ + if (verb->option_namespace) { + r = options_build_json(options, options_end, verb->option_namespace, + /* option_groups= */ NULL, &opts); + if (r < 0) + return r; + } + r = sd_json_buildo( ret, SD_JSON_BUILD_PAIR_STRV("names", STRV_MAKE(verb->verb)), SD_JSON_BUILD_PAIR_CONDITION( !!verb->help, "abstract", SD_JSON_BUILD_STRV(STRV_MAKE(verb->help))), + SD_JSON_BUILD_PAIR_CONDITION(!!opts, "options", SD_JSON_BUILD_VARIANT(opts)), + SD_JSON_BUILD_PAIR_CONDITION( + !!verb->footer, + "postscript", SD_JSON_BUILD_STRV(STRV_MAKE(verb->footer))), SD_JSON_BUILD_PAIR_CONDITION( verb->min_args != VERB_ANY, "minArguments", SD_JSON_BUILD_UNSIGNED(verb->min_args)), @@ -579,6 +689,9 @@ static int verb_build_json(const Verb *verb, sd_json_variant **ret) { SD_JSON_BUILD_PAIR_CONDITION( FLAGS_SET(verb->flags, VERB_DEFAULT), "isDefault", SD_JSON_BUILD_BOOLEAN(true)), + SD_JSON_BUILD_PAIR_CONDITION( + FLAGS_SET(verb->flags, VERB_DEPRECATED), + "isDeprecated", SD_JSON_BUILD_BOOLEAN(true)), SD_JSON_BUILD_PAIR_CONDITION( FLAGS_SET(verb->flags, VERB_ONLINE_ONLY), "isOnlineOnly", SD_JSON_BUILD_BOOLEAN(true))); @@ -625,7 +738,7 @@ static int command_build_json( continue; _cleanup_(sd_json_variant_unrefp) sd_json_variant *o = NULL; - r = verb_build_json(verb, &o); + r = verb_build_json(verb, options, options_end, &o); if (r < 0) return r; @@ -649,7 +762,7 @@ static int command_build_json( "abstract", SD_JSON_BUILD_STRV(STRV_MAKE(cmd->abstract))), SD_JSON_BUILD_PAIR_CONDITION( !!cmd->footer, - "footer", SD_JSON_BUILD_STRV(STRV_MAKE(cmd->footer))), + "postscript", SD_JSON_BUILD_STRV(STRV_MAKE(cmd->footer))), SD_JSON_BUILD_PAIR_CONDITION(!!opts, "options", SD_JSON_BUILD_VARIANT(opts)), SD_JSON_BUILD_PAIR_CONDITION(!!cmds, "verbs", SD_JSON_BUILD_VARIANT(cmds))); if (r < 0) diff --git a/src/shared/verbs.h b/src/shared/verbs.h index 72b6d70f4f..3453c5e72a 100644 --- a/src/shared/verbs.h +++ b/src/shared/verbs.h @@ -18,7 +18,7 @@ typedef enum CommandFlags { typedef struct CommandDescription { const char *names; /* nulstr with the main command name and potentially aliases */ const char *abstract; /* concrete abstract */ - const char *argspec; /* optional specification of positional args in synopsis */ + const char *argspec; /* optional nulstr with specifications of positional args */ const char *footer; /* optional footer to print right above man page links */ const char *man_pages; /* nulstr with man page names */ const char *option_namespace; /* optional option namespace for this command */ @@ -28,10 +28,12 @@ typedef struct CommandDescription { } CommandDescription; typedef enum VerbFlags { - VERB_DEFAULT = 1 << 0, /* The verb to run if no verb is specified */ - VERB_ONLINE_ONLY = 1 << 1, /* Just do nothing when running in chroot or offline */ - VERB_COMMAND_MARKER = 1 << 2, /* Header entry with command description */ - VERB_GROUP_MARKER = 1 << 3, /* Fake verb entry to separate groups */ + VERB_DEFAULT = 1 << 0, /* The verb to run if no verb is specified */ + VERB_ONLINE_ONLY = 1 << 1, /* Just do nothing when running in chroot or offline */ + VERB_OPTION_REQUIRED = 1 << 2, /* The verb always requires an option to be present */ + VERB_COMMAND_MARKER = 1 << 3, /* Header entry with command description */ + VERB_GROUP_MARKER = 1 << 4, /* Fake verb entry to separate groups */ + VERB_DEPRECATED = 1 << 5, /* The verb is deprecated and not listed in help. */ } VerbFlags; /* Note: see the comment on struct Option in options.h for why _alignptr_ is required here. */ @@ -41,12 +43,14 @@ typedef struct _alignptr_ Verb { VerbFlags flags; int (* const dispatch)(int argc, char *argv[], uintptr_t data, void *userdata); uintptr_t data; - const char *argspec; + const char *argspec; /* optional nulstr with specifications of positional args */ const char *help; + const char *footer; /* optional footer to print in --help */ + const char *option_namespace; /* optional namespace with the verb's own options */ } Verb; assert_cc(sizeof(Verb) % sizeof(void*) == 0); -#define _VERB_DATA(d, v, a, amin, amax, f, dat, h) \ +#define _VERB_DATA(d, v, ns, a, amin, amax, f, dat, h, ft) \ _section_("SYSTEMD_VERBS") \ _alignptr_ \ _used_ \ @@ -62,21 +66,34 @@ assert_cc(sizeof(Verb) % sizeof(void*) == 0); .data = dat, \ .argspec = a, \ .help = h, \ + .footer = ft, \ + .option_namespace = ns, \ } -/* Forward-define function d. scope specifies the scope, e.g. static. */ -#define VERB_SCOPE_FULL(scope, d, v, a, amin, amax, f, dat, h) \ +/* Forward-define function d. scope specifies the scope, e.g. static. ns declares the option + * namespace with the verb's own options, which are then shown in the verb's help (see + * command_print_verb_help()) and reported in the CLI introspection. */ +#define VERB_SCOPE_NS_FULL(scope, d, v, ns, a, amin, amax, f, dat, h, ft) \ DISABLE_WARNING_REDUNDANT_DECLS \ scope int d(int, char**, uintptr_t, void*); \ REENABLE_WARNING \ - _VERB_DATA(d, v, a, amin, amax, f, dat, h) -/* The same as VERB_SCOPE_FULL with scope hardwired to 'static'. */ + _VERB_DATA(d, v, ns, a, amin, amax, f, dat, h, ft) +/* The same as VERB_SCOPE_NS_FULL, but for verbs without options of their own. */ +#define VERB_SCOPE_FULL(scope, d, v, a, amin, amax, f, dat, h, ft) \ + VERB_SCOPE_NS_FULL(scope, d, v, /* ns= */ NULL, a, amin, amax, f, dat, h, ft) +/* The same as VERB_SCOPE_NS_FULL/VERB_SCOPE_FULL with scope hardwired to 'static'. */ +#define VERB_NS_FULL(d, v, ns, a, amin, amax, f, dat, h, ft) \ + VERB_SCOPE_NS_FULL(static, d, v, ns, a, amin, amax, f, dat, h, ft) #define VERB_FULL(d, v, a, amin, amax, f, dat, h) \ - VERB_SCOPE_FULL(static, d, v, a, amin, amax, f, dat, h) + VERB_SCOPE_FULL(static, d, v, a, amin, amax, f, dat, h, /* ft= */ NULL) -/* The same as VERB_SCOPE_FULL/VERB_FULL, but without the data argument. */ +/* The same as the macros above, but without the data argument. */ +#define VERB_SCOPE_NS(scope, d, v, ns, a, amin, amax, f, h) \ + VERB_SCOPE_NS_FULL(scope, d, v, ns, a, amin, amax, f, /* dat= */ 0, h, /* ft= */ NULL) #define VERB_SCOPE(scope, d, v, a, amin, amax, f, h) \ - VERB_SCOPE_FULL(scope, d, v, a, amin, amax, f, /* dat= */ 0, h) + VERB_SCOPE_FULL(scope, d, v, a, amin, amax, f, /* dat= */ 0, h, /* ft= */ NULL) +#define VERB_NS(d, v, ns, a, amin, amax, f, h) \ + VERB_SCOPE_NS(static, d, v, ns, a, amin, amax, f, h) #define VERB(d, v, a, amin, amax, f, h) \ VERB_SCOPE(static, d, v, a, amin, amax, f, h) @@ -91,13 +108,16 @@ assert_cc(sizeof(Verb) % sizeof(void*) == 0); /* Magic entry in the table (which will not be returned) that designates the start of the group . * The macro works as a separator between groups and must be between other VERB* stanzas. */ #define VERB_GROUP(gr) \ - _VERB_DATA(/* d= */ NULL, /* v= */ gr, /* a= */ NULL, /* amin= */ 0, /* amax= */ 0, \ - /* f= */ VERB_GROUP_MARKER, /* dat= */ 0, /* h= */ NULL) + _VERB_DATA(/* d= */ NULL, /* v= */ gr, /* ns= */ NULL, /* a= */ NULL, \ + /* amin= */ 0, /* amax= */ 0, /* f= */ VERB_GROUP_MARKER, /* dat= */ 0, \ + /* h= */ NULL, /* ft= */ NULL) -#define _COMMAND(u, ...) \ +#define _COMMAND(u, ...) \ static const CommandDescription UNIQ_T(description, u) = { __VA_ARGS__ }; \ - _VERB_DATA(/* d= */ NULL, /* v= */ NULL, /* a= */ NULL, /* amin= */ 0, /* amax= */ 0, \ - /* f= */ VERB_COMMAND_MARKER, /* dat= */ (uintptr_t) &UNIQ_T(description, u), /* h= */ NULL) + _VERB_DATA(/* d= */ NULL, /* v= */ NULL, /* ns= */ NULL, /* a= */ NULL, \ + /* amin= */ 0, /* amax= */ 0, /* f= */ VERB_COMMAND_MARKER, \ + /* dat= */ (uintptr_t) &UNIQ_T(description, u), \ + /* h= */ NULL, /* ft= */ NULL) #define COMMAND(...) _COMMAND(UNIQ, __VA_ARGS__) /* This is magically mapped to the beginning and end of the section */ @@ -169,6 +189,24 @@ static inline int verb_help_auto(int argc, char **argv, uintptr_t data, void *us return command_print_help_name((const char*) data); } +/* Print the help for a single verb: the synopsis, the one-line help as abstract, the options from + * the verb's option namespace (see VERB_SCOPE_NS*), and the man page links of the command the verb + * belongs to. The verb is attributed to the closest preceding COMMAND() in the verbs section, so: + * name must refer to an existing verb owned by such a command (asserted otherwise), verb names + * must be unique across the whole binary, commands with COMMAND_VERBS_SHARED are not + * disambiguated, and a declared option namespace must contain at least one non-hidden option. */ +int _command_print_verb_help( + const Verb verbs[], + const Verb verbs_end[], + const Option options[], + const Option options_end[], + const char *name); +#define command_print_verb_help(name) \ + _command_print_verb_help( \ + __start_SYSTEMD_VERBS, __stop_SYSTEMD_VERBS, \ + __start_SYSTEMD_OPTIONS, __stop_SYSTEMD_OPTIONS, \ + name) + /* Print a machine-readable description of the program's commands, verbs, and options in the format * defined by the CLI-Introspection Specification. One command object is emitted for each * VERB_COMMAND() in the verb table, so multicall binaries are described in full. */ diff --git a/src/storage/storagectl.c b/src/storage/storagectl.c index f186603de9..3c11391f15 100644 --- a/src/storage/storagectl.c +++ b/src/storage/storagectl.c @@ -140,7 +140,7 @@ static int on_list_reply( return 0; } -VERB(verb_list_volumes, "volumes", "GLOB", /* min_args= */ VERB_ANY, /* max_args= */ 2, VERB_DEFAULT, "List storage volumes"); +VERB(verb_list_volumes, "volumes", "GLOB\0", /* min_args= */ VERB_ANY, /* max_args= */ 2, VERB_DEFAULT, "List storage volumes"); static int verb_list_volumes(int argc, char *argv[], uintptr_t data, void *userdata) { int r; @@ -245,7 +245,7 @@ static int on_list_templates_reply( return 0; } -VERB(verb_templates, "templates", "GLOB", /* min_args= */ VERB_ANY, /* max_args= */ 2, /* flags= */ 0, "List storage volume templates"); +VERB(verb_templates, "templates", "GLOB\0", /* min_args= */ VERB_ANY, /* max_args= */ 2, /* flags= */ 0, "List storage volume templates"); static int verb_templates(int argc, char *argv[], uintptr_t data, void *userdata) { int r; diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 2e4f50d086..18026e1e52 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -911,128 +911,128 @@ int systemctl_dispatch_parse_argv(int argc, char *argv[], int log_level_shift, c VERB_GROUP("Unit Commands"); -VERB_SCOPE(, verb_list_units, "list-units", "[PATTERN…]", VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_list_units, "list-units", "[PATTERN…]\0", VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, "List units currently in memory"); -VERB_SCOPE(, verb_list_automounts, "list-automounts", "[PATTERN…]", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_list_automounts, "list-automounts", "[PATTERN…]\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "List automount units currently in memory, ordered by path"); -VERB_SCOPE(, verb_list_paths, "list-paths", "[PATTERN…]", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_list_paths, "list-paths", "[PATTERN…]\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "List path units currently in memory, ordered by path"); -VERB_SCOPE(, verb_list_sockets, "list-sockets", "[PATTERN…]", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_list_sockets, "list-sockets", "[PATTERN…]\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "List socket units currently in memory, ordered by address"); -VERB_SCOPE(, verb_list_timers, "list-timers", "[PATTERN…]", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_list_timers, "list-timers", "[PATTERN…]\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "List timer units currently in memory, ordered by next elapse"); -VERB_SCOPE(, verb_is_active, "is-active", "PATTERN…", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_is_active, "is-active", "PATTERN…\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Check whether units are active"); -VERB_SCOPE(, verb_is_failed, "is-failed", "[PATTERN…]", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_is_failed, "is-failed", "[PATTERN…]\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "Check whether units are failed or system is in degraded state"); -VERB_SCOPE(, verb_show, "status", "[PATTERN…|PID…]", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_show, "status", "[PATTERN…|PID…]\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "Show runtime status of one or more units"); -VERB_SCOPE(, verb_show, "show", "[PATTERN…|JOB…]", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_show, "show", "[PATTERN…|JOB…]\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "Show properties of one or more units/jobs or the manager"); -VERB_SCOPE(, verb_cat, "cat", "PATTERN…", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_cat, "cat", "PATTERN…\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Show files and drop-ins of specified units"); -VERB_SCOPE(, verb_show, "help", "PATTERN…|PID…", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_show, "help", "PATTERN…|PID…\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "Show manual for one or more units"); -VERB_SCOPE(, verb_list_dependencies, "list-dependencies", "[UNIT…]", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_list_dependencies, "list-dependencies", "[UNIT…]\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "Recursively show units which are required or wanted by the units " "or by which those units are required or wanted"); -VERB_SCOPE(, verb_start, "start", "UNIT…", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_start, "start", "UNIT…\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Start (activate) one or more units"); -VERB_SCOPE(, verb_start, "stop", "UNIT…", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_start, "stop", "UNIT…\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Stop (deactivate) one or more units"); -VERB_SCOPE(, verb_start, "reload", "UNIT…", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_start, "reload", "UNIT…\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Reload one or more units"); -VERB_SCOPE(, verb_start, "restart", "UNIT…", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_start, "restart", "UNIT…\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Start or restart one or more units"); -VERB_SCOPE(, verb_start, "try-restart", "UNIT…", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_start, "try-restart", "UNIT…\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Restart one or more units if active"); VERB_SCOPE(, verb_start, "enqueue-marked", NULL, 1, 1, VERB_ONLINE_ONLY, "Enqueue jobs for all marked units"); -VERB_SCOPE(, verb_start, "reload-or-restart", "UNIT…", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_start, "reload-or-restart", "UNIT…\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "Reload one or more units if possible, otherwise start or restart"); -VERB_SCOPE(, verb_start, "try-reload-or-restart", "UNIT…", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_start, "try-reload-or-restart", "UNIT…\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "If active, reload one or more units, if supported, otherwise restart"); -VERB_SCOPE(, verb_start, "isolate", "UNIT", 2, 2, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_start, "isolate", "UNIT\0", 2, 2, VERB_ONLINE_ONLY, "Start one unit and stop all others"); -VERB_SCOPE(, verb_kill, "kill", "UNIT…", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_kill, "kill", "UNIT…\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Send signal to processes of a unit"); -VERB_SCOPE(, verb_clean_or_freeze, "clean", "UNIT…", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_clean_or_freeze, "clean", "UNIT…\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Clean runtime, cache, state, logs or configuration of unit"); -VERB_SCOPE(, verb_clean_or_freeze, "freeze", "PATTERN…", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_clean_or_freeze, "freeze", "PATTERN…\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Freeze execution of unit processes"); -VERB_SCOPE(, verb_clean_or_freeze, "thaw", "PATTERN…", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_clean_or_freeze, "thaw", "PATTERN…\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Resume execution of a frozen unit"); -VERB_SCOPE(, verb_set_property, "set-property", "UNIT PROPERTY=VALUE…", 3, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_set_property, "set-property", "UNIT PROPERTY=VALUE…\0", 3, VERB_ANY, VERB_ONLINE_ONLY, "Sets one or more properties of a unit"); -VERB_SCOPE(, verb_bind, "bind", "UNIT PATH [PATH]", 3, 4, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_bind, "bind", "UNIT PATH [PATH]\0", 3, 4, VERB_ONLINE_ONLY, "Bind-mount a path from the host into a unit's namespace"); -VERB_SCOPE(, verb_mount_image, "mount-image", "UNIT PATH [PATH [OPTS]]", 4, 5, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_mount_image, "mount-image", "UNIT PATH [PATH [OPTS]]\0", 4, 5, VERB_ONLINE_ONLY, "Mount an image from the host into a unit's namespace"); -VERB_SCOPE(, verb_service_log_setting, "service-log-level", "SERVICE [LEVEL]", 2, 3, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_service_log_setting, "service-log-level", "SERVICE [LEVEL]\0", 2, 3, VERB_ONLINE_ONLY, "Get/set logging threshold for service"); -VERB_SCOPE(, verb_service_log_setting, "service-log-target", "SERVICE [TARGET]", 2, 3, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_service_log_setting, "service-log-target", "SERVICE [TARGET]\0", 2, 3, VERB_ONLINE_ONLY, "Get/set logging target for service"); -VERB_SCOPE(, verb_reset_failed, "reset-failed", "[PATTERN…]", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_reset_failed, "reset-failed", "[PATTERN…]\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "Reset failed state for all, one, or more units"); -VERB_SCOPE(, verb_whoami, "whoami", "[PID…]", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_whoami, "whoami", "[PID…]\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "Return unit caller or specified PIDs are part of"); VERB_GROUP("Unit File Commands"); -VERB_SCOPE(, verb_list_unit_files, "list-unit-files", "[PATTERN…]", VERB_ANY, VERB_ANY, 0, +VERB_SCOPE(, verb_list_unit_files, "list-unit-files", "[PATTERN…]\0", VERB_ANY, VERB_ANY, 0, "List installed unit files"); -VERB_SCOPE(, verb_enable, "enable", "[UNIT…|PATH…]", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_enable, "enable", "[UNIT…|PATH…]\0", 2, VERB_ANY, 0, "Enable one or more unit files"); -VERB_SCOPE(, verb_enable, "disable", "UNIT…", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_enable, "disable", "UNIT…\0", 2, VERB_ANY, 0, "Disable one or more unit files"); -VERB_SCOPE(, verb_enable, "reenable", "UNIT…", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_enable, "reenable", "UNIT…\0", 2, VERB_ANY, 0, "Reenable one or more unit files"); -VERB_SCOPE(, verb_enable, "preset", "UNIT…", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_enable, "preset", "UNIT…\0", 2, VERB_ANY, 0, "Enable/disable one or more unit files based on preset configuration"); VERB_SCOPE(, verb_preset_all, "preset-all", NULL, VERB_ANY, 1, 0, "Enable/disable all unit files based on preset configuration"); -VERB_SCOPE(, verb_is_enabled, "is-enabled", "UNIT…", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_is_enabled, "is-enabled", "UNIT…\0", 2, VERB_ANY, 0, "Check whether unit files are enabled"); -VERB_SCOPE(, verb_enable, "mask", "UNIT…", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_enable, "mask", "UNIT…\0", 2, VERB_ANY, 0, "Mask one or more units"); -VERB_SCOPE(, verb_enable, "unmask", "UNIT…", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_enable, "unmask", "UNIT…\0", 2, VERB_ANY, 0, "Unmask one or more units"); -VERB_SCOPE(, verb_enable, "link", "PATH…", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_enable, "link", "PATH…\0", 2, VERB_ANY, 0, "Link one or more units files into the search path"); -VERB_SCOPE(, verb_enable, "revert", "UNIT…", 2, VERB_ANY, 0, +VERB_SCOPE(, verb_enable, "revert", "UNIT…\0", 2, VERB_ANY, 0, "Revert one or more unit files to vendor version"); -VERB_SCOPE(, verb_add_dependency, "add-wants", "TARGET UNIT…", 3, VERB_ANY, 0, +VERB_SCOPE(, verb_add_dependency, "add-wants", "TARGET UNIT…\0", 3, VERB_ANY, 0, "Add 'Wants' dependency for the target on specified one or more units"); -VERB_SCOPE(, verb_add_dependency, "add-requires", "TARGET UNIT…", 3, VERB_ANY, 0, +VERB_SCOPE(, verb_add_dependency, "add-requires", "TARGET UNIT…\0", 3, VERB_ANY, 0, "Add 'Requires' dependency for the target on specified one or more units"); -VERB_SCOPE(, verb_edit, "edit", "UNIT…", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_edit, "edit", "UNIT…\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Edit one or more unit files"); VERB_SCOPE(, verb_get_default, "get-default", NULL, VERB_ANY, 1, 0, "Get the name of the default target"); -VERB_SCOPE(, verb_set_default, "set-default", "TARGET", 2, 2, 0, +VERB_SCOPE(, verb_set_default, "set-default", "TARGET\0", 2, 2, 0, "Set the default target"); VERB_GROUP("Machine Commands"); -VERB_SCOPE(, verb_list_machines, "list-machines", "[PATTERN…]", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_list_machines, "list-machines", "[PATTERN…]\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "List local containers and host"); VERB_GROUP("Job Commands"); -VERB_SCOPE(, verb_list_jobs, "list-jobs", "[PATTERN…]", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_list_jobs, "list-jobs", "[PATTERN…]\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "List jobs"); -VERB_SCOPE(, verb_cancel, "cancel", "[JOB…]", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_cancel, "cancel", "[JOB…]\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "Cancel all, one, or more jobs"); VERB_GROUP("Environment Commands"); VERB_SCOPE(, verb_show_environment, "show-environment", NULL, VERB_ANY, 1, VERB_ONLINE_ONLY, "Dump environment"); -VERB_SCOPE(, verb_set_environment, "set-environment", "VARIABLE=VALUE…", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_set_environment, "set-environment", "VARIABLE=VALUE…\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Set one or more environment variables"); -VERB_SCOPE(, verb_set_environment, "unset-environment", "VARIABLE…", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_set_environment, "unset-environment", "VARIABLE…\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Unset one or more environment variables"); -VERB_SCOPE(, verb_import_environment, "import-environment", "VARIABLE…", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_import_environment, "import-environment", "VARIABLE…\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "Import all or some environment variables"); VERB_GROUP("Manager State Commands"); @@ -1041,11 +1041,11 @@ VERB_SCOPE(, verb_daemon_reload, "daemon-reload", NULL, 1, "Reload systemd manager configuration"); VERB_SCOPE(, verb_daemon_reload, "daemon-reexec", NULL, 1, 1, VERB_ONLINE_ONLY, "Reexecute systemd manager"); -VERB_SCOPE(, verb_log_setting, "log-level", "[LEVEL]", VERB_ANY, 2, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_log_setting, "log-level", "[LEVEL]\0", VERB_ANY, 2, VERB_ONLINE_ONLY, "Get/set logging threshold for manager"); -VERB_SCOPE(, verb_log_setting, "log-target", "[TARGET]", VERB_ANY, 2, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_log_setting, "log-target", "[TARGET]\0", VERB_ANY, 2, VERB_ONLINE_ONLY, "Get/set logging target for manager"); -VERB_SCOPE(, verb_service_watchdogs, "service-watchdogs", "[BOOL]", VERB_ANY, 2, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_service_watchdogs, "service-watchdogs", "[BOOL]\0", VERB_ANY, 2, VERB_ONLINE_ONLY, "Get/set service watchdog state"); VERB_GROUP("System Commands"); @@ -1068,9 +1068,9 @@ VERB_SCOPE(, verb_start_system_special, "kexec", NULL, VERB_ANY, "Shut down and reboot the system with kexec"); VERB_SCOPE(, verb_start_system_special, "soft-reboot", NULL, VERB_ANY, 1, VERB_ONLINE_ONLY, "Shut down and reboot userspace"); -VERB_SCOPE(, verb_start_special, "exit", "[EXIT_CODE]", VERB_ANY, 2, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_start_special, "exit", "[EXIT_CODE]\0", VERB_ANY, 2, VERB_ONLINE_ONLY, "Request user instance or container exit"); -VERB_SCOPE(, verb_switch_root, "switch-root", "[ROOT [INIT]]", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB_SCOPE(, verb_switch_root, "switch-root", "[ROOT [INIT]]\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "Change to a different root file system"); VERB_SCOPE(, verb_start_system_special, "sleep", NULL, VERB_ANY, 1, VERB_ONLINE_ONLY, "Put the system to sleep (through one of the operations below)"); diff --git a/src/sysupdate/sysupdate.c b/src/sysupdate/sysupdate.c index b56bf3883f..73ae5cebe8 100644 --- a/src/sysupdate/sysupdate.c +++ b/src/sysupdate/sysupdate.c @@ -1942,7 +1942,7 @@ static int verify_polkit(Context *context, sd_varlink *link, const char *action, &s->polkit_registry); } -VERB(verb_list, "list", "[VERSION]", VERB_ANY, 2, VERB_DEFAULT, +VERB(verb_list, "list", "[VERSION]\0", VERB_ANY, 2, VERB_DEFAULT, "Show installed and available versions"); static int verb_list(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(context_done) Context context = CONTEXT_NULL; @@ -2019,7 +2019,7 @@ static int verb_list(int argc, char *argv[], uintptr_t _data, void *userdata) { } } -VERB(verb_features, "features", "[FEATURE]", VERB_ANY, 2, 0, +VERB(verb_features, "features", "[FEATURE]\0", VERB_ANY, 2, 0, "Show optional features"); static int verb_features(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(context_done) Context context = CONTEXT_NULL; @@ -2312,9 +2312,9 @@ static int context_enable_feature( return ret; } -VERB(verb_enable_feature, "enable-feature", "FEATURE…", 1, VERB_ANY, 0, +VERB(verb_enable_feature, "enable-feature", "FEATURE…\0", 1, VERB_ANY, 0, "Enable optional feature"); -VERB(verb_enable_feature, "disable-feature", "FEATURE…", 1, VERB_ANY, 0, +VERB(verb_enable_feature, "disable-feature", "FEATURE…\0", 1, VERB_ANY, 0, "Disable optional feature"); static int verb_enable_feature(int argc, char *argv[], uintptr_t _data, void *userdata) { bool enable = streq(argv[0], "enable-feature"); @@ -2759,7 +2759,7 @@ static int verb_update_impl(int argc, char **argv, UpdateActionFlags action_flag } } -VERB(verb_update, "update", "[VERSION]", VERB_ANY, 2, 0, +VERB(verb_update, "update", "[VERSION]\0", VERB_ANY, 2, 0, "Install new version now"); static int verb_update(int argc, char *argv[], uintptr_t _data, void *userdata) { UpdateActionFlags flags = UPDATE_ACTION_INSTALL; @@ -2770,7 +2770,7 @@ static int verb_update(int argc, char *argv[], uintptr_t _data, void *userdata) return verb_update_impl(argc, argv, flags); } -VERB(verb_acquire, "acquire", "[VERSION]", VERB_ANY, 2, 0, +VERB(verb_acquire, "acquire", "[VERSION]\0", VERB_ANY, 2, 0, "Acquire (download) new version now"); static int verb_acquire(int argc, char *argv[], uintptr_t _data, void *userdata) { return verb_update_impl(argc, argv, UPDATE_ACTION_ACQUIRE); @@ -3163,9 +3163,9 @@ static int vl_method_list_targets(sd_varlink *link, sd_json_variant *parameters, SD_JSON_BUILD_PAIR_VARIANT("targets", l)); } -VERB(verb_enable_component, "enable-component", "COMPONENT…", 1, VERB_ANY, 0, +VERB(verb_enable_component, "enable-component", "COMPONENT…\0", 1, VERB_ANY, 0, "Enable component"); -VERB(verb_enable_component, "disable-component", "COMPONENT…", 1, VERB_ANY, 0, +VERB(verb_enable_component, "disable-component", "COMPONENT…\0", 1, VERB_ANY, 0, "Disable component"); static int verb_enable_component(int argc, char *argv[], uintptr_t _data, void *userdata) { bool enable = streq(argv[0], "enable-component"); diff --git a/src/sysupdate/updatectl.c b/src/sysupdate/updatectl.c index cfe6e031ff..315d0e7381 100644 --- a/src/sysupdate/updatectl.c +++ b/src/sysupdate/updatectl.c @@ -651,7 +651,7 @@ static int describe(sd_bus *bus, const char *target_path, const char *version) { return table_print_with_pager(table, SD_JSON_FORMAT_OFF, arg_pager_flags, arg_legend); } -VERB(verb_list, "list", "[TARGET[@VERSION]]", VERB_ANY, 2, VERB_DEFAULT|VERB_ONLINE_ONLY, +VERB(verb_list, "list", "[TARGET[@VERSION]]\0", VERB_ANY, 2, VERB_DEFAULT|VERB_ONLINE_ONLY, "List available targets and versions"); static int verb_list(int argc, char *argv[], uintptr_t _data, void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); @@ -764,7 +764,7 @@ static int check_finished(sd_bus_message *reply, void *userdata, sd_bus_error *r return 0; } -VERB(verb_check, "check", "[TARGET...]", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB(verb_check, "check", "[TARGET...]\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "Check for updates"); static int verb_check(int argc, char *argv[], uintptr_t _data, void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); @@ -1306,7 +1306,7 @@ static int do_update(sd_bus *bus, char **targets) { return did_anything ? 1 : 0; } -VERB(verb_update, "update", "[TARGET[@VERSION]...]", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB(verb_update, "update", "[TARGET[@VERSION]...]\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "Install updates"); static int verb_update(int argc, char *argv[], uintptr_t _data, void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); @@ -1361,7 +1361,7 @@ static int do_vacuum(sd_bus *bus, const char *target, const char *path) { return count + disabled > 0 ? 1 : 0; } -VERB(verb_vacuum, "vacuum", "[TARGET...]", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, +VERB(verb_vacuum, "vacuum", "[TARGET...]\0", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, "Clean up old updates"); static int verb_vacuum(int argc, char *argv[], uintptr_t _data, void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); @@ -1507,7 +1507,7 @@ static int list_features(sd_bus *bus) { return table_print_with_pager(table, SD_JSON_FORMAT_OFF, arg_pager_flags, arg_legend); } -VERB(verb_features, "features", "[FEATURE]", VERB_ANY, 2, VERB_ONLINE_ONLY, +VERB(verb_features, "features", "[FEATURE]\0", VERB_ANY, 2, VERB_ONLINE_ONLY, "List and inspect optional features on host OS"); static int verb_features(int argc, char *argv[], uintptr_t _data, void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); @@ -1558,9 +1558,9 @@ static int verb_features(int argc, char *argv[], uintptr_t _data, void *userdata return table_print_with_pager(table, SD_JSON_FORMAT_OFF, arg_pager_flags, false); } -VERB(verb_enable, "enable", "FEATURE...", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB(verb_enable, "enable", "FEATURE...\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Enable optional feature on host OS"); -VERB(verb_enable, "disable", "FEATURE...", 2, VERB_ANY, VERB_ONLINE_ONLY, +VERB(verb_enable, "disable", "FEATURE...\0", 2, VERB_ANY, VERB_ONLINE_ONLY, "Disable optional feature on host OS"); static int verb_enable(int argc, char *argv[], uintptr_t _data, void *userdata) { sd_bus *bus = ASSERT_PTR(userdata); diff --git a/src/test/test-verbs.c b/src/test/test-verbs.c index 56062b0bd6..29143cd23f 100644 --- a/src/test/test-verbs.c +++ b/src/test/test-verbs.c @@ -1,5 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include "sd-json.h" + +#include "options.h" #include "strv.h" #include "tests.h" #include "verbs.h" @@ -9,7 +12,7 @@ static int noop_dispatcher(int argc, char *argv[], uintptr_t _data, void *userda } #define test_dispatch_one(argv, verbs, expected) \ - assert_se(_dispatch_verb(argv, verbs, verbs + ELEMENTSOF(verbs) - 1, NULL) == expected); + ASSERT_EQ(_dispatch_verb(argv, verbs, verbs + ELEMENTSOF(verbs) - 1, NULL), expected); TEST(verbs) { static const Verb verbs[] = { @@ -84,4 +87,46 @@ TEST(verbs_no_default_many) { test_dispatch_one(STRV_MAKE("Specials"), verbs, -EINVAL); } +static const CommandDescription introspect_command = { + .names = "test-verbs\0", + .abstract = "Test the verb machinery.", + .man_pages = "systemd(1)\0", +}; + +static const Verb introspect_verbs[] = { + { .flags = VERB_COMMAND_MARKER, .data = (uintptr_t) &introspect_command }, + { .verb = "alpha", .min_args = VERB_ANY, .max_args = VERB_ANY, .dispatch = noop_dispatcher, + .argspec = "FORM1\0FORM2…\0", .help = "Alpha verb", .option_namespace = "test-verbs-alpha" }, + { .verb = "beta", .min_args = VERB_ANY, .max_args = VERB_ANY, .dispatch = noop_dispatcher, + .help = "Beta verb" }, + { .verb = "gamma", .flags = VERB_OPTION_REQUIRED | VERB_DEPRECATED, + .min_args = VERB_ANY, .max_args = VERB_ANY, .dispatch = noop_dispatcher, + .help = "Gamma verb", .footer = "Gamma footer" }, + {} +}; + +static const Option introspect_options[] = { + { 1, .long_code = "test-verbs-alpha", .flags = OPTION_NAMESPACE_MARKER }, + { 2, .short_code = 'x', .long_code = "example", .metavar = "ARG", .help = "An example option" }, + {} +}; + +TEST(introspect_cli_verb_options) { + ASSERT_OK(_introspect_cli(introspect_verbs, introspect_verbs + ELEMENTSOF(introspect_verbs) - 1, + introspect_options, introspect_options + ELEMENTSOF(introspect_options) - 1, + SD_JSON_FORMAT_OFF)); +} + +TEST(command_print_verb_help) { + ASSERT_OK(_command_print_verb_help(introspect_verbs, introspect_verbs + ELEMENTSOF(introspect_verbs) - 1, + introspect_options, introspect_options + ELEMENTSOF(introspect_options) - 1, + "alpha")); + ASSERT_OK(_command_print_verb_help(introspect_verbs, introspect_verbs + ELEMENTSOF(introspect_verbs) - 1, + introspect_options, introspect_options + ELEMENTSOF(introspect_options) - 1, + "beta")); + ASSERT_OK(_command_print_verb_help(introspect_verbs, introspect_verbs + ELEMENTSOF(introspect_verbs) - 1, + introspect_options, introspect_options + ELEMENTSOF(introspect_options) - 1, + "gamma")); +} + DEFINE_TEST_MAIN(LOG_INFO); diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c index 8ff135b9a7..c388768dbb 100644 --- a/src/timedate/timedatectl.c +++ b/src/timedate/timedatectl.c @@ -237,7 +237,7 @@ static int verb_show(int argc, char *argv[], uintptr_t _data, void *userdata) { return 0; } -VERB(verb_set_time, "set-time", "TIME", 2, 2, 0, "Set system time"); +VERB(verb_set_time, "set-time", "TIME\0", 2, 2, 0, "Set system time"); static int verb_set_time(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus *bus = userdata; @@ -263,7 +263,7 @@ static int verb_set_time(int argc, char *argv[], uintptr_t _data, void *userdata return 0; } -VERB(verb_set_timezone, "set-timezone", "ZONE", 2, 2, 0, "Set system time zone"); +VERB(verb_set_timezone, "set-timezone", "ZONE\0", 2, 2, 0, "Set system time zone"); static int verb_set_timezone(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus *bus = userdata; @@ -301,7 +301,7 @@ static int verb_list_timezones(int argc, char *argv[], uintptr_t _data, void *us return 0; } -VERB(verb_set_local_rtc, "set-local-rtc", "BOOL", 2, 2, 0, "Control whether RTC is in local time"); +VERB(verb_set_local_rtc, "set-local-rtc", "BOOL\0", 2, 2, 0, "Control whether RTC is in local time"); static int verb_set_local_rtc(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus *bus = userdata; @@ -333,7 +333,7 @@ static int verb_set_local_rtc(int argc, char *argv[], uintptr_t _data, void *use return 0; } -VERB(verb_set_ntp, "set-ntp", "BOOL", 2, 2, 0, "Enable or disable network time synchronization"); +VERB(verb_set_ntp, "set-ntp", "BOOL\0", 2, 2, 0, "Enable or disable network time synchronization"); static int verb_set_ntp(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -847,7 +847,7 @@ static int parse_ifindex_bus(sd_bus *bus, const char *str) { return i; } -VERB(verb_ntp_servers, "ntp-servers", "INTERFACE SERVER…", 3, VERB_ANY, 0, +VERB(verb_ntp_servers, "ntp-servers", "INTERFACE SERVER…\0", 3, VERB_ANY, 0, "Set the interface specific NTP servers"); static int verb_ntp_servers(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -880,7 +880,7 @@ static int verb_ntp_servers(int argc, char *argv[], uintptr_t _data, void *userd return 0; } -VERB(verb_revert, "revert", "INTERFACE", 2, 2, 0, "Revert the interface specific NTP servers"); +VERB(verb_revert, "revert", "INTERFACE\0", 2, 2, 0, "Revert the interface specific NTP servers"); static int verb_revert(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus *bus = ASSERT_PTR(userdata); diff --git a/src/udev/iocost/iocost.c b/src/udev/iocost/iocost.c index 951243fee9..3501f192ba 100644 --- a/src/udev/iocost/iocost.c +++ b/src/udev/iocost/iocost.c @@ -261,13 +261,13 @@ static int query_solutions_for_path(const char *path) { return 0; } -VERB(verb_query, "query", "PATH", 2, 2, 0, +VERB(verb_query, "query", "PATH\0", 2, 2, 0, "Query the known solution for the device"); static int verb_query(int argc, char *argv[], uintptr_t _data, void *userdata) { return query_solutions_for_path(ASSERT_PTR(argv[1])); } -VERB(verb_apply, "apply", "PATH [SOLUTION]", 2, 3, 0, +VERB(verb_apply, "apply", "PATH [SOLUTION]\0", 2, 3, 0, "Apply solution for the device if found, do nothing otherwise"); static int verb_apply(int argc, char *argv[], uintptr_t _data, void *userdata) { return apply_solution_for_path( diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c index de284d60fe..7ad8451347 100644 --- a/src/udev/udev-builtin.c +++ b/src/udev/udev-builtin.c @@ -76,7 +76,7 @@ void udev_builtin_reload(UdevReloadFlags flags) { void udev_builtin_list(void) { FOREACH_ELEMENT(b, builtins) if (*b) - fprintf(stderr, " %-14s %s\n", (*b)->name, (*b)->help); + printf(" %-14s %s\n", (*b)->name, (*b)->help); } const char* udev_builtin_name(UdevBuiltinCommand cmd) { diff --git a/src/udev/udev-config.c b/src/udev/udev-config.c index c108985c4d..0733f41872 100644 --- a/src/udev/udev-config.c +++ b/src/udev/udev-config.c @@ -2,14 +2,14 @@ #include +#include "sd-json.h" + #include "conf-parser.h" #include "cpu-set-util.h" #include "daemon-util.h" #include "fd-util.h" #include "fileio.h" -#include "format-table.h" #include "hashmap.h" -#include "help-util.h" #include "limits-util.h" #include "options.h" #include "parse-util.h" @@ -25,6 +25,7 @@ #include "udev-rules.h" #include "udev-util.h" #include "udev-worker.h" +#include "verbs.h" #include "version.h" #define WORKER_NUM_MAX UINT64_C(2048) @@ -149,26 +150,15 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat return 0; } -static int help(void) { - _cleanup_(table_unrefp) Table *options = NULL; - int r; - - r = option_parser_get_help_table_ns("udevd", &options); - if (r < 0) - return r; - - help_cmdline("[OPTIONS...]"); - help_abstract("Rule-based manager for device events and files."); - - help_section("Options"); - - r = table_print_or_warn(options); - if (r < 0) - return r; - - help_man_page_reference("systemd-udevd.service", "8"); - return 0; -} +/* systemd-udevd is the same binary as udevadm. This COMMAND intentionally owns no verbs: all of + * udevadm's verbs are defined in udevadm.c right after its own COMMAND, so that they are attributed + * to it. */ +COMMAND( + "systemd-udevd\0", + "Rule-based manager for device events and files.", + .man_pages = "systemd-udevd.service(8)\0", + .option_namespace = "udevd", +); static int parse_argv(int argc, char *argv[], UdevConfig *config) { int r; @@ -185,7 +175,7 @@ static int parse_argv(int argc, char *argv[], UdevConfig *config) { OPTION_NAMESPACE("udevd"): {} OPTION_COMMON_HELP: - return help(); + return command_print_help_name("systemd-udevd"); OPTION('V', "version", NULL, "Show package version"): printf("%s\n", GIT_VERSION); @@ -234,6 +224,9 @@ static int parse_argv(int argc, char *argv[], UdevConfig *config) { else config->timeout_signal = r; break; + + OPTION_COMMON_INTROSPECT_CLI: + return introspect_cli(SD_JSON_FORMAT_OFF); } return 1; diff --git a/src/udev/udevadm-cat.c b/src/udev/udevadm-cat.c index fcce76663e..936455c24a 100644 --- a/src/udev/udevadm-cat.c +++ b/src/udev/udevadm-cat.c @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "sd-json.h" + #include "alloc-util.h" #include "conf-files.h" -#include "format-table.h" -#include "help-util.h" #include "log.h" #include "options.h" #include "parse-argument.h" @@ -11,6 +11,7 @@ #include "static-destruct.h" #include "udevadm.h" #include "udevadm-util.h" +#include "verbs.h" static char *arg_root = NULL; static CatFlags arg_cat_flags = 0; @@ -18,25 +19,6 @@ static bool arg_config = false; STATIC_DESTRUCTOR_REGISTER(arg_root, freep); -static int help(void) { - _cleanup_(table_unrefp) Table *options = NULL; - int r; - - r = option_parser_get_help_table_ns("udevadm-cat", &options); - if (r < 0) - return r; - - help_cmdline("cat [OPTIONS...] [FILE...]"); - help_abstract("Show udev rules files."); - help_section("Options"); - r = table_print_or_warn(options); - if (r < 0) - return r; - - help_man_page_reference("udevadm", "8"); - return 0; -} - static int parse_argv(int argc, char *argv[], char ***remaining_args) { int r; @@ -52,7 +34,7 @@ static int parse_argv(int argc, char *argv[], char ***remaining_args) { OPTION_NAMESPACE("udevadm-cat"): {} OPTION_COMMON_HELP: - return help(); + return command_print_verb_help("cat"); OPTION_COMMON_VERSION_WITH_HIDDEN_V: return print_version(); @@ -73,6 +55,9 @@ static int parse_argv(int argc, char *argv[], char ***remaining_args) { "Show udev.conf rather than udev rules files"): arg_config = true; break; + + OPTION_COMMON_INTROSPECT_CLI: + return introspect_cli(SD_JSON_FORMAT_OFF); } if (arg_config && option_parser_get_n_args(&opts) > 0) diff --git a/src/udev/udevadm-control.c b/src/udev/udevadm-control.c index 54bf1a003b..d1c0ac4e6d 100644 --- a/src/udev/udevadm-control.c +++ b/src/udev/udevadm-control.c @@ -2,9 +2,9 @@ #include +#include "sd-json.h" + #include "creds-util.h" -#include "format-table.h" -#include "help-util.h" #include "log.h" #include "options.h" #include "parse-argument.h" @@ -16,6 +16,7 @@ #include "udev-varlink.h" #include "udevadm.h" #include "varlink-util.h" +#include "verbs.h" #include "virt.h" static char **arg_env = NULL; @@ -45,25 +46,6 @@ static bool arg_has_control_commands(void) { arg_revert; } -static int help(void) { - _cleanup_(table_unrefp) Table *options = NULL; - int r; - - r = option_parser_get_help_table_ns("udevadm-control", &options); - if (r < 0) - return r; - - help_cmdline("control OPTION"); - help_abstract("Control the udev daemon."); - help_section("Options"); - r = table_print_or_warn(options); - if (r < 0) - return r; - - help_man_page_reference("udevadm", "8"); - return 0; -} - static int parse_argv(int argc, char *argv[]) { int r; @@ -78,7 +60,7 @@ static int parse_argv(int argc, char *argv[]) { OPTION_NAMESPACE("udevadm-control"): {} OPTION_COMMON_HELP: - return help(); + return command_print_verb_help("control"); OPTION('V', "version", NULL, "Show package version"): return print_version(); @@ -155,6 +137,9 @@ static int parse_argv(int argc, char *argv[]) { OPTION_LONG("load-credentials", NULL, "Load udev rules from credentials"): arg_load_credentials = true; break; + + OPTION_COMMON_INTROSPECT_CLI: + return introspect_cli(SD_JSON_FORMAT_OFF); } if (!arg_has_control_commands() && !arg_load_credentials) diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c index 0a38e6ee06..143a3a621d 100644 --- a/src/udev/udevadm-hwdb.c +++ b/src/udev/udevadm-hwdb.c @@ -1,13 +1,12 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include +#include "sd-json.h" -#include "format-table.h" -#include "help-util.h" #include "hwdb-util.h" #include "log.h" #include "options.h" #include "udevadm.h" +#include "verbs.h" static const char *arg_test = NULL; static const char *arg_root = NULL; @@ -15,27 +14,6 @@ static const char *arg_hwdb_bin_dir = NULL; static bool arg_update = false; static bool arg_strict = false; -static int help(void) { - _cleanup_(table_unrefp) Table *options = NULL; - int r; - - r = option_parser_get_help_table_ns("udevadm-hwdb", &options); - if (r < 0) - return r; - - help_cmdline("hwdb [OPTIONS]"); - help_abstract("Update or query the hardware database."); - help_section("Options"); - r = table_print_or_warn(options); - if (r < 0) - return r; - - printf("\nNOTE:\n" - "The sub-command 'hwdb' is deprecated, and is left for backwards compatibility.\n" - "Please use systemd-hwdb instead.\n"); - return 0; -} - static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); @@ -48,7 +26,7 @@ static int parse_argv(int argc, char *argv[]) { OPTION_NAMESPACE("udevadm-hwdb"): {} OPTION_COMMON_HELP: - return help(); + return command_print_verb_help("hwdb"); OPTION('V', "version", NULL, "Show package version"): return print_version(); @@ -74,6 +52,9 @@ static int parse_argv(int argc, char *argv[]) { OPTION('r', "root", "PATH", "Alternative root path in the filesystem"): arg_root = opts.arg; break; + + OPTION_COMMON_INTROSPECT_CLI: + return introspect_cli(SD_JSON_FORMAT_OFF); } return 1; diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c index 439cdfd743..4fb9735e47 100644 --- a/src/udev/udevadm-info.c +++ b/src/udev/udevadm-info.c @@ -19,9 +19,7 @@ #include "errno-util.h" #include "fd-util.h" #include "fileio.h" -#include "format-table.h" #include "glyph-util.h" -#include "help-util.h" #include "options.h" #include "pager.h" #include "parse-argument.h" @@ -34,6 +32,7 @@ #include "udev-util.h" #include "udevadm.h" #include "udevadm-util.h" +#include "verbs.h" typedef enum ActionType { ACTION_QUERY, @@ -60,7 +59,6 @@ static bool arg_export = false; static bool arg_value = false; static const char *arg_export_prefix = NULL; static usec_t arg_wait_for_initialization_timeout = 0; -static PagerFlags arg_pager_flags = 0; static sd_json_format_flags_t arg_json_format_flags = SD_JSON_FORMAT_OFF; static ActionType arg_action_type = ACTION_QUERY; static QueryType arg_query = QUERY_ALL; @@ -806,25 +804,6 @@ static int query_device(QueryType query, sd_device* device) { } } -static int help(void) { - _cleanup_(table_unrefp) Table *options = NULL; - int r; - - r = option_parser_get_help_table_ns("udevadm-info", &options); - if (r < 0) - return r; - - help_cmdline("info [OPTIONS] [DEVPATH|FILE]"); - help_abstract("Query sysfs or the udev database."); - help_section("Options"); - r = table_print_or_warn(options); - if (r < 0) - return r; - - help_man_page_reference("udevadm", "8"); - return 0; -} - static int draw_tree( sd_device *parent, sd_device *const array[], size_t n, @@ -996,7 +975,7 @@ static int parse_argv(int argc, char *argv[]) { OPTION_NAMESPACE("udevadm-info"): {} OPTION_COMMON_HELP: - return help(); + return command_print_verb_help("info"); OPTION('V', "version", NULL, "Show package version"): return print_version(); @@ -1179,6 +1158,9 @@ static int parse_argv(int argc, char *argv[]) { "Query devices that are not initialized yet"): arg_initialized_match = MATCH_INITIALIZED_NO; break; + + OPTION_COMMON_INTROSPECT_CLI: + return introspect_cli(arg_json_format_flags); } r = strv_extend_strv(&arg_devices, option_parser_get_args(&opts), /* filter_duplicates= */ false); diff --git a/src/udev/udevadm-lock.c b/src/udev/udevadm-lock.c index fd4b6a9059..f0cc57e43c 100644 --- a/src/udev/udevadm-lock.c +++ b/src/udev/udevadm-lock.c @@ -4,14 +4,14 @@ #include #include +#include "sd-json.h" + #include "blockdev-util.h" #include "device-util.h" #include "fd-util.h" #include "fdset.h" -#include "format-table.h" #include "glyph-util.h" #include "hash-funcs.h" -#include "help-util.h" #include "lock-util.h" #include "options.h" #include "path-util.h" @@ -23,6 +23,7 @@ #include "strv.h" #include "time-util.h" #include "udevadm.h" +#include "verbs.h" static usec_t arg_timeout_usec = USEC_INFINITY; static char **arg_devices = NULL; @@ -34,26 +35,6 @@ STATIC_DESTRUCTOR_REGISTER(arg_devices, strv_freep); STATIC_DESTRUCTOR_REGISTER(arg_backing, strv_freep); STATIC_DESTRUCTOR_REGISTER(arg_cmdline, strv_freep); -static int help(void) { - _cleanup_(table_unrefp) Table *options = NULL; - int r; - - r = option_parser_get_help_table_ns("udevadm-lock", &options); - if (r < 0) - return r; - - help_cmdline("lock [OPTIONS...] COMMAND"); - help_cmdline("lock [OPTIONS...] --print"); - help_abstract("Lock a block device and run a command."); - help_section("Options"); - r = table_print_or_warn(options); - if (r < 0) - return r; - - help_man_page_reference("udevadm", "8"); - return 0; -} - static int parse_argv(int argc, char *argv[]) { int r; @@ -68,7 +49,7 @@ static int parse_argv(int argc, char *argv[]) { OPTION_NAMESPACE("udevadm-lock"): {} OPTION_COMMON_HELP: - return help(); + return command_print_verb_help("lock"); OPTION('V', "version", NULL, "Show package version"): return print_version(); @@ -97,9 +78,12 @@ static int parse_argv(int argc, char *argv[]) { return log_error_errno(r, "Failed to parse --timeout= parameter: %s", opts.arg); break; - OPTION('p', "print", NULL, "Only show which block device the lock would be taken on"): + OPTION('p', "print", NULL, "Only show which device would be locked, without running the command"): arg_print = true; break; + + OPTION_COMMON_INTROSPECT_CLI: + return introspect_cli(SD_JSON_FORMAT_OFF); } char **args = option_parser_get_args(&opts); diff --git a/src/udev/udevadm-monitor.c b/src/udev/udevadm-monitor.c index 76c9d16d1f..ef936cb7d1 100644 --- a/src/udev/udevadm-monitor.c +++ b/src/udev/udevadm-monitor.c @@ -2,21 +2,21 @@ #include "sd-device.h" #include "sd-event.h" +#include "sd-json.h" #include "alloc-util.h" #include "device-monitor-private.h" #include "device-private.h" #include "device-util.h" -#include "format-table.h" #include "format-util.h" #include "hashmap.h" -#include "help-util.h" #include "options.h" #include "set.h" #include "static-destruct.h" #include "string-util.h" #include "time-util.h" #include "udevadm.h" +#include "verbs.h" #include "virt.h" static bool arg_show_property = false; @@ -99,25 +99,6 @@ static int setup_monitor(MonitorNetlinkGroup sender, sd_event *event, sd_device_ return 0; } -static int help(void) { - _cleanup_(table_unrefp) Table *options = NULL; - int r; - - r = option_parser_get_help_table_ns("udevadm-monitor", &options); - if (r < 0) - return r; - - help_cmdline("monitor [OPTIONS]"); - help_abstract("Listen to kernel and udev events."); - help_section("Options"); - r = table_print_or_warn(options); - if (r < 0) - return r; - - help_man_page_reference("udevadm", "8"); - return 0; -} - static int parse_argv(int argc, char *argv[]) { int r; @@ -132,7 +113,7 @@ static int parse_argv(int argc, char *argv[]) { OPTION_NAMESPACE("udevadm-monitor"): {} OPTION_COMMON_HELP: - return help(); + return command_print_verb_help("monitor"); OPTION('V', "version", NULL, "Show package version"): return print_version(); @@ -182,6 +163,9 @@ static int parse_argv(int argc, char *argv[]) { if (r < 0) return log_oom(); break; + + OPTION_COMMON_INTROSPECT_CLI: + return introspect_cli(SD_JSON_FORMAT_OFF); } if (!arg_print_kernel && !arg_print_udev) { diff --git a/src/udev/udevadm-settle.c b/src/udev/udevadm-settle.c index 4398f40e72..dfd00e4b0d 100644 --- a/src/udev/udevadm-settle.c +++ b/src/udev/udevadm-settle.c @@ -8,13 +8,12 @@ #include "sd-bus.h" #include "sd-event.h" +#include "sd-json.h" #include "sd-login.h" #include "sd-messages.h" #include "alloc-util.h" #include "bus-util.h" -#include "format-table.h" -#include "help-util.h" #include "options.h" #include "path-util.h" #include "string-util.h" @@ -24,30 +23,12 @@ #include "udevadm.h" #include "udevadm-util.h" #include "unit-def.h" +#include "verbs.h" #include "virt.h" static usec_t arg_timeout_usec = 120 * USEC_PER_SEC; static const char *arg_exists = NULL; -static int help(void) { - _cleanup_(table_unrefp) Table *options = NULL; - int r; - - r = option_parser_get_help_table_ns("udevadm-settle", &options); - if (r < 0) - return r; - - help_cmdline("settle [OPTIONS]"); - help_abstract("Wait for pending udev events."); - help_section("Options"); - r = table_print_or_warn(options); - if (r < 0) - return r; - - help_man_page_reference("udevadm", "8"); - return 0; -} - static int parse_argv(int argc, char *argv[]) { int r; @@ -62,7 +43,7 @@ static int parse_argv(int argc, char *argv[]) { OPTION_NAMESPACE("udevadm-settle"): {} OPTION_COMMON_HELP: - return help(); + return command_print_verb_help("settle"); OPTION('V', "version", NULL, "Show package version"): return print_version(); @@ -86,6 +67,9 @@ static int parse_argv(int argc, char *argv[]) { return log_info_errno(SYNTHETIC_ERRNO(EINVAL), "Option -%c no longer supported.", opts.opt->short_code); + + OPTION_COMMON_INTROSPECT_CLI: + return introspect_cli(SD_JSON_FORMAT_OFF); } if (option_parser_get_n_args(&opts) > 0) diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c index 3de1366b59..cd8985cae7 100644 --- a/src/udev/udevadm-test-builtin.c +++ b/src/udev/udevadm-test-builtin.c @@ -1,39 +1,21 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "sd-json.h" + #include "device-private.h" #include "device-util.h" -#include "format-table.h" #include "help-util.h" #include "log.h" #include "options.h" #include "udev-builtin.h" #include "udevadm.h" #include "udevadm-util.h" +#include "verbs.h" static sd_device_action_t arg_action = SD_DEVICE_ADD; static const char *arg_command = NULL; static const char *arg_syspath = NULL; -static int help(void) { - _cleanup_(table_unrefp) Table *options = NULL; - int r; - - r = option_parser_get_help_table_ns("udevadm-test-builtin", &options); - if (r < 0) - return r; - - help_cmdline("test-builtin [OPTIONS] COMMAND DEVPATH"); - help_abstract("Test a built-in command."); - help_section("Options"); - r = table_print_or_warn(options); - if (r < 0) - return r; - - help_section("Commands"); - udev_builtin_list(); - return 0; -} - static int parse_argv(int argc, char *argv[]) { int r; @@ -48,7 +30,13 @@ static int parse_argv(int argc, char *argv[]) { OPTION_NAMESPACE("udevadm-test-builtin"): {} OPTION_COMMON_HELP: - return help(); + r = command_print_verb_help("test-builtin"); + if (r < 0) + return r; + + help_section("Commands"); + udev_builtin_list(); + return 0; OPTION('V', "version", NULL, "Show package version"): return print_version(); @@ -58,6 +46,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) != 2) diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c index ba8217c8d3..a496f81b99 100644 --- a/src/udev/udevadm-test.c +++ b/src/udev/udevadm-test.c @@ -11,8 +11,6 @@ #include "alloc-util.h" #include "device-private.h" -#include "format-table.h" -#include "help-util.h" #include "log.h" #include "options.h" #include "parse-argument.h" @@ -24,6 +22,7 @@ #include "udev-rules.h" #include "udevadm.h" #include "udevadm-util.h" +#include "verbs.h" static sd_device_action_t arg_action = SD_DEVICE_ADD; static ResolveNameTiming arg_resolve_name_timing = RESOLVE_NAME_EARLY; @@ -34,25 +33,6 @@ static sd_json_format_flags_t arg_json_format_flags = SD_JSON_FORMAT_OFF; STATIC_DESTRUCTOR_REGISTER(arg_extra_rules_dir, strv_freep); -static int help(void) { - _cleanup_(table_unrefp) Table *options = NULL; - int r; - - r = option_parser_get_help_table_ns("udevadm-test", &options); - if (r < 0) - return r; - - help_cmdline("test [OPTIONS] DEVPATH"); - help_abstract("Test an event run."); - help_section("Options"); - r = table_print_or_warn(options); - if (r < 0) - return r; - - help_man_page_reference("udevadm", "8"); - return 0; -} - static int parse_argv(int argc, char *argv[]) { int r; @@ -67,7 +47,7 @@ static int parse_argv(int argc, char *argv[]) { OPTION_NAMESPACE("udevadm-test"): {} OPTION_COMMON_HELP: - return help(); + return command_print_verb_help("test"); OPTION('V', "version", NULL, "Show package version"): return print_version(); @@ -106,6 +86,9 @@ static int parse_argv(int argc, char *argv[]) { if (r <= 0) return r; break; + + OPTION_COMMON_INTROSPECT_CLI: + return introspect_cli(arg_json_format_flags); } char **args = option_parser_get_args(&opts); diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c index 5d7752783f..bd1d3267d4 100644 --- a/src/udev/udevadm-trigger.c +++ b/src/udev/udevadm-trigger.c @@ -4,13 +4,12 @@ #include "sd-device.h" #include "sd-event.h" +#include "sd-json.h" #include "alloc-util.h" #include "device-enumerator-private.h" #include "device-private.h" #include "device-util.h" -#include "format-table.h" -#include "help-util.h" #include "id128-util.h" #include "options.h" #include "set.h" @@ -20,6 +19,7 @@ #include "time-util.h" #include "udevadm.h" #include "udevadm-util.h" +#include "verbs.h" #include "virt.h" typedef enum { @@ -321,25 +321,6 @@ static int setup_matches(sd_device_enumerator *e) { return 0; } -static int help(void) { - _cleanup_(table_unrefp) Table *options = NULL; - int r; - - r = option_parser_get_help_table_ns("udevadm-trigger", &options); - if (r < 0) - return r; - - help_cmdline("trigger [OPTIONS] DEVPATH"); - help_abstract("Request events from the kernel."); - help_section("Options"); - r = table_print_or_warn(options); - if (r < 0) - return r; - - help_man_page_reference("udevadm", "8"); - return 0; -} - static int parse_argv(int argc, char *argv[]) { int r; @@ -354,7 +335,7 @@ static int parse_argv(int argc, char *argv[]) { OPTION_NAMESPACE("udevadm-trigger"): {} OPTION_COMMON_HELP: - return help(); + return command_print_verb_help("trigger"); OPTION('V', "version", NULL, "Show package version"): return print_version(); @@ -483,6 +464,9 @@ static int parse_argv(int argc, char *argv[]) { if (r < 0) return log_oom(); break; + + OPTION_COMMON_INTROSPECT_CLI: + return introspect_cli(SD_JSON_FORMAT_OFF); } r = strv_extend_strv(&arg_devices, option_parser_get_args(&opts), /* filter_duplicates= */ false); diff --git a/src/udev/udevadm-verify.c b/src/udev/udevadm-verify.c index e7f803dfb1..d850315ca8 100644 --- a/src/udev/udevadm-verify.c +++ b/src/udev/udevadm-verify.c @@ -2,12 +2,12 @@ #include +#include "sd-json.h" + #include "alloc-util.h" #include "ansi-color.h" #include "conf-files.h" #include "errno-util.h" -#include "format-table.h" -#include "help-util.h" #include "log.h" #include "options.h" #include "parse-argument.h" @@ -15,6 +15,7 @@ #include "udev-rules.h" #include "udevadm.h" #include "udevadm-util.h" +#include "verbs.h" static ResolveNameTiming arg_resolve_name_timing = RESOLVE_NAME_EARLY; static char *arg_root = NULL; @@ -23,25 +24,6 @@ static bool arg_style = true; STATIC_DESTRUCTOR_REGISTER(arg_root, freep); -static int help(void) { - _cleanup_(table_unrefp) Table *options = NULL; - int r; - - r = option_parser_get_help_table_ns("udevadm-verify", &options); - if (r < 0) - return r; - - help_cmdline("verify [OPTIONS] [FILE...]"); - help_abstract("Verify udev rules files."); - help_section("Options"); - r = table_print_or_warn(options); - if (r < 0) - return r; - - help_man_page_reference("udevadm", "8"); - return 0; -} - static int parse_argv(int argc, char *argv[], char ***remaining_args) { int r; @@ -57,7 +39,7 @@ static int parse_argv(int argc, char *argv[], char ***remaining_args) { OPTION_NAMESPACE("udevadm-verify"): {} OPTION_COMMON_HELP: - return help(); + return command_print_verb_help("verify"); OPTION('V', "version", NULL, "Show package version"): return print_version(); @@ -81,6 +63,9 @@ static int parse_argv(int argc, char *argv[], char ***remaining_args) { OPTION_LONG("no-style", NULL, "Ignore style issues"): arg_style = false; break; + + OPTION_COMMON_INTROSPECT_CLI: + return introspect_cli(SD_JSON_FORMAT_OFF); } *remaining_args = option_parser_get_args(&opts); diff --git a/src/udev/udevadm-wait.c b/src/udev/udevadm-wait.c index 08c142d5eb..cdee4c8c58 100644 --- a/src/udev/udevadm-wait.c +++ b/src/udev/udevadm-wait.c @@ -4,13 +4,12 @@ #include #include "sd-event.h" +#include "sd-json.h" #include "device-monitor-private.h" #include "device-util.h" #include "event-util.h" -#include "format-table.h" #include "fs-util.h" -#include "help-util.h" #include "options.h" #include "parse-util.h" #include "path-util.h" @@ -21,6 +20,7 @@ #include "time-util.h" #include "udev-util.h" #include "udevadm.h" +#include "verbs.h" typedef enum WaitUntil { WAIT_UNTIL_INITIALIZED, @@ -298,25 +298,6 @@ static int setup_periodic_timer(sd_event *event) { return sd_event_source_set_floating(s, true); } -static int help(void) { - _cleanup_(table_unrefp) Table *options = NULL; - int r; - - r = option_parser_get_help_table_ns("udevadm-wait", &options); - if (r < 0) - return r; - - help_cmdline("wait [OPTIONS] DEVICE [DEVICE…]"); - help_abstract("Wait for devices or device symlinks being created."); - help_section("Options"); - r = table_print_or_warn(options); - if (r < 0) - return r; - - help_man_page_reference("udevadm", "8"); - return 0; -} - static int parse_argv(int argc, char *argv[]) { int r; @@ -331,7 +312,7 @@ static int parse_argv(int argc, char *argv[]) { OPTION_NAMESPACE("udevadm-wait"): {} OPTION_COMMON_HELP: - return help(); + return command_print_verb_help("wait"); OPTION('V', "version", NULL, "Show package version"): return print_version(); @@ -357,6 +338,9 @@ static int parse_argv(int argc, char *argv[]) { OPTION_LONG("settle", NULL, "Also wait for all queued events being processed"): arg_settle = true; break; + + OPTION_COMMON_INTROSPECT_CLI: + return introspect_cli(SD_JSON_FORMAT_OFF); } if (arg_removed) diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c index ebbbadcea0..359c04b30f 100644 --- a/src/udev/udevadm.c +++ b/src/udev/udevadm.c @@ -2,63 +2,50 @@ #include +#include "sd-json.h" + #include "argv-util.h" #include "dlopen-note.h" -#include "format-table.h" -#include "help-util.h" #include "label-util.h" #include "main-func.h" #include "options.h" +#include "pager.h" #include "udev-util.h" #include "udevadm.h" #include "udevd.h" #include "verbs.h" -static int help(void) { - _cleanup_(table_unrefp) Table *verbs = NULL, *options = NULL; - int r; +PagerFlags arg_pager_flags = 0; - r = verbs_get_help_table(&verbs); - if (r < 0) - return r; +COMMAND( + "udevadm\0", + "Send control commands or test the device manager.", + .argspec = "COMMAND [COMMAND OPTION…]\0", + .man_pages = "udevadm(8)\0", + .option_namespace = "udevadm", + .pager_flags = &arg_pager_flags, +); - r = option_parser_get_help_table_ns("udevadm", &options); - if (r < 0) - return r; +/* All verbs are defined here, right after the COMMAND, so that they are attributed to it. Each + * subcommand parses its own options from the "udevadm-" namespace, see udevadm-*.c. */ +VERB_COMMON_HELP_AUTO_PROGRAM("udevadm"); - (void) table_sync_column_widths(0, verbs, options); +#define UDEVADM_VERB(fn, name, args, flags, help, footer) \ + VERB_SCOPE_NS_FULL(, fn, name, "udevadm-" name, args, VERB_ANY, VERB_ANY, flags, /* dat= */ 0, help, footer) - help_cmdline("[OPTIONS…] COMMAND [COMMAND OPTIONS…]"); - help_abstract("Send control commands or test the device manager."); - - help_section("Commands"); - r = table_print_or_warn(verbs); - if (r < 0) - return r; - - help_section("Options"); - r = table_print_or_warn(options); - if (r < 0) - return r; - - help_man_page_reference("udevadm", "8"); - return 0; -} - -VERB_COMMON_HELP(help); - -VERB_SCOPE(, verb_info_main, "info", "[DEVPATH|FILE]", VERB_ANY, VERB_ANY, 0, "Query sysfs or the udev database"); -VERB_SCOPE(, verb_trigger_main, "trigger", "DEVPATH", VERB_ANY, VERB_ANY, 0, "Request events from the kernel"); -VERB_SCOPE(, verb_settle_main, "settle", NULL, VERB_ANY, VERB_ANY, 0, "Wait for pending udev events"); -VERB_SCOPE(, verb_control_main, "control", "OPTION", VERB_ANY, VERB_ANY, 0, "Control the udev daemon"); -VERB_SCOPE(, verb_monitor_main, "monitor", NULL, VERB_ANY, VERB_ANY, 0, "Listen to kernel and udev events"); -VERB_SCOPE(, verb_test_main, "test", "DEVPATH", VERB_ANY, VERB_ANY, 0, "Test an event run"); -VERB_SCOPE(, verb_builtin_main, "test-builtin", "COMMAND DEVPATH", VERB_ANY, VERB_ANY, 0, "Test a built-in command"); -VERB_SCOPE(, verb_verify_main, "verify", "[FILE…]", VERB_ANY, VERB_ANY, 0, "Verify udev rules files"); -VERB_SCOPE(, verb_cat_main, "cat", "[FILE…]", VERB_ANY, VERB_ANY, 0, "Show udev rules files"); -VERB_SCOPE(, verb_wait_main, "wait", "DEVICE [DEVICE…]", VERB_ANY, VERB_ANY, 0, "Wait for device or device symlink"); -VERB_SCOPE(, verb_lock_main, "lock", "[OPTIONS…] COMMAND", VERB_ANY, VERB_ANY, 0, "Lock a block device"); -VERB_SCOPE(, verb_hwdb_main, "hwdb", NULL, VERB_ANY, VERB_ANY, 0, /* help= */ NULL); /* deprecated */ +UDEVADM_VERB(verb_info_main, "info", "[DEVPATH|FILE]\0", 0, "Query sysfs or the udev database", NULL); +UDEVADM_VERB(verb_trigger_main, "trigger", "DEVPATH\0", 0, "Request events from the kernel", NULL); +UDEVADM_VERB(verb_settle_main, "settle", NULL, 0, "Wait for pending udev events", NULL); +UDEVADM_VERB(verb_control_main, "control", NULL, VERB_OPTION_REQUIRED, "Control the udev daemon", NULL); +UDEVADM_VERB(verb_monitor_main, "monitor", NULL, 0, "Listen to kernel and udev events", NULL); +UDEVADM_VERB(verb_test_main, "test", "DEVPATH\0", 0, "Test an event run", NULL); +UDEVADM_VERB(verb_builtin_main, "test-builtin", "COMMAND DEVPATH\0", 0, "Test a built-in command", NULL); +UDEVADM_VERB(verb_verify_main, "verify", "[FILE…]\0", 0, "Verify udev rules files", NULL); +UDEVADM_VERB(verb_cat_main, "cat", "[FILE…]\0", 0, "Show udev rules files", NULL); +UDEVADM_VERB(verb_wait_main, "wait", "DEVICE [DEVICE…]\0", 0, "Wait for device or device symlink", NULL); +UDEVADM_VERB(verb_lock_main, "lock", "COMMAND\0--print\0", 0, "Lock a block device and run a command", NULL); +UDEVADM_VERB(verb_hwdb_main, "hwdb", NULL, VERB_DEPRECATED, "Update or query the hardware database", + "Verb 'hwdb' is deprecated. Use systemd-hwdb instead."); VERB_NOARG(verb_version_main, "version", /* help= */ NULL); static int verb_version_main(int argc, char *argv[], uintptr_t _data, void *userdata) { @@ -78,7 +65,7 @@ static int parse_argv(int argc, char *argv[], char ***remaining_args) { OPTION_NAMESPACE("udevadm"): {} OPTION_COMMON_HELP: - return help(); + return command_print_help_name("udevadm"); OPTION_COMMON_VERSION_WITH_HIDDEN_V: return print_version(); @@ -86,6 +73,9 @@ static int parse_argv(int argc, char *argv[], char ***remaining_args) { OPTION('d', "debug", NULL, "Enable debug logging"): log_set_max_level(LOG_DEBUG); break; + + OPTION_COMMON_INTROSPECT_CLI: + return introspect_cli(SD_JSON_FORMAT_OFF); } *remaining_args = option_parser_get_args(&opts); diff --git a/src/udev/udevadm.h b/src/udev/udevadm.h index 224c0ac4bf..2af2bc646b 100644 --- a/src/udev/udevadm.h +++ b/src/udev/udevadm.h @@ -3,6 +3,8 @@ #include "forward.h" +extern PagerFlags arg_pager_flags; + int verb_cat_main(int argc, char *argv[], uintptr_t _data, void *userdata); int verb_info_main(int argc, char *argv[], uintptr_t _data, void *userdata); int verb_trigger_main(int argc, char *argv[], uintptr_t _data, void *userdata); diff --git a/src/userdb/userdbctl.c b/src/userdb/userdbctl.c index 559a682deb..ef05967a90 100644 --- a/src/userdb/userdbctl.c +++ b/src/userdb/userdbctl.c @@ -418,7 +418,7 @@ static int table_add_uid_map( return n_added; } -VERB(verb_display_user, "user", "[USER…]", VERB_ANY, VERB_ANY, VERB_DEFAULT, +VERB(verb_display_user, "user", "[USER…]\0", VERB_ANY, VERB_ANY, VERB_DEFAULT, "Inspect user"); static int verb_display_user(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(table_unrefp) Table *table = NULL; @@ -763,7 +763,7 @@ static int add_unavailable_gid(Table *table, uid_t start, uid_t end) { return 2; } -VERB(verb_display_group, "group", "[GROUP…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_display_group, "group", "[GROUP…]\0", VERB_ANY, VERB_ANY, 0, "Inspect group"); static int verb_display_group(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(table_unrefp) Table *table = NULL; @@ -966,9 +966,9 @@ static int show_membership(const char *user, const char *group, Table *table) { return 0; } -VERB(verb_display_memberships, "users-in-group", "[GROUP…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_display_memberships, "users-in-group", "[GROUP…]\0", VERB_ANY, VERB_ANY, 0, "Show users that are members of specified groups"); -VERB(verb_display_memberships, "groups-of-user", "[USER…]", VERB_ANY, VERB_ANY, 0, +VERB(verb_display_memberships, "groups-of-user", "[USER…]\0", VERB_ANY, VERB_ANY, 0, "Show groups the specified users are members of"); static int verb_display_memberships(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(table_unrefp) Table *table = NULL; @@ -1131,7 +1131,7 @@ static int verb_display_services(int argc, char *argv[], uintptr_t _data, void * return 0; } -VERB(verb_ssh_authorized_keys, "ssh-authorized-keys", "USER", 2, VERB_ANY, 0, +VERB(verb_ssh_authorized_keys, "ssh-authorized-keys", "USER\0", 2, VERB_ANY, 0, "Show SSH authorized keys for user"); static int verb_ssh_authorized_keys(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(user_record_unrefp) UserRecord *ur = NULL; diff --git a/src/varlinkctl/varlinkctl.c b/src/varlinkctl/varlinkctl.c index 34f47d44ad..8a1a2655b1 100644 --- a/src/varlinkctl/varlinkctl.c +++ b/src/varlinkctl/varlinkctl.c @@ -295,8 +295,8 @@ COMMAND( .pager_flags = &arg_pager_flags, ); -VERB(verb_info, "info", "ADDRESS", 2, 2, 0, "Show service information"); -VERB(verb_info, "list-interfaces", "ADDRESS", 2, 2, 0, "List interfaces implemented by service"); +VERB(verb_info, "info", "ADDRESS\0", 2, 2, 0, "Show service information"); +VERB(verb_info, "list-interfaces", "ADDRESS\0", 2, 2, 0, "List interfaces implemented by service"); static int verb_info(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; const char *url; @@ -390,8 +390,8 @@ typedef struct GetInterfaceDescriptionData { const char *description; } GetInterfaceDescriptionData; -VERB(verb_introspect, "introspect", "ADDRESS [INTERFACE…]", 2, VERB_ANY, 0, "Show interface definition"); -VERB(verb_introspect, "list-methods", "ADDRESS [INTERFACE…]", 2, VERB_ANY, 0, +VERB(verb_introspect, "introspect", "ADDRESS [INTERFACE…]\0", 2, VERB_ANY, 0, "Show interface definition"); +VERB(verb_introspect, "list-methods", "ADDRESS [INTERFACE…]\0", 2, VERB_ANY, 0, "List methods implemented by services or specific interfaces"); static int verb_introspect(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; @@ -709,7 +709,7 @@ static int varlink_call_and_upgrade(const char *url, const char *method, sd_json return 0; } -VERB(verb_call, "call", "ADDRESS METHOD [PARAMS]", 3, VERB_ANY, 0, "Invoke method"); +VERB(verb_call, "call", "ADDRESS METHOD [PARAMS]\0", 3, VERB_ANY, 0, "Invoke method"); static int verb_call(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *jp = NULL; _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; @@ -983,7 +983,7 @@ static int verb_call(int argc, char *argv[], uintptr_t _data, void *userdata) { return 0; } -VERB(verb_validate_idl, "validate-idl", "[FILE]", 1, 2, 0, "Validate interface description"); +VERB(verb_validate_idl, "validate-idl", "[FILE]\0", 1, 2, 0, "Validate interface description"); static int verb_validate_idl(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_varlink_interface_freep) sd_varlink_interface *vi = NULL; _cleanup_free_ char *text = NULL; @@ -1386,7 +1386,7 @@ static int method_serve_upgrade(sd_varlink *link, sd_json_variant *parameters, s return 0; } -VERB(verb_serve, "serve", "METHOD CMDLINE…", 3, VERB_ANY, 0, "Serve a command via varlink protocol upgrade"); +VERB(verb_serve, "serve", "METHOD CMDLINE…\0", 3, VERB_ANY, 0, "Serve a command via varlink protocol upgrade"); static int verb_serve(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(sd_varlink_server_unrefp) sd_varlink_server *s = NULL; _cleanup_(sd_event_unrefp) sd_event *event = NULL; diff --git a/src/veritysetup/veritysetup.c b/src/veritysetup/veritysetup.c index 6e079ac746..cd640bac22 100644 --- a/src/veritysetup/veritysetup.c +++ b/src/veritysetup/veritysetup.c @@ -303,7 +303,7 @@ COMMAND( .man_pages = "systemd-veritysetup@.service(8)\0", ); -VERB(verb_attach, "attach", "VOLUME DATADEVICE HASHDEVICE ROOTHASH [OPTIONS]", 5, 6, 0, +VERB(verb_attach, "attach", "VOLUME DATADEVICE HASHDEVICE ROOTHASH [OPTIONS]\0", 5, 6, 0, "Attach a verity-protected block device"); static int verb_attach(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(crypt_freep) struct crypt_device *cd = NULL; @@ -441,7 +441,7 @@ static int verb_attach(int argc, char *argv[], uintptr_t _data, void *userdata) return 0; } -VERB(verb_detach, "detach", "VOLUME", 2, 2, 0, +VERB(verb_detach, "detach", "VOLUME\0", 2, 2, 0, "Detach a verity-protected block device"); static int verb_detach(int argc, char *argv[], uintptr_t _data, void *userdata) { _cleanup_(crypt_freep) struct crypt_device *cd = NULL; diff --git a/test/units/TEST-74-AUX-UTILS.introspect-cli.sh b/test/units/TEST-74-AUX-UTILS.introspect-cli.sh index c80b1c41eb..8c6e0e0ad3 100755 --- a/test/units/TEST-74-AUX-UTILS.introspect-cli.sh +++ b/test/units/TEST-74-AUX-UTILS.introspect-cli.sh @@ -136,6 +136,7 @@ INTROSPECTABLE=( systemd-tpm2-clear systemd-tpm2-setup systemd-tty-ask-password-agent + systemd-udevd systemd-umount systemd-update-done systemd-validatefs @@ -143,6 +144,7 @@ INTROSPECTABLE=( systemd-vmspawn systemd-vpick timedatectl + udevadm updatectl userdbctl v4l_id @@ -208,6 +210,35 @@ fi systemd-id128 --introspect-cli | jq -e \ '.commands[0].verbs | map(.names[0]) | contains(["new", "machine-id", "show", "help"])' +# udevadm's verbs carry their own options, reported recursively +udevadm --introspect-cli | jq -e \ + '.commands[] | select(.names[0] == "udevadm") | .verbs[] | select(.names[0] == "info") | + [.options[].names[-1]] | contains(["--query", "--json", "--no-pager"])' + +udevadm --introspect-cli | jq -e \ + '.commands[] | select(.names[0] == "udevadm") | .verbs[] | + select(.names[0] == "hwdb") | .isDeprecated == true' + +# udevadm print has multiple argspecs. Check that we print them. +udevadm lock -h | grep -E '^> udevadm .* lock .* COMMAND$' +udevadm lock -h | grep -E '^> udevadm .* lock .* --print$' + +# udevadm is also systemd-udevd +udevadm --introspect-cli | jq -e \ + '[.commands[].names[0]] | sort == ["systemd-udevd", "udevadm"]' + +# The systemd-udevd command must own no verbs: the help-verb check in the loop above relies on +# this to never run 'systemd-udevd help', which would start the daemon. +udevadm --introspect-cli | jq -e \ + '.commands[] | select(.names[0] == "systemd-udevd") | (.verbs // []) == []' + +# Each subcommand's help and introspection must work +for v in cat control hwdb info lock monitor settle test test-builtin trigger verify wait; do + udevadm "$v" --help >/dev/null + udevadm "$v" --introspect-cli | jq -e \ + '.mediaType == "application/vnd.io.systemd.cli-introspection-0"' +done + # systemd is optionally a multicall binary that also provides systemd-executor if [[ "$(readlink "$(command -v systemd-executor)" 2>/dev/null)" == systemd ]]; then systemd --introspect-cli | jq -e \