--- /dev/null
+#!/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