about summary refs log tree commit diff
path: root/Completion/Darwin/Command/_networksetup
blob: 85a91e893ed2b04794a4e1651ebd9fa1789e7076 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
#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 "$@"