# -*-Shell-script-*-
# Author:       Alan Robertson
# Support:      linux-ha-dev@lists.tummy.com
# License:      GNU Lesser General Public License (LGPL)
#
#	Set these variables if they're not already set...
#

prefix=/usr
exec_prefix=/usr
: ${HA_DIR:=/etc/ha.d}
: ${HA_RCDIR:=$HA_DIR/rc.d}
: ${HA_CONFDIR=$HA_DIR/conf}
: ${HA_CF:=$HA_DIR/ha.cf}
: ${HA_VARLIB:=/var/lib/heartbeat}
: ${HA_RSCTMP:=/var/run/heartbeat/rsctmp}
: ${HA_FIFO:=/var/lib/heartbeat/fifo}
: ${HA_BIN:=/usr/lib64/heartbeat}
: ${HA_NOARCHBIN:=/usr/share/heartbeat}
: ${HA_DATEFMT:="%Y/%m/%d_%T "}
: ${HA_DEBUGLOG:=/dev/null}
: ${HA_RESOURCEDIR:=$HA_DIR/resource.d}
: ${HA_DOCDIR:=/usr/share/doc/heartbeat}
: ${__SCRIPT_NAME:=`basename $0`}
: ${HA_LOGTAG:=$__SCRIPT_NAME[$$]}
: ${HA_VARRUN:=/var/run/}
: ${HA_VARLOCK:=/var/lock/subsys/}
: ${HA_SBIN_DIR:=/usr/sbin}

export HA_DIR HA_RCDIR HA_FIFO HA_BIN 
export HA_DEBUGLOG HA_LOGFILE HA_LOGFACILITY
export HA_DATEFMT HA_RESOURCEDIR HA_DOCDIR

TESTPROG=/usr/bin/test
PATH=$HA_BIN:${HA_SBIN_DIR}:/usr/share/heartbeat:$PATH
PATH=`echo $PATH | sed -e 's%::%%' -e 's%:\.:%:%' -e 's%^:%%' -e 's%^\.:%%'`
export PATH

#	A suitable echo command
Echo() {
  echo "$@"
}

hadate() {
  date "+${HA_DATEFMT}"
}

ha_log() {
	if [ "x${HA_LOGD}" = "xyes" ] ; then 
		ha_logger -t "${HA_LOGTAG}" "$@"
		if [ "$?" -eq "0" ] ; then
			return 0
		fi
	fi

	if
	  [ -n "$HA_LOGFACILITY" ]
        then
	  : logging through syslog
	  # loglevel is unknown, use 'notice' for now
          loglevel=notice
          case "${*}" in
            *ERROR*)		loglevel=err;;
            *WARN*)		loglevel=warning;;
            *INFO*|info)	loglevel=info;;
	  esac
	  logger -t "$HA_LOGTAG" -p ${HA_LOGFACILITY}.${loglevel} "${*}"
        fi	
        if
	  [ -n "$HA_LOGFILE" ]
	then
	  : appending to $HA_LOGFILE
	  Echo "$HA_LOGTAG:	"`hadate`"${*}" >> $HA_LOGFILE
	else
	  Echo `hadate`"${*}" >&2
	fi
        if
          [ -n "$HA_DEBUGLOG" ]
        then
          : appending to $HA_DEBUGLOG
          Echo "$HA_LOGTAG:	"`hadate`"${*}" >> $HA_DEBUGLOG
        fi
}

ha_debug() {

        if [ "x${HA_LOGD}" = "xyes" ] ; then  
		ha_logger -t "${HA_LOGTAG}" -D "ha-debug" "$@"
                if [ "$?" -eq "0" ] ; then
                        return 0
                fi
        fi

	if
	  [ -n "$HA_LOGFACILITY" ]
	then
	  : logging through syslog
	  logger -t "$HA_LOGTAG" -p "${HA_LOGFACILITY}.debug" "${*}"
	fi
        if
	  [ -n "$HA_DEBUGLOG" ]
	then
	  : appending to $HA_DEBUGLOG
	  Echo "$HA_LOGTAG:	"`hadate`"${*}" >> $HA_DEBUGLOG
	else
	  Echo "$HA_LOGTAG:	`hadate`${*}:	${HA_LOGFACILITY}" >&2
	fi
}

# copy stdin (text) to FIFO, with surrounding ">>>" and "<<<" marker lines.
# no args.; no result
# Notes:
#	o Using "cat -" rather than "cat" simply for clarity.
#	o The trailing "| cat -" tries to hold things together as a single
#	  write (which is probably preferable behaviour in this context).
ha_clustermsg() {
	(echo ">>>"; cat -; echo "<<<")	| cat - >> $HA_FIFO
}

ha_parameter() {
  VALUE=`sed -e 's%[ 	][ 	]*% %' -e 's%^ %%' -e 's%#.*%%'   $HA_CF |
  grep -i "^$1 " | sed 's%[^ ]* %%'`
  if
    [ "X$VALUE" = X ]
  then
    
    case $1 in
      keepalive)	VALUE=2;;
      deadtime)
			ka=`ha_parameter keepalive`
			VALUE=`expr $ka '*' 2 '+' 1`;;
    esac
  fi
  Echo $VALUE
}

