Import sysutils/sysrc from the ports tree (current version 5.1). Importing

disconnected under the WITH_BSDCONFIG flag (a good idea since this version of
sysrc(8) indeed requires the `sysrc.subr' module installed by bsdconfig(8)).

Multiple reasons sysrc should not simply continue to live in ports. The most
important being that it is tightly coupled with the base.

Approved by:	adrian (co-mentor)
This commit is contained in:
Devin Teske 2012-10-03 02:32:47 +00:00
parent 3955d011f8
commit 2a357efa9c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=241149
5 changed files with 924 additions and 2 deletions

View File

@ -147,6 +147,7 @@ SUBDIR+= bluetooth
.if ${MK_BSDCONFIG} != "no"
SUBDIR+= bsdconfig
SUBDIR+= sysrc
.endif
.if ${MK_BSNMP} != "no"

View File

@ -29,10 +29,10 @@ if [ ! "$_SYSRC_SUBR" ]; then _SYSRC_SUBR=1
############################################################ INCLUDES
BSDCFG_SHARE="/usr/share/bsdconfig"
. $BSDCFG_SHARE/common.subr || exit 1
[ "$_COMMON_SUBR" ] || . $BSDCFG_SHARE/common.subr || exit 1
BSDCFG_LIBE="/usr/libexec/bsdconfig"
f_include_lang $BSDCFG_LIBE/include/messages.subr
[ ! "$_SYSRC_JAILED" ] && f_include_lang $BSDCFG_LIBE/include/messages.subr
############################################################ CONFIGURATION

13
usr.sbin/sysrc/Makefile Normal file
View File

@ -0,0 +1,13 @@
# $FreeBSD$
NO_OBJ=
SCRIPTS= sysrc
MAN= sysrc.8
beforeinstall:
mkdir -p ${DESTDIR}${SCRIPTSDIR}
mkdir -p ${DESTDIR}${MANDIR}8
.include <bsd.prog.mk>

618
usr.sbin/sysrc/sysrc Normal file
View File

@ -0,0 +1,618 @@
#!/bin/sh
#-
# Copyright (c) 2010-2012 Devin Teske
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# $FreeBSD$
#
############################################################ INCLUDES
BSDCFG_SHARE="/usr/share/bsdconfig"
[ "$_COMMON_SUBR" ] || . $BSDCFG_SHARE/common.subr || exit 1
[ "$_SYSRC_SUBR" ] || f_include $BSDCFG_SHARE/sysrc.subr
############################################################ CONFIGURATION
#
# Default verbosity.
#
: ${SYSRC_VERBOSE:=}
############################################################ GLOBALS
#
# Options
#
DELETE=
DESCRIBE=
IGNORE_UNKNOWNS=
JAIL=
QUIET=
ROOTDIR=
SHOW_ALL=
SHOW_EQUALS=
SHOW_FILE=
SHOW_NAME=1
SHOW_VALUE=1
############################################################ FUNCTIONS
# die [ $fmt [ $opts ... ]]
#
# Optionally print a message to stderr before exiting with failure status.
#
die()
{
local fmt="$1"
[ $# -gt 0 ] && shift 1
[ "$fmt" ] && f_err "$fmt\n" "$@"
exit $FAILURE
}
# usage
#
# Prints a short syntax statement and exits.
#
usage()
{
f_err "Usage: %s [OPTIONS] name[=value] ...\n" "$pgm"
f_err "Try \`%s --help' for more information.\n" "$pgm"
die
}
# help
#
# Prints a full syntax statement and exits.
#
help()
{
local optfmt="\t%-11s%s\n"
local envfmt="\t%-17s%s\n"
f_err "Usage: %s [OPTIONS] name[=value] ...\n" "$pgm"
f_err "OPTIONS:\n"
f_err "$optfmt" "-a" \
"Dump a list of all non-default configuration variables."
f_err "$optfmt" "-A" \
"Dump a list of all configuration variables (incl. defaults)."
f_err "$optfmt" "-d" \
"Print a description of the given variable."
f_err "$optfmt" "-D" \
"Show default value(s) only (this is the same as setting"
f_err "$optfmt" "" \
"RC_CONFS to NULL or passing \`-f' with a NULL file-argument)."
f_err "$optfmt" "-e" \
"Print query results as \`var=value' (useful for producing"
f_err "$optfmt" "" \
"output to be fed back in). Ignored if \`-n' is specified."
f_err "$optfmt" "-f file" \
"Operate on the specified file(s) instead of rc_conf_files."
f_err "$optfmt" "" \
"Can be specified multiple times for additional files."
f_err "$optfmt" "-F" \
"Show only the last rc.conf(5) file each directive is in."
f_err "$optfmt" "-h" \
"Print a short usage statement to stderr and exit."
f_err "$optfmt" "--help" \
"Print this message to stderr and exit."
f_err "$optfmt" "-i" \
"Ignore unknown variables."
f_err "$optfmt" "-j jail" \
"The jid or name of the jail to operate within (overrides"
f_err "$optfmt" "" \
"\`-R dir'; requires jexec(8))."
f_err "$optfmt" "-n" \
"Show only variable values, not their names."
f_err "$optfmt" "-N" \
"Show only variable names, not their values."
f_err "$optfmt" "-q" \
"Quiet. Ignore previous \`-v' and/or SYSRC_VERBOSE."
f_err "$optfmt" "-R dir" \
"Operate within the root directory \`dir' rather than \`/'."
f_err "$optfmt" "-v" \
"Verbose. Print the pathname of the specific rc.conf(5)"
f_err "$optfmt" "" \
"file where the directive was found."
f_err "$optfmt" "-x" \
"Remove variable(s) from specified file(s)."
f_err "\n"
f_err "ENVIRONMENT:\n"
f_err "$envfmt" "RC_CONFS" \
"Override default rc_conf_files (even if set to NULL)."
f_err "$envfmt" "RC_DEFAULTS" \
"Location of \`/etc/defaults/rc.conf' file."
f_err "$envfmt" "SYSRC_VERBOSE" \
"Default verbosity. Set to non-NULL to enable."
die
}
# jail_depend
#
# Dump dependencies such as language-file variables and include files to stdout
# to be piped-into sh(1) running via jexec(8)/chroot(8). As a security measure,
# this prevents existing language files and library files from being loaded in
# the jail. This also relaxes the requirement to have these files in every jail
# before sysrc can be used on said jail.
#
jail_depend()
{
#
# Indicate that we are jailed
#
echo export _SYSRC_JAILED=1
#
# Print i18n language variables (their current values are sanitized
# and re-printed for interpretation so that the i18n language files
# do not need to exist within the jail).
#
local var val
for var in \
msg_cannot_create_permission_denied \
msg_permission_denied \
msg_previous_syntax_errors \
; do
val=$( eval echo \"\$$var\" |
awk '{ gsub(/'\''/, "'\''\\'\'\''"); print }' )
echo $var="'$val'"
done
#
# Print include dependencies
#
cat $BSDCFG_SHARE/common.subr
cat $BSDCFG_SHARE/sysrc.subr
}
############################################################ MAIN SOURCE
#
# Perform sanity checks
#
[ $# -gt 0 ] || usage
#
# Check for `--help' command-line option
#
( # Operate in sub-shell to protect $@ in parent
while [ $# -gt 0 ]; do
case "$1" in
--help) exit 1;;
-[fRj]) # These flags take an argument
shift 1;;
esac
shift 1
done
exit 0
) || help
#
# Process command-line flags
#
while getopts aAdDef:Fhij:nNqR:vxX flag; do
case "$flag" in
a) SHOW_ALL=${SHOW_ALL:-1};;
A) SHOW_ALL=2;;
d) DESCRIBE=1;;
D) RC_CONFS=;;
e) SHOW_EQUALS=1;;
f) RC_CONFS="$RC_CONFS${RC_CONFS:+ }$OPTARG";;
F) SHOW_FILE=1;;
h) usage;;
i) IGNORE_UNKNOWNS=1;;
j) [ "$OPTARG" ] || die \
"%s: Missing or null argument to \`-j' flag" "$pgm"
JAIL="$OPTARG";;
n) SHOW_NAME=;;
N) SHOW_VALUE=;;
q) QUIET=1 SYSRC_VERBOSE=;;
R) [ "$OPTARG" ] || die \
"%s: Missing or null argument to \`-R' flag" "$pgm"
ROOTDIR="$OPTARG";;
v) SYSRC_VERBOSE=1 QUIET=;;
x) DELETE=${DELETE:-1};;
X) DELETE=2;;
\?) usage;;
esac
done
shift $(( $OPTIND - 1 ))
#
# [More] Sanity checks (e.g., "sysrc --")
#
[ $# -eq 0 -a ! "$SHOW_ALL" ] && usage
#
# Taint-check all rc.conf(5) files
#
errmsg="$pgm: Exiting due to previous syntax errors"
if ( : ${RC_CONFS?} ) > /dev/null 2>&1; then
( for i in $RC_CONFS; do
[ -e "$i" ] || continue
/bin/sh -n "$i" || exit $FAILURE
done
exit $SUCCESS
) || die "$errmsg"
else
/bin/sh -n "$RC_DEFAULTS" || die "$errmsg"
( . "$RC_DEFAULTS"
for i in $rc_conf_files; do
[ -e "$i" ] || continue
/bin/sh -n "$i" || exit $FAILURE
done
exit $SUCCESS
) || die "$errmsg"
fi
#
# Process `-x' (and secret `-X') command-line options
#
errmsg="$pgm: \`-x' option incompatible with \`-a'/\`-A' options"
errmsg="$errmsg (use \`-X' to override)"
if [ "$DELETE" -a "$SHOW_ALL" ]; then
[ "$DELETE" = "2" ] || die "$errmsg"
fi
#
# Process `-e', `-n', and `-N' command-line options
#
SEP=': '
[ "$SHOW_EQUALS" ] && SEP='="'
[ "$SHOW_NAME" ] || SHOW_EQUALS=
[ "$SYSRC_VERBOSE" = "0" ] && SYSRC_VERBOSE=
if [ ! "$SHOW_VALUE" ]; then
SHOW_NAME=1
SHOW_EQUALS=
fi
#
# Process `-j jail' and `-R dir' command-line options
#
if [ "$JAIL" -o "$ROOTDIR" ]; then
#
# Reconstruct the arguments that we want to carry-over
#
args="
${SYSRC_VERBOSE:+-v}
${QUIET:+-q}
$( [ "$DELETE" = "1" ] && echo \ -x )
$( [ "$DELETE" = "2" ] && echo \ -X )
$( [ "$SHOW_ALL" = "1" ] && echo \ -a )
$( [ "$SHOW_ALL" = "2" ] && echo \ -A )
${DESCRIBE:+-d}
${SHOW_EQUALS:+-e}
${IGNORE_UNKNOWNS:+-i}
$( [ "$SHOW_NAME" ] || echo \ -n )
$( [ "$SHOW_VALUE" ] || echo \ -N )
$( [ "$SHOW_FILE" ] && echo \ -F )
"
if ( : ${RC_CONFS?} ) > /dev/null 2>&1; then
args="$args -f '$RC_CONFS'"
fi
for arg in "$@"; do
args="$args '$arg'"
done
#
# If both are supplied, `-j jail' supercedes `-R dir'
#
if [ "$JAIL" ]; then
#
# Re-execute ourselves with sh(1) via jexec(8)
#
( echo set -- $args
jail_depend
cat $0
) | env - RC_DEFAULTS="$RC_DEFAULTS" \
/usr/sbin/jexec "$JAIL" /bin/sh
exit $?
elif [ "$ROOTDIR" ]; then
#
# Make sure that the root directory specified is not to any
# running jails.
#
# NOTE: To maintain backward compatibility with older jails on
# older systems, we will not perform this check if either the
# jls(1) or jexec(8) utilities are missing.
#
if f_have jexec && f_have jls; then
jid="`jls jid path | \
(
while read JID JROOT; do
[ "$JROOT" = "$ROOTDIR" ] || continue
echo $JID
done
)`"
#
# If multiple running jails match the specified root
# directory, exit with error.
#
if [ "$jid" -a "${jid%[$IFS]*}" != "$jid" ]; then
die "%s: %s: %s" "$pgm" "$ROOTDIR" \
"$( echo "Multiple jails claim this" \
"directory as their root." \
"(use \`-j jail' instead)" )"
fi
#
# If only a single running jail matches the specified
# root directory, implicitly use `-j jail'.
#
if [ "$jid" ]; then
#
# Re-execute outselves with sh(1) via jexec(8)
#
( echo set -- $args
jail_depend
cat $0
) | env - RC_DEFAULTS="$RC_DEFAULTS" \
/usr/sbin/jexec "$jid" /bin/sh
exit $?
fi
# Otherwise, fall through and allow chroot(8)
fi
#
# Re-execute ourselves with sh(1) via chroot(8)
#
( echo set -- $args
jail_depend
cat $0
) | env - RC_DEFAULTS="$RC_DEFAULTS" \
/usr/sbin/chroot "$ROOTDIR" /bin/sh
exit $?
fi
fi
#
# Process `-a' or `-A' command-line options
#
if [ "$SHOW_ALL" ]; then
#
# Get a list of variables that are currently set in the rc.conf(5)
# files (included `/etc/defaults/rc.conf') by performing a call to
# source_rc_confs() in a clean environment.
#
( # Operate in a sub-shell to protect the parent environment
#
# Set which variables we want to preserve in the environment.
# Append the pipe-character (|) to the list of internal field
# separation (IFS) characters, allowing us to use the below
# list both as an extended grep (-E) pattern and argument list
# (required to first get f_clean_env() to preserve these in the
# environment and then later to prune them from the list of
# variables produced by set(1)).
#
IFS="$IFS|"
EXCEPT="IFS|EXCEPT|PATH|RC_DEFAULTS|OPTIND|DESCRIBE|SEP"
EXCEPT="$EXCEPT|DELETE|SHOW_ALL|SHOW_EQUALS|SHOW_NAME"
EXCEPT="$EXCEPT|SHOW_VALUE|SHOW_FILE|SYSRC_VERBOSE|RC_CONFS"
EXCEPT="$EXCEPT|pgm|SUCCESS|FAILURE"
EXCEPT="$EXCEPT|f_sysrc_desc_awk|f_sysrc_delete_awk"
#
# Clean the environment (except for our required variables)
# and then source the required files.
#
f_clean_env --except $EXCEPT
if [ -f "$RC_DEFAULTS" -a -r "$RC_DEFAULTS" ]; then
. "$RC_DEFAULTS"
#
# If passed `-a' (rather than `-A'), re-purge the
# environment, removing the rc.conf(5) defaults.
#
[ "$SHOW_ALL" = "1" ] \
&& f_clean_env --except rc_conf_files $EXCEPT
#
# If `-f file' was passed, set $rc_conf_files to an
# explicit value, modifying the default behavior of
# source_rc_confs().
#
( : ${RC_CONFS?} ) > /dev/null 2>&1 &&
rc_conf_files="$RC_CONFS"
source_rc_confs
#
# If passed `-a' (rather than `-A'), remove
# `rc_conf_files' unless it was defined somewhere
# other than rc.conf(5) defaults.
#
[ "$SHOW_ALL" = "1" -a \
"$( f_sysrc_find rc_conf_files )" = "$RC_DEFAULTS" \
] \
&& unset rc_conf_files
fi
for NAME in $( set |
awk -F= '/^[[:alpha:]_][[:alnum:]_]*=/ {print $1}' |
grep -Ev "^($EXCEPT)$"
); do
#
# If enabled, describe rather than expand value
#
if [ "$DESCRIBE" ]; then
echo "$NAME: $( f_sysrc_desc "$NAME" )"
continue
fi
#
# If `-F' is passed, find it and move on
#
if [ "$SHOW_FILE" ]; then
[ "$SHOW_NAME" ] && echo -n "$NAME: "
f_sysrc_find "$NAME"
continue
fi
#
# If `-X' is passed, delete the variables
#
if [ "$DELETE" = "2" ]; then
f_sysrc_delete "$NAME"
continue
fi
[ "$SYSRC_VERBOSE" ] && \
echo -n "$( f_sysrc_find "$NAME" ): "
#
# If `-N' is passed, simplify the output
#
if [ ! "$SHOW_VALUE" ]; then
echo "$NAME"
continue
fi
echo "${SHOW_NAME:+$NAME$SEP}$(
f_sysrc_get "$NAME" )${SHOW_EQUALS:+\"}"
done
)
#
# Ignore the remainder of positional arguments.
#
exit $SUCCESS
fi
#
# Process command-line arguments
#
while [ $# -gt 0 ]; do
NAME="${1%%=*}"
[ "$DESCRIBE" ] && \
echo "$NAME: $( f_sysrc_desc "$NAME" )"
case "$1" in
*=*)
#
# Like sysctl(8), if both `-d' AND "name=value" is passed,
# first describe, then attempt to set
#
if [ "$SYSRC_VERBOSE" ]; then
file=$( f_sysrc_find "$NAME" )
[ "$file" = "$RC_DEFAULTS" -o ! "$file" ] && \
file=$( f_sysrc_get 'rc_conf_files%%[$IFS]*' )
echo -n "$file: "
fi
#
# If `-x' or `-X' is passed, delete the variable and ignore the
# desire to set some value
#
if [ "$DELETE" ]; then
f_sysrc_delete "$NAME"
shift 1
continue
fi
#
# If `-N' is passed, simplify the output
#
if [ ! "$SHOW_VALUE" ]; then
echo "$NAME"
f_sysrc_set "$NAME" "${1#*}"
else
if [ "$SHOW_FILE" ]; then
before=$( f_sysrc_find "$NAME" )
else
before=$( f_sysrc_get "$NAME" )
fi
if f_sysrc_set "$NAME" "${1#*=}"; then
if [ "$SHOW_FILE" ]; then
after=$( f_sysrc_find "$NAME" )
echo -n "${SHOW_NAME:+$NAME$SEP}"
echo -n "$before${SHOW_EQUALS:+\"}"
echo " -> $after"
else
after=$( f_sysrc_get "$NAME" )
echo -n "${SHOW_NAME:+$NAME$SEP}"
echo "$before -> $after"
fi
fi
fi
;;
*)
if ! IGNORED="$( f_sysrc_get "$NAME?" )"; then
[ "$IGNORE_UNKNOWNS" ] \
|| echo "$pgm: unknown variable '$NAME'"
shift 1
continue
fi
#
# Like sysctl(8), when `-d' is passed,
# desribe it rather than expanding it
#
if [ "$DESCRIBE" ]; then
shift 1
continue
fi
#
# If `-x' or `-X' is passed, delete the variable
#
if [ "$DELETE" ]; then
f_sysrc_delete "$NAME"
shift 1
continue
fi
#
# If `-F' is passed, find it and move on
#
if [ "$SHOW_FILE" ]; then
[ "$SHOW_NAME" ] && echo -n "$NAME: "
f_sysrc_find "$NAME"
shift 1
continue
fi
[ "$SYSRC_VERBOSE" ] && \
echo -n "$( f_sysrc_find "$NAME" ): "
#
# If `-N' is passed, simplify the output
#
if [ ! "$SHOW_VALUE" ]; then
echo "$NAME"
else
echo "${SHOW_NAME:+$NAME$SEP}$(
f_sysrc_get "$NAME" )${SHOW_EQUALS:+\"}"
fi
esac
shift 1
done

290
usr.sbin/sysrc/sysrc.8 Normal file
View File

@ -0,0 +1,290 @@
.\" Copyright (c) 2011-2012 Devin Teske
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd Aug 24, 2012
.Dt SYSRC 8
.Os
.Sh NAME
.Nm sysrc
.Nd safely edit system rc files
.Sh SYNOPSIS
.Nm
.Op Fl dDeFhinNqvx
.Op Fl f Ar file
.Op Fl j Ar jail | Fl R Ar dir
.Ar name Ns Op = Ns Ar value
.Ar ...
.Nm
.Op Fl dDeFhinNqvx
.Op Fl f Ar file
.Op Fl j Ar jail | Fl R Ar dir
.Fl a | A
.Sh DESCRIPTION
The
.Nm
utility retrieves
.Xr rc.conf 5
variables from the collection of system rc files and allows processes with
appropriate privilege to change values in a safe and effective manner.
.Pp
The following options are available:
.Bl -tag -width indent+
.It Fl a
Dump a list of all non-default configuration variables.
.It Fl A
Dump a list of all configuration variables
.Pq incl. defaults .
.It Fl d
Print a description of the given variable.
.It Fl D
Show default value(s) only (this is the same as setting RC_CONFS to NULL or
passing `-f' with a NULL file-argument).
.It Fl e
Print query results as
.Ql var=value
.Pq useful for producing output to be fed back in .
Ignored if
.Fl n
is specified.
.It Fl f Ar file
Operate on the specified file(s) instead of the files obtained by reading the
.Sq rc_conf_files
entry in the
.Ev RC_DEFAULTS
file.
This option can be specified multiple times for additional files.
.It Fl F
Show only the last
.Xr rc.conf 5
file each directive is in.
.It Fl h
Print a short usage message to stderr and exit.
.It Fl -help
Print a full usage statement to stderr and exit.
.It Fl i
Ignore unknown variables.
.It Fl j Ar jail
The
.Ar jid
or name of the
.Ar jail
to operate within
.Pq overrides So Fl R Ar dir Sc ; requires Xr jexec 8 .
.It Fl n
Show only variable values, not their names.
.It Fl N
Show only variable names, not their values.
.It Fl q
Quiet. Ignore previous
.Fl v
and/or
.Ev SYSRC_VERBOSE .
.It Fl R Ar dir
Operate within the root directory
.Pq Sq Ar dir
rather than
.Pq Sq / .
.It Fl v
Verbose. Print the pathname of the specific
.Xr rc.conf 5
file where the directive was found.
.It Fl x
Remove variable(s) from specified file(s).
.El
.Pp
This utility works similar to
.Xr sysctl 8 .
It shares the `-e' and `-n' options
.Pq detailed above
and also has the same
.Ql name[=value]
syntax for querying/setting configuration options.
.Pp
However, while
.Xr sysctl 8
serves to query/modify MIBs in the entrant kernel,
.Xr sysrc 8
instead works on values in the system
.Xr rc.conf 5
configuration files.
.Pp
The list of system configuration files is configured in the file
.Ql /etc/defaults/rc.conf
within the variable
.Ql rc_conf_files ,
which by-default contains a space-separated list of pathnames. On all FreeBSD
systems, this defaults to the value "/etc/rc.conf /etc/rc.conf.local". Each
pathname is sourced in-order upon startup. It is in the same fashion that
.Nm
sources the configuration files before returning the value of the given
variable.
.Pp
When supplied a variable name,
.Nm
will return the value of the variable. If the variable does not appear in any
of the configured
.Ql rc_conf_files ,
an error is printed and error status is returned.
.Pp
When changing values of a given variable, it does not matter if the variable
appears in any of the
.Ql rc_conf_files
or not. If the variable does not appear in any of the files, it is appended to
the end of the first pathname in the
.Ql rc_conf_files
variable. Otherwise,
.Nm
will replace only the last-occurrence in the last-file found to contain the
variable. This gets the value to take effect next boot without heavily
modifying these integral files (yet taking care not to allow the file to
grow unwieldy should
.Nm
be called repeatedly).
.Sh ENVIRONMENT
The following environment variables are referenced by
.Nm :
.Bl -tag -width ".Ev SYSRC_VERBOSE"
.It Ev RC_CONFS
Override default
.Ql rc_conf_files
.Pq even if set to NULL .
.It Ev RC_DEFAULTS
Location of
.Ql /etc/defaults/rc.conf
file.
.It Ev SYSRC_VERBOSE
Default verbosity. Set to non-NULL to enable.
.El
.Sh DEPENDENCIES
The following standard commands are required by
.Nm :
.Pp
.Xr awk 1 ,
.Xr cat 1 ,
.Xr chmod 1 ,
.Xr chown 8 ,
.Xr env 1 ,
.Xr grep 1 ,
.Xr jexec 8 ,
.Xr jls 1 ,
.Xr mktemp 1 ,
.Xr mv 1 ,
.Xr rm 1 ,
.Xr sh 1 ,
.Xr stat 1 ,
.Xr tail 1
.Sh FILES
.Bl -tag -width ".Pa /etc/defaults/rc.conf" -compact
.It Pa /etc/defaults/rc.conf
.It Pa /etc/rc.conf
.It Pa /etc/rc.conf.local
.El
.Sh EXAMPLES
Below are some simple examples of how
.Nm
can be used to query certain values from the
.Xr rc.conf 5
collection of system configuration files:
.Pp
.Nm
sshd_enable
.Dl returns the value of $sshd_enable, usually YES or NO .
.Pp
.Nm
defaultrouter
.Dl returns IP address of default router Pq if configured .
.Pp
Working on other files, such as
.Xr crontab 5 :
.Pp
.Nm
-f /etc/crontab MAILTO
.Dl returns the value of the MAILTO setting Pq if configured .
.Pp
In addition to the above syntax,
.Nm
also supports inline
.Xr sh 1
PARAMETER expansion for changing the way values are reported, shown below:
.Pp
.Nm
\&'hostname%%.*'
.Dl returns $hostname up to (but not including) first `.' .
.Pp
.Nm
\&'network_interfaces%%[$IFS]*'
.Dl returns first word of $network_interfaces .
.Pp
.Nm
\&'ntpdate_flags##*[$IFS]'
.Dl returns last word of $ntpdate_flags (time server address) .
.Pp
.Nm
usbd_flags-"default"
.Dl returns $usbd_flags or "default" if unset or NULL .
.Pp
.Nm
cloned_interfaces+"alternate"
.Dl returns "alternate" if $cloned_interfaces is set .
.Pp
.Nm
\&'#kern_securelevel'
.Dl returns length in characters of $kern_securelevel .
.Pp
.Nm
\&'hostname?'
.Dl returns NULL and error status 2 if $hostname is unset Pq or if set, returns the value of $hostname with no error status .
.Pp
.Nm
\&'hostname:?'
.Dl returns NULL and error status 2 if $hostname is unset or NULL Pq or if set and non-NULL, returns value without error status .
.Sh LIMITATIONS
The
.Nm
utility presently does not support the
.Ql rc.conf.d
collection of system configuration files
.Pq which requires a service name to be known during execution .
.Pp
This will be corrected by a future enhancement.
.Sh SEE ALSO
.Xr jail 8 ,
.Xr jexec 8 ,
.Xr jls 1 ,
.Xr rc 8 ,
.Xr rc.conf 5 ,
.Xr sysctl 8
.Sh HISTORY
A
.Nm
utility first appeared in
.Bx 10.0 .
.Sh AUTHORS
.An Devin Teske Aq dteske@FreeBSD.org
.Sh THANKS TO
Brandon Gooch, Garrett Cooper, Julian Elischer, Pawel Jakub Dawidek,
Cyrille Lefevre, Ross West, Stefan Esser, Marco Steinbach, and Jilles Tjoelker
for suggestions and help.