summaryrefslogtreecommitdiff
path: root/Functions/Zftp/zfuget
diff options
context:
space:
mode:
Diffstat (limited to 'Functions/Zftp/zfuget')
-rw-r--r--Functions/Zftp/zfuget147
1 files changed, 147 insertions, 0 deletions
diff --git a/Functions/Zftp/zfuget b/Functions/Zftp/zfuget
new file mode 100644
index 000000000..482da42e9
--- /dev/null
+++ b/Functions/Zftp/zfuget
@@ -0,0 +1,147 @@
+# function zfuget {
+# Get a list of files from the server with update.
+# In other words, only retrieve files which are newer than local
+# ones. This depends on the clocks being adjusted correctly
+# (i.e. if one is fifteen minutes out, for the next fifteen minutes
+# updates may not be correctly calculated). However, difficult
+# cases --- where the files are the same size, but the remote is newer,
+# or have different sizes, but the local is newer -- are prompted for.
+#
+# Files are globbed on the remote host --- assuming, of course, they
+# haven't already been globbed local, so use 'noglob' e.g. as
+# `alias zfuget="noglob zfuget"'.
+#
+# Options:
+# -G Glob: turn off globbing
+# -v verbose: print more about the files listed.
+# -s silent: don't ask, just guess. The guesses are:
+# - if the files have different sizes but remote is older ) grab
+# - if they have the same size but remote is newer )
+# which is safe if the remote files are always the right ones.
+# -t time: update the local file times to the same time as the remote.
+# Currently this only works if you have the `perl' command,
+# and that perl is version 5 with the standard library.
+# See the function zfrtime for more gory details.
+
+emulate -L zsh
+
+local loc rem locstats remstats doit tmpfile=${TMPPREFIX}zfuget$$
+local rstat remlist verbose optlist opt bad i silent nglob time
+integer stat do_close
+
+zfuget_print_time() {
+ local tim=$1
+ print -n "$tim[1,4]/$tim[5,6]/$tim[7,8] $tim[9,10]:$tim[11,12].$tim[13,14]"
+ print -n GMT
+}
+
+zfuget_print () {
+ print -n "\nremote $rem ("
+ zfuget_print_time $remstats[2]
+ print -n ", $remstats[1] bytes)\nlocal $loc ("
+ zfuget_print_time $locstats[2]
+ 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
+done
+
+[[ -n $bad ]] && return 1
+
+zfautocheck
+
+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
+ zfrglob remlist
+ fi
+ if (( $#remlist )); then
+ for rem in $remlist; do
+ loc=${rem:t}
+ doit=y
+ remstats=()
+ if [[ -f $loc ]]; then
+ zftp local $loc >$tmpfile
+ locstats=($(<$tmpfile))
+ zftp remote $rem >$tmpfile
+ rstat=$?
+ remstats=($(<$tmpfile))
+ rm -f $tmpfile
+ if [[ $rstat = 2 ]]; then
+ print "Server does not implement full command set required." 1>&2
+ return 1
+ elif [[ $rstat = 1 ]]; then
+ print "File not found on server: $rem" 1>&2
+ stat=1
+ continue
+ fi
+ [[ $verbose = 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
+ 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
+ fi
+ else
+ # Files have same size
+ if [[ $locstats[2] < $remstats[2] ]]; then
+ if [[ $silent != 1 ]]; then
+ [[ $verbose != 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
+ doit=n
+ fi
+ fi
+ else
+ [[ $verbose = 1 ]] && print New file $loc
+ fi
+ if [[ $doit = y ]]; then
+ if zftp get $rem >$loc; then
+ if [[ $time = 1 ]]; then
+ # if $remstats is set, it's second element is the remote time
+ zfrtime $loc $rem $remstats[2]
+ fi
+ else
+ stat=$?
+ fi
+
+ fi
+ done
+ fi
+done
+
+(( do_close )) && zfclose
+
+return $stat
+# }