From: Daan De Meyer Date: Wed, 8 Apr 2026 14:31:00 +0000 (+0000) Subject: journal-remote: convert to the new option parser X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fcff95831909f0ff9eb8be6ac61c411bc09fa566;p=thirdparty%2Fsystemd.git journal-remote: convert to the new option parser Replace the getopt_long()-based parser with the FOREACH_OPTION / OPTION_* macros from src/shared/options.h, mirroring the recent conversions of nspawn and vmspawn. Each option's metadata (long name, short name, metavar and help text) now lives next to its parsing logic, and the --help text is generated from those definitions via option_parser_get_help_table() instead of being hard-coded. Positional file arguments are collected via option_parser_get_args() rather than strv_skip(argv, optind). --- diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c index 9cb84bbe1e6..d5277ad7ef1 100644 --- a/src/journal-remote/journal-remote-main.c +++ b/src/journal-remote/journal-remote-main.c @@ -1,6 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include #include #include "sd-daemon.h" @@ -12,6 +11,7 @@ #include "daemon-util.h" #include "extract-word.h" #include "fd-util.h" +#include "format-table.h" #include "format-util.h" #include "fileio.h" #include "hashmap.h" @@ -21,6 +21,7 @@ #include "logs-show.h" #include "main-func.h" #include "microhttpd-util.h" +#include "options.h" #include "parse-argument.h" #include "parse-helpers.h" #include "parse-util.h" @@ -838,155 +839,120 @@ static int parse_config(void) { static int help(void) { _cleanup_free_ char *link = NULL; + _cleanup_(table_unrefp) Table *options = NULL; int r; r = terminal_urlify_man("systemd-journal-remote.service", "8", &link); if (r < 0) return log_oom(); - printf("%s [OPTIONS...] {FILE|-}...\n\n" - "Write external journal events to journal file(s).\n\n" - " -h --help Show this help\n" - " --version Show package version\n" - " --url=URL Read events from systemd-journal-gatewayd at URL\n" - " --getter=COMMAND Read events from the output of COMMAND\n" - " --listen-raw=ADDR Listen for connections at ADDR\n" - " --listen-http=ADDR Listen for HTTP connections at ADDR\n" - " --listen-https=ADDR Listen for HTTPS connections at ADDR\n" - " -o --output=FILE|DIR Write output to FILE or DIR/external-*.journal\n" - " --compress[=BOOL] Use compression in the output journal (default: yes)\n" - " --seal[=BOOL] Use event sealing (default: no)\n" - " --key=FILENAME SSL key in PEM format (default:\n" - " \"" PRIV_KEY_FILE "\")\n" - " --cert=FILENAME SSL certificate in PEM format (default:\n" - " \"" CERT_FILE "\")\n" - " --trust=FILENAME|all SSL CA certificate or disable checking (default:\n" - " \"" TRUST_FILE "\")\n" - " --gnutls-log=CATEGORY...\n" - " Specify a list of gnutls logging categories\n" - " --split-mode=none|host How many output files to create\n" - "\nNote: file descriptors from sd_listen_fds() will be consumed, too.\n" - "\nSee the %s for details.\n", + r = option_parser_get_help_table(&options); + if (r < 0) + return r; + + printf("%s [OPTIONS...] {FILE|-}...\n" + "\n%sWrite external journal events to journal file(s).%s\n" + "\n%sOptions:%s\n", program_invocation_short_name, + ansi_highlight(), + ansi_normal(), + ansi_underline(), + ansi_normal()); + + r = table_print_or_warn(options); + if (r < 0) + return r; + + printf("\nNote: file descriptors from sd_listen_fds() will be consumed, too.\n" + "\nSee the %s for details.\n", link); return 0; } static int parse_argv(int argc, char *argv[]) { - enum { - ARG_VERSION = 0x100, - ARG_URL, - ARG_LISTEN_RAW, - ARG_LISTEN_HTTP, - ARG_LISTEN_HTTPS, - ARG_GETTER, - ARG_SPLIT_MODE, - ARG_COMPRESS, - ARG_SEAL, - ARG_KEY, - ARG_CERT, - ARG_TRUST, - ARG_GNUTLS_LOG, - }; - - static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "url", required_argument, NULL, ARG_URL }, - { "getter", required_argument, NULL, ARG_GETTER }, - { "listen-raw", required_argument, NULL, ARG_LISTEN_RAW }, - { "listen-http", required_argument, NULL, ARG_LISTEN_HTTP }, - { "listen-https", required_argument, NULL, ARG_LISTEN_HTTPS }, - { "output", required_argument, NULL, 'o' }, - { "split-mode", required_argument, NULL, ARG_SPLIT_MODE }, - { "compress", optional_argument, NULL, ARG_COMPRESS }, - { "seal", optional_argument, NULL, ARG_SEAL }, - { "key", required_argument, NULL, ARG_KEY }, - { "cert", required_argument, NULL, ARG_CERT }, - { "trust", required_argument, NULL, ARG_TRUST }, - { "gnutls-log", required_argument, NULL, ARG_GNUTLS_LOG }, - {} - }; - - int c, r; + int r; bool type_a, type_b; assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "ho:", 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 ARG_URL: - r = free_and_strdup_warn(&arg_url, optarg); + OPTION_LONG("url", "URL", "Read events from systemd-journal-gatewayd at URL"): + r = free_and_strdup_warn(&arg_url, arg); if (r < 0) return r; break; - case ARG_GETTER: - r = free_and_strdup_warn(&arg_getter, optarg); + OPTION_LONG("getter", "COMMAND", "Read events from the output of COMMAND"): + r = free_and_strdup_warn(&arg_getter, arg); if (r < 0) return r; break; - case ARG_LISTEN_RAW: - r = free_and_strdup_warn(&arg_listen_raw, optarg); + OPTION_LONG("listen-raw", "ADDR", "Listen for connections at ADDR"): + r = free_and_strdup_warn(&arg_listen_raw, arg); if (r < 0) return r; break; - case ARG_LISTEN_HTTP: + OPTION_LONG("listen-http", "ADDR", "Listen for HTTP connections at ADDR"): if (arg_listen_http || http_socket >= 0) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot currently use --listen-http= more than once"); - r = negative_fd(optarg); + r = negative_fd(arg); if (r >= 0) http_socket = r; else { - r = free_and_strdup_warn(&arg_listen_http, optarg); + r = free_and_strdup_warn(&arg_listen_http, arg); if (r < 0) return r; } break; - case ARG_LISTEN_HTTPS: + OPTION_LONG("listen-https", "ADDR", "Listen for HTTPS connections at ADDR"): if (arg_listen_https || https_socket >= 0) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot currently use --listen-https= more than once"); - r = negative_fd(optarg); + r = negative_fd(arg); if (r >= 0) https_socket = r; else { - r = free_and_strdup_warn(&arg_listen_https, optarg); + r = free_and_strdup_warn(&arg_listen_https, arg); if (r < 0) return r; } break; - case ARG_KEY: - r = free_and_strdup_warn(&arg_key, optarg); + OPTION_LONG("key", "FILENAME", "SSL key in PEM format (default: \"" PRIV_KEY_FILE "\")"): + r = free_and_strdup_warn(&arg_key, arg); if (r < 0) return r; break; - case ARG_CERT: - r = free_and_strdup_warn(&arg_cert, optarg); + OPTION_LONG("cert", "FILENAME", "SSL certificate in PEM format (default: \"" CERT_FILE "\")"): + r = free_and_strdup_warn(&arg_cert, arg); if (r < 0) return r; break; - case ARG_TRUST: + OPTION_LONG("trust", "FILENAME|all", + "SSL CA certificate or disable checking (default: \"" TRUST_FILE "\")"): #if HAVE_GNUTLS - r = free_and_strdup_warn(&arg_trust, optarg); + r = free_and_strdup_warn(&arg_trust, arg); if (r < 0) return r; #else @@ -994,33 +960,35 @@ static int parse_argv(int argc, char *argv[]) { #endif break; - case 'o': - r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_output); + OPTION('o', "output", "FILE|DIR", "Write output to FILE or DIR/external-*.journal"): + r = parse_path_argument(arg, /* suppress_root= */ false, &arg_output); if (r < 0) return r; break; - case ARG_SPLIT_MODE: - arg_split_mode = journal_write_split_mode_from_string(optarg); + OPTION_LONG("split-mode", "none|host", "How many output files to create"): + arg_split_mode = journal_write_split_mode_from_string(arg); if (arg_split_mode == _JOURNAL_WRITE_SPLIT_INVALID) - return log_error_errno(arg_split_mode, "Invalid split mode: %s", optarg); + return log_error_errno(arg_split_mode, "Invalid split mode: %s", arg); break; - case ARG_COMPRESS: - r = parse_boolean_argument("--compress", optarg, &arg_compress); + OPTION_LONG_FLAGS(OPTION_OPTIONAL_ARG, "compress", "BOOL", + "Use compression in the output journal (default: yes)"): + r = parse_boolean_argument("--compress", arg, &arg_compress); if (r < 0) return r; break; - case ARG_SEAL: - r = parse_boolean_argument("--seal", optarg, &arg_seal); + OPTION_LONG_FLAGS(OPTION_OPTIONAL_ARG, "seal", "BOOL", + "Use event sealing (default: no)"): + r = parse_boolean_argument("--seal", arg, &arg_seal); if (r < 0) return r; break; - case ARG_GNUTLS_LOG: + OPTION_LONG("gnutls-log", "CATEGORY,...", "Specify a list of gnutls logging categories"): #if HAVE_GNUTLS - for (const char *p = optarg;;) { + for (const char *p = arg;;) { _cleanup_free_ char *word = NULL; r = extract_first_word(&p, &word, ",", 0); @@ -1036,15 +1004,9 @@ static int parse_argv(int argc, char *argv[]) { return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Option --gnutls-log= is not available."); #endif break; - - case '?': - return -EINVAL; - - default: - assert_not_reached(); } - arg_files = strv_copy(strv_skip(argv, optind)); + arg_files = strv_copy(option_parser_get_args(&state)); if (!arg_files) return log_oom();