#!/bin/sh
#
# Resource script for Proftpd
#
# Description:  Manages Proftpd as an OCF resource in 
#		an Active-Passive High Availability setup.
#
# Author:	Rajat Upadhyaya <urajat@novell.com> : Pure-FTPd script 
# Author:	Achim Stumpf <hakim.news@googlemail.com> : Rewrite as Proftpd
# License:      GNU General Public License (GPL) 
#
#
#	usage: $0 {start|stop|status|monitor|validate-all|meta-data}
#
#	The "start" arg starts Proftpd.
#
#	The "stop" arg stops it.
#
# OCF parameters:
#  OCF_RESKEY_binary
#  OCF_RESKEY_conffile
#  OCF_RESKEY_pidfile
#  OCF_RESKEY_curl_binary
#  OCF_RESKEY_curl_url
#  OCF_RESKEY_test_user
#  OCF_RESKEY_test_pass
#
##########################################################################
# Initialization:

: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs

: ${OCF_RESKEY_binary="/usr/sbin/proftpd"}
: ${OCF_RESKEY_conffile="/etc/proftpd.conf"}
: ${OCF_RESKEY_pidfile="/var/run/proftpd.pid"}
: ${OCF_RESKEY_curl_binary="/usr/bin/curl"}
: ${OCF_RESKEY_curl_url="ftp://localhost/"}
: ${OCF_RESKEY_test_user="test"}
: ${OCF_RESKEY_test_pass=""}

USAGE="Usage: $0 {start|stop|status|monitor|validate-all|meta-data}";

##########################################################################

usage() {
	echo $USAGE >&2
}

meta_data() {
        cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="proftpd">
<version>1.0</version>
<longdesc lang="en">
This script manages Proftpd in an Active-Passive setup
</longdesc>
<shortdesc lang="en">OCF Resource Agent compliant FTP script.</shortdesc>

<parameters>

<parameter name="binary" unique="0" required="0">
<longdesc lang="en">The Proftpd binary</longdesc>
<shortdesc lang="en">The Proftpd binary</shortdesc>
<content type="string" default="/usr/sbin/proftpd" />
</parameter>

<parameter name="conffile" unique="0" required="0">
<longdesc lang="en">
The Proftpd configuration file name with full path. 
For example, "/etc/proftpd.conf"
</longdesc>
<shortdesc lang="en">Configuration file name with full path</shortdesc>
<content type="string" default="/etc/proftpd.conf" />
</parameter>

<parameter name="pidfile" unique="0" required="0">
<longdesc lang="en">The Proftpd PID file. The location of the PID file is configured in the Proftpd configuration file.</longdesc>
<shortdesc lang="en">PID file</shortdesc>
<content type="string" default="/var/run/proftpd.pid" />
</parameter>

<parameter name="curl_binary" unique="0" required="0">
<longdesc lang="en">The absolut path to the curl binary for monitoring with OCF_CHECK_LEVEL greater zero.</longdesc>
<shortdesc lang="en">The absolut path to the curl binary</shortdesc>
<content type="string" default="/usr/bin/curl" />
</parameter>

<parameter name="curl_url" unique="0" required="0">
<longdesc lang="en">The URL which is checked by curl with OCF_CHECK_LEVEL greater zero.</longdesc>
<shortdesc lang="en">The URL which is checked by curl</shortdesc>
<content type="string" default="ftp://localhost/" />
</parameter>

<parameter name="test_user" unique="0" required="0">
<longdesc lang="en">The name of the ftp user for monitoring with OCF_CHECK_LEVEL greater zero.</longdesc>
<shortdesc lang="en">The name of the ftp user</shortdesc>
<content type="string" default="test" />
</parameter>

<parameter name="test_pass" unique="0" required="0">
<longdesc lang="en">The password of the ftp user for monitoring with OCF_CHECK_LEVEL greater zero.</longdesc>
<shortdesc lang="en">The password of the ftp user</shortdesc>
<content type="string" default="" />
</parameter>

</parameters>

<actions>
<action name="start"   timeout="20s" />
<action name="stop"    timeout="20s" />
<action name="monitor" depth="0"  timeout="20s" interval="60s" />
<action name="monitor" depth="10"  timeout="20s" interval="120s" />
<action name="validate-all"  timeout="20s" />
<action name="meta-data"  timeout="5s" />
</actions>
</resource-agent>
END
        exit $OCF_SUCCESS
}

isRunning()
{
	kill -0 "$1" > /dev/null 2>&1
}

proftpd_status()
{
	if [ -f "$OCF_RESKEY_pidfile" ]
	then
	# Proftpd is probably running
		PID=`head -n 1 $OCF_RESKEY_pidfile`
		if [ ! -z "$PID" ] ; then
			isRunning "$PID" && `ps -p $PID | grep proftpd > /dev/null 2>&1`
			return $?
		fi
	fi
	
	# Proftpd is not running
	return $OCF_NOT_RUNNING;
}

