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

Seblu seblu at seblu.net
Tue Aug 23 11:35:47 EDT 2011


On Tue, Aug 23, 2011 at 4:58 PM, Lukas Fleischer
<archlinux at cryptocrack.de> wrote:
> On Tue, Aug 23, 2011 at 03:32:32PM +0200, Sebastien Luttringer wrote:
>> 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]
>
> "usage: $name <action> [options] [daemons]". Although it doesn't really
> matter, `rc.d list --started` should be the default way of specifying
> arguments, see your examples further below.
>
>>
>> -<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
>
> ... is *a* space separated list of script*s*.
>
>>  <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
>
> `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
>> +             ;;
>
> Oh. I thought of an implicit conjunction over the single filter options
> here. This is advantageous if you want to list running auto-started
> daemons (`rc.d list --started --auto`) etc. I would just set some flag
> when parsing the options and filter the daemon list in a single loop
> later on (which is faster, also).
>
>> +     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
>
> Same here. Explicitly specified daemons should not be added to the list,
> but used as input to the filter options (if any). I would suggest
> following procedure:
>
> Iterate over the daemons specified on the command line if any,
> "/etc/rc.d/*" otherwise:
>
> * Set some flag to 1 (indicating whether the daemon will be included in
>  the list or not).
>
> * If "--started" or "--stopped" are specified (you stored this in some
>  other flag earlier), possibly reset the flag to 0, depending on what
>  ck_daemon() returns.
>
> * Do the same thing with "--auto" or "--noauto" (and ck_autostart()).
>
> * Add the daemon to some array if the flag is still set to 1.
>
> This removes the need for special treatment in any of the action cases
> below, also.

What's append if you type rc.d stop with you algo? You stop all your daemon?

For the list command, we want no daemon = all daemon. For all others,
we don't want. I would escape populate the list of daemons if action
is list before being in list context.

using --option as a filter is more in tune with pacman.

-- 
Sébastien Luttringer
www.seblu.net


More information about the arch-projects mailing list