summaryrefslogtreecommitdiff
path: root/etc/bash_completion.d/vyatta-op
diff options
context:
space:
mode:
Diffstat (limited to 'etc/bash_completion.d/vyatta-op')
-rw-r--r--etc/bash_completion.d/vyatta-op451
1 files changed, 451 insertions, 0 deletions
diff --git a/etc/bash_completion.d/vyatta-op b/etc/bash_completion.d/vyatta-op
new file mode 100644
index 0000000..6336038
--- /dev/null
+++ b/etc/bash_completion.d/vyatta-op
@@ -0,0 +1,451 @@
+
+# **** License ****
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# 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.
+#
+# This code was originally developed by Vyatta, Inc.
+# Portions created by Vyatta are Copyright (C) 2006, 2007 Vyatta, Inc.
+# All Rights Reserved.
+#
+# Author: Tom Grennan
+# Date: 2007
+# Description: setup bash completion for Vyatta operational commands
+#
+# **** End License ****
+
+test -z "$_vyatta_less_options" && \
+ declare -r _vyatta_less_options="\
+ --QUIT-AT-EOF\
+ --quit-if-one-screen\
+ --RAW-CONTROL-CHARS\
+ --squeeze-blank-lines\
+ --no-init"
+test -z "$_vyatta_default_pager" && \
+ declare -r _vyatta_default_pager="less \
+ --buffers=64\
+ --auto-buffers\
+ --no-lessopen\
+ $_vyatta_less_options"
+declare -x VYATTA_PAGER=$_vyatta_default_pager
+
+_vyatta_op_do_key_bindings ()
+{
+ if [ "$SHELL" != "/bin/vbash" ]; then
+ # only do bindings if vbash
+ return
+ fi
+
+ bind '"?": possible-completions'
+ bind 'set show-all-if-ambiguous on'
+
+ nullglob_save=$(shopt -p nullglob)
+ shopt -u nullglob
+ bind_cmds=$(grep '^bind .* # vyatta key binding$' $HOME/.bashrc)
+ eval $bind_cmds
+ eval $nullglob_save
+}
+
+_vyatta_op_do_key_bindings
+
+test -f /etc/default/vyatta && \
+ source /etc/default/vyatta
+
+test ! -d "$vyatta_op_templates" && \
+ return 0
+
+declare -r _vyatta_op_last_comp_init='>>>>>>LASTCOMP<<<<<<'
+declare _vyatta_op_last_comp=${_vyatta_op_last_comp_init}
+declare _vyatta_op_node_path
+declare -a _vyatta_op_noncompletions _vyatta_op_completions
+declare -x -a _vyatta_pipe_noncompletions _vyatta_pipe_completions
+
+# $1: label
+# #2...: strings
+_vyatta_op_debug ()
+{
+ echo -ne \\n$1:
+ shift
+ for s ; do
+ echo -ne " \"$s\""
+ done
+}
+
+_vyatta_op_init ()
+{
+ complete -F _vyatta_op_expand ''
+
+ for xd in $vyatta_op_templates/* ; do
+ if [ -d $xd ] ; then
+ cmd=${xd##*/}
+ complete -F _vyatta_op_expand $cmd
+ eval alias $cmd=\'_vyatta_op_run $cmd\'
+ fi
+ done
+
+ shopt -s histverify
+}
+
+_vyatta_op_get_node_def_field ()
+{
+ local file=$1 field=$2
+
+ sed -n '/^'"$field"':/,$ {
+# strip field name and hold rest of line
+ s/[a-z]*: *//
+ h
+ :b
+# at EOF, print hold buffer and quit
+ $ { x; p; q }
+# input next line
+ n
+# if start of another field def, print hold buf and quit
+ /^[a-z]*:/ { x; p; q }
+# add to hold buf and branch to input next line
+ H
+ bb
+ }' $file
+}
+
+# $1: label
+# $2...: help
+_vyatta_op_print_help ()
+{
+ local label=$1 help=$2
+
+ if [ ${#help} -eq 0 ] ; then
+ echo -ne "\n $label"
+ elif [ ${#label} -lt 6 ] ; then
+ echo -ne "\n $label\t\t$help"
+ elif [ ${#label} -lt 14 ] ; then
+ echo -ne "\n $label\t$help"
+ else
+ echo -ne "\n $label\n\t\t$help"
+ fi
+}
+
+# $1: $cur
+# $2...: possible completions
+_vyatta_op_help ()
+{
+ local cur=$1; shift
+ local ndef node_tag_help node_run help last_help
+
+ ndef=${_vyatta_op_node_path}/node.tag/node.def
+ [ -f $ndef ] && \
+ node_tag_help=$( _vyatta_op_get_node_def_field $ndef help )
+
+ ndef=${_vyatta_op_node_path}/node.def
+ [ -f $ndef ] && \
+ node_run=$( _vyatta_op_get_node_def_field $ndef run )
+
+ echo -en "\nPossible completions:"
+ if [ -z "$cur" -a -n "$node_run" ]; then
+ _vyatta_op_print_help '<Enter>' "Execute the current command"
+ fi
+ for comp ; do
+ if [ -z "$comp" ] ; then
+ if [ "X$node_tag_help" == "X$last_help" ] ; then
+ help=""
+ else
+ last_help=$node_tag_help
+ help=$node_tag_help
+ fi
+ _vyatta_op_print_help '*' "$help"
+ elif [[ -z "$cur" || $comp == ${cur}* ]] ; then
+ ndef=${_vyatta_op_node_path}/$comp/node.def
+ if [ -f $ndef ] ; then
+ help=$( _vyatta_op_get_node_def_field $ndef help )
+ else
+ help=$node_tag_help
+ fi
+ if [ "X$help" == "X$last_help" ] ; then
+ help=""
+ else
+ last_help=$help
+ fi
+ _vyatta_op_print_help "$comp" "$help"
+ fi
+ done
+}
+
+_vyatta_op_set_node_path ()
+{
+ _vyatta_op_node_path=$vyatta_op_templates
+ for (( i=0 ; i<COMP_CWORD ; i++ )) ; do
+ if [ -f "${_vyatta_op_node_path}/${COMP_WORDS[i]}/node.def" ] ; then
+ _vyatta_op_node_path+=/${COMP_WORDS[i]}
+ elif [ -f ${_vyatta_op_node_path}/node.tag/node.def ] ; then
+ _vyatta_op_node_path+=/node.tag
+ else
+ return 1
+ fi
+ done
+}
+
+_vyatta_op_set_completions ()
+{
+ local -a allowed completions
+
+ for ndef in ${_vyatta_op_node_path}/*/node.def ; do
+ if [[ $ndef == */node.tag/node.def ]] ; then
+ local acmd=$( _vyatta_op_get_node_def_field $ndef allowed )
+ local -a a=($( eval "$acmd" ))
+ if [ ${#a[@]} -ne 0 ] ; then
+ allowed+=( "${a[@]}" )
+ else
+ allowed+=( "" )
+ fi
+ else
+ local sdir=${ndef%/*}
+ allowed+=( ${sdir##*/} )
+ fi
+ done
+
+ # donot complete entries like <HOSTNAME> or <A.B.C.D>
+ _vyatta_op_noncompletions=( )
+ completions=( )
+ for (( i=0 ; i<${#allowed[@]} ; i++ )) ; do
+ if [[ "${allowed[i]}" == \<*\> ]] ; then
+ _vyatta_op_noncompletions+=( ${allowed[i]} )
+ else
+ completions+=( ${allowed[i]} )
+ fi
+ done
+
+ _vyatta_op_completions=($( printf "%s\n" ${completions[@]} | sort -u ))
+}
+
+_vyatta_op_comprely_needs_ambiguity ()
+{
+ local -a uniq
+
+ [ ${#COMPREPLY[@]} -eq 1 ] && return
+
+ uniq=( `printf "%s\n" ${COMPREPLY[@]} | cut -c1 | sort -u` )
+
+ [ ${#uniq[@]} -eq 1 ] && return
+ false
+}
+
+_vyatta_op_expand ()
+{
+ local restore_shopts=$( shopt -p extglob nullglob | tr \\n \; )
+ shopt -s extglob nullglob
+ local cur=""
+
+ if (( ${#COMP_WORDS[@]} > 0 )); then
+ cur=${COMP_WORDS[COMP_CWORD]}
+ else
+ (( COMP_CWORD = ${#COMP_WORDS[@]} ))
+ fi
+
+ if _vyatta_pipe_completion "${COMP_WORDS[@]}"; then
+ if [ "${COMP_WORDS[*]}" == "$_vyatta_op_last_comp" ] ; then
+ _vyatta_do_pipe_help
+ COMPREPLY=( "" " " )
+ _vyatta_op_last_comp=${_vyatta_op_last_comp_init}
+ else
+ COMPREPLY=( "${_vyatta_pipe_completions[@]}" )
+ _vyatta_op_last_comp="${COMP_WORDS[*]}"
+ fi
+ eval "$restore_shopts"
+ return
+ fi
+
+ if [ "${COMP_WORDS[*]}" != "$_vyatta_op_last_comp" ] ; then
+ if ! _vyatta_op_set_node_path ; then
+ echo -e \\a
+ COMPREPLY=( "" " " )
+ eval "$restore_shopts"
+ return 1
+ fi
+ _vyatta_op_set_completions
+ fi
+
+ COMPREPLY=($( compgen -W "${_vyatta_op_completions[*]}" -- $cur ))
+
+ # if the last command line arg is empty and we have
+ # an empty completion option (meaning wild card),
+ # append a blank(s) to the completion array to force ambiguity
+ if [ -z "$cur" ] ; then
+ for comp ; do
+ if [ -z "$comp" ] ; then
+ if [ ${#COMPREPLY[@]} -eq 0 ] ; then
+ COMPREPLY+=( " " "" )
+ elif _vyatta_op_comprely_needs_ambiguity ; then
+ COMPREPLY+=( " " )
+ fi
+ fi
+ done
+ fi
+
+ if [ "${COMP_WORDS[*]}" == "$_vyatta_op_last_comp" ] ; then
+ _vyatta_op_help "$cur" \
+ ${_vyatta_op_noncompletions[@]} \
+ ${_vyatta_op_completions[@]} \
+ | ${VYATTA_PAGER:-cat}
+ COMPREPLY=( "" " " )
+ _vyatta_op_last_comp=${_vyatta_op_last_comp_init}
+ else
+ _vyatta_op_last_comp="${COMP_WORDS[*]}"
+ fi
+
+ eval "$restore_shopts"
+}
+
+_vyatta_op_run ()
+{
+ local -i estat
+ local tpath=$vyatta_op_templates
+ local restore_shopts=$( shopt -p extglob nullglob | tr \\n \; )
+ shopt -s extglob nullglob
+
+ _vyatta_op_last_comp=${_vyatta_op_last_comp_init}
+ false; estat=$?
+
+ i=1
+ for arg in "$@"
+ do
+ if [ -f "$tpath/$arg/node.def" ] ; then
+ tpath+=/$arg
+ elif [ -f $tpath/node.tag/node.def ] ; then
+ tpath+=/node.tag
+ else
+ echo "Invalid command" >&2
+ eval $restore_shopts
+ return 1
+ fi
+ let "i+=1"
+ done
+
+ local run_cmd=$(_vyatta_op_get_node_def_field $tpath/node.def run)
+ local ret=0
+ if [ -n "$run_cmd" ]; then
+ if [[ -t 1 && "$1" == "show" && \
+ ! $run_cmd =~ ^\(LESSOPEN=\|less\|pager\|tail\|/opt/vyatta/bin/vyatta-tshark-interface-port.pl\).* ]] ; then
+ eval "($run_cmd) | ${VYATTA_PAGER:-cat}"
+ else
+ eval "$run_cmd"
+ fi
+ else
+ echo "Incomplete command" >&2
+ ret=1
+ fi
+ eval $restore_shopts
+ return $ret
+}
+
+# "pipe" functions
+count ()
+{
+ wc -l
+}
+
+match ()
+{
+ grep -E -e "$1"
+}
+
+no-match ()
+{
+ grep -E -v -e "$1"
+}
+
+no-more ()
+{
+ cat
+}
+
+# pipe command help
+# $1: command
+_vyatta_pipe_help ()
+{
+ local help="No help text available"
+ case "$1" in
+ count) help="Count the number of lines in the output";;
+ match) help="Only output lines that match specified pattern";;
+ no-match) help="Only output lines that do not match specified pattern";;
+ more) help="Paginate the output";;
+ no-more) help="Do not paginate the output";;
+ '<pattern>') help="Pattern for matching";;
+ esac
+ echo -n "$help"
+}
+
+_vyatta_do_pipe_help ()
+{
+ local help=''
+ if (( ${#_vyatta_pipe_completions[@]} + ${#_vyatta_pipe_noncompletions[@]}
+ == 0 )); then
+ return
+ fi
+ echo -en "\nPossible completions:"
+ for comp in "${_vyatta_pipe_completions[@]}" \
+ "${_vyatta_pipe_noncompletions[@]}"; do
+ _vyatta_op_print_help "$comp" "$(_vyatta_pipe_help "$comp")"
+ done
+}
+
+# pipe completion
+# $@: words
+_vyatta_pipe_completion ()
+{
+ local -a pipe_cmd=()
+ local -a all_cmds=( 'count' 'match' 'no-match' 'more' 'no-more' )
+ local found=0
+ _vyatta_pipe_completions=()
+ _vyatta_pipe_noncompletions=()
+
+ for word in "$@"; do
+ if [ "$found" == "1" -o "$word" == "|" ]; then
+ pipe_cmd+=( "$word" )
+ found=1
+ fi
+ done
+ if (( found == 0 )); then
+ return 1
+ fi
+ if (( ${#pipe_cmd[@]} == 1 )); then
+ # "|" only
+ _vyatta_pipe_completions=( "${all_cmds[@]}" )
+ return 0
+ fi
+ if (( ${#pipe_cmd[@]} == 2 )); then
+ # "|<space, chars, or space+chars>"
+ _vyatta_pipe_completions=($(compgen -W "${all_cmds[*]}" -- ${pipe_cmd[1]}))
+ return 0
+ fi
+ if (( ${#pipe_cmd[@]} == 3 )); then
+ # "|<chars or space+chars><space or space+chars>"
+ case "${pipe_cmd[1]}" in
+ match|no-match) _vyatta_pipe_noncompletions=( '<pattern>' );;
+ esac
+ return 0
+ fi
+ return 0
+}
+
+nullglob_save=$( shopt -p nullglob )
+shopt -s nullglob
+for f in ${vyatta_datadir}/vyatta-op/functions/allowed/* ; do
+ source $f
+done
+eval $nullglob_save
+unset nullglob_save
+
+# don't initialize if we are in configure mode
+if [ "$_OFR_CONFIGURE" == "ok" ]; then
+ return 0
+fi
+
+_vyatta_op_init $@
+
+### Local Variables:
+### mode: shell-script
+### End: