[arch-projects] [INITSCRIPTS][PATCH] rc.d: handle a set of options

Sebastien Luttringer seblu at seblu.net
Tue Aug 23 09:32:32 EDT 2011


rc.d can now take --started, --stopped, --auto, --noauto as option which
help user to populate list of daemon for all actions

As a corollary list command can now take a list of dameon to display
All kind of arguments can be mixed to obtain the proper output.

zsh and bash completion are updated

Note: Output of help command exit 0 and is no more printed on stderr

Signed-off-by: Sebastien Luttringer <seblu at seblu.net>
---
 bash-completion |   20 +++++-----
 rc.d            |  109 ++++++++++++++++++++++++++++++++++++++-----------------
 zsh-completion  |    5 +--
 3 files changed, 86 insertions(+), 48 deletions(-)

diff --git a/bash-completion b/bash-completion
index d78484e..1df229e 100644
--- a/bash-completion
+++ b/bash-completion
@@ -3,20 +3,20 @@
 _rc_d()
 {
 	local action cur prev
-	action="help list start stop reload restart"
+	actions='help list start stop reload restart'
+	options='--started --stopped --auto --noauto'
 	_get_comp_words_by_ref cur prev
-	if ((COMP_CWORD == 1)); then
-		COMPREPLY=($(compgen -W "${action}" -- "$cur"))
-	elif [[ "$prev" == help ]]; then
+	_get_first_arg
+	if [[ -z "$arg" ]]; then
+		COMPREPLY=($(compgen -W "${actions} ${options}" -- "$cur"))
+	elif [[ "$arg" == help ]]; then
 		COMPREPLY=()
-	elif [[ "$prev" == list ]]; then
-		((COMP_CWORD == 2)) && COMPREPLY=($(compgen -W "started stopped" -- "$cur")) || COMPREPLY=()
-	elif [[ "$prev" == start ]]; then
+	elif [[ "$arg" == start ]]; then
 		COMPREPLY=($(comm -23 <(cd /etc/rc.d && compgen -f -X 'functions*' "$cur"|sort) <(cd /run/daemons/ && compgen -f "$cur"|sort)))
-	elif [[ "$prev" =~ stop|restart|reload ]]; then
+	elif [[ "$arg" =~ stop|restart|reload ]]; then
 		COMPREPLY=($(cd /run/daemons/ && compgen -f "$cur"|sort))
-	elif ((COMP_CWORD > 1)); then
-		COMPREPLY=($(cd /etc/rc.d && compgen -f -X 'functions*' "$cur"|sort))
+	else
+		COMPREPLY=($(compgen -W "${options} $(cd /etc/rc.d && compgen -f -X 'functions*')" -- "$cur"))
 	fi
 }
 complete -F _rc_d rc.d
diff --git a/rc.d b/rc.d
index 9b0f092..907439b 100755
--- a/rc.d
+++ b/rc.d
@@ -4,74 +4,115 @@ NEED_ROOT=0 # this script can be run without be root
 . /etc/rc.conf
 . /etc/rc.d/functions
 
+# print usage and exit
 usage() {
 	local name=${0##*/}
 	cat >&2 << EOF
-usage: $name <action> <daemon> [daemon] ...
-       $name list [started|stopped]
-       $name help
+usage: $name [options] <action> [daemons]
 
-<daemon> is the name of a script in /etc/rc.d
+options:
+  --started     Append started daemons to the list
+  --stopped     Append stopped dameons to the list
+  --auto        Append autostarted daemons to the list
+  --noauto      Append not autostarted daemons to the list
+
+<daemons> is space separated list of script in /etc/rc.d
 <action> can be a start, stop, restart, reload, status, ...
 WARNING: initscripts are free to implement or not the above actions.
 
 e.g: $name list
-     $name list started
-     $name help
+     $name list sshd gpm
+     $name list --started gpm
      $name start sshd gpm
+     $name stop --noauto
+     $name help
 EOF
-	exit 1
+	exit ${1:-1}
 }
 
 (( $# < 1 )) && usage
 
+# parse options
+argv=$(getopt -l 'started,stopped,auto,noauto' -- '' "$@")
+(( $? )) && usage
+eval set -- "$argv"
+
+# going into script directory
+cd /etc/rc.d
+
+# create an initial daemon list
+declare -a daemons=()
+while [[ "$1" != -- ]]; do
+	case "$1" in
+		--started)
+			for d in *; do have_daemon "$d" && ! ck_daemon "$d" && daemons+=("$d"); done
+		;;
+		--stopped)
+			for d in *; do have_daemon "$d" && ck_daemon "$d" && daemons+=("$d"); done
+		;;
+		--auto)
+			for d in *; do have_daemon "$d" && ! ck_autostart "$d" && daemons+=("$d"); done
+		;;
+		--noauto)
+			for d in *; do have_daemon "$d" && ck_autostart "$d" && daemons+=("$d"); done
+		;;
+	esac
+	shift
+done
+
+# remove --
+shift
+# get action
+action=$1
+shift
+
+# add daemons
+for daemon; do
+	if ! have_daemon "$daemon"; then
+		printf "${C_FAIL}:: ${C_DONE}Dameon script ${C_FAIL}${daemon}${C_DONE} does \
+not exist or is not executable.${C_CLEAR}\n" >&2
+		exit 2
+	fi
+	daemons+=("$daemon")
+done
+
 declare -i ret=0
