1# resolvectl(1) completion -*- shell-script -*- 2# SPDX-License-Identifier: LGPL-2.1-or-later 3# 4# This file is part of systemd. 5# 6# systemd is free software; you can redistribute it and/or modify it 7# under the terms of the GNU Lesser General Public License as published by 8# the Free Software Foundation; either version 2.1 of the License, or 9# (at your option) any later version. 10# 11# systemd is distributed in the hope that it will be useful, but 12# WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14# General Public License for more details. 15# 16# You should have received a copy of the GNU Lesser General Public License 17# along with systemd; If not, see <http://www.gnu.org/licenses/>. 18 19__contains_word () { 20 local w word=$1; shift 21 for w in "$@"; do 22 [[ $w = "$word" ]] && return 23 done 24} 25 26__get_interfaces(){ 27 local name 28 for name in $(cd /sys/class/net && command ls); do 29 [[ "$name" != "lo" ]] && echo "$name" 30 done 31} 32 33_resolvectl() { 34 local i comps verb name 35 local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} 36 local -A OPTS=( 37 [STANDALONE]='-h --help --version -4 -6 --legend=no --cname=no 38 --validate=no --synthesize=no --cache=no --zone=no 39 --trust-anchor=no --network=no --service-address=no 40 --service-txt=no --search=no --no-pager' 41 [ARG]='-t --type -c --class -i --interface -p --protocol --raw' 42 ) 43 local -A VERBS=( 44 [DOMAIN]='query service openpgp' 45 [FAMILY]='tlsa' 46 [STATUS]='status' 47 [LINK]='revert dns domain nta' 48 [BOOLEAN]='default-route' 49 [RESOLVE]='llmnr mdns' 50 [DNSSEC]='dnssec' 51 [DNSOVERTLS]='dnsovertls' 52 [STANDALONE]='statistics reset-statistics flush-caches reset-server-features' 53 [LOG_LEVEL]='log-level' 54 ) 55 local -A ARGS=( 56 [FAMILY]='tcp udp sctp' 57 [BOOLEAN]='yes no' 58 [RESOLVE]='yes no resolve' 59 [DNSSEC]='yes no allow-downgrade' 60 [DNSOVERTLS]='yes no opportunistic' 61 ) 62 local interfaces=$( __get_interfaces ) 63 64 if __contains_word "$prev" ${OPTS[ARG]}; then 65 case $prev in 66 --interface|-i) 67 comps="$interfaces" 68 ;; 69 --protocol|-p|--type|-t|--class|-c) 70 comps=$( resolvectl --legend=no "$prev" help; echo help ) 71 ;; 72 --raw) 73 comps="payload packet" 74 ;; 75 esac 76 COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) 77 return 0 78 fi 79 80 if [[ "$cur" = -* ]]; then 81 COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") ) 82 return 0 83 fi 84 85 for ((i=0; i < COMP_CWORD; i++)); do 86 if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} && 87 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then 88 verb=${COMP_WORDS[i]} 89 break 90 fi 91 done 92 93 if [[ -z ${verb-} ]]; then 94 comps="${VERBS[*]}" 95 96 elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[DOMAIN]}; then 97 comps='' 98 99 elif __contains_word "$verb" ${VERBS[STATUS]}; then 100 comps="$interfaces" 101 102 elif __contains_word "$verb" ${VERBS[LOG_LEVEL]}; then 103 comps='debug info notice warning err crit alert emerg' 104 105 elif __contains_word "$verb" ${VERBS[FAMILY]}; then 106 for ((i++; i < COMP_CWORD; i++)); do 107 if __contains_word "${COMP_WORDS[i]}" ${ARGS[FAMILY]} && 108 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then 109 name=${COMP_WORDS[i]} 110 break; 111 fi 112 done 113 if [[ -z $name ]]; then 114 comps=${ARGS[FAMILY]} 115 else 116 comps="" 117 fi 118 119 elif __contains_word "$verb" ${VERBS[LINK]} ${VERBS[BOOLEAN]} ${VERBS[RESOLVE]} ${VERBS[DNSSEC]} ${VERBS[DNSOVERTLS]}; then 120 for ((i++; i < COMP_CWORD; i++)); do 121 if __contains_word "${COMP_WORDS[i]}" $interfaces && 122 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then 123 name=${COMP_WORDS[i]} 124 break; 125 fi 126 done 127 128 if [[ -z $name ]]; then 129 comps="$interfaces" 130 131 elif __contains_word "$verb" ${VERBS[RESOLVE]}; then 132 name= 133 for ((i++; i < COMP_CWORD; i++)); do 134 if __contains_word "${COMP_WORDS[i]}" ${ARGS[RESOLVE]} && 135 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then 136 name=${COMP_WORDS[i]} 137 break; 138 fi 139 done 140 141 if [[ -z $name ]]; then 142 comps=${ARGS[RESOLVE]} 143 else 144 comps='' 145 fi 146 147 elif __contains_word "$verb" ${VERBS[BOOLEAN]}; then 148 name= 149 for ((i++; i < COMP_CWORD; i++)); do 150 if __contains_word "${COMP_WORDS[i]}" ${ARGS[BOOLEAN]} && 151 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then 152 name=${COMP_WORDS[i]} 153 break; 154 fi 155 done 156 157 if [[ -z $name ]]; then 158 comps=${ARGS[BOOLEAN]} 159 else 160 comps='' 161 fi 162 163 elif __contains_word "$verb" ${VERBS[DNSSEC]}; then 164 name= 165 for ((i++; i < COMP_CWORD; i++)); do 166 if __contains_word "${COMP_WORDS[i]}" ${ARGS[DNSSEC]} && 167 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then 168 name=${COMP_WORDS[i]} 169 break; 170 fi 171 done 172 173 if [[ -z $name ]]; then 174 comps=${ARGS[DNSSEC]} 175 else 176 comps='' 177 fi 178 179 elif __contains_word "$verb" ${VERBS[DNSOVERTLS]}; then 180 name= 181 for ((i++; i < COMP_CWORD; i++)); do 182 if __contains_word "${COMP_WORDS[i]}" ${ARGS[DNSOVERTLS]} && 183 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then 184 name=${COMP_WORDS[i]} 185 break; 186 fi 187 done 188 189 if [[ -z $name ]]; then 190 comps=${ARGS[DNSOVERTLS]} 191 else 192 comps='' 193 fi 194 195 else 196 comps='' 197 fi 198 fi 199 200 COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) 201 return 0 202} 203 204complete -F _resolvectl resolvectl 205