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>