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