A batch of conversions to the new options parsers (#41302)
This was partially done with Claude, but it needed an insane amount of prodding to not do stupid things.
This commit is contained in:
@@ -14264,7 +14264,7 @@ CHANGES WITH 235:
|
||||
the "utmp" group already, and it appears to be generally understood
|
||||
that members of "utmp" can modify/flush the utmp/wtmp/lastlog/btmp
|
||||
databases. Previously this was implemented correctly for all these
|
||||
databases excepts btmp, which has been opened up like this now
|
||||
databases except btmp, which has been opened up like this now
|
||||
too. Note that while the other databases are world-readable
|
||||
(i.e. 0644), btmp is not and remains more restrictive.
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
||||
+23
-44
@@ -1,13 +1,13 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "battery-util.h"
|
||||
#include "build.h"
|
||||
#include "format-table.h"
|
||||
#include "log.h"
|
||||
#include "main-func.h"
|
||||
#include "options.h"
|
||||
#include "pretty-print.h"
|
||||
#include "string-util.h"
|
||||
|
||||
@@ -20,77 +20,56 @@ static enum {
|
||||
|
||||
static int help(void) {
|
||||
_cleanup_free_ char *link = NULL;
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
r = terminal_urlify_man("systemd-ac-power", "1", &link);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
printf("%1$s [OPTION]\n"
|
||||
"\n%2$sReport whether we are connected to an external power source.%3$s\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Show package version\n"
|
||||
" -v --verbose Show state as text\n"
|
||||
" --low Check if battery is discharging and low\n"
|
||||
"\nSee the %4$s for details.\n",
|
||||
r = option_parser_get_help_table(&options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
printf("%s [OPTIONS...]\n"
|
||||
"\n%sReport whether we are connected to an external power source.%s\n"
|
||||
"\nOptions:\n",
|
||||
program_invocation_short_name,
|
||||
ansi_highlight(),
|
||||
ansi_normal(),
|
||||
link);
|
||||
ansi_normal());
|
||||
table_print(options, stdout);
|
||||
|
||||
printf("\nSee the %s for details.\n", link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
enum {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_LOW,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "low", no_argument, NULL, ARG_LOW },
|
||||
{}
|
||||
};
|
||||
|
||||
int c;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "hv", options, NULL)) >= 0)
|
||||
OptionParser state = {};
|
||||
const char *arg;
|
||||
|
||||
FOREACH_OPTION(&state, c, argc, argv, &arg, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
|
||||
case 'h':
|
||||
help();
|
||||
return 0;
|
||||
|
||||
case ARG_VERSION:
|
||||
OPTION_COMMON_VERSION:
|
||||
return version();
|
||||
|
||||
case 'v':
|
||||
OPTION('v', "verbose", NULL, "Show state as text"):
|
||||
arg_verbose = true;
|
||||
break;
|
||||
|
||||
case ARG_LOW:
|
||||
OPTION_LONG("low", NULL, "Check if battery is discharging and low"):
|
||||
arg_action = ACTION_LOW;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"%s takes no arguments.",
|
||||
program_invocation_short_name);
|
||||
if (option_parser_get_n_args(&state, argc, argv) > 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments.");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
+51
-105
@@ -1,6 +1,5 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sd-varlink.h"
|
||||
@@ -10,10 +9,12 @@
|
||||
#include "build.h"
|
||||
#include "bus-polkit.h"
|
||||
#include "constants.h"
|
||||
#include "format-table.h"
|
||||
#include "hashmap.h"
|
||||
#include "json-util.h"
|
||||
#include "log.h"
|
||||
#include "main-func.h"
|
||||
#include "options.h"
|
||||
#include "parse-argument.h"
|
||||
#include "pretty-print.h"
|
||||
#include "string-table.h"
|
||||
@@ -39,124 +40,72 @@ STATIC_DESTRUCTOR_REGISTER(arg_message, freep);
|
||||
|
||||
static int help(void) {
|
||||
_cleanup_free_ char *link = NULL;
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
r = terminal_urlify_man("systemd-ask-password", "1", &link);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
printf("%1$s [OPTIONS...] MESSAGE\n\n"
|
||||
"%3$sQuery the user for a passphrase, via the TTY or a UI agent.%4$s\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" --icon=NAME Icon name\n"
|
||||
" --id=ID Query identifier (e.g. \"cryptsetup:/dev/sda5\")\n"
|
||||
" --keyname=NAME Kernel key name for caching passwords (e.g. \"cryptsetup\")\n"
|
||||
" --credential=NAME\n"
|
||||
" Credential name for ImportCredential=, LoadCredential= or\n"
|
||||
" SetCredential= credentials\n"
|
||||
" --timeout=SEC Timeout in seconds\n"
|
||||
" --echo=yes|no|masked\n"
|
||||
" Control whether to show password while typing (echo)\n"
|
||||
" -e --echo Equivalent to --echo=yes\n"
|
||||
" --emoji=yes|no|auto\n"
|
||||
" Show a lock and key emoji\n"
|
||||
" --no-tty Ask question via agent even on TTY\n"
|
||||
" --accept-cached Accept cached passwords\n"
|
||||
" --multiple List multiple passwords if available\n"
|
||||
" --no-output Do not print password to standard output\n"
|
||||
" -n Do not suffix password written to standard output with\n"
|
||||
" newline\n"
|
||||
" --user Ask only our own user's agents\n"
|
||||
" --system Ask agents of the system and of all users\n"
|
||||
"\nSee the %2$s for details.\n",
|
||||
r = option_parser_get_help_table(&options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
printf("%s [OPTIONS...] MESSAGE\n"
|
||||
"\n%sQuery the user for a passphrase, via the TTY or a UI agent.%s\n"
|
||||
"\nOptions:\n",
|
||||
program_invocation_short_name,
|
||||
link,
|
||||
ansi_highlight(),
|
||||
ansi_normal());
|
||||
table_print(options, stdout);
|
||||
|
||||
printf("\nSee the %s for details.\n", link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
enum {
|
||||
ARG_ICON = 0x100,
|
||||
ARG_TIMEOUT,
|
||||
ARG_EMOJI,
|
||||
ARG_NO_TTY,
|
||||
ARG_ACCEPT_CACHED,
|
||||
ARG_MULTIPLE,
|
||||
ARG_ID,
|
||||
ARG_KEYNAME,
|
||||
ARG_NO_OUTPUT,
|
||||
ARG_VERSION,
|
||||
ARG_CREDENTIAL,
|
||||
ARG_USER,
|
||||
ARG_SYSTEM,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "icon", required_argument, NULL, ARG_ICON },
|
||||
{ "timeout", required_argument, NULL, ARG_TIMEOUT },
|
||||
{ "echo", optional_argument, NULL, 'e' },
|
||||
{ "emoji", required_argument, NULL, ARG_EMOJI },
|
||||
{ "no-tty", no_argument, NULL, ARG_NO_TTY },
|
||||
{ "accept-cached", no_argument, NULL, ARG_ACCEPT_CACHED },
|
||||
{ "multiple", no_argument, NULL, ARG_MULTIPLE },
|
||||
{ "id", required_argument, NULL, ARG_ID },
|
||||
{ "keyname", required_argument, NULL, ARG_KEYNAME },
|
||||
{ "no-output", no_argument, NULL, ARG_NO_OUTPUT },
|
||||
{ "credential", required_argument, NULL, ARG_CREDENTIAL },
|
||||
{ "user", no_argument, NULL, ARG_USER },
|
||||
{ "system", no_argument, NULL, ARG_SYSTEM },
|
||||
{}
|
||||
};
|
||||
|
||||
const char *emoji = NULL;
|
||||
int c, r;
|
||||
int r;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
/* Note the asymmetry: the long option --echo= allows an optional argument, the short option does
|
||||
* not. */
|
||||
|
||||
/* Resetting to 0 forces the invocation of an internal initialization routine of getopt_long()
|
||||
* that checks for GNU extensions in optstring ('-' or '+' at the beginning). */
|
||||
optind = 0;
|
||||
while ((c = getopt_long(argc, argv, "+hen", options, NULL)) >= 0)
|
||||
OptionParser state = {};
|
||||
const char *arg;
|
||||
|
||||
FOREACH_OPTION(&state, c, argc, argv, &arg, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
|
||||
case 'h':
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
|
||||
case ARG_VERSION:
|
||||
OPTION_COMMON_VERSION:
|
||||
return version();
|
||||
|
||||
case ARG_ICON:
|
||||
arg_icon = optarg;
|
||||
OPTION_LONG("icon", "NAME", "Icon name"):
|
||||
arg_icon = arg;
|
||||
break;
|
||||
|
||||
case ARG_TIMEOUT:
|
||||
r = parse_sec(optarg, &arg_timeout);
|
||||
OPTION_LONG("timeout", "SEC", "Timeout in seconds"):
|
||||
r = parse_sec(arg, &arg_timeout);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse --timeout= parameter: %s", optarg);
|
||||
|
||||
return log_error_errno(r, "Failed to parse --timeout= parameter: %s", arg);
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
if (!optarg) {
|
||||
/* Note the asymmetry: the long option --echo= allows an optional argument,
|
||||
* the short option does not. */
|
||||
OPTION_LONG_FLAGS(OPTION_OPTIONAL_ARG, "echo", "yes|no|masked",
|
||||
"Control whether to show password while typing"): {}
|
||||
OPTION('e', "echo", NULL, "Equivalent to --echo=yes"):
|
||||
if (!arg) {
|
||||
/* Short option -e is used, or no argument to long option --echo= */
|
||||
arg_flags |= ASK_PASSWORD_ECHO;
|
||||
arg_flags &= ~ASK_PASSWORD_SILENT;
|
||||
} else if (isempty(optarg) || streq(optarg, "masked"))
|
||||
} else if (isempty(arg) || streq(arg, "masked"))
|
||||
/* Empty argument or explicit string "masked" for default behaviour. */
|
||||
arg_flags &= ~(ASK_PASSWORD_ECHO|ASK_PASSWORD_SILENT);
|
||||
else {
|
||||
r = parse_boolean_argument("--echo=", optarg, NULL);
|
||||
r = parse_boolean_argument("--echo=", arg, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -165,55 +114,50 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
}
|
||||
break;
|
||||
|
||||
case ARG_EMOJI:
|
||||
emoji = optarg;
|
||||
OPTION_LONG("emoji", "yes|no|auto", "Show a lock and key emoji"):
|
||||
emoji = arg;
|
||||
break;
|
||||
|
||||
case ARG_NO_TTY:
|
||||
OPTION_LONG("no-tty", NULL, "Ask question via agent even on TTY"):
|
||||
arg_flags |= ASK_PASSWORD_NO_TTY;
|
||||
break;
|
||||
|
||||
case ARG_ACCEPT_CACHED:
|
||||
OPTION_LONG("accept-cached", NULL, "Accept cached passwords"):
|
||||
arg_flags |= ASK_PASSWORD_ACCEPT_CACHED;
|
||||
break;
|
||||
|
||||
case ARG_MULTIPLE:
|
||||
OPTION_LONG("multiple", NULL, "List multiple passwords if available"):
|
||||
arg_multiple = true;
|
||||
break;
|
||||
|
||||
case ARG_ID:
|
||||
arg_id = optarg;
|
||||
OPTION_LONG("id", "ID", "Query identifier (e.g. \"cryptsetup:/dev/sda5\")"):
|
||||
arg_id = arg;
|
||||
break;
|
||||
|
||||
case ARG_KEYNAME:
|
||||
arg_key_name = optarg;
|
||||
OPTION_LONG("keyname", "NAME", "Kernel key name for caching passwords"):
|
||||
arg_key_name = arg;
|
||||
break;
|
||||
|
||||
case ARG_NO_OUTPUT:
|
||||
OPTION_LONG("no-output", NULL, "Do not print password to standard output"):
|
||||
arg_no_output = true;
|
||||
break;
|
||||
|
||||
case ARG_CREDENTIAL:
|
||||
arg_credential_name = optarg;
|
||||
OPTION_LONG("credential", "NAME",
|
||||
"Credential name for ImportCredential=, LoadCredential= or SetCredential= credentials"):
|
||||
arg_credential_name = arg;
|
||||
break;
|
||||
|
||||
case ARG_USER:
|
||||
OPTION_LONG("user", NULL, "Ask only our own user's agents"):
|
||||
arg_flags |= ASK_PASSWORD_USER;
|
||||
break;
|
||||
|
||||
case ARG_SYSTEM:
|
||||
OPTION_LONG("system", NULL, "Ask agents of the system and of all users"):
|
||||
arg_flags &= ~ASK_PASSWORD_USER;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
OPTION_SHORT('n', NULL, "Do not suffix password written to standard output with newline"):
|
||||
arg_newline = false;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
if (isempty(emoji) || streq(emoji, "auto"))
|
||||
@@ -226,8 +170,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
SET_FLAG(arg_flags, ASK_PASSWORD_HIDE_EMOJI, !r);
|
||||
}
|
||||
|
||||
if (argc > optind) {
|
||||
arg_message = strv_join(argv + optind, " ");
|
||||
char **args = option_parser_get_args(&state, argc, argv);
|
||||
|
||||
if (!strv_isempty(args)) {
|
||||
arg_message = strv_join(args, " ");
|
||||
if (!arg_message)
|
||||
return log_oom();
|
||||
} else if (FLAGS_SET(arg_flags, ASK_PASSWORD_ECHO)) {
|
||||
|
||||
+34
-51
@@ -1,6 +1,5 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -12,8 +11,10 @@
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "format-table.h"
|
||||
#include "log.h"
|
||||
#include "main-func.h"
|
||||
#include "options.h"
|
||||
#include "pager.h"
|
||||
#include "path-util.h"
|
||||
#include "pretty-print.h"
|
||||
@@ -108,88 +109,69 @@ static int cat_config(char **files) {
|
||||
|
||||
static int help(void) {
|
||||
_cleanup_free_ char *link = NULL;
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
r = terminal_urlify_man("systemd-binfmt.service", "8", &link);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
|
||||
"Registers binary formats with the kernel.\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Show package version\n"
|
||||
" --cat-config Show configuration files\n"
|
||||
" --tldr Show non-comment parts of configuration\n"
|
||||
" --no-pager Do not pipe output into a pager\n"
|
||||
" --unregister Unregister all existing entries\n"
|
||||
"\nSee the %s for details.\n",
|
||||
program_invocation_short_name,
|
||||
link);
|
||||
r = option_parser_get_help_table(&options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n"
|
||||
"\n%sRegisters binary formats with the kernel.%s\n"
|
||||
"\nOptions:\n",
|
||||
program_invocation_short_name,
|
||||
ansi_highlight(),
|
||||
ansi_normal());
|
||||
table_print(options, stdout);
|
||||
|
||||
printf("\nSee the %s for details.\n", link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
enum {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_CAT_CONFIG,
|
||||
ARG_TLDR,
|
||||
ARG_NO_PAGER,
|
||||
ARG_UNREGISTER,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "cat-config", no_argument, NULL, ARG_CAT_CONFIG },
|
||||
{ "tldr", no_argument, NULL, ARG_TLDR },
|
||||
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
||||
{ "unregister", no_argument, NULL, ARG_UNREGISTER },
|
||||
{}
|
||||
};
|
||||
|
||||
int c;
|
||||
static int parse_argv(int argc, char *argv[], char ***ret_args) {
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
|
||||
OptionParser state = {};
|
||||
const char *arg;
|
||||
|
||||
FOREACH_OPTION(&state, c, argc, argv, &arg, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
|
||||
case 'h':
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
|
||||
case ARG_VERSION:
|
||||
OPTION_COMMON_VERSION:
|
||||
return version();
|
||||
|
||||
case ARG_CAT_CONFIG:
|
||||
OPTION_COMMON_CAT_CONFIG:
|
||||
arg_cat_flags = CAT_CONFIG_ON;
|
||||
break;
|
||||
|
||||
case ARG_TLDR:
|
||||
OPTION_COMMON_TLDR:
|
||||
arg_cat_flags = CAT_TLDR;
|
||||
break;
|
||||
|
||||
case ARG_NO_PAGER:
|
||||
OPTION_COMMON_NO_PAGER:
|
||||
arg_pager_flags |= PAGER_DISABLE;
|
||||
break;
|
||||
|
||||
case ARG_UNREGISTER:
|
||||
OPTION_LONG("unregister", NULL, "Unregister all existing entries"):
|
||||
arg_unregister = true;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
if ((arg_unregister || arg_cat_flags != CAT_CONFIG_OFF) && argc > optind)
|
||||
char **args = option_parser_get_args(&state, argc, argv);
|
||||
|
||||
if ((arg_unregister || arg_cat_flags != CAT_CONFIG_OFF) && !strv_isempty(args))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Positional arguments are not allowed with --cat-config/--tldr or --unregister.");
|
||||
|
||||
*ret_args = args;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -208,7 +190,8 @@ static int binfmt_mounted_and_writable_warn(void) {
|
||||
static int run(int argc, char *argv[]) {
|
||||
int r;
|
||||
|
||||
r = parse_argv(argc, argv);
|
||||
char **args = NULL;
|
||||
r = parse_argv(argc, argv, &args);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@@ -221,13 +204,13 @@ static int run(int argc, char *argv[]) {
|
||||
if (arg_unregister)
|
||||
return disable_binfmt();
|
||||
|
||||
if (argc > optind) {
|
||||
if (!strv_isempty(args)) {
|
||||
r = binfmt_mounted_and_writable_warn();
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
for (int i = optind; i < argc; i++)
|
||||
RET_GATHER(r, apply_file(argv[i], false));
|
||||
STRV_FOREACH(f, args)
|
||||
RET_GATHER(r, apply_file(*f, false));
|
||||
|
||||
} else {
|
||||
_cleanup_strv_free_ char **files = NULL;
|
||||
|
||||
+42
-53
@@ -1,6 +1,5 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
@@ -9,9 +8,11 @@
|
||||
#include "efivars.h"
|
||||
#include "fd-util.h"
|
||||
#include "find-esp.h"
|
||||
#include "format-table.h"
|
||||
#include "fs-util.h"
|
||||
#include "log.h"
|
||||
#include "main-func.h"
|
||||
#include "options.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "pretty-print.h"
|
||||
@@ -34,76 +35,65 @@ typedef enum Status {
|
||||
|
||||
static int help(void) {
|
||||
_cleanup_free_ char *link = NULL;
|
||||
_cleanup_(table_unrefp) Table *options = NULL, *verbs = NULL;
|
||||
int r;
|
||||
|
||||
r = terminal_urlify_man("systemd-bless-boot.service", "8", &link);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
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_width(options, 0, verbs, 0);
|
||||
|
||||
printf("%s [OPTIONS...] COMMAND\n"
|
||||
"\n%sMark the boot process as good or bad.%s\n"
|
||||
"\nCommands:\n"
|
||||
" status Show status of current boot loader entry\n"
|
||||
" good Mark this boot as good\n"
|
||||
" bad Mark this boot as bad\n"
|
||||
" indeterminate Undo any marking as good or bad\n"
|
||||
"\nOptions:\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Print version\n"
|
||||
" --path=PATH Path to the $BOOT partition (may be used multiple times)\n"
|
||||
"\nSee the %s for details.\n",
|
||||
"\nCommands:\n",
|
||||
program_invocation_short_name,
|
||||
ansi_highlight(),
|
||||
ansi_normal(),
|
||||
link);
|
||||
ansi_normal());
|
||||
table_print(verbs, stdout);
|
||||
|
||||
printf("\nOptions:\n");
|
||||
table_print(options, stdout);
|
||||
|
||||
printf("\nSee the %s for details.\n", link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int verb_help(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
return help();
|
||||
}
|
||||
VERB_COMMON_HELP_HIDDEN(help);
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
enum {
|
||||
ARG_PATH = 0x100,
|
||||
ARG_VERSION,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "path", required_argument, NULL, ARG_PATH },
|
||||
{}
|
||||
};
|
||||
|
||||
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, "h", options, NULL)) >= 0)
|
||||
switch (c) {
|
||||
OptionParser state = {};
|
||||
const char *arg;
|
||||
|
||||
case 'h':
|
||||
FOREACH_OPTION(&state, c, argc, argv, &arg, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
|
||||
case ARG_VERSION:
|
||||
OPTION_COMMON_VERSION:
|
||||
return version();
|
||||
|
||||
case ARG_PATH:
|
||||
r = strv_extend(&arg_path, optarg);
|
||||
OPTION_LONG("path", "PATH", "Path to the $BOOT partition (may be used multiple times)"):
|
||||
r = strv_extend(&arg_path, arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
*ret_args = option_parser_get_args(&state, argc, argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -344,6 +334,7 @@ static int make_bad(const char *prefix, uint64_t done, const char *suffix, char
|
||||
return 0;
|
||||
}
|
||||
|
||||
VERB(verb_status, "status", NULL, VERB_ANY, 1, VERB_DEFAULT, "Show status of current boot loader entry");
|
||||
static int verb_status(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
_cleanup_free_ char *path = NULL, *prefix = NULL, *suffix = NULL, *good = NULL, *bad = NULL;
|
||||
uint64_t left, done;
|
||||
@@ -451,6 +442,12 @@ static int rename_in_dir_idempotent(int fd, const char *from, const char *to) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
VERB_FULL(verb_set, "good", NULL, VERB_ANY, 1, 0, STATUS_GOOD,
|
||||
"Mark this boot as good");
|
||||
VERB_FULL(verb_set, "bad", NULL, VERB_ANY, 1, 0, STATUS_BAD,
|
||||
"Mark this boot as bad");
|
||||
VERB_FULL(verb_set, "indeterminate", NULL, VERB_ANY, 1, 0, STATUS_INDETERMINATE,
|
||||
"Undo any marking as good or bad");
|
||||
static int verb_set(int argc, char *argv[], uintptr_t data, void *userdata) {
|
||||
_cleanup_free_ char *path = NULL, *prefix = NULL, *suffix = NULL, *good = NULL, *bad = NULL;
|
||||
const char *target, *source1, *source2;
|
||||
@@ -561,20 +558,12 @@ exists:
|
||||
}
|
||||
|
||||
static int run(int argc, char *argv[]) {
|
||||
static const Verb verbs[] = {
|
||||
{ "help", VERB_ANY, VERB_ANY, 0, verb_help },
|
||||
{ "status", VERB_ANY, 1, VERB_DEFAULT, verb_status },
|
||||
{ "good", VERB_ANY, 1, 0, verb_set, STATUS_GOOD },
|
||||
{ "bad", VERB_ANY, 1, 0, verb_set, STATUS_BAD },
|
||||
{ "indeterminate", VERB_ANY, 1, 0, verb_set, STATUS_INDETERMINATE },
|
||||
{}
|
||||
};
|
||||
|
||||
char **args = NULL;
|
||||
int r;
|
||||
|
||||
log_setup();
|
||||
|
||||
r = parse_argv(argc, argv);
|
||||
r = parse_argv(argc, argv, &args);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@@ -586,7 +575,7 @@ static int run(int argc, char *argv[]) {
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"Marking a boot is only supported on EFI systems.");
|
||||
|
||||
return dispatch_verb(argc, argv, verbs, NULL);
|
||||
return dispatch_verb_with_args(args, NULL);
|
||||
}
|
||||
|
||||
DEFINE_MAIN_FUNCTION(run);
|
||||
|
||||
@@ -143,6 +143,7 @@
|
||||
|
||||
#define XCONCATENATE(x, y) x ## y
|
||||
#define CONCATENATE(x, y) XCONCATENATE(x, y)
|
||||
#define CONCATENATE3(x, y, z) CONCATENATE(x, CONCATENATE(y, z))
|
||||
|
||||
#define assert_cc(expr) _Static_assert(expr, #expr)
|
||||
|
||||
|
||||
+1
-1
@@ -189,7 +189,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
if (optind + 1 != argc)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"%s excepts exactly one argument (the mount point).",
|
||||
"%s expects exactly one argument (the mount point).",
|
||||
program_invocation_short_name);
|
||||
|
||||
arg_target = argv[optind];
|
||||
|
||||
@@ -21,7 +21,8 @@ static bool option_arg_required(const Option *opt) {
|
||||
|
||||
static bool option_is_metadata(const Option *opt) {
|
||||
/* A metadata entry that is not a real option, like the group marker */
|
||||
return FLAGS_SET(ASSERT_PTR(opt)->flags, OPTION_GROUP_MARKER);
|
||||
return FLAGS_SET(ASSERT_PTR(opt)->flags, OPTION_GROUP_MARKER) ||
|
||||
FLAGS_SET(ASSERT_PTR(opt)->flags, OPTION_HELP_ENTRY);
|
||||
}
|
||||
|
||||
static void kill_arg(char* argv[], int argc, int index) {
|
||||
@@ -240,7 +241,7 @@ int option_parse(
|
||||
return option->id;
|
||||
}
|
||||
|
||||
char** option_parser_get_args(OptionParser *state, int argc, char *argv[]) {
|
||||
char** option_parser_get_args(const OptionParser *state, int argc, char *argv[]) {
|
||||
/* Returns positional args as a strv.
|
||||
* If "--" was found, it has been removed. */
|
||||
|
||||
@@ -274,8 +275,6 @@ int _option_parser_get_help_table(
|
||||
if (group_marker)
|
||||
break; /* End of group */
|
||||
|
||||
assert(!option_is_metadata(opt));
|
||||
|
||||
if (!opt->help)
|
||||
/* No help string — we do not show the option */
|
||||
continue;
|
||||
|
||||
+13
-1
@@ -2,11 +2,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "shared-forward.h"
|
||||
#include "strv.h"
|
||||
|
||||
typedef enum OptionFlags {
|
||||
OPTION_OPTIONAL_ARG = 1U << 0, /* Same as optional_argument in getopt */
|
||||
OPTION_STOPS_PARSING = 1U << 1, /* This option acts like "--" */
|
||||
OPTION_GROUP_MARKER = 1U << 2, /* Fake option entry to separate groups */
|
||||
OPTION_HELP_ENTRY = 1U << 3, /* Fake option entry to insert an additional help line */
|
||||
} OptionFlags;
|
||||
|
||||
typedef struct Option {
|
||||
@@ -43,7 +45,9 @@ typedef struct Option {
|
||||
#define OPTION_FULL(fl, sc, lc, mv, h) _OPTION(__COUNTER__, fl, sc, lc, mv, h)
|
||||
#define OPTION(sc, lc, mv, h) OPTION_FULL(/* fl= */ 0, sc, lc, mv, h)
|
||||
#define OPTION_LONG(lc, mv, h) OPTION(/* sc= */ 0, lc, mv, h)
|
||||
#define OPTION_LONG_FLAGS(fl, lc, mv, h) OPTION_FULL(fl, /* sc= */ 0, lc, mv, h)
|
||||
#define OPTION_SHORT(sc, mv, h) OPTION(sc, /* lc= */ NULL, mv, h)
|
||||
#define OPTION_SHORT_FLAGS(fl, sc, mv, h) OPTION_FULL(fl, sc, /* lc= */ NULL, mv, h)
|
||||
|
||||
#define OPTION_COMMON_HELP \
|
||||
OPTION('h', "help", NULL, "Show this help")
|
||||
@@ -53,6 +57,10 @@ typedef struct Option {
|
||||
OPTION_LONG("no-pager", NULL, "Do not start a pager")
|
||||
#define OPTION_COMMON_NO_LEGEND \
|
||||
OPTION_LONG("no-legend", NULL, "Do not show headers and footers")
|
||||
#define OPTION_COMMON_CAT_CONFIG \
|
||||
OPTION_LONG("cat-config", NULL, "Show configuration files")
|
||||
#define OPTION_COMMON_TLDR \
|
||||
OPTION_LONG("tldr", NULL, "Show non-comment parts of configuration")
|
||||
#define OPTION_COMMON_JSON \
|
||||
OPTION_LONG("json", "FORMAT", "Generate JSON output (pretty, short, or off)")
|
||||
|
||||
@@ -89,7 +97,11 @@ int option_parse(
|
||||
#define FOREACH_OPTION(parser, opt, argc, argv, ret_a, on_error) \
|
||||
FOREACH_OPTION_FULL(parser, opt, argc, argv, /* ret_o= */ NULL, ret_a, on_error)
|
||||
|
||||
char** option_parser_get_args(OptionParser *state, int argc, char *argv[]);
|
||||
char** option_parser_get_args(const OptionParser *state, int argc, char *argv[]);
|
||||
static inline size_t option_parser_get_n_args(const OptionParser *state, int argc, char *argv[]) {
|
||||
return strv_length(option_parser_get_args(state, argc, argv));
|
||||
}
|
||||
|
||||
int _option_parser_get_help_table(
|
||||
const Option options[],
|
||||
const Option options_end[],
|
||||
|
||||
+4
-2
@@ -160,6 +160,9 @@ int _verbs_get_help_table(const Verb verbs[], const Verb verbs_end[], Table **re
|
||||
for (const Verb *verb = verbs; verb < verbs_end; verb++) {
|
||||
assert(verb->dispatch);
|
||||
|
||||
if (!verb->help)
|
||||
continue;
|
||||
|
||||
/* 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. */
|
||||
@@ -170,8 +173,7 @@ int _verbs_get_help_table(const Verb verbs[], const Verb verbs_end[], Table **re
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
|
||||
const char *help = verb->help ?: "FIXME";
|
||||
_cleanup_strv_free_ char **s = strv_split(help, /* separators= */ NULL);
|
||||
_cleanup_strv_free_ char **s = strv_split(verb->help, /* separators= */ NULL);
|
||||
if (!s)
|
||||
return log_oom();
|
||||
|
||||
|
||||
+12
-3
@@ -21,13 +21,15 @@ typedef struct {
|
||||
} Verb;
|
||||
|
||||
#define VERB_FULL(d, v, a, amin, amax, f, dat, h) \
|
||||
DISABLE_WARNING_REDUNDANT_DECLS \
|
||||
static int d(int, char**, uintptr_t, void*); \
|
||||
REENABLE_WARNING \
|
||||
_section_("SYSTEMD_VERBS") \
|
||||
_alignptr_ \
|
||||
_used_ \
|
||||
_retain_ \
|
||||
_variable_no_sanitize_address_ \
|
||||
static const Verb CONCATENATE(d, _data) = { \
|
||||
static const Verb CONCATENATE3(d, _data_, __COUNTER__) = { \
|
||||
.verb = v, \
|
||||
.min_args = amin, \
|
||||
.max_args = amax, \
|
||||
@@ -66,8 +68,15 @@ int _verbs_get_help_table(const Verb verbs[], const Verb verbs_end[], Table **re
|
||||
#define verbs_get_help_table(ret) \
|
||||
_verbs_get_help_table(ALIGN_PTR(__start_SYSTEMD_VERBS), __stop_SYSTEMD_VERBS, ret)
|
||||
|
||||
#define VERB_COMMON_HELP(impl) \
|
||||
VERB(verb_help, "help", NULL, VERB_ANY, VERB_ANY, 0, "Show this help"); \
|
||||
#define _VERB_COMMON_HELP_IMPL(impl) \
|
||||
static int verb_help(int argc, char **argv, uintptr_t data, void *userdata) { \
|
||||
return impl(); \
|
||||
}
|
||||
|
||||
#define VERB_COMMON_HELP(impl) \
|
||||
VERB(verb_help, "help", NULL, VERB_ANY, VERB_ANY, 0, "Show this help"); \
|
||||
_VERB_COMMON_HELP_IMPL(impl)
|
||||
|
||||
#define VERB_COMMON_HELP_HIDDEN(impl) \
|
||||
VERB(verb_help, "help", NULL, VERB_ANY, VERB_ANY, 0, NULL); \
|
||||
_VERB_COMMON_HELP_IMPL(impl)
|
||||
|
||||
@@ -57,6 +57,8 @@ static void test_option_parse_one(
|
||||
char **args = option_parser_get_args(&state, argc, argv);
|
||||
ASSERT_TRUE(strv_equal(args, remaining));
|
||||
ASSERT_STREQ(argv[0], saved_argv0);
|
||||
|
||||
ASSERT_EQ(option_parser_get_n_args(&state, argc, argv), strv_length(remaining));
|
||||
}
|
||||
|
||||
static void test_option_invalid_one(
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "build.h"
|
||||
#include "chase.h"
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "format-table.h"
|
||||
#include "label-util.h"
|
||||
#include "log.h"
|
||||
#include "main-func.h"
|
||||
#include "options.h"
|
||||
#include "parse-argument.h"
|
||||
#include "pretty-print.h"
|
||||
#include "string-util.h"
|
||||
@@ -61,65 +63,56 @@ static int save_timestamp(const char *dir, struct timespec *ts) {
|
||||
|
||||
static int help(void) {
|
||||
_cleanup_free_ char *link = NULL;
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
r = terminal_urlify_man("systemd-update-done", "8", &link);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
printf("%1$s [OPTIONS...]\n\n"
|
||||
"%5$sMark /etc/ and /var/ as fully updated.%6$s\n"
|
||||
"\n%3$sOptions:%4$s\n"
|
||||
" -h --help Show this help\n"
|
||||
" --root=PATH Operate on root directory PATH\n"
|
||||
"\nSee the %2$s for details.\n",
|
||||
program_invocation_short_name,
|
||||
link,
|
||||
ansi_underline(),
|
||||
ansi_normal(),
|
||||
ansi_highlight(),
|
||||
ansi_normal());
|
||||
r = option_parser_get_help_table(&options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
printf("%s [OPTIONS...]\n"
|
||||
"\n%sMark /etc/ and /var/ as fully updated.%s\n"
|
||||
"\n%sOptions:%s\n",
|
||||
program_invocation_short_name,
|
||||
ansi_highlight(),
|
||||
ansi_normal(),
|
||||
ansi_underline(),
|
||||
ansi_normal());
|
||||
table_print(options, stdout);
|
||||
|
||||
printf("\nSee the %s for details.\n", link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
enum {
|
||||
ARG_ROOT = 0x100,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "root", required_argument, NULL, ARG_ROOT },
|
||||
{},
|
||||
};
|
||||
|
||||
int r, c;
|
||||
int r;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
|
||||
OptionParser state = {};
|
||||
const char *arg;
|
||||
|
||||
FOREACH_OPTION(&state, c, argc, argv, &arg, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
|
||||
case 'h':
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
|
||||
case ARG_ROOT:
|
||||
r = parse_path_argument(optarg, /* suppress_root= */ true, &arg_root);
|
||||
OPTION_COMMON_VERSION:
|
||||
return version();
|
||||
|
||||
OPTION_LONG("root", "PATH", "Operate on root directory PATH"):
|
||||
r = parse_path_argument(arg, /* suppress_root= */ true, &arg_root);
|
||||
if (r < 0)
|
||||
return r;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
if (option_parser_get_n_args(&state, argc, argv) > 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments.");
|
||||
|
||||
return 1;
|
||||
|
||||
+36
-52
@@ -1,7 +1,5 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#include "sd-device.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
@@ -12,11 +10,13 @@
|
||||
#include "device-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "format-table.h"
|
||||
#include "gpt.h"
|
||||
#include "initrd-util.h"
|
||||
#include "log.h"
|
||||
#include "main-func.h"
|
||||
#include "mountpoint-util.h"
|
||||
#include "options.h"
|
||||
#include "parse-argument.h"
|
||||
#include "path-util.h"
|
||||
#include "pretty-print.h"
|
||||
@@ -32,93 +32,77 @@ STATIC_DESTRUCTOR_REGISTER(arg_target, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
||||
|
||||
static int help(void) {
|
||||
_cleanup_free_ char *link = NULL;
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
_cleanup_free_ char *link = NULL;
|
||||
r = terminal_urlify_man("systemd-validatefs@.service", "8", &link);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
printf("%1$s [OPTIONS...] /path/to/mountpoint\n"
|
||||
"\n%3$sCheck file system validation constraints.%4$s\n\n"
|
||||
" -h --help Show this help and exit\n"
|
||||
" --version Print version string and exit\n"
|
||||
" --root=PATH|auto Operate relative to the specified path\n"
|
||||
"\nSee the %2$s for details.\n",
|
||||
r = option_parser_get_help_table(&options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
printf("%s [OPTIONS...] /path/to/mountpoint\n"
|
||||
"\n%sCheck file system validation constraints.%s\n"
|
||||
"\nOptions:\n",
|
||||
program_invocation_short_name,
|
||||
link,
|
||||
ansi_highlight(),
|
||||
ansi_normal());
|
||||
table_print(options, stdout);
|
||||
|
||||
printf("\nSee the %s for details.\n", link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
enum {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_ROOT,
|
||||
};
|
||||
|
||||
int c, r;
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version" , no_argument, NULL, ARG_VERSION },
|
||||
{ "root", required_argument, NULL, ARG_ROOT },
|
||||
{}
|
||||
};
|
||||
int r;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
|
||||
OptionParser state = {};
|
||||
const char *arg;
|
||||
|
||||
FOREACH_OPTION(&state, c, argc, argv, &arg, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
case 'h':
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
|
||||
case ARG_VERSION:
|
||||
OPTION_COMMON_VERSION:
|
||||
return version();
|
||||
|
||||
case ARG_ROOT:
|
||||
if (streq(optarg, "auto")) {
|
||||
arg_root = mfree(arg_root);
|
||||
OPTION_LONG("root", "PATH|auto", "Operate relative to the specified path"):
|
||||
if (streq(arg, "auto"))
|
||||
r = free_and_strdup_warn(&arg_root, in_initrd() ? "/sysroot" : NULL);
|
||||
else {
|
||||
if (!path_is_absolute(arg))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"--root= argument must be 'auto' or absolute path, got: %s", arg);
|
||||
|
||||
if (in_initrd()) {
|
||||
arg_root = strdup("/sysroot");
|
||||
if (!arg_root)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
break;
|
||||
r = parse_path_argument(arg, /* suppress_root= */ true, &arg_root);
|
||||
}
|
||||
|
||||
if (!path_is_absolute(optarg))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--root= argument must be 'auto' or absolute path, got: %s", optarg);
|
||||
|
||||
r = parse_path_argument(optarg, /* suppress_root= */ true, &arg_root);
|
||||
if (r < 0)
|
||||
return r;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
if (optind + 1 != argc)
|
||||
char **args = option_parser_get_args(&state, argc, argv);
|
||||
|
||||
if (strv_length(args) != 1)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"%s excepts exactly one argument (the mount point).",
|
||||
"%s expects exactly one argument (the mount point).",
|
||||
program_invocation_short_name);
|
||||
|
||||
arg_target = strdup(argv[optind]);
|
||||
arg_target = strdup(args[0]);
|
||||
if (!arg_target)
|
||||
return log_oom();
|
||||
|
||||
if (arg_root && !path_startswith(arg_target, arg_root))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Specified path '%s' does not start with specified root '%s', refusing.", arg_target, arg_root);
|
||||
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Specified path '%s' does not start with specified root '%s', refusing.",
|
||||
arg_target, arg_root);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ Priority=202
|
||||
Table=22
|
||||
|
||||
# The four routing policy rules below intentionally have the same config
|
||||
# excepts for their To= addresses. See issue #35874.
|
||||
# except for their To= addresses. See issue #35874.
|
||||
[RoutingPolicyRule]
|
||||
To=192.0.2.0/26
|
||||
Table=1001
|
||||
|
||||
Reference in New Issue
Block a user