Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Oct 2010 17:39:41 -0700
From:      Devin Teske <dteske@vicor.com>
To:        freebsd-rc@freebsd.org
Cc:        Julian Elischer <julian@freebsd.org>
Subject:   Re: sysrc(8) -- a sysctl(8)-like utility for managing rc.conf(5)
Message-ID:  <1287448781.5713.3.camel@localhost.localdomain>
In-Reply-To: <1286996709.32724.60.camel@localhost.localdomain>
References:  <1286925182.32724.18.camel@localhost.localdomain> <1286996709.32724.60.camel@localhost.localdomain>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 2010-10-13 at 12:05 -0700, Devin Teske wrote: 
> On Tue, 2010-10-12 at 16:13 -0700, Devin Teske wrote:
> > Hey all,
> > 
> > [...]
> > 
> > Behold... sysrc(8) v2.0
> > 
> > #!/bin/sh
> > [...]
> 
> Version 2.1 is available here: http://druidbsd.sf.net/

Version 2.2 now.
Same links.

I added `-R dir' for specifying an alternate root (other than `/')
directory (mostly for handling jails).


> 
> Direct links:
> http://druidbsd.sf.net/download/sysrc.gz (download gzipped)
> http://druidbsd.sf.net/download/sysrc.txt (view as text)
> 
> Here's the changes:
> 

--- sysrc.txt	2010-10-13 19:02:08.000000000 +0000
+++ bin/sysrc	2010-10-18 13:30:54.000000000 +0000
@@ -2,8 +2,8 @@
 # -*- tab-width:  4 -*- ;; Emacs
 # vi: set tabstop=4     :: Vi/ViM
 #
-# Revision: 2.1
-# Last Modified: October 13th, 2010
+# Revision: 2.2
+# Last Modified: October 18th, 2010
 ############################################################ COPYRIGHT
 #
 # (c)2010. Devin Teske. All Rights Reserved.
@@ -30,6 +30,7 @@
 # SUCH DAMAGE.
 #
 # AUTHOR      DATE      DESCRIPTION
+# dteske   2010.10.18   Add `-R dir' for operating in different root-dir
 # dteske   2010.10.13   Allow `-f file' multiple times.
 # dteske   2010.10.12   Updates per freebsd-hackers thread.
 # dteske   2010.09.29   Initial version.
@@ -54,6 +55,7 @@
 #   	-i         Ignore unknown variables.
 #   	-n         Show only variable values, not their names.
 #   	-N         Show only variable names, not their values.
+#   	-R dir     Operate within the root directory `dir' rather than `/'.
 # 
 #   ENVIRONMENT:
 #   	RC_DEFAULTS      Location of `/etc/defaults/rc.conf' file.
@@ -88,8 +90,9 @@
 # Options
 #
 DESCRIBE=
-RC_CONFS=
 IGNORE_UNKNOWNS=
+RC_CONFS=
+ROOTDIR=
 SHOW_ALL=
 SHOW_EQUALS=
 SHOW_NAME=1
@@ -170,6 +173,8 @@
 	        "Show only variable values, not their names."
 	eprintf "$optfmt" "-N" \
 	        "Show only variable names, not their values."
+	eprintf "$optfmt" "-R dir" \
+	        "Operate within the root directory \`dir' rather than \`/'."
 	eprintf "\n"
 
 	eprintf "ENVIRONMENT:\n"
@@ -185,10 +190,10 @@
 #
 # Unset all environment variables in the current scope. An optional list of
 # arguments can be passed, indicating which variables to avoid unsetting; the
-# `--except' is required to enabled the exclusion-list as the remainder of
+# `--except' is required to enable the exclusion-list as the remainder of
 # positional arguments.
 #
-# Be careful not to call this in a shell that you still except to perform
+# Be careful not to call this in a shell that you still expect to perform
 # $PATH expansion in, because this will blow $PATH away. This is best used
 # within a sub-shell block "(...)" or "$(...)" or "`...`".
 #
@@ -267,16 +272,41 @@
 		. "$RC_DEFAULTS"
 
 		#
+		# If the query is for `rc_conf_files' then store the value that
+		# we inherited from sourcing RC_DEFAULTS (above) so that we may
+		# conditionally restore this value after source_rc_confs in the
+		# event that RC_CONFS does not customize the value.
+		#
+		if [ "$1" = "rc_conf_files" ]; then
+			_rc_conf_files="$rc_conf_files"
+		fi
+
+		#
 		# If `-f file' was passed, set $rc_conf_files to an explicit
 		# value, modifying the default behavior of source_rc_confs().
 		#
 		[ "$RC_CONFS" ] && rc_conf_files="$RC_CONFS"
 
+		source_rc_confs
+
+		#
+		# If the query was for `rc_conf_files' AND after calling
+		# source_rc_confs the value has not changed, then we should
+		# restore the value to the one inherited from RC_DEFAULTS
+		# before performing the final query (preventing us from
+		# returning RC_CONFS which may be relative to ROOTDIR).
+		#
+		if [ "$1" = "rc_conf_files" -a \
+		     "$RC_CONFS" != "" -a \
+		     "$rc_conf_files" = "$RC_CONFS" \
+		]; then
+			rc_conf_files="$_rc_conf_files"
+			unset _rc_conf_files
+		fi
+
 		unset RC_CONFS
 			# no longer needed
 
