From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from primenet.com.au (ns1.primenet.com.au [203.24.36.2]) by inbox.vuxu.org (OpenSMTPD) with ESMTP id b705db86 for ; Sun, 30 Dec 2018 23:12:36 +0000 (UTC) Received: (qmail 7786 invoked by alias); 30 Dec 2018 23:12:21 -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: 43959 Received: (qmail 20536 invoked by uid 1010); 30 Dec 2018 23:12:21 -0000 X-Qmail-Scanner-Diagnostics: from mail-io1-f50.google.com by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.100.2/25112. spamassassin: 3.4.2. Clear:RC:0(209.85.166.50):SA:0(-1.9/5.0):. Processed in 4.046163 secs); 30 Dec 2018 23:12:21 -0000 X-Envelope-From: dana@dana.is X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dana-is.20150623.gappssmtp.com; s=20150623; h=from:content-transfer-encoding:mime-version:subject:message-id:date :to; bh=pE50U1t53jFR5qbd8HXznTFtsU/oMe5TtaZHm7AybvI=; b=GSKVGAdnXGZ7qA10YzVvD9kL5GaTY4mYLPa6MWFESF2JBJVj5VnkZU+1a1Da6gbIZ0 Kn0LzhzLHybNNBrCSD8RjRfeSNSUS8z+j/UI4HTKqZcUB4Plq2erXrpfyIYIdQu4a88w M1KKsaZVSonuz+1HOF0TZW4v4yw7H/vtWKlbdG53HuQFWz0ZOWogRmF8BwxpkfMdWuG+ AjP26Ot+arela0yGh6F3xeaFMsxtLT05r/afTCw3CkU1X86Zcs6fYmQ6a68Oh7d73ObY lg85oePZ3yVqS1Y5Zz6PiJCIYkuU66gzcvsJkvSoEIIu3OjPa5y4WtpFw1CZNv9Fistd QtzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:content-transfer-encoding:mime-version :subject:message-id:date:to; bh=pE50U1t53jFR5qbd8HXznTFtsU/oMe5TtaZHm7AybvI=; b=HBRwGgMDPh2oUXH4xqxhAnbNFbPyhPuyN1KQjsWgNC1NaPQ9bm8shCmRE/3HJeIpsc CrBZAoMFLOFjCFXnI2QzXkmOU9f+HergNFXYQbtI0hYPesXYb/+vPoEclEmolYMDWLOi 5j5y7IOzUlTj4TF+iUFxk+yORuIEuFKhzEQ+AJoneEScJ1facewuNERlII4U2qED7hOQ rP7FwFmSQk6hrA2Gic28q+rvshrh3PR9ZvnZcAlbtpGx+uOiXrAG3xgiU+YSt4OYsOf8 yiXLe/IXSaJ7+dVQXn87OQqSWskDISQG6tstgkA3QrwWVHoZchY/SSNGH4/S5BGJOQgv pbDQ== X-Gm-Message-State: AJcUukfA71VoCBKZsgZKSMqoLxmiqbwnlCQ4hG9ZrSE5R1cYDo8tFbE2 0lC0uhDb+T/B8d6KL1LGHaJOm2SEy2fRzg== X-Google-Smtp-Source: ALg8bN51gyCeNhTANGezVvgRAlPki9hXR/3SNQMtcE2I09/NGXeLJRrjy7p2VwioQCSQLzjJPa5TlQ== X-Received: by 2002:a5d:85c5:: with SMTP id e5mr23028888ios.125.1546211533415; Sun, 30 Dec 2018 15:12:13 -0800 (PST) From: dana Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Mime-Version: 1.0 (Mac OS X Mail 12.0 \(3445.100.39\)) Subject: [PATCH] Completion: Add _ipsec, _swanctl Message-Id: Date: Sun, 30 Dec 2018 17:14:37 -0600 To: Zsh workers X-Mailer: Apple Mail (2.3445.100.39) New functions for ipsec and swanctl (provided by strongSwan, &al.) Also a very minor addition to _urls (_swanctl is what led me to workers/43922 (handling of options like -+). = I haven't merged that yet because i found that it impacts the behaviour = for some already-broken edge-case options like -: and -\. Want to see how = irritating it'd be to fix those properly rather than just shuffle the brokenness = around) dana diff --git a/Completion/Unix/Command/_ipsec = b/Completion/Unix/Command/_ipsec new file mode 100644 index 000000000..631d2bc9a --- /dev/null +++ b/Completion/Unix/Command/_ipsec @@ -0,0 +1,179 @@ +#compdef ipsec strongswan + +# Completion for the ipsec script (aka strongswan on some systems) = provided by +# FreeS/WAN, Openswan, Libreswan, and strongSwan. See also strongSwan's = swanctl. +# +# As with swanctl, elevated privileges are usually required to complete = SA names +# and the like; consider setting the gain-privileges style as follows: +# zstyle ':completion:*:(ipsec|strongswan)/*' gain-privileges yes +# +# @todo We don't complete pool names or virtual IPs + +# Complete connection (IKE SA) names and optionally SA/instance names +# --instances =3D> also complete SA/instance names +(( $+functions[_ipsec_connections] )) || +_ipsec_connections() { + local -a instances tmp ipsec_conns ipsec_insts + + zparseopts -D -E -a instances - -instances + + tmp=3D( ${(f)${"$( + _call_program -p ipsec-status ${_ipsec_cmd:-$words[1]} statusall + )"#*$'\n'[[:space:]]#[Cc]onnections:[[:space:]]#$'\n'}} ) + tmp=3D( ${(@M)tmp:#[[:space:]]#[^[:space:]]##:[[:space:]]##?*} ) + tmp=3D( ${(@)${(@)tmp##[[:space:]]##}%%:*} ) + + ipsec_conns=3D( ${(@)tmp%%['[{']<->['}]']} ) + ipsec_insts=3D( ${(@M)tmp:#*['[{']<->['}]']} ) + + (( $#ipsec_conns )) || { + _message -e connections 'connection name' + return + } + + tmp=3D( 'connections:connection name:compadd -a - ipsec_conns' ) + (( $#instances && $#ipsec_insts )) && + tmp+=3D( 'instances:connection SA/instance name:compadd -a - = ipsec_insts' ) + + _alternative $tmp +} + +# Complete arguments to /usr/lib/ipsec/starter. This is rarely invoked = directly, +# and there is almost no documentation on it, but the start/restart = commands +# pass options to it +(( $+functions[_ipsec_starter] )) || +_ipsec_starter() { + _arguments : \ + '(--nofork)--attach-gdb[start daemon under gdb (implies --nofork)]' = \ + '--auto-update[specify select time-out]:select time-out (seconds)' = \ + '--conf[specify path to ipsec.conf]:ipsec.conf file:_files' \ + '--daemon[specify daemon name]:daemon name' \ + '--nofork[do not fork daemon]' \ + + '(d)' \ + '--debug[set log level 2]' \ + '--debug-more[set log level 3]' \ + '--debug-all[set log level 4]' \ + '--nolog[set log level 0]' +} + +_ipsec() { + local ret=3D1 variant _ipsec_cmd=3D$words[1] + local -a context line state state_descr tmp + local -A opt_args + + _pick_variant -r variant \ + freeswan=3D'(#i)frees/#wan' \ + libreswan=3D'(#i)libreswan' \ + openswan=3D'(#i)openswan' \ + strongswan=3D'(#i)strongswan' \ + unix \ + --version + + # Provide only basic completion for non-strongSwan implementations + if [[ $variant =3D=3D unix ]]; then + _default + return + elif [[ $variant =3D=3D (free|libre|open)* ]]; then + tmp=3D( ${(f)"$( _call_program ipsec-help $words[1] --help )"} ) + tmp=3D( ${(@M)tmp:#($' '|$'\t')*} ) + tmp=3D( ${(@)tmp:#*[':/<>()[]']*} ) + tmp=3D( ${(f)${(F)tmp//[[:space:]]##/$'\n'}} ) + + _arguments -S -A '-*' : \ + '(: * -)--help[display help information]' \ + '(: * -)--version[display version information]' \ + "(-)1:command:(${(j< >)${(@q-)tmp}})" \ + '(-)2: :_default' + return + fi + + _arguments -A '-*' \ + '(: * -)--confdir[display path to configuration directory = (IPSEC_CONFDIR)]' \ + '(: * -)--copyright[display copyright information]' \ + '(: * -)--directory[display path to libexec/utility directory = (IPSEC_DIR)]' \ + '(: * -)--help[display help information]' \ + '(: * -)--piddir[display path to PID directory (IPSEC_PIDDIR)]' \ + '(: * -)--version[display version information]' \ + '(: * -)--versioncode[display brief version information]' \ + '1:command:(( + down\:"terminate IPsec connection/SA" + down-srcip\:"terminate IKE SAs by client virtual IP" + leases\:"display IP address/pool status" + listaacerts\:"display X.509 authorization authority certificates" + listacerts\:"display X.509 attribute certificates" + listalgs\:"display loaded algorithms" + listall\:"execute all list commands" + listcacerts\:"display X.509 certificate authority certificates" + listcainfos\:"display certificate authority information" + listcerts\:"display X.509/OpenPGP certificates" + listcounters\:"display IKE counter information" + listcrls\:"display certificate revocation lists" + listgroups\:"display groups for user authorization profiles" + listocsp\:"display OCSP revocation information" + listocspcerts\:"display X.509 OCSP signer certificates" + listplugins\:"display loaded plug-in features" + listpubkeys\:"display RSA public keys" + purgecerts\:"purge cached certificates" + purgecrl\:"purge cached certificate revocation lists" + purgeike\:"purge IKE SAs without a quick mode or CHILD_SA" + purgeocsp\:"purge cached OCSP information" + reload\:"reload entire configuration (send SIGUSR1)" + rereadacerts\:"re-read attribute certificates" + rereadaacerts\:"flush and re-read authorization authority = certificates" + rereadall\:"execute all re-read commands" + rereadcacerts\:"flush and re-read certificate authority = certificates" + rereadcrls\:"re-read certificate revocation lists" + rereadocspcerts\:"re-read OCSP certificates" + rereadsecrets\:"flush and re-read secrets" + resetcounters\:"reset IKE counter information" + restart\:"equivalent to stop + start" + route\:"insert kernel IPsec policy for connection" + start\:"start IKE daemon" + status\:"display concise connection status" + statusall\:"display detailed connection status" + stop\:"terminate all IPsec connections and stop IKE daemon" + stroke\:"issue stroke command" + unroute\:"remove kernel IPsec policy for connection" + up\:"bring up IPsec connection" + update\:"reload changes in configuration (send SIGHUP)" + ))' \ + '*:: :->next' \ + && ret=3D0 + + [[ $state =3D=3D next ]] && + case $words[1] in + down) + _arguments : '1: :_ipsec_connections --instances' && ret=3D0 + ;; + listcounters|resetcounters|route|status|statusall|unroute|up) + _arguments : '1: :_ipsec_connections' && ret=3D0 + ;; + down-srcip) + _arguments : \ + '1:virtual IP address (start)' \ + '2::virtual IP address (end)' \ + && ret=3D0 + ;; + leases) + _arguments : '1:pool name' '2::virtual IP address' && ret=3D0 + ;; + list*~list(counters|plugins)) + _arguments : '--utc[use UTC for time fields]' && ret=3D0 + ;; + start|restart) + _ipsec_starter && ret=3D0 + ;; + stroke) + _arguments -s -S -A '-*' \ + '(: * -)'{-h,--help}'[display help information]' \ + '(-d --daemon)'{-d+,--daemon=3D}'[specify daemon name]:daemon = name' \ + '1: :_guard "^-*" "stroke command"' \ + '*:stroke command argument:_default' \ + && ret=3D0 + ;; + esac + + return ret +} + +_ipsec "$@" diff --git a/Completion/Unix/Command/_swanctl = b/Completion/Unix/Command/_swanctl new file mode 100644 index 000000000..ba2f5402d --- /dev/null +++ b/Completion/Unix/Command/_swanctl @@ -0,0 +1,225 @@ +#compdef swanctl + +# Completion for strongSwan's swanctl. See also ipsec, which is = deprecated but +# still supported by strongSwan, and also used by Openswan/Libreswan. +# +# Note that in most cases elevated privileges are required to connect = to the +# VICI socket, so the gain-privileges style may be necessary to = complete SA +# names and the like: zstyle ':completion:*:swanctl/*' gain-privileges = yes +# +# Other notes: +# - One of swanctl's selling points is that it can provide 'raw' = structured +# responses for scripting, etc. In practice, though, the output = formatted for +# humans seems easier to 'parse' from the shell than the plist-like = raw output +# - @todo We don't complete authority names, pool names, peer IPs, etc. + +# Complete connection names, SA names, or SA unique IDs. The = distinctions +# between concepts like 'connections' and 'SAs' are very blurry here, = partially +# for convenience and partially due to author confusion +# --child =3D> complete only child/CHILD_SA names/IDs +# --ids =3D> complete unique SA IDs rather than connection/SA names +# --ike =3D> complete only connection/IKE_SA names/IDs +(( $+functions[_swanctl_connections] )) || +_swanctl_connections() { + local i which + local -a expl tmp matches + local -A opts + + zparseopts -D -E -A opts - -child -ids -ike + + tmp=3D( ${(@M)${(f)"$( + _call_program -p swanctl-sas $words[1] -l + )"}:#[^:]##: \#<->*} ) + (( $+opts[--ids] )) || tmp+=3D( ${(@M)${(f)"$( + _call_program -p swanctl-conns $words[1] -L + )"}:#[^:]##: ([A-Z][A-Za-z0-9]#|),*} ) + + for i in $tmp; do + if (( $+opts[--child] )) && [[ $i !=3D [[:space:]]* ]]; then + continue + elif (( $+opts[--ike] )) && [[ $i =3D=3D [[:space:]]* ]]; then + continue + fi + + # : #, ... + i=3D${i//[#:,]/ } + + if (( $+opts[--ids] )); then + matches+=3D( "${i[(w)2]}:${i[(w)1]} #${i[(w)2]}" ) + else + matches+=3D( ${i[(w)1]} ) + fi + done + + if (( $+opts[--ids] )); then + matches=3D( ${(onu)matches} ) + if (( $+opts[--child] )); then + which=3DCHILD_ + elif (( $+opts[--ike] )); then + which=3DIKE_ + fi + _describe -x2Vt sa-ids "${which}SA unique ID" matches + else + if (( $+opts[--child] )); then + which=3D'child ' + elif (( $+opts[--ike] )); then + which=3D'IKE ' + fi + _wanted -x connections expl "${which}connection/SA name" compadd - = $matches + fi +} + +_swanctl() { + # Although swanctl will correctly parse multiple short options in the = first + # word, as in `swanctl -lh`, it won't actually *do* anything with the + # subsequent options -- so we'll require that they be separated. = Also, --help + # doesn't take any further options, so just stop if we've got that + if (( CURRENT =3D=3D 2 )) || [[ $words[2] =3D=3D (-h*|--help) ]]; = then + _arguments : \ + '(-)'{-a,--load-pools}'[(re)load pool configuration]' \ + '(-)'{-A,--list-pools}'[display loaded pool configurations]' \ + '(-)'{-b,--load-authorities}'[(re)load authority configuration]' = \ + '(-)'{-B,--list-authorities}'[display loaded authority = configurations]' \ + '(-)'{-c,--load-conns}'[(re)load connection configuration]' \ + '(-)'{-C,--counters}'[display or reset IKE event counters]' \ + '(-)'{-d,--redirect}'[redirect IKE_SA]' \ + '(-)'{-f,--flush-certs}'[flush cached certificates]' \ + '(-)'{-g,--list-algs}'[display loaded algorithms]' \ + '(-)'{-h,--help}'[display help information]' \ + '(-)'{-i,--initiate}'[initiate a connection]' \ + '(-)'{-l,--list-sas}'[display currently active IKE_SAs]' \ + '(-)'{-L,--list-conns}'[display loaded configurations]' \ + '(-)'{-m,--monitor-sa}'[monitor for IKE_SA and CHILD_SA changes]' = \ + '(-)'{-p,--install}'[install trap or shunt policy]' \ + '(-)'{-P,--list-pols}'[display currently installed policies]' \ + '(-)'{-q,--load-all}'[load credentials, authorities, pools, and = connections]' \ + '(-)'{-r,--reload-settings}'[reload daemon strongswan.conf]' \ + '(-)'{-R,--rekey}'[rekey SA]' \ + '(-)'{-s,--load-creds}'[(re)load credentials]' \ + '(-)'{-S,--stats}'[display daemon statistics]' \ + '(-)'{-t,--terminate}'[terminate connection]' \ + '(-)'{-T,--log}'[trace logging output]' \ + '(-)'{-u,--uninstall}'[uninstall trap or shunt policy]' \ + '(-)'{-v,--version}'[display version information]' \ + '(-)'{-x,--list-certs}'[display stored certificates]' + return + fi + + local ret=3D1 cmd + local -a args cert_flags cert_types + + cert_flags=3D( aa any ca none ocsp ) + cert_types=3D( ocsp_response pubkey x509 x509_ac x509_crl ) + + if [[ $words[2] =3D=3D -[^-]* ]]; then + cmd=3D${(M)words[2]#??} + else + cmd=3D$words[2] + fi + words=3D( $words[1] "${(@)words[3,-1]}" ) + (( CURRENT-- )) + + # Technically, only -v, -u, and -+ are truly global command options. = However, + # in practice, all commands also support -h, -P, and -r + args=3D( + '(: * -)'{-h,--help}'[display help information]' + '(-P -r --pretty --raw)'{-P,--pretty}'[dump raw response message in = pretty print]' + '(-P -r --pretty --raw)'{-r,--raw}'[dump raw response message]' + # = https://wiki.strongswan.org/projects/strongswan/wiki/LoggerConfiguration + # = https://github.com/strongswan/strongswan/blob/master/src/libstrongswan/uti= ls/debug.h + '(-v --debug)'{-v+,--debug=3D}'[specify debug level]:debug level = [1]:(( + -1\:"absolutely silent (SILENT)" + 0\:"basic auditing (AUDIT)" + 1\:"generic control flow with errors (CTRL)" + 2\:"detailed control flow (DIAG)" + 3\:"raw binary blobs (RAW)" + 4\:"sensitive data (PRIVATE)" + ))' + '(-u --uri)'{-u+,--uri=3D}'[specify service URI to connect to]:VICI = service URI:_urls' + '(-+ --options)'{'-\++',--options=3D}'[read command-line options = from specified file]:options file:_files' + ) + + case $cmd in + -A|--list-pools) args+=3D( + '(-n --name)'{-n+,--name=3D}'[filter by specified pool name]:pool = name' + '(-l --leases)'{-l,--leases}'[display leases of each pool]' + ) ;; + -B|--list-authorities) args+=3D( + '(-n --name)'{-n+,--name=3D}'[filter by specified authority = name]:authority name' + ) ;; + -C|--counters) args+=3D( + '(-a -n --all --name)'{-a,--all}'[display/reset counters for all = tracked connections]' + '(-a -n --all --name)'{-n+,--name=3D}'[specify connection name]: = :_swanctl_connections --ike' + '(-r --reset)'{-r,--reset}'[reset counters]' + ) ;; + -d|--redirect) args+=3D( + '(-d --peer-id)'{-d+,--peer-id=3D}'[redirect by IKE_SA matching = specified peer identity]:peer identity' + '(-g --gateway)'{-g+,--gateway=3D}'[redirect to specified = gateway]:target gateway' + '(-i --ike)'{-i+,--ike=3D}'[redirect by specified IKE_SA name]: = :_swanctl_connections --ike' + '(-I --ike-id)'{-I+,--ike-id=3D}'[redirect by specified IKE_SA = unique ID]: :_swanctl_connections --ids --ike' + '(-p --peer-ip)'{-p+,--peer-ip=3D}'[redirect by IKE_SA matching = specified peer IP]:peer IP address' + ) ;; + -f|--flush-certs) args+=3D( + '(-t --type)'{-t+,--type=3D}"[filter by specified certificate = type]:certificate type:( + ${(j< >)${(@q-)cert_types}} + )" + ) ;; + -i|--initiate) args+=3D( + '(-c --child)'{-c+,--child=3D}'[specify CHILD_SA name]: = :_swanctl_connections --child' + '(-i --ike)'{-i+,--ike=3D}"[specify CHILD_SA's connection name]: = :_swanctl_connections --ike" + '(-t --timeout)'{-t+,--timeout=3D}'[specify timeout before = detaching]:timeout (seconds)' + ) ;; + -l|--list-sas) args+=3D( + '(-i --ike)'{-i+,--ike=3D}'[filter by specified IKE_SA name]: = :_swanctl_connections --ike' + '(-I --ike-id)'{-I+,--ike-id=3D}'[filter by specified IKE_SA = unique ID]: :_swanctl_connections --ids --ike' + '(-n --noblock)'{-n,--noblock}'[do not wait for IKE_SAs in use]' + ) ;; + -p|-u|--install|--uninstall) args+=3D( + '(-c --child)'{-c+,--child=3D}'[specify CHILD_SA name]: = :_swanctl_connections --child' + '(-i --ike)'{-i+,--ike=3D}"[specify CHILD_SA's connection name]: = :_swanctl_connections --ike" + ) ;; + -P|--list-pols) args+=3D( + '(-c --child)'{-c+,--child=3D}'[filter by specified CHILD_SA = name]: :_swanctl_connections --child' + '(-d --drop)'{-d,--drop}'[list drop policies]' + '(-p --pass)'{-p,--pass}'[list bypass policies]' + '(-t --trap)'{-t,--trap}'[list trap policies]' + ) ;; + -q|-s|--load-all|--load-creds) args+=3D( + '(-c --clear)'{-c,--clear}'[clear previously loaded credentials]' + '(-n --noprompt)'{-n,--noprompt}'[do not prompt for passwords]' + ) ;; + -R|--rekey) args+=3D( + '(-c --child)'{-c+,--child=3D}'[rekey by specified CHILD_SA = name]: :_swanctl_connections --child' + '(-C --child-id)'{-C+,--child-id=3D}'[rekey by specified CHILD_SA = unique ID]: :_swanctl_connections --ids --child' + '(-i --ike)'{-i+,--ike=3D}'[rekey by specified IKE_SA name]: = :_swanctl_connections --ike' + '(-I --ike-id)'{-I+,--ike-id=3D}'[rekey by specified IKE_SA = unique ID]: :_swanctl_connections --ids --ike' + ) ;; + -t|--terminate) args+=3D( + '(-t --timeout)'{-t+,--timeout=3D}'[specify timeout before = detaching]:timeout (seconds)' + '(-c --child)'{-c+,--child=3D}'[terminate by specified CHILD_SA = name]: :_swanctl_connections --child' + '(-C --child-id)'{-C+,--child-id=3D}'[terminate by specified = CHILD_SA unique ID]: :_swanctl_connections --ids --child' + '(-i --ike)'{-i+,--ike=3D}'[terminate by specified IKE_SA name]: = :_swanctl_connections --ike' + '(-I --ike-id)'{-I+,--ike-id=3D}'[terminate by specified IKE_SA = unique ID]: :_swanctl_connections --ids --ike' + ) ;; + -v|--version) args+=3D( + '(-d --daemon)'{-d,--daemon}'[query daemon version]' + ) ;; + -x|--list-certs) args+=3D( + '(-f --flag)'{-f+,--flag=3D}"[filter by specified X.509 = certificate flag]:certificate flag:( + ${(j< >)${(@q-)cert_flags}} + )" + '(-p --pem)'{-p,--pem}'[display PEM encoding of certificate]' + '(-s --subject)'{-s+,--subject=3D}'[filter by specified = certificate subject]:certificate subject' + '(-S --short)'{-S,--short}'[omit some certificate details]' + '(-t --type)'{-t+,--type=3D}"[filter by specified certificate = type]:certificate type:( + ${(j< >)${(@q-)cert_types}} + )" + '(-u --utc)'{-u,--utc}'[use UTC for time fields]' + ) ;; + esac + + _arguments -s -S : $args && ret=3D0 + return ret +} + +_swanctl "$@" diff --git a/Completion/Unix/Type/_urls b/Completion/Unix/Type/_urls index e81eaac05..5d4990442 100644 --- a/Completion/Unix/Type/_urls +++ b/Completion/Unix/Type/_urls @@ -81,7 +81,7 @@ case "$scheme" in return fi ;; - file) + file|unix) [[ -prefix //(127.0.0.1|localhost)/ ]] && compset -P = '//(127.0.0.1|localhost)' [[ -prefix /// ]] && compset -P // if ! compset -P //; then