From f40745a8d450aeddd4e7e54e53a62393c9e47728 Mon Sep 17 00:00:00 2001 From: zawz Date: Tue, 8 Jun 2021 16:45:50 +0200 Subject: [PATCH] remove zsync --- zsync/zsync | 449 ---------------------------------------------------- 1 file changed, 449 deletions(-) delete mode 100755 zsync/zsync diff --git a/zsync/zsync b/zsync/zsync deleted file mode 100755 index 376b084..0000000 --- a/zsync/zsync +++ /dev/null @@ -1,449 +0,0 @@ -#!/bin/sh - -## -## NO T OPTION FOR RSYNC - -# globals -syncdir=".zsync" -lock_file=".zsync/lock" -ignore_file=".zsync/ignore" -tree_full=".zsync/tree_full" -tree_hash=".zsync/tree_hash" -config_file=".zsync/config" - -rsync_opts='-rvlpE' - -tmpdir=${TMPDIR-/tmp} - -# usage -fname=$(basename "$0") -usage() -{ - echo "$fname [operation] - -Operations: - server Setup sync on current folder with server target - run [file...] Run sync with server - push [file...] Regular run but push all conflicts - pull [file...] Regular run but pull all conflicts - dry [file...] Run a simulated sync but do not perform any action - drypush [file...] Dry run as push - drypull [file...] Dry run as pull - forcepush Push by force the entire tree. Will replace and delete remote files - forcepull Pull by force the entire tree. Will replace and delete local files" -} - -## generic tools - -# $@ = paths -check_paths() -{ - for N - do - echo "$N" | grep "^/" && echo "Path cannot start with /" >&2 && return 1 - echo "$N" | grep -w ".." && echo "Path cannot contain .." >&2 && return 1 - done - return 0 -} - -tmpdir() { - echo "$tmpdir/zsync_$(tr -dc '[:alnum:]' /dev/null 2>&1 || { echo rsync not installed on server >&2 ; return 3; } - touch "$config_file" || return 5 -} - -get_server() { - [ ! -f "$config_file" ] && return 1 - servconf=$(sed 's|^[ \t]*||g' "$config_file" | grep -E '^server[ \t]' | sed 's|^server[ \t]*||g' | tail -n1) - raddr=$(echo "$servconf" | cut -d ':' -f1) - rdir=$(echo "$servconf" | cut -d ':' -f2-) -} - -# $1 = server arg -setup_server() -{ - init_config || return $? - [ -z "$1" ] && echo "$fname server user@host:path" && return 1 - sed -i '/^[ \t]*server[ \t]/d' "$config_file" - echo "server $1" >> "$config_file" -} - -ignores="" -get_ignores() { - if [ -f "$ignore_file" ] - then - ignores="($(tr '\n' '|' < "$ignore_file"))" - else - ignores='(^$)' - fi - ignores=$(echo "$ignores" | sed ' s/|)/)/g ; s/^()$/^$/g ') -} - -## LOCK - -lock_local() { touch "$lock_file"; } -unlock_local() { rm "$lock_file"; } -lock_server() { ssh "$raddr" "cd '$rdir' && touch '$lock_file'"; } -unlock_server() { ssh "$raddr" "cd '$rdir' && rm '$lock_file'"; } -lock_all() { lock_local && lock_server ; } -unlock_all() { ret=0; unlock_local || ret=$? ; unlock_server || ret=$?; return $ret ; } - -local_lock_check() { - [ ! -f "$lock_file" ] || { echo "Local sync locked, wait for sync completion" >&2 && return 1; } -} -server_lock_check() { - ssh "$raddr" "cd '$rdir' && [ ! -f '$lock_file' ]" || { echo "Server is busy, wait for sync completion" >&2 && return 1; } -} - -# init -init_local() { - mkdir -p "$syncdir" || return 2 - which rsync >/dev/null 2>&1 || { echo rsync not installed on server >&2 ; return 3; } - local_lock_check || return 4 - touch "$lock_file" || return 5 -} - -init_server() { - ssh "$raddr" " - cd '$rdir' || exit 1 - mkdir -p '$syncdir' || exit 2 - which rsync >/dev/null 2>&1 || { echo rsync not installed on server >&2 ; exit 3; } - [ -f '$lock_file' ] && { echo Server is busy, wait for sync completion ; exit 4; } - touch '$lock_file' || exit 5 - " -} - -## LIST GET - -local_hash_list() -{ - { ( set -e - find . -type f ! -regex "^./$syncdir/.*" | sed 's|^./||g' | tr '\n' '\0' | xargs -0 md5sum | cut -c1-33,35- | grep -vE "$ignores" - find . -type l | sed 's|^./||g' | while read -r ln - do - find "$ln" -maxdepth 0 -printf '%l' | md5sum | sed "s|-|$ln|g" - done | cut -c1-33,35- | grep -vE "$ignores" - ) || return $?; } | sort -} - -server_hash_list() -{ - ssh "$raddr" "set -e - cd '$rdir' - find . -type f ! -regex '^./$syncdir/.*' | sed 's|^./||g' | tr '\n' '\0' | xargs -0 md5sum | cut -c1-33,35- | grep -vE '$ignores' - find . -type l | sed 's|^./||g' | while read -r ln - do - find \"\$ln\" -maxdepth 0 -printf '%l' | md5sum | sed \"s|-|\$ln|g\" - done | cut -c1-33,35- | grep -vE '$ignores' - " | sort -} - -local_full_list() { - find . -mindepth 1 ! -regex "^./$syncdir\$" ! -regex "^./$syncdir/.*" | sed 's|^./||g' | grep -vE "$ignores" | sort -} - -server_full_list() { - ssh "$raddr" "set -e - cd '$rdir' - find . -mindepth 1 ! -regex '^./$syncdir\$' ! -regex '^./$syncdir/.*' | sed 's|^./||g' | grep -vE '$ignores' - "| sort -} - -write_lists() -{ - local_full_list > "$tree_full" - local_hash_list > "$tree_hash" -} - -## FILTERS - -run_ignore() { - [ -n "$ignores" ] && grep -vE "$ignores" "$@" -} - -# $1 = regex , $@ = args -grep_after_sum() -{ - reg=$1 - shift 1 - grep --color=never -E "^[0-9a-f]{32} $reg" "$@" -} -# $@ = match these -merge() -{ - if [ $# -gt 0 ] - then - re="$1" - shift 1 - for N - do - re="$re|$N" - done - grep -E "^($re)" - return 0 - else # don't change input - cat - fi -} - -reduce_list() -{ - list="$(cat /dev/stdin)" - I=1 - while true - do - ln=$(echo "$list" | sed -n "$I"p) # get nth line - [ -z "$ln" ] && break - list=$(echo "$list" | grep -v "^$ln/") - I=$((I+1)) - done - echo "$list" -} - -## DIFFERENCES - -# find changes from list -# $1 = list file , $@ = targets -# requisite: file contains both hash and filename and is sorted -list_diff() -{ - file=$1 - shift 1 - [ ! -f "$tree_hash" ] && { cut -c34- "$file" ; return 0; } - diff --old-line-format="" --unchanged-line-format="" "$tree_hash" "$file" | cut -c34- | merge "$@" -} - -# find deleted from list -# $1 = list file , $@ = targets -# requisite: file contains only filename and is sorted -get_deleted() -{ - file=$1 - shift 1 - [ ! -f "$tree_full" ] && return 0 - diff --new-line-format="" --unchanged-line-format="" "$tree_full" "$file" | reduce_list | grep -vE "$ignores" | merge "$@" -} - -## TRANSACTIONS - -# read list from stdin -# $1 = dry mode -send() { - if [ "$1" = "dry" ] - then - echo "* files to send" - cat - else - printf '* ' - rsync $rsync_opts --files-from=- --exclude=".zsync" -e ssh "$(pwd)" "$raddr:$rdir" || return $? - fi -} - -# read list from stdin -# $1 = dry mode -recieve() { - if [ "$1" = "dry" ] - then - echo "* files to recieve" - cat - else - printf '* ' - rsync $rsync_opts --files-from=- -e ssh "$raddr:$rdir" "$(pwd)" || return $? - fi -} - - -# read list from stdin -# $1 = dry mode -delete_server() { - if [ "$1" = "dry" ] - then - echo "* deleted to send" - cat - else - echo "* sending deleted" - ssh "$raddr" "cd '$rdir' || exit 1 - trashutil='gio trash' - which trash-put >/dev/null 2>&1 && trashutil=trash-put - while read -r ln - do - \$trashutil \"\$ln\" && echo \"\$ln\" || exit \$? - done - " || return $? - fi -} -# read delete from stdin -# $1 = dry mode -delete_local() { - if [ "$1" = "dry" ] - then - echo "* deleted to recieve" - cat - else - echo "* recieving deleted" - trashutil='gio trash' - which trash-put >/dev/null 2>&1 && trashutil=trash-put - while read -r ln - do - $trashutil "$ln" && echo "$ln" || return $? - done - fi -} - -forcepull() -{ - local ret=0 - get_server || return $? - init_local || return $? - init_server || { unlock_local ; return $?; } - rsync $rsync_opts -r --delete -e ssh "$raddr:$rdir" "$(pwd)/." || ret=$? - unlock_all - write_lists - return $ret -} - -forcepush() -{ - local ret=0 - get_server || return $? - init_local || return $? - init_server || { unlock_local ; return $?; } - rsync $rsync_opts -r --delete -e ssh "$(pwd)/." "$raddr:$rdir" || ret=$? - unlock_all - write_lists - return $ret -} - -# $1 = method (null/'push'/'pull') , $2 = dry (null/'dry') , $@ = files -sync() -{ - method=$1 - dry=$2 - shift 2 - - check_paths "$@" || return $? - - get_server || { echo "Server not configured on this instance" >&2 && return 1; } - get_ignores - - # init and check local - init_local || return $? - - # init, check, and lock server - init_server || { - ret=$? - unlock_local - return $ret - } - - tdir=$(tmpdir) - mkdir -p "$tdir" - - - local_full_list > "$tdir/local_full" - local_hash_list > "$tdir/local_hash" - server_full_list > "$tdir/server_full" - server_hash_list > "$tdir/server_hash" - - # get changed on both sides - local_newer=$( list_diff "$tdir/local_hash" "$@") || { rm -rf "$tdir" ; unlock_all ; return 1; } - server_newer=$(list_diff "$tdir/server_hash" "$@") || { rm -rf "$tdir" ; unlock_all ; return 1; } - # get deleted on both sides - deleted_local=$( get_deleted "$tdir/local_full" "$@") || { rm -rf "$tdir" ; unlock_all ; return 1; } - deleted_server=$(get_deleted "$tdir/server_full" "$@") || { rm -rf "$tdir" ; unlock_all ; return 1; } - - # get collisions - collisions=$(printf "%s\n%s\n" "$local_newer" "$server_newer" | sort | uniq -d) - [ -n "$collisions" ] && [ "$method" != push ] && [ "$method" != pull ] && { - echo "-- There are file collisions" >&2 - echo "$collisions" - rm -rf "$tdir" - unlock_all - return 100 - } - - # remove collisions from opposing method - [ -n "$collisions" ] && { - if [ "$method" = "pull" ] - then - local_newer=$(printf "%s\n%s\n" "$collisions" "$local_newer" | sort | uniq -u) - else - server_newer=$(printf "%s\n%s\n" "$collisions" "$server_newer" | sort | uniq -u) - fi - } - - if [ -n "$local_newer" ] || [ -n "$server_newer" ] || [ -n "$deleted_local" ] || [ -n "$deleted_server" ] - then - # operations - if [ "$method" = "pull" ] - then - [ -n "$server_newer" ] && echo "$server_newer" | recieve "$dry" - [ -n "$local_newer" ] && echo "$local_newer" | send "$dry" - else - [ -n "$local_newer" ] && echo "$local_newer" | send "$dry" - [ -n "$server_newer" ] && echo "$server_newer" | recieve "$dry" - fi - - # delete has no impact on timestamps - [ -n "$deleted_local" ] && echo "$deleted_local" | delete_server "$dry" - [ -n "$deleted_server" ] && echo "$deleted_server" | delete_local "$dry" - - # real run - [ "$dry" != "dry" ] && { - # update lists - write_lists - } - fi - - rm -rf "$tdir" - - unlock_all -} - -which rsync >/dev/null || { echo "rsync not installed" >&2 && exit 1; } - -# options -unset arg_c -while getopts ":hC:" opt; -do - case $opt in - C) - [ -z "$OPTARG" ] && echo "Option -C requires an argument" >&2 && exit 1 - arg_c="$OPTARG" - ;; - h) usage && exit 1 ;; - \?) echo "Unknown option: $OPTARG" >&2 && usage && exit 1 ;; - esac -done -shift $((OPTIND-1)) - -# raddr=zawz@zawz.net -# rdir=sync/tmp -[ -f "$server_file" ] && get_server - -# preprocess -[ -n "$arg_c" ] && { cd "$arg_c" || exit $?; } # -C opt - -[ $# -lt 1 ] && usage && exit 1 -arg=$1 -shift 1 - -# actions -case $arg in - server) setup_server "$@" ;; - run) sync "" "" "$@" ;; - pull) sync pull "" "$@" ;; - push) sync push "" "$@" ;; - dry) sync "" dry "$@" ;; - drypush) sync push dry "$@" ;; - drypull) sync pull dry "$@" ;; - forcepush) forcepush ;; - forcepull) forcepull ;; - *) usage && exit 1 ;; -esac