#!/bin/bash -f
# wakeup host at specified time.
# CGI vars:
#	hostname=HostName
#	wake_second=UnixTimeSecond
#	wake_time=HumanReadableDateTime

function uri_unescape() {
	local	b c i l
	b=""
	while read
	do
		i=0
		l=${#REPLY}
		while (( ${i} < ${l} ))
		do
			c=${REPLY:${i}:1}
			case ${#b} in
			  (0)
				case "${c}" in
				  (+)
					echo -n " "
				  ;;
				  (%)
					b='\x'
				  ;;
				  (*)
					echo -n "${c}"
				  ;;
				esac
			  ;;
			  (2)
				b="${b}${c}"
			  ;;
			  (3)
				b="${b}${c}"
				printf "%b" "${b}"
				b=""
			  ;;
			  (*)
				echo -n "${c}"
				b=""
			  ;;
			esac
			i=$(( ${i} + 1 ))
		done
	done
}

function query_var() {
	key="$1"
	echo ${QUERY_STRING} | \
	tr '&' '\n' | \
	grep "^$1=" | \
	sed -n -e "s/^$1=//p" | \
	uri_unescape
}

operation="add"
order_state="add"

shell_operators='$|&;<>(){}[]`'

wake_host=`query_var   hostname    | tr -dc '[:alnum:]._-' `
wake_second=`query_var wake_second | tr -dc '+-[:digit:]'`
wake_time=`query_var   wake_time   | tr -d "${shell_operators}"`

if [[ -n "${wake_host}" ]]
then
	# Add waketimer
	wake_ip=`ping -c 1 "${wake_host}" | \
		grep PING | \
		cut -f 2 -d '(' | \
		cut -f 1 -d ')'`

	if [[ -z "${wake_ip}" ]]
	then
		operation="error"
		order_state="not_found"
	else
		wake_mac=`/usr/sbin/arp -n | \
			  fgrep "${wake_ip}" | \
			  gawk '{print $3}'`

		if [[ -z "${wake_mac}" ]]
		then
			operation="error"
			order_state="not_found"
		fi
	fi
else
	# Request active list.
	wake_ip=""
	wake_mac=""
	operation="list"
	order_state="list"
fi

if [[ -n "${wake_time}" ]]
then
	wake_time_s=`date --date="${wake_time}" +%s 2>/dev/null`
	if [[ -n "${wake_time_s}" ]]
	then
		wake_second=$(( ${wake_time_s} + 0 ))
	else
		operation="error"
		order_state="error"
	fi
fi

now_sec=`date +%s`

wake_sleep=$(( ${wake_second} - ${now_sec} ))
if (( ${wake_sleep} < 0 ))
then
	wake_second=${now_sec}
	wake_sleep=0
fi

order_label="${wake_host}/${wake_mac}/${wake_second}"

page_title=""
if [[ "${operation}" == "list" ]]
then
	page_title="WOL waketimers list"
else
	page_title="WOL waketimers order ${order_label}"
fi

echo "Content-type: text/html"
echo ""
echo "<html>"
echo "<head>"
echo "<title>${page_title}</title>"
echo "</head>"
echo "<body>"
echo "<h1>${page_title}</h1>"
echo "<hr>"

echo "<table style=\"border-collapse: collapse;\" border=\"1\">"
echo "<tr><th>order-id</th><th>time</th><th>state</th></tr>"

for find_id in  `ps -eo "%a" | \
		grep 'bash.*sleep.*wakeonlan.*echo' | \
		sed 's/.*echo//'`
do
	state="queued"
	if [[ "${find_id}" == "${order_label}" ]]
	then
		operation="nop"
		order_state="queued"
	fi
	if [[ "${operation}" == "list" ]]
	then
		active_time=`basename "${find_id}"`
		active_ymdhms=`date --date=@${active_time} "+%Y/%m/%d %H:%M:%S"`
		echo -n "<tr>"
		echo -n "<td>${find_id}</td>"
		echo -n "<td>${active_ymdhms}</td>"
		echo -n "<td>${state}</td>"
		echo "</tr>"
	fi
done

if [[ "${operation}" == "add" ]]
then
	(	nohup /bin/bash -c "sleep ${wake_sleep}; wakeonlan ${wake_mac}; echo ${order_label}" 
	) > /dev/null 2>&1 &
fi

if [[ "${operation}" != "list" ]]
then
	active_ymdhms=`date --date=@${wake_second} "+%Y/%m/%d %H:%M:%S"`
	echo -n "<tr>"
	echo -n "<td>${order_label}</td>"
	echo -n "<td>${active_ymdhms}</td>"
	echo -n "<td>${order_state}</td>"
	echo "</tr>"
fi

echo "</table>"

echo "</body>"
echo "</html>"

exit 0
