# OpenVPN 3 Linux client -- Next generation OpenVPN client # # SPDX-License-Identifier: AGPL-3.0-only # # Copyright (C) 2018 - 2023 OpenVPN Inc # Copyright (C) 2018 - 2023 David Sommerseth # ## # @file bash_completion_openvpn3 # # @brief A bash_completion helper script for the openvpn3 command line # programs. This script makes use of the shell-completion command # provided by openvpn3 or openvpn3-admin, which provides up-to-date # insight on the various commands, options and arguments. # # Also works with zsh after loading bascomphinit # (autoload -U +X bashcompinit && bashcompinit) _openvpn3_generic_completion() { local cmd first cur prev opts base COMPREPLY=() cmd="$1" first=${COMP_WORDS[1]} cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" o3cmds="" if [ "${cur:0:2}" != "--" -a "${cur:0:1}" != "-" ]; then o3cmds="$($cmd shell-completion --list-commands)" fi selopts="" echo "$o3cmds" | tr ' ' '\n' | grep -v "version" | grep -qE "^$cur$" if [ $? -eq 0 ]; then # All commands except 'version' takes at least one option. # If the requested command is not "version", attach the '--' now COMPREPLY=( "$first --") elif [ $COMP_CWORD -eq 1 ]; then # The first argument is always an openvpn3 command # and it never starts with - or -- COMPREPLY=( $( compgen -W "$o3cmds" $cur ) ) elif [ $COMP_CWORD -gt 1 ]; then if [ "${cur:0:2}" == "--" -o "${cur:0:1}" == "-" ]; then # If the argument starts with '-' or '--' provide list of options comp_op="-W" selopts="$($cmd shell-completion --list-options $first)" else # Some options can get some extra help from bash case "${prev}" in "--config") # Takes configuration profile names and file names # Prepare a simple filter, providing partial matching filter="cat" # by default everything passes if [ -n "$cur" ]; then filter="grep -E ^$cur" fi comp_op="-W" if [ "config-import" = "${first}" -o "session-start" = "${first}" ]; then # Only list files which most likely are OpenVPN configuration files selopts="$(grep -sm1 -E '(client|remote |port |lport |rport |key |cert |ca )' ${cur}*.conf ${cur}*.ovpn | cut -d: -f1 | $filter | tr '\n' ' ')" # Add directories too, but ignore those starting with '.{some-alpha-num-letters}' selopts="$(compgen -d -- $cur | sed 's#$#/#' | grep -vE '^\.\w+' | tr '\n' ' ') $selopts" fi # In addition, extend with all pre-loaded configurations selopts="$($cmd shell-completion --list-options $first --arg-help $prev) $selopts" ;; "--grant"|"--revoke") # Takes username (or UID, which we don't tackle here) comp_op="-u" selopts="" ;; *) # Otherwise try to fill out with possible argument values for the # provided option comp_op="-W" arghelp="$prev" if [ "$cur" == "=" ]; then arghelp="$prev$cur" fi if [ -n "$first" -a -z "${cur}" -a -z "${selopts}" ]; then selopts="--" else selopts="$($cmd shell-completion --list-options $first --arg-help $arghelp)" fi ;; esac fi if [ "$cur" == "=" ]; then cur="" fi COMPREPLY=( $( compgen ${comp_op} "${selopts}" -- $cur ) ) fi } _openvpn3_completion() { _openvpn3_generic_completion openvpn3 } complete -F _openvpn3_completion -o nospace openvpn3 _openvpn3admin_completion() { _openvpn3_generic_completion openvpn3-admin } complete -F _openvpn3admin_completion -o nospace openvpn3-admin