about summary refs log tree commit diff
path: root/Completion/Linux/Command/_modutils
blob: 66e65d32e3110e2137a56e165767e0177ec06c94 (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
143
144
145
146
#compdef lsmod modinfo modprobe rmmod insmod

_modules_caching_policy()
{
    # Rebuild if $modules_dir is newer than the cache, or every week.
    local -a oldp

    oldp=( "$1"(Nmw+0) )
    (( $#oldp )) || [[ $modules_dir -nt $1 ]]
}

_modutils() {
    local curcontext="$curcontext" expl state line modules ign args ret=1
    local -r modules_dir=/lib/modules

    local update_policy
    zstyle -s ":completion:*:*:$service:*" cache-policy update_policy
    if [[ -z "$update_policy" ]]; then
	zstyle ":completion:*:*:$service:*" cache-policy _modules_caching_policy
    fi

    args=(
	'(-)'{-V,--version}'[print version]'
	'(-)'{-h,--help}'[print help text]'
    )

    case "$service" in
	lsmod) _arguments -s "$args[@]" && return ;;

	modinfo)
	    _arguments -s -C "$args[@]" \
		'(-)'{-a,--author}"[display the module's author]" \
		'(-)'{-d,--description}"[display the module's description]" \
		'(-)'{-l,--license}"[display the module's license]" \
		'(-)'{-n,--filename}"[display the module's filename]" \
		'(-)'{-p,--parameters}'[display the typed parameters that a module may support]' \
		'(-)'{-F,--field}"[display only selected module's information]:module_field:(alias author depends description filename license parm)" \
		'(-)-k[use modules from a different kernel version]:kernel_version:($(echo $modules_dir/*(/\:t)))' \
		'1:module file:->all_modules' && ret=0
	    ;;

	modprobe)
	    ign='-h --help -V --version -c --showconfig'
	    _arguments -s -C "$args[@]" \
		"(-a --all $ign)"{-a,--all}'[load all matching modules]' \
		'(-)'{-c,--showconfig}'[show current configuration]' \
		"(-d --debug $ign)"{-d,--debug}'[print debug info]' \
		"(-k --autoclean $ign)"{-k,--autoclean}'[set autoclean]' \
		"(-n --show $ign)"{-n,--show}"[don't actually perform action]" \
		"(-q --quiet $ign)"{-q,--quiet}"[don't complain about insmod failures]" \
		"(-s --syslog $ign)"{-s,--syslog}'[report via syslog instead of stderr]' \
		"(* -t --type $ign)"{-t,--type}'[module type]:module type' \
		"(-v --verbose $ign)"{-v,--verbose}'[print all commands as executed]' \
		'(-C --config)'{-C,--config}'[specify config file]:config file:_files' \
		"(-r --remove -l --list -t --type -a --all $ign)"{-r,--remove}'[remove module (stacks)]' \
		"(-l --list -t --type -a --all $ign)"{'-i[ignore install/remove commands in config file]','--ignore-install[ignore install commands in config file]','--ignore-remove[ignore remove commands in config file]'} \
		"(* -l --list -r --remove $ign)"{-l,--list}'[list matching modules]' \
		"(-c $ign)1:modules:->loadable_modules" \
		"(-c -l --list -t --type $ign)*:params:->params" && ret=0

	    [[ -n $state ]] && (( $+opt_args[-r] )) && state=loaded_modules
	    ;;

	rmmod)
	    _arguments -s -C "$args[@]" \
		'(-a --all)'{-a,--all}'[remove all unused autocleanable modules]' \
		'(-e --persist)'{-e,--persist}'[save persistent data]' \
		'(-r --stacks)'{-r,--stacks}'[remove a module stack]' \
		'(-s --syslog)'{-s,--syslog}'[output to syslog]' \
		'(-v --verbose)'{-v,--verbose}'[be verbose]' \
		'*:loaded module:->loaded_modules' && ret=0
	    ;;

	insmod)
	    _arguments \
		'1:module file:_files' \
		'*:module parameters:' && ret=0
	    ;;
    esac 

    case "$state" in
	loaded_modules|loadable_modules)
	    if [[ -r /proc/modules ]]; then
		loaded_modules=(${${(f)"$(</proc/modules)"}%% *})
	    elif [[ -x /sbin/lsmod ]]; then
		loaded_modules=(${${(f)"$(/sbin/lsmod)"}[2,-1]%% *})
	    else
		return 1
	    fi

	    if [[ $state = loaded_modules ]]; then
		_wanted modules expl 'loaded module' compadd -a loaded_modules \
		    && return
		return ret
	    fi
	    ;&

	all_modules)
	    local kver
	    integer kver_idx
	    if (( kver_idx=${words[(I)-k]} )); then
		kver=${words[kver_idx+1]}
	    else
		kver=$(uname -r)
	    fi

	    if _cache_invalid modules-$kver || ! _retrieve_cache modules-$kver;
	    then 
		# 2011-01-02 gi1242: Do we need .o files? Or is .ko enough?
		modules=( $modules_dir/$kver/(*~(source|build))/**/*.(o|ko|ko.gz)(.:t:r:r) )
		_store_cache modules-$kver modules
	    fi

	    if [[ $state = loadable_modules ]]; then
		modules=( ${modules:#(${(j:|:)~${=loaded_modules//_/-}})} )
	    fi

	    _tags files modules
	    while _tags; do
		_requested files expl "module file"  _files -g '*.ko(-.)' && ret=0
		_requested modules expl module compadd -a modules && ret=0
	    done
	    ;;

	params)
	    if compset -P '*='; then
		_message -e value 'parameter value'
	    else
		local params
		params=( ${${(M)${(f)"$(_call_program module_parameter /sbin/modinfo "$words[2]" 2>/dev/null)"}:#parm:*}##parm:[[:space:]]##} )
		if [[ $#params -eq 0 ]]; then
		    _message -e parameter "This modules doesn't have parameters"
		else
		    typeset -A val_args

		    _values -S = -C -w 'module parameter' \
			${${${(M)params:#*(:bool|\(bool\))}/:/[}/(bool| \(bool\))/]} ${^${params:#*(:bool|\(bool\))}/:/[}"]:auto added argument: " && ret=0
		fi
	    fi
	    ;;
    esac

    return ret
}

_modutils "$@"