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 reset 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 "$@" 97