-		source_rc_confs
-
 		#
 		# This must be the last functional line for both the sub-shell,
 		# and the function to preserve the return status from formats
@@ -332,8 +362,9 @@
 	# Find which file matches assignment to the given variable name.
 	#
 	for file in $conf_files; do
+		[ -f "$file" -a -r "$file" ] || continue
 		if grep -q "^[[:space:]]*$varname=" $file; then
-			echo $file
+			echo ${file#$ROOTDIR}
 			return $SUCCESS
 		fi
 	done
@@ -404,7 +435,7 @@
 	#
 	local not_found=
 	local file="$( sysrc_find "$varname" )"
-	if [ "$file" = "$RC_DEFAULTS" -o ! "$file" ]; then
+	if [ "$file" = "${RC_DEFAULTS#$ROOTDIR}" -o ! "$file" ]; then
 		#
 		# We either got a null response (not found) or the variable
 		# was only found in the rc.conf(5) defaults. In either case,
@@ -554,7 +585,7 @@
 #
 # Process command-line options
 #
-while getopts hf:aAdevinN flag; do
+while getopts hf:aAdevinNR: flag; do
 	case "$flag" in
 	h) usage;;
 	f) RC_CONFS="$RC_CONFS${RC_CONFS:+ }$OPTARG";;
@@ -566,13 +597,14 @@
 	i) IGNORE_UNKNOWNS=1;;
 	n) SHOW_NAME=;;
 	N) SHOW_VALUE=;;
+	R) ROOTDIR="$OPTARG";;
 	\?) usage;;
 	esac
 done
 shift $(( $OPTIND - 1 ))
 
 #
-# Process command-line options
+# Process `-e', `-n', and `-N' command-line options
 #
 SEP=': '
 [ "$SHOW_EQUALS" ] && SEP='="'
@@ -583,13 +615,49 @@
 	SHOW_EQUALS=
 fi
 
+#
+# Process `-R dir' command-line option
+#
+if [ "$ROOTDIR" ]; then
+	#
+	# Sanity checks
+	#
+	[ -e "$ROOTDIR" ] || die "%s: %s: No such file or directory" \
+		"$progname" "$ROOTDIR"
+	[ -d "$( eval realpath "$ROOTDIR" )" ] || die \
+		"%s: %s: Not a directory" "$progname" "$ROOTDIR"
+
+	#
+	# When ROOTDIR is set, we need to:
+	#
+	# a. Prefix RC_DEFAULTS with ROOTDIR
+	#
+	RC_DEFAULTS="$ROOTDIR$RC_DEFAULTS"
+
+	# b. Override the use of rc_conf_files from RC_DEFAULTS
+	#    by setting RC_CONFS
+	#
+	[ "$RC_CONFS" ] || RC_CONFS="$( sysrc_get rc_conf_files )"
+
+	# c. Prefix RC_CONFS with ROOTDIR
+	#
+	r=
+	for file in $RC_CONFS; do
+		r="$r${r:+ }$ROOTDIR$file"
+	done
+	RC_CONFS="$r"
+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
@@ -602,7 +670,7 @@
 		IFS="$IFS|"
 		EXCEPT="IFS|EXCEPT|PATH|RC_DEFAULTS|OPTIND|DESCRIBE|SEP"
 		EXCEPT="$EXCEPT|SHOW_ALL|SHOW_EQUALS|SHOW_NAME|SHOW_VALUE"
-		EXCEPT="$EXCEPT|SYSRC_VERBOSE|RC_CONFS"
+		EXCEPT="$EXCEPT|SYSRC_VERBOSE|RC_CONFS|ROOTDIR"
 
 		#
 		# Clean the environment (except for our required variables)
@@ -634,7 +702,8 @@
 			# other than rc.conf(5) defaults.
 			#
 			[ "$SHOW_ALL" = "1" -a \
-			  "$( sysrc_find rc_conf_files )" = "$RC_DEFAULTS" \
+			  "$( sysrc_find rc_conf_files )" = \
+			  	"${RC_DEFAULTS#$ROOTDIR}" \
 			] \
 			&& unset rc_conf_files
 		fi
@@ -691,8 +760,11 @@
 
 		if [ "$SYSRC_VERBOSE" ]; then
 			file="$( sysrc_find "$NAME" )"
-			[ "$file" = "$RC_DEFAULTS" -o ! "$file" ] && \
+			if [ "$file" = "${RC_DEFAULTS#$ROOTDIR}" \
+			     -o ! "$file" ]; then
 				file="$( sysrc_get "rc_conf_files%%[$IFS]*" )"
+				file="${file#$ROOTDIR}"
+			fi
 			echo -n "$file: "
 		fi
 



-- 
Cheers,
Devin Teske

-> CONTACT INFORMATION <-
Business Solutions Consultant II
FIS - fisglobal.com
510-735-5650 Mobile
510-621-2038 Office
510-621-2020 Office Fax
909-477-4578 Home/Fax
devin.teske@fisglobal.com

-> LEGAL DISCLAIMER <-
This message  contains confidential  and proprietary  information
of the sender,  and is intended only for the person(s) to whom it
is addressed. Any use, distribution, copying or disclosure by any
other person  is strictly prohibited.  If you have  received this
message in error,  please notify  the e-mail sender  immediately,
and delete the original message without making a copy.

-> END TRANSMISSION <-




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1287448781.5713.3.camel>