From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2439 invoked by alias); 18 May 2018 20:14:45 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: List-Unsubscribe: X-Seq: 42803 Received: (qmail 28570 invoked by uid 1010); 18 May 2018 20:14:45 -0000 X-Qmail-Scanner-Diagnostics: from park01.gkg.net by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.99.2/21882. spamassassin: 3.4.1. Clear:RC:0(205.235.26.22):SA:0(-1.4/5.0):. Processed in 4.247644 secs); 18 May 2018 20:14:45 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.4 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE,SPF_PASS,T_DKIM_INVALID autolearn=no autolearn_force=no version=3.4.1 X-Envelope-From: SRS0=D2FQ=IF=yahoo.co.uk=okiddle@bounces.park01.gkg.net X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | X-Virus-Scanned: by amavisd-new at gkg.net Authentication-Results: amavisd4.gkg.net (amavisd-new); dkim=pass (2048-bit key) header.d=yahoo.co.uk X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.co.uk; s=s2048; t=1526674472; bh=Bh8oyxXGB4339JigPWkrAQYx1GA/douemlt0TetJ4nc=; h=From:To:Subject:Date:From:Subject; b=JmUEzRkIOPeYS61/CYBj9IR3r8afAUM8+M1va315QhzVHnN4QRJe0nE7zqRe8WJ/7rodV3eO07/WWR7KcbckfNaUL6i4OOdaDIk0sPxVqLYld0/3a10ktn/cok0HFfOnvyZi2lrOTxUNrPz1exJpafXXiSxKk0TOR5fQ3fjBUex3qvX5SCa3Pv5kNPDsWRa2YWvYmN4IE/jbS1PGvUo+i4I1py+uSyqs3uGe6vM7df7p5jAU175wedt3lq8RzMP2j/Cj7GndF15jdE1PJ4ohmlKhjVVnjG5efwXGEzg9f+NvCth0tXhvzKUxk9aSKjYjHZQWD/Nz3Ll2zYu1ePcRAQ== X-YMail-OSG: TH3Vxm0VM1k27pXvXQ.PtFAN5_5cLHTv53NLjCPNxlkEDOeCHT23UyfkSY0Hr8h 45_YyF0GwFP9zakGqotathh3K.Tjpm0fy2JQq0pMbh7IUf5uQcuMCRVT8b58kTVjBPCwaKOlNYCu z5wjANlhf7RxaKciQPpu7xOC46vnVNnSyW3O0Wf2ezX36wf.SoT309qoO6.jKn7ZTkgHWPAi6e3l qw75rJuINw6wMPqNZm04N.RXo0QrZ.riwjqFvFCYjTCGRdS5_CFkHOfFLtFAH0JDSOPMFXDcGo3N QUmrwtgQrzJ28k1zzoZ2QFGoFkhQwYs8gtsTXincavivU4DbMCXX8KbQFYFsCk6EDTUkXrjDsknc XKUHGurz0Qbg0Z.DN0mBUc7HebAqqzVdsEdF4ZUVI1DMJcwyNQqvCNc1G9eBXhAug436IJMxVW82 m6lvo1RrIKGKcMnBsR3U8m4nhGNiQeF8HsHZPmiDH1JaJzUIW7g.04Ct0od_K7R9K1xDJHlh1noV Y990EoXD47p.Mn5DtSdX5hekwMe_URpMhy8qTVOAwfemia278RjMsogYJMj3LW8eRJ5DatIcu9.A JOO99V8AMZHBFDkyNTAEe_._820g4CreU3dNuepdj1C5zMQSKXqta2ItEjC0mfwcU From: Oliver Kiddle To: Zsh workers Subject: PATCH: handle other systems in netstat completion MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-ID: <30196.1526674457.1@thecus> Content-Transfer-Encoding: 8bit Date: Fri, 18 May 2018 22:14:17 +0200 Message-ID: <30197.1526674457@thecus> This adapts netstat completion to handle options on Linux and the most common BSDs in addition to Solaris. I'll move it to the Unix directory. Online man pages for macOS are for 10.9 which is fairly old so it may not be fully up-to-date for the darwin variant. To reduce the number of listed options, I've got it to hide display specific options until an option that selects a particular display type has been selected. This isn't strictly correct - options can come in any order – but does make it much more useful. This function shows up some of the quirks of _arguments sets. Particularly with packed single letter options. Oliver diff --git a/Completion/Solaris/Command/_netstat b/Completion/Solaris/Command/_netstat index bf8e5aaa4..c03aae9a2 100644 --- a/Completion/Solaris/Command/_netstat +++ b/Completion/Solaris/Command/_netstat @@ -1,61 +1,337 @@ #compdef netstat -_netstat() { - local -a f_rules +local Wopt Xopt nopt="[don't resolve addresses to names]" +local lopt='[show only listening sockets]' +local zopt='-z[reset statistic counters after displaying them]' +local popt='(-f)-p+[filter by protocol]:protocol:compadd -a plist' +local Iopt='(-i)-I+[show information about the specified interface]:interface:_net_interfaces' +local set sel +local -A sets +local -a Mopts families flist plist args sockets extend interval verbose +local -a {sel_,}{bpf,dhcp,groups,interfaces,masquerade,media,memory,multicast,pcb,queues,routing,statistics,wireless} - f_rules=( - 'af\::specify address family: inet, inet6, unix, number' - 'outif\::specify output interface: ifName, ifIndex, any, none' - 'dst\::specify destination IP: ip-addr[/mask], any, none' - 'flags\::select routes tagged with flags: [+ -]?[ABDGHLMSU]+' - ) +case $OSTYPE in + linux-gnu) + families=( + '(-4 --inet)'{-4,--inet} + '(-6 --inet)'{-4,--inet6} + '(-A --protocol)'{-A+,--protocol=}':protocol:_sequence compadd - inet inet6 unix ipx ax25 netrom ddp bluetooth' + --unix -x --ip --tcpip --ax25 --x25 --rose --ash + --bluetooth --ipx --netrom --ddp --appletalk --econet --ec + ) + extend=( \*{-e,--extend}'[show additional information]' ) + verbose=( '(-v --verbose)'{-v,--verbose}'[show what is going on]' ) + args=( + '(-c --continuous)'{-c,--continuous}'[repeat information every second]' + '!(-n --numeric)'{-N,--symbolic} + '(-n --numeric)'{-n,--numeric}"$nopt" + --numeric-hosts --numeric-ports --numeric-users + '1: :_guard "[0-9]#" "repeat interval (seconds)"' + - '(help)' + '(- 1)'{-h,--help}'[display usage information]' + '(- 1)'{-V,--version}'[display version information]' + ) + sets=( + routing '(--route|-[^-]#r*)' + groups '(--groups|-[^-]#g*)' + interfaces '(--interfaces|-[^-]#[iI]*)' + statistics '(--statistics|-[^-]#s*)' + masquerade '(--masquerade|-[^-]#M*)' + ) - _arguments \ - - set1 \ - '-a[show state of all sockets, all routing tables or all interfaces]' \ - '-R[show extended security attributes for sockets and routing tables]' \ - '-n[do not resolve addresses to names]' \ - '-v[verbose]' \ - '-f[specify address family]:address family:(inet inet6 unix)' \ - '-P[specify protocol]:protocol:(ip ipv6 icmp icmpv6 igmp udp tcp rawip)' \ - - set2 \ - '-r[show routing table]' \ - '-f[filter routing table]:rule:(($f_rules))' \ - '-a[show state of all sockets, all routing tables or all interfaces]' \ - '-v[verbose]' \ - '-n[do not resolve addresses to names]' \ - '-R[show extended security attributes for sockets and routing tables]' \ - - set3 \ - '-g[show multicast group memberships]' \ - '-n[do not resolve addresses to names]' \ - '-v[verbose]' \ - '-f[specify address family]:address family:(inet inet6 unix)' \ - - set4 \ - '-i[show state of interfaces]' \ - '-a[show state of all sockets, all routing tables or all interfaces]' \ - '-f[specify address family]:address family:(inet inet6 unix)' \ - '-n[do not resolve addresses to names]' \ - '-I[select interface]:interface:_net_interfaces' \ - - set5 \ - '-m[show STREAMS memory statistics]' \ - '-v[verbose]' \ - - set6 \ - '-p[show net to media tables]' \ - '-n[do not resolve addresses to names]' \ - '-f[specify address family]:address family:(inet inet6 unix)' \ - - set7 \ - '-s[show per protocol statistics]' \ - '-f[specify address family]:address family:(inet inet6 unix)' \ - '-P[specify protocol]:protocol:(ip ipv6 icmp icmpv6 igmp udp tcp rawip)' \ - - set8 \ - '-M[show multicast routing tables]' \ - '-f[specify address family]:address family:(inet inet6 unix)' \ - '-n[do not resolve addresses to names]' \ - '-s[show per protocol statistics]' \ - - set9 \ - '-D[show status of DHCP configured interfaces]' \ - '-f[specify address family]:address family:(inet inet6 unix)' \ - '-I[select interface]:interface:_net_interfaces' \ -} + sel_routing=( '(-r --route)'{-r,--route}'[display routing table]' ) + sel_interfaces=( + '(-I --interfaces)-i[display interface table]' + '(-i -I --interfaces)'{--interface=-,-I=-}'[display interface table]::interface:_net_interfaces' + ) + sel_groups=( '(-g --groups)'{-g,--groups}'[display multicast group memberships]' ) + sel_masquerade=( '(-M --masquerade)'{-M,--masquerade}'[display masqueraded connections]' ) + [[ -e /proc/net/ip_masquerade ]] || sel_masquerade=( \!${^sel_masquerade} ) + sel_statistics=( '(-s --statistics -c --continuous -n --numeric --numeric-hosts --numeric-ports --numeric-users)'{-s,--statistics}'[display networking statistics]' ) -_netstat "$@" + sockets=( + $families $verbose + --tcp -t --udp -u --udplite -U --sctp -S --raw -w + '(-2 --l2cap)'{-2,--l2cap} + '(-f --rfcomm)'{-f,--rfcomm} + '(-a --all -l --listening)'{-l,--listening}$lopt + '(-a --all -l --listening)'{-a,--all}'[show all sockets]' + --symbolic -N --extend -e + '(--timers -o)'{--timers,-o}'[show information on networking timers]' + '(--program -p)'{--program,-p}'[show process id and program name for sockets]' + '(--wide -W)'{--wide,-W}"[don't truncate IP addresses in output]" + '(-Z --context)'{-Z,--context}'[display SELinux security context for sockets]' + ) + routing=( + $families $extend $verbose + '-C[display routing cache instead of FIB]' + ) + interfaces=( + $extend $verbose + '(-a --all)'{-a,--all}'[show interfaces that are not up]' + ) + groups=() + masquerade=( $extend ) + statistics=( $families ) + ;; + solaris*|darwin*|dragonfly*|freebsd*) + families=( '(-p -4 -6)-f+[specify address family]:address family:compadd -a flist' ) + ;| + freebsd*) + families+=( + '(-6 -f)-4[show IPv4 only]' + '(-4 -f)-6[show IPv6 only]' + ) + ;| + (open|net)bsd*) + popt='(-f)-p+[filter by protocol]:protocol:compadd - ${(M)${(f)"$() + args=( '-T+[specify time format]:time format:((u\:seconds\ since\ epoch d\:standard\ date\ format))' ) + sockets=( '-u[list user, pid and program that created network endpoint]' ) + ;& + solaris*) + args=( -A '-*' $args ) + interval=( + '1: :_guard "[0-9]#" "repeat interval (seconds)"' + '2: :_guard "[0-9]#" "count"' + ) + sets+=( + dhcp '-[^-]#D*' + media '-[^-]#p*' + multicast '-[^-]#M*' + ) + sel_media=( '-p[display net to media tables]' ) + sel_memory=( '-m[display STREAMS memory statistics]' ) + sel_multicast=( '-M[display multicast routing tables]' ) + sel_dhcp=( '-D[display status of DHCP configured interfaces]' ) + sockets+=( + $verbose + '-R[show extended security attributes]' + '-P[specify protocol]:protocol:(ip ipv6 icmp icmpv6 igmp udp tcp rawip)' + ) + routing+=( $verbose + '*-f+[filter routing table]:rule:_values -S \: "filter rule" $flist + "af[specify address family]\:family\:(inet inet6 unix)" + "outif[specify output interface]\:interface\:_net_interfaces" + "dst[specify destination IP]\:IP address" + "flags[select routes tagged with flags]\:flags"' \ + '-a[show state of all routing tables]' + '-R[show extended security attributes]' + ) + groups+=( $families -n$nopt $verbose ) + interfaces+=( $interval + '-a[show state of all interfaces]' + ) + statistics+=( + '-P[specify protocol]:protocol:(ip ipv6 icmp icmpv6 igmp udp tcp rawip)' + ) + media=( -n$nopt $families ) + memory+=( $verbose $interval ) + multicast+=( + -n$nopt $families + '-s[show per protocol statistics]' + ) + dhcp=( $families $Iopt ) + ;; + darwin*) + sets+=( queues '-[^-]#q*' ) + sel_queues=( '*-q[display network interface send queue statistics]' ) + sel_memory=( \*$sel_memory ) + sockets+=( + '-l[show full IPv6 address]' + '-W[avoid truncating addresses]' + ) + routing+=( '-l[show mtu and use wider display]' ) + interfaces+=( + '(-x)-R[show reachability information]' + '-S[show interface link status and state]' + '(-R)-x[show extended reachability information]' + ) + queues=( $Iopt + '-c+[limit statistics to specified queue]:queue' + ) + groups+=( $families + '*-v[show link-layer memberships; repeat for timers and counters]' + ) + ;; + dragonfly*) + plist+=( carp ) + sockets+=( + '-P[show additional protocol-specific information]' + '-c+[access cpu specific route table]:cpu' + ) + interfaces+=( $zopt + '-B[show maximum buffer sizes instead of current buffer usage]' + '-t[show the contents of watchdog timers]' + '(-a -B -b -d -h -n -t -w)*-s[show protocol statistics; repeat to suppress those with zero counters]' + ) + routing+=( + '-A[show contents of internal Patricia tree structures]' + '-a[show protocol-cloned routes]' + ) + ;; + openbsd*) + sets+=( wireless '-W*' ) + sel_wireless=( '-W+[display per-interface IEEE 802.11 wireless statistics]:interface' ) + flist+=( local mpls ) + sockets+=( -l$lopt '-B[show buffer sizes for TCP sockets]' ) + routing+=( + '-F[only show routes with gateway in the same address family as the destination]' + '-T+[select an alternate routing table to query]:routing table' + ) + interfaces+=( + '-c+[show specified number of updates, then exit]:count' + '-q[only show interfaces that have seen packets]' + '-t[show current value of the watchdog timer function]' + ) + statistics+=( $popt ) + pcb+=( $Mopts $verbose ) + ;; + netbsd*) + popt='(-f)-p+[filter by protocol]:protocol:compadd - ${(M)${(f)"$(.*) + routing+=( '-F+[show specified routing table]:routing table' ) + bpf=( '-z[reset statistic counters after displaying them]' ) + statistics+=( $bpf[-1] ) + ;& + freebsd*) + flist+=( pfkey netgraph ng link ) + plist+=( sctp ipsec6 pfkey ) + + sets+=( netisr '-[^-]#Q*' ) + sel_netisr=( '-Q[display netisr(9) statistics]' ) + sockets+=( + '-R[show flowid and flowtype for each socket]' + '-T[show diagnostic information from the TCP control block]' + '-x[show socket buffer and TCP timer statistics]' + ) + interfaces+=( + $popt $Mopts $Iopt $Wopt + '-q+[exit after specified number of outputs]:number' + ) + bpf+=( $Iopt $zopt ) + ;; +esac + +# Ignore display specific options except the default (socket) display until a +# display has been selected. This is not strictly correct (options can be in +# any order) but makes the completion much more useful. Descriptions for +# options that select a specific display (option set) typically start with +# "display" to set them apart from other options. +sock='' +for set in ${(k)sets}; do + sel=sel_$set + if [[ -z $words[(r)$~sets[$set]] ]]; then + ign='!' + else + sock='!' + ign='' + fi + args+=( - "$set" ${(P)sel} ${ign}${(P)^set} ) +done +args+=( - sockets ${sock}${sockets} ) + +_arguments -s -S $args