#!/bin/sh

# ClonePanel - Manages duplicate accounts on two or more webservers,
# including snapshot backups, monitoring and failover dns.
# Copyright (C)2006 Chris Cheers, Internet Lynx.
# Contact chris[at]clonepanel[dot]com.
# Internet Lynx, PO Box 7117, Mannering Park, NSW 2259, Australia

# This program 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 2
# of the License, or (at your option) any later version.

# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

Version=0.33
# sync_remote -h for built-in documentation

set -u
# Be strict about variable declaration

unset PATH
#avoid use of $PATH - limit script to system commands we choose

PROGRAM_DIR=$(/bin/echo $0 |/bin/sed -e "s/\/[a-zA-Z0-9_]*$//")
# Extract the working directory from command line
# NB - if your system doesn't have echo and sed in these locations
# then this line will need to be changed in all shell scripts

# Standard include files:
. $PROGRAM_DIR/includes

# Built-in documentation:
function showdocs {
	$CAT <<-EODOC
		Sync / update the setup, data and script files on a remote account.
		ssh (secure shell) access MUST ALREADY BE ENABLED on remote account!

		This script uses rsync to update on the remote server
		(both special setup and common script files)
		
		Command line options: 
		-h		Print these instructions and exit
		-H host		Nickname of the server hosting the account
					(if not specified, update all hosts for the specified user)
		-u user		CPanel username of the account
					(must be specified or script will prompt for it)
		
EODOC
	exit $DOC_REQUEST
}

# Initialise own input variables:
ophost=''
opuser=''

function sync_account_user {
# Find all applicable hosts for this user (unless single host specified)
	user=$1
	thishost=$2
	# User-specific Include files (only after defining $user):
	config -u $user

	if [ $thishost ]; then
		sync_account "$user" "$thishost"
	else
		for thishost in `$GREP -v "^DNS" $ROLES_FILE |$CUT -d "=" -f2 |$SORT |$UNIQ`
# sync to all host names in the roles file except for dns-only hosts
		do
			if [ "$thishost" ]; then
				sync_account "$user" "$thishost"
			fi
		done
		
	fi
}

function sync_account {
# Do the real work of syncing remote accounts here - given a username and host name
	user=$1
	host=$2
	
	config -u $user -H $host
	
	remote_ssh="$SSH -p $SSH_PORT -i $AUTH_DIR/$host";
	# how to authenticate with remote domain (restricted password-less key system)
	
	if [ ! "$REMOTE_SKEL" ]; then
		cecho -c $error "Fatal config error"
		exit $E_EMPTY_CONFIG_VAR
	fi
	# Clear files from this dir (should be empty anyway)
	$RM -rf $REMOTE_SKEL/*
	
	if [ ! -d $REMOTE_SKEL ]; then
# Create the new temporary directory if necessary
		$MKDIR $REMOTE_SKEL
	fi
	
# and copy important system files there
	$CP $ROLES_FILE $REMOTE_SKEL
	$CP -r $USER_DIR/$DATABASE_DIRNAME $REMOTE_SKEL
	$CP -r $USER_DIR/$ZONES_DIRNAME $REMOTE_SKEL
	if [ "$MONITOR_PROXY" == 'y' ]; then
		$CP -r $HOSTS_DIR $REMOTE_SKEL
# Host information only required for monitoring by proxy
		for c_var in $REMOTE_MONITOR_VARS
# Monitor hosts require another config file containing further variables
		do
			eval c_val=\$$c_var		
			$ECHO "$c_var='$c_val'" >>$REMOTE_SKEL/mconfig
		done
		$CP -r $REMOTE_CGI_DIR $REMOTE_SKEL
# CGI programs for monitor
		for script in `$FIND $REMOTE_SKEL/$REMOTE_CGI_DIRNAME -type f`
		do
			for var in $SYNC_CGI_SUBS
			do
				eval val=\$$var
# Indirect reference to variable named in SYNC_CGI_SUBS
				regexp="s|_${var}_|$val|"
				$SED -ie $regexp $script
# In cgi scripts, replace _variablename_ with current value of that variable
			done
		done
		$RM $REMOTE_SKEL/$REMOTE_CGI_DIRNAME/*.cgie
# Clear sed backups
	fi
# plus the needed script files
	$CP -r $REMOTE_PROGRAM_DIR $REMOTE_SKEL
# If mail handling is required and no option to install modules site-wide
        if [ "$UPLOAD_PERL_MAIL_MODULES" == $host -o "$UPLOAD_PERL_MAIL_MODULES" == "all" ]; then
		$CP -r $REMOTE_SETUP_DIR/$PERL_MODULES_DIR $REMOTE_SKEL/$REMOTE_PROGRAM_DIRNAME
	fi

# Now create a config file containing all the variables needed by the remote scripts
	$ECHO "MY_NAME='$host'" >>$REMOTE_SKEL/rconfig
# Special case - don't use value of $MY_NAME, instead use host's name
	for c_var in $REMOTE_COMMAND_VARS $REMOTE_CONFIG_VARS
	do
		eval c_val=\$$c_var		
		$ECHO "$c_var='$c_val'" >>$REMOTE_SKEL/rconfig
	done

# Next handle any overrides required
	for c_file in $REMOTE_CONFIG_FILES
	do
		for override_dir in $PROGRAM_DIR $HOSTS_DIR/$host $ACCOUNTS_DIR/$user/$host
		do
			if [ -f "$override_dir/$c_file" ]; then
				$CAT $override_dir/$c_file >>$REMOTE_SKEL/$c_file
#	Allow override of standard config files by host or by user and host
			fi
		done
	done

	#sync files to the remote machine
	$RSYNC	--bwlimit=$RSYNC_BWLIMIT		\
		-avz  --delete				\
                --exclude=$SYNC_R			\
		-e "$remote_ssh" 			\
		$REMOTE_SKEL/* $REMOTEHOST_USERNAME@$A:$REMOTEHOST_HOME/$REMOTEHOST_SYNC_DIRNAME
	checkerror $? $E_RSYNC_SPECIFIC_FAILED

	#clear files again (tidying)
	$RM -rf $REMOTE_SKEL/* ;
	
	cecho -c $ok "Sync complete for $user ($REMOTEHOST_USERNAME) on $host" ;
}

# Start real script

# Check for help request and input variables in the command line options:
while getopts ":hH:u:" opt
do
	case $opt in
		h)	showdocs
			;;
		H)	ophost=$OPTARG
			;;
		u)	opuser=$OPTARG
			;;
		*)	$ECHO "Unknown option. Use -h for instructions"; exit $E_UNKNOWN_OPT
			;;
	esac
done
shift $(($OPTIND - 1))

OPTIND=1
# reset getopts for next time

if [ ! $opuser ]; then
	cecho -n -c $prompt "Enter account username: "
	read opuser
	if [ ! $opuser ]; then
		cecho -c $error "Username must be specified"
		exit $E_BLANK_INPUTS
	fi
fi

sync_account_user "$opuser" "$ophost"


