#!/bin/sh

SIMULATE=0
SUDO=0
SUDO_BIN=sudo
EXEC=""
SSHONCE=0
TRUNCATE=0

usage() {
	echo "$0 [-n] [-d] [-s [-e sudo|doas]] server"
	exit 0
}

while getopts pndse: arg; do
	case ${arg} in
		n) SIMULATE=1 ;;
		d) TRUNCATE=1 ;;
		s) SUDO=1 ;;
		e) SUDO_BIN="${OPTARG}" ;;
		p) SSHONCE=1 ;;
		*) usage ;;
	esac
done
shift $((OPTIND - 1))

# allow to use a privilege escalation program
if [ "$SUDO" -eq 1 ]
then
	EXEC="$SUDO_BIN"
fi

# use ControlMaster to make connections persistent
if [ "$SSHONCE" -eq 1 ]
then
	SSH_PARAMS=-o"ControlMaster=auto"" "-o"ControlPath=/tmp/drist_ssh_%h_%p_%r.sock"" "-o"ControlPersist=1m"
fi

# check if host exists
if [ "$#" -ne 1 ]; then
	usage
else
	HOSTNAME=$(ssh $SSH_PARAMS "$1" "${EXEC} uname -n")
	if [ "$?" -ne 0 ]; then
		echo "Error while ssh ${1}"
		exit 2
	fi

	if [ "$TRUNCATE" -eq 1 ]; then
		HOSTNAME="${HOSTNAME%%.*}"
	fi
fi

# $1 = directory name
# $2 = remote server
copy_files() {
	# -l = keep symlink / -D = special device
	if [ -d "${1}" ]
	then
		LIST=$(mktemp /tmp/drist-rsync.XXXXXXXXXX)
		if [ -f "$LIST" ]
		then
			printf 'Copying files from folder "%s":\n' "$1"
			find "${1}"/ -type f -or -type l | cut -d '/' -f 2- | tee "${LIST}" | sed 's/^/	\//'
			if [ "$SIMULATE" -ne 1 ]
			then
				rsync -e "ssh $SSH_PARAMS" --rsync-path="${EXEC} rsync" -lDp --files-from="${LIST}" "${1}/" "${2}":/
			fi
			rm "$LIST"
		fi
	fi
}

# $1 = script filename
# $2 = remote server
remote_script() {
	if [ -f "${1}" ]
	then
		printf 'Executing file "%s":\n' "$1"
		if [ "$SIMULATE" -ne 1 ]
		then
			dr="$(mktemp ./drist.XXXXXXXXXXXX)"
			ssh $SSH_PARAMS "${2}" "DRIST=${dr} &&
			    cat - > \$DRIST &&
			    chmod u+x \$DRIST &&
			    ${EXEC} \$DRIST ;
			    rm \$DRIST" < "$1"
			rm "$dr"
		fi
	fi
}

# $1 = directory name
# $2 = remote server
delete_files() {
	if [ -d "${1}" ]
	then
		LIST=$(mktemp /tmp/drist-rsync.XXXXXXXXXX)
		if [ -f "$LIST" ]
		then
			printf 'Removing files from folder "%s":\n' "$1"
			find "$1" -type f | sed 's/"/\\&/' | \
				awk -v path="${1}" '{ printf "\"%s\" ",substr($0,length(path)+1)}' | \
				tee "${LIST}" | sed 's/^/	/'
			printf '\n' # add a new line

			if [ "$SIMULATE" -ne 1 ]
			then
				test -s "$LIST" && ssh $SSH_PARAMS "$2" "${EXEC} rm $(cat $LIST)"
			fi
			rm $LIST
		fi
	fi
}


copy_files "files" "$1"
copy_files "files-${HOSTNAME}" "$1"
delete_files "absent" "$1"
delete_files "absent-${HOSTNAME}" "$1"
remote_script "script" "$1"
remote_script "script-${HOSTNAME}" "$1"

# close socket if persistance is actived
if [ "$SSHONCE" -eq 1 ]
then
	ssh $SSH_PARAMS -O exit -N "$1"
fi
