Index: service.sh =================================================================== --- service.sh +++ service.sh @@ -36,23 +36,81 @@ echo "${0##*/} -R" echo "${0##*/} [-v] -l | -r" echo "${0##*/} [-v] start|stop|etc." + echo "${0##*/} [-v] [-s] enable|disable|rcvar|rcopts|rcdelete" echo "${0##*/} -h" echo '' echo '-e Show services that are enabled' echo "-R Stop and start enabled $local_startup services" echo "-l List all scripts in /etc/rc.d and $local_startup" echo '-r Show the results of boot time rcorder' + echo '-s Use a separate config file in /etc/rc.conf.d/' echo '-v Verbose' echo '' } -while getopts 'ehlrRv' COMMAND_LINE_ARGUMENT ; do +do_rc_action () { + dir=$1 + script=$2 + + eval `grep ^name= $dir/$script` + eval `grep ^rcvar $dir/$script` + + if [ -n "$SEPARATE_CONFIG" ]; then + config_path="/etc/rc.conf.d/$script" + else + config_path=/etc/rc.conf + fi + + if [ $RC_ACTION = "YES" -o $RC_ACTION = "NO" ]; then + # Enable or disable the service + if [ -n "$SEPARATE_CONFIG" ]; then + [ -d ${config_path%/*} ] || mkdir ${config_path%/*} + fi + /usr/sbin/sysrc $sysrc_flags $rcvar=${RC_ACTION} > /dev/null + elif [ $RC_ACTION = "DELETE" ]; then + # Delete the service + if [ -n "$SEPARATE_CONFIG" ]; then + rm -f /etc/rc.conf.d/$script + else + /usr/sbin/sysrc -x $rcvar > /dev/null + fi + elif [ $RC_ACTION = "RC_OPTS" ]; then + # Show optional variables for the service + echo "Available rc.conf options for $script:" + + # Print the comments between the KEYWORDS and the sourcing of + # /etc/rc.subr + # XXX: This is a hack. rc(8) lacks a proper way to register + # additional rc.conf variables for a service. + awk ' + /^#\ [A-Z]+:.*$/ {flag=1;next} + /^\.\ \/etc\/rc.subr/ {exit} + flag == 1 {print $0}' \ + $dir/$script + exit 0 + fi + exitflag=$? + # XXX: At the moment sysrc(8) exits with exit code 0 + # even if the variable to be deleted is not in + # rc.conf. So the text below is printed + # unconditionally. (Fixed in r268860) + if [ $exitflag -eq 0 ]; then + if [ $RC_ACTION = "DELETE" -a -n "$SEPARATE_CONFIG" ]; then + echo "$config_path deleted." + else + echo "$script $RC_ACTION_TEXT in $config_path" + fi + fi +} + +while getopts 'ehlrRsv' COMMAND_LINE_ARGUMENT ; do case "${COMMAND_LINE_ARGUMENT}" in e) ENABLED=eopt ;; h) usage ; exit 0 ;; l) LIST=lopt ;; r) RCORDER=ropt ;; R) RESTART=Ropt ;; + s) SEPARATE_CONFIG=sopt ;; v) VERBOSE=vopt ;; *) usage ; exit 1 ;; esac @@ -135,15 +193,58 @@ exit 1 fi +if [ -n "$SEPARATE_CONFIG" ]; then + sysrc_flags="-f /etc/rc.conf.d/$script" +fi + + +case $1 in +enable) + RC_ACTION=YES + RC_ACTION_TEXT=enabled + shift + ;; +disable) + RC_ACTION=NO + RC_ACTION_TEXT=disabled + shift + ;; +rcdelete) + RC_ACTION=DELETE + RC_ACTION_TEXT=deleted + shift + ;; +rcopts) + RC_ACTION=RC_OPTS + shift + ;; +*) + ;; +esac + + cd / for dir in /etc/rc.d $local_startup; do if [ -x "$dir/$script" ]; then [ -n "$VERBOSE" ] && echo "$script is located in $dir" - exec env -i HOME=/ PATH=/sbin:/bin:/usr/sbin:/usr/bin $dir/$script $* + + # This part touches /etc/rc.conf or /etc/rc.conf.d/$script + if [ -n "$RC_ACTION" ]; then + do_rc_action "$dir" "$script" + fi + + [ $# -gt 0 ] && + exec env -i HOME=/ PATH=/sbin:/bin:/usr/sbin:/usr/bin $dir/$script $* fi done +# If an rc.conf action was made but no additional rc command was given, exit +# with sysrc's exit code. +[ -n "$exitflag" ] && exit $exitflag + # If the script was not found echo "$script does not exist in /etc/rc.d or the local startup" echo "directories (${local_startup})" exit 1 + +# vim:set ts=4: