From 7fa060f335bfbbd2bcfc0f4d9d9c89904036ef27 Mon Sep 17 00:00:00 2001 From: An-Cheng Huang Date: Wed, 31 Oct 2007 11:52:46 -0700 Subject: rename bash completion script to enforce ordering. --- etc/bash_completion.d/20vyatta-cfg | 862 +++++++++++++++++++++++++++++++++++++ etc/bash_completion.d/vyatta-cfg | 862 ------------------------------------- 2 files changed, 862 insertions(+), 862 deletions(-) create mode 100644 etc/bash_completion.d/20vyatta-cfg delete mode 100644 etc/bash_completion.d/vyatta-cfg (limited to 'etc/bash_completion.d') diff --git a/etc/bash_completion.d/20vyatta-cfg b/etc/bash_completion.d/20vyatta-cfg new file mode 100644 index 0000000..bef195d --- /dev/null +++ b/etc/bash_completion.d/20vyatta-cfg @@ -0,0 +1,862 @@ +# **** License **** +# Version: VPL 1.0 +# +# The contents of this file are subject to the Vyatta Public License +# Version 1.0 ("License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.vyatta.com/vpl +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# This code was originally developed by Vyatta, Inc. +# Portions created by Vyatta are Copyright (C) 2006, 2007 Vyatta, Inc. +# All Rights Reserved. +# +# Author: An-Cheng Huang +# Date: 2007 +# Description: bash completion for Vyatta configuration commands +# +# **** End License **** + +# only do this if we are going into configure mode +if [ "$_OFR_CONFIGURE" != "ok" ]; then + return 0 +fi + +umask 0002 + +if [ -r /etc/default/vyatta ]; then + source /etc/default/vyatta +fi + +declare is_set=0 +declare last_idx=0 +declare -a comp_words=() + +# commands to unalias +declare -a unalias_cmds=( clear configure date debug edit exit load \ + no set show save terminal undebug ) +for cmd in "${unalias_cmds[@]}"; do + unalias $cmd >& /dev/null +done + +show () +{ + eval "${vyatta_sbindir}/vyatta-output-config.pl \ + \${VYATTA_EDIT_LEVEL//\// } $@" +} + +save () +{ + eval "${vyatta_sbindir}/vyatta-save-config.pl $@" +} + +declare vyatta_cfg_prompt_level='' +set_config_ps1 () +{ + local level=$1 + if [ -z "$level" ]; then + export PS1="[edit]\n\u@\h# " + vyatta_cfg_prompt_level='' + else + export PS1="[edit $level]\n\u@\h# " + vyatta_cfg_prompt_level="$level" + fi +} + +load () +{ + # don't load if there are uncommitted changes. + if [ -f "$VYATTA_TEMP_CONFIG_DIR/$VYATTA_MOD_NAME" ]; then + echo "Cannot load: configuration modified." + echo "Commit or discard the changes before loading a config file." + return 1 + fi + # return to top level. + export VYATTA_EDIT_LEVEL="/" + export VYATTA_TEMPLATE_LEVEL="/" + set_config_ps1 '' + eval "${vyatta_sbindir}/vyatta-load-config.pl $@" +} + +edit () +{ + local num_comp=${#@} + local _mpath=${VYATTA_TEMP_CONFIG_DIR}/${VYATTA_EDIT_LEVEL} + local _tpath=${VYATTA_CONFIG_TEMPLATE}/${VYATTA_TEMPLATE_LEVEL} + local idx + for (( idx=1; idx <= num_comp; idx++ )); do + local comp + eval "comp=\$$idx" + vyatta_escape comp comp + push_path _mpath $comp + push_path _tpath $comp + if [ ! -d $_mpath ]; then + # "edit" only allows existing node + break + fi + + # check if it's not tag value + if [ -d $_tpath ]; then + continue + fi + + # check if it's tag value + pop_path _tpath + push_path _tpath $VYATTA_TAG_NAME + if [ -d $_tpath ]; then + continue + fi + pop_path _tpath + pop_path _mpath + break + done + # "edit" only valid for + # * "node.tag" level + # * "node.def" level without "type:" + if (( idx != ( num_comp + 1) )); then + echo "Invalid node \"$*\" for the 'edit' command" + return 1 + fi + if [ "${_tpath:((-9))}" != "/node.tag" ]; then + # we are not at "node.tag" level. look for "type:". + if [ ! -r "$_tpath/node.def" ]; then + vyatta_cfg_type="" + else + vyatta_parse_tmpl "$_tpath/node.def" + fi + if [ -n "$vyatta_cfg_type" ]; then + # "type:" present + echo "The 'edit' command cannot be issued at the \"$*\" level" + return 1 + fi + fi + export VYATTA_EDIT_LEVEL="${_mpath#$VYATTA_TEMP_CONFIG_DIR}/" + export VYATTA_TEMPLATE_LEVEL="${_tpath#$VYATTA_CONFIG_TEMPLATE}/" + + declare -a path_arr + path_str2arr VYATTA_EDIT_LEVEL path_arr + local path_str="${path_arr[*]}" + set_config_ps1 "$path_str" +} + +really_exit() +{ + sudo umount $VYATTA_TEMP_CONFIG_DIR + sudo rm -rf $VYATTA_TEMP_CONFIG_DIR $VYATTA_CHANGES_ONLY_DIR \ + $VYATTA_CONFIG_TMP + unset _OFR_CONFIGURE + builtin exit 0 +} + +exit () +{ + local discard + if [ $# == 0 ]; then + discard=0 + elif [ $# == 1 ] && [ "$1" == "discard" ]; then + discard=1 + else + echo "Invalid argument \"$*\" for 'exit'" + return 1 + fi + + if [ "$VYATTA_EDIT_LEVEL" == "/" ]; then + # we are at the root level. check if we can really exit. + if [ -f "$VYATTA_TEMP_CONFIG_DIR/$VYATTA_MOD_NAME" ]; then + if (( ! discard )); then + echo "Cannot exit: configuration modified." + echo "Use 'exit discard' to discard the changes and exit." + return 1 + fi + fi + really_exit + fi + + # "exit" to the root level. + export VYATTA_EDIT_LEVEL="/" + export VYATTA_TEMPLATE_LEVEL="/" + set_config_ps1 '' +} + +declare v_cfg_completion_debug=0 +decho () +{ + if (( v_cfg_completion_debug )); then + echo -n "$*" + fi +} + +push_path_arr () +{ + # $1: \@path_arr + # $2: component + eval "$1=( \"\${$1[@]}\" '$2' )" +} + +pop_path_arr () +{ + # $1: \@path_arr + eval "$1=( \"\${$1[@]:0:((\${#$1[@]}-1))}\" )" +} + +path_arr2str () +{ + # $1: \@path_arr + # $2: \$path_str + eval "$2=\"\${$1[*]}\"" + eval "$2=/\${$2// //}" +} + +path_str2arr () +{ + # $1: \$path_str + # $2: \@path_arr + local tmp + eval "tmp=\${$1:1}" + eval "$2=( \${tmp//\// } )" +} + +push_path () +{ + # $1: \$path_str + # $2: component + declare -a path_arr + eval "path_str2arr $1 path_arr" + eval "push_path_arr path_arr '$2'" + eval "path_arr2str path_arr $1" +} + +pop_path () +{ + # $1: \$path_str + declare -a path_arr + eval "path_str2arr $1 path_arr" + pop_path_arr path_arr + eval "path_arr2str path_arr $1" +} + +get_filtered_dir_listing () +{ + # $1: path + # $2: \@listing + if [ ! -d $1 ]; then + eval "$2=()" + return + fi + local pattern='^node\.def$|^node\.tag$|^node\.val$|^\.modified$' + patterh=$pattern'|^\.commit\.lck$|^\.wh\.' + local cmd="ls $1 |egrep -v '$pattern'" + declare -a listing=( $(eval $cmd) ) + for enode in "${listing[@]}"; do + local unode + vyatta_unescape enode unode + eval "$2[\${#$2[@]}]=$unode" + done +} + +filter_existing_nodes () +{ + # $1: mpath + # $2: \@orig + # $3: \@filtered + declare -a orig + eval "orig=( \"\${$2[@]}\" )" + for node in "${orig[@]}"; do + if [ -d "$1/$node" ]; then + eval "$3[\${#$3[@]}]=$node" + fi + done +} + +get_prefix_filtered_list () +{ + # $1: prefix + # $2: \@list + # $3: \@filtered + declare -a olist + local pfx=$1 + pfx=${pfx#\"} + eval "olist=( \"\${$2[@]}\" )" + local idx=0 + for elem in "${olist[@]}"; do + local sub=${elem#$pfx} + if [ "$elem" == "$sub" ] && [ -n "$pfx" ]; then + continue + fi + eval "$3[$idx]=\"$elem\"" + (( idx++ )) + done +} + +vyatta_parse_tmpl_comp_fields () +{ + # $1: tmpl + # $2: field name + sed -n ' + /^#'"$2"':/,$ { + s/^#'"$2"':// + h + :b + $ { x; p; q } + n + /^#[-_a-z]\+:/ { x; p; q } + s/^#// + H + bb + } + ' $1 +} + +declare vyatta_cfg_help="" +declare vyatta_cfg_type="" +declare vyatta_cfg_tag=0 +declare vyatta_cfg_multi=0 +declare -a vyatta_cfg_allowed=() +declare vyatta_cfg_comp_help="" +vyatta_parse_tmpl () +{ + # $1: tmpl + vyatta_cfg_help="" + vyatta_cfg_type="" + vyatta_cfg_tag=0 + vyatta_cfg_multi=0 + vyatta_cfg_allowed=() + vyatta_cfg_comp_help='' + if [ ! -r $1 ]; then + return + fi + eval `sed -n ' + /^help:[ ]\+/,/^[a-z]\+:/ { + s/^help:[ ]\+/vyatta_cfg_help=/p + /^ /p + } + /^syntax:[ ]\+\$(@)[ ]\+in[ ]\+/ { + s/^syntax:[ ]\+\$(@)[ ]\+in[ ]\+/vyatta_cfg_allowed=( / + s/^\([^;]\+\);.*$/\1 )/ + s/[ ]*,[ ]*/ /gp + } + s/^tag:/vyatta_cfg_tag=1/p + s/^multi:/vyatta_cfg_multi=1/p + s/^type:[ ]\+\([^ ]\+\)$/vyatta_cfg_type=\1/p + ' $1` + + local acmd=$(vyatta_parse_tmpl_comp_fields $1 "allowed") + vyatta_cfg_comp_help=$(vyatta_parse_tmpl_comp_fields $1 "comp_help") + + if (( ${#vyatta_cfg_allowed[@]} == 0 )); then + local ares=$(eval "$acmd") + eval "vyatta_cfg_allowed=( $ares )" + fi + if [ -z "$vyatta_cfg_help" ]; then + vyatta_cfg_help='' + fi +} + +# this fills in $vyatta_help_text +generate_help_text () +{ + # $1: \@items + # $2: \@help_strs + declare -a items + declare -a helps + eval "items=( \"\${$1[@]}\" )" + eval "helps=( \"\${$2[@]}\" )" + if [ -n "$vyatta_cfg_comp_help" ]; then + vyatta_help_text="\\n${vyatta_cfg_comp_help}" + return 0 + fi + vyatta_help_text="\\nPossible completions:" + for (( idx = 0; idx < ${#items[@]}; idx++ )); do + vyatta_help_text="${vyatta_help_text}\\n\\x20\\x20" + if [ ${#items[$idx]} -lt 6 ]; then + vyatta_help_text="${vyatta_help_text}${items[$idx]}\\t\\t" + elif [ ${#items[$idx]} -lt 14 ]; then + vyatta_help_text="${vyatta_help_text}${items[$idx]}\\t" + else + vyatta_help_text="${vyatta_help_text}${items[$idx]}\\n\\x20\\x20\\t\\t" + fi + vyatta_help_text="${vyatta_help_text}${helps[$idx]}" + done +} + +# this fills in $vyatta_help_text +get_tmpl_subdir_help () +{ + # $1: path + # $2: \@subdirs + declare -a subdirs + eval "subdirs=( \"\${$2[@]}\" )" + if [ ${#subdirs[@]} == 0 ]; then + vyatta_help_text="" + return + fi + declare -a hitems=() + declare -a hstrs=() + for subdir in "${subdirs[@]}"; do + if [ ! -r $1/$subdir/node.def ]; then + vyatta_cfg_help="" + else + vyatta_parse_tmpl "$1/$subdir/node.def" + # comp_help overrides the current help, so we reset it here since + # it is from the subdir. + vyatta_cfg_comp_help='' + fi + hitems[${#hitems[@]}]=$subdir + hstrs[${#hstrs[@]}]=$vyatta_cfg_help + done + generate_help_text hitems hstrs +} + +# return 0 if yes. 1 if no. +item_in_list () +{ + # $1: item + # $2: \@list + declare -a olist + local item + eval "olist=( \"\${$2[@]}\" )" + for item in "${olist[@]}"; do + if [ "$1" == "$item" ]; then + return 0 + fi + done + return 1 +} + +append_allowed_values () +{ + # $1: tmpl_path + # $2: \@values + if [ ! -r "$1/node.def" ]; then + return + fi + vyatta_parse_tmpl "$1/node.def" + local item + for item in "${vyatta_cfg_allowed[@]}"; do + if ! item_in_list "$item" $2; then + eval "$2[\${#$2[@]}]=\"$item\"" + fi + done +} + +# return 0 if yes. 1 if no. +is_setting_new_leaf () +{ + # $1: tmpl_path + if [ $is_set == 0 ]; then + return 1 + fi + vyatta_parse_tmpl "$1/node.def" + if [ -z "$vyatta_cfg_type" ]; then + return 1 + fi + return 0 +} + +# this fills in $vyatta_help_text +get_node_value_help () +{ + # $1: path + # $2: \@values + declare -a vals + eval "vals=( \"\${$2[@]}\" )" + if [ $is_set == 0 -a ${#vals[@]} == 0 ]; then + vyatta_help_text="" + return + fi + if [ ! -r "$1/node.def" ]; then + vyatta_cfg_help="" + vyatta_cfg_type="" + else + vyatta_parse_tmpl "$1/node.def" + fi + if [ $is_set == 1 -a ! -z "$vyatta_cfg_type" ]; then + # add a value + local val="<$vyatta_cfg_type>" + vals=( $val "${vals[@]}" ) + fi + if [ ${#vals[@]} == 0 ]; then + vyatta_help_text="" + return + fi + declare -a hitems=() + declare -a hstrs=() + for val in "${vals[@]}"; do + hitems[${#hitems[@]}]=$val + hstrs[${#hstrs[@]}]=$vyatta_cfg_help + done + generate_help_text hitems hstrs +} + +get_value_list () +{ + # $1: path + # $2: \@listing + local vfile=$1/node.val + if [ ! -r $vfile ]; then + eval "$2=()" + return + fi + declare -a listing=() + local cmd=$(sed 's/^\(.*\)$/listing[\${#listing[@]}]='\''\1'\''/' $vfile) + eval "$cmd" + eval "$2=( \"\${listing[@]}\" )" +} + +vyatta_escape () +{ + # $1: \$original + # $2: \$escaped + eval "$2=\${$1//\%/%25}" + eval "$2=\${$2//\*/%2A}" + eval "$2=\${$2//\//%2F}" +} + +vyatta_unescape () +{ + # $1: \$escaped + # $2: \$original + eval "$2=\${$1//\%2F/\/}" + eval "$2=\${$2//\%2A/*}" + eval "$2=\${$2//\%25/%}" +} + +declare -a vyatta_completions +declare vyatta_help_text="\\nNo help text available" +declare vyatta_do_help=0 +vyatta_do_complete () +{ + # when this function is called, it is expected that: + # * "vyatta_help_text" is filled with the help text. + # * "vyatta_completions" is an array of "filtered" possible completions + # (i.e., only those starting with the current last component). + local do_help=$vyatta_do_help + + # we may not want to do the following +<<'ENDCOMMENT' + if [ ${#vyatta_completions[@]} == 1 ]; then + # no ambiguous completions. do completion instead of help. + do_help=0 + fi + + # now check if we can auto-complete at least 1 more character. + if (( do_help )); then + local schar="" + for comp in "${vyatta_completions[@]}"; do + local sub=$comp + if [ ! -z "${COMP_WORDS[COMP_CWORD]}" ]; then + sub=${comp#${comp_words[$last_idx]}} + if [ "$comp" == "$sub" ]; then + # should not happen since vyatta_completions should be filtered. + continue + fi + fi + if [ -z "$schar" ]; then + schar=${sub:0:1} + else + if [ "$schar" != "${sub:0:1}" ]; then + schar="" + break + fi + fi + done + if [ ! -z "$schar" ]; then + do_help=0 + fi + fi +ENDCOMMENT + + if (( do_help )); then + printf "$vyatta_help_text" + COMPREPLY=( "" " " ) + else + local -a f_comps=() + get_prefix_filtered_list "${COMP_WORDS[COMP_CWORD]}" \ + vyatta_completions f_comps + local estr="COMPREPLY=( " + for w in "${f_comps[@]}"; do + estr="$estr\"$w\" " + done + estr="${estr})" + eval "$estr" + fi + vyatta_help_text="\\nNo help text available" +} + +vyatta_config_complete () +{ + local restore_shopts=$( shopt -p extglob nullglob | tr \\n \; ) + shopt -s extglob nullglob + + if [ "$COMP_LINE" == "$VYATTA_COMP_LINE" ]; then + VYATTA_COMP_LINE='' + vyatta_do_help=1 + else + VYATTA_COMP_LINE=$COMP_LINE + vyatta_do_help=0 + fi + + local command=${COMP_WORDS[0]} + # completion for "set" is different from other commands + is_set=0 + if [ "$command" == "set" ]; then + is_set=1 + fi + local end_space=0 + local num_comp=$COMP_CWORD + if [ -z "${COMP_WORDS[$COMP_CWORD]}" ]; then + end_space=1 + (( num_comp -= 1 )) + fi + (( last_idx = num_comp - 1 )) + comp_words=( ${COMP_WORDS[@]:1:$num_comp} ) + + # handle "exit" + if [ "$command" == "exit" ]; then + if (( num_comp > 1 || ( end_space && num_comp > 0 ) )); then + COMPREPLY=() + return + fi + declare -a hitems=( "discard" ) + declare -a hstrs=( "Discard any changes" ) + generate_help_text hitems hstrs + vyatta_completions=( "discard" ) + vyatta_do_complete + return + fi + + local _mpath=${VYATTA_TEMP_CONFIG_DIR}/${VYATTA_EDIT_LEVEL} + local _tpath=${VYATTA_CONFIG_TEMPLATE}/${VYATTA_TEMPLATE_LEVEL} + local last_tag=0 + local idx=0 + for (( idx=0; idx < num_comp; idx++ )); do + last_tag=0 + local comp=${comp_words[$idx]} + vyatta_escape comp comp + push_path _mpath $comp + push_path _tpath $comp + if [ -d $_tpath ]; then + if (( ! is_set )); then + # we are not in "set" => only allow existing node + if [ ! -d $_mpath ]; then + break + fi + fi + continue + fi + pop_path _tpath + push_path _tpath $VYATTA_TAG_NAME + if [ -d $_tpath ]; then + if (( ! is_set && end_space )); then + # we are not in "set" && last component is complete. + # => only allow existing tag value. + if [ ! -d $_mpath ]; then + break + fi + fi + if (( idx != last_idx )); then + # TODO validate value + # break if not valid + # XXX is this validation necessary? (set will validate anyway) + true + fi + last_tag=1 + continue + fi + pop_path _tpath + pop_path _mpath + break + done + # at the end of the loop, 3 possibilities: + # 1. (idx < last_idx): some component before the last is invalid + # => invalid command + # 2. (idx == last_idx): last component matches neither template nor node.tag + # => if end_space, then invalid command + # otherwise, may be an incomplete (non-tag) component, or incomplete + # "leaf value" + # => try matching dirs in _tpath or value(s) in _mpath/node.val + # 3. (idx == num_comp): the whole command matches templates/tags + if (( idx < last_idx || ( idx == last_idx && end_space ) )); then + # TODO error message? + COMPREPLY=() + return + fi + + declare -a matches + if (( idx == last_idx )); then + # generate possibile matches (dirs in _tpath, and "help" from + # node.def in each dir, or values in _mpath/node.val) + declare -a fmatches + if [ -f $_mpath/node.val ]; then + decho {1a} + get_value_list $_mpath matches + get_prefix_filtered_list ${comp_words[$last_idx]} matches fmatches + append_allowed_values $_tpath fmatches + get_node_value_help $_tpath fmatches + else + decho {1b} + # see if the last component is a new leaf node + fmatches=() + if is_setting_new_leaf $_tpath; then + append_allowed_values $_tpath fmatches + get_node_value_help $_tpath fmatches + else + # last component is a non-value node. look for child nodes. + if (( ! is_set )); then + # not "set". only complete existing nodes. + declare -a amatches=() + get_filtered_dir_listing $_tpath amatches + filter_existing_nodes $_mpath amatches matches + else + get_filtered_dir_listing $_tpath matches + fi + get_prefix_filtered_list ${comp_words[$last_idx]} matches fmatches + get_tmpl_subdir_help $_tpath fmatches + fi + fi + vyatta_completions=( "${fmatches[@]}" ) + vyatta_do_complete + return + fi + + if (( last_tag && end_space )); then + # if not "set", check _mpath (last component is the tag) is valid + # generate possible matches (dirs in _tpath, and "help" from node.def + # in each dir) + decho {2} + if [ $is_set == 1 -o -d $_mpath ]; then + if (( ! is_set )); then + # not "set". only complete existing nodes. + declare -a fmatches=() + get_filtered_dir_listing $_tpath fmatches + filter_existing_nodes $_mpath fmatches matches + else + get_filtered_dir_listing $_tpath matches + fi + get_tmpl_subdir_help $_tpath matches + vyatta_completions=( "${matches[@]}" ) + vyatta_do_complete + return + fi + return + fi + + if (( last_tag && !end_space )); then + # generate possible matches (dirs in _mpath, and "help" from node.def + # in dirs in _tpath) + decho {3} + pop_path _mpath + pop_path _tpath + get_filtered_dir_listing $_mpath matches + declare -a fmatches + get_prefix_filtered_list ${comp_words[$last_idx]} matches fmatches + append_allowed_values $_tpath fmatches + get_node_value_help $_tpath fmatches + vyatta_completions=( "${fmatches[@]}" ) + vyatta_do_complete + return + fi + + if (( !last_tag && end_space )); then + # generate possible matches + # 1. dirs in _tpath, and "help" from node.def in each dir + # 2. value(s) in _mpath/node.val (only if _tpath/node.def is "multi:") + # 3. dirs in _mpath (only if _tpath/node.def is "tag:") + if [ -d $_tpath/node.tag ]; then + # last component is a "tag name". look for tag values. + decho {4a} + get_filtered_dir_listing $_mpath matches + append_allowed_values $_tpath matches + get_node_value_help $_tpath matches + elif [ -f $_mpath/node.val ]; then + # last component is a leaf node. look for values. + decho {4b} + get_value_list $_mpath matches + append_allowed_values $_tpath matches + get_node_value_help $_tpath matches + else + decho {4c} + # see if the last component is a new leaf node + matches=() + if is_setting_new_leaf $_tpath; then + append_allowed_values $_tpath matches + get_node_value_help $_tpath matches + else + # last component is a non-value node. look for child nodes. + if (( ! is_set )); then + # not "set". only complete existing nodes. + declare -a fmatches=() + get_filtered_dir_listing $_tpath fmatches + filter_existing_nodes $_mpath fmatches matches + else + get_filtered_dir_listing $_tpath matches + fi + get_tmpl_subdir_help $_tpath matches + fi + fi + vyatta_completions=( "${matches[@]}" ) + vyatta_do_complete + return + fi + + if (( !last_tag && !end_space )); then + # generate possible matches (dirs in _tpath, and "help" from node.def + # in each dir) + decho {5} + pop_path _tpath + get_filtered_dir_listing $_tpath matches + declare -a fmatches + get_prefix_filtered_list ${comp_words[$last_idx]} matches fmatches + get_tmpl_subdir_help $_tpath fmatches + vyatta_completions=( "${fmatches[@]}" ) + vyatta_do_complete + return + fi + + eval $restore_shopts +} + +DEF_GROUP=quaggavty +make_vyatta_config_dir () +{ + sudo mkdir -m 0775 -p $1 + sudo chgrp ${DEF_GROUP} $1 +} + +make_vyatta_config_dir $VYATTA_ACTIVE_CONFIGURATION_DIR +make_vyatta_config_dir $VYATTA_CHANGES_ONLY_DIR +make_vyatta_config_dir $VYATTA_CONFIG_TMP +if [ ! -d $VYATTA_TEMP_CONFIG_DIR ]; then + make_vyatta_config_dir $VYATTA_TEMP_CONFIG_DIR + sudo mount -t unionfs -o dirs=${VYATTA_CHANGES_ONLY_DIR}=rw:/opt/vyatta/config/active=ro unionfs ${VYATTA_TEMP_CONFIG_DIR} +fi + +# disallow 'Ctrl-D' exit, since we need special actions on 'exit' +set -o ignoreeof 1 + +set_config_ps1 '' +alias commit=/opt/vyatta/sbin/my_commit +alias set=/opt/vyatta/sbin/my_set +alias delete=/opt/vyatta/sbin/my_delete + +export VYATTA_COMP_LINE="" + +# readline bindings +bind 'set show-all-if-ambiguous on' +if ! bind -p |grep -q '\\C-x\\C-t'; then + bind '"\C-x\C-t": kill-region' +fi +if ! bind -p |grep -q '\\C-x\\C-o'; then + bind '"\C-x\C-o": copy-region-as-kill' +fi + +complete -F vyatta_config_complete set +complete -F vyatta_config_complete delete +complete -F vyatta_config_complete show +complete -F vyatta_config_complete edit +complete -F vyatta_config_complete exit + diff --git a/etc/bash_completion.d/vyatta-cfg b/etc/bash_completion.d/vyatta-cfg deleted file mode 100644 index bef195d..0000000 --- a/etc/bash_completion.d/vyatta-cfg +++ /dev/null @@ -1,862 +0,0 @@ -# **** License **** -# Version: VPL 1.0 -# -# The contents of this file are subject to the Vyatta Public License -# Version 1.0 ("License"); you may not use this file except in -# compliance with the License. You may obtain a copy of the License at -# http://www.vyatta.com/vpl -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -# the License for the specific language governing rights and limitations -# under the License. -# -# This code was originally developed by Vyatta, Inc. -# Portions created by Vyatta are Copyright (C) 2006, 2007 Vyatta, Inc. -# All Rights Reserved. -# -# Author: An-Cheng Huang -# Date: 2007 -# Description: bash completion for Vyatta configuration commands -# -# **** End License **** - -# only do this if we are going into configure mode -if [ "$_OFR_CONFIGURE" != "ok" ]; then - return 0 -fi - -umask 0002 - -if [ -r /etc/default/vyatta ]; then - source /etc/default/vyatta -fi - -declare is_set=0 -declare last_idx=0 -declare -a comp_words=() - -# commands to unalias -declare -a unalias_cmds=( clear configure date debug edit exit load \ - no set show save terminal undebug ) -for cmd in "${unalias_cmds[@]}"; do - unalias $cmd >& /dev/null -done - -show () -{ - eval "${vyatta_sbindir}/vyatta-output-config.pl \ - \${VYATTA_EDIT_LEVEL//\// } $@" -} - -save () -{ - eval "${vyatta_sbindir}/vyatta-save-config.pl $@" -} - -declare vyatta_cfg_prompt_level='' -set_config_ps1 () -{ - local level=$1 - if [ -z "$level" ]; then - export PS1="[edit]\n\u@\h# " - vyatta_cfg_prompt_level='' - else - export PS1="[edit $level]\n\u@\h# " - vyatta_cfg_prompt_level="$level" - fi -} - -load () -{ - # don't load if there are uncommitted changes. - if [ -f "$VYATTA_TEMP_CONFIG_DIR/$VYATTA_MOD_NAME" ]; then - echo "Cannot load: configuration modified." - echo "Commit or discard the changes before loading a config file." - return 1 - fi - # return to top level. - export VYATTA_EDIT_LEVEL="/" - export VYATTA_TEMPLATE_LEVEL="/" - set_config_ps1 '' - eval "${vyatta_sbindir}/vyatta-load-config.pl $@" -} - -edit () -{ - local num_comp=${#@} - local _mpath=${VYATTA_TEMP_CONFIG_DIR}/${VYATTA_EDIT_LEVEL} - local _tpath=${VYATTA_CONFIG_TEMPLATE}/${VYATTA_TEMPLATE_LEVEL} - local idx - for (( idx=1; idx <= num_comp; idx++ )); do - local comp - eval "comp=\$$idx" - vyatta_escape comp comp - push_path _mpath $comp - push_path _tpath $comp - if [ ! -d $_mpath ]; then - # "edit" only allows existing node - break - fi - - # check if it's not tag value - if [ -d $_tpath ]; then - continue - fi - - # check if it's tag value - pop_path _tpath - push_path _tpath $VYATTA_TAG_NAME - if [ -d $_tpath ]; then - continue - fi - pop_path _tpath - pop_path _mpath - break - done - # "edit" only valid for - # * "node.tag" level - # * "node.def" level without "type:" - if (( idx != ( num_comp + 1) )); then - echo "Invalid node \"$*\" for the 'edit' command" - return 1 - fi - if [ "${_tpath:((-9))}" != "/node.tag" ]; then - # we are not at "node.tag" level. look for "type:". - if [ ! -r "$_tpath/node.def" ]; then - vyatta_cfg_type="" - else - vyatta_parse_tmpl "$_tpath/node.def" - fi - if [ -n "$vyatta_cfg_type" ]; then - # "type:" present - echo "The 'edit' command cannot be issued at the \"$*\" level" - return 1 - fi - fi - export VYATTA_EDIT_LEVEL="${_mpath#$VYATTA_TEMP_CONFIG_DIR}/" - export VYATTA_TEMPLATE_LEVEL="${_tpath#$VYATTA_CONFIG_TEMPLATE}/" - - declare -a path_arr - path_str2arr VYATTA_EDIT_LEVEL path_arr - local path_str="${path_arr[*]}" - set_config_ps1 "$path_str" -} - -really_exit() -{ - sudo umount $VYATTA_TEMP_CONFIG_DIR - sudo rm -rf $VYATTA_TEMP_CONFIG_DIR $VYATTA_CHANGES_ONLY_DIR \ - $VYATTA_CONFIG_TMP - unset _OFR_CONFIGURE - builtin exit 0 -} - -exit () -{ - local discard - if [ $# == 0 ]; then - discard=0 - elif [ $# == 1 ] && [ "$1" == "discard" ]; then - discard=1 - else - echo "Invalid argument \"$*\" for 'exit'" - return 1 - fi - - if [ "$VYATTA_EDIT_LEVEL" == "/" ]; then - # we are at the root level. check if we can really exit. - if [ -f "$VYATTA_TEMP_CONFIG_DIR/$VYATTA_MOD_NAME" ]; then - if (( ! discard )); then - echo "Cannot exit: configuration modified." - echo "Use 'exit discard' to discard the changes and exit." - return 1 - fi - fi - really_exit - fi - - # "exit" to the root level. - export VYATTA_EDIT_LEVEL="/" - export VYATTA_TEMPLATE_LEVEL="/" - set_config_ps1 '' -} - -declare v_cfg_completion_debug=0 -decho () -{ - if (( v_cfg_completion_debug )); then - echo -n "$*" - fi -} - -push_path_arr () -{ - # $1: \@path_arr - # $2: component - eval "$1=( \"\${$1[@]}\" '$2' )" -} - -pop_path_arr () -{ - # $1: \@path_arr - eval "$1=( \"\${$1[@]:0:((\${#$1[@]}-1))}\" )" -} - -path_arr2str () -{ - # $1: \@path_arr - # $2: \$path_str - eval "$2=\"\${$1[*]}\"" - eval "$2=/\${$2// //}" -} - -path_str2arr () -{ - # $1: \$path_str - # $2: \@path_arr - local tmp - eval "tmp=\${$1:1}" - eval "$2=( \${tmp//\// } )" -} - -push_path () -{ - # $1: \$path_str - # $2: component - declare -a path_arr - eval "path_str2arr $1 path_arr" - eval "push_path_arr path_arr '$2'" - eval "path_arr2str path_arr $1" -} - -pop_path () -{ - # $1: \$path_str - declare -a path_arr - eval "path_str2arr $1 path_arr" - pop_path_arr path_arr - eval "path_arr2str path_arr $1" -} - -get_filtered_dir_listing () -{ - # $1: path - # $2: \@listing - if [ ! -d $1 ]; then - eval "$2=()" - return - fi - local pattern='^node\.def$|^node\.tag$|^node\.val$|^\.modified$' - patterh=$pattern'|^\.commit\.lck$|^\.wh\.' - local cmd="ls $1 |egrep -v '$pattern'" - declare -a listing=( $(eval $cmd) ) - for enode in "${listing[@]}"; do - local unode - vyatta_unescape enode unode - eval "$2[\${#$2[@]}]=$unode" - done -} - -filter_existing_nodes () -{ - # $1: mpath - # $2: \@orig - # $3: \@filtered - declare -a orig - eval "orig=( \"\${$2[@]}\" )" - for node in "${orig[@]}"; do - if [ -d "$1/$node" ]; then - eval "$3[\${#$3[@]}]=$node" - fi - done -} - -get_prefix_filtered_list () -{ - # $1: prefix - # $2: \@list - # $3: \@filtered - declare -a olist - local pfx=$1 - pfx=${pfx#\"} - eval "olist=( \"\${$2[@]}\" )" - local idx=0 - for elem in "${olist[@]}"; do - local sub=${elem#$pfx} - if [ "$elem" == "$sub" ] && [ -n "$pfx" ]; then - continue - fi - eval "$3[$idx]=\"$elem\"" - (( idx++ )) - done -} - -vyatta_parse_tmpl_comp_fields () -{ - # $1: tmpl - # $2: field name - sed -n ' - /^#'"$2"':/,$ { - s/^#'"$2"':// - h - :b - $ { x; p; q } - n - /^#[-_a-z]\+:/ { x; p; q } - s/^#// - H - bb - } - ' $1 -} - -declare vyatta_cfg_help="" -declare vyatta_cfg_type="" -declare vyatta_cfg_tag=0 -declare vyatta_cfg_multi=0 -declare -a vyatta_cfg_allowed=() -declare vyatta_cfg_comp_help="" -vyatta_parse_tmpl () -{ - # $1: tmpl - vyatta_cfg_help="" - vyatta_cfg_type="" - vyatta_cfg_tag=0 - vyatta_cfg_multi=0 - vyatta_cfg_allowed=() - vyatta_cfg_comp_help='' - if [ ! -r $1 ]; then - return - fi - eval `sed -n ' - /^help:[ ]\+/,/^[a-z]\+:/ { - s/^help:[ ]\+/vyatta_cfg_help=/p - /^ /p - } - /^syntax:[ ]\+\$(@)[ ]\+in[ ]\+/ { - s/^syntax:[ ]\+\$(@)[ ]\+in[ ]\+/vyatta_cfg_allowed=( / - s/^\([^;]\+\);.*$/\1 )/ - s/[ ]*,[ ]*/ /gp - } - s/^tag:/vyatta_cfg_tag=1/p - s/^multi:/vyatta_cfg_multi=1/p - s/^type:[ ]\+\([^ ]\+\)$/vyatta_cfg_type=\1/p - ' $1` - - local acmd=$(vyatta_parse_tmpl_comp_fields $1 "allowed") - vyatta_cfg_comp_help=$(vyatta_parse_tmpl_comp_fields $1 "comp_help") - - if (( ${#vyatta_cfg_allowed[@]} == 0 )); then - local ares=$(eval "$acmd") - eval "vyatta_cfg_allowed=( $ares )" - fi - if [ -z "$vyatta_cfg_help" ]; then - vyatta_cfg_help='' - fi -} - -# this fills in $vyatta_help_text -generate_help_text () -{ - # $1: \@items - # $2: \@help_strs - declare -a items - declare -a helps - eval "items=( \"\${$1[@]}\" )" - eval "helps=( \"\${$2[@]}\" )" - if [ -n "$vyatta_cfg_comp_help" ]; then - vyatta_help_text="\\n${vyatta_cfg_comp_help}" - return 0 - fi - vyatta_help_text="\\nPossible completions:" - for (( idx = 0; idx < ${#items[@]}; idx++ )); do - vyatta_help_text="${vyatta_help_text}\\n\\x20\\x20" - if [ ${#items[$idx]} -lt 6 ]; then - vyatta_help_text="${vyatta_help_text}${items[$idx]}\\t\\t" - elif [ ${#items[$idx]} -lt 14 ]; then - vyatta_help_text="${vyatta_help_text}${items[$idx]}\\t" - else - vyatta_help_text="${vyatta_help_text}${items[$idx]}\\n\\x20\\x20\\t\\t" - fi - vyatta_help_text="${vyatta_help_text}${helps[$idx]}" - done -} - -# this fills in $vyatta_help_text -get_tmpl_subdir_help () -{ - # $1: path - # $2: \@subdirs - declare -a subdirs - eval "subdirs=( \"\${$2[@]}\" )" - if [ ${#subdirs[@]} == 0 ]; then - vyatta_help_text="" - return - fi - declare -a hitems=() - declare -a hstrs=() - for subdir in "${subdirs[@]}"; do - if [ ! -r $1/$subdir/node.def ]; then - vyatta_cfg_help="" - else - vyatta_parse_tmpl "$1/$subdir/node.def" - # comp_help overrides the current help, so we reset it here since - # it is from the subdir. - vyatta_cfg_comp_help='' - fi - hitems[${#hitems[@]}]=$subdir - hstrs[${#hstrs[@]}]=$vyatta_cfg_help - done - generate_help_text hitems hstrs -} - -# return 0 if yes. 1 if no. -item_in_list () -{ - # $1: item - # $2: \@list - declare -a olist - local item - eval "olist=( \"\${$2[@]}\" )" - for item in "${olist[@]}"; do - if [ "$1" == "$item" ]; then - return 0 - fi - done - return 1 -} - -append_allowed_values () -{ - # $1: tmpl_path - # $2: \@values - if [ ! -r "$1/node.def" ]; then - return - fi - vyatta_parse_tmpl "$1/node.def" - local item - for item in "${vyatta_cfg_allowed[@]}"; do - if ! item_in_list "$item" $2; then - eval "$2[\${#$2[@]}]=\"$item\"" - fi - done -} - -# return 0 if yes. 1 if no. -is_setting_new_leaf () -{ - # $1: tmpl_path - if [ $is_set == 0 ]; then - return 1 - fi - vyatta_parse_tmpl "$1/node.def" - if [ -z "$vyatta_cfg_type" ]; then - return 1 - fi - return 0 -} - -# this fills in $vyatta_help_text -get_node_value_help () -{ - # $1: path - # $2: \@values - declare -a vals - eval "vals=( \"\${$2[@]}\" )" - if [ $is_set == 0 -a ${#vals[@]} == 0 ]; then - vyatta_help_text="" - return - fi - if [ ! -r "$1/node.def" ]; then - vyatta_cfg_help="" - vyatta_cfg_type="" - else - vyatta_parse_tmpl "$1/node.def" - fi - if [ $is_set == 1 -a ! -z "$vyatta_cfg_type" ]; then - # add a value - local val="<$vyatta_cfg_type>" - vals=( $val "${vals[@]}" ) - fi - if [ ${#vals[@]} == 0 ]; then - vyatta_help_text="" - return - fi - declare -a hitems=() - declare -a hstrs=() - for val in "${vals[@]}"; do - hitems[${#hitems[@]}]=$val - hstrs[${#hstrs[@]}]=$vyatta_cfg_help - done - generate_help_text hitems hstrs -} - -get_value_list () -{ - # $1: path - # $2: \@listing - local vfile=$1/node.val - if [ ! -r $vfile ]; then - eval "$2=()" - return - fi - declare -a listing=() - local cmd=$(sed 's/^\(.*\)$/listing[\${#listing[@]}]='\''\1'\''/' $vfile) - eval "$cmd" - eval "$2=( \"\${listing[@]}\" )" -} - -vyatta_escape () -{ - # $1: \$original - # $2: \$escaped - eval "$2=\${$1//\%/%25}" - eval "$2=\${$2//\*/%2A}" - eval "$2=\${$2//\//%2F}" -} - -vyatta_unescape () -{ - # $1: \$escaped - # $2: \$original - eval "$2=\${$1//\%2F/\/}" - eval "$2=\${$2//\%2A/*}" - eval "$2=\${$2//\%25/%}" -} - -declare -a vyatta_completions -declare vyatta_help_text="\\nNo help text available" -declare vyatta_do_help=0 -vyatta_do_complete () -{ - # when this function is called, it is expected that: - # * "vyatta_help_text" is filled with the help text. - # * "vyatta_completions" is an array of "filtered" possible completions - # (i.e., only those starting with the current last component). - local do_help=$vyatta_do_help - - # we may not want to do the following -<<'ENDCOMMENT' - if [ ${#vyatta_completions[@]} == 1 ]; then - # no ambiguous completions. do completion instead of help. - do_help=0 - fi - - # now check if we can auto-complete at least 1 more character. - if (( do_help )); then - local schar="" - for comp in "${vyatta_completions[@]}"; do - local sub=$comp - if [ ! -z "${COMP_WORDS[COMP_CWORD]}" ]; then - sub=${comp#${comp_words[$last_idx]}} - if [ "$comp" == "$sub" ]; then - # should not happen since vyatta_completions should be filtered. - continue - fi - fi - if [ -z "$schar" ]; then - schar=${sub:0:1} - else - if [ "$schar" != "${sub:0:1}" ]; then - schar="" - break - fi - fi - done - if [ ! -z "$schar" ]; then - do_help=0 - fi - fi -ENDCOMMENT - - if (( do_help )); then - printf "$vyatta_help_text" - COMPREPLY=( "" " " ) - else - local -a f_comps=() - get_prefix_filtered_list "${COMP_WORDS[COMP_CWORD]}" \ - vyatta_completions f_comps - local estr="COMPREPLY=( " - for w in "${f_comps[@]}"; do - estr="$estr\"$w\" " - done - estr="${estr})" - eval "$estr" - fi - vyatta_help_text="\\nNo help text available" -} - -vyatta_config_complete () -{ - local restore_shopts=$( shopt -p extglob nullglob | tr \\n \; ) - shopt -s extglob nullglob - - if [ "$COMP_LINE" == "$VYATTA_COMP_LINE" ]; then - VYATTA_COMP_LINE='' - vyatta_do_help=1 - else - VYATTA_COMP_LINE=$COMP_LINE - vyatta_do_help=0 - fi - - local command=${COMP_WORDS[0]} - # completion for "set" is different from other commands - is_set=0 - if [ "$command" == "set" ]; then - is_set=1 - fi - local end_space=0 - local num_comp=$COMP_CWORD - if [ -z "${COMP_WORDS[$COMP_CWORD]}" ]; then - end_space=1 - (( num_comp -= 1 )) - fi - (( last_idx = num_comp - 1 )) - comp_words=( ${COMP_WORDS[@]:1:$num_comp} ) - - # handle "exit" - if [ "$command" == "exit" ]; then - if (( num_comp > 1 || ( end_space && num_comp > 0 ) )); then - COMPREPLY=() - return - fi - declare -a hitems=( "discard" ) - declare -a hstrs=( "Discard any changes" ) - generate_help_text hitems hstrs - vyatta_completions=( "discard" ) - vyatta_do_complete - return - fi - - local _mpath=${VYATTA_TEMP_CONFIG_DIR}/${VYATTA_EDIT_LEVEL} - local _tpath=${VYATTA_CONFIG_TEMPLATE}/${VYATTA_TEMPLATE_LEVEL} - local last_tag=0 - local idx=0 - for (( idx=0; idx < num_comp; idx++ )); do - last_tag=0 - local comp=${comp_words[$idx]} - vyatta_escape comp comp - push_path _mpath $comp - push_path _tpath $comp - if [ -d $_tpath ]; then - if (( ! is_set )); then - # we are not in "set" => only allow existing node - if [ ! -d $_mpath ]; then - break - fi - fi - continue - fi - pop_path _tpath - push_path _tpath $VYATTA_TAG_NAME - if [ -d $_tpath ]; then - if (( ! is_set && end_space )); then - # we are not in "set" && last component is complete. - # => only allow existing tag value. - if [ ! -d $_mpath ]; then - break - fi - fi - if (( idx != last_idx )); then - # TODO validate value - # break if not valid - # XXX is this validation necessary? (set will validate anyway) - true - fi - last_tag=1 - continue - fi - pop_path _tpath - pop_path _mpath - break - done - # at the end of the loop, 3 possibilities: - # 1. (idx < last_idx): some component before the last is invalid - # => invalid command - # 2. (idx == last_idx): last component matches neither template nor node.tag - # => if end_space, then invalid command - # otherwise, may be an incomplete (non-tag) component, or incomplete - # "leaf value" - # => try matching dirs in _tpath or value(s) in _mpath/node.val - # 3. (idx == num_comp): the whole command matches templates/tags - if (( idx < last_idx || ( idx == last_idx && end_space ) )); then - # TODO error message? - COMPREPLY=() - return - fi - - declare -a matches - if (( idx == last_idx )); then - # generate possibile matches (dirs in _tpath, and "help" from - # node.def in each dir, or values in _mpath/node.val) - declare -a fmatches - if [ -f $_mpath/node.val ]; then - decho {1a} - get_value_list $_mpath matches - get_prefix_filtered_list ${comp_words[$last_idx]} matches fmatches - append_allowed_values $_tpath fmatches - get_node_value_help $_tpath fmatches - else - decho {1b} - # see if the last component is a new leaf node - fmatches=() - if is_setting_new_leaf $_tpath; then - append_allowed_values $_tpath fmatches - get_node_value_help $_tpath fmatches - else - # last component is a non-value node. look for child nodes. - if (( ! is_set )); then - # not "set". only complete existing nodes. - declare -a amatches=() - get_filtered_dir_listing $_tpath amatches - filter_existing_nodes $_mpath amatches matches - else - get_filtered_dir_listing $_tpath matches - fi - get_prefix_filtered_list ${comp_words[$last_idx]} matches fmatches - get_tmpl_subdir_help $_tpath fmatches - fi - fi - vyatta_completions=( "${fmatches[@]}" ) - vyatta_do_complete - return - fi - - if (( last_tag && end_space )); then - # if not "set", check _mpath (last component is the tag) is valid - # generate possible matches (dirs in _tpath, and "help" from node.def - # in each dir) - decho {2} - if [ $is_set == 1 -o -d $_mpath ]; then - if (( ! is_set )); then - # not "set". only complete existing nodes. - declare -a fmatches=() - get_filtered_dir_listing $_tpath fmatches - filter_existing_nodes $_mpath fmatches matches - else - get_filtered_dir_listing $_tpath matches - fi - get_tmpl_subdir_help $_tpath matches - vyatta_completions=( "${matches[@]}" ) - vyatta_do_complete - return - fi - return - fi - - if (( last_tag && !end_space )); then - # generate possible matches (dirs in _mpath, and "help" from node.def - # in dirs in _tpath) - decho {3} - pop_path _mpath - pop_path _tpath - get_filtered_dir_listing $_mpath matches - declare -a fmatches - get_prefix_filtered_list ${comp_words[$last_idx]} matches fmatches - append_allowed_values $_tpath fmatches - get_node_value_help $_tpath fmatches - vyatta_completions=( "${fmatches[@]}" ) - vyatta_do_complete - return - fi - - if (( !last_tag && end_space )); then - # generate possible matches - # 1. dirs in _tpath, and "help" from node.def in each dir - # 2. value(s) in _mpath/node.val (only if _tpath/node.def is "multi:") - # 3. dirs in _mpath (only if _tpath/node.def is "tag:") - if [ -d $_tpath/node.tag ]; then - # last component is a "tag name". look for tag values. - decho {4a} - get_filtered_dir_listing $_mpath matches - append_allowed_values $_tpath matches - get_node_value_help $_tpath matches - elif [ -f $_mpath/node.val ]; then - # last component is a leaf node. look for values. - decho {4b} - get_value_list $_mpath matches - append_allowed_values $_tpath matches - get_node_value_help $_tpath matches - else - decho {4c} - # see if the last component is a new leaf node - matches=() - if is_setting_new_leaf $_tpath; then - append_allowed_values $_tpath matches - get_node_value_help $_tpath matches - else - # last component is a non-value node. look for child nodes. - if (( ! is_set )); then - # not "set". only complete existing nodes. - declare -a fmatches=() - get_filtered_dir_listing $_tpath fmatches - filter_existing_nodes $_mpath fmatches matches - else - get_filtered_dir_listing $_tpath matches - fi - get_tmpl_subdir_help $_tpath matches - fi - fi - vyatta_completions=( "${matches[@]}" ) - vyatta_do_complete - return - fi - - if (( !last_tag && !end_space )); then - # generate possible matches (dirs in _tpath, and "help" from node.def - # in each dir) - decho {5} - pop_path _tpath - get_filtered_dir_listing $_tpath matches - declare -a fmatches - get_prefix_filtered_list ${comp_words[$last_idx]} matches fmatches - get_tmpl_subdir_help $_tpath fmatches - vyatta_completions=( "${fmatches[@]}" ) - vyatta_do_complete - return - fi - - eval $restore_shopts -} - -DEF_GROUP=quaggavty -make_vyatta_config_dir () -{ - sudo mkdir -m 0775 -p $1 - sudo chgrp ${DEF_GROUP} $1 -} - -make_vyatta_config_dir $VYATTA_ACTIVE_CONFIGURATION_DIR -make_vyatta_config_dir $VYATTA_CHANGES_ONLY_DIR -make_vyatta_config_dir $VYATTA_CONFIG_TMP -if [ ! -d $VYATTA_TEMP_CONFIG_DIR ]; then - make_vyatta_config_dir $VYATTA_TEMP_CONFIG_DIR - sudo mount -t unionfs -o dirs=${VYATTA_CHANGES_ONLY_DIR}=rw:/opt/vyatta/config/active=ro unionfs ${VYATTA_TEMP_CONFIG_DIR} -fi - -# disallow 'Ctrl-D' exit, since we need special actions on 'exit' -set -o ignoreeof 1 - -set_config_ps1 '' -alias commit=/opt/vyatta/sbin/my_commit -alias set=/opt/vyatta/sbin/my_set -alias delete=/opt/vyatta/sbin/my_delete - -export VYATTA_COMP_LINE="" - -# readline bindings -bind 'set show-all-if-ambiguous on' -if ! bind -p |grep -q '\\C-x\\C-t'; then - bind '"\C-x\C-t": kill-region' -fi -if ! bind -p |grep -q '\\C-x\\C-o'; then - bind '"\C-x\C-o": copy-region-as-kill' -fi - -complete -F vyatta_config_complete set -complete -F vyatta_config_complete delete -complete -F vyatta_config_complete show -complete -F vyatta_config_complete edit -complete -F vyatta_config_complete exit - -- cgit v1.2.3