]> git.ipfire.org Git - people/stevee/network.git/commitdiff
Add bash-completion for the network command
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 30 Dec 2014 01:30:40 +0000 (01:30 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 30 Dec 2014 01:30:40 +0000 (01:30 +0000)
Makefile.am
src/bash-completion/network [new file with mode: 0644]
src/functions/functions.hook
src/functions/functions.ports
src/functions/functions.settings
src/network

index 96d59e42ac10866fd6c01bf63e782b4fa65877e7..8a5e4adff3ae04b2e9494eb22670caefe2a05410 100644 (file)
@@ -28,6 +28,7 @@ AUTOMAKE_OPTIONS = color-tests
 # keep itermediate files
 .SECONDARY:
 
+bashcompletiondir= $(datadir)/bash-completion/completions
 libexecdir       = $(prefix)/lib
 pkgconfigdatadir = $(datadir)/pkgconfig
 pppdir           = $(sysconfdir)/ppp
@@ -261,6 +262,11 @@ dist_sysctl_DATA = \
 
 # ------------------------------------------------------------------------------
 
+dist_bashcompletion_SCRIPTS = \
+       src/bash-completion/network
+
+# ------------------------------------------------------------------------------
+
 dist_tmpfiles_DATA = \
        src/tmpfiles/network
 
diff --git a/src/bash-completion/network b/src/bash-completion/network
new file mode 100644 (file)
index 0000000..ad6bd95
--- /dev/null
@@ -0,0 +1,282 @@
+#!/bin/bash
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2014 Michael Tremer                                           #
+#                                                                             #
+# 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/>.       #
+#                                                                             #
+###############################################################################
+# network(8) completion
+
+function _network_find_on_cmdline () {
+       local word subcommand c=0
+       while [ ${c} -lt ${cword} ]; do
+               word="${words[c]}"
+               for subcommand in ${1}; do
+                       if [ "${subcommand}" = "${word}" ]; then
+                               echo "${subcommand}"
+                               return
+                       fi
+               done
+               ((c++))
+       done
+}
+
+function _network_complete_hooks() {
+       local type="${1}"
+
+       COMPREPLY=( $(compgen -W "$(network raw list-hooks "${type}")" -- "${cur}") )
+}
+
+function _network_complete_ports() {
+       COMPREPLY=( $(compgen -W "$(network raw list-ports)" -- "${cur}") )
+}
+
+function _network_complete_zones() {
+       COMPREPLY=( $(compgen -W "$(network raw list-zones)" -- "${cur}") )
+}
+
+function _network_device() {
+       local words=( $@ )
+
+       local commands="list $(network raw list-devices)"
+       local cmd="$(_network_find_on_cmdline "${commands}")"
+       if [[ -z "${cmd}" ]]; then
+               COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") )
+               return 0
+       fi
+
+       local args="${words[@]:1}"
+       case "${cmd}" in
+               list)
+                       return 0
+                       ;;
+               *)
+                       _network_device_subcommand ${args}
+                       ;;
+       esac
+}
+
+function _network_device_subcommand() {
+       local words=( $@ )
+
+       local commands="discover monitor status unlock ussd"
+       local cmd="$(_network_find_on_cmdline "${commands}")"
+
+       if [[ -z "${cmd}" ]]; then
+               COMPREPLY=( $(compgen -W "discover monitor status unlock ussd" \
+                       -- "${cur}") )
+               return 0
+       fi
+                       
+       case "${cmd}" in
+               ussd)
+                       # TODO
+                       ;;
+       esac
+}
+
+function _network_port() {
+       local words=( $@ )
+
+       local commands="new destroy $(network raw list-ports)"
+       local cmd="$(_network_find_on_cmdline "${commands}")"
+       if [[ -z "${cmd}" ]]; then
+               COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") )
+               return 0
+       fi
+
+       local args="${words[@]:1}"
+       case "${cmd}" in
+               new)
+                       _network_complete_hooks "port"
+                       ;;
+               destroy)
+                       _network_complete_ports
+                       ;;
+               *)
+                       local args="${words[@]:1}"
+                       _network_port_subcommand ${args}
+                       ;;
+       esac
+}
+
+function _network_port_subcommand() {
+       local words=( $@ )
+
+       local commands="create down edit remove status up"
+       local cmd="$(_network_find_on_cmdline "${commands}")"
+       if [[ -z "${cmd}" ]]; then
+               COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") )
+               return 0
+       fi
+}
+
+function _network_settings() {
+       local words=( $@ )
+
+       local key keys
+       for key in $(network raw list-settings); do
+               keys="${keys} ${key}="
+       done
+       COMPREPLY=( $(compgen -W "${keys}" -- "${cur}") )
+}
+
+function _network_zone() {
+       local words=( $@ )
+
+       local commands="new destroy $(network raw list-zones)"
+       local cmd="$(_network_find_on_cmdline "${commands}")"
+       if [[ -z "${cmd}" ]]; then
+               COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") )
+               return 0
+       fi
+
+       local args="${words[@]:1}"
+       case "${cmd}" in
+               new)
+                       # TODO
+                       return 0
+                       ;;
+               destroy)
+                       _network_complete_zones
+                       ;;
+               *)
+                       local zone="${cmd}"
+                       local args="${words[@]:1}"
+                       _network_zone_subcommand "${zone}" ${args}
+                       ;;
+       esac
+}
+
+function _network_zone_subcommand() {
+       local zone="${1}"
+       shift
+
+       local words=( $@ )
+
+       local commands="config disable down edit enable port status up"
+       local cmd="$(_network_find_on_cmdline "${commands}")"
+       if [[ -z "${cmd}" ]]; then
+               COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") )
+               return 0
+       fi
+                       
+       local args="${words[@]:1}"
+       case "${cmd}" in
+               config)
+                       # TODO
+                       ;;
+               port)
+                       _network_zone_subcommand_port "${zone}" ${args}
+                       ;;
+       esac
+}
+
+function _network_zone_subcommand_port() {
+       local zone="${1}"
+       shift
+
+       local words=( $@ )
+
+       local commands="attach detach $(network raw list-ports-of-zone "${zone}")"
+       local cmd="$(_network_find_on_cmdline "${commands}")"
+       if [[ -z "${cmd}" ]]; then
+               COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") )
+               return 0
+       fi
+
+       case "${cmd}" in
+               attach)
+                       COMPREPLY=( $(compgen -W "$(network raw list-free-ports "${zone}")" \
+                               -- "${cur}") )
+                       ;;
+               detach)
+                       COMPREPLY=( $(compgen -W "$(network raw list-ports-of-zone "${zone}")" \
+                               -- "${cur}") )
+                       ;;
+               *)
+                       local port="${cmd}"
+                       local args="${words[@]:1}"
+                       _network_zone_subcommand_port_subcommand "${zone}" "${port}" ${args}
+                       ;;
+       esac
+}
+
+function _network_zone_subcommand_port_subcommand() {
+       local zone="${1}"
+       local port="${2}"
+       shift 2
+
+       local words=( $@ )
+
+       local commands="edit"
+       local cmd="$(_network_find_on_cmdline "${commands}")"
+       if [[ -z "${cmd}" ]]; then
+               COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") )
+               return 0
+       fi
+
+       case "${cmd}" in
+               edit)
+                       # TODO auto-complete the zone-port hook
+                       ;;
+       esac
+}
+
+function _network() {
+       local cur prev words cword
+       _init_completion || return
+
+       local cmd i
+       for (( i=1; i < ${#words[@]} - 1; i++ )); do
+               [[ "${words[i]}" = -* ]] && continue
+               cmd="${words[i]}" && break
+       done
+
+       if [[ -z "${cmd}" ]]; then
+               case "${cur}" in
+                       -*)
+                               COMPREPLY=( $(compgen -W "--debug" -- "${cur}") )
+                               ;;
+                       *)
+                               COMPREPLY=( $(compgen -W "device hostname port settings status zone" \
+                                       -- "${cur}") )
+                               ;;
+               esac
+
+               return 0
+       fi
+
+       local args="${words[@]:i+1}"
+       case "${cmd}" in
+               device)
+                       _network_device ${args}
+                       ;;
+               port)
+                       _network_port ${args}
+                       ;;
+               settings)
+                       _network_settings ${args}
+                       ;;
+               start|stop|status)
+                       # start, stop and status optionally take a zone
+                       _network_complete_zones
+                       ;;
+               zone)
+                       _network_zone ${args}
+                       ;;
+       esac
+} && complete -F _network network
index 90532973e083dc973ae1b9824cea6b6e001687eb..f8e2b6b5f02a465cd72ad2c3d2cc59f64782d7c8 100644 (file)
@@ -30,6 +30,22 @@ function hook_dir() {
 }
 NETWORK_HOOKS_DIR_ZONES="$(hook_dir zone)"
 