-case $1 in
+case $action in
 	help)
-		usage
-		;;
+		usage 0 2>&1
+	;;
 	list)
-		shift
-		cd /etc/rc.d/
-		for d in *; do
-			have_daemon "$d" || continue
+		# list take all daemons by default
+		[[ -z $daemons ]] && for d in *; do have_daemon "$d" && daemons+=("$d"); done
+		for daemon in "${daemons[@]}"; do
 			# print running / stopped satus
-			if ! ck_daemon "$d"; then
-				[[ "$1" == stopped ]] && continue
-				printf "${C_OTHER}[${C_DONE}STARTED${C_OTHER}]"
+			if ! ck_daemon "$daemon"; then
+				s_status="${C_OTHER}[${C_DONE}STARTED${C_OTHER}]"
 			else
-				[[ "$1" == started ]] && continue
-				printf "${C_OTHER}[${C_FAIL}STOPPED${C_OTHER}]"
+				s_status="${C_OTHER}[${C_FAIL}STOPPED${C_OTHER}]"
 			fi
 			# print auto / manual status
-			if ! ck_autostart "$d"; then
-				printf "${C_OTHER}[${C_DONE}AUTO${C_OTHER}]"
+			if ! ck_autostart "$daemon"; then
+				s_auto="${C_OTHER}[${C_DONE}AUTO${C_OTHER}]"
 			else
-				printf "${C_OTHER}[${C_FAIL}    ${C_OTHER}]"
+				s_auto="${C_OTHER}[${C_FAIL}    ${C_OTHER}]"
 			fi
-			printf " ${C_CLEAR}$d\n"
+			printf "$s_status$s_auto${C_CLEAR} $daemon\n"
 		done
 	;;
 	*)
 		# check min args count
-		(( $# < 2 )) && usage
-		action=$1
-		shift
+		[[ -z $daemons ]] && usage
 		# set same environment variables as init
 		runlevel=$(/sbin/runlevel)
-		ENV=("PATH=/bin:/usr/bin:/sbin:/usr/sbin"
+		ENV=('PATH=/bin:/usr/bin:/sbin:/usr/sbin'
 			"PREVLEVEL=${runlevel%% *}"
 			"RUNLEVEL=${runlevel##* }"
 			"CONSOLE=${CONSOLE:-/dev/console}"
 			"TERM=$TERM")
 		cd /
-		for i; do
-			if [[ -x "/etc/rc.d/$i" ]]; then
-				env -i "${ENV[@]}" "/etc/rc.d/$i" "$action"
-			else
-				printf "${C_FAIL}:: ${C_DONE}Daemon ${C_FAIL}$i${C_DONE} does not exist \
-or is not executable${C_CLEAR}\n"
-			fi
+		for daemon in "${daemons[@]}"; do
+			env -i "${ENV[@]}" "/etc/rc.d/$daemon" "$action"
 			(( ret += !! $? ))  # clamp exit value to 0/1
 		done
 	;;
diff --git a/zsh-completion b/zsh-completion
index e5c2850..69b3896 100644
--- a/zsh-completion
+++ b/zsh-completion
@@ -4,7 +4,7 @@ _rc.d () {
 	local curcontext="$curcontext" state line
 	typeset -A opt_args
 
-	 _arguments "1: :->action" "*: :->service"
+	 _arguments "1: :->action" "*: :->service" "--started" "--stopped" "--auto" "--noauto"
 
 	case $state in
 		action)
@@ -18,9 +18,6 @@ _rc.d () {
 				help)
 					_arguments "*: :"
 					;;
-				list)
-					_arguments "2: :(started stopped)"
-					;;
 				start)
 					_arguments "*: :($(comm -23 <(echo /etc/rc.d/*(N-*:t)|tr ' ' '\n') <(echo /run/daemons/*(N:t)|tr ' ' '\n')))"
 					;;
-- 
Sebastien "Seblu" Luttringer



More information about the arch-projects mailing list