]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
hostnamectl: use the new option and verb macros
authorZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Wed, 25 Mar 2026 14:56:02 +0000 (15:56 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Thu, 26 Mar 2026 22:39:28 +0000 (23:39 +0100)
--help is the same except for strings in common options.

Co-developed-by: Claude <claude@anthropic.com>
src/hostname/hostnamectl.c

index 75a17a13aeeac6abfc04fce5c05584583d0e4db9..52fa3319d70700a56105cc3df09035ad37e901f5 100644 (file)
@@ -1,6 +1,5 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <getopt.h>
 #include <linux/vm_sockets.h>
 #include <locale.h>
 #include <string.h>
@@ -23,6 +22,7 @@
 #include "hostname-util.h"
 #include "log.h"
 #include "main-func.h"
+#include "options.h"
 #include "parse-argument.h"
 #include "polkit-agent.h"
 #include "pretty-print.h"
@@ -549,6 +549,7 @@ static int get_hostname_based_on_flag(sd_bus *bus) {
         return get_one_name(bus, attr, NULL);
 }
 
+VERB(verb_show_status, "status", NULL, VERB_ANY, 1, VERB_DEFAULT, "Show current hostname settings");
 static int verb_show_status(int argc, char *argv[], uintptr_t _data, void *userdata) {
         sd_bus *bus = userdata;
         int r;
@@ -687,26 +688,36 @@ 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 */
 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 */
 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 */
 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 */
 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 */
 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]);
