From: Zbigniew Jędrzejewski-Szmek Date: Thu, 16 Apr 2026 08:20:39 +0000 (+0200) Subject: import-fs: convert to the new option and verb parsers X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=94ec4b98438e65dc8741045c213ab21f2abe2bf9;p=thirdparty%2Fsystemd.git import-fs: convert to the new option and verb parsers --help is the same except for whitespace. Co-developed-by: Claude Opus 4.6 --- diff --git a/src/import/import-fs.c b/src/import/import-fs.c index 4b2394d4147..3605320300d 100644 --- a/src/import/import-fs.c +++ b/src/import/import-fs.c @@ -1,6 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include #include #include @@ -11,6 +10,7 @@ #include "copy.h" #include "discover-image.h" #include "fd-util.h" +#include "format-table.h" #include "format-util.h" #include "import-common.h" #include "import-util.h" @@ -18,6 +18,7 @@ #include "log.h" #include "main-func.h" #include "mkdir-label.h" +#include "options.h" #include "parse-argument.h" #include "path-util.h" #include "ratelimit.h" @@ -107,6 +108,8 @@ static int progress_bytes(uint64_t nbytes, uint64_t bps, void *userdata) { return 0; } +VERB(verb_import_fs, "run", "DIRECTORY [NAME]", 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; _cleanup_(progress_info_free) ProgressInfo progress = { .bps = UINT64_MAX }; @@ -266,145 +269,115 @@ static int verb_import_fs(int argc, char *argv[], uintptr_t _data, void *userdat } static int help(void) { - printf("%1$s [OPTIONS...] {COMMAND} ...\n" - "\n%4$sImport container images from a file system directories.%5$s\n" - "\n%2$sCommands:%3$s\n" - " run DIRECTORY [NAME] Import a directory\n" - "\n%2$sOptions:%3$s\n" - " -h --help Show this help\n" - " --version Show package version\n" - " --force Force creation of image\n" - " --image-root=PATH Image root directory\n" - " --read-only Create a read-only image\n" - " --direct Import directly to specified directory\n" - " --btrfs-subvol=BOOL Controls whether to create a btrfs subvolume\n" - " instead of a directory\n" - " --btrfs-quota=BOOL Controls whether to set up quota for btrfs\n" - " subvolume\n" - " --sync=BOOL Controls whether to sync() before completing\n" - " --class=CLASS Select image class (machine, sysext, confext,\n" - " portable)\n" - " --system Operate in per-system mode\n" - " --user Operate in per-user mode\n", + _cleanup_(table_unrefp) Table *options = NULL, *verbs = NULL; + int r; + + r = verbs_get_help_table(&verbs); + if (r < 0) + return r; + + r = option_parser_get_help_table(&options); + if (r < 0) + return r; + + (void) table_sync_column_widths(0, verbs, options); + + printf("%s [OPTIONS...] {COMMAND} ...\n\n" + "%sImport container images from file system directories.%s\n" + "\n%sCommands:%s\n", program_invocation_short_name, - ansi_underline(), - ansi_normal(), ansi_highlight(), + ansi_normal(), + ansi_underline(), ansi_normal()); - return 0; -} + r = table_print_or_warn(verbs); + if (r < 0) + return r; + + printf("\n%sOptions:%s\n", + ansi_underline(), + ansi_normal()); + + r = table_print_or_warn(options); + if (r < 0) + return r; -static int verb_help(int argc, char *argv[], uintptr_t _data, void *userdata) { - return help(); + return 0; } -static int parse_argv(int argc, char *argv[]) { - enum { - ARG_VERSION = 0x100, - ARG_FORCE, - ARG_IMAGE_ROOT, - ARG_READ_ONLY, - ARG_DIRECT, - ARG_BTRFS_SUBVOL, - ARG_BTRFS_QUOTA, - ARG_SYNC, - ARG_CLASS, - ARG_SYSTEM, - ARG_USER, - }; - - static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "force", no_argument, NULL, ARG_FORCE }, - { "image-root", required_argument, NULL, ARG_IMAGE_ROOT }, - { "read-only", no_argument, NULL, ARG_READ_ONLY }, - { "direct", no_argument, NULL, ARG_DIRECT }, - { "btrfs-subvol", required_argument, NULL, ARG_BTRFS_SUBVOL }, - { "btrfs-quota", required_argument, NULL, ARG_BTRFS_QUOTA }, - { "sync", required_argument, NULL, ARG_SYNC }, - { "class", required_argument, NULL, ARG_CLASS }, - { "system", no_argument, NULL, ARG_SYSTEM }, - { "user", no_argument, NULL, ARG_USER }, - {} - }; - - int c, r; +VERB_COMMON_HELP_HIDDEN(help); +static int parse_argv(int argc, char *argv[], char ***ret_args) { assert(argc >= 0); assert(argv); + assert(ret_args); - while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) + OptionParser state = { argc, argv }; + const char *arg; + int r; + 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 ARG_FORCE: + OPTION_LONG("force", NULL, "Force creation of image"): arg_force = true; break; - case ARG_IMAGE_ROOT: - r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_image_root); + OPTION_LONG("image-root", "PATH", "Image root directory"): + r = parse_path_argument(arg, /* suppress_root= */ false, &arg_image_root); if (r < 0) return r; - break; - case ARG_READ_ONLY: + OPTION_LONG("read-only", NULL, "Create a read-only image"): arg_read_only = true; break; - case ARG_DIRECT: + OPTION_LONG("direct", NULL, "Import directly to specified directory"): arg_direct = true; break; - case ARG_BTRFS_SUBVOL: - r = parse_boolean_argument("--btrfs-subvol=", optarg, &arg_btrfs_subvol); + OPTION_LONG("btrfs-subvol", "BOOL", + "Controls whether to create a btrfs subvolume instead of a directory"): + r = parse_boolean_argument("--btrfs-subvol=", arg, &arg_btrfs_subvol); if (r < 0) return r; - break; - case ARG_BTRFS_QUOTA: - r = parse_boolean_argument("--btrfs-quota=", optarg, &arg_btrfs_quota); + OPTION_LONG("btrfs-quota", "BOOL", + "Controls whether to set up quota for btrfs subvolume"): + r = parse_boolean_argument("--btrfs-quota=", arg, &arg_btrfs_quota); if (r < 0) return r; - break; - case ARG_SYNC: - r = parse_boolean_argument("--sync=", optarg, &arg_sync); + OPTION_LONG("sync", "BOOL", "Controls whether to sync() before completing"): + r = parse_boolean_argument("--sync=", arg, &arg_sync); if (r < 0) return r; - break; - case ARG_CLASS: - arg_class = image_class_from_string(optarg); + OPTION_LONG("class", "CLASS", + "Select image class (machine, sysext, confext, portable)"): + arg_class = image_class_from_string(arg); if (arg_class < 0) - return log_error_errno(arg_class, "Failed to parse --class= argument: %s", optarg); - + return log_error_errno(arg_class, "Failed to parse --class= argument: %s", arg); break; - case ARG_SYSTEM: + OPTION_LONG("system", NULL, "Operate in per-system mode"): arg_runtime_scope = RUNTIME_SCOPE_SYSTEM; break; - case ARG_USER: + OPTION_LONG("user", NULL, "Operate in per-user mode"): arg_runtime_scope = RUNTIME_SCOPE_USER; break; - - case '?': - return -EINVAL; - - default: - assert_not_reached(); } if (!arg_image_root) { @@ -413,31 +386,22 @@ static int parse_argv(int argc, char *argv[]) { return log_error_errno(r, "Failed to pick image root: %m"); } + *ret_args = option_parser_get_args(&state); return 1; } -static int import_fs_main(int argc, char *argv[]) { - - static const Verb verbs[] = { - { "help", VERB_ANY, VERB_ANY, 0, verb_help }, - { "run", 2, 3, 0, verb_import_fs }, - {} - }; - - return dispatch_verb(argc, argv, verbs, NULL); -} - static int run(int argc, char *argv[]) { int r; setlocale(LC_ALL, ""); log_setup(); - r = parse_argv(argc, argv); + char **args = NULL; + r = parse_argv(argc, argv, &args); if (r <= 0) return r; - return import_fs_main(argc, argv); + return dispatch_verb_with_args(args, NULL); } DEFINE_MAIN_FUNCTION(run);