From owner-freebsd-bugs@FreeBSD.ORG Wed Dec 21 16:50:04 2011 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D2018106564A for ; Wed, 21 Dec 2011 16:50:04 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id A76FF8FC18 for ; Wed, 21 Dec 2011 16:50:04 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id pBLGo4GZ081988 for ; Wed, 21 Dec 2011 16:50:04 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id pBLGo4Cn081987; Wed, 21 Dec 2011 16:50:04 GMT (envelope-from gnats) Resent-Date: Wed, 21 Dec 2011 16:50:04 GMT Resent-Message-Id: <201112211650.pBLGo4Cn081987@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Maxim Ignatenko Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7B486106566B for ; 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 ; 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 ; 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 To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: conf/163508: [patch] Add "enable" and "disable" commands to rc.subr X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 Dec 2011 16:50:04 -0000 >Number: 163508 >Category: conf >Synopsis: [patch] Add "enable" and "disable" commands to rc.subr >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >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: >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 inf 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: >Unformatted: