142 lines
5.2 KiB
Bash
Executable File
142 lines
5.2 KiB
Bash
Executable File
#!/bin/bash
|
|
# Copyright 2021 Luca Paris
|
|
#This file is part of masync.
|
|
|
|
#masync is free software: you can redistribute it and/or modify
|
|
#it under the terms of the GNU General Public License as published by
|
|
#the Free Software Foundation, either version 3 of the License, or
|
|
#(at your option) any later version.
|
|
|
|
#masync is distributed in the hope that it will be useful,
|
|
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
#GNU General Public License for more details.
|
|
|
|
#You should have received a copy of the GNU General Public License
|
|
#along with masync. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
## REQUIREMENT
|
|
# apt-get install inotify-tools
|
|
# @1 hash to retrieve sync
|
|
# @2 local path to sync
|
|
# @3 remote path to sync
|
|
#echo "$1, $2, $3"
|
|
source ~/bin/.synccmd.sh
|
|
source ~/bin/.colordef.sh
|
|
TMPQUEUEFILE=~/.syncdir_$1.queue
|
|
TMPQUEUEDELETES=~/.syncdir_$1.deletes
|
|
|
|
LOCALPATH_HASH=$1
|
|
LOCALPATH=$2
|
|
REMOTEPATH=$3
|
|
|
|
REMOTEHOST=$(echo "$REMOTEPATH" | cut -d : -f 1 | cut -d @ -f 2)
|
|
REMOTERELATIVEPATH=$(echo "$REMOTEPATH" | cut -d : -f 2)
|
|
|
|
#acquire lock_deletes file descritptor
|
|
exec {lock_deletes}>>${TMPQUEUEDELETES}
|
|
#acquire lock queue file descriptor
|
|
exec {lock_queue}>>${TMPQUEUEFILE}
|
|
|
|
min() {
|
|
if [ $1 -gt $2 ]; then
|
|
echo $2
|
|
else
|
|
echo $1
|
|
fi
|
|
}
|
|
|
|
synccycle() {
|
|
lastsynctime="$(date -u +%s.%N)"
|
|
### initial max waiting time for pull (seconds) used as unit
|
|
### first pulliteration zero cause immediate pulling from remote
|
|
pulllimitunit=60
|
|
pulliteration=0
|
|
maxpulliteration=5
|
|
let "maxpulllimit = $pulllimitunit * $pulliteration"
|
|
### max waiting time for pull (seconds) 10 min
|
|
thresholdpulllimit=600
|
|
while :
|
|
do
|
|
if [ -f "$TMPQUEUEFILE" ] || [ -f "$TMPQUEUEDELETES" ]; then
|
|
### DELETES WHILE LOOP
|
|
if [ -f "$TMPQUEUEDELETES" ]; then
|
|
ndeletes=$(wc -l < ${TMPQUEUEDELETES})
|
|
while [ $ndeletes -gt 0 ]; do
|
|
echo -e "${PURPLE}[PUSH FILES TO DELETE]${ENDCOLOR} to remote: ${RED}$(head -n $ndeletes ${TMPQUEUEDELETES} | tr '\n', ' ')${ENDCOLOR}"
|
|
ssh $REMOTEHOST "rm -rf $(head -n $ndeletes ${TMPQUEUEDELETES} | tr '\n', ' ')"
|
|
echo -e ${PURPLE}DONE${ENDCOLOR}
|
|
# remove the first ndeletes lines
|
|
flock $lock_deletes
|
|
tmpfile=$(mktemp)
|
|
tail -n +$(expr ${ndeletes} + 1) < ${TMPQUEUEDELETES} > ${tmpfile}
|
|
cat ${tmpfile} > ${TMPQUEUEDELETES}
|
|
rm -f ${tmpfile}
|
|
flock -u $lock_deletes
|
|
ndeletes=$(wc -l < ${TMPQUEUEDELETES})
|
|
done
|
|
fi
|
|
|
|
### PUSH WHILE LOOP
|
|
if [ -f "$TMPQUEUEFILE" ]; then
|
|
nqueue=$(wc -l < ${TMPQUEUEFILE})
|
|
while [ $nqueue -gt 0 ]; do
|
|
#echo "${TMPQUEUEFILE} not empty consume ${nqueue} updates in queue"
|
|
echo -e "${PURPLE}[PUSH FILES]${ENDCOLOR} to remote: ${GREEN}$(head -n ${nqueue} ${TMPQUEUEFILE} | tr '\n', ' ')${ENDCOLOR}"
|
|
sync $LOCALPATH_HASH $LOCALPATH $REMOTEPATH
|
|
echo -e "${PURPLE}DONE${ENDCOLOR}"
|
|
# remove the first nqueue lines from queue
|
|
flock $lock_queue
|
|
tmpfile=$(mktemp)
|
|
tail -n +$(expr ${nqueue} + 1) < ${TMPQUEUEFILE} > ${tmpfile}
|
|
cat ${tmpfile} > ${TMPQUEUEFILE}
|
|
rm -f ${tmpfile}
|
|
flock -u $lock_queue
|
|
#lastsynctime="$(date -u +%s.%N)"
|
|
nqueue=$(wc -l < ${TMPQUEUEFILE})
|
|
done
|
|
fi
|
|
fi
|
|
now="$(date -u +%s.%N)"
|
|
elapsed="$(bc <<<"$now-$lastsynctime")"
|
|
## if elapsed is greater than maxpulllimit sync from remote with delete option
|
|
if [ 1 -eq $(echo "$elapsed>$maxpulllimit" | bc) ]; then
|
|
echo -e "${PURPLE}[PULL LIMIT REACHED]${ENDCOLOR}: $maxpulllimit seconds reached: sync from remote with --delete option"
|
|
sync $LOCALPATH_HASH $REMOTEPATH $LOCALPATH '--delete'
|
|
lastsynctime="$(date -u +%s.%N)"
|
|
## increment the pull iteration or reset it
|
|
if [ ${pulliteration} -eq ${maxpulliteration} ]; then
|
|
pulliteration=0
|
|
else
|
|
let pulliteration++
|
|
fi
|
|
let "limit = $pulliteration * $pulliteration * $pulllimitunit"
|
|
maxpulllimit=$(min $limit $thresholdpulllimit)
|
|
fi
|
|
sleep 10
|
|
done
|
|
}
|
|
|
|
synccycle &
|
|
|
|
# exclude swp,swpx and 4913 files created by vim
|
|
inotifywait -m -r -e create -e close_write -e move -e delete --exclude "\.swp|\.swx|4913|.txt~" $LOCALPATH | while read dir action file; do
|
|
if [ $action = 'DELETE' ] || [ $action = 'DELETE,ISDIR' ] || [ $action = 'MOVED_FROM' ] || [ $action = 'MOVED_FROM,ISDIR' ]; then
|
|
echo -e "${PURPLE}[ENQUEUE delete]${ENDCOLOR}: $dir$file"
|
|
flock $lock_deletes
|
|
echo $dir$file | sed -e "s~$LOCALPATH~$REMOTERELATIVEPATH~g" | tee -a ${TMPQUEUEDELETES} 1>/dev/null
|
|
flock -u $lock_deletes
|
|
else
|
|
flock $lock_queue
|
|
## add to queue only if not already in it
|
|
if [ $(grep -E ${file}$ ${TMPQUEUEFILE} | wc -l) -lt 1 ]; then
|
|
#echo "Add notify to queue: file '$file' in directory '$dir' for '$action'" | tee -a ${TMPQUEUEFILE}
|
|
echo -e "${PURPLE}[ENQUEUE file]${ENDCOLOR}: $dir$file"
|
|
# AVOID TO USE TEE: SIMPLY append
|
|
#echo ${dir}${file} | tee -a ${TMPQUEUEFILE}
|
|
echo ${dir}${file} >> ${TMPQUEUEFILE}
|
|
fi
|
|
flock -u $lock_queue
|
|
fi
|
|
done
|