#compdef networksetup # Notes: # - Inconsistent option capitalisation is intentional; see networksetup(1) # - Options related to user/log-in/system profiles are omitted, since they no # longer function (despite appearing in the manual) # - Each d/p/s could list associated d/p/s in the descriptions # - Options that take multiple devices/services (e.g. -createBond) could exclude # those previously specified on the command line # - Bond, PPPoE, and VLAN functionality couldn't be tested; some option- # arguments aren't completed (-deleteBond, -deleteVLAN, ...) # - -createpppoeservice arguments in particular may not be right # Complete network devices (( $+functions[_networksetup_devices] )) || _networksetup_devices() { local -a expl tmp tmp=( ${(f)"$( _call_program network-devices $words[1] -listallhardwareports )"} ) tmp=( ${(@M)tmp##Device:*} ) tmp=( ${(@)tmp##Device:[[:space:]]##} ) _wanted -x devices expl 'network device' compadd -a "$@" - tmp } # Complete network locations (( $+functions[_networksetup_locations] )) || _networksetup_locations() { local -a expl tmp tmp=( ${(f)"$( _call_program network-locations $words[1] -listlocations )"} ) _wanted -x locations expl 'network location' compadd -a "$@" - tmp } # Complete hardware ports (( $+functions[_networksetup_ports] )) || _networksetup_ports() { local -a expl tmp tmp=( ${(f)"$( _call_program hardware-ports $words[1] -listallhardwareports )"} ) tmp=( ${(@M)tmp##Hardware Port:*} ) tmp=( ${(@)tmp##Hardware Port:[[:space:]]##} ) _wanted -x ports expl 'hardware port' compadd -a "$@" - tmp } # Complete network services (( $+functions[_networksetup_services] )) || _networksetup_services() { local -a expl tmp tmp=( ${(f)"$( _call_program network-services $words[1] -listallnetworkservices )"} ) # The command output doesn't distinguish between a leading asterisk used to # indicate an inactive service and one that's just used in the service name # itself... but the latter scenario seems uncommon, so we'll assume it's # always the former tmp=( ${(@)tmp#\*} ) # The first line is an explanation of the asterisk thing; skip it tmp=( ${(@)tmp[2,-1]} ) _wanted -x services expl 'network service' compadd -a "$@" - tmp } # Complete Wi-Fi networks — this function expects the final argument to be the # name of a wireless device (pre-escaped, as if taken from $words) (( $+functions[_networksetup_wifi_networks] )) || _networksetup_wifi_networks() { local -a expl tmp tmp=( ${(f)"$( _call_program wifi-networks $words[1] \ -listpreferredwirelessnetworks ${(q-)@[-1]} )"} ) # Lines with Wi-Fi networks on them are prefixed by white space tmp=( ${(@M)tmp##[[:space:]]*} ) tmp=( ${(@)tmp##[[:space:]]##} ) shift -p # Discard device argument _wanted -x wifi-networks expl 'Wi-Fi network' compadd -a "$@" - tmp } _networksetup() { local i j ret=1 local -a context line state state_descr args tmp local -A opt_args val_args proxies args=( + '(cmd)' '-addDeviceToBond[add specified device/port to bond]: :->dp: :->b' '-addpreferredwirelessnetworkatindex[add preferred Wi-Fi network for specified device]: :->d: :->w:*::: :->wifi-idx-info' '-connectpppoeservice[connect specified PPPoE service]: :->P' '-create6to4service[create new 6to4 service]:6to4 service name' '-createBond[create bond with specified devices/ports]:bond name: :*: :->dp' '-createlocation[create new network location]:network location name: :*: :->s' '-createnetworkservice[create new network service on specified device/port]: :->dp:network service name' '-createpppoeservice[create new PPPoE service on specified device/port]: :->dp: :->s:PPPoE account name: :PPPoE password: :PPPoE service name' '-createVLAN[create VLAN on specified device/port]:VLAN name: : :->dp:VLAN tag' '-deleteBond[delete specified bond]: :->b' '-deletelocation[delete specified network location]: :->l' '-deletepppoeservice[delete specified PPPoE service]: :->P' '-deleteVLAN[delete VLAN from specified device/port]:VLAN name: : :->dp:VLAN tag' '-detectnewhardware[detect new network hardware]' '-disconnectpppoeservice[disconnect specified PPPoE service]: :->P' '-duplicatenetworkservice[duplicate specified network service]: :->s:network service name' '-getadditionalroutes[list additional IPv4 routes for specified network service]: :->s' '-getairportnetwork[display Wi-Fi network for specified device]: :->d' '-getairportpower[display Wi-Fi power state for specified device]: :->d' '-getautoproxyurl[display proxy auto-config URL for specified network service]: :->s' '-getv6additionalroutes[list additional IPv6 routes for specified network service]: :->s' '-getcomputername[display computer name]' '-getcurrentlocation[display current network location]' '-getdnsservers[display DNS info for specified network service]: :->s' '-getinfo[display info for specified network service]: :->s' '-getmacaddress[display MAC address for specified device/port]: :->dp' '-getMedia[display media for specified device/port]: :->dp' '-getMTU[display MTU for specified device/port]: :->dp' '-getnetworkserviceenabled[get enabled state for specified network service]: :->s' '-getpassiveftp[display passive FTP state for specified network service]: :->s' '-getproxyautodiscovery[display proxy auto-discovery state for specified network service]: :->s' '-getproxybypassdomains[display proxy bypass domains for specified network service]: :->s' '-getsearchdomains[display DNS search domains for specified network service]: :->s' '-help[display help information]' '-isBondSupported[display whether device/port can be added to a bond]: :->dp' '-listallhardwareports[list hardware ports]' '-listallnetworkservices[list network services]' '-listBonds[list bonds]' '-listdevicesthatsupportVLAN[list devices that support VLANs]' '-listlocations[list network locations]' '-listnetworkserviceorder[list network services and their devices/ports in order]' '-listpreferredwirelessnetworks[list preferred Wi-Fi networks for the specified device]: :->d' '-listpppoeservices[list PPPoE services]' '-listValidMedia[list valid media for specified device/port]: :->dp' '-listValidMTURange[display valid MTU range for specified device/port]: :->dp' '-listVLANs[list VLANs]' '-ordernetworkservices[set network service order]:*: :->s' '-printcommands[list commands]' '-removeallpreferredwirelessnetwork[remove all preferred Wi-Fi networks from specified device]: :->d' '-removeDeviceFromBond[remove specified device/port from bond]: :->dp: :->b' '-removenetworkservice[remove specified network service]: :->s' '-removepreferredwirelessnetwork[remove preferred Wi-Fi network from specified device]: :->d: :->w' '-renamenetworkservice[rename specified network service]: :->s:network service name' '-set6to4automatic[set specified 6to4 service to get relay address automatically]:6to4 service:->s' '-set6to4manual[set specified 6to4 service to use manual relay address]:6to4 service:->s:relay address' '-setadditionalroutes[set additional IPv4 routes for specified network service]: :->s:*::: :->routes-v4' '-setairportnetwork[set Wi-Fi network for specified device]: :->d: :->w:Wi-Fi network password' '-setairportpower[set Wi-Fi power state for specified device]: :->d:Wi-Fi power state:(on off)' '-setautoproxyurl[set proxy auto-config URL for specified network service]: :->s:proxy auto-config URL:_urls' '-setcomputername[set computer name]:computer name' '-setbootp[set specified network service to use BOOTP]: :->s' '-setdhcp[set specified network service to use DHCP]: :->s:client ID (optional)' '-setdnsservers[set DNS servers for specified network service]: :->s:*:DNS server address' '-setmanual[set specified network service to use manual IPv4 IP/subnet/router]: :->s:IP address: :subnet mask: :router address' '-setmanualwithdhcprouter[set specified network service to use DHCP with manual IP]: :->s:IP address' '-setMedia[set media for specified device/port]: :->dp: :->media:*:media option' '-setMTU[set MTU for specified device/port]: :->dp: :->mtu' '-setMTUAndMediaAutomatically[set specified device/port to automatically set MTU and media type]: :->dp' '-setnetworkserviceenabled[set enabled state for specified network service]: :->s:network service enabled state:(on off)' '-setpassiveftp[set passive FTP state for specified network service]: :->s:passive FTP state:(on off)' '-setpppoeaccountname[set account name for specified PPPoE service]: :->P:PPPoE account name' '-setpppoepassword[set password for specified PPPoE service]: :->P:PPPoE password' '-setproxyautodiscovery[set proxy auto-discovery state for specified network service]: :->s:proxy auto-discovery state:(on off)' '-setproxybypassdomains[set proxy bypass domains for specified network service]: :->s:*:proxy bypass domain' '-setsearchdomains[set DNS search domains for specified network service]: :->s:*:DNS search domain' '-setv6additionalroutes[set additional IPv6 routes for specified network service]: :->s:*::: :->routes-v6' '-setv4automatic[set specified network service to get IPv4 address automatically]: :->s' '-setv6automatic[set specified network service to get IPv6 address automatically]: :->s' '-setv6linklocal[set specified network service to use link-local address only for IPv6]: :->s' '-setv6manual[set specified network service to use manual IPv6 IP/prefix/router]: :->s:IP address: :prefix length: :router address' '-setv4off[disable IPv4 for specified network service]: :->s' '-setv6off[disable IPv6 for specified network service]: :->s' '-showBondStatus[display status for specified bond]: :->b' '-showpppoestatus[display status for specified PPPoE service]: :->P' '-switchtolocation[switch to specified network location]: :->l' ) proxies=( ftp FTP gopher Gopher socks SOCKS secureweb HTTPS streaming RTSP web HTTP ) for i j in ${(kv)proxies}; do args+=( "-get${i}proxy[display $j proxy info for specified network service]: :->s" "-set${i}proxy[set $j proxy info for specified network service]: :->s:*::: :->proxy-info" "-set${i}proxystate[set $j proxy state for specified network service]: :->s:proxy state:(on off)" ) done _arguments : $args && ret=0 case $state in b) _message -e bonds 'interface bond' && ret=0 ;; d) _networksetup_devices && ret=0 ;; l) _networksetup_locations && ret=0 ;; p) _networksetup_ports && ret=0 ;; P) _message -e pppoe-services 'PPPoE service' && ret=0 ;; s) _networksetup_services && ret=0 ;; dp) _alternative \ 'devices::_networksetup_devices' \ 'ports::_networksetup_ports' \ && ret=0 ;; dps) _alternative \ 'devices::_networksetup_devices' \ 'ports::_networksetup_ports' \ 'services::_networksetup_services' \ && ret=0 ;; ps) _alternative \ 'ports::_networksetup_ports' \ 'services::_networksetup_services' \ && ret=0 ;; w) # Wi-Fi network always follows device/port on command line _networksetup_wifi_networks $words[(CURRENT - 1)] && ret=0 ;; media) # Media type always follows device/port on command line tmp=( ${(f)"$( _call_program media-types $words[1] \ -listValidMedia $words[(CURRENT - 1)] )"} ) tmp=( ${tmp##\**} ) # Error message if (( $#tmp )); then _describe -t media-types 'media type' tmp && ret=0 else _message -e media-types 'media type' && ret=0 fi ;; mtu) # MTU value always follows device/port on command line tmp=( ${(f)"$( _call_program mtu-ranges $words[1] \ -listValidMTURange $words[(CURRENT - 1)] )"} ) tmp=( ${(M)tmp##Valid MTU Range:*} ) tmp=( ${tmp##*:[[:space:]]#} ) _message -e mtu-value "MTU value${tmp:+ (${tmp})}" && ret=0 ;; proxy-info) (( CURRENT > 5 )) || case $(( CURRENT % 5 )) in 1) _message -e hosts 'proxy server address' && ret=0 ;; 2) _message -e ports 'proxy port number' && ret=0 ;; 3) _values 'authenticated proxy support' on off && ret=0 ;; 4) [[ $words[(CURRENT - 1)] == on ]] && _message -e users 'proxy user name' && ret=0 ;; 0) [[ $words[(CURRENT - 2)] == on ]] && _message -e passwords 'proxy password' && ret=0 ;; esac ;; routes-v4) case $(( CURRENT % 3 )) in 1) _message -e addresses 'destination address' && ret=0 ;; 2) _message -e masks 'subnet mask' && ret=0 ;; 0) _message -e addresses 'router address' && ret=0 ;; esac ;; routes-v6) case $(( CURRENT % 3 )) in 1) _message -e addresses 'destination address' && ret=0 ;; 2) _message -e prefixes 'prefix length' && ret=0 ;; 0) _message -e addresses 'router address' && ret=0 ;; esac ;; wifi-idx-info) (( CURRENT > 3 )) || case $(( CURRENT % 3 )) in 1) _message -e wifi-indexes 'index in preferred Wi-Fi networks list' && ret=0 ;; 2) tmp=( 'OPEN:none (unsecured)' 'WPA:WPA Personal' 'WPA2:WPA2 Personal' 'WPA/WPA2:WPA/WPA2 Personal' 'WPAE:WPA Enterprise' 'WPA2E:WPA2 Enterprise' 'WPAE/WPA2E:WPA/WPA2 Enterprise' 'WEP:plain WEP' '8021XWEP:802.1X WEP' ) _describe -t security-types 'Wi-Fi network security type' tmp && ret=0 ;; 0) [[ ${(U)words[(CURRENT - 1)]} != OPEN ]] && _message -e passwords 'Wi-Fi network password' && ret=0 ;; esac ;; esac return ret } _networksetup "$@"