From 887cbbdbed140808f0ec0faf5f7e7ecd4eccb7af Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 30 May 2005 09:46:57 +0000 Subject: Joerg Sonnenberger: 21252: Dragonfly BSD support --- ChangeLog | 9 + Completion/BSD/Command/_chflags | 45 ++ Completion/Unix/Command/_apm | 41 ++ Completion/Unix/Command/_cvs | 959 +++++++++++++++++++++++++++++++++++ Completion/Unix/Command/_ifconfig | 82 +++ Completion/Unix/Command/_mount | 819 ++++++++++++++++++++++++++++++ Completion/Unix/Command/_mt | 80 +++ Completion/Unix/Command/_sysctl | 45 ++ Completion/Unix/Type/_file_systems | 37 ++ Completion/Unix/Type/_net_interfaces | 22 + Src/Modules/zpty.c | 407 +++++++++------ configure.ac | 2 +- 12 files changed, 2405 insertions(+), 143 deletions(-) create mode 100644 Completion/BSD/Command/_chflags create mode 100644 Completion/Unix/Command/_apm create mode 100644 Completion/Unix/Command/_cvs create mode 100644 Completion/Unix/Command/_ifconfig create mode 100644 Completion/Unix/Command/_mount create mode 100644 Completion/Unix/Command/_mt create mode 100644 Completion/Unix/Command/_sysctl create mode 100644 Completion/Unix/Type/_file_systems create mode 100644 Completion/Unix/Type/_net_interfaces diff --git a/ChangeLog b/ChangeLog index 3d00b54ec..c4e44dc10 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,15 @@ * 21270: Src/system.h: don't use poll() on Apple. +2005-05-11 Oliver Kiddle + + * Joerg Sonnenberger: 21252: configure.ac, Src/Modules/zpty.c, + Completion/BSD/Command/_chflags, Completion/Unix/Command/_apm, + Completion/Unix/Command/_cvs, Completion/Unix/Command/_ifconfig, + Completion/Unix/Command/_mount, Completion/Unix/Command/_mt, + Completion/Unix/Command/_sysctl, Completion/Unix/Type/_file_systems, + Completion/Unix/Type/_net_interfaces: Dragonfly BSD support + 2005-05-10 Oliver Kiddle * Haakon Riiser: 21188: Completion/X/Command/_acroread: handle diff --git a/Completion/BSD/Command/_chflags b/Completion/BSD/Command/_chflags new file mode 100644 index 000000000..d6bcfe4b3 --- /dev/null +++ b/Completion/BSD/Command/_chflags @@ -0,0 +1,45 @@ +#compdef chflags + +local flags own='-g *(-u$EUID)' + +flags=( + '(noopaque)opaque[set the opaque flag]' + '(opaque)noopaque[unset the opaque flag]' + '(dump)nodump[set the nodump flag]' + '(nodump)dump[unset the nodump flag]' + '(nouappnd)uappnd[set the user append-only flag]' + '(uappnd)nouappnd[unset the user append-only flag]' + '(nouchg)uchg[set the user immutable flag]' + '(uchg)nouchg[unset the user immutable flag]' +) + +if (( ! EUID )); then + flags=( $flags[@] + '(noarch)arch[set the archived flag]' + '(arch)noarch[unset the archived flag]' + '(nosappnd)sappnd[set the system append-only flag]' + '(sappnd)nosappnd[unset the system append-only flag]' + '(noschg)schg[set the system immutable flag]' + '(schg)noschg[unset the system immutable flag]' + ) + unset own +fi + +if [[ $OSTYPE = (freebsd|dragonfly)* ]]; then + flags=( $flags[@] + '(nouunlnk)uunlnk[set the user undeletable flag]' + '(uunlnk)nouunlnk[unset the user undeletable flag]' + ) + (( EUID )) || flags=( $flags[@] + '(nosunlnk)sunlnk[set the system undeletable flag]' + '(sunlnk)nosunlnk[unset the system undeletable flag]' + ) +fi + +_arguments -s -A "-*" \ + '(-L -P)-H[follow symlinks on the command line (specify with -R)]' \ + '(-H -P)-L[follow all symlinks (specify with -R)]' \ + '(-L -H)-P[do not follow symlinks (specify with -R)]' \ + '-R[recurse directories]' \ + ':file flag:_values -s , "file flags" $flags[@]' \ + '*:file:_files "$own"' diff --git a/Completion/Unix/Command/_apm b/Completion/Unix/Command/_apm new file mode 100644 index 000000000..e6179d676 --- /dev/null +++ b/Completion/Unix/Command/_apm @@ -0,0 +1,41 @@ +#compdef apm + +if [[ $OSTYPE == linux* ]]; then + + _arguments -s \ + '(-)'{-V,--version}'[print the apm program version and exit immediately]' \ + '(-v --verbose)'{-v,--verbose}'[print information about APM BIOS and Linux APM driver version]' \ + '(-m --minutes)'{-m,--minutes}'[print total minutes remaining instead of using an hh:mm format]' \ + '(-s --suspend)'{-s,--suspend}'[put the machine into suspend mode if possible]' \ + '(-S --standby)'{-S,--standby}'[put the machine into standby mode if possible]' \ + '(-n --noignore)'{-n,--noignore}'[tell the system not to ignore system-generated APM message]' \ + '(-i --ignore)'{-i,--ignore}'[tell the system to ignore system-generated APM message]' && return + +elif [[ $OSTYPE == (freebsd|dragonfly)* ]]; then + + _arguments \ + '-a[display AC line status]' \ + '-b[display battery status]' \ + '-d[disable/enable display suspension]:bool:' \ + '-e[disable/enable apm functions]:bool:' \ + '-h[disable/enable HLT in kernel context switch]:bool:' \ + '-l[display remaining battery percentage]' \ + '-r[enable resume wakeup timer]' \ + '-s[display status of APM support]' \ + '-t[display estimated remaining battery life in seconds]' \ + '-Z[transition system into standby mode]' \ + '-z[suspend the system]' && return + +elif [[ $OSTYPE == openbsd* ]]; then + _arguments \ + '-z[engage suspend mode]' \ + '-S[engage stand-by mode]' \ + '-l[display estimated battery lifetime percentage]' \ + '-m[display estimated battery lifetime minutes]' \ + '-b[display battery status]' \ + '-a[display AC line status]' \ + '-v[verbose]' \ + '-f[socket]:sockname:_files' && return +fi + +return 1 diff --git a/Completion/Unix/Command/_cvs b/Completion/Unix/Command/_cvs new file mode 100644 index 000000000..3a8775c5e --- /dev/null +++ b/Completion/Unix/Command/_cvs @@ -0,0 +1,959 @@ +#compdef cvs + +# redefine _cvs. + +_cvs() { + local extra + + # "+Qqrwtnlvb:T:e:d:Hfz:s:xa" + case $OSTYPE in + freebsd*|openbsd*|dragonfly*) + extra='-R[read only access]' + ;; + esac + + _arguments -s \ + $extra \ + '-a[authenticate]' \ + '-f[disable .cvsrc]' \ + '(-n)-l[disable logging]' \ + '(-l)-n[no change]' \ + '(-q)-Q[really quiet]' \ + '(-Q)-q[somewhat quiet]' \ + '(-w)-r[make new working file read only]' \ + '-t[trace]' \ + '(-r)-w[make new working file read-write]' \ + '-x[encrypt client/server communication]' \ + '(-)'{-v,--version}'[print version and copyright information]' \ + '(-)'{-H,--help}'[print help information]' \ + '(-)--help-commands[command help]' \ + '(-)--help-synonyms[command synonyms help]' \ + '(-)--help-options[global options help]' \ + '*--allow-root=[allowable root for pserver]:rootdir:_files -/' \ + '-T+[temporary directory]:temporary directory:_cvs_tempdir' \ + '-d+[cvs root directory]:cvsroot:_cvs_root' \ + '-e+[editor]:editor:_cvs_editor' \ + '-s+[user variable]:user variable:_cvs_user_variable' \ + '-z+[gzip level]:gzip level:(0 1 2 3 4 5 6 7 8 9)' \ + '*::cvs command:_cvs_command' +} + +# define cvs command dispatch function. + +(( $+functions[_cvs_command] )) || +_cvs_command() { + local cmd cvsroot="$CVSROOT" ret=1 + [[ -f CVS/Root ]] && cvsroot="$(&1)"}[2,-2]/(#b) #([a-z]#) #([a-z]#) ([a-z]#)/$match[1] $match[2]:$match[3]} ) + fi + + (( $+_cvs_cmds )) || _cvs_cmds=( + ${${(f)"$(_call_program commands cvs --help-commands 2>&1)"}[2,-2]/(#b) #([a-z]##) #([A-Z])/$match[1]:${match[2]:l}} + 'version:display cvs version being used on client and server' + ) + + if (( CURRENT == 1 )); then + _describe -t commands 'cvs command' _cvs_cmds || compadd "$@" - ${(s.:.)${(j.:.)_cvs_syns}} + else + local curcontext="$curcontext" + + cmd="${${_cvs_cmds[(r)$words[1]:*]%%:*}:-${(k)_cvs_syns[(r)(*:|)$words[1](:*|)]}}" + if (( $#cmd )); then + curcontext="${curcontext%:*:*}:cvs-${cmd}:" + _call_function ret _cvs_$cmd || _message 'no more arguments' + else + _message "unknown cvs command: $words[1]" + fi + return ret + fi +} + +# define completion functions for each cvs command + +(( $+functions[_cvs_add] )) || +_cvs_add() { + # "+k:m:" + _arguments -s \ + '-k+[keyword]:keyword substitution:_cvs_k' \ + '-m+[message]:message:_cvs_m' \ + '*:added file:_cvs_files_unmaintained' \ +} + +(( $+functions[_cvs_admin] )) || +_cvs_admin() { + # "+ib::c:a:A:e::l::u::LUn:N:m:o:s:t::IqxV:k:" + _arguments -s \ + -{i,x} \ + '(-U)-L[set lock strict]' \ + '(-L)-U[set locl non-strict]' \ + '-I[interactive]' \ + '-q[quiet]' \ + '-b-[default branch]:default branch:(1.1.1)' \ + '-c+:comment leader (not used)' \ + '-a+:login names (not work with CVS)' \ + '-A+:access list to append (not work with CVS)' \ + '-e-:access list to erase (not work with CVS)' \ + '-l-[lock]:revision to lock' \ + '-u-[unlock]:revision to unlock' \ + '-n+[name revision]:symbolic-name(\:revision)' \ + '-N+[force to name revision]:symbolic-name(\:revision)' \ + '-m+[replace log]:revision\:msg' \ + '-o+[delete revision]:range to delete' \ + '-s+[replace state attribute]:state(\:revision)' \ + '-t-[replace descriptive text]:descriptive text:_cvs_admin_t' \ + '-V+:version (obsolete)' \ + '-k+[set keyword substitution]:keyword substitution:_cvs_k' \ + '*:file:_cvs_files' +} + +(( $+functions[_cvs_admin_t] )) || +_cvs_admin_t() { + if compset -P -; then + _message -e descriptions 'descriptive text' + else + _files "$@" + fi +} + +(( $+functions[_cvs_annotate] )) || +_cvs_annotate() { + # "+lr:D:fR" + _arguments -s \ + "(-R)-l[don't recurse]" \ + '-f[use head revision]' \ + '(-l)-R[recursive]' \ + '(-f -D)-r+[specify revision]:tag:_cvs_revisions' \ + '(-f -r)-D+[specify date]:date:_cvs_D' \ + '*:file:_cvs_files' +} + +(( $+functions[_cvs_rannotate] )) || +_cvs_rannotate() { + # "+lr:D:fR" + _arguments -s \ + "(-R)-l[don't recurse]" \ + '-f[use head revision]' \ + '(-l)-R[recursive]' \ + '(-f -D)-r+[specify revision]:tag:_cvs_revisions' \ + '(-f -r)-D+[specify date]:date:_cvs_D' \ + '*:file:_cvs_modules' +} + +(( $+functions[_cvs_checkout] )) || +_cvs_checkout() { + # "+ANnk:d:flRpQqcsr:D:j:P" + _arguments -s \ + '-N[don'\''t shorten module paths]' \ + '-A[reset sticky tags, dates and -k]' \ + '-n[disable checkout program]' \ + '-f[use most recent revision if -D/-r is not matched]' \ + "(-R)-l[don't recurse]" \ + '(-l)-R[recursive]' \ + '(-s)-c[module database]' \ + '(-c)-s[module database with status]' \ + '-P[prune empty directory]' \ + '-k+[keyword]:keyword substitution:_cvs_k' \ + '-d+[directory]:directory:_files -/' \ + '(-D)-r+[specify revision]:tag:_cvs_revisions' \ + '(-r)-D+[specify date]:date:_cvs_D' \ + '-j+[merge]:tag:_cvs_revisions' \ + '*:module:_cvs_modules' +} + +(( $+functions[_cvs_commit] )) || +_cvs_commit() { + # "+nlRm:fF:r:" + _arguments -s \ + '-n[disable module program]' \ + "(-R)-l[don't recurse]" \ + '(-l)-R[recursive]' \ + '-f[force to commit]' \ + '(-F)-m+[message]:message:_cvs_m' \ + '(-m)-F+[message file]:log message file:_files' \ + '-r+[specify revision]:tag:_cvs_revisions' \ + '*:modified file:_cvs_files_modified' +} + +(( $+functions[_cvs_diff] )) || +_cvs_diff() { + local of ofwuc ouc oss ofwy ofwg ofwl + # output formats + of="-y --side-by-side -n --rcs -e -f --ed -q --brief -c -C --context -u -U \ + --unified --old-group-format --new-group-format --changed-group-format \ + --unchanged-group-format --line-format --old-line-format --new-line-format \ + --unchanged-line-format" + + # output formats w/o unified and context + ofwuc="-y --side-by-side -n --rcs -e -f --ed -q --brief --old-group-format \ + --new-group-format --changed-group-format --unchanged-group-format \ + --line-format --old-line-format --new-line-format --unchanged-line-format" + + # option specific to unified or context diff + ouc='-L --label -p --show-c-function -F --show-function-line' + + # option specific to side by side + oss='-W --width --left-column --suppress-common-lines' + + # output formats w/o side by side + ofwy="-n --rcs -e -f --ed -q --brief -c -C --context -u -U --unified \ + --old-group-format --new-group-format --changed-group-format \ + --unchanged-group-format --line-format --old-line-format \ + --new-line-format --unchanged-line-format" + + # output formats w/o group format + ofwg="-n --rcs -e -f --ed -q --brief -c -C --context -u -U --unified \ + --line-format --old-line-format --new-line-format --unchanged-line-format" + + # output formats w/o line format + ofwl="-n --rcs -e -f --ed -q --brief -c -C --context -u -U --unified \ + --old-group-format --new-group-format --changed-group-format \ + --unchanged-group-format" + + # "+abcdefhilnpstuw0123456789BHNRC:D:F:I:L:U:V:W:k:r:" + _arguments -s \ + "(-R)-l[don't recurse]" \ + '(-l)-R[recursive]' \ + '-k+[keyword]:keyword substitution:_cvs_k' \ + {,}'(-r)-D+[specify date]:date:_cvs_D' \ + {,}'(-D)-r+[specify revision]:tag:_cvs_revisions' \ + -{h,0,1,2,3,4,5,6,7,8,9} \ + '--binary[binary mode]' \ + '--ifdef=[set macro name for merged if-then-else format]:name' \ + '(-i --ignore-case)'{-i,--ignore-case}'[case insensitive]' \ + '(-w --ignore-all-space)'{-w,--ignore-all-space}'[ignore all white space]' \ + '(-b --ignore-space-change)'{-b,--ignore-space-change}'[ignore changes in the amount of white space]' \ + '(-B --ignore-blank-lines)'{-B,--ignore-blank-lines}'[ignore lines that are all blank]' \ + '(-I --ignore-matching-lines)'{-I+,--ignore-matching-lines=}'[ignore lines that match regex]:line exclusion regex' \ + '(-a --text)'{-a,--text}'[treat all files as text]' \ + "($of $oss)"{-C+,--context=-}'[context diff; specify lines of context]:number of lines of context' \ + "($of $oss)-c[output a context diff]" \ + "($of $oss)"{-U+,--unified=-}'[unified diff; specify lines of context]:number of lines of context' \ + "($of $oss)-u[output a unified diff]" \ + {,}"($ofwuc $oss -L --label)"{-L+,--label=}'[set label to use instead of file name]:label' \ + "($ofwuc $oss -p --show-c-function)"{-p,--show-c-function}'[show C function of each change]' \ + "($ofwuc $oss -F --show-function-line=)"{-F+,--show-function-line=}'[show the most recent line matching regex]:regex' \ + "($of $ouc $oss)--brief[output only whether files differ]" \ + "($of $ouc $oss)"{-e,--ed}'[output an ed script]' \ + "($of $ouc $oss)"{-f,--forward-ed}'[output a reversed ed script]' \ + "($of $ouc $oss)"{-n,--rcs}'[RCS format diff]' \ + "($of $ouc)--side-by-side[output in two columns]" \ + "($of $ouc)-y[output in two columns]" \ + "($ofwy $ouc -W --width)"{-W+,--width=}'[set size of line]:number of characters per line' \ + "($ofwy $ouc)--left-column[output only left column of common lines]" \ + "($ofwy $ouc)--suppress-common-lines[do not output common lines]" \ + "($ofwg $ouc $oss)--old-group-format=[set old group format]:old group format" \ + "($ofwg $ouc $oss)--new-group-format=[set new group format]:new group format" \ + "($ofwg $ouc $oss)--changed-group-format=[set changed group format]:changed group format" \ + "($ofwg $ouc $oss)--unchanged-group-format=[set unchanged group format]:unchanged group format" \ + "($ofwl $ouc $oss)--line-format=[set line format]:line format" \ + "($ofwl $ouc $oss)--old-line-format=[set old line format]:old line format" \ + "($ofwl $ouc $oss)--new-line-format=[set new line format]:new line format" \ + "($ofwl $ouc $oss)--unchanged-line-format=[set unchanged line format]:unchanged line format" \ + '--paginate[output through pr]' \ + '(-t --expand-tabs)'{-t,--expand-tabs}'[expand tabs to spaces]' \ + '--initial-tab[prepend a tab]' \ + '(-N --new-file)'{-N,--new-file}'[treat absent files as empty]' \ + '(-s --report-identical-files)'{-s,--report-identical-files}'[report when two files are the same]' \ + '--horizon-lines=[set number of lines to keep in prefix and suffix]:number of horizon lines' \ + '(-d --minimal)'{-d,--minimal}'[try to find a smaller set of changes]' \ + '(-H --speed-large-files)'{-H,--speed-large-files}'[assume large files and many small changes]' \ + '*:file:_cvs_diff_arg' +} + +(( $+functions[_cvs_diff_arg] )) || +_cvs_diff_arg() { + _cvs_files_modified || _cvs_files +} + +(( $+functions[_cvs_edit] )) || +_cvs_edit() { + # "+lRa:" + _arguments -s \ + "(-R)-l[don't recurse]" \ + '(-l)-R[recursive]' \ + '-a+[specify action]:action:(edit unedit commit all none)' \ + '*:file:_cvs_files' +} + +(( $+functions[_cvs_editors] )) || +_cvs_editors() { + # "+lR" + _arguments -s \ + "(-R)-l[don't recurse]" \ + '(-l)-R[recursive]' \ + '*:file:_cvs_files' +} + +(( $+functions[_cvs_export] )) || +_cvs_export() { + # "+Nnk:d:flRQqr:D:" + _arguments -s \ + '-N[don'\''t shorten module paths]' \ + '-n[disable checkout program]' \ + '-f[use most recent revision if -D/-r is not matched]' \ + "(-R)-l[don't recurse]" \ + '(-l)-R[recursive]' \ + '-k+[keyword]:keyword substitution:_cvs_k' \ + '-d+[directory]:directory:_files -/' \ + '(-D)-r+[specify revision]:tag:_cvs_revisions' \ + '(-r)-D+[specify date]:date:_cvs_D' \ + '*:module:_cvs_modules' +} + +(( $+functions[_cvs_history] )) || +_cvs_history() { + # "+Tacelow?D:b:f:m:n:p:r:t:u:x:X:z:" + _arguments -s \ + '-T[all tags]' \ + '-a[all users]' \ + '-c[modified files]' \ + '-e[everything]' \ + '-l[last modification]' \ + '-o[check-outed modules]' \ + '-w[working directory]' \ + '-D+[since date]:date:_cvs_D' \ + '-b+[back to record]:string' \ + '-f+[specify file]:file:_cvs_files' \ + '-m+[specify module]:module:_cvs_modules' \ + '*-n+[in module]:module:_cvs_modules' \ + '*-p+[in repository]:repository' \ + '-r+[since revision]:rev' \ + '-t+[since tag]:tag' \ + '*-u+[specify user]:user name' \ + '-x+[specify type]:type:_cvs_history_x' \ + '-X+[debugging]:arg' \ + '-z+[specify timezone]:timezone' \ + '*:file:_cvs_files' +} + +(( $+functions[_cvs_history_x] )) || +_cvs_history_x() { + _values -s '' 'type' \ + 'F[release]' \ + 'O[checkout]' \ + 'E[export]' \ + 'T[rtag]' \ + 'C[merge collision-detected]' \ + 'G[merge succeed]' \ + 'U[working file was copied]' \ + 'W[working file was deleted]' \ + 'A[a file was added]' \ + 'M[a file was modified]' \ + 'R[a file was removed]' +} + +(( $+functions[_cvs_import] )) || +_cvs_import() { + # "+Qqdb:m:I:k:W:" + _arguments -s \ + '-d[use file modification time]' \ + '-b+[specify vendor branch]:branch:(1.1.3)' \ + '-m+[message]:message:_cvs_m' \ + '*-I+[ignore files]:name:_files' \ + '-k+[keyword]:keyword substitution:_cvs_k' \ + '*-W+[wrapper specification]:spec:_files' \ + ':repository:_cvs_modules' \ + ':vendor tag:_cvs_vendor_branches' \ + ':release tag' +} + +(( $+functions[_cvs_log] )) || +_cvs_log() { + # "+bd:hlNRr::s:tw::" + _arguments -s \ + '-b[default branch]' \ + '(-t)-h[header]' \ + '-l[don'\''t recurse]' \ + '-R[print the name of RCS file in the repository]' \ + '-N[don'\''t list tags]' \ + '(-h)-t[header with descriptive text]' \ + '-d+[specify dates]:dates' \ + '-r-[specify revisions]:revisions' \ + '-s+[specify states]:states:(Exp Stab Rel dead)' \ + '-w-[specify logins]:logins' \ + '*:file:_cvs_files' +} + +(( $+functions[_cvs_rlog] )) || +_cvs_rlog() { + # "+bd:hlNRr::s:tw::" + _arguments -s \ + '-b[default branch]' \ + '(-t)-h[header]' \ + "(-R)-l[don't recurse]" \ + '(-l)-R[recursive]' \ + '-N[don'\''t list tags]' \ + '(-h)-t[header with descriptive text]' \ + '-d+[specify dates]:dates' \ + '-r-[specify revisions]:revisions' \ + '-s+[specify states]:states:(Exp Stab Rel dead)' \ + '-w-[specify logins]:logins' \ + '*:file:_cvs_modules' +} + +(( $+functions[_cvs_rdiff] )) || +_cvs_rdiff() { + # "+V:k:cuftsQqlRD:r:" + _arguments -s \ + '-c[output a context diff]' \ + '-u[output a unified diff]' \ + '-f[use most recent revision if -D/-r is not matched]' \ + '-s[short patch]' \ + "(-R)-l[don't recurse]" \ + '(-l)-R[recursive]' \ + '-V+[specify version]:version' \ + '-k+[keyword]:keyword substitution:_cvs_k' \ + '(-D -D -r -r)-t[top two differences]' \ + '(-t -r)-D+[specify date]:date:_cvs_D' \ + '(-t -r)-D+[specify date]:date:_cvs_D' \ + '(-t -D)-r+[specify revision]:tag:_cvs_revisions' \ + '(-t -D)-r+[specify revision]:tag:_cvs_revisions' \ + '*:module:_cvs_modules' +} + +(( $+functions[_cvs_release] )) || +_cvs_release() { + # "+Qdq" + _arguments -s \ + '-d[delete]' \ + '*:directory:_files -/' +} + +(( $+functions[_cvs_remove] )) || +_cvs_remove() { + # "+flR" + _arguments -s \ + '-f[force to remove]' \ + "(-R)-l[don't recurse]" \ + '(-l)-R[recursive]' \ + '*:removed file:_cvs_remove_arg' +} + +(( $+functions[_cvs_remove_arg] )) || +_cvs_remove_arg() { + if (( $+opt_args[-f] )); then + _cvs_files + else + _cvs_files_removed + fi +} + +(( $+functions[_cvs_rtag] )) || +_cvs_rtag() { + # "+FanfQqlRdbr:D:" + _arguments -s \ + '(-d)-F[move tag if already exists]' \ + '(-d)-a[clear tag from removed files]' \ + '-n[disable tag program]' \ + '(-d)-f[force a head revision]' \ + "(-R)-l[don't recurse]" \ + '(-l)-R[recursive]' \ + '(-b)-d[delete tag]' \ + '(-d)-b[create branch]' \ + '-D+[specify date]:date:_cvs_D' \ + '-r+[specify revision]:tag:_cvs_revisions' \ + ':tag' \ + '*:module:_cvs_modules' +} + +(( $+functions[_cvs_status] )) || +_cvs_status() { + # "+vlR" + _arguments -s \ + '-v[verbose]' \ + "(-R)-l[don't recurse]" \ + '(-l)-R[recursive]' \ + '*:file:_cvs_files' +} + +(( $+functions[_cvs_tag] )) || +_cvs_tag() { + # "+FQqlRcdr:D:bf" + _arguments -s \ + '(-d)-F[move tag if already exists]' \ + "(-R)-l[don't recurse]" \ + '(-l)-R[recursive]' \ + '-c[check that working files unmodified]' \ + '(-b)-d[delete tag]' \ + '(-d)-b[create branch]' \ + '(-d)-f[force a head revision]' \ + '-r+[specify revision]:tag:_cvs_revisions' \ + '-D+[specify date]:date:_cvs_D' \ + ':tag:_cvs_revisions' \ + '*:file:_cvs_files' +} + +(( $+functions[_cvs_unedit] )) || +_cvs_unedit() { + # "+lR" + _arguments -s \ + "(-R)-l[don't recurse]" \ + '(-l)-R[recursive]' \ + '*:file:_cvs_files' +} + +(( $+functions[_cvs_update] )) || +_cvs_update() { + # "+ApCPflRQqduk:r:D:j:I:W:" + _arguments -s \ + '-C[overwrite local modification]' \ + '-A[reset sticky tags, dates and -k]' \ + '-p[check out to standard output]' \ + '-P[prune empty directory]' \ + '-f[use head revision]' \ + "(-R)-l[don't recurse]" \ + '(-l)-R[recursive]' \ + '-d[create directories]' \ + '-k+[keyword]:keyword substitution:_cvs_k' \ + '(-D)-r+[specify revision]:tag:_cvs_revisions' \ + '(-r)-D+[specify date]:date:_cvs_D' \ + '*-j+[merge]:tag:_cvs_revisions' \ + '*-I+[ignore files]:file:_files' \ + '*-W+[wrapper specification]:spec:_files' \ + '*:file:_cvs_files' +} + +(( $+functions[_cvs_watch] )) || +_cvs_watch() { + local expl + + if (( CURRENT == 2 )); then + _wanted values expl 'watch command' compadd on off add remove + else + case "$words[2]" in + on|off) # "+lR" + _arguments -s \ + "(-R)-l[don't recurse]" \ + '(-l)-R[recursive]' \ + ':watch command' \ + '*:file:_cvs_files' + ;; + add|remove) # "+lRa:" + _arguments -s \ + "(-R)-l[don't recurse]" \ + '(-l)-R[recursive]' \ + '*-a+[specify action]:action:(edit unedit commit all none)' \ + ':watch command' \ + '*:file:_cvs_files' + ;; + esac + fi +} + +(( $+functions[_cvs_watchers] )) || +_cvs_watchers() { + # "+lR" + _arguments -s \ + "(-R)-l[don't recurse]" \ + '(-l)-R[recursive]' \ + '*:file:_cvs_files' +} + +(( $+functions[_cvs_loadstat] )) || +_cvs_loadstat() { + zstyle -t ":completion:${curcontext}:" disable-stat && return 1 + (( $+_cvs_loadstat_status )) && return $_cvs_loadstat_status + + zmodload -i zsh/stat 2>/dev/null + (( _cvs_loadstat_status = ! $+builtins[stat] )) + return $_cvs_loadstat_status +} + +(( $+functions[_cvs_root] )) || +_cvs_root() { + local cvspassfile id slash + + typeset -gU _cvs_roots + + if [[ -f "${cvspassfile::=${CVS_PASSFILE:-$HOME/.cvspass}}" ]]; then + if _cvs_loadstat; then + id="$(LC_ALL=C builtin stat -g +mtime -F '%Y/%m/%d-%T' "$cvspassfile")" + else + id="$(LC_ALL=C ls -l "$cvspassfile")" + fi + if [[ "$id" != "$_cvs_pass_id" ]]; then + slash=/ + _cvs_roots=($_cvs_roots ${${${${(f)"$(<$cvspassfile)"}#/1 }%% *}/:2401${slash}/:/}) + _cvs_pass_id="$id" + fi + fi + + _tags files && { + compadd -M 'r:|[:@./]=** r:|=**' "$@" -a _cvs_roots || { + compset -P ':(local|fork):'; _files "$@" -W / -/ + } + } +} + +(( $+functions[_cvs_tempdir] )) || +_cvs_tempdir() { + _tags directories && compadd "$@" $TMPPREFIX:h $TMPDIR /tmp +} + +(( $+functions[_cvs_user_variable] )) || +_cvs_user_variable() { + if compset -P '*='; then + _default + else + _message -e variables "variable" + fi +} + +# define completion functions for cvs global options. + +(( $+functions[_cvs_editor] )) || +_cvs_editor() { + _tags commands && compadd "$@" vi +} + +# define completion functions for cvs common options and arguments. + +(( $+functions[_cvs_D] )) || +_cvs_D() { + _tags values && compadd "$@" today yesterday week\ ago month\ ago +} + +(( $+functions[_cvs_k] )) || +_cvs_k() { + _values 'keyword substitution' \ + 'kv[generate keyword strings using the default form]' \ + "kvl[include locker's name in strings if given revision is locked]" \ + 'k[generate only keyword names in keyword strings; omit their values]' \ + 'o[generate the old keyword string as present in the file before check in]' \ + "b[binary - like \`o' but also inhibit line ending conversions]" \ + 'v[generate only keyword values for keyword strings]' +} + +(( $+functions[_cvs_m] )) || +_cvs_m() { + _message -e messages "log message" +} + +(( $+functions[_cvs_modules] )) || +_cvs_modules() { + if compset -P '(#m)(*/)'; then + _cvs_sub_modules "$cvsroot" "${MATCH%/}" + else + _cvs_top_modules "$cvsroot" + fi +} + +(( $+functions[_cvs_top_modules] )) || +_cvs_top_modules() { + local root="$1" + + if [[ -d $root ]]; then + _wanted modules expl 'module name' \ + compadd - $root/*(/:t) \ + ${${(M)${(f)"$(<$root/CVSROOT/modules)"}:#[^#]*}%%[ ]*} + else + if [[ "$_cvs_top_modules_cache_key" != "$root" ]]; then + _cvs_top_modules_cache_key="$root" + _cvs_top_modules_cache_mods=() + if zstyle -T ":completion:${curcontext}:" remote-access; then + _cvs_remote_directories "$root" . _cvs_top_modules_cache_mods + _cvs_top_modules_cache_mods=( + "$_cvs_top_modules_cache_mods[@]" + ${(M)${${(f)"$( + CVS_IGNORE_REMOTE_ROOT= _call_program modules cvs -d "$root" co -c + )"}%%[ ]*}:#?*} + ) + fi + fi + if (( $#_cvs_top_modules_cache_mods )); then + _wanted modules expl 'module name' \ + compadd -a _cvs_top_modules_cache_mods + else + _message -e modules 'module name' + fi + fi +} + +(( $+functions[_cvs_sub_modules] )) || +_cvs_sub_modules() { + local root="$1" dir="$2" ignore + + if [[ -d $root ]]; then + _wanted modules expl 'module name' \ + _path_files -W "($root/$dir)" -/ -F "(Attic */Attic)" + else + if [[ $_cvs_sub_modules_cache_key != "$root $dir" ]]; then + _cvs_sub_modules_cache_key="$root $dir" + _cvs_sub_modules_cache_mods=() + if zstyle -T ":completion:${curcontext}:" remote-access; then + _cvs_remote_directories "$root" "$dir" _cvs_sub_modules_cache_mods + fi + fi + if (( $#_cvs_sub_modules_cache_mods )); then + _wanted modules expl 'module name' \ + compadd -qS/ -a _cvs_sub_modules_cache_mods + else + _message -e modules 'module name' + fi + fi +} + +# _cvs_run cvsroot directory cvs-arguments... +(( $+functions[_cvs_run] )) || +_cvs_run() { + local cvsroot="$1" dir="$2" + shift 2 + local d=/tmp/zsh-cvs-work-$$ + mkdir $d >&/dev/null + cd $d + mkdir CVS >&/dev/null + print -r - "$cvsroot" > CVS/Root + print "$dir" > CVS/Repository + print D > CVS/Entries + CVS_IGNORE_REMOTE_ROOT= cvs "$@" + cd $OLDPWD + rm -rf $d +} + +# _cvs_remote_directories cvsroot directory [variable] +(( $+functions[_cvs_remote_directories] )) || +_cvs_remote_directories() { + local root="$1" dir="$2" subdirs + shift 2 + subdirs=(${${(M)${(f)"$(_call_program directories _cvs_run "$root" "$dir" update -r00 -d -p 2>&1)"}:#* New directory \`*\' -- ignored}/(#b)*\`(*)\'*/$match[1]}) + if (( $# )); then + eval "$1=(\"\$subdirs[@]\")" + else + if (( $#subdirs )); then + print -lr - $subdirs + fi + fi +} + +(( $+functions[_cvs_vendor_branches] )) || +_cvs_vendor_branches() { + local expl vendor_branch + vendor_branch=() + if zstyle -T ":completion:${curcontext}:" remote-access; then + if [[ -n $opt_args[-b] ]]; then + _cvs_extract_vendor_branch -b "$opt_args[-b]" "$cvsroot" "$line[1]" \ + vendor_branch + else + _cvs_extract_vendor_branch "$cvsroot" "$line[1]" vendor_branch + fi + fi + if (( $#vendor_branch )); then + _wanted values expl 'vendor branch' compadd -a vendor_branch + else + _message -e branches 'vendor branch' + fi +} + +# _cvs_extract_vendor_branch [-b numeric-branch] cvsroot directory [variable] +(( $+functions[_cvs_extract_vendor_branch] )) || +_cvs_extract_vendor_branch() { + local numeric='1\.1\.1' + if [[ $1 = -b ]]; then + numeric="${2//./\\.}" + shift 2 + fi + local root="$1" dir="$2" + shift 2 + + local vtags + vtags=($( + _call_program tags _cvs_run "$root" "$dir" -Q log -h 2>/dev/null | + sed -ne $'/^symbolic names:/{ +n +:loop +/^[^ \t]/d +/: '"$numeric"$'$/b found +n +b loop +:found +s/^[ \t]*\\(.*\\): '"$numeric"$'$/\\1/p +n +/^[ \t]/b found +q +}')) + if (( $# )); then + eval "$1=(\"\$vtags[@]\")" + else + if (( $#vtags )); then + print -lr - "$vtags[@]" + fi + fi +} + +(( $+functions[_cvs_revisions] )) || +_cvs_revisions() { + local expl + + if [[ $_cvs_revisions_key != $cvsroot:$PWD ]]; then + _cvs_revisions_key="$cvsroot:$PWD" + if zstyle -T ":completion:${curcontext}:" remote-access; then + _cvs_revisions_cache=( + $(CVS_IGNORE_REMOTE_ROOT= _call_program tags cvs -d "$cvsroot" -q status -vl .| + sed -n -e '/No Tags Exist/d' \ + -e 's/^ \([A-Za-z][-_0-9A-Za-z+]*\).*/\1/p'| + sort|uniq) + ) + else + _cvs_revisions_cache=() + fi + fi + + if (( $#_cvs_revisions_cache )); then + _wanted values expl revision compadd -a _cvs_revisions_cache + else + _message -e revisions revision + fi +} + +# define completion functions for files maintained by cvs. + +(( $+functions[_cvs_files] )) || +_cvs_files() { + _alternative \ + 'directories:directory:_cvs_existing_directories' \ + 'existing-files:file:_cvs_existing_entries' \ + 'removed-files:removed file:_cvs_nonexistent_entries' +} + +(( $+functions[_cvs_files_modified] )) || +_cvs_files_modified() { + _alternative \ + 'directories:directory:_cvs_existing_directories' \ + 'existing-files:file:_cvs_modified_entries' \ + 'removed-files:removed file:_cvs_nonexistent_entries' +} + +(( $+functions[_cvs_files_removed] )) || +_cvs_files_removed() { + _alternative \ + 'directories:directory:_cvs_existing_directories' \ + 'removed-files:removed file:_cvs_nonexistent_entries' +} + +(( $+functions[_cvs_files_unmaintained] )) || +_cvs_files_unmaintained() { + _cvs_nonentried_files || + _cvs_existing_directories || + _cvs_strict_nonentried_files +} + +(( $+functions[_cvs_existing_directories] )) || +_cvs_existing_directories() { + local expl + _wanted directories expl directory _path_files -g "*~(*/|)CVS(/)" || + _cvs_path_prefixes +} + +(( $+functions[_cvs_existing_entries] )) || +_cvs_existing_entries() { + local expl match linedir realdir pat + match=() + : ${PREFIX:#(#b)(*/)(*)} + linedir="$match[1]" + realdir=${(e)~linedir} + [[ -f "$realdir"CVS/Entries ]] && + pat=(${(@)${(@)${(@M)${(@f)"$(<"$realdir"CVS/Entries)"}:#/*}#/}%%/*}) + (( ${#pat} )) && _wanted files expl file _path_files -a pat +} + +(( $+functions[_cvs_modified_entries] )) || +_cvs_modified_entries() { + if _cvs_loadstat; then + local expl match linedir realdir pat slash=/ + match=() + : ${PREFIX:#(#b)(*/)(*)} + linedir="$match[1]" + realdir=${(e)~linedir} + [[ -f "$realdir"CVS/Entries ]] && + [[ -n ${pat::="${(@j:|:)${(@)${(@)${(@)${(@)${(@)${(@M)${(@f)"$(<"$realdir"CVS/Entries)"}:#/*}#/}/${slash}[^${slash}]#${slash}//}%/[^/]#/[^/]#}:#${(j:|:)~${${${${(f)"$(LC_ALL=C builtin stat -gn +mtime -F '%a %b %e %T %Y' ${realdir}*(D) 2>/dev/null)"}##*/}/ //}//(#m)[][*?()<|^~#\\]/\\$MATCH}}}%%/*}//(#m)[][*?()<|^~#\\]/\\$MATCH}"} ]] && + _wanted files expl 'modified file' _path_files -g "$pat" + else + _cvs_existing_entries + fi +} + +(( $+_cvs_ignore_default )) || +_cvs_ignore_default=( + RCS SCCS CVS CVS.adm RCSLOG 'cvslog.*' tags TAGS .make.state .nse_depinfo + '*\~' '\#*' '.\#*' ',*' '_$*' '*$' '*.old' '*.bak' '*.BAK' '*.orig' '*.rej' + '.del-*' '*.a' '*.olb' '*.o' '*.obj' '*.so' '*.exe' '*.Z' '*.elc' '*.ln' + core +) + +(( $+functions[_cvs_strict_nonentried_files] )) || +_cvs_strict_nonentried_files() { + local expl match linedir realdir omitpats + + match=() + : ${PREFIX:#(#b)(*/)(*)} + linedir="$match[1]" + realdir=${(e)~linedir} + [[ -f "$realdir"CVS/Entries ]] && { + omitpats=( + ${${${${(M)${(f)"$(<"$realdir"CVS/Entries)"}:#/*}#/}%%/*}//(#m)[][*?()<|^~#\\]/\\$MATCH} + ) + if (( $#omitpats )); then + _path_files -g "*~(*/|)(${(j:|:)~omitpats})(D.)" + else + _path_files -g "*~(*/|)(D.)" + fi + } +} + +(( $+functions[_cvs_nonentried_files] )) || +_cvs_nonentried_files() { + local expl match linedir realdir omitpats + + match=() + : ${PREFIX:#(#b)(*/)(*)} + linedir="$match[1]" + realdir=${(e)~linedir} + [[ -f "$realdir"CVS/Entries ]] && { + omitpats=( + ${${${${(M)${${(f)"$(<"$realdir"CVS/Entries)"}:#/*/-*/*/*/*}:#(D|)/*}#(D|)/}%%/*}//(#m)[][*?()<|^~#\\]/\\$MATCH} + $_cvs_ignore_default + ${=cvsignore} + ) + [[ -r ~/.cvsignore ]] && omitpats=($omitpats $(<~/.cvsignore)) + [[ -r ${realdir}.cvsignore ]] && omitpats=($omitpats $(<${realdir}.cvsignore)) + omitpats=($omitpats $=CVSIGNORE) + + _path_files -g "*~(*/|)(${(j:|:)~omitpats})(D.)" + } +} + +(( $+functions[_cvs_nonexistent_entries] )) || +_cvs_nonexistent_entries() { + local expl match linedir realdir files + match=() + : ${PREFIX:#(#b)(*/)(*)} + linedir="$match[1]" + realdir=${(e)~linedir} + files=(${realdir}*(D:t)) + [[ -f "$realdir"CVS/Entries ]] && { + files=( + ${${${${(M)${(f)"$(<"$realdir"CVS/Entries)"}:#(D|)/*}#(D|)/}%%/*}:#${(j:|:)~${files//(#m)[][*?()<|^~#\\]/\\$MATCH}}} + ) + compquote files + _wanted files expl 'removed file' compadd -Qp "$linedir" -a files + } +} + +(( $+functions[_cvs_path_prefixes] )) || +_cvs_path_prefixes() { + local expl match + match=() + [[ "$PREFIX$SUFFIX" = (#b)(*)(/[^/]#) ]] && { + PREFIX="$match[1]" + ISUFFIX="$match[2]$ISUFFIX" + SUFFIX='' + _wanted directories expl directory \ + _path_files -g "*~($PREFIX|(*/|)CVS)(/)" -S '' + } +} + +_cvs "$@" diff --git a/Completion/Unix/Command/_ifconfig b/Completion/Unix/Command/_ifconfig new file mode 100644 index 000000000..49b018841 --- /dev/null +++ b/Completion/Unix/Command/_ifconfig @@ -0,0 +1,82 @@ +#compdef ifconfig + +local curcontext="$curcontext" state line ret=1 +local -a opts args alias debug updownlist + +alias=( '(-alias alias)'{,-}'alias[remove or establish alternate address for if]' ) +debug=( '(-debug debug)'{,-}'debug[disable or enable debugging code]' ) +updownlist=( + '(-a -d -C)-u[restrict to interfaces which are up]' + '(-a -u -C)-d[restrict to interfaces which are down]' + '(-a -C -m -L 1 *)-l[list interfaces]' +) + +case $OSTYPE in + darwin*) + args=( -s $updownlist ) + opts=( + $alias $debug delete dest_address ipdst nsellength + {,-}trailers {,-}link{0,1,2} + ) + ;; + freebsd*|dragonfly*) + args=( -s $updown + '(-a -l -u -d -m -L 1 *)-C[list interface cloners]' + '(-l -C)-m[list supported media]' + '(-l -C)-L[show address lifetime as time offset]' + ) + opts=( $alias $debug + anycast lladdr media {,-}mediaopt {,delete}tunnel create destroy + {,un}plumb vlan {,-}vlandev metric prefixlen range phase ssid muid + stationname channel authmode {,-}powersave powersavesleep wepmode + {,-}wep {,-}nwkey add delete ether {,-}link{0,1,2} + ) + ;; + irix5*) opts=( $debug ) ;; + irix6*) + opts=( $debug {-,}highbw {,-}link{0,1,2} primary rspace sspace ) + args=( '-w[display additional information]' ) + ;; + linux*) + opts=( + '(-promisc promisc)'{,-}'promisc[disable or enable promiscuous mode]' + '(-allmulti allmulti)'{,-}'allmulti[disable or enable all-multicast]' + 'media[set physical port type]:medium type:(auto 10base2 10baseT AUI)' + 'hw[set hardware class]:hardware class:(ether ax25 ARCnet netrom)' + add del dstaddr io_addr irq mem_start multicast pointopoint + tunnel txqueuelen + ) + ;; + solaris*) + args=( + '-ad[apply to all down interfaces]' + '-adD[apply to all down interfaces not controlled by DHCP]' + '-au[apply to all up interfaces]' + '-auD[apply to all up interfaces not controlled by DHCP]' + ) + opts=( + 'auto-revarp[use RARP to acquire address]' + {,-}trailers {,-}private {,un}plumb + '(dhcp auto-dhcp)'{,auto-}'dhcp[use dhcp]' + primary wait drop extend ping release start status + ) + ;; +esac + +_arguments -C "$args[@]" \ + '-a[apply to all interfaces]' \ + '1:network interface:_net_interfaces' \ + '::address family:(atalk ether inet inet6 ax25 ddp ipx netrom)' \ + '*:option:->options' && ret=0 + +[[ -n "$state" ]] && _values -S ' ' -w 'option' "$opts[@]" \ + '(down)up[activate interface]' \ + '(up)down[shut down interface]' \ + '(-arp arp)'{,-}'arp[disable or enable address resolution protocol]' \ + 'metric[set routing metric for interface]:routing metric' \ + 'mtu[set maximum transfer unit]:mtu' \ + 'netmask[specify network mask]:netmask' \ + 'broadcast[specify broadcast address]:broadcast address' \ + 'address[specify IP address of interface]:IP address' && ret=0 + +return ret diff --git a/Completion/Unix/Command/_mount b/Completion/Unix/Command/_mount new file mode 100644 index 000000000..7a45a9e00 --- /dev/null +++ b/Completion/Unix/Command/_mount @@ -0,0 +1,819 @@ +#compdef mount umount + +if [[ "$OSTYPE" == cygwin ]]; then + if [[ "$service" == mount ]] ; then + _arguments -s \ + - mount \ + '(-b -t --text --binary)'{-b,--binary}'[Unix line endings LF]' \ + '(-f --force)'{-f,--force}'[be silent]' \ + '(-s -u --user --system)'{-s,--system}'[system-wide mount point]' \ + '(-t -b --binary --text)'{-t,--text}'[DOS line endings CR-LF]' \ + '(-u -s --system --user)'{-u,--user}'[user private mount point]' \ + '(-x -X --executable --cygwin-executable)'{-x,--executable}'[all files under mountpoint are executables]' \ + '(-x -X --executable --cygwin-executable)'{-X,--cygwin-executable}'[all files under mountpoint are cygwin executables]' \ + ':Windows path:' \ + ':Unix path:_path_files -P/ -W "(/)" -/' \ + - control \ + '(-)'{-i,--import-old-mounts}'[import old mounts]' \ + '(-)'{-p,--show-cygdrive-prefix}'[show cygdrive prefix]' \ + '(-)'{-c,--change-cygdrive-prefix}'[cygdrive prefix]:cygdrive prefix (POSIX path):_files -P/ -W "(/)" -/' \ + + return + else + local line + local -a wpaths upaths + mount | while read -r line; do + [[ $line == ?:\ * ]] && continue + wpaths=($wpaths ${line%% on*}) + upaths=($upaths ${${line##*on }%% type*}) + done + _alternative \ + 'windowspath:Windows path:compadd -a wpaths' \ + 'unixpath:Unix path:compadd -a upaths' + return + fi +fi + +# This is table-driven: the tables for the values for the different +# file system types are directly below. The tables describing the +# arguments for the `mount' command for different operating systems +# are below these table. + +local curcontext="$curcontext" state line suf ret=1 +local args deffs=iso9660 tmp typeops=-t _nfs_access _nfs_ufs + +typeset -A opt_args + +if (( ! $+_fs_any )); then + + # These are tables describing the possible values and their + # arguments for the `-o' option. There is one array per + # file system type (only for those that accept more values + # than those in the `_fs_any' array). The elements of the + # array are used as arguments to `_values'. The first tables + # are used by several systems while system specific tables are + # (re)defined in a "$OSTYPE" case. + + _fs_any=( + '(rw)ro[mount file system read-only]' + '(ro)rw[mount file system read-write]' + ) + _nfs_access=( + 'acregmin[specify cached file attributes minimum hold time]:cached file attributes minimum hold time' + 'acregmax[specify cached file attributes maximum hold time]:cached file attributes maximum hold time' + 'acdirmin[specify cached directory attributes minimum hold time]:cached directory attributes minimum hold time' + 'acdirmax[specify cached directory attributes maximum hold time]:cached directory attributes maximum hold time' + "actimeo[set all attributes' cache timeout]:cache timeout" + ) + _fs_nfs=( + 'rsize[specify read buffer size]:read buffer size:(8192)' + 'wsize[specify write buffer size]:write buffer size:(8192)' + '(soft)hard[hang process on server crash (so to say)]' + '(hard)soft[allow time out on server crash]' + '(nolock)lock[use locking]' + "(lock)nolock[don't use locking]" + 'timeo[specify initial timeout for UDP]:initial timeout for UDP' + 'retrans[set number of NFS retransmissions]:number of NFS retransmissions' + 'retry[specify number of mount failure retries]:mount failure retries' + '(fg)bg[retry in the background]' + '(bg)fg[retry in the foreground]' + '(nintr)intr[allow operations to be interrupted]' + '(intr)nintr[prevent operations from being interrupted]' + '(nfsv3)nfsv2[use NFS version 2]' + '(nfsv2)nfsv3[use NFS version 3]' + 'proto[specify protocol]:protocol:(udp tcp)' + 'port[specify server port number]:server port number' + 'proplist[allow property lists]' + "$_nfs_access[@]" + "nocto[don't get fresh attributes on open]" + "noac[don't set attribute caching]" + ) + _nfs_ufs=( + '(nodev)dev[interpret devices]' + "(dev)nodev[don't interpret devices]" + '(nosuid)suid[use suid and sgib bits]' + '(suid)nosuid[ignore suid and sgid bits]' + '(nosync)sync[do I/O synchronously]' + '(sync)nosync[do all I/O asynchronously]' + '(noexec)exec[permit execution of binaries]' + "(exec)noexec[don't allow execution of binaries]" + '(nogrpid)grpid[new file gets group ID of directory]' + '(grpid)nogrpid[new file gets fsgid of current process]' + ) + _fs_ufs=( + 'dirty[allow mount even if not cleanly unmounted]' + "$_nfs_ufs[@]" + ) + + case "$OSTYPE" in + aix*) + _fs_any=( + 'bsy[prevent mount over cwd of process]' + 'log[logical volume to log operations]:logical volume name' + 'nodev[cannot open devices from mount]' + 'nosuid[prevent running setuid/setgid from mount]' + "$_fs_any[@]" + ) + + _fs_nfs=( + '(fg)bg[mount in background]' + '(bg)fg[mount in foreground]' + 'vers[NFS version]:NFS version:(2 3)' + 'proto[specify transport protocol]' + 'retry[number of retries]:no. of retries' + 'rsize[read buffer size]:read buffer size' + 'wsize[write buffer size]:write buffer size' + 'llock[local locking]' + 'timeo[time-out period]:time-out period' + 'retrans[NFS transmissions]:no. of NFS transmissions' + 'port[IP port no]:IP port no' + '(hard)soft[error on no server response]' + '(soft)hard[retry pending server response]' + '(nointr)intr[allow keyboard interrupts on hard mount]' + '(intr)nointr[disallow keyboard interrupts on hard mount]' + 'posix[exchange pathconf info on NFS version 2 mount]' + 'secure[use DES encryption]' + 'grpid[inherit group id of parent directory]' + "(acl)noacl[don't use access control lists]" + '(noacl)acl[use access control lists for this mount]' + 'noac[no attribute or directory caching]' + 'shortdev[server lack support for 32-bit device special files]' + "$_nfs_access[@]" + ) + ;; + irix*) + _fs_any=( + 'nodev[cannot open devices from mount]' + 'nosuid[prevent running setuid/setgid from mount]' + 'grpid[inherit group id of parent directory]' + "$_fs_any[@]" + ) + + _fs_efs=( + 'raw[raw device pathname to filesystem]:raw device pathname:->devordir' + '(nofsck)fsck[fsck should check this filesystem by default]' + '(fsck)nofsck[fsck should not check this filesystem by default]' + '(noquota)quota[turn on quotas]' + '(quota)noquota[turn off quotas]' + 'lbsize[no of bytes transferred in each operation]:bytes' + ) + + _fs_iso9660=( + 'setx[set execute permissions on every file]' + 'notranslate[don'\''t translate filenames]' + 'cache[no of 2048 blocks for directory cache]:cache size' + 'noext[ignore rock ridge extensions]' + '(nosusp)susp[enable system use sharing protocol]' + '(susp)nosusp[disable system use sharing protocol]' + '(norrip)rrip[enable rock ridge extensions]' + '(rrip)norrip[disable rock ridge extensions]' + 'nmconv[specify filename translation]:filename translation:((c\:no\ translation l\:to\ lowercase m\:suppress\ version\ no))' + ) + + _fs_nfs=( + '(fg)bg[mount in background]' + '(bg)fg[mount in foreground]' + 'retry[number of retries]:no. of retries' + 'rsize[read buffer size]:read buffer size' + 'wsize[write buffer size]:write buffer size' + 'timeo[time-out period]:time-out period' + 'retrans[NFS transmissions]:no. of NFS transmissions' + 'port[IP port no]:IP port no' + '(hard)soft[error on no server response]' + '(soft)hard[retry pending server response]' + 'intr[allow keyboard interrupts on hard mount]' + 'noac[no attribute caching]' + 'private[use local locking and do not flush on last close]' + 'symttl[time-to-live of cached symbolic links]:seconds' + "$_nfs_access[@]" + ) + + _fs_cachefs=( + 'backfstype[type of the back file system]:back file system type:(efs nfs iso9660 dos hfs cachefs)' + 'backpath[specify back file system location]:back file system location:_files -/' + 'cachedir[name of the cache directory]:name of cache directory:_files -/' + 'cacheid[cache ID]:cache ID' + '(write-around)non-shared[cache not shared]' + '(non-shared)write-around[cache shared]' + 'noconst[disable consistency checking]' + 'local-access[check permissions locally]' + 'purge[purge any cached information]' + "$_nfs_access[@]" + ) + + ;; + solaris*) + _fs_s5fs=( + 'remount[remount file system]' + '(suid)nosuid[ignore suid and sgid bits]' + '(nosuid)suid[use suid and sgib bits]' + ) + _fs_ufs=( + "(atime)noatime[don't update access time]" + 'f[fake an /etc/mnttab entry]' + "m[don't make an /etc/mnttab entry]" + '(noforcedirection)forcedirection[do I/O synchronously]' + '(forcedirection)noforcedirection[do all I/O asynchronously]' + '(nointr)intr[allow operations to be interrupted]' + '(intr)nointr[prevent operations from being interrupted]' + "(nolargefiles)largefiles[don't restrict file size]" + '(largefiles)nolargefiles[restrict file size]' + '(nologging)logging[log transactions]' + '(logging)nologging[log transactions]' + 'onerror[action to recover from error]:action:(panic lock umount)' + 'quota[turn on quotas]' + '(ro rw)rq[mount file system read-write with quotas]' + "$_fs_s5fs[@]" + ) + _fs_tmpfs=( + 'size[set file system size]:size' + ) + _fs_pcfs=( + '(nofoldcase)foldcase[force filenames to lowercase]' + "(foldcase)nofoldcase[don't force filenames to lowercase]" + ) + _fs_hsfs=( + 'nrr[no rock ridge]' + 'notraildot[no trail dot when no extension]' + "nomaplcase[don't force lowercase]" + 'nosuid[ignore suid and sgid bits]' + ) + _fs_nfs=( + '(fg)bg[retry in the background]' + '(bg)fg[retry in the foreground]' + '(nogrpid)grpid[new file gets group ID of directory]' + '(grpid)nogrpid[new file gets fsgid of current process]' + '(nointr)intr[allow operations to be interrupted]' + '(intr)nointr[prevent operations from being interrupted]' + '(sec secure)kerberos[use kerberos authentication]' + 'noac[no attribute caching]' + 'port[server IP port number]:port' + 'posix[posix semantics]' + 'proto[specify protocol]:protocol:'\("$(grep -v '^#' /etc/netconfig 2> /dev/null | cut -d ' ' -f 1)"\) + 'public[force public file handle]' + '(noquota)quota[enable quotas]' + '(quota)noquota[disable quotas]' + 'timeo[specify initial timeout for UDP]:initial timeout for UDP' + 'retrans[set number of NFS retransmissions]:number of NFS retransmissions:(5)' + 'retry[specify number of mount failure retries]:mount failure retries:(10000)' + 'rsize[specify read buffer size]:read buffer size:(8192)' + 'wsize[specify write buffer size]:write buffer size:(8192)' + '(kerberos secure)sec[set the security mode]:security mode:(sys dh krb4 none)' + '(kerberos sec)secure[use Diffie-Hellman public key system]' + 'vers[set NFS version number]:NFS version number:(2 3)' + "$_nfs_access[@]" + "$_fs_s5fs[@]" + ) + _fs_cachefs=( + 'backfstype[type of the back file system]:back file system type:(nfs hsfs)' + 'backpath[specify back file system location]:back file system location:_files -/' + 'cacheid[specify a cache ID]:cache ID' + 'local-access[check permissions locally]' + 'noconst[disable cache consistency checking]' + 'purge[purge any cached information]' + '(suid)nosuid[ignore setuid and setgid bits]' + '(nosuid)suid[use setuid and setgid bits]' + '(write-around)non-shared[purge cache on writes]' + '(non-shared)write-around[keep file in cache on writes]' + "$_nfs_access[@]" + ) + ;; + osf*) + _fs_advfs=( + '(ro rw)rq[mount file system read-write]' + 'dual[allow mount even if same domain ID as already mounted domain]' + 'sync[do I/O synchronously]' + ) + _fs_cdfs=( + '(nodefperm)defperm[ignore permission bits]' + '(defperm)defperm[use permission bits]' + 'noversion[strip off version extension]' + 'rrip[use RRIP extensions]' + ) + _fs_nfs=( + "$_nfs_ufs[@]" + "$_fs_nfs[@]" + ) + ;; + linux*) + _fs_any=( + '(sync)async[do all I/O asynchronously]' + '(noatime)atime[update access time]' + '(noauto)auto[can be mounted with -a]' + '(rw suid dev exec auto nouser async)defaults[use default options]' + '(nodev)dev[interpret devices]' + '(noexec)exec[permit execution of binaries]' + "(atime)noatime[don't update access time]" + '(auto)noauto[can only be mounted explicitly]' + "(dev)nodev[don't interpret devices]" + "(exec)noexec[don't allow execution of binaries]" + '(suid)nosuid[ignore suid and sgid bits]' + '(user)nouser[can only be mounted by root]' + 'remount[mount already mounted file system]' + '(rw)ro[mount file system read-only]' + '(ro)rw[mount file system read-write]' + '(nosuid)suid[use suid and sgib bits]' + '(async)sync[do I/O synchronously]' + 'dirsync[perform directory updates synchronously]' + 'loop[use loopback device]:loopback device:_files' + 'encryption[enable encryption]:cypher' + 'keybits[set number of bits in encryption key]:key size:(64 128 160 192 256)' + 'offset[specify data start for loopback mount]:offset (bytes)' + ) + _fs_affs=( + 'uid[set owner of root]:user ID' + 'gid[set group of root]:group ID' + 'setuid[set owner of all files]:user ID' + 'setgid[set group of all files]:group ID' + 'mode[set file permissions]:file permission bits' + "protect[don't allow changes to permissions]" + 'usemp[set owner of root to owner of mount point]' + 'verbose[print message per mount]' + 'prefix[prefix before volume name when following link]:prefix string' + "volume[prefix before '/' when following link]:prefix string" + 'reserved[set number of unused blocks at start of device]:number of unused blocks' + 'root[specify location of the root block]:root block location' + 'bs[specify block size]:block size:(512 1024 2048 4192)' + ) + _fs_ext2=( + '(minixdf)bsddf[select bsddf behavior]' + '(bsddf)minixdf[select bsddf behavior]' + '(nocheck)check[set checking level]::checking level:((normal\:check\ inode\ and\ block\ bitmaps\ on\ mount strict\:check\ on block\ deallocation none\:no\ checking))' + 'debug[print debugging info upon each (re)mount]' + 'errors[specify behavior on error]:error behavior:((continue\:ignore\ errors remount-ro\:remount\ file\ system\ read-only panic\:panic\ and\ halt\ system))' + '(nogrpid bsdgroups sysvgroups)grpid[new file gets group ID of directory]' + '(grpid nogrpid sysvgroups)bsdgroups[new file gets group ID of directory]' + '(grpid bsdgroups sysvgroups)nogrpid[new file gets fsgid of current process]' + '(grpid bsdgroups nogrpid)sysvgroups[new file gets fsgid of current process]' + 'resgid[specify access to reserved space (group ID)]:group ID' + 'resuid[specify access to reserved space (user ID)]:user ID' + 'sb[specify super block number]:super block number' + 'nouid32[disable 32-bit UIDs and GIDs]' + ) + _fs_fat=( + 'blocksize[specify block size]:block size:(512 1024 2048)' + 'uid[specify user ID of all files]:user ID' + 'gid[specify group ID of all files]:group ID' + 'umask[specify umask]:umask value (octal)' + 'dmask[specify umask for directories only]:umask value (octal)' + 'fmask[specify umask for files only]:umask value (octal)' + 'check[specify checking level]:checking level:((relaxed\:accept\ upper\ and\ lower\ case,\ truncate\ long\ name normal\:like\ '"'\`'"'relaxed'"\\'"',\ but\ reject\ special\ characters strict\:like\ '"'\`'"'normal'"\\'"',\ but\ no\ long\ parts))' + 'codepage[specify codepage for converting filenames to short form]:codepage' + 'conf[specify CR/NL conversion]:CR/NL conversion mode:((binary\:no\ translation text\:conversion\ on\ all\ files auto\:perform\ translation\ on\ file\ without\ binary\ extension))' + 'conv[convert form of text files]:mode:(binary text auto)' + 'cvf_format[use specified compressed volume format module]:module' + 'cvf_option[pass option to CVF module]:option' + 'debug[debug mode]' + 'fat[specify fat type]:fat type (bit):(12 16 32)' + 'iocharset[character set to use for converting from 8 bit to unicode]:character set' + 'quiet[quiet mode]' + ) + _fs_ext3=( + "$_fs_ext2[@]" + 'journal[update fs journal]:update or inode number:(update)' + 'noload[do not load journal]' + 'data[specify mode for data]:journalling mode:(journal ordered writeback)' + ) + _fs_msdos=( "$_fs_fat[@]" ) + _fs_umsdos=( "$_fs_fat[@]" ) + _fs_vfat=( "$_fs_fat[@]" + '(utf8)uni_xlate[translate unicode to escaped sequences]' + 'posix[allow file names only differing in case]' + 'nonumtail[try short name before number extension]' + '(uni_xlate)utf8[mount the filesystem in UTF8 mode]' + 'shortname[specify handling of 8.3 filenames]:mode:(lower win95 winnt mixed)' + ) + _fs_hpfs=( + 'uid[specify user ID of all files]:user ID' + 'gid[specify group ID of all files]:group ID' + 'umask[specify umask]:umask value (octal)' + 'case[specify file name conversion]:file name conversion:((lower\:convert\ to\ lower\ case asis\:no\ conversion))' + 'conv[specify CR elimination]:CR elimination:((binary\:no\ elimination test\:delete\ CRs\ \(e.g.\ before\ NL\) auto\:sometimes\ yes,\ sometimes\ not))' + "nocheck[don't abort mount on consistency check failure]" + ) + _fs_iso9660=( + 'norock[disable Rock Ridge extensions]' + 'nojoliet[disable Microsoft Joliet extensions]' + 'check[specify file name conversion]:file name conversion:((relaxed\:convert\ to\ lower\ case\ before\ lookup strict\:no\ conversion))' + 'uid[specify user ID of all files]:user ID' + 'gid[specify group ID of all files]:group ID' + 'map[specify non-Rock Ridge name conversion]:file name conversion:((normal\:map\ upper\ to\ lower,\ ignore\ \;1,\ map\ \;\ to\ . off\:no\ conversion))' + 'mode[specify permissions]:file access permissions' + 'unhide[show hidden and associated files]' + 'block[specify block size]:block size:(512 1024 2048)' + 'cruft[ignore high bits of file length]' + 'session[select session number on multisession CD]:session' + 'sbsector[specify starting sector]:sector' + 'iocharset[character set when converting from 8 bit to unicode (Joliet)]:character set' + 'utf8[mount the filesystem in UTF8 mode (Joliet)]' + ) + _fs_ntfs=( + 'iocharset[character set to use when returning file names]:character set' + '(uni_xlate)utf8[use UTF-8 for converting file names]' + '(utf8)uni_xlate[translate unicode to escaped sequences]:type:(0 1 2)' + 'posix[distinguish upper and lower case]:state:((0\:off 1\:on))' + 'uid[specify user ID of all files]:user ID' + 'gid[specify group ID of all files]:group ID' + 'umask[specify umask]:umask value (octal)' + ) + _fs_reiserfs=( + 'conv[mount 3.5 fs using 3.6 format for new objects]' + 'hash[choose hash type]:hash function:(rupasov tea r5 detect)' + '(no_unhashed_relocation)hashed_relocation[tune the block allocator]' + 'noborder[disable border allocator algorithm]' + 'nolog[disable journalling]' + 'notail[disable packing of files into the tree]' + '(hashed_relocation)no_unhashed_relocation[tune the block allocator]' + 'replayonly[replay but do not mount]' + 'resize[assume the device has this many blocks]:number of blocks' + ) + _fs_smbfs=( "$_fs_nfs[@]" ) + _fs_tmpfs=( + 'size[set file system size]:size (bytes)' + 'mode[set root directory permissions]:mode' + 'nr_blocks[set number of blocks]:blocks' + 'nr_inodes[set number of inodes]:inodes' + ) + _fs_udf=( + 'uid[specify user ID of all files]:user ID' + 'gid[specify group ID of all files]:group ID' + 'umask[specify umask]:umask value (octal)' + 'unhide[show hidden and associated files]' + 'undelete[show deleted files]' + 'bs[set the block size]:block size:2048' + 'novrs[skip volume sequence recognition]' + 'session[set the CDROM session]:session' + 'anchor[override standard anchor location]:anchor location:256' + 'lastblock[set the last block of the file system]:last block' + ) + _fs_ufs=( + 'ufstype[set ufs type]:ufs type:(old 44bsd sun sunx86 nextstep nextstep-cd openstep)' + 'onerror[set behaviour on error]:behaviour on error:(panic lock umount repair)' + ) + _fs_xfs=( + 'biosize[specify preferred buffered I/O size]:base 2 logarithm:((13:8K 14:16K 15:32K 16:64K))' + '(xdsm)dmapi[enable DMAPI event callouts]' + '(dmapi)xdsm[enable DMAPI event callouts]' + 'logbufs[set number of in-memory log buffers]:(2 3 4 5 6 7 8)' + 'logbsize[set size of each in-memory log buffer]:(16384 32768)' + 'logdev[use external log device]:_files' + 'rtdev[use external realtime device]:_files' + 'noalign[do not align data allocations at stripe unit boundaries]' + 'noatime[do not update atime on reads]' + 'norecovery[do not run log recovery]' + 'osyncisdsync[make O_SYNC behave as O_DSYNC]' + '(usrquota uqnoenforce)quota[enable user quotas]' + '(quota uqnoenforce)usrquota[enable user quotas]' + '(quota usrquota)uqnoenforce[enable user quotas without enforcement]' + '(gqnoenforce)grpquota[enable group quotas]' + '(grpquota)gqnoenforce[enable group quotas without enforcement]' + 'sunit[specify stripe unit]:size' + 'swidth[specify stripe width]:size' + ) + ;; + freebsd*|dragonfly*) + _fs_any=( + '(sync)async[do all I/O asynchronously]' + 'current[use current options on already mounted file system]' + 'force[force R/W mount of unclean filesystem]' + 'fstab[use options listed in /etc/fstab]' + 'noasync[do I/O synchronously]' + "noatime[don't update access time]" + 'noauto[can only be mounted explicitly]' + 'noclusterr[disable read clustering]' + 'noclusterw[disable write clustering]' + "nodev[don't interpret devices]" + "noexec[don't allow execution of binaries]" + 'nosuid[ignore suid and sgid bits]' + "nosymfollow[don't follow symlinks]" + 'rdonly[mount file system read-only]' + '(async)sync[do all I/O synchronously]' + 'suiddir[allow suid bits on directories]' + 'update[change status of already mounted filesystem]' + 'union[cause the namespace at the mount point to appear as the union of the mounted filesystem and the existing directory]' + ) + _fs_iso9660=( + 'extatt[enable use of extended attributes]' + "gens[don't strip version number on files]" + "joliet[don't use any Joliet extensions]" + "rrip[don't use any Rockridge extensions]" + 'strictjoliet[relax checking for Supplementary Volume Descriptor Flags field which is set to a wrong value on some Joliet formatted disks]' + ) + _fs_std=( + "nodev[don't interpret devices]" + "noexec[don't allow execution of binaries]" + 'nosuid[ignore suid and sgid bits]' + 'rdonly[mount file system read-only]' + 'union[cause the namespace at the mount point to appear as the union of the mounted filesystem and the existing directory]' + ) + _fs_devfs=( "$_fs_std[@]" ) + _fs_fdesc=( "$_fs_std[@]" ) + _fs_kernfs=( "$_fs_std[@]" ) + _fs_linprocfs=( "$_fs_std[@]" ) + _fs_procfs=( "$_fs_std[@]" ) + _fs_msdos=( + 'shortnames[]' + 'longnames[]' + 'nowin95[]' + ) + ;; + esac +fi + +if [[ "$service" = mount ]]; then + + # Here are the tests and tables for the arguments and options for + # the `mount' program. This should set the `deffs' parameter if + # the default file system type is not `iso9660' (it should be set + # to the name of the default file system type), and set 'typeops' + # to the mount option for file system type selection when it is + # not '-t'. + + case "$OSTYPE" in + aix*) + args=( -s + '(:)-a[mount all filesystems in /etc/fstab]' + '-f[forced mount]' + '-n[remote node]:remote node:_hosts' + '-p[mount as removable file system]' + '-r[mount read-only]' + '-t[specify file system type]:file system type:_file_systems' + '-o[specify file system options]:file system option:->fsopt' + '-v[filesystem defined by /etc/vfs]:VfsName' + ':dev or dir:->devordir' + ':mount point:_files -/' + ) + deffs=jfs + ;; + irix*) + args=( -s + '-a[mount all filesystems in /etc/fstab]' + '-b[mount all filesystems in /etc/fstab except those listed]:list of directories:_dir_list -s,' + '-c[check any dirty filesystems before mounting]' + "-f[fake a new /etc/mtab entry, but don't mount any filesystems]" + '-h[mount all filesystems associated with host]:hostnames:_hosts' + '-n[mount filesystem without making entry in /etc/mtab]' + '-o[specify file system options]:file system option:->fsopt' + '-p[print list of mounted filesystems in format suitable for /etc/fstab]' + '-r[mount read-only]' + '-t[specify file system type]:file system type:_file_systems' + '-v[verbose]' + '-M[use alternate mtab]:alternate mtab:_files' + '-P[with -p, prepend prefix to paths]:prefix' + ) + deffs=efs + ;; + linux*) + args=( -s + '(- :)-h[show help]' + '(- :)-V[show version]' + '(-V -h)-v[verbose mode]' + '(-V -h)-p[specify file descriptor from which to read passphrase]:file descriptor:_file_descriptors' + '(-V -h -o :)-a[mount all filesystems in fstab]' + '(-V -h)-F[fork off one child per device]' + '(-V -h)-f[fake mount]' + "(-V -h)-i[don't call /sbin/mount. helper]" + '(-V -h)-l[output ext2, ext3 and XFS labels]' + "(-V -h)-n[don't write /etc/mtab]" + '(-V -h)-s[tolerate sloppy mount options]' + '(-V -h -w)-r[mount read-only]' + '(-V -h -r)-w[mount read/write]' + '(-V -h)-L[mount partition with specified label]:label' + '(-V -h)-U[mount partition with specified uuid]:uuid' + '(-V -h)-t[specify file system type]:file system type:->fslist' + '(-V -h)-O[with -a, restrict filesystems by options]:file system option:->fsopt' + '(-V -h -a -O)-o[specify file system options]:file system option:->fsopt' + '(: -)--bind[remount part of filesystem elsewhere]:old directory:_directories:new directory:_directories' + '(: -)--rbind[remount part of filesystem including submounts elsewhere]:old directory:_directories:new directory:_directories' + '(: -)--move[move part of filesystem elsewhere]:old directory:_directories:new directory:_directories' + ':dev or dir:->devordir' + ':mount point:_files -/' + ) + ;; + osf*) + args=( -s + '(-o :)-a[mount all filesystems in fstab]' + '-d[mount even if not unmounted]' + '-e[list all mount points]' + '-f[fake mount]' + '-l[display values of all file system options]' + '-t[specify file system type]:file system type:_file_systems' + '-o[specify file system options]:file system option:->fsopt' + '-u[remount file system]' + '-r[mount read-only]' + '-w[mount read/write]' + '-v[verbose]' + ':dev or dir:->devordir' + ':mount point:_files -/' + ) + deffs=cdfs + ;; + solaris*) + args=( -s + '(-p -v)-a[mount all filesystems in fstab]' + '(-p -v)-F[specify file system type]:file system type:_file_systems' + '(-a -v)-p[print mounted file systems]' + '(-p -a)-v[print mounted file systems verbosely]' + '(-p -v)-V[echo command-line but do not execute]' + "(-p -v)-m[don't write /etc/mnttab]" + '(-p -v)-g[mount globally]' + '(-p -v)-o[specify file system options]:file system option:->fsopt' + '(-p -v)-O[overlay mount]' + '(-p -v)-r[mount read-only]' + ':dev or dir:->devordir' + ':mount point:_files -/' + ) + deffs=hsfs + typeops=-F + ;; + freebsd*|dragonfly*) + args=( -s + '(:)-a[mount all filesystems in fstab]' + '-d[cause everything to be done except for the actual system call]' + '-f[forced mount]' + '-o[specify file system options]:file system option:->fsopt' + '-p[print mounted file systems]' + '-r[mount readonly]' + '-t[specify file system type]:file system type:->fslist' + '-u[change status of already mounted filesystem]' + '-v[verbose mode]' + '-w[mount read/write]' + ':dev or dir:->devordir' + ':mount point:_files -/' + ) + deffs=ufs + ;; + *) + # Default for all other systems. Dunno. + + args=( -s + '(-o :)-a[mount all filesystems in fstab]' + '-t[specify file system type]:file system type:_file_systems' + '-o[specify file system options]:file system option:->fsopt' + '-f[fake mount]' + ':dev or dir:->devordir' + ':mount point:_files -/' + ) + deffs=ufs + ;; + esac + + _arguments -C "$args[@]" && ret=0 + +else + + # Completion for umount. + + case "$OSTYPE" in + aix*) + args=( + '(*)-a[unmount all mounted file systems]' + '-f[force unmount]' + '-n[remote node]:remote node:_hosts' + '-t[specify file system type]:file system type:_file_systems' + '*:dev or dir:->udevordir' + ) + ;; + irix*) + args=( + '-a[unmount all mounted file systems]' + '-b[unmount all filesystems in /etc/fstab except those listed]:list of directories:_dir_list -s,' + '-h[unmount all filesystems associated with host]:hostnames:_hosts' + '-k[kill all processes with files open on filesystems before unmounting]' + '-t[unmount all filesystems of specified type]:file system type:_file_systems' + '-v[verbose]' + ) + ;; + linux*) + args=( + '(- *)-h[show help]' + '(- *)-V[show version]' + '(-V -h)-v[verbose mode]' + "(-V -h)-n[don't write /etc/mtab]" + '(-V -h)-r[remount read-only on failure]' + '(-V -h)-d[for loopback mount, free loop device]' + '(-V -h *)-a[unmount all file systems from /etc/mtab]' + '(-V -h)-t[specify file system type]:file system type:_file_systems' + '(-V -h *)-O[with -a, restrict filesystems by options]:file system option:->fsopt' + '(-V -h)-f[force unmount]' + '(-V -h)-l[lazy unmount]' + '*:dev or dir:->udevordir' + ) + ;; + freebsd*|dragonfly*) + args=( + '(*)-a[unmount all mounted file systems]' + '-A[unmount all mounted file systems except the root]' + '-f[force unmount]' + '-h[unmount all filesystems associated with host]:hostnames:_hosts' + '-t[unmount all filesystems of specified type]:file system type:->fslist' + '-v[verbose mode]' + '*:dev or dir:->udevordir' + ) + ;; + solaris*) + args=( + '-a[unmount all mounted file systems]' + '-f[force unmount]' + '-V[echo command-line but do not execute]' + '-o[specify file system options]:file system option:->fsopt' + '*:dev or dir:->udevordir' + ) + ;; + *) + args=( + '-v[verbose mode]' + '(*)-a[unmount all file systems from /etc/mtab]' + '-t[specify file system type]:file system type:_file_systems' + '*:dev or dir:->udevordir' + ) + ;; + esac + + _arguments -C -s "$args[@]" && ret=0 + +fi + +case "$state" in +fslist) + compset -P '*,' + compset -S ',*' || suf=',' + _file_systems -qS "$suf" +;; +fsopt) + _tags options || return 1 + + eval 'tmp=(' '"$_fs_'${(s:,:)^${opt_args[$typeops]:-${deffs}}}'[@]"' ')' + tmp=( "$_fs_any[@]" "${(@)tmp:#}" ) + _values -s , 'file system option' "$tmp[@]" && ret=0 + ;; +devordir) + local dev_tmp mp_tmp mline + + if compset -P '*:'; then + _wanted exports expl 'exported path' compadd \ + ${${(f)"$(path+=( {/usr,}/sbin(N) ) _call_program exports \ + showmount -e ${IPREFIX%:} 2>/dev/null)"}[2,-1]%% *} && ret=0 + return ret + fi + if compset -S ':*'; then + _hosts -S '' && ret=0 + return ret + fi + + case "$OSTYPE" in + freebsd*|dragonfly*) + while read mline; do + case $mline[(w)1] in + \#* ) + ;; + proc) + ;; + *) + [[ $mline[(w)3] == swap ]] || \ + dev_tmp=( $dev_tmp $mline[(w)1] ) \ + mp_tmp=( $mp_tmp $mline[(w)2] ) + ;; + esac + done < /etc/fstab + + _alternative \ + 'hosts:host:_hosts -S :' \ + 'devices:device:compadd -a dev_tmp' \ + 'directories:mount point:compadd -a mp_tmp' && ret=0 + ;; + *) + if (( ${${(s.,.)opt_args[-o]}[(I)loop(|=*)]} )) ; then + _wanted device-files expl 'loop device file' _files && ret=0 + else + _alternative \ + 'hosts:host:_hosts -S :' \ + 'files:device or mount point:_files -g "*(-%b,-/)"' && ret=0 + fi + ;; + esac + ;; +udevordir) + local dev_tmp mp_tmp mline + + case "$OSTYPE" in + linux*|irix*) + tmp=( "${(@f)$(< /etc/mtab)}" ) + dev_tmp=( "${(@)${(@)tmp%% *}:#none}" ) + mp_tmp=( "${(@)${(@)tmp#* }%% *}" ) + ;; + *) + /sbin/mount | while read mline; do + mp_tmp=( $mp_tmp $mline[(w)1] ) + dev_tmp=( $dev_tmp $mline[(w)3] ) + done + ;; + esac + + _alternative \ + 'devices:device:compadd -a dev_tmp' \ + 'directories:mount point:compadd -a mp_tmp' && ret=0 + ;; +esac + +return ret diff --git a/Completion/Unix/Command/_mt b/Completion/Unix/Command/_mt new file mode 100644 index 000000000..01b27634f --- /dev/null +++ b/Completion/Unix/Command/_mt @@ -0,0 +1,80 @@ +#compdef mt + +local -a args cmds +local state line curcontext="$curcontext" ret=1 + +args=( '(-)-f[specify raw tape device]:tape device:_files' ) +cmds=( + {eof,weof}':write specified number of EOF marks at current position' + 'fsf:forward space by specified number of files' + 'fsr:forward space by specified number of records' + 'bsf:backward space by specified number of files' + 'bsr:backward space by specified number of records' + 'asf:absolute space to specified file number' + 'eom:go to end of recorded media on the tape' + 'rewind:rewind the tape' + {offline,rewoffl}':rewind and unload the tape' + 'status:print status information about the tape unit' + 'retension:rewind, wind to end of reel, rewind again - smoothes tape tension' + 'erase:erase the tape' +) + +if _pick_variant gnu=GNU unix --version; then + args=( + '(1 2 -)'{-V,--version}'[print version info]' + '(1 2 -)--help[display usage info]' + '(-V --version --help -f --file)'{-f,--file=}'[specify raw tape device]:tape device:_files' + '(-V --version --help)--rsh-command=[specify remote shell command]:rsh command:_command_names -e' + ) + # should really allow remote user@host for tape device + cmds+=( + 'bsfm:backward space by specified number of file marks' + 'fsfm:forward space by specified number of file marks' + 'fss:forward space by specified number of setmarks' + 'bss:backward space by specified number of setmarks' + 'wset:write specified number of setmarks at current position' + {eod,seod}':space to end of valid data' + 'setblk:set drive block size' + 'setdensity:set tape density code' + 'drvbuffer:set drive buffer code' + 'stoptions:set driver option bits' + 'stwrthreshold:set device write threshold' + 'seek:seek to specified block' + 'tell:tell the current block on tape' + 'densities:explain some common density codes' + 'datcompression:enquire or set compression status' + ) +elif [[ $OSTYPE = (freebsd|dragonfly)* ]]; then + cmds=( ${cmds:#(asf|eof):*} + 'smk:write specified number of setmarks at current position' + 'fss:forward space by specified number of setmarks' + 'bss:backward space by specified number of setmarks' + 'rdhpos:read hardware block position' + 'rdspos:read SCSI logical block position' + 'sethpos:set hardware block position' + 'setspos:set SCSI logical block position' + 'errstat:print error status info about device' + 'blocksize:set drive block size' + 'density:set tape density code' + 'geteotmodel:print the current EOT filemark model' + 'seteotmodel:set the current EOT filemark model' + 'eod:go to end of recorded media on the tape' + 'comp:set compression mode' + ) +elif [[ $OSTYPE = solaris* ]]; then + cmds+=( + 'nbsf:back space by specified number of files positioning at file start' + 'reserve:allow drive to remain reserved after close until explicit release' + 'release:re-establish release at close behaviour' + ) + if (( ! EUID )); then + cmds+=( 'forcereserve:break reservation of tape drive held by other host' ) + fi +fi + +_arguments -C "$args[@]" '(--help --version -V)1:operation:->operation' \ + '2:count:' && ret=0 + +[[ -n "$state" ]] && _describe -t operations 'operation' cmds && ret=0 + +return ret diff --git a/Completion/Unix/Command/_sysctl b/Completion/Unix/Command/_sysctl new file mode 100644 index 000000000..99870b405 --- /dev/null +++ b/Completion/Unix/Command/_sysctl @@ -0,0 +1,45 @@ +#compdef sysctl + +case $OSTYPE in + freebsd[5-9].*|freebsd4.[4-9]*) + local -a sysctlvars + sysctlvars=( $(sysctl -aN) ) + _arguments -s -A "-*" \ + '(*)-a[list all]' \ + '-b[binary output]' \ + '(-n)-N[show only variable names]' \ + '(-N)-n[show only variable values]' \ + '(-x)-o[show opaques as well (values suppressed)]' \ + '(-o)-x[show opaques as well (entire values)]' \ + '(-a)*:sysctl variable:_multi_parts -i . sysctlvars' + ;; + freebsd[0-4].*|darwin*|dragonfly*) + : ${(A)_cache_sysctlvars:=${${$(sysctl -A 2>/dev/null):#[^a-z]*}%%:*}} + _arguments -s -A "-*" \ + '(-w -X *)-a[list all]' \ + '(-w -X *)-A[show all opaques (values suppressed)]' \ + '(-w)-b[binary output]' \ + '(-w)-n[show only variable values]' \ + '(-a -A -b -n -X)-w[write mode]' \ + '(-a -A -w *)-X[show all opaques (entire values)]' \ + '(-a -A -X)*:sysctl variable:_multi_parts ${words[(r)-w]:+-S=} -i . _cache_sysctlvars' + ;; + linux*) + _arguments -A "-*" \ + '-n[show only variable values]' \ + '(-n -p -a -A)-w[write mode]' \ + '(-n -w -a -A *)-p[specify file to load sysctl settings from]:file:_files' \ + '(-n -w -p -A *)-a[list all]' \ + '(-n -w -p -a *)-A[list all in table form]' \ + '(-n -p -a -A)*:sysctl variable:_files -W /proc/sys' + ;; + openbsd*) + : ${(A)_cache_sysctlvars:=${${(f)"$(sysctl -a)"}%% *}} + _arguments -s -A "-*" \ + '(-w -A *)-a[list all string and integer variables]' \ + '(-w -a *)-A[list all known variables]' \ + '(-w)-n[show only values]' \ + '(-a -A -n)-w[write variable]' \ + '(-a -A)*:sysctl variable:_multi_parts ${words[(r)-w]:+-S=} -i . _cache_sysctlvars' + ;; +esac diff --git a/Completion/Unix/Type/_file_systems b/Completion/Unix/Type/_file_systems new file mode 100644 index 000000000..d541fac15 --- /dev/null +++ b/Completion/Unix/Type/_file_systems @@ -0,0 +1,37 @@ +#autoload + +local fss + +case $OSTYPE in + aix*) fss=( jfs nfs cdrfs ) ;; + irix*) fss=( efs proc fd nfs iso9660 dos hfs cachefs xfs ) ;; + linux*) + typeset -aU fss + fss=( adfs bfs cramfs ext2 ext3 hfs hpfs iso9660 minix ntfs qnx4 + reiserfs romfs swap udf ufs vxfs xfs xiafs ) + [[ -r /proc/filesystems ]] && + fss=( $fss ${$( +#endif + +#if defined(I_FIND) && defined(I_PUSH) +/* + * These tests are ad hoc. Unfortunately if you get the wrong ioctl, + * STREAMS simply hangs up, so there's no obvious way of doing this + * more systematically. + * + * Apparently Solaris needs all three ioctls, but HP-UX doesn't need + * ttcompat. The Solaris definition has been extended to all __SVR4 + * as a guess; I have no idea if this is right. + */ +#ifdef __SVR4 +#define USE_STREAMS_IOCTLS +#define USE_STREAMS_TTCOMPAT +#endif +#ifdef __hpux +#define USE_STREAMS_IOCTLS +#endif +#endif static int -get_pty(int *master, int *slave) +get_pty(int master, int *retfd) { - int mfd, sfd; - char *name; + static char *name; + static int mfd, sfd; +#ifdef USE_STREAMS_IOCTLS int ret; +#endif - if ((mfd = open("/dev/ptmx", O_RDWR)) < 0) - return 1; + if (master) { + if ((mfd = open("/dev/ptmx", O_RDWR|O_NOCTTY)) < 0) + return 1; - if (grantpt(mfd) || unlockpt(mfd) || !(name = ptsname(mfd))) { - close(mfd); - return 1; + if (grantpt(mfd) || unlockpt(mfd) || !(name = ptsname(mfd))) { + close(mfd); + return 1; + } + *retfd = mfd; + + return 0; } - if ((sfd = open(name, O_RDWR)) < 0) { + if ((sfd = open(name, O_RDWR +#ifndef __CYGWIN__ + /* It is not clear whether this flag is actually needed. */ + |O_NOCTTY +#endif + )) < 0) { close(mfd); return 1; } +#ifdef USE_STREAMS_IOCTLS if ((ret = ioctl(sfd, I_FIND, "ptem")) != 1) if (ret == -1 || ioctl(sfd, I_PUSH, "ptem") == -1) { close(mfd); @@ -199,81 +222,127 @@ get_pty(int *master, int *slave) close(sfd); return 1; } +#ifdef USE_STREAMS_TTCOMPAT if ((ret = ioctl(sfd, I_FIND, "ttcompat")) != 1) if (ret == -1 || ioctl(sfd, I_PUSH, "ttcompat") == -1) { close(mfd); close(sfd); return 1; } - *master = mfd; - *slave = sfd; +#endif +#endif + + *retfd = sfd; return 0; } -#else /* ! (defined(__SVR4) || defined(sinix)) */ +#else /* No /dev/ptmx or no pt functions */ static int -get_pty(int *master, int *slave) +get_pty(int master, int *retfd) { #ifdef __linux static char char1[] = "abcdefghijklmnopqrstuvwxyz"; static char char2[] = "0123456789abcdef"; -#else /* ! __linux */ - static char char1[] = "pq"; +#elif defined(__FreeBSD__) || defined(__DragonFly__) + static char char1[] = "pqrsPQRS"; + static char char2[] = "0123456789abcdefghijklmnopqrstuv"; +#else /* __FreeBSD__ || __DragonFly__ */ + static char char1[] = "pqrstuvwxyzPQRST"; static char char2[] = "0123456789abcdef"; -#endif /* __linux */ +#endif - char name[11], *p1, *p2; - int mfd, sfd; + static char name[11]; + static int mfd, sfd; + char *p1, *p2; - strcpy(name, "/dev/ptyxx"); + if (master) { + strcpy(name, "/dev/ptyxx"); - for (p1 = char1; *p1; p1++) { - name[8] = *p1; - for (p2 = char2; *p2; p2++) { - name[9] = *p2; - if ((mfd = open(name, O_RDWR)) >= 0) { - name[5] = 't'; - if ((sfd = open(name, O_RDWR)) >= 0) { - *master = mfd; - *slave = sfd; + for (p1 = char1; *p1; p1++) { + name[8] = *p1; + for (p2 = char2; *p2; p2++) { + name[9] = *p2; + if ((mfd = open(name, O_RDWR|O_NOCTTY)) >= 0) { + *retfd = mfd; return 0; } - name[5] = 'p'; - close(mfd); } } } + name[5] = 't'; + if ((sfd = open(name, O_RDWR|O_NOCTTY)) >= 0) { + *retfd = sfd; + + return 0; + } + close(mfd); + return 1; } -#endif /* __SVR4 */ -#endif /* __osf__ */ +#endif /* /dev/ptmx or alternatives */ static int -newptycmd(char *nam, char *pname, char **args, int echo, int block) +newptycmd(char *nam, char *pname, char **args, int echo, int nblock) { Ptycmd p; int master, slave, pid; - char *cmd; + Eprog prog; - if (!(cmd = findcmd(*args, 1))) { - zwarnnam(nam, "unknown command: %s", *args, 0); + prog = parse_string(zjoin(args, ' ', 1)); + if (!prog) { + errflag = 0; return 1; } - if (get_pty(&master, &slave)) { - zwarnnam(nam, "can't open pseudo terminal", NULL, 0); + + if (get_pty(1, &master)) { + zwarnnam(nam, "can't open pseudo terminal: %e", NULL, errno); return 1; } if ((pid = fork()) == -1) { + zwarnnam(nam, "can't create pty command %s: %e", pname, errno); close(master); - close(slave); - zwarnnam(nam, "couldn't create pty command: %s", pname, 0); return 1; } else if (!pid) { + /* This code copied from the clone module, except for getting * + * the descriptor from get_pty() and duplicating it to 0/1/2. */ + + clearjobtab(0); + ppid = getppid(); + mypid = getpid(); +#ifdef HAVE_SETSID + if (setsid() != mypid) { + zwarnnam(nam, "failed to create new session: %e", NULL, errno); +#endif +#ifdef TIOCNOTTY + if (ioctl(SHTTY, TIOCNOTTY, 0)) + zwarnnam(nam, "%e", NULL, errno); + setpgrp(0L, mypid); +#endif +#ifdef HAVE_SETSID + } +#endif + + if (get_pty(0, &slave)) + exit(1); +#ifdef TIOCGWINSZ + /* Set the window size before associating with the terminal * + * so that we don't get hit with a SIGWINCH. I'm paranoid. */ + if (interact) { + struct ttyinfo info; + + if (ioctl(slave, TIOCGWINSZ, (char *) &info.winsize) == 0) { + info.winsize.ws_row = lines; + info.winsize.ws_col = columns; + ioctl(slave, TIOCSWINSZ, (char *) &info.winsize); + } + } +#endif /* TIOCGWINSZ */ + if (!echo) { struct ttyinfo info; @@ -291,21 +360,9 @@ newptycmd(char *nam, char *pname, char **args, int echo, int block) } } -#ifdef TIOCGWINSZ - if (interact) { - struct ttyinfo info; - - if (ioctl(slave, TIOCGWINSZ, (char *) &info.winsize) == 0) { - info.winsize.ws_row = lines; - info.winsize.ws_col = columns; - ioctl(slave, TIOCSWINSZ, (char *) &info.winsize); - } - } -#endif /* TIOCGWINSZ */ - - signal_default(SIGTERM); - signal_default(SIGINT); - signal_default(SIGQUIT); +#ifdef TIOCSCTTY + ioctl(slave, TIOCSCTTY, 0); +#endif close(0); close(1); @@ -315,15 +372,20 @@ newptycmd(char *nam, char *pname, char **args, int echo, int block) dup2(slave, 1); dup2(slave, 2); + closem(0); close(slave); - - setpgrp(0L, getpid()); - - execve(cmd, args, environ); - exit(0); + close(master); + close(coprocin); + close(coprocout); + init_io(); + setsparam("TTY", ztrdup(ttystrname)); + + opts[INTERACTIVE] = 0; + execode(prog, 1, 0); + stopmsg = 2; + zexit(lastval, 0); } master = movefd(master); - close(slave); p = (Ptycmd) zalloc(sizeof(*p)); @@ -332,13 +394,16 @@ newptycmd(char *nam, char *pname, char **args, int echo, int block) p->fd = master; p->pid = pid; p->echo = echo; - p->block = block; + p->nblock = nblock; p->fin = 0; + p->read = -1; + p->old = NULL; + p->olen = 0; p->next = ptycmds; ptycmds = p; - if (!block) + if (nblock) ptynonblock(master); return 0; @@ -362,12 +427,12 @@ deleteptycmd(Ptycmd cmd) zsfree(p->name); freearray(p->args); + zclose(cmd->fd); + /* We kill the process group the command put itself in. */ kill(-(p->pid), SIGHUP); - zclose(cmd->fd); - zfree(p, sizeof(*p)); } @@ -387,17 +452,26 @@ deleteallptycmds(void) static void checkptycmd(Ptycmd cmd) { - if (kill(cmd->pid, 0) < 0) { - cmd->fin = 1; - zclose(cmd->fd); + char c; + int r; + + if (cmd->read != -1 || cmd->fin) + return; + if ((r = read(cmd->fd, &c, 1)) < 0) { + if (kill(cmd->pid, 0) < 0) { + cmd->fin = 1; + zclose(cmd->fd); + } + return; } + if (r) cmd->read = (int) c; } static int ptyread(char *nam, Ptycmd cmd, char **args) { - int blen = 256, used = 0, ret = 1; - char *buf = (char *) zhalloc(blen + 1); + int blen, used, seen = 0, ret = 0; + char *buf; Patprog prog = NULL; if (*args && args[1]) { @@ -414,6 +488,25 @@ ptyread(char *nam, Ptycmd cmd, char **args) zwarnnam(nam, "bad pattern: %s", args[1], 0); return 1; } + } else + fflush(stdout); + + if (cmd->old) { + used = cmd->olen; + buf = (char *) zhalloc((blen = 256 + used) + 1); + memcpy(buf, cmd->old, cmd->olen); + zfree(cmd->old, cmd->olen); + cmd->old = NULL; + cmd->olen = 0; + } else { + used = 0; + buf = (char *) zhalloc((blen = 256) + 1); + } + if (cmd->read != -1) { + buf[used] = (char) cmd->read; + buf[used + 1] = '\0'; + seen = used = 1; + cmd->read = -1; } do { if (!ret) { @@ -421,84 +514,94 @@ ptyread(char *nam, Ptycmd cmd, char **args) if (cmd->fin) break; } - if ((ret = read(cmd->fd, buf + used, 1)) == 1) { + if (cmd->read != -1 || (ret = read(cmd->fd, buf + used, 1)) == 1) { + if (cmd->read != -1) { + ret = 1; + buf[used] = (char) cmd->read; + cmd->read = -1; + } + seen = 1; if (++used == blen) { - buf = hrealloc(buf, blen, blen << 1); - blen <<= 1; + if (!*args) { + write(1, buf, used); + used = 0; + } else { + buf = hrealloc(buf, blen, blen << 1); + blen <<= 1; + } } } buf[used] = '\0'; - /**** Hm. If we leave the loop when ret < 0 the user would have - * to make sure that `zpty -r' is tried more than once if - * there will be some output and we only got the ret == -1 - * because the output is not yet available. - * The same for the `write' below. */ + if (!prog && (ret <= 0 || (*args && buf[used - 1] == '\n'))) + break; + } while (!(errflag || breaks || retflag || contflag) && + used < READ_MAX && !(prog && ret && pattry(prog, buf))); - if (ret < 0 && (cmd->block + if (prog && ret < 0 && #ifdef EWOULDBLOCK - || errno != EWOULDBLOCK + errno == EWOULDBLOCK #else #ifdef EAGAIN - || errno != EAGAIN + errno == EAGAIN #endif #endif - )) - break; - - if (!prog && !ret) - break; - } while (!errflag && - (prog ? (used < READ_MAX && (!ret || !pattry(prog, buf))) : - (used < READ_LEN))); + ) { + cmd->old = (char *) zalloc(cmd->olen = used); + memcpy(cmd->old, buf, cmd->olen); + return 1; + } if (*args) setsparam(*args, ztrdup(metafy(buf, used, META_HREALLOC))); - else { - fflush(stdout); + else if (used) write(1, buf, used); - } - return !used; + + return (seen ? 0 : cmd->fin + 1); } static int ptywritestr(Ptycmd cmd, char *s, int len) { - int written; + int written, all = 0; - for (; len; len -= written, s += written) { - if ((written = write(cmd->fd, s, len)) < 0 && - (cmd->block + for (; !errflag && !breaks && !retflag && !contflag && len; + len -= written, s += written) { + if ((written = write(cmd->fd, s, len)) < 0 && cmd->nblock && #ifdef EWOULDBLOCK - || errno != EWOULDBLOCK + errno == EWOULDBLOCK #else #ifdef EAGAIN - || errno != EAGAIN + errno == EAGAIN #endif #endif - )) - return 1; + ) + return !all; if (written < 0) { checkptycmd(cmd); if (cmd->fin) break; written = 0; } + if (written > 0) + all += written; } - return 0; + return (all ? 0 : cmd->fin + 1); } static int ptywrite(Ptycmd cmd, char **args, int nonl) { if (*args) { - char sp = ' '; + char sp = ' ', *tmp; + int len; - while (*args) - if (ptywritestr(cmd, *args, strlen(*args)) || + while (*args) { + unmetafy((tmp = dupstring(*args)), &len); + if (ptywritestr(cmd, tmp, len) || (*++args && ptywritestr(cmd, &sp, 1))) return 1; - + } if (!nonl) { sp = '\n'; if (ptywritestr(cmd, &sp, 1)) @@ -517,19 +620,23 @@ ptywrite(Ptycmd cmd, char **args, int nonl) /**/ static int -bin_zpty(char *nam, char **args, char *ops, int func) +bin_zpty(char *nam, char **args, Options ops, UNUSED(int func)) { - if ((ops['r'] && ops['w']) || - ((ops['r'] || ops['w']) && (ops['d'] || ops['e'] || - ops['b'] || ops['L'])) || - (ops['n'] && (ops['b'] || ops['e'] || ops['r'] || - ops['d'] || ops['L'])) || - (ops['d'] && (ops['b'] || ops['e'] || ops['L'])) || - (ops['L'] && (ops['b'] || ops['e']))) { + if ((OPT_ISSET(ops,'r') && OPT_ISSET(ops,'w')) || + ((OPT_ISSET(ops,'r') || OPT_ISSET(ops,'w')) && + (OPT_ISSET(ops,'d') || OPT_ISSET(ops,'e') || + OPT_ISSET(ops,'b') || OPT_ISSET(ops,'L'))) || + (OPT_ISSET(ops,'w') && OPT_ISSET(ops,'t')) || + (OPT_ISSET(ops,'n') && (OPT_ISSET(ops,'b') || OPT_ISSET(ops,'e') || + OPT_ISSET(ops,'r') || OPT_ISSET(ops,'t') || + OPT_ISSET(ops,'d') || OPT_ISSET(ops,'L'))) || + (OPT_ISSET(ops,'d') && (OPT_ISSET(ops,'b') || OPT_ISSET(ops,'e') || + OPT_ISSET(ops,'L') || OPT_ISSET(ops,'t'))) || + (OPT_ISSET(ops,'L') && (OPT_ISSET(ops,'b') || OPT_ISSET(ops,'e')))) { zwarnnam(nam, "illegal option combination", NULL, 0); return 1; } - if (ops['r'] || ops['w']) { + if (OPT_ISSET(ops,'r') || OPT_ISSET(ops,'w')) { Ptycmd p; if (!*args) { @@ -539,13 +646,16 @@ bin_zpty(char *nam, char **args, char *ops, int func) zwarnnam(nam, "no such pty command: %s", *args, 0); return 1; } - checkptycmd(p); if (p->fin) + return 2; + if (OPT_ISSET(ops,'t') && p->read == -1 && + !read_poll(p->fd, &p->read, 0, 0)) return 1; - return (ops['r'] ? + + return (OPT_ISSET(ops,'r') ? ptyread(nam, p, args + 1) : - ptywrite(p, args + 1, ops['n'])); - } else if (ops['d']) { + ptywrite(p, args + 1, OPT_ISSET(ops,'n'))); + } else if (OPT_ISSET(ops,'d')) { Ptycmd p; int ret = 0; @@ -561,6 +671,18 @@ bin_zpty(char *nam, char **args, char *ops, int func) deleteallptycmds(); return ret; + } else if (OPT_ISSET(ops,'t')) { + Ptycmd p; + + if (!*args) { + zwarnnam(nam, "missing pty command name", NULL, 0); + return 1; + } else if (!(p = getptycmd(*args))) { + zwarnnam(nam, "no such pty command: %s", *args, 0); + return 1; + } + checkptycmd(p); + return p->fin; } else if (*args) { if (!args[1]) { zwarnnam(nam, "missing command", NULL, 0); @@ -570,16 +692,17 @@ bin_zpty(char *nam, char **args, char *ops, int func) zwarnnam(nam, "pty command name already used: %s", *args, 0); return 1; } - return newptycmd(nam, *args, args + 1, ops['e'], ops['b']); + return newptycmd(nam, *args, args + 1, OPT_ISSET(ops,'e'), + OPT_ISSET(ops,'b')); } else { Ptycmd p; char **a; for (p = ptycmds; p; p = p->next) { checkptycmd(p); - if (ops['L']) + if (OPT_ISSET(ops,'L')) printf("%s %s%s%s ", nam, (p->echo ? "-e " : ""), - (p->block ? "-b " : ""), p->name); + (p->nblock ? "-b " : ""), p->name); else if (p->fin) printf("(finished) %s: ", p->name); else @@ -596,19 +719,19 @@ bin_zpty(char *nam, char **args, char *ops, int func) } static int -ptyhook(Hookdef d, void *dummy) +ptyhook(UNUSED(Hookdef d), UNUSED(void *dummy)) { deleteallptycmds(); return 0; } static struct builtin bintab[] = { - BUILTIN("zpty", 0, bin_zpty, 0, -1, 0, "ebdrwLn", NULL), + BUILTIN("zpty", 0, bin_zpty, 0, -1, 0, "ebdrwLnt", NULL), }; /**/ int -setup_(Module m) +setup_(UNUSED(Module m)) { return 0; } @@ -635,7 +758,7 @@ cleanup_(Module m) /**/ int -finish_(Module m) +finish_(UNUSED(Module m)) { return 0; } diff --git a/configure.ac b/configure.ac index da38620d0..b209c76da 100644 --- a/configure.ac +++ b/configure.ac @@ -2172,7 +2172,7 @@ char *argv[]; esac fi case "$host_os" in - freebsd*|linux*|irix*|osf*|gnu*) DLLDFLAGS="${DLLDFLAGS=-shared}" ;; + freebsd*|linux*|irix*|osf*|gnu*|dragonfly*) DLLDFLAGS="${DLLDFLAGS=-shared}" ;; sunos*) DLLDFLAGS="${DLLDFLAGS=-assert nodefinitions}" ;; sysv4*|esix*) DLLDFLAGS="${DLLDFLAGS=-G $ldflags}" ;; netbsd*) DLLDFLAGS="${DLLDFLAGS=${DLLDARG}-x -shared --whole-archive}" ;; -- cgit 1.4.1