blob: 25800097d49debf3b2b70b524d827ebe32d3f2de (
plain)
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
|
#!/bin/bash
# -----------------------------------------------------------------
# ipset set listing wrapper script
#
# https://github.com/AllKind/ipset_list
# https://sourceforge.net/projects/ipset-list/
# -----------------------------------------------------------------
# Copyright (C) 2013 AllKind (AllKind@fastest.cc)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# -----------------------------------------------------------------
#
# This is the bash programmable completion for ipset_list
# (put it into ~/.bash_completion or /etc/bash_completion.d/)
#
# -----------------------------------------------------------------
# Name may be modified
ipset_list=ipset_list
# -----------------------------------------------------------------
# -----------------------------------------------------------------
# DO NOT MODIFY ANYTHING BEYOND THIS LINE!
# -----------------------------------------------------------------
shopt -s extglob
_remove_reply_entry() {
local -i x
while (($#)); do
for x in ${!COMPREPLY[@]}; do
if [[ ${COMPREPLY[x]} = $1 ]]; then
unset COMPREPLY[x]
break
fi
done
shift
done
}
_ipset_list_complete() {
local -i i=x=show_all=isolate=show_members=resolve=headers_only=0
local cur prev
local sets=()
sets=( $("$ipset_list" -n ) )
local opts=(-? -a -c -d -h -i -m -n -r -s -t -v)
local Copts=(-Cs -Co)
local Fopts=(-Fh -Fi -Fg -Fr)
local Hopts=(-Hr -Hs -Ht -Hv)
local Topts=(-Tm -To -Ts)
local Xopts=(-Xh -Xg -Xr -Xs)
: ${PATH:=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin}
COMPREPLY=()
_get_comp_words_by_ref cur || return
_get_comp_words_by_ref prev || return
#DEBUG=Y
if [[ $DEBUG ]]; then
printf "\ncur: <%s> prev: <%s>\n" "$cur" "$prev"
printf "COMP_WORDS:\n"
printf "<%s>\n" "${COMP_WORDS[@]}"
fi
# dont' allow an option after the set name(s)
if [[ $cur = -* ]]; then
for i in ${!sets[@]}; do
[[ ${sets[i]} = $prev ]] && return 0
done
fi
# some options allow only a subset of other options
for ((i=1; i <= ${#COMP_WORDS[@]}; i++)); do
case "${COMP_WORDS[i]}" in
-a) show_all=1 ;;
-i) isolate=1 ;;
-m) show_members=1 ;;
-r) resolve=1 ;;
-t) headers_only=1 ;;
-\?|-h|-n|-v)
return 0
;;
esac
done
# invalid combinations of options
if ((headers_only)); then
if ((show_all || show_members || isolate || resolve)); then
return 0
fi
elif ((isolate && show_all)); then
return 0
fi
case "$cur" in
-C) COMPREPLY=( ${Copts[@]} $cur )
for ((i=1; i <= ${#COMP_WORDS[@]}; i++)); do # no set counting on -i
if [[ ${COMP_WORDS[i]} = -i ]]; then
COMPREPLY=( -Co )
break
fi
done
;;
-F) COMPREPLY=( ${Fopts[@]} ) ;;
-H) COMPREPLY=( ${Hopts[@]} ) ;;
-M) COMPREPLY=( -Mc ) ;;
-T) COMPREPLY=( ${Topts[@]} ) ;;
-X) COMPREPLY=( ${Xopts[@]} ) ;;
-*) # any option is requested
case "$prev" in # options that exclude any other option, or need a value we can't predict
@(-@(\?|d|h|n|v|Fg|Fh|Fi|Fr|Ht|Hr|Hs|Hv|Mc|To|Xg|Xh|Xr)))
return 0
;;
esac
if ((${#COMP_WORDS[@]} > 2)); then # these options don't allow any other
opts=("${opts[@]/@(-n|-h|-\?)/}")
fi
# some options allow only a subset of other options
if ((isolate)); then
COMPREPLY=( -Co -d -r -s $cur )
elif ((headers_only)); then
COMPREPLY=( -c ${Copts[@]} ${Fopts[@]} ${Hopts[@]} -Mc ${Topts[@]} ${Xopts[@]} )
elif ((show_members)); then
COMPREPLY=( -c -d -r -s ${Copts[@]} ${Fopts[@]} ${Hopts[@]} -Mc ${Topts[@]} )
elif ((show_all)); then
COMPREPLY=( -c -d -r -s ${Copts[@]} ${Fopts[@]} ${Hopts[@]} -Mc ${Topts[@]} ${Xopts[@]} )
elif ((resolve)); then
COMPREPLY=( -a -c -d -s -m ${Copts[@]} ${Fopts[@]} ${Hopts[@]} -Mc ${Topts[@]} ${Xopts[@]} )
else
COMPREPLY=( ${opts[@]} ${Copts[@]} ${Fopts[@]} ${Hopts[@]} -Mc ${Topts[@]} ${Xopts[@]} )
fi
;;
*) # not an option was requested
COMPREPLY=( $( compgen -W '${sets[@]}' -- $cur ) )
case "$prev" in
-Xh) # retrieve list of headers
COMPREPLY=()
while read -r; do
[[ $REPLY = Name ]] && continue
COMPREPLY[${#COMPREPLY[@]}]="$REPLY"
done < <( "$ipset_list" -t "${sets[0]}" | command awk -F: '{ print $1 }' )
compopt -o nospace
local IFS=$'\n'
COMPREPLY=( $( compgen -P '"' -S ':*"' -W '${COMPREPLY[@]}' -- $cur ) )
;;
@(-@(Hr|Hs|Hv|Mc))) # options making use of arithmetic comparison
compopt -o nospace
COMPREPLY=( '\!' '\<' '\>' '\<=' '\>=' )
;;
@(-@(\?|d|h|n|v|Fg|Fh|Fi|Fr|Ht|To|Xg|Xr))) COMPREPLY=() ;;
esac
if ((isolate)); then # allow only one set with isolate
for i in ${!sets[@]}; do
if [[ ${sets[i]} = $prev ]]; then
COMPREPLY=()
break
fi
done
fi
esac
if ((${#COMPREPLY[@]})); then # post process the reply
for ((i=1; i <= ${#COMP_WORDS[@]}; i++)); do # mutual exclusive options
case "${COMP_WORDS[i]}" in
-Fg) _remove_reply_entry "-Fr" "-Xg" "-Xr" ;;
-Fr) _remove_reply_entry "-Fg" "-Xg" "-Xr" ;;
-Xg) _remove_reply_entry "-Fg" "-Fr" "-Xr" ;;
-Xr) _remove_reply_entry "-Fg" "-Fr" "-Xg" ;;
esac
done
for ((i=1; i <= ${#COMP_WORDS[@]}; i++)); do # remove options that can only be used once
if [[ ${COMP_WORDS[i]} = @(""|-|-@(Fh|Fi|Xh|Xs)) ]]; then
continue
else
for x in ${!COMPREPLY[@]}; do
if [[ ${COMP_WORDS[i]} = ${COMPREPLY[x]} ]]; then
unset COMPREPLY[$x]
break
fi
done
fi
done
fi
if [[ $DEBUG ]]; then
printf "COMPREPLY:\n"
printf "<%s>\n" "${COMPREPLY[@]}"
fi
}
complete -F _ipset_list_complete "$ipset_list"
|