#!/bin/sh
#
# Resource script for sending WinPopups using smbclient
# derived from Alan Robertson's MailTo script
#
# Author: Sandro Poppi <spoppi@gmx.de>
#
# Description: sends WinPopups to a sysadmin's workstation
#	       whenever a takeover occurs.
#
#	  OCF parameters are as below:
#		OCF_RESKEY_hostfile
#		
#	where "hostfile" is a file containing the IPs/Workstation names
#	one by line to be sent WinPopups
#
# License:  GNU General Public License (GPL)

WINPOPUPFILE=${HA_VARRUN}/WinPopup
#######################################################################
# Initialization:

# Source function library.
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs

# Parameter defaults

OCF_RESKEY_hostfile_default="hosts"

: ${OCF_RESKEY_hostfile=${OCF_RESKEY_hostfile_default}}

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

us=`uname -n`

usage() {
  echo "Usage: $0 {start|stop|status|monitor|validate-all|meta-data}"
}

meta_data() {
	cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="WinPopup" version="1.0">
<version>1.0</version>

<longdesc lang="en">
Resource script for WinPopup. It sends WinPopups message to a 
sysadmin's workstation whenever a takeover occurs.
</longdesc>
<shortdesc lang="en">Sends an SMB notification message to selected hosts</shortdesc>

<parameters>
<parameter name="hostfile" unique="0" required="1">
<longdesc lang="en">
The file containing the hosts to send WinPopup messages to.
</longdesc>
<shortdesc lang="en">Host file</shortdesc>
<content type="string" default="${OCF_RESKEY_hostfile_default}" />
</parameter>
</parameters>

<actions>
<action name="start" timeout="30s" />
<action name="stop" timeout="30s" />
<action name="status" depth="0" timeout="10s" interval="10s" />
<action name="monitor" depth="0" timeout="10s" interval="10s" />
<action name="validate-all" timeout="5s" />
<action name="meta-data" timeout="5s" />
</actions>
</resource-agent>
END
}

sendWinPopup() {
  # if workstation file exists and is not zero
  if [ -s "$hostfile" ] ; then
    subject=$1
    shift

    for i in `cat $hostfile` ; do
      echo "$subject $*" | smbclient -M $i >/dev/null 2>&1
    done
  else
    ocf_log err "Workstation file $hostfile missing or corrupt!"
    return $OCF_ERR_ARGS
  fi

  return $?
}

SubjectLine() {
  case $1 in
    ??*)	echo $1;;
    *)		echo "Resource Group";;
  esac
}


WinPopupStart() {

	Subject="`SubjectLine $2` Takeover in progress on $us"
 
	if sendWinPopup "$Subject" $1; then
		touch $WINPOPUPFILE
		return $?
	else
		return $?
	fi

}

WinPopupStop () {
	Subject="`SubjectLine $2` Reestablishing original master connection in progress on $us"

	if sendWinPopup "$Subject" $1; then
		rm -f $WINPOPUPFILE
		return $?
	else
		return $?
	fi

}

WinPopupStatus () {
	ocf_log warn "Don't stat/monitor me! WinPopup is a pseudo resource agent, so the status reported may be incorrect"
	if [ -f $WINPOPUPFILE ]; then
		echo "running"
		return $OCF_SUCCESS
	else
		echo "stopped"
		return $OCF_NOT_RUNNING
	fi
}

# A not reliable IP address checking function, which only picks up those _obvious_ violations...
#
# It accepts IPv4 address in dotted quad notation, for example "192.168.1.1"
#
# 100% confidence whenever it reports "negative", 
# but may get false "positive" answer. 
# 
CheckIP() {
  ip="$1"
  case $ip in
    *[!0-9.]*) #got invalid char
	false;;
    .*|*.) #begin or end by ".", which is invalid
	false;;
    *..*) #consecutive ".", which is invalid
	false;;
    *.*.*.*.*) #four decimal dots, which is too many
	false;;
    *.*.*.*) #exactly three decimal dots, candidate, evaluate each field
	local IFS=.
	set -- $ip
	if
	    ( [ $1 -le 254 ] && [ $2 -le 254 ] && [ $3 -le 254 ] && [ $4 -le 254 ] )
	then
	    true
	fi	   
	;;
    *) #less than three decimal dots
	false;;
  esac
  return $? # This return is unnecessary, this comment too :)
}

WinPopupValidateAll () {
  if [ ! -s "$hostfile" ] ; then
    ocf_log err "Workstation file $hostfile missing or corrupt!"
    return $OCF_ERR_ARGS
  fi

  # What kind of hostfiles are valid? 
  # We stick to the definition that, a hostfile is valid if and only if it 
  # contains at least one valid host to send WinPopup message to.

#  have_valid_host=no
  for host in `cat $hostfile`; do
	nmblookup $host 2>&1 | grep -q "failed to find name $host\>"
	if [ $? -ne 0 ]; then
#	  have_valid_host=yes
	  return $OCF_SUCCESS
	fi
	# $host is not a netbios name, an IP address maybe?
	if CheckIP "$host"; then
#	  have_valid_host=yes
	  return $OCF_SUCCESS
	fi
  done

  ocf_log err "Workstation file $hostfile contains no valid host!"
  return $OCF_ERR_CONFIGURED
}

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

# See how the environment virables were set.
hostfile=${OCF_RESKEY_hostfile}

case "$1" in
  meta-data)
	meta_data
	exit $OCF_SUCCESS
	;;
  start)
	WinPopupStart
	;;
  stop)
	WinPopupStop
	;;

	#	Not quite sure what to do with this one...
  status|monitor)
	WinPopupStatus
	;;
  validate-all)
	WinPopupValidateAll
	;;
  usage)
	usage
	exit $OCF_SUCCESS
	;;
  *)
        usage
	exit $OCF_ERR_UNIMPLEMENTED
	;;
esac

exit $?
