#! /bin/sh

set -e

export PATH=/usr/sbin:/usr/bin:/sbin:/bin

test "$MAXSLEEP" || MAXSLEEP=3600

if test -f /etc/cubbli/cubbli.conf; then
	. /etc/cubbli/cubbli.conf
fi
test "$PING_HOST" || PING_HOST="$REPOSITORY_SERVER"
test "$PING_HOST" || PING_HOST="www.cs.helsinki.fi"


mailif() {
	# $? will contain exit code from current shell

	if test -s "$mailfile" -a $? -ne 0; then
		if test "$MAILTO"; then
			mail -s "$(hostname -f): cubbli-installer-cron failed" \
					"$MAILTO" <"$mailfile"
		fi
	fi
	rm "$mailfile"
}


run() {
	if test "$MAILTO"; then
		"$@" 1>>"$mailfile" 2>&1
	else
		"$@"
	fi
}


needs_running() {
	for script in /usr/share/cubbli-installer/rc.d/*; do
		#
		# Why will "check" return non-zero for "needs to be run"?
		#
		#  - Most of the time script doesn't need to be run, thus
		#    true is better return code for the operation.
		#
		#  - If the script fails (due to error), this cannot be
		#    confused with "no running needed".
		#
		#  - Email is sent when actual run results in failure. If
		#    "check" fails, the script will be run again, (hopefully)
		#    fail again, and administrators will be notified.
		#
		if ! sh "$script" check; then
			return 0
		fi
	done

	# Only reached if none of the scripts need running.
	# Return code 1 is considered as "no, no running needed".
	# "ok" means we don't send out an email.
	return 1
}


random_sleep() {
	if ! test "$RANDOM"; then
		RANDOM=$(dd if=/dev/urandom count=1 2>/dev/null | \
				cksum | cut -c 1-5)
	fi
	sleep $(( $RANDOM % $MAXSLEEP ))
	return 0
}


wait_for_dpkg() {
	for a in $(seq 1 60); do
		if apt-get check -o quiet=9; then
			return 0
		fi
		sleep $a
	done

	echo "cubbli-installer-cron thinks apt is busy"
	return 1
}


check_network() {
	if ping -c 1 "$PING_HOST" >/dev/null 2>&1; then
		return 0
	else
		# exit gracefully
		exit 0
	fi
}


update() {
	if aptitude -o quiet=2 update; then
		return 0
	else
		echo "aptitude update failed!"
		echo "running apt-get update in case it provides more info"
		if apt-get update; then
			return 0
		else
			return 1
		fi
	fi
}


run_scripts() {
	ret=0
	for script in /usr/share/cubbli-installer/rc.d/*; do
		if ! sh "$script"; then
			echo "$script failed"
			# This script may have failed, but there may be
			# others that also need to be run. No exit here.
			ret=1
		fi
	done
	return $ret
}



needs_running 	|| exit 0
random_sleep

# Ok, ready to run. Prepare to receive stuff for email.
mailfile=$(mktemp)
trap "mailif" 0


run wait_for_dpkg
check_network
run update
run run_scripts

# trap will call mailif here
exit 0
