1#compdef -p */(init|rc[0-9S]#).d/*
2
3local cmds script
4local -a flags
5
6_compskip=all
7
8if [[ $OSTYPE = freebsd* ]]; then
9  (( $+functions[_init_d_fullpath] )) ||
10  _init_d_fullpath() {
11    local -a scriptpath
12    local name=$1 dir
13    # Known locations of init scripts
14    # C.f. Unix/Type/_services
15    scriptpath=(/etc/rc.d $(/bin/sh -c '. /etc/rc.subr; load_rc_config XXX; echo $local_startup' 2>/dev/null))
16
17    for dir in $scriptpath; do
18      if [[ -f $dir/$name ]]; then
19        echo $dir/$name
20        return 0
21      fi
22    done
23    return 1
24  }
25
26  (( $+functions[_init_d_get_cmds] )) ||
27  _init_d_get_cmds() {
28    local magic cmds cmd_prefix
29
30    [[ -x $script ]] || return 1
31    [[ $(read -u0 -k2 magic < $script && echo $magic) = '#!' ]] || return 0
32    [[ -f /etc/rc.subr ]] && [[ -x /sbin/rcorder ]] || return 0
33    grep -q '^ *\.  */etc/rc\.subr *$' $script || return 0
34    cmds=(
35      start stop restart rcvar status poll
36      $(/bin/sh -c "set -- rcvar; . $script >/dev/null; echo \$extra_commands" 2>/dev/null)
37    )
38
39    for cmd_prefix in {,one,fast,force,quiet}; do
40      echo ${cmds/#/$cmd_prefix}
41    done
42
43    return 0
44  }
45elif [[ $OSTYPE = openbsd* ]]; then
46  (( $+functions[_init_d_fullpath] )) ||
47  _init_d_fullpath() {
48    echo /etc/rc.d/$1
49    return 0
50  }
51
52  (( $+functions[_init_d_get_cmds] )) ||
53  _init_d_get_cmds() {
54    local -a cmds disabled
55
56    cmds=(start stop reload restart check)
57    disabled=(${${${(M)${(f)"$(< $script)"}:#rc_(${(~j:|:)cmds})=NO}#rc_}%=NO})
58    echo ${cmds:|disabled}
59  }
60
61  flags=('-d[print debug information]' '-f[forcibly start the daemon]')
62else
63  (( $+functions[_init_d_fullpath] )) ||
64  _init_d_fullpath() {
65    local -a scriptpath
66    local name=$1 dir
67    # Known locations of init scripts
68    # C.f. Unix/Type/_services
69    scriptpath=(/etc/init.d /etc/rc.d /etc/rc.d/init.d)
70
71    for dir in $scriptpath; do
72      if [[ -f $dir/$name ]]; then
73        echo $dir/$name
74        return 0
75      fi
76    done
77    return 1
78  }
79
80  (( $+functions[_init_d_get_cmds] )) ||
81  _init_d_get_cmds() {
82    local what magic cmds
83    local -a tmp
84
85    [[ -x $script ]] || return 1
86
87    # If the file starts with `#!' we hope that this is a shell script
88    # and get lines looking like <space>foo|bar) with the words in $what. Note
89    # that we'll fail to match if any of the alternate patterns in the case
90    # clause are not enumerated (e.g., `start|stop|custom)` won't match)
91    tmp=(
92      status add delete clean list
93      load save show check {config,}test
94      standalone master graceful
95      debug debug{_,-}{up,down} dump{,{_,-}stats}
96      {force-,graceful-,try-,}{start,stop,restart,reload}
97      {start,stop}-htcacheclean
98    )
99    what="((['\"]|)(${(j<|>)tmp})(['\"]|))"
100
101    read -u0 -k2 magic < $script && [[ $magic = '#!' ]] && {
102      cmds=( ${(f)"$(< $script)"} )
103      cmds=( ${(M)cmds:#[[:blank:]]#${~what}([[:blank:]]#\|[[:blank:]]#${~what})#[[:blank:]]#\)} )
104      cmds=( ${${(j:|:s:|:)cmds}//[^-a-z_]} )
105    }
106
107    # This would be the pattern to use every line of the form <space>foo).
108    # Some people say this might match too many lines...
109    #
110    #    cmds=( ${${(j:|:s:|:)${(M)${(f)"$(< $script)"}:#[[:blank:]]#(\'|)[a-z_|]##\'|)\)}}//[^a-z_]} )
111
112    echo $cmds
113    return 0
114  }
115fi
116
117script=$words[1]
118[[ $script = */* ]] || script="$(_init_d_fullpath "$script")"
119
120cmds=( $(_init_d_get_cmds) ) || return 1
121
122(( $#cmds )) || zstyle -a ":completion:${curcontext}:commands" commands cmds ||
123    cmds=(start stop)
124
125_arguments -s -A "-*" $flags ':init.d command:_sub_commands $cmds'
126