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).
This commit is contained in:
committed by
Daan De Meyer
parent
e57c8aa0a0
commit
fcff958319
@@ -1,6 +1,5 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user