diff options
Diffstat (limited to 'Functions/Zftp')
-rw-r--r-- | Functions/Zftp/zfanon | 29 | ||||
-rw-r--r-- | Functions/Zftp/zfautocheck | 12 | ||||
-rw-r--r-- | Functions/Zftp/zfcd | 12 | ||||
-rw-r--r-- | Functions/Zftp/zfcd_match | 12 | ||||
-rw-r--r-- | Functions/Zftp/zfcget | 30 | ||||
-rw-r--r-- | Functions/Zftp/zfdir | 30 | ||||
-rw-r--r-- | Functions/Zftp/zffcache | 24 | ||||
-rw-r--r-- | Functions/Zftp/zfgcp | 33 | ||||
-rw-r--r-- | Functions/Zftp/zfget | 34 | ||||
-rw-r--r-- | Functions/Zftp/zfget_match | 33 | ||||
-rw-r--r-- | Functions/Zftp/zfgoto | 31 | ||||
-rw-r--r-- | Functions/Zftp/zfinit | 22 | ||||
-rw-r--r-- | Functions/Zftp/zfmark | 5 | ||||
-rw-r--r-- | Functions/Zftp/zfopen | 30 | ||||
-rw-r--r-- | Functions/Zftp/zfparams | 22 | ||||
-rw-r--r-- | Functions/Zftp/zfpcp | 5 | ||||
-rw-r--r-- | Functions/Zftp/zfrglob | 10 | ||||
-rw-r--r-- | Functions/Zftp/zfsession | 71 | ||||
-rw-r--r-- | Functions/Zftp/zfstat | 29 | ||||
-rw-r--r-- | Functions/Zftp/zftp_chpwd | 26 | ||||
-rw-r--r-- | Functions/Zftp/zftp_progress | 12 | ||||
-rw-r--r-- | Functions/Zftp/zftransfer | 62 | ||||
-rw-r--r-- | Functions/Zftp/zfuget | 50 | ||||
-rw-r--r-- | Functions/Zftp/zfuput | 42 |
24 files changed, 383 insertions, 283 deletions
diff --git a/Functions/Zftp/zfanon b/Functions/Zftp/zfanon index 9624d48d9..f5754dda6 100644 --- a/Functions/Zftp/zfanon +++ b/Functions/Zftp/zfanon @@ -2,31 +2,19 @@ emulate -L zsh -local opt optlist once dir +local opt opt_1 dir -while [[ $1 = -* ]]; do - if [[ $1 = - || $1 = -- ]]; then - shift; - break; - fi - optlist=${1#-} - for (( i = 1; i <= $#optlist; i++)); do - opt=$optlist[$i] - case $optlist[$i] in - 1) once=1 - ;; - *) print option $opt not recognised >&2 - ;; - esac - done - shift +while getopts :1 opt; do + [[ $opt = "?" ]] && print "zfanon: bad option: -$OPTARG" >&2 && return 1 + eval "opt_$opt=1" done +(( OPTIND > 1 )) && shift $(( OPTIND - 1 )) if [[ -z $EMAIL_ADDR ]]; then # Exercise in futility. There's a poem by Wallace Stevens # called something like `N ways of looking at a blackbird', # where N is somewhere around 0x14 to 0x18. Now zftp is - # ashamed to prsent `N ways of looking at a hostname'. + # ashamed to present `N ways of looking at a hostname'. local domain host # First, maybe we've already got it. Zen-like. if [[ $HOST = *.* ]]; then @@ -38,7 +26,8 @@ if [[ -z $EMAIL_ADDR ]]; then [[ -n $domain ]] && host=$HOST.$domain fi # Next, maybe we've got nlsookup. May not work on LINUX. - [[ -z $host ]] && host=$(nslookup $HOST | awk '/Name:/ { print $2 }') + [[ -z $host ]] && host=$(nslookup $HOST 2>/dev/null | + awk '/Name:/ { print $2 }') if [[ -z $host ]]; then # we're running out of ideas, but this should work. # after all, i wrote it... @@ -67,7 +56,7 @@ if [[ $1 = */* ]]; then 1=${1%%/*} fi -if [[ $once = 1 ]]; then +if [[ $opt_1 = 1 ]]; then zftp open $1 anonymous $EMAIL_ADDR || return 1 else zftp params $1 anonymous $EMAIL_ADDR diff --git a/Functions/Zftp/zfautocheck b/Functions/Zftp/zfautocheck index d06beca4f..993e84ebf 100644 --- a/Functions/Zftp/zfautocheck +++ b/Functions/Zftp/zfautocheck @@ -11,9 +11,12 @@ # command, which implies we are looking for something so should stay open # for it. -# Remember the old session: zflastsession will be overwritten by +# Remember the old location: will be overwritten by # a successful open. -local lastsession=$zflastsession +local lastloc=$zfconfig[lastloc_$ZFTP_SESSION] + +# Don't print out user messages when re-opening the connection. +local ZFTP_VERBOSE=${ZFTP_VERBOSE//0} # Unset the delay counter from the progress meter in case there was an # abnormal exit. @@ -30,8 +33,9 @@ fi if [[ $1 = *n* ]]; then return 0 -elif [[ -n $lastsession && $ZFTP_HOST = ${lastsession%%:*} ]]; then - zfcd ${lastsession#*:} +elif [[ -n $lastloc && $ZFTP_HOST = ${lastloc%%:*} ]]; then + # don't print directory since we're just going back where we were. + zfcd ${lastloc#*:} >& /dev/null fi # } diff --git a/Functions/Zftp/zfcd b/Functions/Zftp/zfcd index b726d9f55..2ecc8b0f6 100644 --- a/Functions/Zftp/zfcd +++ b/Functions/Zftp/zfcd @@ -22,9 +22,9 @@ emulate -L zsh if [[ $1 = /* ]]; then - zfautocheck -dn + zfautocheck -dn || return 1 else - zfautocheck -d + zfautocheck -d || return 1 fi if [[ $1 = $HOME || $1 = $HOME/* ]]; then @@ -36,7 +36,7 @@ if (( $# == 0 )); then set -- '~' elif [[ $# -eq 1 && $1 = - ]]; then # Emulate `cd -' behaviour. - set -- $zflastdir + set -- $zfconfig[lastdir_$ZFTP_SESSION] elif [[ $# -eq 2 ]]; then # Emulate `cd old new' behaviour. # We have to find a character not in $1 or $2; ! is a good bet. @@ -47,6 +47,8 @@ fi # if we want to keep it. local lastdir=$ZFTP_PWD -zftp cd "$@" && zflastdir=$lastdir -print $zflastsession +zftp cd "$@" && [[ $lastdir != $ZFTP_PWD ]] && +zfconfig[lastdir_$ZFTP_SESSION]=$lastdir + +print $zfconfig[lastloc_$ZFTP_SESSION] # } diff --git a/Functions/Zftp/zfcd_match b/Functions/Zftp/zfcd_match index 67e719888..e9d283c97 100644 --- a/Functions/Zftp/zfcd_match +++ b/Functions/Zftp/zfcd_match @@ -15,7 +15,7 @@ local tmpf=${TMPPREFIX}zfcm$$ if [[ $ZFTP_SYSTEM = UNIX* ]]; then # hoo, aren't we lucky: this makes things so much easier - setopt localoptions rcexpandparam + setopt rcexpandparam local dir if [[ $1 = ?*/* ]]; then dir=${1%/*} @@ -25,13 +25,15 @@ if [[ $ZFTP_SYSTEM = UNIX* ]]; then # If we're using -F, we get away with using a directory # to list, but not a glob. Don't ask me why. # I hate having to rely on awk here. - zftp ls -F $dir >$tmpf + zftp ls -LF $dir >$tmpf reply=($(awk '/\/$/ { print substr($1, 0, length($1)-1) }' $tmpf)) rm -f $tmpf - if [[ $dir = / ]]; then - reply=(${dir}$reply) + [[ -n $dir && $dir != */ ]] && dir="$dir/" + if [[ -n $WIDGET ]]; then + _description expl 'remote directory' + compadd -S/ -q -P "$dir" - $reply elif [[ -n $dir ]]; then - reply=($dir/$reply) + reply=(${dir}$reply) fi else # I simply don't know what to do here. diff --git a/Functions/Zftp/zfcget b/Functions/Zftp/zfcget index fd6accfed..f95f37704 100644 --- a/Functions/Zftp/zfcget +++ b/Functions/Zftp/zfcget @@ -12,35 +12,21 @@ emulate -L zsh -local loc rem stat=0 optlist opt nglob remlist locst remst -local tmpfile=${TMPPREFIX}zfcget$$ rstat tsize time +local loc rem stat=0 opt opt_G opt_t remlist locst remst +local tmpfile=${TMPPREFIX}zfcget$$ rstat tsize -while [[ $1 = -* ]]; do - if [[ $1 = - || $1 = -- ]]; then - shift; - break; - fi - optlist=${1#-} - for (( i = 1; i <= $#optlist; i++)); do - opt=$optlist[$i] - case $optlist[$i] in - G) nglob=1 - ;; - t) time=1 - ;; - *) print option $opt not recognised >&2 - ;; - esac - done - shift +while getopts :Gt opt; do + [[ $opt = '?' ]] && print "zfcget: bad option: -$OPTARG" && return 1 + eval "opt_$opt=1" done +(( OPTIND > 1 )) && shift $(( OPTIND - 1 )) for remlist in $*; do # zfcd directory hack to put the front back to ~ if [[ $remlist = $HOME || $remlist = $HOME/* ]]; then remlist="~${remlist#$HOME}" fi - if [[ $nglob != 1 ]]; then + if [[ $opt_G != 1 ]]; then zfrglob remlist fi if (( $#remlist )); then @@ -73,7 +59,7 @@ for remlist in $*; do continue else if zftp getat $rem $locst[1] >>$loc; then - [[ $time = 1 ]] && zfrtime $loc $rem $remst[2] + [[ $opt_t = 1 ]] && zfrtime $loc $rem $remst[2] else stat=1 fi diff --git a/Functions/Zftp/zfdir b/Functions/Zftp/zfdir index 55befe000..deb5b9762 100644 --- a/Functions/Zftp/zfdir +++ b/Functions/Zftp/zfdir @@ -23,6 +23,8 @@ emulate -L zsh setopt extendedglob local file opt optlist redir i newargs force +local curdir=$zfconfig[curdir_$ZFTP_SESSION] +local otherdir=$zfconfig[otherdir_$ZFTP_SESSION] while [[ $1 = -* ]]; do if [[ $1 = - || $1 = -- ]]; then @@ -40,9 +42,9 @@ while [[ $1 = -* ]]; do ;; f) force=1 ;; - d) [[ -n $zfcurdir && -f $zfcurdir ]] && rm -f $zfcurdir - [[ -n $zfotherdir && -f $zfotherdir ]] && rm -f $zfotherdir - zftp_fcache=() + d) [[ -n $curdir && -f $curdir ]] && rm -f $curdir + [[ -n $otherdir && -f $otherdir ]] && rm -f $otherdir + zffcache -d return 0 ;; esac @@ -50,7 +52,7 @@ while [[ $1 = -* ]]; do shift done -zfautocheck -d +zfautocheck -d || return 1 # directory hack, see zfcd for (( i = 1; i <= $#argv; i++ )); do @@ -62,26 +64,32 @@ done if [[ $# -eq 0 ]]; then # Cache it in the current directory file. This means that repeated # calls to zfdir with no arguments always use a cached file. - [[ -z $zfcurdir ]] && zfcurdir=${TMPPREFIX}zfcurdir$$ - file=$zfcurdir + if [[ -z $curdir ]]; then + curdir=${TMPPREFIX}zfcurdir_${ZFTP_SESSION}_$$ + zfconfig[curdir_$ZFTP_SESSION]=$curdir + fi + file=$curdir else # Last directly looked at was not the current one, or at least # had non-standard arguments. - [[ -z $zfotherdir ]] && zfotherdir=${TMPPREFIX}zfotherdir$$ - file=$zfotherdir + if [[ -z $otherdir ]]; then + otherdir=${TMPPREFIX}zfotherdir_${ZFTP_SESSION}_$$ + zfconfig[otherdir_$ZFTP_SESSION]=$otherdir + fi + file=$otherdir newargs="$*" if [[ -f $file && $redir != 1 && $force -ne 1 ]]; then # Don't use the cached file if the arguments changed. - [[ $newargs = $zfotherargs ]] || rm -f $file + [[ $newargs = $zfconfig[otherargs_$ZFTP_SESSION] ]] || rm -f $file fi - zfotherargs=$newargs + zfconfig[otherargs_$ZFTP_SESSION]=$newargs fi if [[ $force -eq 1 ]]; then rm -f $file # if it looks like current directory has changed, better invalidate # the filename cache, too. - (( $# == 0 )) && zftp_fcache=() + (( $# == 0 )) && zffcache -d fi if [[ -n $file && -f $file ]]; then diff --git a/Functions/Zftp/zffcache b/Functions/Zftp/zffcache new file mode 100644 index 000000000..0d9686660 --- /dev/null +++ b/Functions/Zftp/zffcache @@ -0,0 +1,24 @@ +# Generate an array name for storing the cache for the current session, +# storing it in fcache_name, then generate the cache for the current +# directory, or with argument -d clear the cache. + +fcache_name=$zfconfig[fcache_$ZFTP_SESSION] +if [[ -z $fcache_name ]]; then + local vals + vals=(${(v)zfconfig[(I)fcache_*]##zftp_fcache_}) + integer i + while [[ -n ${vals[(r)zftp_fcache_$i]} ]]; do + (( i++ )) + done + fcache_name=zftp_fcache_$i + zfconfig[fcache_$ZFTP_SESSION]=$fcache_name +fi + +if [[ $1 = -d ]]; then + unset $fcache_name +elif (( ${(P)#fcache_name} == 0 )); then + local tmpf=${TMPPREFIX}zffcache$$ + zftp ls >$tmpf + eval "$fcache_name=(\${(f)\"\$(<\$tmpf)\"})" + rm -f $tmpf +fi diff --git a/Functions/Zftp/zfgcp b/Functions/Zftp/zfgcp index 26a08697d..916a5f7b6 100644 --- a/Functions/Zftp/zfgcp +++ b/Functions/Zftp/zfgcp @@ -16,30 +16,16 @@ emulate -L zsh -local opt optlist nglob remlist rem loc time +local opt remlist rem loc opt_G opt_t integer stat do_close -while [[ $1 == -* ]]; do - if [[ $1 == - || $1 == -- ]]; then - shift; - break; - fi - optlist=${1#-} - for (( i = 1; i <= $#optlist; i++)); do - opt=$optlist[$i] - case $opt in - G) nglob=1 - ;; - t) time=1 - ;; - *) print option $opt not recognised >&2 - ;; - esac - done - shift +while getopts :Gt opt; do + [[ $opt = '?' ]] && print "zfgcp: bad option: -$OPTARG" >&2 && return 1 + eval "opt_$opt=1" done +(( OPTIND > 1 )) && shift $(( OPTIND - 1 )) -zfautocheck +zfautocheck || return 1 # hmm, we should really check this after expanding the glob, # but we shouldn't expand the last argument remotely anyway. @@ -59,14 +45,14 @@ if [[ -d $argv[-1] ]]; then if [[ $remlist = $HOME || $remlist = $HOME/* ]]; then remlist="~${remlist#$HOME}" fi - if [[ $nglob != 1 ]]; then + if [[ $opt_G != 1 ]]; then zfrglob remlist fi if (( $#remlist )); then for rem in $remlist; do loc=$dir/${rem:t} if zftp get $rem >$loc; then - [[ $time = 1 ]] && zfrtime $rem $loc + [[ $opt_t = 1 ]] && zfrtime $rem $loc else stat=1 fi @@ -74,6 +60,9 @@ if [[ -d $argv[-1] ]]; then fi done else + if [[ $1 = $HOME || $1 = $HOME/* ]]; then + 1="~${1#$HOME}" + fi zftp get $1 >$2 || stat=$? fi diff --git a/Functions/Zftp/zfget b/Functions/Zftp/zfget index cee0290b3..cb058204d 100644 --- a/Functions/Zftp/zfget +++ b/Functions/Zftp/zfget @@ -19,50 +19,34 @@ emulate -L zsh -local loc rem optlist opt nglob remlist time cat +local loc rem opt remlist opt_G opt_t opt_c integer stat do_close -while [[ $1 == -* ]]; do - if [[ $1 == - || $1 == -- ]]; then - shift; - break; - fi - optlist=${1#-} - for (( i = 1; i <= $#optlist; i++)); do - opt=$optlist[$i] - case $opt in - G) nglob=1 - ;; - t) time=1 - ;; - c) cat=1 - ;; - *) print option $opt not recognised >&2 - ;; - esac - done - shift +while getopts :Gtc opt; do + [[ $opt = '?' ]] && print "zfget: bad option: -$OPTARG" && return 1 + eval "opt_$opt=1" done +(( OPTIND > 1 )) && shift $(( OPTIND - 1 )) -zfautocheck +zfautocheck || return 1 for remlist in $*; do # zfcd directory hack to put the front back to ~ if [[ $remlist == $HOME || $remlist == $HOME/* ]]; then remlist="~${remlist#$HOME}" fi - if [[ $nglob != 1 ]]; then + if [[ $opt_G != 1 ]]; then zfrglob remlist fi if (( $#remlist )); then for rem in $remlist; do - if [[ -n $cat ]]; then + if [[ -n $opt_c ]]; then zftp get $rem stat=$? else loc=${rem:t} if zftp get $rem >$loc; then - [[ $time = 1 ]] && zfrtime $rem $loc + [[ $opt_t = 1 ]] && zfrtime $rem $loc else stat=1 fi diff --git a/Functions/Zftp/zfget_match b/Functions/Zftp/zfget_match index 677108ede..875fca5f1 100644 --- a/Functions/Zftp/zfget_match +++ b/Functions/Zftp/zfget_match @@ -10,18 +10,29 @@ fi local tmpf=${TMPPREFIX}zfgm$$ if [[ $ZFTP_SYSTEM == UNIX* && $1 == */* ]]; then - # On the first argument to ls, we usually get away with a glob. - zftp ls "$1*$2" >$tmpf - reply=($(<$tmpf)) - rm -f $tmpf -else - if (( $#zftp_fcache == 0 )); then - # Always cache the current directory and use it - # even if the system is UNIX. - zftp ls >$tmpf - zftp_fcache=($(<$tmpf)) + if [[ -n $WIDGET ]]; then + local dir=${1:h} + [[ $dir = */ ]] || dir="$dir/" + zftp ls -LF $dir >$tmpf + local reply + reply=(${${${(f)"$(<$tmpf)"}##$dir}%\*}) + rm -f $tmpf + _description expl 'remote file' + compadd "$expl[@]" -P $dir - $reply + else + # On the first argument to ls, we usually get away with a glob. + zftp ls "$1*$2" >$tmpf + reply=($(<$tmpf)) rm -f $tmpf fi - reply=($zftp_fcache); +else + local fcache_name + zffcache + if [[ -n $WIDGET ]]; then + _description expl 'remote file' + compadd "$expl[@]" -F fignore - ${(P)fcache_name} + else + reply=(${(P)fcache_name}); + fi fi # } diff --git a/Functions/Zftp/zfgoto b/Functions/Zftp/zfgoto index bd1cdbfe5..57651e383 100644 --- a/Functions/Zftp/zfgoto +++ b/Functions/Zftp/zfgoto @@ -2,6 +2,9 @@ # Go to bookmark bname, a location on a remote FTP host. Unless # this was the last session or is for anonymous FTP, prompt for # the user's password. +# +# Maybe this should try and look for an appropriate session to use +# for the transfer. emulate -L zsh setopt extendedglob @@ -11,33 +14,20 @@ setopt extendedglob : ${ZFTP_BMFILE:=${ZFDOTDIR:-$HOME}/.zfbkmarks} typeset -A bkmarks -local line ncftp opt optlist +local line opt_n opt -while [[ $1 == -* ]]; do - if [[ $1 == - || $1 == -- ]]; then - shift; - break; - fi - optlist=${1#-} - for (( i = 1; i <= $#optlist; i++)); do - opt=$optlist[$i] - case $opt in - n) ncftp=1 - ;; - *) print option $opt not recognised >&2 - return 1 - ;; - esac - done - shift +while getopts :n opt; do + [[ $opt = '?' ]] && print "zfgoto: bad option: -$OPTARG" && return 1 + eval "opt_$opt=1" done +(( OPTIND > 1 )) && shift $(( OPTIND - 1 )) if (( $# != 1 )); then print "Usage: zfgoto bookmark" >&2 return 1 fi -if [[ -n $ncftp && -f ~/.ncftp/bookmarks ]]; then +if [[ -n $opt_n && -f ~/.ncftp/bookmarks ]]; then local oldifs=$IFS IFS=, while read -rA line; do @@ -73,7 +63,8 @@ if [[ $ZFTP_USER = $user && $ZFTP_HOST = $host ]]; then elif [[ $user = ftp || $user = anonymous ]]; then # Anonymous ftp, so we don't need password etc. zfanon $host && [[ -n $dir ]] && zfcd $dir -elif [[ $zflastsession = ${host}:* && $user = $zflastuser ]]; then +elif [[ $zfconfig[lastloc_$ZFTP_SESSION] = ${host}:* && + $user = $zfconfig[lastuser_$ZFTP_SESSION] ]]; then # This was the last session, so assume it's still setup in the # open parameters zfopen && [[ -n $dir ]] && zfcd $dir diff --git a/Functions/Zftp/zfinit b/Functions/Zftp/zfinit index 0bc619277..f650b7bbb 100644 --- a/Functions/Zftp/zfinit +++ b/Functions/Zftp/zfinit @@ -4,7 +4,7 @@ emulate -L zsh if [[ ${+zfconfig} = 0 ]]; then typeset -gA zfconfig - zfconfig=(progress bar update 1) + zfconfig=(progress bar update 1 lastsession default) fi alias zfcd='noglob zfcd' @@ -14,9 +14,9 @@ alias zfdir='noglob zfdir' alias zfuget='noglob zfuget' autoload -U zfanon zfautocheck zfcd zfcd_match zfcget zfclose zfcput -autoload -U zfdir zfgcp zfget zfget_match zfgoto zfhere zfinit zfls -autoload -U zfmark zfopen zfparams zfpcp zfput zfrglob zfrtime zfstat -autoload -U zftp_chpwd zftp_progress zftype zfuget zfuput +autoload -U zfdir zffcache zfgcp zfget zfget_match zfgoto zfhere zfinit zfls +autoload -U zfmark zfopen zfparams zfpcp zfput zfrglob zfrtime zfsession +autoload -U zfstat zftp_chpwd zftp_progress zftransfer zftype zfuget zfuput # # zftp completions: only use these if new-style completion is not @@ -33,7 +33,8 @@ if [[ ${#_patcomps} -eq 0 || ${_patcomps[(i)zf*]} -gt ${#_patcomps} ]]; then close quit)' - \ 'w[1,cd][1,ls][1,dir][1,rmdir]' -K zfcd_match -S/ -q - \ 'W[1,get*]' -K zfget_match - 'w[1,delete][1,remote]' -K zfget_match - \ - 'w[1,open][1,params]' -k hosts -- zftp + 'w[1,open][1,params]' -k hosts - \ + 'w[1,session]' -s '${$(zftp session):#$ZFTP_SESSION}' -- zftp compctl -K zfcd_match -S/ -q zfcd zfdir zfls compctl -K zfget_match zfget zfgcp zfuget zfcget compctl -k hosts zfanon zfopen zfparams @@ -42,4 +43,15 @@ if [[ ${#_patcomps} -eq 0 || ${_patcomps[(i)zf*]} -gt ${#_patcomps} ]]; then -x 'W[1,-*n*]' \ -s '$(awk -F, '\''NR > 2 { print $1 }'\'' ~/.ncftp/bookmarks)' -- \ zfgoto zfmark + compctl -s '${$(zftp session):#$ZFTP_SESSION}' -- zfsession + # in _zftp for new completion, but hard to inline into a compctl + zftransfer_match() { + local sess=${1%%:*} oldsess=$ZFTP_SESSION + [[ -n $sess ]] && zftp session $sess + zfget_match ${1#*:} $2 + [[ -n $sess && -n $oldsess ]] && zftp session $oldsess + reply=(${sess}:${^reply}) + } + compctl -s '$(zftp session)' -S : -x 'C[0,*:*]' \ + -K zftransfer_match -- zftransfer fi diff --git a/Functions/Zftp/zfmark b/Functions/Zftp/zfmark index 8d35ce45a..74cc702ac 100644 --- a/Functions/Zftp/zfmark +++ b/Functions/Zftp/zfmark @@ -37,8 +37,9 @@ fi if [[ -n $ZFTP_HOST ]]; then bkmarks[$1]="${ZFTP_USER}@${ZFTP_HOST}:${ZFTP_PWD}" -elif [[ -n $zflastsession ]]; then - bkmarks[$1]="${zflastuser}@${zflastsession}" +elif [[ -n $zfconfig[lastloc_$ZFTP_SESSION] ]]; then + bkmarks[$1]="${zfconig[lastuser_$ZFTP_SESSION]}@\ +${zfconfig[lastloc_$ZFTP_SESSION]}" else print "No current or recent ZFTP session to bookmark." >&2 return 1 diff --git a/Functions/Zftp/zfopen b/Functions/Zftp/zfopen index b264aeaba..32b450411 100644 --- a/Functions/Zftp/zfopen +++ b/Functions/Zftp/zfopen @@ -7,25 +7,13 @@ emulate -L zsh -local optlist opt once dir +local opt dir opt_1 -while [[ $1 = -* ]]; do - if [[ $1 = - || $1 = -- ]]; then - shift; - break; - fi - optlist=${1#-} - for (( i = 1; i <= $#optlist; i++)); do - opt=$optlist[$i] - case $optlist[$i] in - 1) once=1 - ;; - *) print option $opt not recognised >&2 - ;; - esac - done - shift +while getopts :1 opt; do + [[ $opt = "?" ]] && print "zfopen: bad option: -$OPTARG" >&2 && return 1 + eval "opt_$opt=1" done +(( OPTIND > 1 )) && shift $(( OPTIND - 1 )) # This is where we should try and do same name-lookupage in # both .netrc and .ncftp/bookmarks . We could even try saving @@ -37,8 +25,14 @@ if [[ $1 = */* ]]; then 1=${1%%/*} fi -if [[ $once = 1 ]]; then +if [[ $opt_1 = 1 ]]; then zftp open $* || return 1 + if [[ $# = 1 ]]; then + if ! zftp login; then + zftp close + return 1 + fi + fi else # set parameters, but only if there was at least a host (( $# > 0 )) && zfparams $* diff --git a/Functions/Zftp/zfparams b/Functions/Zftp/zfparams index 5c5262c52..faae63251 100644 --- a/Functions/Zftp/zfparams +++ b/Functions/Zftp/zfparams @@ -2,11 +2,25 @@ emulate -L zsh -# Set to prompt for any user or password if not given. -# Don't worry about accounts here. -if (( $# > 0 )); then +if [[ $# -eq 1 && $1 = - ]]; then + # Delete existing parameter set. + local sess=$ZFTP_SESSION key + key=${zfconfig[fcache_$sess]} + [[ -n $key ]] && unset $key + for key in fcache lastloc lastdir curdir otherdir otherargs lastuser; do + unset "zfconfig[${key}_${sess}]" + done +elif (( $# > 0 )); then + # Set to prompt for any user or password if not given. + # Don't worry about accounts here. (( $# < 2 )) && 2='?' - (( $# < 3 )) && 3='?' + if (( $# < 3 )); then + if [[ $2 = '?'* ]]; then + 3="?Password on ${1}: " + else + 3="?Password for ${2##\\?} on ${1}: " + fi + fi fi zftp params $* # } diff --git a/Functions/Zftp/zfpcp b/Functions/Zftp/zfpcp index ddd570e59..9642688b7 100644 --- a/Functions/Zftp/zfpcp +++ b/Functions/Zftp/zfpcp @@ -17,7 +17,7 @@ emulate -L zsh local rem loc integer stat do_close -zfautocheck +zfautocheck || return 1 if [[ $# -gt 2 || $2 = (.|..) || $2 = */ ]]; then local dir=$argv[-1] @@ -32,6 +32,9 @@ if [[ $# -gt 2 || $2 = (.|..) || $2 = */ ]]; then zftp put $rem <$loc || stat=1 done else + if [[ $2 = $HOME || $2 = $HOME/* ]]; then + 2="~${2#$HOME}" + fi zftp put $2 <$1 stat=$? if [[ stat -ne 0 && $ZFTP_CODE = 553 && $ZFTP_REPLY = *'Is a directory'* ]] diff --git a/Functions/Zftp/zfrglob b/Functions/Zftp/zfrglob index fad0c3849..535cb8006 100644 --- a/Functions/Zftp/zfrglob +++ b/Functions/Zftp/zfrglob @@ -57,14 +57,10 @@ else rm -f $tmpf else # we just have to do an ls and hope that's right + local fcache_name + zffcache nondir=$pat - if (( $#zftp_fcache == 0 )); then - # Why does `zftp_fcache=($(zftp ls))' sometimes not work? - zftp ls >$tmpf - zftp_fcache=($(<$tmpf)) - rm -f $tmpf - fi - files=($zftp_fcache) + files=(${(P)fcache_name}) fi # now we want to see which of the $files match $nondir: # ${...:/foo} deletes occurrences of foo matching a complete word, diff --git a/Functions/Zftp/zfsession b/Functions/Zftp/zfsession new file mode 100644 index 000000000..9cd0d918f --- /dev/null +++ b/Functions/Zftp/zfsession @@ -0,0 +1,71 @@ +# function zfsession { +# Change or list the sessions for the current zftp connection. + +emulate -L zsh + +local opt opt_l opt_v opt_o opt_d hadopts + +while getopts ":lovd" opt; do + [[ $opt = "?" ]] && print "zfsession: bad option: -$OPTARG" >&2 && return 1 + eval "opt_$opt=1" + hadopts=1 +done +(( OPTIND > 1 )) && shift $(( OPTIND - 1 )) + +if [[ $# -gt 1 || (( -n $hadopts && -z $opt_d ) && $# -gt 0 ) ]] +then + print "Usage: zfsession ( [ -lvod ] | session )" 1>&2 + return 1 +fi + +if [[ -n $opt_v ]]; then + local sess + for sess in $(zftp session); do + print -n "${(r.15.. ..:.)sess}\t${zfconfig[lastloc_$sess]:-not connected}" + if [[ $sess = $ZFTP_SESSION ]]; then + print " *" + else + print + fi + done +elif [[ -n $opt_l ]]; then + zftp session +fi + +if [[ -n $opt_o ]]; then + if [[ $zfconfig[lastsession] != $ZFTP_SESSION ]]; then + local cursession=$ZFTP_SESSION + zftp session $zfconfig[lastsession] + zfconfig[lastsession]=$cursession + print $ZFTP_SESSION + else + print "zfsession: no previous session." >&2 + return 1 + fi +fi + +if [[ -n $opt_d ]]; then + local del=${1:-$ZFTP_SESSION} key + key=${zfconfig[fcache_$del]} + [[ -n $key ]] && unset $key + for key in fcache lastloc lastdir curdir otherdir otherargs lastuser; do + unset "zfconfig[${key}_${del}]" + done + zftp rmsession $del + return +fi + +[[ -n $hadopts ]] && return $stat + +if [[ $# = 0 ]]; then + print $ZFTP_SESSION + return +fi + +local oldsession=${ZFTP_SESSION:-default} +zftp session $1 +if [[ $ZFTP_SESSION != $oldsession ]]; then + zfconfig[lastsession]=$oldsession + zftp_chpwd +fi +# } diff --git a/Functions/Zftp/zfstat b/Functions/Zftp/zfstat index 0ca755d03..6945da99b 100644 --- a/Functions/Zftp/zfstat +++ b/Functions/Zftp/zfstat @@ -6,25 +6,15 @@ setopt localoptions unset unsetopt ksharrays -local i stat=0 opt optlist verbose +local i stat=0 opt opt_v -while [[ $1 = -* ]]; do - if [[ $1 = - || $1 = -- ]]; then - shift; - break; - fi - optlist=${1#-} - for (( i = 1; i <= $#optlist; i++)); do - opt=$optlist[$i] - case $opt in - v) verbose=1 - ;; - *) print option $opt not recognised >&2 - ;; - esac - done - shift +while getopts :v opt; do + [[ $opt = "?" ]] && print "zfstat: bad option: -$OPTARG" >&2 && return 1 + eval "opt_$opt=1" done +(( OPTIND > 1 )) && shift $(( OPTIND - 1 )) + +[[ -n $ZFTP_SESSION ]] && print "Session:\t$ZFTP_SESSION" if [[ -n $ZFTP_HOST ]]; then print "Host:\t\t$ZFTP_HOST" @@ -55,7 +45,8 @@ if [[ -n $ZFTP_HOST ]]; then fi else print "Not connected." - [[ -n $zflastsession ]] && print "Last session:\t$zflastsession" + [[ -n $zfconfig[lastloc_$ZFTP_SESSION] ]] && + print "Last location:\t$zfconfig[lastloc_$ZFTP_SESSION]" stat=1 fi @@ -77,7 +68,7 @@ for (( i = 1; i <= ${#ZFTP_PREFS}; i++ )); do done print -if [[ -n $ZFTP_HOST && $verbose = 1 ]]; then +if [[ -n $ZFTP_HOST && $opt_v = 1 ]]; then zfautocheck -d print "Status of remote server:" # make sure we print the reply diff --git a/Functions/Zftp/zftp_chpwd b/Functions/Zftp/zftp_chpwd index 0b5bbd7d5..53972cd65 100644 --- a/Functions/Zftp/zftp_chpwd +++ b/Functions/Zftp/zftp_chpwd @@ -2,14 +2,14 @@ # You may want to alter chpwd to call this when $ZFTP_USER is set. # If the directory really changed... -if [[ $ZFTP_PWD != $zflastdir ]]; then - # Cancel the filename cache for the current directory. - zftp_fcache=() +if [[ $ZFTP_PWD != $zfconfig[lastdir_$ZFTP_SESSION] ]]; then # ...and also empty the stored directory listing cache. # As this function is called when we close the connection, this # is the only place we need to do these two things. - [[ -n $zfcurdir && -f $zfcurdir ]] && rm -f $zfcurdir - zfotherargs= + local curdir=$zfconfig[curdir_$ZFTP_SESSION] + [[ -n $curdir && -f $curdir ]] && rm -f $curdir + zfconfig[otherargs_$ZFTP_SESSION]= + zffcache -d fi if [[ -z $ZFTP_USER ]]; then @@ -18,24 +18,24 @@ if [[ -z $ZFTP_USER ]]; then # delete the non-current cached directory [[ -n $zfotherdir && -f $zfotherdir ]] && rm -f $zfotherdir - # don't keep zflastdir between opens (do keep zflastsession) - zflastdir= + # don't keep lastdir between opens (do keep lastloc) + zfconfig[lastdir_$ZFTP_SESSION]= # return the display to standard # uncomment the following line if you have a chpwd which shows directories - # chpwd + chpwd else - [[ -n $ZFTP_PWD ]] && zflastdir=$ZFTP_PWD - zflastsession="$ZFTP_HOST:$ZFTP_PWD" - zflastuser="$ZFTP_USER" + [[ -n $ZFTP_PWD ]] && zfconfig[lastdir_$ZFTP_SESSION]=$ZFTP_PWD + zfconfig[lastloc_$ZFTP_SESSION]="$ZFTP_HOST:$ZFTP_PWD" + zfconfig[lastuser_$ZFTP_SESSION]="$ZFTP_USER" local args if [[ -t 1 && -t 2 ]]; then - local str=$zflastsession + local str=$zfconfig[lastloc_$ZFTP_SESSION] [[ ${#str} -lt 70 ]] && str="%m: %~ $str" case $TERM in sun-cmd) print -n -P "\033]l$str\033\\" ;; - xterm) print -n -P "\033]2;$str\a" + xterm|aixterm) print -n -P "\033]2;$str\a" ;; esac fi diff --git a/Functions/Zftp/zftp_progress b/Functions/Zftp/zftp_progress index 344d1c9c1..b4b639fce 100644 --- a/Functions/Zftp/zftp_progress +++ b/Functions/Zftp/zftp_progress @@ -26,17 +26,19 @@ if [[ -n $ZFTP_TRANSFER ]]; then # avoid a `parameter unset' message [[ $ZFTP_TRANSFER != *F ]] && (( ${+zftpseconds} )) && (( SECONDS - zftpseconds < update )) && return - if [[ -n $ZFTP_SIZE ]]; then - local frac="$(( ZFTP_COUNT * 100 / ZFTP_SIZE ))%" + # size is usually ZFTP_SIZE, but zftransfer may set ZFTP_TSIZE + local size=${ZFTP_TSIZE:-$ZFTP_SIZE} + if [[ -n $size ]]; then + local frac="$(( ZFTP_COUNT * 100 / size ))%" if [[ $style = bar && ${+COLUMNS} = 1 && $COLUMNS -gt 0 ]]; then if (( ! ${+zftpseconds} )); then - print "$ZFTP_FILE ($ZFTP_SIZE bytes): $ZFTP_TRANSFER" 1>&2 + print "$ZFTP_FILE ($size bytes): $ZFTP_TRANSFER" 1>&2 fi integer maxwidth=$(( COLUMNS - 7 )) - local width="$(( ZFTP_COUNT * maxwidth / ZFTP_SIZE ))" + local width="$(( ZFTP_COUNT * maxwidth / size ))" print -nP "\r%S${(l:width:):-}%s${(l:maxwidth-width:):-}: ${frac}%%" 1>&2 else - print -n "\r$ZFTP_FILE ($ZFTP_SIZE bytes): $ZFTP_TRANSFER $frac" 1>&2 + print -n "\r$ZFTP_FILE ($size bytes): $ZFTP_TRANSFER $frac" 1>&2 fi else print -n "\r$ZFTP_FILE: $ZFTP_TRANSFER $ZFTP_COUNT" 1>&2 diff --git a/Functions/Zftp/zftransfer b/Functions/Zftp/zftransfer new file mode 100644 index 000000000..929f099d2 --- /dev/null +++ b/Functions/Zftp/zftransfer @@ -0,0 +1,62 @@ +# function zftransfer { +# Transfer files between two distinct sessions. No remote globbing +# is done, since only single pairs can be transferred. + +emulate -L zsh + +local sess1 sess2 file1 file2 oldsess=${ZFTP_SESSION} + +if [[ $# -ne 2 ]]; then + print "Usage: zftransfer sess1:file1 sess2:file2" 1>&2 + return 1 +fi + +if [[ $1 = *:* ]]; then + sess1=${1%%:*} + file1=${1#*:} +fi +: ${sess1:=$ZFTP_SESSION} + +if [[ $2 = *:* ]]; then + sess2=${2%%:*} + file2=${2#*:} +fi +: ${sess2:=$ZFTP_SESSION} +if [[ -z $file2 || $file2 = */ ]]; then + file2="${file2}${file1:t}" +fi + +if [[ $sess1 = $sess2 ]]; then + print "zftransfer: must use two distinct sessions." 1>&2 + return 1 +fi + +zftp session $sess1 +zfautocheck || return 1 + +# It's more useful to show the progress for the second part +# of the pipeline, but unfortunately that can't necessarily get +# the size from the pipe --- and if it does, it's probably wrong. +# To avoid that, try to get the size and set it for the progress to +# see. +if [[ $zfconfig[progress] != none ]]; then + local ZFTP_TSIZE array tmpfile=${TMPPREFIX}zft$$ + zftp remote $file1 >$tmpfile 2>/dev/null + array=($(<$tmpfile)) + rm -f $tmpfile + [[ $#array -eq 2 ]] && ZFTP_TSIZE=$array[1] +fi + +# We do the RHS of the pipeline in a subshell, too, so that +# the LHS can get SIGPIPE when it exits. +{ zfconfig[progress]=none + zftp get $file1 } | +( zftp session $sess2 + zfautocheck && zftp put $file2 ) + +local stat=$? + +zftp session $oldsess + +return $stat +# } diff --git a/Functions/Zftp/zfuget b/Functions/Zftp/zfuget index 482da42e9..955c48f4a 100644 --- a/Functions/Zftp/zfuget +++ b/Functions/Zftp/zfuget @@ -26,7 +26,7 @@ emulate -L zsh local loc rem locstats remstats doit tmpfile=${TMPPREFIX}zfuget$$ -local rstat remlist verbose optlist opt bad i silent nglob time +local rstat remlist opt opt_v opt_s opt_G opt_t integer stat do_close zfuget_print_time() { @@ -43,40 +43,20 @@ zfuget_print () { print ", $locstats[1] bytes)" } -while [[ $1 = -* ]]; do - if [[ $1 = - || $1 = -- ]]; then - shift; - break; - fi - optlist=${1#-} - for (( i = 1; i <= $#optlist; i++)); do - opt=$optlist[$i] - case $optlist[$i] in - v) verbose=1 - ;; - s) silent=1 - ;; - G) nglob=1 - ;; - t) time=1 - ;; - *) print option $opt not recognised >&2 - ;; - esac - done - shift +while getopts :vsGt opt; do + [[ $opt = "?" ]] && print "zfuget: bad option: -$OPTARG" >&2 && return 1 + eval "opt_$opt=1" done +(( OPTIND > 1 )) && shift $(( OPTIND - 1 )) -[[ -n $bad ]] && return 1 - -zfautocheck +zfautocheck || return 1 for remlist in $*; do # zfcd directory hack to put the front back to ~ if [[ $remlist == $HOME || $remlist == $HOME/* ]]; then remlist="~${remlist#$HOME}" fi - if [[ $nglob != 1 ]]; then + if [[ $opt_n != 1 ]]; then zfrglob remlist fi if (( $#remlist )); then @@ -99,11 +79,11 @@ for remlist in $*; do stat=1 continue fi - [[ $verbose = 1 ]] && zfuget_print + [[ $opt_v = 1 ]] && zfuget_print if (( $locstats[1] != $remstats[1] )); then # Files have different sizes - if [[ $locstats[2] > $remstats[2] && $silent != 1 ]]; then - [[ $verbose != 1 ]] && zfuget_print + if [[ $locstats[2] > $remstats[2] && $opt_s != 1 ]]; then + [[ $opt_v != 1 ]] && zfuget_print print "Local file $loc more recent than remote," 1>&2 print -n "but sizes are different. Transfer anyway [y/n]? " 1>&2 read -q doit @@ -111,24 +91,24 @@ for remlist in $*; do else # Files have same size if [[ $locstats[2] < $remstats[2] ]]; then - if [[ $silent != 1 ]]; then - [[ $verbose != 1 ]] && zfuget_print + if [[ $opt_s != 1 ]]; then + [[ $opt_v != 1 ]] && zfuget_print print "Local file $loc has same size as remote," 1>&2 print -n "but local file is older. Transfer anyway [y/n]? " 1>&2 read -q doit fi else # presumably same file, so don't get it. - [[ $verbose = 1 ]] && print Not transferring + [[ $opt_v = 1 ]] && print Not transferring doit=n fi fi else - [[ $verbose = 1 ]] && print New file $loc + [[ $opt_v = 1 ]] && print New file $loc fi if [[ $doit = y ]]; then if zftp get $rem >$loc; then - if [[ $time = 1 ]]; then + if [[ $opt_t = 1 ]]; then # if $remstats is set, it's second element is the remote time zfrtime $loc $rem $remstats[2] fi diff --git a/Functions/Zftp/zfuput b/Functions/Zftp/zfuput index b54d0d0d4..cb179052c 100644 --- a/Functions/Zftp/zfuput +++ b/Functions/Zftp/zfuput @@ -12,7 +12,7 @@ emulate -L zsh local loc rem locstats remstats doit tmpfile=${TMPPREFIX}zfuput$$ -local rstat verbose optlist opt bad i silent +local rstat opt opt_v opt_s integer stat do_close zfuput_print_time() { @@ -29,29 +29,13 @@ zfuput_print () { print ", $locstats[1] bytes)" } -while [[ $1 = -* ]]; do - if [[ $1 = - || $1 = -- ]]; then - shift; - break; - fi - optlist=${1#-} - for (( i = 1; i <= $#optlist; i++)); do - opt=$optlist[$i] - case $optlist[$i] in - v) verbose=1 - ;; - s) silent=1 - ;; - *) print option $opt not recognised >&2 - ;; - esac - done - shift +while getopts :vs opt; do + [[ $opt = "?" ]] && print "zfuget: bad option: -$OPTARG" >&2 && return 1 + eval "opt_$opt=1" done +(( OPTIND > 1 )) && shift $(( OPTIND - 1 )) -[[ -n $bad ]] && return 1 - -zfautocheck +zfautocheck || return 1 if [[ $ZFTP_VERBOSE = *5* ]]; then # should we turn it off locally? @@ -77,13 +61,13 @@ for rem in $*; do print "Server does not implement full command set required." 1>&2 return 1 elif [[ $rstat = 1 ]]; then - [[ $verbose = 1 ]] && print New file $loc + [[ $opt_v = 1 ]] && print New file $loc else - [[ $verbose = 1 ]] && zfuput_print + [[ $opt_v = 1 ]] && zfuput_print if (( $locstats[1] != $remstats[1] )); then # Files have different sizes - if [[ $locstats[2] < $remstats[2] && $silent != 1 ]]; then - [[ $verbose != 1 ]] && zfuput_print + if [[ $locstats[2] < $remstats[2] && $opt_s != 1 ]]; then + [[ $opt_v != 1 ]] && zfuput_print print "Remote file $rem more recent than local," 1>&2 print -n "but sizes are different. Transfer anyway [y/n]? " 1>&2 read -q doit @@ -91,15 +75,15 @@ for rem in $*; do else # Files have same size if [[ $locstats[2] > $remstats[2] ]]; then - if [[ $silent != 1 ]]; then - [[ $verbose != 1 ]] && zfuput_print + if [[ $opt_s != 1 ]]; then + [[ $opt_v != 1 ]] && zfuput_print print "Remote file $rem has same size as local," 1>&2 print -n "but remote file is older. Transfer anyway [y/n]? " 1>&2 read -q doit fi else # presumably same file, so don't get it. - [[ $verbose = 1 ]] && print Not transferring + [[ $opt_v = 1 ]] && print Not transferring doit=n fi fi |