From nobody@FreeBSD.org  Wed Dec 21 16:46:33 2011
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 7B486106566B
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 21 Dec 2011 16:46:33 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id 6A37C8FC0A
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 21 Dec 2011 16:46:33 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.4/8.14.4) with ESMTP id pBLGkXwJ084762
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 21 Dec 2011 16:46:33 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.4/8.14.4/Submit) id pBLGkXLG084761;
	Wed, 21 Dec 2011 16:46:33 GMT
	(envelope-from nobody)
Message-Id: <201112211646.pBLGkXLG084761@red.freebsd.org>
Date: Wed, 21 Dec 2011 16:46:33 GMT
From: Maxim Ignatenko <gelraen.ua@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [patch] Add "enable" and "disable" commands to rc.subr
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         163508
>Category:       conf
>Synopsis:       [rc.subr] [patch] Add "enable" and "disable" commands to rc.subr
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-rc
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Dec 21 16:50:04 UTC 2011
>Closed-Date:    
>Last-Modified:  Thu Dec 27 18:40:00 UTC 2012
>Originator:     Maxim Ignatenko
>Release:        8-STABLE
>Organization:
>Environment:
FreeBSD imax 8.2-STABLE FreeBSD 8.2-STABLE #5: Tue Nov 15 10:50:14 EET 2011     root@imax:/usr/obj/usr/src/sys/IMAX  i386
>Description:
Attached patch adds "enable" and "disable" commands to /etc/rc.subr.
Each command first check /etc/rc.conf.d/${name} file (if /etc/rc.conf.d/
exists) for presence of ${rcvar} assignment, then all files in rc_conf_files
checked. If there are no ${rcvar} assignment it gets added to
/etc/rc.conf.d/${name} (if /etc/rc.conf.d exists) or to last writable file
in rc_conf_files
>How-To-Repeat:

>Fix:


Patch attached with submission follows:

--- /usr/src.8/etc/rc.subr	2011-09-25 10:25:06.000000000 +0300
+++ /etc/rc.subr	2011-12-21 18:36:15.000000000 +0200
@@ -441,9 +441,34 @@
 }
 
 #
+# replace_var
+#	Replaces values of all variable $2 assignments in file $1 with
+#	value $3
+#
+replace_var()
+{
+	local file var val
+	file="$1"
+	var="$2"
+	val="$3"
+	/usr/bin/sed -E -I"" -e "s/^([[:space:]]*)${var}=.*/\1${var}=${val}/" "${file}"
+}
+
+#
+# check_var_exists
+#	Retuns 0 if variable $2 is explicitly set in file $1
+#
+check_var_exists()
+{
+	local file var
+	file="$1"
+	var="$2"
+	grep -qE "^[[:space:]]*${var}=" "${file}"
+}
+
 # run_rc_command argument
 #	Search for argument in the list of supported commands, which is:
-#		"start stop restart rcvar status poll ${extra_commands}"
+#		"start stop restart rcvar status poll enable disable ${extra_commands}"
 #	If there's a match, run ${argument}_cmd or the default method
 #	(see below).
 #
@@ -579,6 +604,10 @@
 #
 #	rcvar		Display what rc.conf variable is used (if any).
 #
+#	enable		Set ${rcvar} to YES
+#
+#	disable		Set ${rcvar} to NO
+#
 #	Variables available to methods, and after run_rc_command() has
 #	completed:
 #
@@ -647,7 +676,7 @@
 	eval _override_command=\$${name}_program
 	command=${_override_command:-$command}
 
-	_keywords="start stop restart rcvar $extra_commands"
+	_keywords="start stop restart rcvar enable disable $extra_commands"
 	rc_pid=
 	_pidcmd=
 	_procname=${procname:-${command}}
@@ -689,12 +718,26 @@
 		if [ "$_elem" != "$rc_arg" ]; then
 			continue
 		fi
+
+		if [ -n "${rcvar}" -a "${rc_arg}" == "enable" ]; then
+			if checkyesno ${rcvar}; then
+				echo "Service ${name} already enabled."
+				return 0
+			fi
+		fi
+		if [ -n "${rcvar}" -a "${rc_arg}" == "disable" ]; then
+			if ! checkyesno ${rcvar}; then
+				echo "Service ${name} not enabled."
+				return 0
+			fi
+		fi
+
 					# if ${rcvar} is set, $1 is not "rcvar"
 					# and ${rc_pid} is not set, then run
 					#	checkyesno ${rcvar}
 					# and return if that failed
 					#
