#autoload _svcs_fmri() { local type="$argv[$#]" local fmri_abbrevs m i typeset -a -g _smf_fmris local update_policy zstyle -s ":completion:${curcontext}:" cache-policy update_policy if [[ -z "$update_policy" ]]; then zstyle ":completion:${curcontext}:" cache-policy _smf_caching_policy fi # The cache really must be per-host local cache_id=smf_fmri:$HOST # TODO: Do something useful with the expand and/or ambiguous styles. case $type in (-i|-c) # We probably also need an option to eliminate ambiguous # results for use in places where that's not allowed. # Grab all FMRIs that have a word beginning with $PREFIX, # making sure not to return the portion of the FMRI before # $PREFIX. Use the cache if it exists and the user wants to. if ( [[ $#_smf_fmris -eq 0 ]] || _cache_invalid $cache_id ) && ! _retrieve_cache $cache_id; then _smf_fmris=( ${(f)"$(svcs -a -H -o fmri)"} ) _store_cache $cache_id _smf_fmris fi # Each element of the array is removed which doesn't match (^|.*/)$PREFIX.* fmri_abbrevs=( ${(M)_smf_fmris:#((#s)|*[/:])$PREFIX*} ) # Go through the remaining elements and remove the characters # in front of $PREFIX. for i in {1..$#fmri_abbrevs}; do # Either one of these will work, but they're too # greedy, preventing multiple matches below. fmri_abbrevs[i]=${${fmri_abbrevs[i]}/((#s)|*[\/:])(#b)($PREFIX*)/$match[1]} #fmri_abbrevs[i]=${${(M)${fmri_abbrevs[i]}:#(#b)((#s)|*/)$PREFIX*}#$match[1]} done # Remove the "default" instance identifier if we can (not for # svccfg) # TODO Can't remove default when there are other instances. if [[ $type == "-i" ]]; then fmri_abbrevs=( ${fmri_abbrevs//:default(#e)/} ) fi # Search for a second match within each result. # for m in $fmri_abbrevs; do # if [[ -n ${(M)m:#((#s)|*/)$PREFIX*/$PREFIX*} ]]; then # fmri_abbrevs=( $fmri_abbrevs ${${(SMI:1:)m%%/$PREFIX*}#/} ) # fi # done # After playing with _multi_parts, I'm not sure it's actually that useful. # _wanted fmri expl "full or unambiguously abbreviated FMRIs" _multi_parts / fmri_abbrevs _wanted fmri expl "full or unambiguously abbreviated FMRIs" compadd $fmri_abbrevs ;; (-m) _wanted fmri expl "milestone FMRIs" \ compadd $(svcs -H -o fmri svc:/milestone/\*) all ;; (-r) # TODO: need some way to pick out only restarters _wanted fmri expl "restarter FMRIs" compadd master svc:/network/inetd:default ;; (*) _message "unknown argument to _svcs_fmri: $type" ;; esac } _smf_caching_policy() { # /etc/svc/repository.db is not a public interface, so this is kinda # grody. [[ ! -f "$1" || /etc/svc/repository.db -nt "$1" ]] } _svcs_fmri "$@"