From 3fbb80b1d3581066f423e8240587cbc3f750861a Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Fri, 25 Aug 2017 15:20:10 +0200 Subject: 41601: handle system differences in arp completion and add function for route --- ChangeLog | 4 + Completion/Unix/Command/_arp | 110 +++++++++++++++--- Completion/Unix/Command/_route | 254 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 353 insertions(+), 15 deletions(-) create mode 100644 Completion/Unix/Command/_route diff --git a/ChangeLog b/ChangeLog index ed463e905..377b390a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2017-08-25 Oliver Kiddle + * 41601: Completion/Unix/Command/_arp, + Completion/Unix/Command/_route: handle system differences + in arp completion and add function for route + * 41600: Completion/Unix/Command/_mpc: fix quoting of songs for completion and avoid sending errors to stderr diff --git a/Completion/Unix/Command/_arp b/Completion/Unix/Command/_arp index f340e979e..80e829022 100644 --- a/Completion/Unix/Command/_arp +++ b/Completion/Unix/Command/_arp @@ -1,23 +1,103 @@ #compdef arp local state line expl curcontext="$curcontext" ret=1 -local -a cmds +typeset -A opt_args +local -a cmds args -cmds=(-a --display -d --delete -s --set -f --file) +flags=( temp pub ) +cmds=( + '(2 3)-a[show entries for all hosts]' + '(2 -d)-d[delete entry from table]' + '(-n -v)-s[create an arp entry]' + '(2 3 -n -v)-f[read multiple entries from file]' +) +args=( '-n[show numeric addresses]' ) +vopt='-v[be verbose]' -_arguments -C \ - "($cmds 1 -D --use-device)"{-a,--display}'[show entries for all or specified hosts]:host:->hostintable' \ - "($cmds 1 -n --numeric -D --use-device -H --hw-type)"{-d,--delete}'[delete entry from table]:host:->hostintable' \ - "($cmds 1 -n --numeric)"{-s,--set}'[create an ARP entry]:host:_hosts:ethernet address::*:option:(temp trail pub)' \ - "($cmds 1 -n --numeric)"{-f,--file}'[read multiple entries from file]:file:_files' \ - '(-i --device)'{-i,--device}'[select an interface]:::_net_interfaces:' \ - '(-D --use-device -a --display -d --delete)'{-D,--use-device}"[use the interface ifa's hardware address]" \ - '(-H --hw-type -d --delete)'{-H,--hw-type}'[class of entries to check for]:class:(ether arcnet pronet ax25 netrom)' \ - '(-n --numeric -d --delete -s --set -f --file)'{-n,--numeric}'[shows numerical addresses]' \ - '(-v --verbose)'{-v,--verbose}'[be verbose]' \ - '(-a)1:host:->hostintable' && ret=0 +if (( ${+words[(r)-d]} )) && [[ $OSTYPE = (*bsd|dragonfly|darwin)* ]]; then + args+=( '(1 *)-a[delete all entries]' ) +fi -[[ "$state" = hostintable ]] && - _wanted hosts expl 'host' compadd ${${${(f)"$(${words[1]} -an)"}##[ ?(]#}%%[ )]*} && ret=0 +case $OSTYPE in + linux*) + cmds=( + '(2 * -D --use-device)-a[show entries in BSD style output format]' + '!(2 * -D --use-device)-e' + '(2 -n --numeric -D --use-device -H --hw-type)'{-d,--delete}'[delete entry from table]' + '(-n --numeric)'{-s,--set}'[create an ARP entry]' + '(2 * -D --use-device)'{-f,--file}'[read multiple entries from file]' + ) + args=( + '(-i --device)'{-i+,--device=}'[select an interface]:interface:_net_interfaces' + '(-D --use-device -a --display -d --delete)'{-D,--use-device}"[use specified interface's hardware address]" + '(-H --hw-type -d --delete)'{-H+,--hw-type=}'[specify class of entries to check for]:class:(ash ether arcnet pronet ax25 netrom rose dlci fddi hippi irda x25 infiniband eui64)' + '(* -n --numeric -d --delete -s --set -f --file)'{-n,--numeric}'[show numeric addresses]' + '(-v --verbose)'{-v,--verbose}'[be verbose]' + ) + flags+=( netmask ) + ;; + darwin*|freebsd*|dragonfly*) + cmds+=( '(-n -v -i)-S[create an arp entry, replacing any existing entry]' ) + ;| + darwin*|freebsd*) + args+=( '(-s -Q -f)-i+[select an interface]:interface:_net_interfaces' ) + ;| + darwin*) + args+=( + '(-d -s -S -f)-l[show link-layer reachability information]' + '(-d -s -S -f)-x[show extended link-layer reachability information]' + ) + flags+=( reject blackhole only ifscope ) + ;; + dragonfly*) + flags+=( only ) + args+=( '-c:cpu' ) + ;; + netbsd*) + flags+=( proxy ) + args+=( $vopt ) + ;; + freebsd*) + args+=( $vopt ) + flags+=( blackhole reject ) + ;; + openbsd*) + args+=( + '(-a -d -W)-F[overwrite existing entries]' + '(-W)-V+[select the routing domain]:routing domain' + ) + cmds+=( + '(- 1)-W[send the wake on LAN frame]' + ) + flags+=( permanent ) + ;; + solaris*) flags+=( trail permanent) ;; +esac + +_arguments -C -s -S $args \ + '1: :->hostintable' \ + '2:ethernet address' \ + "*: :->flags" \ + + '(cmds)' $cmds && ret=0 + +if [[ "$state" = hostintable ]]; then + if [[ -n $opt_args[(i)-(D|-use-device)] ]]; then + _wanted interfaces expl interface _net_interfaces && ret=0 + elif [[ -n $opt_args[(i)-(f|-file)] ]]; then + _files && ret=0 + elif [[ -n $opt_args[(i)-(s|S|-set)] ]]; then + _hosts && ret=0 + else + _wanted hosts expl 'host' compadd ${${${(f)"$(${words[1]} -an)"}##[ ?(]#}%%[ )]*} && ret=0 + fi +elif [[ "$state" = flags ]]; then + if [[ $words[CURRENT-1] = netmask ]]; then + _message -e netmasks netmask + elif (( $+opt_args[-W] )) || [[ $words[CURRENT-1] = ifscope ]]; then + _wanted interfaces expl interface _net_interfaces && ret=0 + else + _wanted flags expl flag compadd -F line $flags && ret=0 + fi +fi return ret diff --git a/Completion/Unix/Command/_route b/Completion/Unix/Command/_route new file mode 100644 index 000000000..f8426874c --- /dev/null +++ b/Completion/Unix/Command/_route @@ -0,0 +1,254 @@ +#compdef route + +local curcontext="$curcontext" expect ret=1 +local -a state state_descr line args families modifiers ignore sub sequential tags +local -A opt_args subcmds once params + +subcmds=( + add 'add a route' + flush 'remove all routes' + delete 'delete a specific route' + change 'change aspects of a route (such as its gateway)' + get 'lookup route for a destination' + monitor 'continuously report any changes to the routing information' +) +args=( + '-n[output addresses numerically]' + '(-q)-v[verbose output]' +) +modifiers=( + '-net:interpret destination as a network' + '-host:interpret destination as a host' +) +params=( + '-dst' target # does this definitely follow + '(-|)netmask' netmask + '(gw|-gateway)' gateway + metric metric + '(mss|window|-(send|recv)pipe)' size:bytes + '[i-]rtt' time:ms + -rttvar rttvar + -mtu mtu + '(dev|-ifscope|-ifp)' interface + -ifa address + -expire time:epoch + -hopcount hopcount + -tag tag + -prefixlen bits + '-(label|push|pop|swap)' label + -priority number # is it a number + -secattr secattr + '(-iw|-iwmax|-msl)' value + '-fib' table +) + +case $OSTYPE in + ^linux*) + args+=( '(-v)-q[suppress all output]' ) + families=( -inet -inet6 ) + modifiers+=( + '-dst:distinguish a destination' + '-gateway:distinguish a gateway address' + -netmask + -rtt -rttvar + -sendpipe -recvpipe + -mtu -hopcount + -expire + '-lock' '-lockrest' + -i{,nter}face:'indicate destination is directly reachable' + '-static:manually added route' + '-nostatic:pretend route added by kernel or daemon' + '-reject:emit an ICMP unreachable when matched' + '-blackhole:silently discard packets (during updates)' + '-proto1:set protocol specific routing flag #1' + '-proto2:set protocol specific routing flag #2' + ) + sequential=( target gateway netmask ) + ;| + *bsd*|darwin*|dragonfly*) + modifiers+=( + -link '-ifp' '-ifa' # do these need an argument: interface or address + '-prefixlen:indicate mask bits' + ) + ;| + (net|free)bsd*|darwin*|dragonfly*) + families+=( -xns ) + modifiers+=( '-xresolve:emit mesg on use (for external lookup)' ) + ;| + (net|open)bsd*|darwin*|dragonfly*) + modifiers+=( + '-cloning:generate a new route on use' + '-llinfo:validly translate proto addr to link addr' + ) + ;| + (open|free)bsd*|darwin*|dragonfly*) + args+=( + "-d[debug-only mode: don't update routing table]" + '-t[test-only mode: /dev/null used instead of a socket]' + ) + ;| + netbsd*|solaris*) + args+=( '-f[remove all routes first]' ) + ;; + (netbsd|darwin|dragonfly)*) + modifiers+=( '-proxy:make entry a link level proxy' ) + ;| + (netbsd|openbsd|dragonfly)*) + subcmds+=( show 'print out the routing table' ) + families+=( -mpls ) + ;| + (netbsd|darwin)*) + families+=( -atalk ) + ;| + (freebsd|darwin)*) + families+=( -osi ) + ;| + (openbsd|dragonfly)*) + modifiers+=( -push -pop -swap ) + ;| + freebsd*) + subcmds+=( + del $subcmds[delete] + show $subcmds[get] + ) + args+=( + '(-6)-4[specify IPv4 address family]' + '(-4)-6[specify IPv6 address family]' + ) + families+=( -4 -6 ) + modifiers+=( '-fib:specify a routing table' ) + ;; + netbsd*) + subcmds+=( flushall 'remove all routes including the default gateway' ) + args+=( + '-S[print a space when a flag is missing to align flags]' + '-s[suppress all output from get except for the gateway]' + ) + modifiers+=( + '-tag' + '-noreject:clear reject flag' + '-noblackhole:clear blackhole flag' + ) + ;; + openbsd*) + subcmds+=( exec 'execute a command with alternate routing table' ) + args+=( + '-T+[select specified alternate routing table]:table id' + ) + modifiers+=( + -sa + '-label' + '-priority' + '-mpath:multiple gateways for a destination exist' + -mplslabel -in -out + ) + ;; + solaris*) + subcmds+=( show 'display list of routes applied at system startup' ) + args+=( + '-p[make changes to the route tables persistent across system restarts]' + '-R+[specify alternate root directory where changes are applied]:directory:_directories' + ) + modifiers+=( + "-private:don't advertise this route" + '-multirt:create the specified redundant route' + '-setsrc:assign the default source address' + '-secattr:security attributes' + ) + ;; + darwin*) + modifiers+=( -ifscope ) + ;| + dragonfly*) + modifiers+=( -iw -iwmax -msl ) + ;| + linux*) + args+=( + '(H -n)--numeric[output addresses numerically]' + '(H)*'{-e,--extend}'[display other/more information]' + '!(H -C --cache)'{-F,--fib} + '(H -C --cache)'{-C,--cache}'[display routing cache instead of FIB]' + + '(family)' + '-A+[use specified address family]:address family:(inet inet6 ax25 netrom ipx ddp x25)' + -4 -6 --inet --inet6 --ax25 --netrom --ipx --ddp --x25 + + '(H)' + '(1 *)'{-h,--help}'[display help information]' + '(1 *)'{-V,--version}'[display version information]' + ) + subcmds[del]=$subcmds[delete] + unset 'subcmds[monitor]' 'subcmds[get]' 'subcmds[change]' + modifiers+=( + netmask gw metric mss window irtt reject mod dyn reinstate + 'dev:force route to be associated with the specified device' + ) + sequential=( target interface ) + ;; +esac + +print -v sub -f '%s\\:%s' ${(kvq)subcmds} +_arguments -C -s -S "1:command:(($sub))" '*::args:->args' $args && ret=0 + +[[ -n $opt_args[(i)-[46]] ]] && families=() + +if [[ -n $state ]]; then + if [[ $line[1] = exec ]]; then + shift words + (( CURRENT-- )) + _normal + elif [[ $line[1] = (flush|monitor) ]]; then + sequential=() + fi + + for ((i=2;i