proftpd_start()
{
	# make a few checks and start Proftpd
  	if ocf_is_root ; then : ; else
		ocf_log err "You must be root"
		exit $OCF_ERR_PERM
	fi
	
	# if Proftpd is running return success
	if proftpd_status ; then
		ocf_log info "Proftpd is running already"
		exit $OCF_SUCCESS
	fi

	# starting Proftpd
	${OCF_RESKEY_binary} --config ${OCF_RESKEY_conffile} 2>/dev/null

	if [ "$?" -ne 0 ]; then
		ocf_log err "Proftpd returned error" $?
		exit $OCF_ERR_GENERIC
	fi

	exit $OCF_SUCCESS
}


proftpd_stop()
{
	if proftpd_status ; then
		PID=`head -n 1 $OCF_RESKEY_pidfile`
		if [ ! -z "$PID" ]; then
			ocf_log info "Killing Proftpd PID $PID"
			kill $PID > /dev/null 2>&1 
			if [ "$?" -eq 0 ]; then
				TRIES=0
				while isRunning "$PID" && [ "$TRIES" -lt 30 ]
				do
					sleep 1
					ocf_log info "Proftpd PID $PID is still running"
					TRIES=`expr $TRIES + 1`
				done
				isRunning "$PID"
				RET=$?
				if [ "$RET" -eq 0 ]; then
					ocf_log info "Killing Proftpd PID $PID with SIGKILL"
					kill -9 $PID > /dev/null 2>&1
					while isRunning "$PID" 
					do
						sleep 1
						ocf_log info "Proftpd PID $PID is still running"
					done
				fi
			else
				ocf_log err "Killing Proftpd PID $PID FAILED"
				exit $OCF_ERR_GENERIC
			fi	
		fi
	fi

	exit $OCF_SUCCESS
}

proftpd_monitor()
{
	proftpd_status
	RET=$?

	if [ "$RET" -ne 0 -o "$OCF_CHECK_LEVEL" = 0 ]; then	
		if [ "$RET" -eq 0 ]; then
			PID=`head -n 1 $OCF_RESKEY_pidfile`
			ocf_log debug "Proftpd monitor on PID $PID succeeded"
			return $OCF_SUCCESS
		else
			ocf_log debug "Proftpd monitor on PID $PID failed"
			return $OCF_NOT_RUNNING
		fi
	else
		${OCF_RESKEY_curl_binary} -sS -u "${OCF_RESKEY_test_user}:${OCF_RESKEY_test_pass}" ${OCF_RESKEY_curl_url} > /dev/null 2>&1
		if [ "$?" -eq 0 ]; then
			ocf_log debug "Proftpd monitor with curl on URL $OCF_RESKEY_curl_url succeeded"
			return $OCF_SUCCESS
		else
			ocf_log err "Proftpd monitor with curl on URL $OCF_RESKEY_curl_url failed"
			return $OCF_NOT_RUNNING
		fi
	fi
}

proftpd_validate_all()
{

	# check that the proftpd binary exists
	if [ ! -x "$OCF_RESKEY_binary" ]; then
		ocf_log err "Proftpd binary $OCF_RESKEY_binary does not exist"
		exit $OCF_ERR_INSTALLED
	fi	

	# check that the Proftpd config file exists
	if [ ! -f "$OCF_RESKEY_conffile" ]; then
		ocf_log err "Proftpd config file $OCF_RESKEY_conffile does not exist"
		exit $OCF_ERR_CONFIGURED
	fi

	# check that the curl binary exists
	if [ ! -x "$OCF_RESKEY_curl_binary" ]; then
		ocf_log err "$OCF_RESKEY_curl_binary does not exist"
		exit $OCF_ERR_INSTALLED
	fi
}

#
# Main
#

if [ $# -ne 1 ]
then
  usage
  exit $OCF_ERR_ARGS
fi

case $1 in
    start)	proftpd_validate_all
			proftpd_start
			;;
	
    stop)	proftpd_stop
    		;;
		
    status)	if proftpd_status
    		then
				ocf_log info "Proftpd is running"
				exit $OCF_SUCCESS
			else
				ocf_log info "Proftpd is stopped"
				exit $OCF_NOT_RUNNING
			fi
    		;;
		
    monitor)	proftpd_monitor
    			exit $?
    			;;
		
    validate-all)	proftpd_validate_all
					exit $OCF_SUCCESS
    				;;
			
    meta-data)	meta_data
  				;;
		
    usage)	usage
    		exit $OCF_SUCCESS
			;;
		
    *)	usage
 		exit $OCF_ERR_UNIMPLEMENTED
		;;
esac