BSD_Status() {
  local base=${1##*/}
  local pid

  ret_status=`/bin/ps -ao pid,command | grep $base | sed 's/ .*//'`

  if 
    [ "$ret_status" != "" ]
  then
    echo "${base} is running..."
  return 0
  fi

  if 
    [ -f $HA_VARRUN/${base}.pid ] 
  then
    echo "${base} dead but pid file exists"
    return 1
  fi

  if 
    [ -f /var/run/${base}.pid ] 
  then
    echo "${base} dead but pid file exists"
    return 1
  fi

  if 
    [ -f $HA_VARLOCK/var/lock/subsys/${base}.pid ] 
  then
    echo "${base} dead but lock file exists"
    return 2
  fi

  if 
    [ -f /var/spool/lock/${base} ] 
  then
    echo "${base} dead but lock file exists"
    return 2
  fi
}
#

#
# pseudo_resource status tracking function...
#
# This allows pseudo resources to give correct status information.  As we add
# resource monitoring, and better resource tracking in general, this will
# become essential.
#
# These scripts work because ${HA_RSCTMP} is cleaned out every time
# heartbeat is started.
#
# We create "resource-string" tracking files under ${HA_RSCTMP} in a
# very simple way:
#
#	Existence of "${HA_RSCTMP}/resource-string" means that we consider
#	the resource named by "resource-string" to be running.
#
# Note that "resource-string" needs to be unique.  Using the resource type
# plus the resource instance arguments to make up the resource string
# is probably sufficient...
#
# usage: ha_pseudo_resource resource-string op [tracking_file]
# 	where op is {start|stop|monitor|status|restart|reload|print}
#	print is a special op which just prints the tracking file location
#	user can override our choice of the tracking file location by
#		specifying it as the third arg
#	Note that all operations are silent...
#
ha_pseudo_resource()
{
  ha_resource_tracking_file="${3:-${HA_RSCTMP}/$1}"
  case $2 in
    start|restart|reload)  touch "$ha_resource_tracking_file";;
    stop) rm -f "$ha_resource_tracking_file";;
    status|monitor)
           if
             [ -f "$ha_resource_tracking_file" ]
           then
             return 0
           else
             case $2 in
               status)	return 3;;
               *)	return 7;;
             esac
           fi;;
    print)  echo "$ha_resource_tracking_file";;
    *)	return 3;;
  esac
}

# usage: dirname DIR
dirname()
{
	local a
	local b

	[ $# = 1 ] || return 1
	a="$1"
	while [ 1 ]; do
		b="${a%/}"
		[ "$a" = "$b" ] && break
		a="$b"
	done
	b=${a%/*}
	[ -z "$b" -o "$a" = "$b"  ] && b="."

	echo "$b"
	return 0
}

# usage: maketempdir
maketempdir()
{
	local i=1
	local tmp

	# The loop allows for the cases where
	# A process has multiple tempfiles or dirs or;
	# A previous process with the same PID that had tempfiles or
	# directories did not exit cleanly
	while [ $i -gt 0 ]; do
		tmp="/tmp/lha-dir-$$-$i"
		if (umask 077 && mkdir "$tmp" 2>/dev/null); then
			echo "$tmp"
			return 0
		fi
		i=$((i+1))
	done

	echo "Could not create tempoary directory to store logs" >& 2
	return 1
}

# usage: rmtempdir TMPDIR
rmtempdir()
{
	[ $# = 1 ] || return 1
	if [ -e "$1" ]; then
		rmdir "$1" || return 1
	fi
	return 0
}

# usage: maketempfile [-d]
maketempfile()
{
	local dir="no"
	local name

	if [ $# = 1 -a "$1" = "-d" ]; then
		dir="yes"
	elif [ $# != 0 ]; then
		return 1
	fi

	name=$(maketempdir) || return $?

	if [ "$dir" = "yes" ]; then
		echo "$name"
		return 0
	fi

	name="$name/tmpfile"

	if ! touch "$name"; then
		rmtempdir
		return 1
	fi

	echo "$name"
	return 0
}

# usage: rmtempfile TMPFILE
rmtempfile ()
{
	[ $# = 1 ] || return 1
	if [ -e "$1" ]; then
		rm "$1" || return 1
	fi
	rmtempdir $(dirname "$1") || return 1
	return 0
}

# The 'ping' command takes highly OS-dependent arguments, so this
# function creates a suitable argument list for the host OS's 'ping'.
# We use a subset of its functionality:
# 1. single packet
# 2. reasonable timeout (say 1 second)
#
# arguments:
#	$1: IP address to ping
# result string:
#	arguments for ping command
#
# If more flexibility is needed, they could be specified in the environment
# to this function, to adjust the resulting 'ping' arguments.
#	David Lee <t.d.lee@durham.ac.uk> May 2007
pingargs() {
	_baseip=$1
	_timeout=1	# seconds
	_pktcount=1
	_systype="`uname -s`"
	case $_systype in
		Linux)
			# Default is perpetual ping: need "-c $_pktcount".
			# -c count -t timetolive -q(uiet) -n(umeric) -W timeout
			_pingargs="-c $_pktcount -q -n $_baseip"
			;;
		SunOS)
			# Default is immediate (or timeout) return.
			_pingargs="$_baseip $_timeout"
			;;
		*)
			_pingargs="-c $_pktcount $_baseip"
			;;
	esac

	echo "$_pingargs"
}

