mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
poudriere.conf is handed to sysrc(8), including the jail, tree, and set overlays poudriere(8) consults. make, src, and src-env are sub-targets over the matching make(1) files under poudriere.d. -l and -L list one path per line; -L includes overlays that do not exist yet. A bare -- ends the sub-target so the next word is a variable. Bump sysconf(8) to 2.2. Reviewed by: fuz, kfv, bcr Differential Revision: https://reviews.freebsd.org/D59943
696 lines
20 KiB
C
696 lines
20 KiB
C
/*
|
|
* Copyright (c) 2013-2026 Devin Teske <[email protected]>
|
|
* Copyright (c) 2021-2026 Faraz Vahedi <[email protected]>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
/*
|
|
* sysconf(8): CLI entry, option parsing, and program state.
|
|
*/
|
|
|
|
#include "sysconf_priv.h"
|
|
|
|
/* Requests to process (one per name argument) */
|
|
struct request *reqs; /* set by main() */
|
|
unsigned int nreqs; /* set by main() */
|
|
|
|
/* Union of all directives, for `-a' against multi-file targets */
|
|
struct dumpent *dumps; /* set by scan_cb() */
|
|
size_t ndumps; /* set by scan_cb() */
|
|
size_t dumpsize; /* set by scan_cb() */
|
|
|
|
/* Resolved target state */
|
|
char **conf_files; /* ordered backing files */
|
|
size_t nconf_files;
|
|
size_t conf_scanidx; /* file being parsed (scan_pass) */
|
|
size_t write_idx; /* default write target index */
|
|
int defaults_idx = -1; /* defaults file index in conf_files
|
|
* (read-only, never listed); -1 if none */
|
|
enum bsdconf_format format = BSDCONF_FORMAT_GENERIC;
|
|
|
|
/* Extra display information */
|
|
const char *pgm; /* set to getprogname() by main() */
|
|
bool check = false; /* `-c' */
|
|
bool defaults_only = false; /* `-D' */
|
|
bool dump_all = false; /* `-a' */
|
|
bool existing_only = false; /* `-E' */
|
|
bool ignore_unknown = false; /* `-i' */
|
|
bool list_all = false; /* `-L' */
|
|
bool list_files = false; /* `-l' */
|
|
bool name_only = false; /* `-N' */
|
|
bool quiet = false; /* `-q' */
|
|
bool remove_mode = false; /* `-x' */
|
|
bool set_knobs = false; /* `-s' WITH_/WITHOUT_ presence */
|
|
bool show_desc = false; /* `-d' */
|
|
bool show_equals = false; /* `-e' */
|
|
bool show_file = false; /* `-F' */
|
|
bool value_only = false; /* `-n' */
|
|
bool verbose = false; /* `-v' */
|
|
bool verbose_trail = false; /* `-V' */
|
|
bool with_defaults = false; /* `-A' */
|
|
|
|
/* Option arguments */
|
|
const char *file = NULL; /* `-f file' */
|
|
bool file_stdin = false; /* `-f -' given */
|
|
const char *jailname = NULL; /* `-j jail' */
|
|
const char *module = NULL; /* `-k module' */
|
|
const char *rootdir = ""; /* `-R dir' */
|
|
|
|
/*
|
|
* Run the getopt(3) loop over `argv', setting the option globals. Called
|
|
* once for the options preceding the target keyword and once for those
|
|
* following it. Returns the number of arguments consumed (optind).
|
|
*/
|
|
static int
|
|
parse_options(int argc, char *argv[])
|
|
{
|
|
int ch;
|
|
|
|
while ((ch = getopt(argc, argv, OPTSTRING)) != -1) {
|
|
switch (ch) {
|
|
case 'A': /* dump all directives, defaults included */
|
|
with_defaults = 1;
|
|
break;
|
|
case 'a': /* dump all directives */
|
|
dump_all = 1;
|
|
break;
|
|
case 'c': /* check only; do not modify */
|
|
check = 1;
|
|
break;
|
|
case 'd': /* show directive descriptions */
|
|
show_desc = 1;
|
|
break;
|
|
case 'D': /* consult the defaults file only */
|
|
defaults_only = 1;
|
|
break;
|
|
case 'E': /* list existing files only (with -l/-L) */
|
|
existing_only = 1;
|
|
break;
|
|
case 'e': /* show name=value */
|
|
show_equals = 1;
|
|
break;
|
|
case 'F': /* show authoritative file, not value */
|
|
show_file = 1;
|
|
break;
|
|
case 'f': /* explicit file (`-' is standard input) */
|
|
if (strcmp(optarg, "-") == 0) {
|
|
file = "/dev/stdin";
|
|
file_stdin = 1;
|
|
} else {
|
|
file = optarg;
|
|
file_stdin = 0;
|
|
}
|
|
break;
|
|
case 'h': /* help/usage */
|
|
usage();
|
|
break;
|
|
case 'i': /* ignore unknown names */
|
|
ignore_unknown = 1;
|
|
break;
|
|
case 'j': /* jail name or id */
|
|
jailname = optarg;
|
|
break;
|
|
case 'k': /* kernel module drop-in */
|
|
module = optarg;
|
|
break;
|
|
case 'l': /* list backing files */
|
|
list_files = 1;
|
|
break;
|
|
case 'L': /* list all candidate files */
|
|
list_all = 1;
|
|
break;
|
|
case 'n': /* value only */
|
|
value_only = 1;
|
|
break;
|
|
case 'N': /* name only */
|
|
name_only = 1;
|
|
break;
|
|
case 'q': /* quiet */
|
|
quiet = 1;
|
|
break;
|
|
case 'R': /* root dir */
|
|
rootdir = optarg;
|
|
break;
|
|
case 's': /* set empty WITH_/WITHOUT_ knobs (make/src) */
|
|
set_knobs = 1;
|
|
break;
|
|
case 'v': /* verbose (last file + final value) */
|
|
verbose = 1;
|
|
break;
|
|
case 'V': /* verbose trail (every assignment step) */
|
|
verbose_trail = 1;
|
|
break;
|
|
case 'x': /* remove */
|
|
remove_mode = 1;
|
|
break;
|
|
case '?': /* unknown argument (based on optstring) */
|
|
default: /* unhandled argument (based on switch) */
|
|
usage();
|
|
}
|
|
}
|
|
|
|
return (optind);
|
|
}
|
|
|
|
/*
|
|
* The native configuration trinity's third member: read and modify
|
|
* loader.conf(5), sysctl.conf(5), make.conf(5), and arbitrary configuration
|
|
* files with sysctl(8) assignment syntax.
|
|
*/
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
int have_reads = 0;
|
|
int have_writes = 0;
|
|
int n;
|
|
int rv = EXIT_SUCCESS;
|
|
const char *resolved = NULL;
|
|
const char *target = NULL;
|
|
|
|
pgm = getprogname();
|
|
|
|
/*
|
|
* Target selection, including the rc and poudriere pass-throughs,
|
|
* runs while argv is still pristine (see target_resolve()).
|
|
*/
|
|
resolved = target_resolve(&argc, argv);
|
|
|
|
/*
|
|
* Honor `--help' and `--version' wherever they appear (getopt(3)
|
|
* knows nothing of long options and would reject them as illegal
|
|
* short options). A bare `--' ends option processing as usual.
|
|
*/
|
|
for (n = 1; n < argc; n++) {
|
|
if (strcmp(argv[n], "--") == 0)
|
|
break;
|
|
if (strcmp(argv[n], "--help") == 0)
|
|
help();
|
|
if (strcmp(argv[n], "--version") == 0) {
|
|
printf("%s (libbsdconf %s)\n", SYSCONF_VERSION,
|
|
BSDCONF_VERSION);
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Process command-line options
|
|
*/
|
|
n = parse_options(argc, argv);
|
|
argc -= n;
|
|
argv += n;
|
|
|
|
/*
|
|
* Consume the (required) target keyword and allow further options
|
|
* to follow it, mirroring the option placement freedom of
|
|
* sysctl(8) (e.g., `sysconf sysctl -L'). getopt(3) skips over its
|
|
* first argument, so hand it the target keyword's slot as the
|
|
* program name.
|
|
*
|
|
* Nested `poudriere make|src|src-env' already stripped both keywords;
|
|
* remaining argv is options plus names.
|
|
*/
|
|
if (argc > 0 && !poudriere_native()) {
|
|
target = resolved != NULL ? resolved : argv[0];
|
|
argc--;
|
|
argv++;
|
|
#ifdef __FreeBSD__
|
|
optreset = 1;
|
|
optind = 1;
|
|
#else
|
|
optind = 0; /* glibc and musl re-initialize at zero */
|
|
#endif
|
|
n = parse_options(argc + 1, argv - 1) - 1;
|
|
argc -= n;
|
|
argv += n;
|
|
}
|
|
|
|
if (jailname != NULL && *rootdir != '\0') {
|
|
warnx("-j and -R are mutually exclusive");
|
|
usage();
|
|
}
|
|
if (file != NULL && module != NULL) {
|
|
warnx("-f and -k are mutually exclusive");
|
|
usage();
|
|
}
|
|
if (existing_only && !list_files && !list_all) {
|
|
warnx("-E requires -l or -L");
|
|
usage();
|
|
}
|
|
if (set_knobs && remove_mode) {
|
|
warnx("-s and -x are mutually exclusive");
|
|
usage();
|
|
}
|
|
|
|
#ifdef __FreeBSD__
|
|
if (jailname != NULL) {
|
|
int jid;
|
|
|
|
if ((jid = jail_getid(jailname)) < 0)
|
|
errx(EXIT_FAILURE, "%s", jail_errmsg);
|
|
if (jail_attach(jid) != 0)
|
|
err(EXIT_FAILURE, "jail_attach(%d)", jid);
|
|
}
|
|
#else
|
|
if (jailname != NULL)
|
|
errx(EXIT_FAILURE, "-j is not supported on this platform");
|
|
#endif
|
|
|
|
/* Resolve the target format and its backing files */
|
|
if (poudriere_native())
|
|
poudriere_setup();
|
|
else
|
|
resolve_target(target);
|
|
|
|
/* `-k' requires a target with a module drop-in directory */
|
|
if (module != NULL) {
|
|
const struct bsdconf_format_def *def;
|
|
const struct bsdconf_source *source;
|
|
int has_moddir = 0;
|
|
|
|
def = bsdconf_format_lookup(format);
|
|
if (def != NULL && def->sources != NULL)
|
|
for (source = def->sources; source->path != NULL;
|
|
source++)
|
|
if (source->type == BSDCONF_SOURCE_MODDIR)
|
|
has_moddir = 1;
|
|
if (!has_moddir) {
|
|
warnx("target does not support -k");
|
|
usage();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* `-d', `-D', and `-A' consult a body of defaults; only targets
|
|
* that have one support them (make.conf and friends have no
|
|
* defaults file, and no directive descriptions to give). The
|
|
* exception is `sysctl -d', whose descriptions come from the
|
|
* running kernel rather than any file.
|
|
*/
|
|
{
|
|
const struct bsdconf_format_def *def;
|
|
int has_defaults;
|
|
|
|
def = bsdconf_format_lookup(format);
|
|
has_defaults = def != NULL && def->defaults != NULL;
|
|
|
|
if (show_desc) {
|
|
if (format != BSDCONF_FORMAT_SYSCTL &&
|
|
!has_defaults) {
|
|
warnx("target does not support -d");
|
|
usage();
|
|
}
|
|
if (file != NULL) {
|
|
warnx("-d and -f are mutually exclusive");
|
|
usage();
|
|
}
|
|
if (list_files || list_all || remove_mode || check ||
|
|
set_knobs) {
|
|
warnx("-d cannot be combined with "
|
|
"-c/-l/-L/-s/-x");
|
|
usage();
|
|
}
|
|
#ifdef __FreeBSD__
|
|
if (format == BSDCONF_FORMAT_SYSCTL &&
|
|
*rootdir != '\0')
|
|
errx(EXIT_FAILURE, "sysctl descriptions "
|
|
"come from the running kernel; "
|
|
"-R does not apply");
|
|
#endif
|
|
}
|
|
if ((defaults_only || with_defaults) && !has_defaults) {
|
|
warnx("target does not support -%c",
|
|
defaults_only ? 'D' : 'A');
|
|
usage();
|
|
}
|
|
if ((defaults_only || with_defaults) && file != NULL) {
|
|
warnx("-%c and -f are mutually exclusive",
|
|
defaults_only ? 'D' : 'A');
|
|
usage();
|
|
}
|
|
}
|
|
|
|
/* File listings take no names and perform no other work */
|
|
if (list_files || list_all) {
|
|
if (argc != 0 || dump_all) {
|
|
warnx("-l/-L take no names");
|
|
usage();
|
|
}
|
|
exit(do_list());
|
|
}
|
|
|
|
/* `-A' with no names dumps everything, defaults included */
|
|
if (with_defaults && argc == 0)
|
|
dump_all = 1;
|
|
|
|
/* Display usage and exit if not given at least one name */
|
|
if (argc == 0 && !dump_all) {
|
|
warnx("no names provided");
|
|
usage();
|
|
}
|
|
if (argc != 0 && dump_all) {
|
|
warnx("-a does not take names");
|
|
usage();
|
|
}
|
|
|
|
/* Classify the remaining arguments */
|
|
nreqs = (unsigned int)argc;
|
|
if (nreqs > 0 &&
|
|
(reqs = calloc(nreqs, sizeof(*reqs))) == NULL)
|
|
err(EXIT_FAILURE, NULL);
|
|
if (set_knobs) {
|
|
if (format != BSDCONF_FORMAT_MAKE &&
|
|
format != BSDCONF_FORMAT_SRC) {
|
|
warnx("-s is only valid for make and src");
|
|
usage();
|
|
}
|
|
if (argc == 0) {
|
|
warnx("-s requires at least one WITH_/WITHOUT_ name");
|
|
usage();
|
|
}
|
|
}
|
|
for (n = 0; n < argc; n++) {
|
|
split_request(argv[n], &reqs[n], remove_mode);
|
|
if (set_knobs) {
|
|
if (reqs[n].newvalue != NULL) {
|
|
warnx("-s does not take a value "
|
|
"('%s')", argv[n]);
|
|
usage();
|
|
}
|
|
if (!make_knob_name_p(reqs[n].name)) {
|
|
if (strcmp(reqs[n].name,
|
|
"WITHOUT_MODULES") == 0)
|
|
warnx("WITHOUT_MODULES takes a "
|
|
"module list; use "
|
|
"WITHOUT_MODULES=...");
|
|
else
|
|
warnx("-s requires a WITH_ or "
|
|
"WITHOUT_ name ('%s')",
|
|
reqs[n].name);
|
|
usage();
|
|
}
|
|
reqs[n].newvalue = "";
|
|
}
|
|
if (reqs[n].newvalue != NULL && !reqs[n].remove)
|
|
warn_with_equals_no(reqs[n].name,
|
|
reqs[n].newvalue, NULL, 0);
|
|
if (reqs[n].remove || reqs[n].newvalue != NULL)
|
|
have_writes = 1;
|
|
else
|
|
have_reads = 1;
|
|
}
|
|
if (check && !have_writes) {
|
|
warnx("-c requires at least one name=value or -s name");
|
|
usage();
|
|
}
|
|
|
|
/* Descriptions are read-only */
|
|
if (show_desc) {
|
|
if (have_writes) {
|
|
warnx("-d does not take values");
|
|
usage();
|
|
}
|
|
#ifndef __FreeBSD__
|
|
if (format == BSDCONF_FORMAT_SYSCTL)
|
|
errx(EXIT_FAILURE,
|
|
"sysctl descriptions require FreeBSD");
|
|
#endif
|
|
/* Explicit names need no file scan at all */
|
|
if (!dump_all) {
|
|
#ifdef __FreeBSD__
|
|
if (format == BSDCONF_FORMAT_SYSCTL)
|
|
exit(describe_sysctl());
|
|
#endif
|
|
exit(describe_defaults());
|
|
}
|
|
|
|
/*
|
|
* Dumps (-ad, -Ad, -aDd) pair each scanned directive with
|
|
* its description; harvest the descriptions before the
|
|
* read sandbox slams shut.
|
|
*/
|
|
if (format != BSDCONF_FORMAT_SYSCTL)
|
|
load_descriptions();
|
|
}
|
|
|
|
/* Defaults can be read and checked against, never rewritten */
|
|
if ((defaults_only || with_defaults) && have_writes && !check)
|
|
errx(EXIT_FAILURE, "defaults are read-only");
|
|
|
|
/* Standard input can be read and checked, never rewritten */
|
|
if (file_stdin && have_writes && !check)
|
|
errx(EXIT_FAILURE, "cannot write to standard input");
|
|
|
|
#if defined(__FreeBSD__)
|
|
/*
|
|
* Refuse up front to set sysctl OIDs that can never take effect
|
|
* from sysctl.conf(5) (non-leaf, read-only, loader-only tunables)
|
|
* or whose values cannot fit the OID's CTLTYPE (so an overflowing
|
|
* assignment cannot surprise sysctl(8) at boot). Unknown OIDs are
|
|
* warned about but still written -- the module may not be loaded
|
|
* yet, matching init(8)'s handling of sysctl.conf(5). Only
|
|
* meaningful against the running system's sysctl tree, so skipped
|
|
* under -R. -i/-q quiet the unknown-OID warning; -k remains the
|
|
* module drop-in selector.
|
|
*/
|
|
if (format == BSDCONF_FORMAT_SYSCTL && have_writes && !check &&
|
|
*rootdir == '\0') {
|
|
int quiet_unknown = ignore_unknown || quiet;
|
|
unsigned int u;
|
|
|
|
for (u = 0; u < nreqs; u++) {
|
|
if (reqs[u].newvalue == NULL)
|
|
continue;
|
|
if (sysctl_writable(reqs[u].name, reqs[u].newvalue,
|
|
quiet_unknown) != 0) {
|
|
/* Convert to a no-op; count the failure */
|
|
reqs[u].newvalue = NULL;
|
|
reqs[u].remove = 0;
|
|
reqs[u].name = "";
|
|
rv = EXIT_FAILURE;
|
|
}
|
|
}
|
|
have_writes = 0;
|
|
have_reads = 0;
|
|
for (u = 0; u < nreqs; u++) {
|
|
if (reqs[u].remove || reqs[u].newvalue != NULL)
|
|
have_writes = 1;
|
|
else if (reqs[u].name[0] != '\0')
|
|
have_reads = 1;
|
|
}
|
|
if (rv != EXIT_SUCCESS && !have_writes && !have_reads)
|
|
exit(rv); /* nothing settable remains */
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* Scan the backing files to locate each request's authoritative
|
|
* definition. Pure reads and -c checks (do_checks() never calls
|
|
* put) run the scan inside a Capsicum sandbox -- except a sysctl
|
|
* description dump, whose kernel queries the sandbox would deny.
|
|
* Classify by whether we will actually write, not by whether the
|
|
* argv looked like name=value (`-c' sets have_writes for checks).
|
|
*/
|
|
scan_pass((check || !have_writes) &&
|
|
!(show_desc && format == BSDCONF_FORMAT_SYSCTL));
|
|
|
|
/* Materialize list edits now that effective values are known */
|
|
if (merge_list_requests() != EXIT_SUCCESS)
|
|
rv = EXIT_FAILURE;
|
|
|
|
if (check) {
|
|
if (do_make_strikes(1) != EXIT_SUCCESS)
|
|
rv = EXIT_FAILURE;
|
|
if (do_checks() != EXIT_SUCCESS)
|
|
rv = EXIT_FAILURE;
|
|
exit(rv);
|
|
}
|
|
|
|
/* Apply writes first so that subsequent reads see the result */
|
|
if (have_writes) {
|
|
int wrv;
|
|
|
|
if ((wrv = do_make_strikes(0)) != EXIT_SUCCESS)
|
|
rv = wrv;
|
|
if ((wrv = do_writes()) != EXIT_SUCCESS)
|
|
rv = wrv;
|
|
|
|
/* Refresh the scan for any trailing read requests */
|
|
if (have_reads || dump_all) {
|
|
for (n = 0; (unsigned int)n < nreqs; n++) {
|
|
size_t ai;
|
|
|
|
trail_free(reqs[n].trail, reqs[n].ntrail);
|
|
reqs[n].trail = NULL;
|
|
reqs[n].ntrail = 0;
|
|
for (ai = 0; ai < reqs[n].nassigns; ai++)
|
|
free(reqs[n].assigns[ai].piece);
|
|
free(reqs[n].assigns);
|
|
reqs[n].assigns = NULL;
|
|
reqs[n].nassigns = 0;
|
|
reqs[n].found = 0;
|
|
reqs[n].append_present = 0;
|
|
reqs[n].srcidx = -1;
|
|
reqs[n].line = 0;
|
|
memset(reqs[n].infile, 0, nconf_files);
|
|
}
|
|
scan_pass(0);
|
|
}
|
|
}
|
|
|
|
if (have_reads || dump_all) {
|
|
int rrv;
|
|
|
|
if ((rrv = do_reads()) != EXIT_SUCCESS)
|
|
rv = rrv;
|
|
}
|
|
|
|
exit(rv);
|
|
}
|
|
|
|
/*
|
|
* Print short usage statement to stderr and exit with error status.
|
|
*/
|
|
void
|
|
usage(void)
|
|
{
|
|
|
|
fprintf(stderr,
|
|
"usage: %s target [-AcDeFinNqsvVx] [-j jail | -R dir]"
|
|
" [-f file | -k module]\n"
|
|
" name[[+|-]=value] ...\n", pgm);
|
|
fprintf(stderr,
|
|
" %s target [-ADeFnNqvV] [-j jail | -R dir]"
|
|
" [-f file | -k module] -a\n", pgm);
|
|
fprintf(stderr,
|
|
" %s target [-AaDinNq] [-j jail | -R dir]"
|
|
" -d [name ...]\n", pgm);
|
|
fprintf(stderr,
|
|
" %s target [-E] [-j jail | -R dir] [-k module]"
|
|
" -l | -L\n", pgm);
|
|
fprintf(stderr,
|
|
" %s rc [sysrc(8) argument ...]\n", pgm);
|
|
poudriere_usage();
|
|
fprintf(stderr, "Try `%s --help' for more information.\n", pgm);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/*
|
|
* Print long usage statement to stderr and exit with error status.
|
|
*/
|
|
void
|
|
help(void)
|
|
{
|
|
|
|
fprintf(stderr,
|
|
"usage: %s target [-AcDeFinNqsvVx] [-j jail | -R dir]"
|
|
" [-f file | -k module] name[[+|-]=value] ...\n", pgm);
|
|
fprintf(stderr, "TARGETS:\n");
|
|
#define TGTFMT "\t%-9s %s\n"
|
|
fprintf(stderr, TGTFMT, "loader",
|
|
"files named by loader_conf_files et al. in");
|
|
fprintf(stderr, TGTFMT, "",
|
|
"/boot/defaults/loader.conf (typically /boot/loader.conf,");
|
|
fprintf(stderr, TGTFMT, "",
|
|
"loader.conf.d/*.conf, loader.conf.local)");
|
|
fprintf(stderr, TGTFMT, "sysctl",
|
|
"/etc/sysctl.conf, sysctl.conf.local, sysctl.kld.d/*.conf");
|
|
fprintf(stderr, TGTFMT, "make",
|
|
"/etc/make.conf (or -f for any make-syntax file)");
|
|
fprintf(stderr, TGTFMT, "src",
|
|
"/usr/src build triad: src-env.conf, make.conf, src.conf");
|
|
fprintf(stderr, TGTFMT, "",
|
|
"(new writes prefer src.conf; env: SRC_ENV_CONF,");
|
|
fprintf(stderr, TGTFMT, "",
|
|
"__MAKE_CONF, SRCCONF)");
|
|
fprintf(stderr, TGTFMT, "rc",
|
|
"pass-through: all other arguments go to sysrc(8) verbatim");
|
|
poudriere_help();
|
|
fprintf(stderr, TGTFMT, "generic",
|
|
"no default files; requires -f file");
|
|
fprintf(stderr,
|
|
"A unique prefix of a target keyword is accepted.\n");
|
|
fprintf(stderr, "OPTIONS:\n");
|
|
#define OPTFMT "\t%-9s %s\n"
|
|
fprintf(stderr, OPTFMT, "-A",
|
|
"Include the target's defaults file in the sourcing order");
|
|
fprintf(stderr, OPTFMT, "",
|
|
"(alone, dumps everything, defaults included).");
|
|
fprintf(stderr, OPTFMT, "-a",
|
|
"Dump the union of all directives from the target's files.");
|
|
fprintf(stderr, OPTFMT, "-c",
|
|
"Check. Return success if no changes needed, else error.");
|
|
fprintf(stderr, OPTFMT, "-D",
|
|
"Consult only the target's defaults file.");
|
|
fprintf(stderr, OPTFMT, "-d",
|
|
"Show directive descriptions (from the defaults file's");
|
|
fprintf(stderr, OPTFMT, "",
|
|
"comments; for sysctl, from the running kernel). With");
|
|
fprintf(stderr, OPTFMT, "",
|
|
"-a, -A, or -D, describe every directive in scope.");
|
|
fprintf(stderr, OPTFMT, "-E",
|
|
"With -l or -L, list only files that exist on disk.");
|
|
fprintf(stderr, OPTFMT, "-e",
|
|
"Separate name and value with `=' (reads and write echoes).");
|
|
fprintf(stderr, OPTFMT, "-F",
|
|
"Show the file holding each directive's effective value.");
|
|
fprintf(stderr, OPTFMT, "-f file",
|
|
"Operate on file, in the target's format, instead of the");
|
|
fprintf(stderr, OPTFMT, "",
|
|
"target's standard files (`-' means standard input).");
|
|
fprintf(stderr, OPTFMT, "-h",
|
|
"Print a short usage statement to stderr and exit.");
|
|
fprintf(stderr, OPTFMT, "--help",
|
|
"Print this message to stderr and exit.");
|
|
fprintf(stderr, OPTFMT, "--version",
|
|
"Print the utility and library versions and exit.");
|
|
fprintf(stderr, OPTFMT, "-i",
|
|
"Ignore unknown names (and quiet unknown sysctl OID warnings).");
|
|
fprintf(stderr, OPTFMT, "-j jail",
|
|
"Operate within the jail `jail' (name or numeric id).");
|
|
fprintf(stderr, OPTFMT, "-k module",
|
|
"Include the kernel module drop-in file for `module'.");
|
|
fprintf(stderr, OPTFMT, "-l",
|
|
"List the pathnames of the target's backing files.");
|
|
fprintf(stderr, OPTFMT, "-L",
|
|
"List all candidate files, including module drop-ins.");
|
|
fprintf(stderr, OPTFMT, "-n",
|
|
"Show only directive values, not their names.");
|
|
fprintf(stderr, OPTFMT, "-N",
|
|
"Show only directive names, not their values.");
|
|
fprintf(stderr, OPTFMT, "-q",
|
|
"Quiet. Suppress unknown-directive warnings and the");
|
|
fprintf(stderr, OPTFMT, "",
|
|
"`old -> new' echo of writes.");
|
|
fprintf(stderr, OPTFMT, "-R dir",
|
|
"Operate within the root directory `dir' rather than `/'.");
|
|
fprintf(stderr, OPTFMT, "-s",
|
|
"Set empty WITH_/WITHOUT_ knobs (make and src only).");
|
|
fprintf(stderr, OPTFMT, "-v",
|
|
"Verbose. Print the pathname of the configuration file");
|
|
fprintf(stderr, OPTFMT, "",
|
|
"holding the final effective value.");
|
|
fprintf(stderr, OPTFMT, "-V",
|
|
"Trail. Reads: each assignment step (file:line, operator,");
|
|
fprintf(stderr, OPTFMT, "",
|
|
"fragment, running effective). Writes: file:line:");
|
|
fprintf(stderr, OPTFMT, "",
|
|
"name=old -> name=new (or name=value (unchanged)).");
|
|
fprintf(stderr, OPTFMT, "-x",
|
|
"Remove name(s) from the target's files.");
|
|
fprintf(stderr, "ENVIRONMENT:\n");
|
|
fprintf(stderr, OPTFMT, "BSDCONF_MAX_BYTES",
|
|
"Cap on bytes read from a configuration file (see bsdconf(3)).");
|
|
fprintf(stderr, OPTFMT, "LOADER_DEFAULTS",
|
|
"Defaults file for the loader target (in place of");
|
|
fprintf(stderr, OPTFMT, "",
|
|
"/boot/defaults/loader.conf).");
|
|
fprintf(stderr, OPTFMT, "SRC_ENV_CONF",
|
|
"src-env.conf for the src target (default /etc/src-env.conf).");
|
|
fprintf(stderr, OPTFMT, "__MAKE_CONF",
|
|
"make.conf for the src target (default /etc/make.conf).");
|
|
fprintf(stderr, OPTFMT, "SRCCONF",
|
|
"src.conf for the src target (default /etc/src.conf).");
|
|
exit(EXIT_FAILURE);
|
|
}
|