-		if [ -n "${rcvar}" -a "$rc_arg" != "rcvar" -a "$rc_arg" != "stop" ] ||
+		if [ -n "${rcvar}" -a "$rc_arg" != "rcvar" -a "$rc_arg" != "stop" -a "$rc_arg" != "enable" ] ||
 		    [ -n "${rcvar}" -a "$rc_arg" = "stop" -a -z "${rc_pid}" ]; then
 			if ! checkyesno ${rcvar}; then
 				if [ -n "${rc_quiet}" ]; then
@@ -895,6 +938,43 @@
 			echo ""
 			;;
 
+		enable|disable)
+			local done filelist new_state val
+			if [ "${rc_arg}" = "enable" ]; then
+				new_state="enabled"
+				val="YES"
+			else
+				new_state="disabled"
+				val="NO"
+			fi
+			done=0
+			filelist=$(reverse_list ${rc_conf_files})
+			if [ -d "/etc/rc.conf.d" ]; then
+				filelist="/etc/rc.conf.d/${name} ${filelist}"
+			fi
+			for file in ${filelist}; do
+				if [ -r "${file}" -a -w "${file}" ]; then
+					if check_var_exists "${file}" "${rcvar}"; then
+						replace_var "${file}" "${rcvar}" "${val}"
+						echo "Service ${name} ${new_state} in ${file}."
+						done=1
+						break
+					fi
+				fi
+			done
+			if [ "${done}" = "0" ]; then
+				if [ -d "/etc/rc.conf.d" ]; then
+					touch "/etc/rc.conf.d/name"
+				fi
+				for file in ${filelist}; do
+					if [ -w "${file}" ]; then
+						echo "${rcvar}=${val}" >> "${file}"
+						echo "Service ${name} ${new_state} in ${file}."
+					fi
+				done
+			fi
+			;;
+
 		*)
 			rc_usage $_keywords
 			;;


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-rc 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Sat Dec 24 01:59:19 UTC 2011 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=163508 

From: Doug Barton <dougb@FreeBSD.org>
To: bug-followup@FreeBSD.org, gelraen.ua@gmail.com
Cc:  
Subject: Re: conf/163508: [rc.subr] [patch] Add &quot;enable&quot; and &quot;disable&quot;
 commands to rc.subr
Date: Fri, 23 Dec 2011 18:15:24 -0800

 This idea has been considered before and rejected because it's too
 difficult to catch all the corner cases, and actually editing a config
 file is not really all that hard of a thing to do.
 
 
 Doug
 
 -- 
 
 		[^L]
 
 	Breadth of IT experience, and depth of knowledge in the DNS.
 	Yours for the right price.  :)  http://SupersetSolutions.com/
 

From: Devin Teske <devin.teske@fisglobal.com>
To: <bug-followup@FreeBSD.org>, <gelraen.ua@gmail.com>
Cc:  
Subject: Re: conf/163508: [rc.subr] [patch] Add &quot;enable&quot; and &quot;disable&quot; commands to rc.subr
Date: Fri, 23 Dec 2011 18:34:45 -0800

 --Apple-Mail-39-642018807
 Content-Transfer-Encoding: 7bit
 Content-Type: text/plain; charset="us-ascii"
 
 
 I agree with dougb that this is out of scope.
 
 If you want though, check out the following to solve your needs:
 
 http://druidbsd.sourceforge.net/download/sysrc.txt
 
 A utility with sysctl(8)-like syntax that operates on rc.conf(5).
 -- 
 Devin
 
 _____________
 The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you.
 
 --Apple-Mail-39-642018807
 Content-Transfer-Encoding: 7bit
 Content-Type: text/html; charset="us-ascii"
 
 <html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br>
 I agree with dougb that this is out of scope.<div><br></div><div>If you want though, check out the following to solve your needs:</div><div><br></div><div><a href="http://druidbsd.sourceforge.net/download/sysrc.txt">http://druidbsd.sourceforge.net/download/sysrc.txt</a></div><div><br></div><div>A utility with sysctl(8)-like syntax that operates on rc.conf(5).</div><div>--&nbsp;</div><div>Devin</div>
 <DIV>
 _____________<BR>
 The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you.<BR>
 </DIV></body></html>
 
 --Apple-Mail-39-642018807--

From: Maxim Ignatenko <gelraen.ua@gmail.com>
To: Doug Barton <dougb@freebsd.org>
Cc: bug-followup@freebsd.org
Subject: Re: conf/163508: [rc.subr] [patch] Add &quot;enable&quot; and
 &quot;disable&quot; commands to rc.subr
