about summary refs log tree commit diff
path: root/Completion/Solaris/Type/_svcs_fmri
blob: 684dc8d6d65a62d8133d53b7d146202daa7212d5 (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
#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 "$@"