#!/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 . # # # ############################################################################### # network(8) completion _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 } _network_complete_hooks() { local type="${1}" COMPREPLY=( $(compgen -W "$(network raw list-hooks "${type}")" -- "${cur}") ) } _network_complete_ports() { COMPREPLY=( $(compgen -W "$(network raw list-ports)" -- "${cur}") ) } _network_complete_zones() { COMPREPLY=( $(compgen -W "$(network raw list-zones)" -- "${cur}") ) } _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 } _network_device_subcommand() { local words=( $@ ) local commands="discover identify monitor status unlock ussd" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi case "${cmd}" in ussd) # TODO ;; esac } _network_dhcpd() { local proto="${1}" shift local words=( $@ ) local commands="edit reload restart show start stop subnet" 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 subnet) _network_dhcpd_subnet "${proto}" ${args} ;; esac } _network_dhcpd_subnet() { local proto="${1}" shift local words=( $@ ) local commands="new remove show $(network raw list-dhcpd-subnets "${proto}")" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi local subnet="${words[0]}" local args="${words[@]:1}" case "${cmd}" in new) : # TODO ;; remove) : # TODO ;; [0-9]*) _network_dhcpd_subnet_subcommand "${proto}" "${subnet}" ${args} ;; esac } _network_dhcpd_subnet_subcommand() { local proto="${1}" local subnet="${2}" shift 2 local words=( $@ ) local commands="edit options range show" 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 edit) : # TODO ;; options) _network_dhcpd_subnet_subcommand_options "${proto}" "${subnet}" ${args} ;; range) _network_dhcpd_subnet_subcommand_range "${proto}" "${subnet}" ${args} ;; esac } _network_dhcpd_subnet_subcommand_options() { local proto="${1}" local subnet="${2}" shift 2 local options option for option in $(network raw list-dhcpd-subnet-options "${proto}"); do options="${options} ${option}=" done COMPREPLY=( $(compgen -W "${options}" -- "${cur}") ) } _network_dhcpd_subnet_subcommand_range() { local proto="${1}" local subnet="${2}" shift 2 local words=( $@ ) local commands="new remove" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi case "${cmd}" in new) COMPREPLY=( $(compgen -W "--end= --start=" -- "${cur}") ) ;; remove) COMPREPLY=( $(compgen -W "$(network raw list-dhcpd-ranges-of-subnet "${proto}" "${subnet}")" \ -- "${cur}") ) ;; esac } _network_dns_server() { local words=( $@ ) local commands="add list remove update" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi case "${cmd}" in remove) COMPREPLY=( $(compgen -W "$(network raw list-dns-servers)" \ -- "${cur}") ) ;; esac } _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 } _network_port_subcommand() { local words=( $@ ) local commands="create down edit identify remove status up" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi } _network_route() { local words=( $@ ) local commands="static" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi case "${cmd}" in static) local args="${words[@]}" _network_route_static ${args} ;; esac } _network_route_static() { local words=( $@ ) local commands="add list remove reload" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi case "${cmd}" in add) if [[ "${cur}" = -* ]]; then COMPREPLY=( $(compgen -W "--blackhole --gateway= --mtu= \ --prohibit --unreachable" -- "${cur}") ) fi ;; list) # TODO auto-complete options like --protocol here COMPREPLY=( $(compgen -W "--protocol=" -- "${cur}") ) ;; esac } _network_settings() { local words=( $@ ) local key keys for key in $(network raw list-settings); do keys="${keys} ${key}=" done COMPREPLY=( $(compgen -W "${keys}" -- "${cur}") ) } _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 } _network_zone_subcommand() { local zone="${1}" shift local words=( $@ ) local commands="config disable down edit enable identify port rename 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) _network_zone_subcommand_config "${zone}" ${args} ;; port) _network_zone_subcommand_port "${zone}" ${args} ;; esac } _network_zone_subcommand_config() { local zone="${1}" shift local words=( $@ ) local commands="new destroy" local cmd="$(_network_find_on_cmdline "${commands}")" if [[ -z "${cmd}" ]]; then COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") ) return 0 fi case "${cmd}" in new) _network_complete_hooks "config" ;; esac } _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 } _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 } _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 dhcpv4 dhcpv6 dns-server \ help hostname port reset route settings status zone" \ -- "${cur}") ) ;; esac return 0 fi local args="${words[@]:i+1}" case "${cmd}" in device) _network_device ${args} ;; dhcpv[64]) _network_dhcpd "${cmd/dhcpv/ipv}" ${args} ;; dns-server) _network_dns_server ${args} ;; port) _network_port ${args} ;; route) _network_route ${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