@@ -714,164 +725,108 @@ static int verb_get_or_set_location(int argc, char *argv[], uintptr_t _data, voi
 
 static int help(void) {
         _cleanup_free_ char *link = NULL;
+        _cleanup_(table_unrefp) Table *options = NULL, *verbs = NULL;
         int r;
 
         r = terminal_urlify_man("hostnamectl", "1", &link);
         if (r < 0)
                 return log_oom();
 
-        printf("%1$s [OPTIONS...] COMMAND ...\n\n"
-               "%2$sQuery or change system hostname.%3$s\n"
-               "\n%4$sCommands:%5$s\n"
-               "  status                 Show current hostname settings\n"
-               "  hostname [NAME]        Get/set system hostname\n"
-               "  icon-name [NAME]       Get/set icon name for host\n"
-               "  chassis [NAME]         Get/set chassis type for host\n"
-               "  deployment [NAME]      Get/set deployment environment for host\n"
-               "  location [NAME]        Get/set location for host\n"
-               "\n%4$sOptions:%5$s\n"
-               "  -h --help              Show this help\n"
-               "     --version           Show package version\n"
-               "     --no-ask-password   Do not prompt for password\n"
-               "  -H --host=[USER@]HOST  Operate on remote host\n"
-               "  -M --machine=CONTAINER Operate on local container\n"
-               "     --transient         Only set transient hostname\n"
-               "     --static            Only set static hostname\n"
-               "     --pretty            Only set pretty hostname\n"
-               "     --json=pretty|short|off\n"
-               "                         Generate JSON output\n"
-               "  -j                     Same as --json=pretty on tty, --json=short otherwise\n"
-               "\nSee the %6$s for details.\n",
+        r = option_parser_get_help_table(&options);
+        if (r < 0)
+                return r;
+
+        r = verbs_get_help_table(&verbs);
+        if (r < 0)
+                return r;
+
+        (void) table_sync_column_widths(0, options, verbs);
+
+        printf("%s [OPTIONS...] COMMAND ...\n"
+               "\n%sQuery or change system hostname.%s\n"
+               "\nCommands:\n",
                program_invocation_short_name,
                ansi_highlight(),
-               ansi_normal(),
-               ansi_underline(),
-               ansi_normal(),
-               link);
+               ansi_normal());
+        table_print(verbs, stdout);
 
-        return 0;
-}
+        printf("\nOptions:\n");
+        table_print(options, stdout);
 
-static int verb_help(int argc, char *argv[], uintptr_t _data, void *userdata) {
-        return help();
+        printf("\nSee the %s for details.\n", link);
+        return 0;
 }
 
-static int parse_argv(int argc, char *argv[]) {
-
-        enum {
-                ARG_VERSION = 0x100,
-                ARG_NO_ASK_PASSWORD,
-                ARG_TRANSIENT,
-                ARG_STATIC,
-                ARG_PRETTY,
-                ARG_JSON,
-        };
-
-        static const struct option options[] = {
-                { "help",            no_argument,       NULL, 'h'                 },
-                { "version",         no_argument,       NULL, ARG_VERSION         },
-                { "transient",       no_argument,       NULL, ARG_TRANSIENT       },
-                { "static",          no_argument,       NULL, ARG_STATIC          },
-                { "pretty",          no_argument,       NULL, ARG_PRETTY          },
-                { "host",            required_argument, NULL, 'H'                 },
-                { "machine",         required_argument, NULL, 'M'                 },
-                { "no-ask-password", no_argument,       NULL, ARG_NO_ASK_PASSWORD },
-                { "json",            required_argument, NULL, ARG_JSON            },
-                {}
-        };
+VERB_COMMON_HELP_HIDDEN(help);
 
-        int c, r;
+static int parse_argv(int argc, char *argv[], char ***ret_args) {
+        int r;
 
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hH:M:j", options, NULL)) >= 0)
+        OptionParser state = { argc, argv };
+        const char *arg;
 
+        FOREACH_OPTION(&state, c, &arg, /* on_error= */ return c)
                 switch (c) {
-
-                case 'h':
+                OPTION_COMMON_HELP:
                         return help();
 
-                case ARG_VERSION:
+                OPTION_COMMON_VERSION:
                         return version();
 
-                case 'H':
+                OPTION_COMMON_NO_ASK_PASSWORD:
+                        arg_ask_password = false;
+                        break;
+
+                OPTION_COMMON_HOST:
                         arg_transport = BUS_TRANSPORT_REMOTE;
-                        arg_host = optarg;
+                        arg_host = arg;
                         break;
 
-                case 'M':
-                        r = parse_machine_argument(optarg, &arg_host, &arg_transport);
+                OPTION_COMMON_MACHINE:
+                        r = parse_machine_argument(arg, &arg_host, &arg_transport);
                         if (r < 0)
                                 return r;
                         break;
 
-                case ARG_TRANSIENT:
+                OPTION_LONG("transient", NULL, "Only set transient hostname"):
                         arg_transient = true;
                         break;
 
-                case ARG_PRETTY:
-                        arg_pretty = true;
-                        break;
-
-                case ARG_STATIC:
+                OPTION_LONG("static", NULL, "Only set static hostname"):
                         arg_static = true;
                         break;
 
-                case ARG_NO_ASK_PASSWORD:
-                        arg_ask_password = false;
+                OPTION_LONG("pretty", NULL, "Only set pretty hostname"):
+                        arg_pretty = true;
                         break;
 
-                case ARG_JSON:
-                        r = parse_json_argument(optarg, &arg_json_format_flags);
+                OPTION_COMMON_JSON:
+                        r = parse_json_argument(arg, &arg_json_format_flags);
                         if (r <= 0)
                                 return r;
-
                         break;
 
-                case 'j':
+                OPTION_COMMON_LOWERCASE_J:
                         arg_json_format_flags = SD_JSON_FORMAT_PRETTY_AUTO|SD_JSON_FORMAT_COLOR_AUTO;
                         break;
-
-                case '?':
-                        return -EINVAL;
-
-                default:
-                        assert_not_reached();
                 }
 
+        *ret_args = option_parser_get_args(&state);
         return 1;
 }
 
-static int hostnamectl_main(sd_bus *bus, int argc, char *argv[]) {
-
-        static const Verb verbs[] = {
-                { "status",         VERB_ANY, 1,        VERB_DEFAULT, verb_show_status           },
-                { "hostname",       VERB_ANY, 2,        0,            verb_get_or_set_hostname   },
-                { "set-hostname",   2,        2,        0,            verb_get_or_set_hostname   }, /* obsolete */
-                { "icon-name",      VERB_ANY, 2,        0,            verb_get_or_set_icon_name  },
-                { "set-icon-name",  2,        2,        0,            verb_get_or_set_icon_name  }, /* obsolete */
-                { "chassis",        VERB_ANY, 2,        0,            verb_get_or_set_chassis    },
-                { "set-chassis",    2,        2,        0,            verb_get_or_set_chassis    }, /* obsolete */
-                { "deployment",     VERB_ANY, 2,        0,            verb_get_or_set_deployment },
-                { "set-deployment", 2,        2,        0,            verb_get_or_set_deployment }, /* obsolete */
-                { "location",       VERB_ANY, 2,        0,            verb_get_or_set_location   },
-                { "set-location",   2,        2,        0,            verb_get_or_set_location   }, /* obsolete */
-                { "help",           VERB_ANY, VERB_ANY, 0,            verb_help                  }, /* Not documented, but supported since it is created. */
-                {}
-        };
-
-        return dispatch_verb(argc, argv, verbs, bus);
-}
-
 static int run(int argc, char *argv[]) {
         _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+        char **args = NULL;
         int r;
 
         setlocale(LC_ALL, "");
         log_setup();
 
-        r = parse_argv(argc, argv);
+        r = parse_argv(argc, argv, &args);
         if (r <= 0)
                 return r;
 
@@ -879,7 +834,7 @@ static int run(int argc, char *argv[]) {
         if (r < 0)
                 return bus_log_connect_error(r, arg_transport, RUNTIME_SCOPE_SYSTEM);
 
-        return hostnamectl_main(bus, argc, argv);
+        return dispatch_verb_with_args(args, bus);
 }
 
 DEFINE_MAIN_FUNCTION(run);