+function hook_list() {
+       local type="${1}"
+       assert isoneof type port zone
+
+       local dir="$(hook_dir "${type}")"
+       assert isset dir
+
+       local hook
+       for hook in ${dir}/*; do
+               hook_exists "${hook}" || continue
+               print "${hook}"
+       done
+
+       return ${EXIT_OK}
+}
+
 function hook_exists() {
        local type=${1}
        local hook=${2}
index a63709135423278babc2f45fad53b0fbee10f82c..059b8f243015aa5b7865ffa8e534a95a351fc5ec 100644 (file)
@@ -23,6 +23,47 @@ function port_dir() {
        echo "${NETWORK_CONFIG_DIR}/ports"
 }
 
+function port_list() {
+       local port
+       for port in $(port_dir)/*; do
+               port="$(basename "${port}")"
+               if port_exists "${port}"; then
+                       print "${port}"
+               fi
+       done
+}
+
+function port_list_in_use() {
+       local ports_in_use
+
+       # Collect all ports that are attached to a zone
+       local zone
+       for zone in $(zones_get_all); do
+               list_append ports_in_use $(zone_get_ports "${zone}")
+       done
+
+       # Collect all ports that are enslaved by an other port
+       local port
+       for port in $(port_list); do
+               list_append ports_in_use $(port_get_slaves "${port}")
+       done
+
+       list_sort ${ports_in_use}
+}
+
+function port_list_free() {
+       local ports_in_use="$(port_list_in_use)"
+
+       local port
+       for port in $(port_list); do
+               if ! list_match "${port}" ${ports_in_use}; then
+                       print "${port}"
+               fi
+       done
+
+       return ${EXIT_OK}
+}
+
 function port_get_hook() {
        local port=${1}
        assert isset port
@@ -65,13 +106,7 @@ function port_settings_write() {
 }
 
 function ports_get_all() {
-       local port
-
-       for port in $(port_dir)/*; do
-               [ -f "${port}" ] || continue
-
-               basename ${port}
-       done
+       port_list
 }
 
 function port_file() {
index 2f2821ff0e1a7f168b721b4a38f65010c185c64c..9e78858f0f54ab7039bff9d52ae29742d14b44d7 100644 (file)
@@ -263,6 +263,10 @@ function network_settings_print() {
        settings_print ${NETWORK_SETTINGS_FILE_PARAMS}
 }
 
+function network_settings_list() {
+       print "${NETWORK_SETTINGS_FILE_PARAMS}"
+}
+
 function firewall_settings_read() {
        settings_read "${FIREWALL_SETTINGS_FILE}" "${FIREWALL_SETTINGS_PARAMS}"
 }
index 80ddae0dfe1976a498a7d66c70d87f3d16c14860..ebd1b5c2912ac3dd922a14340c26ba03dc42eb8b 100644 (file)
@@ -1244,6 +1244,42 @@ function cli_dns_server() {
        exit ${EXIT_OK}
 }
 
+function cli_raw() {
+       local cmd="${1}"
+       assert isset cmd
+       shift
+
+       case "${cmd}" in
+               list-devices)
+                       device_list
+                       ;;
+               list-free-ports)
+                       port_list_free
+                       ;;
+               list-hooks)
+                       hook_list $@
+                       ;;
+               list-ports)
+                       port_list
+                       ;;
+               list-ports-of-zone)
+                       zone_get_ports $@
+                       ;;
+               list-settings)
+                       network_settings_list
+                       ;;
+               list-zones)
+                       zones_get_all
+                       ;;
+               *)
+                       error "No such command: ${cmd}"
+                       exit ${EXIT_ERROR}
+                       ;;
+       esac
+
+       exit ${EXIT_OK}
+}
+
 # Process the given action
 case "${action}" in
        init)
@@ -1268,6 +1304,10 @@ case "${action}" in
                cli_help $@
                ;;
 
+       raw)
+               cli_raw $@
+               ;;
+
        *)
                error "Invalid command given: ${action}"
                cli_usage "network help"