summaryrefslogtreecommitdiffstats
path: root/Completion/Unix/Command/_init_d
blob: 7b3c8ee4126a06ee5b39539f5d472acfb3081ddf (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#compdef -p */(init|rc[0-9S]#).d/*

local cmds script state
local -a flags line

_compskip=all

if [[ $OSTYPE = freebsd* ]]; then
  (( $+functions[_init_d_fullpath] )) ||
  _init_d_fullpath() {
    local -a scriptpath
    local name=$1 dir
    # Known locations of init scripts
    # C.f. Unix/Type/_services
    scriptpath=(/etc/rc.d $(/bin/sh -c '. /etc/rc.subr; load_rc_config XXX; echo $local_startup' 2>/dev/null))

    for dir in $scriptpath; do
      if [[ -f $dir/$name ]]; then
        echo $dir/$name
        return 0
      fi
    done
    return 1
  }

  (( $+functions[_init_d_get_cmds] )) ||
  _init_d_get_cmds() {
    local magic cmds cmd_prefix

    [[ -x $script ]] || return 1
    [[ $(read -u0 -k2 magic < $script && echo $magic) = '#!' ]] || return 0
    [[ -f /etc/rc.subr ]] && [[ -x /sbin/rcorder ]] || return 0
    grep -q '^ *\.  */etc/rc\.subr *$' $script || return 0
    cmds=(
      start stop restart rcvar status poll
      $(/bin/sh -c "set -- rcvar; . $script >/dev/null; echo \$extra_commands" 2>/dev/null)
    )

    for cmd_prefix in {,one,fast,force,quiet}; do
      echo ${cmds/#/$cmd_prefix}
    done

    return 0
  }
elif [[ $OSTYPE = openbsd* ]]; then
  (( $+functions[_init_d_fullpath] )) ||
  _init_d_fullpath() {
    echo /etc/rc.d/$1
    return 0
  }

  (( $+functions[_init_d_get_cmds] )) ||
  _init_d_get_cmds() {
    local -a cmds disabled

    cmds=(start stop reload restart check)
    disabled=(${${${(M)${(f)"$(< $script)"}:#rc_(${(~j:|:)cmds})=NO}#rc_}%=NO})
    echo ${cmds:|disabled}
  }

  flags=('-d[print debug information]' '-f[forcibly start the daemon]')
else
  (( $+functions[_init_d_fullpath] )) ||
  _init_d_fullpath() {
    local -a scriptpath
    local name=$1 dir
    # Known locations of init scripts
    # C.f. Unix/Type/_services
    scriptpath=(/etc/init.d /etc/rc.d /etc/rc.d/init.d)

    for dir in $scriptpath; do
      if [[ -f $dir/$name ]]; then
        echo $dir/$name
        return 0
      fi
    done
    return 1
  }

  (( $+functions[_init_d_get_cmds] )) ||
  _init_d_get_cmds() {
    local what magic cmds
    local -a tmp

    [[ -x $script ]] || return 1

    # If the file starts with `#!' we hope that this is a shell script
    # and get lines looking like <space>foo|bar) with the words in $what. Note
    # that we'll fail to match if any of the alternate patterns in the case
    # clause are not enumerated (e.g., `start|stop|custom)` won't match)
    tmp=(
      status add delete clean list
      load save show check {config,}test
      standalone master graceful
      debug debug{_,-}{up,down} dump{,{_,-}stats}
      {force-,graceful-,try-,}{start,stop,restart,reload}
      {start,stop}-htcacheclean
    )
    what="((['\"]|)(${(j<|>)tmp})(['\"]|))"

    read -u0 -k2 magic < $script && [[ $magic = '#!' ]] && {
      cmds=( ${(f)"$(< $script)"} )
      cmds=( ${(M)cmds:#[[:blank:]]#${~what}([[:blank:]]#\|[[:blank:]]#${~what})#[[:blank:]]#\)} )
      cmds=( ${${(j:|:s:|:)cmds}//[^-a-z_]} )
    }

    # This would be the pattern to use every line of the form <space>foo).
    # Some people say this might match too many lines...
    #
    #    cmds=( ${${(j:|:s:|:)${(M)${(f)"$(< $script)"}:#[[:blank:]]#(\'|)[a-z_|]##\'|)\)}}//[^a-z_]} )

    echo $cmds
    return 0
  }
fi

script=$words[1]
[[ $script = */* ]] || script="$(_init_d_fullpath "$script")"

cmds=( $(_init_d_get_cmds) ) || return 1

(( $#cmds )) || zstyle -a ":completion:${curcontext}:commands" commands cmds ||
    cmds=(start stop)

local svcname=$words[1] ret=1

_arguments -C -s -A "-*" $flags \
  ':init.d command:_sub_commands $cmds' \
  '*:: :->svcargs' && ret=0

if [[ $state == svcargs ]]; then
  case $svcname:$line[1] in
    jail:(*stop|*restart|console|status)) _jails && ret=0 ;;
    jail:*) _jails -c && ret=0 ;;
    netif:*) _net_interfaces && ret=0 ;;
    *)
      _call_function ret _init_d-$svcname $line[1]
      ;;
  esac
fi

return ret