#!/bin/sh -
#
# $FreeBSD$
#

# PROVIDE: ggatessh
# REQUIRE: NETWORKING
# BEFORE: mountlate
# KEYWORD: nojail

. /etc/rc.subr

name="ggatessh"
desc="ggate devices over ssh/sftp"
rcvar="ggatessh_enable"
destroy_cmd="ggatessh_iter destroy"
rescue_cmd="ggatessh_iter rescue"
start_cmd="ggatessh_iter start"
stop_cmd="ggatessh_iter stop"
status_cmd="ggatessh_iter status"
tests_cmd="ggatessh_tests"
extra_commands="destroy rescue status tests"
required_modules="geom_gate:g_gate"

# ggatessh_devs="0 2 3"
# ggatessh_0_path="remuser@host.example.com:somepath"
# ggatessh_0_pidfile="xxx"
# ggatessh_0_sector="512"
# ggatessh_0_port="22"
# ggatessh_0_sshkey="/root/.ssh/id.rsa.ggate0"

getvar()
{
	eval echo \${ggatessh_${devnum}_$1}
}

getpidfile()
{
	local pidfile

	pidfile=$(getvar pidfile)
	pidfile=${pidfile:=/var/run/ggatessh.ggate${devnum}.pid}
	echo "$pidfile"
}

# Parses ggatessh_${devnum}_path into the variables:
# user - username of user (defaults to root)
# host - hostname of server
# imgpath - path to image on server

getpid()
{
	pgrep -L -F $(getpidfile) 2>/dev/null
}

parse_path()
{
	path=$(getvar path)
	imgpath="${path#*:}"
	userhost="${path%:*}"
	host="${userhost#*@}"
	user="${userhost%$host}"
	user="${user%@}"
	user="${user:=root}"
}

ggatessh_destroy()
{
	echo destroying ggate$devnum
	ggatessh destroy -u "$devnum"
}

ggatessh_run()
{
	if [ x"$(getvar pidfile)" != x"" ]; then
		args="-F $(getvar pidfile)"
	fi
	if [ x"$(getvar sshkey)" != x"" ]; then
		args="$args -i $(getvar sshkey)"
	fi
	if [ x"$(getvar sector)" != x"" ]; then
		args="$args -s $(getvar sector)"
	fi
	if [ x"$(getvar port)" != x"" ]; then
		args="$args -p $(getvar port)"
	fi

	ggatessh "$1" $args -l "$user" -u "$devnum" "$host" "$imgpath"
}

ggatessh_rescue()
{
	echo "rescuing ggatessh ggate$devnum"
	ggatessh_run rescue
}

ggatessh_start()
{
	echo "starting ggatessh ggate$devnum"
	ggatessh_run create
}

ggatessh_stop()
{
	pid=$(getpid)
	if [ x"$pid" != x"" ]; then
		echo "killing ggatessh ggate$devnum pid $pid"
		while :; do
			pkill -L -F $(getpidfile) -q
			if ! getpid >/dev/null; then
				echo .
				sleep .5
			fi
		done
	else
		echo "error ggatessh $devnum not running"
		exit 1
	fi
}

ggatessh_status()
{
	pid=$(getpid)
	if [ x"$pid" != x"" ]; then
		echo "ggatessh for ggate$devnum is running (pid=$pid)"
	else
		echo "ggatessh for ggate$devnum is not running"
	fi
}

# Tests to make sure various functions work as expected
ggatessh_tests()
{

	echo starting tests: $(date)

	devnum=5
	ggatessh_5_path="auser@ahost:apath"
	parse_path
	if [ "$user" != "auser" -o "$host" != "ahost" -o "$imgpath" != "apath" ]; then
		echo failed to parse: $ggatessh_5_path
		exit 1
	fi
	ggatessh_5_path="@ahost:apath"
	parse_path
	if [ "$user" != "root" -o "$host" != "ahost" -o "$imgpath" != "apath" ]; then
		echo failed to parse: $ggatessh_5_path
		exit 1
	fi
	ggatessh_5_path="ahost:apath"
	parse_path
	if [ "$user" != "root" -o "$host" != "ahost" -o "$imgpath" != "apath" ]; then
		echo failed to parse: $ggatessh_5_path
		exit 1
	fi

	if [ x"$(getpidfile)" != x"/var/run/ggatessh.ggate5.pid" ]; then
		echo "getpidfile returned invalid: $(getpidfile)"
		exit 1
	fi

	ggatessh_5_pidfile="somepidfile"
	if [ x"$(getvar pidfile)" != x"somepidfile" ]; then
		echo getvar failed to fetch pidfile
		exit 1
	fi
	if [ x"$(getpidfile)" != x"somepidfile" ]; then
		echo "getpidfile returned invalid: $(getpidfile)"
		exit 1
	fi


	ggatessh()
	{
		if [ x"$*" != x"$expected" ]; then
			echo failed, got: "$*"
			exit 1
		fi
	}

	ggatessh_5_sshkey=""

	expected="create -F somepidfile -l root -u 5 ahost apath"
	res=$(ggatessh_start)
	if [ x"$res" != x"starting ggatessh ggate5" ]; then
		echo failed to output correct info on start, got: "$res"
		exit 1
	fi

	expected="rescue -F somepidfile -l root -u 5 ahost apath"
	res=$(ggatessh_rescue)
	if [ x"$res" != x"rescuing ggatessh ggate5" ]; then
		echo failed to output correct info on rescue, got: "$res"
		exit 1
	fi

	ggatessh_5_sector="123"
	expected="rescue -F somepidfile -s 123 -l root -u 5 ahost apath"
	ggatessh_rescue >/dev/null

	ggatessh_5_sector=""
	ggatessh_5_sshkey="some.keyfile"
	expected="create -F somepidfile -i some.keyfile -l root -u 5 ahost apath"
	ggatessh_start >/dev/null

	ggatessh_5_port="randomport"
	expected="create -F somepidfile -i some.keyfile -p randomport -l root -u 5 ahost apath"
	ggatessh_start >/dev/null

	ggatessh_5_port="randomport"
	expected="destroy -u 5"
	ggatessh_destroy >/dev/null

	echo done
}

ggatessh_iter()
{

	for devnum in $ggatedevnums; do
		parse_path
		if [ x"$1" = x"start" ]; then
			ggatessh_start
		elif [ x"$1" = x"stop" ]; then
			ggatessh_stop
		elif [ x"$1" = x"status" ]; then
			ggatessh_status
		fi
	done
}

load_rc_config $name

cmd="$1"
shift
tmp="$*"
ggatedevnums="${tmp:=$ggatessh_devs}"

run_rc_command "$cmd"
