1 /* 2 * Copyright (c) 2013-2026 Devin Teske <dteske@FreeBSD.org> 3 * Copyright (c) 2021-2026 Faraz Vahedi <kfv@FreeBSD.org> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8 /* 9 * sysconf(8): CLI entry, option parsing, and program state. 10 */ 11 12 #include "sysconf_priv.h" 13 14 /* Requests to process (one per name argument) */ 15 struct request *reqs; /* set by main() */ 16 unsigned int nreqs; /* set by main() */ 17 18 /* Union of all directives, for `-a' against multi-file targets */ 19 struct dumpent *dumps; /* set by scan_cb() */ 20 size_t ndumps; /* set by scan_cb() */ 21 size_t dumpsize; /* set by scan_cb() */ 22 23 /* Resolved target state */ 24 char **conf_files; /* ordered backing files */ 25 size_t nconf_files; 26 size_t conf_scanidx; /* file being parsed (scan_pass) */ 27 size_t write_idx; /* default write target index */ 28 int defaults_idx = -1; /* defaults file index in conf_files 29 * (read-only, never listed); -1 if none */ 30 enum bsdconf_format format = BSDCONF_FORMAT_GENERIC; 31 32 /* Extra display information */ 33 const char *pgm; /* set to getprogname() by main() */ 34 bool check = false; /* `-c' */ 35 bool defaults_only = false; /* `-D' */ 36 bool dump_all = false; /* `-a' */ 37 bool existing_only = false; /* `-E' */ 38 bool ignore_unknown = false; /* `-i' */ 39 bool list_all = false; /* `-L' */ 40 bool list_files = false; /* `-l' */ 41 bool name_only = false; /* `-N' */ 42 bool quiet = false; /* `-q' */ 43 bool remove_mode = false; /* `-x' */ 44 bool set_knobs = false; /* `-s' WITH_/WITHOUT_ presence */ 45 bool show_desc = false; /* `-d' */ 46 bool show_equals = false; /* `-e' */ 47 bool show_file = false; /* `-F' */ 48 bool value_only = false; /* `-n' */ 49 bool verbose = false; /* `-v' */ 50 bool verbose_trail = false; /* `-V' */ 51 bool with_defaults = false; /* `-A' */ 52 53 /* Option arguments */ 54 const char *file = NULL; /* `-f file' */ 55 bool file_stdin = false; /* `-f -' given */ 56 const char *jailname = NULL; /* `-j jail' */ 57 const char *module = NULL; /* `-k module' */ 58 const char *rootdir = ""; /* `-R dir' */ 59 60 /* 61 * Locate the target keyword in `argv' without consuming or validating 62 * anything: the first argument that is neither an option cluster nor the 63 * argument of one (per OPTSTRING; an unknown option letter is assumed to 64 * take no argument). A `--' ends option scanning as usual. Returns the 65 * argv index of the target, or -1 when there is none. Used before any 66 * getopt(3) processing so that the `rc' pass-through target (see 67 * exec_sysrc() below) can be detected while the command line is still 68 * pristine. 69 * 70 * Attached arguments (`-fPATH', `-R/altroot') are self-contained: the rest 71 * of the cluster is the option's argument, so the following argv element is 72 * not consumed. Only a trailing option letter that takes an argument and 73 * has nothing after it in the cluster (`-f PATH') skips the next element. 74 */ 75 static int 76 find_target(int argc, char *argv[]) 77 { 78 int n; 79 const char *o; 80 const char *p; 81 82 for (n = 1; n < argc; n++) { 83 if (strcmp(argv[n], "--") == 0) 84 return (n + 1 < argc ? n + 1 : -1); 85 if (argv[n][0] == '-' && argv[n][1] != '\0') { 86 for (p = argv[n] + 1; *p != '\0'; p++) { 87 o = strchr(OPTSTRING, *p); 88 if (o != NULL && o[1] == ':') { 89 /* Takes an argument */ 90 if (p[1] != '\0') { 91 ; 92 /* attached: rest of argv[n] */ 93 } else if (n + 1 < argc) { 94 n++; 95 /* separate argv */ 96 } 97 break; 98 } 99 } 100 continue; 101 } 102 return (n); 103 } 104 105 return (-1); 106 } 107 108 /* 109 * The `rc' pass-through: rc.conf(5) is sysrc(8)'s domain, and its feature 110 * set is a superset of ours, so no option or argument is validated, 111 * interpreted, or reordered here -- every argument except the target 112 * keyword itself (at argv index `skip') is handed to sysrc(8) verbatim. 113 * Never returns. 114 */ 115 static void 116 exec_sysrc(int argc, char *argv[], int skip) 117 { 118 int n; 119 int nargc = 0; 120 char **nargv; 121 122 if ((nargv = calloc((size_t)argc + 1, sizeof(*nargv))) == NULL) 123 err(EXIT_FAILURE, NULL); 124 nargv[nargc++] = (char *)(uintptr_t)"sysrc"; 125 for (n = 1; n < argc; n++) { 126 if (n == skip) 127 continue; 128 nargv[nargc++] = argv[n]; 129 } 130 nargv[nargc] = NULL; 131 132 execvp("sysrc", nargv); 133 err(EXIT_FAILURE, "sysrc"); 134 } 135 136 /* 137 * Run the getopt(3) loop over `argv', setting the option globals. Called 138 * once for the options preceding the target keyword and once for those 139 * following it. Returns the number of arguments consumed (optind). 140 */ 141 static int 142 parse_options(int argc, char *argv[]) 143 { 144 int ch; 145 146 while ((ch = getopt(argc, argv, OPTSTRING)) != -1) { 147 switch (ch) { 148 case 'A': /* dump all directives, defaults included */ 149 with_defaults = 1; 150 break; 151 case 'a': /* dump all directives */ 152 dump_all = 1; 153 break; 154 case 'c': /* check only; do not modify */ 155 check = 1; 156 break; 157 case 'd': /* show directive descriptions */ 158 show_desc = 1; 159 break; 160 case 'D': /* consult the defaults file only */ 161 defaults_only = 1; 162 break; 163 case 'E': /* list existing files only (with -l/-L) */ 164 existing_only = 1; 165 break; 166 case 'e': /* show name=value */ 167 show_equals = 1; 168 break; 169 case 'F': /* show authoritative file, not value */ 170 show_file = 1; 171 break; 172 case 'f': /* explicit file (`-' is standard input) */ 173 if (strcmp(optarg, "-") == 0) { 174 file = "/dev/stdin"; 175 file_stdin = 1; 176 } else { 177 file = optarg; 178 file_stdin = 0; 179 } 180 break; 181 case 'h': /* help/usage */ 182 usage(); 183 break; 184 case 'i': /* ignore unknown names */ 185 ignore_unknown = 1; 186 break; 187 case 'j': /* jail name or id */ 188 jailname = optarg; 189 break; 190 case 'k': /* kernel module drop-in */ 191 module = optarg; 192 break; 193 case 'l': /* list backing files */ 194 list_files = 1; 195 break; 196 case 'L': /* list all candidate files */ 197 list_all = 1; 198 break; 199 case 'n': /* value only */ 200 value_only = 1; 201 break; 202 case 'N': /* name only */ 203 name_only = 1; 204 break; 205 case 'q': /* quiet */ 206 quiet = 1; 207 break; 208 case 'R': /* root dir */ 209 rootdir = optarg; 210 break; 211 case 's': /* set empty WITH_/WITHOUT_ knobs (make/src) */ 212 set_knobs = 1; 213 break; 214 case 'v': /* verbose (last file + final value) */ 215 verbose = 1; 216 break; 217 case 'V': /* verbose trail (every assignment step) */ 218 verbose_trail = 1; 219 break; 220 case 'x': /* remove */ 221 remove_mode = 1; 222 break; 223 case '?': /* unknown argument (based on optstring) */ 224 default: /* unhandled argument (based on switch) */ 225 usage(); 226 } 227 } 228 229 return (optind); 230 } 231 232 /* 233 * The native configuration trinity's third member: read and modify 234 * loader.conf(5), sysctl.conf(5), make.conf(5), and arbitrary configuration 235 * files with sysctl(8) assignment syntax. 236 */ 237 int 238 main(int argc, char *argv[]) 239 { 240 int have_reads = 0; 241 int have_writes = 0; 242 int n; 243 int rv = EXIT_SUCCESS; 244 const char *target = NULL; 245 246 pgm = getprogname(); 247 248 /* 249 * The `rc' target is a pure pass-through to sysrc(8), detected 250 * while the command line is still pristine so that nothing -- 251 * `--help' and `--version' included -- is intercepted on its way 252 * there (see exec_sysrc()). 253 */ 254 n = find_target(argc, argv); 255 if (n > 0 && strcmp(argv[n], "rc") == 0) 256 exec_sysrc(argc, argv, n); /* never returns */ 257 258 /* 259 * Honor `--help' and `--version' wherever they appear (getopt(3) 260 * knows nothing of long options and would reject them as illegal 261 * short options). A bare `--' ends option processing as usual. 262 */ 263 for (n = 1; n < argc; n++) { 264 if (strcmp(argv[n], "--") == 0) 265 break; 266 if (strcmp(argv[n], "--help") == 0) 267 help(); 268 if (strcmp(argv[n], "--version") == 0) { 269 printf("%s (libbsdconf %s)\n", SYSCONF_VERSION, 270 BSDCONF_VERSION); 271 exit(EXIT_SUCCESS); 272 } 273 } 274 275 /* 276 * Process command-line options 277 */ 278 n = parse_options(argc, argv); 279 argc -= n; 280 argv += n; 281 282 /* 283 * Consume the (required) target keyword and allow further options 284 * to follow it, mirroring the option placement freedom of 285 * sysctl(8) (e.g., `sysconf sysctl -L'). getopt(3) skips over its 286 * first argument, so hand it the target keyword's slot as the 287 * program name. 288 */ 289 if (argc > 0) { 290 target = argv[0]; 291 argc--; 292 argv++; 293 #ifdef __FreeBSD__ 294 optreset = 1; 295 optind = 1; 296 #else 297 optind = 0; /* glibc and musl re-initialize at zero */ 298 #endif 299 n = parse_options(argc + 1, argv - 1) - 1; 300 argc -= n; 301 argv += n; 302 } 303 304 if (jailname != NULL && *rootdir != '\0') { 305 warnx("-j and -R are mutually exclusive"); 306 usage(); 307 } 308 if (file != NULL && module != NULL) { 309 warnx("-f and -k are mutually exclusive"); 310 usage(); 311 } 312 if (existing_only && !list_files && !list_all) { 313 warnx("-E requires -l or -L"); 314 usage(); 315 } 316 if (set_knobs && remove_mode) { 317 warnx("-s and -x are mutually exclusive"); 318 usage(); 319 } 320 321 #ifdef __FreeBSD__ 322 if (jailname != NULL) { 323 int jid; 324 325 if ((jid = jail_getid(jailname)) < 0) 326 errx(EXIT_FAILURE, "%s", jail_errmsg); 327 if (jail_attach(jid) != 0) 328 err(EXIT_FAILURE, "jail_attach(%d)", jid); 329 } 330 #else 331 if (jailname != NULL) 332 errx(EXIT_FAILURE, "-j is not supported on this platform"); 333 #endif 334 335 /* Resolve the target format and its backing files */ 336 resolve_target(target); 337 338 /* `-k' requires a target with a module drop-in directory */ 339 if (module != NULL) { 340 const struct bsdconf_format_def *def; 341 const struct bsdconf_source *source; 342 int has_moddir = 0; 343 344 def = bsdconf_format_lookup(format); 345 if (def != NULL && def->sources != NULL) 346 for (source = def->sources; source->path != NULL; 347 source++) 348 if (source->type == BSDCONF_SOURCE_MODDIR) 349 has_moddir = 1; 350 if (!has_moddir) { 351 warnx("target does not support -k"); 352 usage(); 353 } 354 } 355 356 /* 357 * `-d', `-D', and `-A' consult a body of defaults; only targets 358 * that have one support them (make.conf and friends have no 359 * defaults file, and no directive descriptions to give). The 360 * exception is `sysctl -d', whose descriptions come from the 361 * running kernel rather than any file. 362 */ 363 { 364 const struct bsdconf_format_def *def; 365 int has_defaults; 366 367 def = bsdconf_format_lookup(format); 368 has_defaults = def != NULL && def->defaults != NULL; 369 370 if (show_desc) { 371 if (format != BSDCONF_FORMAT_SYSCTL && 372 !has_defaults) { 373 warnx("target does not support -d"); 374 usage(); 375 } 376 if (file != NULL) { 377 warnx("-d and -f are mutually exclusive"); 378 usage(); 379 } 380 if (list_files || list_all || remove_mode || check || 381 set_knobs) { 382 warnx("-d cannot be combined with " 383 "-c/-l/-L/-s/-x"); 384 usage(); 385 } 386 #ifdef __FreeBSD__ 387 if (format == BSDCONF_FORMAT_SYSCTL && 388 *rootdir != '\0') 389 errx(EXIT_FAILURE, "sysctl descriptions " 390 "come from the running kernel; " 391 "-R does not apply"); 392 #endif 393 } 394 if ((defaults_only || with_defaults) && !has_defaults) { 395 warnx("target does not support -%c", 396 defaults_only ? 'D' : 'A'); 397 usage(); 398 } 399 if ((defaults_only || with_defaults) && file != NULL) { 400 warnx("-%c and -f are mutually exclusive", 401 defaults_only ? 'D' : 'A'); 402 usage(); 403 } 404 } 405 406 /* File listings take no names and perform no other work */ 407 if (list_files || list_all) { 408 if (argc != 0 || dump_all) { 409 warnx("-l/-L take no names"); 410 usage(); 411 } 412 exit(do_list()); 413 } 414 415 /* `-A' with no names dumps everything, defaults included */ 416 if (with_defaults && argc == 0) 417 dump_all = 1; 418 419 /* Display usage and exit if not given at least one name */ 420 if (argc == 0 && !dump_all) { 421 warnx("no names provided"); 422 usage(); 423 } 424 if (argc != 0 && dump_all) { 425 warnx("-a does not take names"); 426 usage(); 427 } 428 429 /* Classify the remaining arguments */ 430 nreqs = (unsigned int)argc; 431 if (nreqs > 0 && 432 (reqs = calloc(nreqs, sizeof(*reqs))) == NULL) 433 err(EXIT_FAILURE, NULL); 434 if (set_knobs) { 435 if (format != BSDCONF_FORMAT_MAKE && 436 format != BSDCONF_FORMAT_SRC) { 437 warnx("-s is only valid for make and src"); 438 usage(); 439 } 440 if (argc == 0) { 441 warnx("-s requires at least one WITH_/WITHOUT_ name"); 442 usage(); 443 } 444 } 445 for (n = 0; n < argc; n++) { 446 split_request(argv[n], &reqs[n], remove_mode); 447 if (set_knobs) { 448 if (reqs[n].newvalue != NULL) { 449 warnx("-s does not take a value " 450 "('%s')", argv[n]); 451 usage(); 452 } 453 if (!make_knob_name_p(reqs[n].name)) { 454 if (strcmp(reqs[n].name, 455 "WITHOUT_MODULES") == 0) 456 warnx("WITHOUT_MODULES takes a " 457 "module list; use " 458 "WITHOUT_MODULES=..."); 459 else 460 warnx("-s requires a WITH_ or " 461 "WITHOUT_ name ('%s')", 462 reqs[n].name); 463 usage(); 464 } 465 reqs[n].newvalue = ""; 466 } 467 if (reqs[n].newvalue != NULL && !reqs[n].remove) 468 warn_with_equals_no(reqs[n].name, 469 reqs[n].newvalue, NULL, 0); 470 if (reqs[n].remove || reqs[n].newvalue != NULL) 471 have_writes = 1; 472 else 473 have_reads = 1; 474 } 475 if (check && !have_writes) { 476 warnx("-c requires at least one name=value or -s name"); 477 usage(); 478 } 479 480 /* Descriptions are read-only */ 481 if (show_desc) { 482 if (have_writes) { 483 warnx("-d does not take values"); 484 usage(); 485 } 486 #ifndef __FreeBSD__ 487 if (format == BSDCONF_FORMAT_SYSCTL) 488 errx(EXIT_FAILURE, 489 "sysctl descriptions require FreeBSD"); 490 #endif 491 /* Explicit names need no file scan at all */ 492 if (!dump_all) { 493 #ifdef __FreeBSD__ 494 if (format == BSDCONF_FORMAT_SYSCTL) 495 exit(describe_sysctl()); 496 #endif 497 exit(describe_defaults()); 498 } 499 500 /* 501 * Dumps (-ad, -Ad, -aDd) pair each scanned directive with 502 * its description; harvest the descriptions before the 503 * read sandbox slams shut. 504 */ 505 if (format != BSDCONF_FORMAT_SYSCTL) 506 load_descriptions(); 507 } 508 509 /* Defaults can be read and checked against, never rewritten */ 510 if ((defaults_only || with_defaults) && have_writes && !check) 511 errx(EXIT_FAILURE, "defaults are read-only"); 512 513 /* Standard input can be read and checked, never rewritten */ 514 if (file_stdin && have_writes && !check) 515 errx(EXIT_FAILURE, "cannot write to standard input"); 516 517 #if defined(__FreeBSD__) 518 /* 519 * Refuse up front to set sysctl OIDs that can never take effect 520 * from sysctl.conf(5) (non-leaf, read-only, loader-only tunables) 521 * or whose values cannot fit the OID's CTLTYPE (so an overflowing 522 * assignment cannot surprise sysctl(8) at boot). Unknown OIDs are 523 * warned about but still written -- the module may not be loaded 524 * yet, matching init(8)'s handling of sysctl.conf(5). Only 525 * meaningful against the running system's sysctl tree, so skipped 526 * under -R. -i/-q quiet the unknown-OID warning; -k remains the 527 * module drop-in selector. 528 */ 529 if (format == BSDCONF_FORMAT_SYSCTL && have_writes && !check && 530 *rootdir == '\0') { 531 int quiet_unknown = ignore_unknown || quiet; 532 unsigned int u; 533 534 for (u = 0; u < nreqs; u++) { 535 if (reqs[u].newvalue == NULL) 536 continue; 537 if (sysctl_writable(reqs[u].name, reqs[u].newvalue, 538 quiet_unknown) != 0) { 539 /* Convert to a no-op; count the failure */ 540 reqs[u].newvalue = NULL; 541 reqs[u].remove = 0; 542 reqs[u].name = ""; 543 rv = EXIT_FAILURE; 544 } 545 } 546 have_writes = 0; 547 have_reads = 0; 548 for (u = 0; u < nreqs; u++) { 549 if (reqs[u].remove || reqs[u].newvalue != NULL) 550 have_writes = 1; 551 else if (reqs[u].name[0] != '\0') 552 have_reads = 1; 553 } 554 if (rv != EXIT_SUCCESS && !have_writes && !have_reads) 555 exit(rv); /* nothing settable remains */ 556 } 557 #endif 558 559 /* 560 * Scan the backing files to locate each request's authoritative 561 * definition. Pure reads and -c checks (do_checks() never calls 562 * put) run the scan inside a Capsicum sandbox -- except a sysctl 563 * description dump, whose kernel queries the sandbox would deny. 564 * Classify by whether we will actually write, not by whether the 565 * argv looked like name=value (`-c' sets have_writes for checks). 566 */ 567 scan_pass((check || !have_writes) && 568 !(show_desc && format == BSDCONF_FORMAT_SYSCTL)); 569 570 /* Materialize list edits now that effective values are known */ 571 if (merge_list_requests() != EXIT_SUCCESS) 572 rv = EXIT_FAILURE; 573 574 if (check) { 575 if (do_make_strikes(1) != EXIT_SUCCESS) 576 rv = EXIT_FAILURE; 577 if (do_checks() != EXIT_SUCCESS) 578 rv = EXIT_FAILURE; 579 exit(rv); 580 } 581 582 /* Apply writes first so that subsequent reads see the result */ 583 if (have_writes) { 584 int wrv; 585 586 if ((wrv = do_make_strikes(0)) != EXIT_SUCCESS) 587 rv = wrv; 588 if ((wrv = do_writes()) != EXIT_SUCCESS) 589 rv = wrv; 590 591 /* Refresh the scan for any trailing read requests */ 592 if (have_reads || dump_all) { 593 for (n = 0; (unsigned int)n < nreqs; n++) { 594 size_t ai; 595 596 trail_free(reqs[n].trail, reqs[n].ntrail); 597 reqs[n].trail = NULL; 598 reqs[n].ntrail = 0; 599 for (ai = 0; ai < reqs[n].nassigns; ai++) 600 free(reqs[n].assigns[ai].piece); 601 free(reqs[n].assigns); 602 reqs[n].assigns = NULL; 603 reqs[n].nassigns = 0; 604 reqs[n].found = 0; 605 reqs[n].append_present = 0; 606 reqs[n].srcidx = -1; 607 reqs[n].line = 0; 608 memset(reqs[n].infile, 0, nconf_files); 609 } 610 scan_pass(0); 611 } 612 } 613 614 if (have_reads || dump_all) { 615 int rrv; 616 617 if ((rrv = do_reads()) != EXIT_SUCCESS) 618 rv = rrv; 619 } 620 621 exit(rv); 622 } 623 624 /* 625 * Print short usage statement to stderr and exit with error status. 626 */ 627 void 628 usage(void) 629 { 630 631 fprintf(stderr, 632 "usage: %s target [-AcDeFinNqsvVx] [-j jail | -R dir]" 633 " [-f file | -k module]\n" 634 " name[[+|-]=value] ...\n", pgm); 635 fprintf(stderr, 636 " %s target [-ADeFnNqvV] [-j jail | -R dir]" 637 " [-f file | -k module] -a\n", pgm); 638 fprintf(stderr, 639 " %s target [-AaDinNq] [-j jail | -R dir]" 640 " -d [name ...]\n", pgm); 641 fprintf(stderr, 642 " %s target [-E] [-j jail | -R dir] [-k module]" 643 " -l | -L\n", pgm); 644 fprintf(stderr, 645 " %s rc [sysrc(8) argument ...]\n", pgm); 646 fprintf(stderr, "Try `%s --help' for more information.\n", pgm); 647 exit(EXIT_FAILURE); 648 } 649 650 /* 651 * Print long usage statement to stderr and exit with error status. 652 */ 653 void 654 help(void) 655 { 656 657 fprintf(stderr, 658 "usage: %s target [-AcDeFinNqsvVx] [-j jail | -R dir]" 659 " [-f file | -k module] name[[+|-]=value] ...\n", pgm); 660 fprintf(stderr, "TARGETS:\n"); 661 #define TGTFMT "\t%-9s %s\n" 662 fprintf(stderr, TGTFMT, "loader", 663 "files named by loader_conf_files et al. in"); 664 fprintf(stderr, TGTFMT, "", 665 "/boot/defaults/loader.conf (typically /boot/loader.conf,"); 666 fprintf(stderr, TGTFMT, "", 667 "loader.conf.d/*.conf, loader.conf.local)"); 668 fprintf(stderr, TGTFMT, "sysctl", 669 "/etc/sysctl.conf, sysctl.conf.local, sysctl.kld.d/*.conf"); 670 fprintf(stderr, TGTFMT, "make", 671 "/etc/make.conf (or -f for any make-syntax file)"); 672 fprintf(stderr, TGTFMT, "src", 673 "/usr/src build triad: src-env.conf, make.conf, src.conf"); 674 fprintf(stderr, TGTFMT, "", 675 "(new writes prefer src.conf; env: SRC_ENV_CONF,"); 676 fprintf(stderr, TGTFMT, "", 677 "__MAKE_CONF, SRCCONF)"); 678 fprintf(stderr, TGTFMT, "rc", 679 "pass-through: all other arguments go to sysrc(8) verbatim"); 680 fprintf(stderr, TGTFMT, "generic", 681 "no default files; requires -f file"); 682 fprintf(stderr, "OPTIONS:\n"); 683 #define OPTFMT "\t%-9s %s\n" 684 fprintf(stderr, OPTFMT, "-A", 685 "Include the target's defaults file in the sourcing order"); 686 fprintf(stderr, OPTFMT, "", 687 "(alone, dumps everything, defaults included)."); 688 fprintf(stderr, OPTFMT, "-a", 689 "Dump the union of all directives from the target's files."); 690 fprintf(stderr, OPTFMT, "-c", 691 "Check. Return success if no changes needed, else error."); 692 fprintf(stderr, OPTFMT, "-D", 693 "Consult only the target's defaults file."); 694 fprintf(stderr, OPTFMT, "-d", 695 "Show directive descriptions (from the defaults file's"); 696 fprintf(stderr, OPTFMT, "", 697 "comments; for sysctl, from the running kernel). With"); 698 fprintf(stderr, OPTFMT, "", 699 "-a, -A, or -D, describe every directive in scope."); 700 fprintf(stderr, OPTFMT, "-E", 701 "With -l or -L, list only files that exist on disk."); 702 fprintf(stderr, OPTFMT, "-e", 703 "Separate name and value with `=' (reads and write echoes)."); 704 fprintf(stderr, OPTFMT, "-F", 705 "Show the file holding each directive's effective value."); 706 fprintf(stderr, OPTFMT, "-f file", 707 "Operate on file, in the target's format, instead of the"); 708 fprintf(stderr, OPTFMT, "", 709 "target's standard files (`-' means standard input)."); 710 fprintf(stderr, OPTFMT, "-h", 711 "Print a short usage statement to stderr and exit."); 712 fprintf(stderr, OPTFMT, "--help", 713 "Print this message to stderr and exit."); 714 fprintf(stderr, OPTFMT, "--version", 715 "Print the utility and library versions and exit."); 716 fprintf(stderr, OPTFMT, "-i", 717 "Ignore unknown names (and quiet unknown sysctl OID warnings)."); 718 fprintf(stderr, OPTFMT, "-j jail", 719 "Operate within the jail `jail' (name or numeric id)."); 720 fprintf(stderr, OPTFMT, "-k module", 721 "Include the kernel module drop-in file for `module'."); 722 fprintf(stderr, OPTFMT, "-l", 723 "List the pathnames of the target's backing files."); 724 fprintf(stderr, OPTFMT, "-L", 725 "List all candidate files, including module drop-ins."); 726 fprintf(stderr, OPTFMT, "-n", 727 "Show only directive values, not their names."); 728 fprintf(stderr, OPTFMT, "-N", 729 "Show only directive names, not their values."); 730 fprintf(stderr, OPTFMT, "-q", 731 "Quiet. Suppress unknown-directive warnings and the"); 732 fprintf(stderr, OPTFMT, "", 733 "`old -> new' echo of writes."); 734 fprintf(stderr, OPTFMT, "-R dir", 735 "Operate within the root directory `dir' rather than `/'."); 736 fprintf(stderr, OPTFMT, "-s", 737 "Set empty WITH_/WITHOUT_ knobs (make and src only)."); 738 fprintf(stderr, OPTFMT, "-v", 739 "Verbose. Print the pathname of the configuration file"); 740 fprintf(stderr, OPTFMT, "", 741 "holding the final effective value."); 742 fprintf(stderr, OPTFMT, "-V", 743 "Trail. Reads: each assignment step (file:line, operator,"); 744 fprintf(stderr, OPTFMT, "", 745 "fragment, running effective). Writes: file:line:"); 746 fprintf(stderr, OPTFMT, "", 747 "name=old -> name=new (or name=value (unchanged))."); 748 fprintf(stderr, OPTFMT, "-x", 749 "Remove name(s) from the target's files."); 750 fprintf(stderr, "ENVIRONMENT:\n"); 751 fprintf(stderr, OPTFMT, "LOADER_DEFAULTS", 752 "Defaults file for the loader target (in place of"); 753 fprintf(stderr, OPTFMT, "", 754 "/boot/defaults/loader.conf)."); 755 fprintf(stderr, OPTFMT, "SRC_ENV_CONF", 756 "src-env.conf for the src target (default /etc/src-env.conf)."); 757 fprintf(stderr, OPTFMT, "__MAKE_CONF", 758 "make.conf for the src target (default /etc/make.conf)."); 759 fprintf(stderr, OPTFMT, "SRCCONF", 760 "src.conf for the src target (default /etc/src.conf)."); 761 exit(EXIT_FAILURE); 762 } 763