Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 02 Nov 2010 18:06:28 -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:  <1288746388.7362.4.camel@localhost.localdomain>
In-Reply-To: <D763F474-8F19-4C65-B23F-78C9B137A8FE@vicor.com>
References:  <1286925182.32724.18.camel@localhost.localdomain> <1286996709.32724.60.camel@localhost.localdomain> <1287448781.5713.3.camel@localhost.localdomain> <1287510629.25599.2.camel@localhost.localdomain> <D763F474-8F19-4C65-B23F-78C9B137A8FE@vicor.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 2010-10-20 at 23:46 -0700, Devin Teske wrote: 
> On Oct 19, 2010, at 10:50 AM, Devin Teske wrote:
> 
> > On Mon, 2010-10-18 at 17:39 -0700, Devin Teske wrote:
> >> 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).
> > 
> > Version 2.3 now.
> > Same links.
> > 
> 
> Version 2.4 now.
> Same links.
> 

Version 2.5 now.
Same links.

That should be all the features that were requested (and some that
weren't).

> > 
> >> 
> >>> 
> >>> 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.2_4	2010-10-20 23:36:51.000000000 -0700
+++ sysrc	2010-11-02 17:47:23.000000000 -0700
@@ -2,8 +2,8 @@
 # -*- tab-width:  4 -*- ;; Emacs
 # vi: set tabstop=4     :: Vi/ViM
 #
-# Revision: 2.4
-# Last Modified: October 20th, 2010
+# Revision: 2.5
+# Last Modified: November 2nd, 2010
 ############################################################ COPYRIGHT
 #
 # (c)2010. Devin Teske. All Rights Reserved.
@@ -30,6 +30,11 @@
 # SUCH DAMAGE.
 #
 # AUTHOR      DATE      DESCRIPTION
+# dteske   2010.11.02   Preserve leading/trailing whitespace in sysrc_set().
+# dteske   2010.11.02   Deprecate lrev() in favor of tail(1)'s `-r' flag.
+# dteske   2010.11.02   Map `-R dir' to `-j jail' if `dir' maps to a single
+#                       running jail (or produce an error if `dir' maps to
+#                       many running jails).
 # dteske   2010.10.20   Make `-j jail' and `-R dir' more secure
 # dteske   2010.10.19   Add `-j jail' for operating on jails (see jexec(8)).
 # dteske   2010.10.18   Add `-R dir' for operating in different root-dir.
@@ -105,6 +110,16 @@
 
 ############################################################ FUNCTION
 
+# have $anything
+#
+# A wrapper to the `type' built-in. Returns true if argument is a valid shell
+# built-in, keyword, or externally-tracked binary, otherwise false.
+#
+have()
+{
+	type "$@" > /dev/null 2>&1
+}
+
 # fprintf $fd $fmt [ $opts ... ]
 #
 # Like printf, except allows you to print to a specific file-descriptor. Useful
@@ -382,50 +397,6 @@
 	return $FAILURE # Not found
 }
 
-# ... | lrev
-# lrev $file ...
-#
-# Reverse lines of input. Unlike rev(1) which reverses the ordering of
-# characters on a single line, this function instead reverses the line
-# sequencing.
-#
-# For example, the following input:
-#
-# 	Line 1
-# 	Line 2
-# 	Line 3
-#
-# Becomes reversed in the following manner:
-#
-# 	Line 3
-# 	Line 2
-# 	Line 1
-#
-lrev()
-{
-	local stdin_rev=
-	if [ $# -gt 0 ]; then
-		#
-		# Reverse lines from files passed as positional arguments.
-		#
-		while [ $# -gt 0 ]; do
-			local file="$1"
-			[ -f "$file" ] && lrev < "$file"
-			shift 1
-		done
-	else
-		#
-		# Reverse lines from standard input
-		#
-		while read -r LINE; do
-			stdin_rev="$LINE
-$stdin_rev"
-		done
-	fi
-
-	echo -n "$stdin_rev"
-}
-
 # sysrc_set $varname $new_value
 #
 # Change a setting in the system configuration files (edits the files in-place
@@ -485,19 +456,49 @@
 	#
 	# Operate on the matching file, replacing only the last occurrence.
 	#
-	local new_contents="`lrev $file 2> /dev/null | \
+	local __IFS="$IFS"
+	local new_contents="`tail -r $file 2> /dev/null | \
 	( found=
+	  IFS=
 	  while read -r LINE; do
-	  	if [ ! "$found" ]; then
-	  		match="$( echo "$LINE" | grep "$regex" )"
-	  		if [ "$match" ]; then
-	  			LINE="$varname"'="'"$new_value"'"'
-	  			found=1
-	  		fi
-	  	fi
-	  	echo "$LINE"
+	  	if [ "$found" ]; then
+			echo "$LINE"
+			continue
+		fi
+
+		#
+		# Determine what type of assignment is being performed
+		# and append the proper expression to accurately replace
+		# the current value.
+		#
+		# NOTE: The base regular expression below should match
+		#       functionally the regex used by sysrc_find().
+		#
+		regex="^([[:space:]]*$varname=)"
+		if echo "$LINE" | grep -Eq "$regex'"; then
+			# found assignment w/ single-quoted value
+			found=1
+			regex="$regex(')([^']*)('{0,1})"
+		elif echo "$LINE" | grep -Eq "$regex"'"'; then
+			# found assignment w/ double-quoted value
+			found=1
+			regex="$regex"'(")([^\\\\]*\\\\")*[^"]*("{0,1})'
+		elif echo "$LINE" | grep -Eq "$regex[^[:space:]]"; then
+			# found assignment w/ non-quoted value
+			found=1
+			regex="$regex()([^[:space:]]*)()"
+
+			# Use quotes if replacing with multi-word value
+			[ "${new_value%[$__IFS]*}" != "$new_value" ] \
+				&& new_value='"'"$new_value"'"'
+		fi
+
+		[ "$found" ] && LINE="$( echo "$LINE" \
+			| sed -re "s/$regex/\1\2$new_value\4/" )"
+
+		echo "$LINE"
 	  done
-	) | lrev`"
+	) | tail -r`"
 
 	[ "$new_contents" ] || return $FAILURE
 
@@ -668,6 +669,52 @@
 		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(8) or jexec(8) utilities are missing.
+		#
+		if have jexec && 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" "$progname" "$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
+				  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

-- 
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.

-> FUN STUFF <-
-----BEGIN GEEK CODE BLOCK-----
Version 3.1
GAT/CS d(+) s: a- C++(++++) UB++++$ P++(++++) L++(++++) !E--- W++ N? o? K- w O
M+ V- PS+ PE Y+ PGP- t(+) 5? X+(++) R>++ tv(+) b+(++) DI+(++) D(+) G+>++ e>+ h
r>++ y+ 
------END GEEK CODE BLOCK------
http://www.geekcode.com/

-> END TRANSMISSION <-




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