#!/bin/bash

BROADSYNCDIR=~/.broadsync
SYNCLINEFILE="synclines"

function returnnewer {
    fctime=$(stat -c %Y "$1")
    if [ -z "$2" ] || [ $fctime -gt $2 ]; then
	echo $fctime
    else
	echo $2
    fi
}

if [ ! -d "$BROADSYNCDIR" ]; then
    mkdir "$BROADSYNCDIR" || exit 1
    echo "Created directory $BROADSYNCDIR."
fi

if [ ! -f "$BROADSYNCDIR/$SYNCLINEFILE" ]; then
    touch "$BROADSYNCDIR/$SYNCLINEFILE" || exit 1
    chmod 600 "$BROADSYNCDIR/$SYNCLINEFILE" || \
	rm "$BROADSYNCDIR/$SYNCLINEFILE"
    echo "# line format:
# user:password:port:/remote_directory:/local_directory" > \
    "$BROADSYNCDIR/$SYNCLINEFILE"
    echo "Created syncline file $BROADSYNCDIR/$SYNCLINEFILE."
fi

if [ $(cat "$BROADSYNCDIR/$SYNCLINEFILE" | grep -v "#" | wc -l) -eq 0 ]; then
    echo "Your syncline file $BROADSYNCDIR/$SYNCLINEFILE is empty."
    echo "You have to add at least one syncline to run broadsync!"
fi

tmpdir="$(mktemp -p /tmp -d broadsync-XXXXXXX)" || exit 1

subnets=$(ip addr | \
    sed -En 's/.*inet (([0-9]*\.){3}[0-9]*)\/.*/\1/p' | \
    grep -v '127.0.0.1' | \
    sed -En 's/(([0-9]*\.){3})[0-9]*/\1/p')

echo "Subnets to probe: $(echo "$subnets" | tr '\n' ' ')"

while read syncline; do
    syncline_user=$(echo "$syncline" | cut -f1 -d":")
    syncline_pass=$(echo "$syncline" | cut -f2 -d":")
    syncline_port=$(echo "$syncline" | cut -f3 -d":")
    syncline_rdir=$(echo "$syncline" | cut -f4 -d":")
    syncline_ldir=$(eval echo "$(echo "$syncline" | cut -f5 -d":")")

    syncline_hash=$(echo "$syncline_user:$syncline_port:$syncline_rdir" | \
	md5sum | cut -f1 -d" ")

    echo "Processing syncline $syncline_user:$syncline_port:$syncline_rdir"

    if [ ! -d "$syncline_ldir" ]; then
	echo "Creating local syncdir $syncline_ldir"
	mkdir "$syncline_ldir" || exit 1
    fi

    statdir="$BROADSYNCDIR/$syncline_hash.stat"
    if [ ! -d "$statdir" ]; then
	echo "Creating statdir $statdir"
	mkdir "$statdir" || exit 1
    fi

    if [ -f "$statdir/newestdate" ]; then
	newestdate=$(cat "$statdir/newestdate")
	echo "Using newestdate $(LANG=en_US date +"%T %B %d %Y" -d @$newestdate)"
    else
	newestdate=0
    fi

    for subnet in $subnets; do
	echo "Scanning for potential hosts in subnet $subnet"

	for i in $(seq 1 254); do
	    (nc -w 5 -z "$subnet$i" "$syncline_port"; echo $? > "$tmpdir/nc-$subnet-$i") &
	done
	wait

	for i in $(seq 1 254); do
	    if [ $(cat "$tmpdir/nc-$subnet-$i") -eq 0 ]; then
		echo "Trying to sync with potential host $subnet$i"

		while read logline; do
		    [ -n "$lastfile" ] && newestdate=$(returnnewer "$syncline_ldir/$lastfile" "$newestdate")
		    echo $logline

		    file=$(echo "$logline" | sed -En 's/Transferring file .(.*)./\1/p')
		    if [ -n $file ]; then
			lastfile="$file"
		    else
			lastfile=""
		    fi
		done < <(lftp -p "$syncline_port" \
		    -u "$syncline_user,$syncline_pass" \
		    -e "mirror -v -N \"$(LANG=en_US date +"%T %B %d %Y" -d @$newestdate)\" \"$syncline_rdir\" \"$syncline_ldir\"" \
		    "$subnet$i")

		[ -n "$lastfile" ] && newestdate=$(returnnewer "$syncline_ldir/$lastfile" "$newestdate")		
	    fi
	done
    done

    echo $newestdate > "$statdir/newestdate"
    
done < <(cat "$BROADSYNCDIR/$SYNCLINEFILE" | grep -v '#')

rm -r "$tmpdir"

exit 0