Date: Sat, 24 Dec 2011 14:20:19 +0200

 On 24 December 2011 04:15, Doug Barton <dougb@freebsd.org> wrote:
 > This idea has been considered before and rejected because it's too
 > difficult to catch all the corner cases, and actually editing a config
 > file is not really all that hard of a thing to do.
 >
 
 The idea was to make enabling/disabling services less error-prone. It
 don't need to catch _all_ corner cases, because if administrator do
 something unusual with startup configuration he should be able to
 manipulate it in proper way, or even have tools that do something
 similar.
 Proposed patch handles /etc/rc.conf, /etc/rc.conf.local and
 /etc/rc.conf.d/* properly (I hope), so it should fit nicely in 95% of
 cases.
 Doing `service someserive enable` is much faster and less error-prone
 that `service someservice rcvar ; echo someservicercvar_enable=YES >>
 /etc/rc.conf`

From: Doug Barton <dougb@FreeBSD.org>
To: Maxim Ignatenko <gelraen.ua@gmail.com>
Cc: bug-followup@freebsd.org
Subject: Re: conf/163508: [rc.subr] [patch] Add &quot;enable&quot; and &quot;disable&quot;
 commands to rc.subr
Date: Sat, 24 Dec 2011 12:59:44 -0800

 On 12/24/2011 04:20, Maxim Ignatenko wrote:
 > The idea was to make enabling/disabling services less error-prone.
 
 How is adding foo_enable=1 to rc.conf error-prone?
 
 
 -- 
 
 		[^L]
 
 	Breadth of IT experience, and depth of knowledge in the DNS.
 	Yours for the right price.  :)  http://SupersetSolutions.com/
 

From: Maxim Ignatenko <gelraen.ua@gmail.com>
To: Doug Barton <dougb@freebsd.org>
Cc: bug-followup@freebsd.org
Subject: Re: conf/163508: [rc.subr] [patch] Add &quot;enable&quot; and
 &quot;disable&quot; commands to rc.subr
Date: Sun, 25 Dec 2011 09:15:44 +0200

 On 24 December 2011 22:59, Doug Barton <dougb@freebsd.org> wrote:
 > On 12/24/2011 04:20, Maxim Ignatenko wrote:
 >> The idea was to make enabling/disabling services less error-prone.
 >
 > How is adding foo_enable=1 to rc.conf error-prone?
 >
 
 Typo like fooo_enbale=1, or one missed '>' in echo foo_enable=1 > /etc/rc.conf

From: Devin Teske <devin.teske@fisglobal.com>
To: <bug-followup@FreeBSD.org>, <gelraen.ua@gmail.com>
Cc: <devin.teske@fisglobal.com>
Subject: Re: conf/163508: [rc.subr] [patch] Add &quot;enable&quot; and &quot;disable&quot; commands to rc.subr
Date: Tue, 27 Dec 2011 10:17:42 -0800

 ------=_NextPart_000_0285_01CCC480.C5B42FC0
 Content-Type: text/plain; charset="us-ascii"
 Content-Transfer-Encoding: 7bit
 
 I would like to submit for review a modified version of the original submitter's
 patch.
 
 I feel that the original patch takes a too-simplistic view of the problem
 at-hand and am offering a much more robust solution. The replacement patch uses
 my "sysrc" utility which -- if you haven't discovered it yet -- is a
 peer-reviewed "nuclear reactor" approach opposed to a "bike shed" approach.
 sysrc takes everything into consideration, including (but not limited to):
 
 (listed in no particular order)
 
 1. Environment Variable Taint
 
 It is not possible to "confuse" or "break" the code by exporting strange things
 into the environment.
 
 2. Shell Taint Checking
 
 If rc.conf(5) has invalid syntax prior to editing, it will refuse to edit and an
 error is produced. Similarly, if editing rc.conf(5) introduces a syntax error,
 the original rc.conf(5) is restored and an error is produced.
 
 This prevents producing a situation where rc.conf itself prevents you from
 booting into multi-user mode. If, for any reason at all, rc.conf(5) causes you
 to drop to single-user mode, it's assuredly is NOT because of sysrc, as it
 taint-checks both before and after.
 
 3. Safety First
 
 Use mktemp to prevent race-conditions. Use atomic actions where necessary.
 
 4. Minimal changes
 
 The original patch submitted with conf/163508 does more work than is necessary
 w/respect to items-changed within a single-file. Case-in-point, the
 "replace_var" function simply fires a sed global-replace to replace all
 instances of "thing=blah" on multiple lines. That's not cool.
 
 Sysrc will ONLY change the last [valid] assignment to the variable. Sysrc wants
 to keep your rc.conf exactly the way you like it as best it can and change as
 little as possible (and when it does make changes, it wants to do it in a
 fashion that's going to preserve as much structure as possible; see next item).
 
 5. Quotations, whitespace, compound statements and in-line comments
 
 The sed command in the original patch's "replace_var" function (a) WILL preserve
 leading whitespace but (b) WON'T preserve in-line comments that appear after the
 assignment, (c) NOR preserve the type of quotation that was used in the
 assignment(s), (d) NOR preserve compound statements.
 
 When sysrc replaces the last [valid] assignment to a given variable, it will
 actually preserve the type of quotation used (whether it be single, double or
 no-quotation). It will also preserve both leading whitespace and trailing
 whitespace. It will also retain in-line comments. It will also preserve trailing
 commands in a compound statement (multi-variable-assignment compound separated
 by whitespace or multi-command compound separated by semi-colon).
 
 6. Leave certain things alone!
 
 Sysrc will refuse to modify things that it knows that it couldn't have possibly
 done. For example, it will refuse to touch something like this:
 
 foogribble_enable=`echo YES`
 
 and instead opt to add an overriding new entry.
 
 7. Performance
 
 Sysrc has been rewritten several times to improve performance. It heavily
 leverages awk to improve performance by several orders of magnitude compared to
 using straight bourne-shell built-in internals.
 
 ( end itemized list ; continue discussion )
 
 The above list calls out major flaws in the currently-submitted patch and
 highlights the fact that sysrc has no such short-comings.
 
 NOTE: sysrc would have to be taken into the base to support this patch. (aside)
 MidnightBSD has taken it into its base already (and there's another distro that
 escapes my mind at the moment, which has similarly taken it into its base)
 
 NOTE: In my submitted patch, there are two open-ended questions to reviewers:
 (a) ought we to use a full pathname to sysrc and if-so (b) where might sysrc be
 placed? (/bin would be nice so that it's available in single-user mode).
 -- 
 Devin
 
 P.S. sysrc is available here: http://druidbsd.sourceforge.net/download/sysrc.txt
 
 _____________
 The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you.
 
 ------=_NextPart_000_0285_01CCC480.C5B42FC0
 Content-Type: text/plain; name="conf_163508_patch.new.txt"
 Content-Transfer-Encoding: quoted-printable
 Content-Disposition: attachment; filename="conf_163508_patch.new.txt"
 
 --- /usr/src.8/etc/rc.subr	2011-09-25 10:25:06.000000000 +0300=0A=
 +++ /etc/rc.subr	2011-12-27 08:33:50.000000000 -0800=0A=
 @@ -443,7 +443,7 @@=0A=
  #=0A=
  # run_rc_command argument=0A=
  #	Search for argument in the list of supported commands, which is:=0A=
 -#		"start stop restart rcvar status poll ${extra_commands}"=0A=
 +#		"start stop restart rcvar status poll enable disable =
 ${extra_commands}"=0A=
  #	If there's a match, run ${argument}_cmd or the default method=0A=
  #	(see below).=0A=
  #=0A=
 @@ -579,6 +579,10 @@=0A=
  #=0A=
  #	rcvar		Display what rc.conf variable is used (if any).=0A=
  #=0A=
 +#	enable		Set ${rcvar} to YES=0A=
 +#=0A=
 +#	disable		Set ${rcvar} to NO=0A=
 +#=0A=
  #	Variables available to methods, and after run_rc_command() has=0A=
  #	completed:=0A=
  #=0A=
 @@ -647,7 +651,7 @@=0A=
  	eval _override_command=3D\$${name}_program=0A=
  	command=3D${_override_command:-$command}=0A=
  =0A=
 -	_keywords=3D"start stop restart rcvar $extra_commands"=0A=
 +	_keywords=3D"start stop restart rcvar enable disable $extra_commands"=0A=
  	rc_pid=3D=0A=
  	_pidcmd=3D=0A=
  	_procname=3D${procname:-${command}}=0A=
 @@ -689,12 +693,26 @@=0A=
  		if [ "$_elem" !=3D "$rc_arg" ]; then=0A=
  			continue=0A=
  		fi=0A=
 +=0A=
 +		if [ -n "${rcvar}" -a "${rc_arg}" =3D=3D "enable" ]; then=0A=
 +			if checkyesno ${rcvar}; then=0A=
 +				echo "Service ${name} already enabled."=0A=
 +				return 0=0A=
 +			fi=0A=
 +		fi=0A=
 +		if [ -n "${rcvar}" -a "${rc_arg}" =3D=3D "disable" ]; then=0A=
 +			if ! checkyesno ${rcvar}; then=0A=
 +				echo "Service ${name} not enabled."=0A=
 +				return 0=0A=
 +			fi=0A=
 +		fi=0A=
 +=0A=
  					# if ${rcvar} is set, $1 is not "rcvar"=0A=
  					# and ${rc_pid} is not set, then run=0A=
  					#	checkyesno ${rcvar}=0A=
  					# and return if that failed=0A=
  					#=0A=
 -		if [ -n "${rcvar}" -a "$rc_arg" !=3D "rcvar" -a "$rc_arg" !=3D "stop" =
 ] ||=0A=
 +		if [ -n "${rcvar}" -a "$rc_arg" !=3D "rcvar" -a "$rc_arg" !=3D "stop" =
 -a "$rc_arg" !=3D "enable" ] ||=0A=
  		    [ -n "${rcvar}" -a "$rc_arg" =3D "stop" -a -z "${rc_pid}" ]; then=0A=
  			if ! checkyesno ${rcvar}; then=0A=
  				if [ -n "${rc_quiet}" ]; then=0A=
 @@ -895,6 +913,16 @@=0A=
  			echo ""=0A=
  			;;=0A=
  =0A=
 +		enable|disable)=0A=
 +			local val=0A=
 +			if [ "$rc_arg" =3D "enable" ]; then=0A=
 +				val=3D"YES"=0A=
 +			else=0A=
 +				val=3D"NO"=0A=
 +			fi=0A=
 +			sysrc "$rcvar=3D$val" && sysrc -v "$rcvar"=0A=
 +			;;=0A=
 +=0A=
  		*)=0A=
  			rc_usage $_keywords=0A=
  			;;=0A=
 
 ------=_NextPart_000_0285_01CCC480.C5B42FC0--

From: Devin Teske <devin.teske@fisglobal.com>
To: <bug-followup@FreeBSD.org>, <gelraen.ua@gmail.com>
Cc:  
Subject: Re: conf/163508: [rc.subr] [patch] Add &quot;enable&quot; and &quot;disable&quot; commands to rc.subr
Date: Wed, 28 Dec 2011 13:21:38 -0800

 I've submitted PR ports/163679 to add sysutils/sysrc to the ports-tree.
 
 With any luck, it will become immensely popular and then be migrated into the
 base -- making my previously-attached "conf_163508_patch.new.txt" possible (as
 it relies on sysrc being available).
 -- 
 Devin
 
 _____________
 The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you.

From: Devin Teske <devin.teske@fisglobal.com>
To: <bug-followup@FreeBSD.org>, <gelraen.ua@gmail.com>
Cc: Devin Teske <dteske@freebsd.org>
Subject: Re: conf/163508: [rc.subr] [patch] Add &quot;enable&quot; and &quot;disable&quot; commands to rc.subr
Date: Thu, 27 Dec 2012 10:32:10 -0800

 In HEAD is usr.sbin/sysrc
 
 I'm not advocating the use of sysrc(8) to solve this problem, but instead, =
 that tool uses a common library of sh(1) routines that can be used to solve=
  this problem. Specifically,=85
 
 /usr/share/bsdconfig/sysrc.subr
 
 Is the complete module allowing any shell script (or subroutine collection,=
  such as /etc/rc.subr) to manage the rc.conf(5) collection of system config=
 uration files.
 
 Currently, this include file (sysrc.subr) only exists in HEAD and is not di=
 stributed to RELEASE yet. To install this script, first download HEAD and t=
 hen:
 
 cd usr.sbin/bsdconfig
 make all install
 
 --=20
 Devin
 
 _____________
 The information contained in this message is proprietary and/or confidentia=
 l. If you are not the intended recipient, please: (i) delete the message an=
 d all copies; (ii) do not disclose, distribute or use the message in any ma=
 nner; and (iii) notify the sender immediately. In addition, please be aware=
  that any message addressed to our domain is subject to archiving and revie=
 w by persons other than the intended recipient. Thank you.
>Unformatted:
