From owner-freebsd-rc@FreeBSD.ORG Wed Nov 3 01:06:32 2010 Return-Path: Delivered-To: freebsd-rc@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id F27A6106566C; Wed, 3 Nov 2010 01:06:32 +0000 (UTC) (envelope-from dteske@vicor.com) Received: from postoffice.vicor.com (postoffice.vicor.com [69.26.56.53]) by mx1.freebsd.org (Postfix) with ESMTP id D7C678FC12; Wed, 3 Nov 2010 01:06:32 +0000 (UTC) Received: from [208.206.78.30] (port=43992 helo=dt.vicor.com) by postoffice.vicor.com with esmtpsa (SSLv3:RC4-MD5:128) (Exim 4.71) (envelope-from ) id 1PDRo4-0006Hm-Tg; Tue, 02 Nov 2010 18:06:31 -0700 From: Devin Teske To: freebsd-rc@freebsd.org In-Reply-To: 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> Content-Type: text/plain Organization: Vicor, Inc Date: Tue, 02 Nov 2010 18:06:28 -0700 Message-Id: <1288746388.7362.4.camel@localhost.localdomain> Mime-Version: 1.0 X-Mailer: Evolution 2.0.2 (2.0.2-41.el4) Content-Transfer-Encoding: 7bit X-Scan-Signature: eeda19339be77836aac052df51e20ca1 X-Scan-Host: postoffice.vicor.com Cc: Julian Elischer Subject: Re: sysrc(8) -- a sysctl(8)-like utility for managing rc.conf(5) X-BeenThere: freebsd-rc@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Discussion related to /etc/rc.d design and implementation." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Nov 2010 01:06:33 -0000 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 <-