summaryrefslogtreecommitdiff
path: root/Completion/Unix/Command
diff options
context:
space:
mode:
authorOliver Kiddle <opk@zsh.org>2016-06-09 22:51:18 +0200
committerOliver Kiddle <opk@zsh.org>2016-06-09 22:51:18 +0200
commitcf01ad96d4758c602b41df59bf0fe1330a88b800 (patch)
tree873d72c4204b8774ff329577f7fae583ce6ce2c1 /Completion/Unix/Command
parent5e4db660b24b617fcb848785e17328dedcfcf920 (diff)
downloadzsh-cf01ad96d4758c602b41df59bf0fe1330a88b800.tar.gz
zsh-cf01ad96d4758c602b41df59bf0fe1330a88b800.zip
38639: fix username completion after -, update options and get user shell with getent
Diffstat (limited to 'Completion/Unix/Command')
-rw-r--r--Completion/Unix/Command/_su127
1 files changed, 67 insertions, 60 deletions
diff --git a/Completion/Unix/Command/_su b/Completion/Unix/Command/_su
index 057a41371..73b27ee90 100644
--- a/Completion/Unix/Command/_su
+++ b/Completion/Unix/Command/_su
@@ -2,79 +2,86 @@
local -A opt_args
local -a args context state line expl
-local shell=${words[(i)(-s|--shell=*)]} first='1:user name:_users'
-local usr=root
+local first='(-)${norm}:user name:_users'
+integer norm=1 strip
+local shell usr
-if _pick_variant gnu="Free Software Foundation" unix --version; then
- args=(
- '(--command)-c[pass command to shell]:command string:->command'
- '(-c)--command=-[pass command to shell]:command string:->command'
- '-f[pass -f to shell (csh)]'
- '(--login)-l[use a login shell]'
- '(-l)--login[use a login shell]'
- '(-p --preserve-environment)-m[do not reset environment]'
- '(-m --preserve-environment)-p[do not reset environment]'
- '(-m -p)--preserve-environment[do not reset environment]'
- '(--shell)-s[run the specified shell]:shell:->shell'
- '(-s)--shell=-[run the specified shell]:shell:->shell'
- )
-else
- args=(
- '-l[use a login shell]'
- '-s[run the specified shell]:shell:->shell'
- )
- case $OSTYPE in
- freebsd*)
- args=(
+(( $words[(i)-(l|-login)] < CURRENT )) || args=( '-[use a login shell]' )
+case $OSTYPE in
+ linux*)
+ args=( -S $args
+ '(-c --command --session-command *)'{-c,--command=}'[pass command to shell]:command string:_cmdstring'
+ "(-c --command *)--session-command=[pass command to shell and don't create a new session]:command string:_cmdstring"
+ '(--fast -f)'{-f,--fast}'[pass -f to shell]'
+ '(-l --login -m -p --preserve-environment)'{-l,--login}'[use a login shell]'
+ '(-l --login -m -p --preserve-environment)'{-m,-p,--preserve-environment}"[don't reset environment]"
+ '(-s --shell)'{-s,--shell=}'[run the specified shell]:shell:->shells'
+ '(-)--help[display help information]'
+ '(-)--version[display version information]'
+ )
+ (( EUID )) || args+=(
+ '(-g --group)'{-g,--group=}'[specify primary group]:group:_groups'
+ \*{-G,--supp-group=}'[specify supplemental group]:group:_groups'
+ )
+ first="(--help --version)${first#???}"
+ ;;
+ *bsd*|dragonfly*)
+ args+=(
'-c[use settings from specified login class]:class'
'-f[if the invoked shell is csh, prevent it from reading .cshrc]'
- '-l[use a login shell]'
- '-m[do not reset environment]'
- '-s[set the MAC label]'
+ '(-m)-l[use a login shell]'
+ "(-l)-m[don't reset environment]"
+ )
+ ;|
+ freebsd*) args+=( '-s[set the MAC label]' ) ;;
+ openbsd*)
+ args+=(
+ '(-K)-a[specify authentication type]:authentication type'
+ '(-a)-K[shorthand for -a passwd]'
+ '-s[run the specified shell]:shell:->shells'
+ '-L[loop until login succeeds]'
)
;;
- *) args+=( '-c[pass command to shell]:command string:->command' ) ;;
- esac
-fi
+ netbsd*)
+ args+=(
+ '-d[use a login shell but retain current directory]'
+ "-K[don't use Kerberos]"
+ )
+ ;;
+esac
-if [[ $#words -ge 2 && $words[2] != -* && CURRENT -ne 2 ]]; then
- usr=$words[2]
- first=
+if (( $words[(i)-] < CURRENT )); then
+ args=( ${args:#*-(-login|l|)\[*} '1:-' )
+ norm=2
fi
-[[ $words[shell] == -s ]] && ((shell++))
+_arguments $args ${(e)first} "*:shell arguments:= ->rest" && return
-if [[ CURRENT -ne shell && -n ${words[shell]} ]]; then
- shell=${words[shell]#*=}
+usr=${line[norm]/--/root}
+if (( $#opt_args[(i)-(s|-shell)] )); then
+ shell=${(v)opt_args[(i)-(s|-shell)]}
+elif (( ${+commands[getent]} )); then
+ shell="${$(_call_program shells getent passwd $usr)##*:}"
else
- shell="${${(M@)${(@f)$(</etc/passwd)}:#$usr*}##*:}"
+ shell="${${(M@)${(@f)$(</etc/passwd)}:#$usr*}##*:}"
fi
-[[ -z $first ]] && compset -n 2
-
-_arguments : $args[@] $first "*:${shell:t} arguments:->rest" && return
-
case $state in
- (command)
- compset -q
- _normal
- return
- ;;
- (shell)
- _wanted -C $context shells expl shell compadd ${(f)^"$(</etc/shells)"}(N)
- return
- ;;
- (rest)
- if [[ -z $shell || $shell = */(nologin|false) ]]; then
- _arguments "-s[run the specified shell, $usr has no shell]" ||
- _message "-s option required, $usr has no shell"
- compstate[insert]=
- else
- # Something wrong here: doubles the file listing sometimes
- _dispatch ${service}:${context} $shell $shell:t -default-
- return
- fi
- ;;
+ shells)
+ _wanted -C $context shells expl shell compadd ${(f)^"$(</etc/shells)"}(N)
+ return
+ ;;
+ rest)
+ if [[ -z $shell || $shell = */(nologin|false) ]]; then
+ _message "-s option required, $usr has no shell"
+ else
+ (( strip = $#words - $#line + norm ))
+ (( CURRENT -= strip - 1 ))
+ words[2,strip]=()
+ _dispatch ${service}:${context} $shell $shell:t -default-
+ return
+ fi
+ ;;
esac
return 1