|
1 #autoload |
|
2 |
|
3 _svcs_fmri() { |
|
4 local type="$argv[$#]" |
|
5 local fmri_abbrevs m i |
|
6 typeset -a -g _smf_fmris |
|
7 |
|
8 local update_policy |
|
9 zstyle -s ":completion:${curcontext}:" cache-policy update_policy |
|
10 if [[ -z "$update_policy" ]]; then |
|
11 zstyle ":completion:${curcontext}:" cache-policy _smf_caching_policy |
|
12 fi |
|
13 # The cache really must be per-host |
|
14 local cache_id=smf_fmri:$HOST |
|
15 |
|
16 # TODO: Do something useful with the expand and/or ambiguous styles. |
|
17 case $type in |
|
18 (-i|-c) |
|
19 # We probably also need an option to eliminate ambiguous |
|
20 # results for use in places where that's not allowed. |
|
21 |
|
22 # Grab all FMRIs that have a word beginning with $PREFIX, |
|
23 # making sure not to return the portion of the FMRI before |
|
24 # $PREFIX. Use the cache if it exists and the user wants to. |
|
25 if ( [[ $#_smf_fmris -eq 0 ]] || _cache_invalid $cache_id ) \ |
|
26 && ! _retrieve_cache $cache_id; then |
|
27 _smf_fmris=( ${(f)"$(svcs -a -H -o fmri)"} ) |
|
28 _store_cache $cache_id _smf_fmris |
|
29 fi |
|
30 # Each element of the array is removed which doesn't match |
|
31 # (^|.*/)$PREFIX.* |
|
32 fmri_abbrevs=( ${(M)_smf_fmris:#((#s)|*[/:])$PREFIX*} ) |
|
33 |
|
34 # Go through the remaining elements and remove the characters |
|
35 # in front of $PREFIX. |
|
36 for ((i = 1; i < $#fmri_abbrevs; i++ )); do |
|
37 # Either one of these will work, but they're too |
|
38 # greedy, preventing multiple matches below. |
|
39 fmri_abbrevs[i]=${${fmri_abbrevs[i]}/((#s)|*[\/:])(#b)($PREFIX*)/$match[1]} |
|
40 #fmri_abbrevs[i]=${${(M)${fmri_abbrevs[i]}:#(#b)((#s)|*/)$PREFIX*}#$match[1]} |
|
41 done |
|
42 |
|
43 # Remove the "default" instance identifier if it's the only |
|
44 # instance for a given service (not for svccfg). |
|
45 if [[ $type == "-i" ]]; then |
|
46 local -a svcs insts nabbrevs |
|
47 local s |
|
48 svcs=( ${(u)fmri_abbrevs%:*} ) |
|
49 for s in $svcs; do |
|
50 insts=( ${(@M)fmri_abbrevs:#$s:*} ) |
|
51 if [[ $#insts -eq 1 && $insts[1] == *":default" ]]; then |
|
52 nabbrevs=($nabbrevs ${insts//:default}) |
|
53 elif [[ $#insts -eq 0 ]]; then |
|
54 # Turns out we're completing the |
|
55 # instance name. |
|
56 nabbrevs=($nabbrevs $s) |
|
57 else |
|
58 nabbrevs=($nabbrevs $insts) |
|
59 fi |
|
60 done |
|
61 fmri_abbrevs=( $nabbrevs ) |
|
62 fi |
|
63 |
|
64 # After playing with _multi_parts, I'm not sure it's actually |
|
65 # that useful. |
|
66 # _wanted fmri expl "full or unambiguously abbreviated FMRIs" \ |
|
67 # _multi_parts -i / fmri_abbrevs |
|
68 |
|
69 _wanted fmri expl "full or unambiguously abbreviated FMRIs" \ |
|
70 compadd $fmri_abbrevs |
|
71 ;; |
|
72 |
|
73 (-m) |
|
74 _wanted fmri expl "milestone FMRIs" \ |
|
75 compadd $(svcs -H -o fmri svc:/milestone/\*) all |
|
76 ;; |
|
77 |
|
78 (-r) |
|
79 # TODO: need some way to pick out only restarters |
|
80 _wanted fmri expl "restarter FMRIs" \ |
|
81 compadd master svc:/network/inetd:default |
|
82 ;; |
|
83 |
|
84 (*) |
|
85 _message "unknown argument to _svcs_fmri: $type" |
|
86 ;; |
|
87 esac |
|
88 } |
|
89 |
|
90 _smf_caching_policy() { |
|
91 # /etc/svc/repository.db is not a public interface, so this is kinda |
|
92 # grody. |
|
93 [[ ! -f "$1" || /etc/svc/repository.db -nt "$1" ]] |
|
94 } |
|
95 |
|
96 _svcs_fmri "$@" |