#!/bin/bash

# bash provides Brace Substitution (${word%pattern}) and declare -F

# The distro and kernel version is needed to select appropriate IPMI modules
# or install actions so hpmgmtbase gets the "distro sniffer".  It leaves
# its finding in its conf file for other apps to grab.

: ${DEBUG:=}
[ "$DEBUG" ] && H="${RPMACTION}->helper" || H=""
set -u

export PATH="/sbin:/usr/sbin:/bin:/usr/bin:$PATH"

# Catch-22: something has to come first.  The package installs with a dummy
# config file; the installer must call this helper script to rewrite it.

CONF=/etc/opt/hp/hpmgmtbase.conf	# Gotta be hardcoded
if [ ! -e $CONF ]; then	
    echo "$CONF is missing and that's BAD; you should reinstall $PRODACRO" >&2
    exit 99
fi
. $CONF

# There's a known problem in rpm on RHEL3 (at least) where it leaves fd 18
# open.  This annoys programs like ssh, which wait for the last close on
# its fd, because the stray fd gets inherited by any daemons that we spawn,
# so let's close those pesky extra file descriptors right now:

exec 3>&- 4>&- 5>&- 6>&- 7>&- 8>&- 9>&- 10>&- 11>&- 12>&- 13>&- 14>&- 15>&- \
     16>&- 17>&- 18>&- 19>&- 20>&- 21>&- 22>&- 23>&- 24>&- 25>&- 26>&- 27>&-

# If making changes to this distro awareness algorithm,
# please also check DISTROS/create.spec to see if 
# the changes you make propogate.

# first check for Debian, 'cause the algorithm below depends on RPM which
#   is not a standard part of a Debian distro.

DISTROVENDOR=""
DISTROVERSION=""
DISTROEXTRA=""

# used to load modules for specific platforms in functions.acpi/ipmi
PLATFORM=`uname -p`
if [ "$PLATFORM" = "athlon" ]; then
  PLATFORM=i686
fi

VENDORFILE=/etc/debian_version
if [ -f $VENDORFILE ]; then
  DISTROVENDOR="Debian"
  DISTROVERSION=`cat $VENDORFILE`
fi

# If ! Debian
if [ -z "$DISTROVENDOR" ]; then
  # Find the distro info by RPM name
  F=/etc/redflag-release
  [ ! -f $F ] && F=/etc/redhat-release
  [ ! -f $F ] && F=/etc/SuSE-release
  [ ! -f $F ] && echo "Can't find xxxx-release file" >&2 && exit 99

  # match RPM name to determine DISTROVERSION, DISTROVENDOR, and DISTROEXTRA

  R=`rpm -qf $F`
  [ -z "$R" ] && echo "Can't get RPM for $F" >&2 && exit 99
  number=$(expr $R : '[^0-9]*\([0-9]*\)')	# Get the first digit
  case $R in
    redhat-release-[3-5]*)			# 2010
	DISTROVENDOR="RedHat"
	if [ "$number" -ge 5 ]; then
	    number=`lsb_release -r | awk '{print $2}'`
	    DISTROEXTRA=`uname -r | awk '/.*xen/ { print "xen" }'`
	    if [ -z "$DISTROEXTRA" ]; then
	    	DISTROEXTRA=`uname -r | awk '/*PAE*/ { print "PAE" }'`
	    fi
	else
	    number="$number.x"			# don't care in 2010
	fi
	DISTROVERSION="RHEL-$number"
	;;
    redhat-release-[0-9]*)			# RHEL3, RHEL4, and beyond!
	DISTROVENDOR="RedHat"
	DISTROVERSION="EL-$number.0"
	;;
    redhat-release-server-[0-9]*)                      # RHEL6
        DISTROVENDOR="RedHat"
        DISTROVERSION="EL-$number.0"
        ;;
    sles-release-1[0-2]*)			# 2014 SUSE12
        DISTROVENDOR="SuSE"
	MAJOR=`awk '/VERSION/ {print $3}' $F`
	MINOR=`awk '/PATCHLEVEL/ {print $3}' $F`
	DISTROVERSION="SLES-$MAJOR.$MINOR"
	;;
  esac
fi

# Well?

[ `id -u` -ne 0 ] && echo "Must be root" >&2 && exit 4
mkdir -p $LOGDIR
touch $LOGFILE

if [ -z "$DISTROVENDOR" ]; then
  echo "Unable to determine distribution vendor"
  echo "Unable to determine distribution vendor" >> $LOGFILE
  exit 1
fi
if [ -z "$DISTROVERSION" ]; then
  echo "Cannot determine version of $DISTROVENDOR"
  echo "Cannot determine version of $DISTROVENDOR" >> $LOGFILE
  exit 2
fi

# Rewrite the config file.

TMP=/tmp/helper$$
trap "rm -f $TMP; exit 0" 0 1 2 3 15

NEW="DISTROVENDOR=\"$DISTROVENDOR\""
sed -e "s/^DISTROVENDOR=.*/$NEW/" <$CONF >$TMP
[ ! -s $TMP ] && echo VENDOR rewrite failed && exit 1
mv $TMP $CONF

NEW="DISTROVERSION=\"$DISTROVERSION\""
sed -e "s/^DISTROVERSION=.*/$NEW/" <$CONF >$TMP
[ ! -s $TMP ] && echo VERSION rewrite failed && exit 1
mv $TMP $CONF

NEW="DISTROEXTRA=\"$DISTROEXTRA\""
sed -e "s/^DISTROEXTRA=.*/$NEW/" <$CONF >$TMP
[ ! -s $TMP ] && echo EXTRA rewrite failed && exit 1
mv $TMP $CONF

LOCKDIR=/var/lock/hp	# Can't use / in sed script
[ "$DISTROVENDOR" = Debian ] && LOCKDIR=/var/lock/subsys/hp
NEW="LOCKDIR=\"$LOCKDIR\""
sed -e "s,^LOCKDIR=.*,$NEW," <$CONF >$TMP
[ ! -s $TMP ] && echo LOCKDIR rewrite failed && exit 1
mv $TMP $CONF

trap - 0 1 2 3 15
. $CONF

# These are permanent droppings: once I start the convention of having
# them around, there's no way to tell who else might be using them.
mkdir -p $LOCKDIR
mkdir -p $LOGDIR

# Get the startup scripts, observing the order dependency

cd $HPETC/rc.d
SCRIPTS=`ls S*`	# asterisk will pick up the absolute path
RSCRIPTS=`ls -r S*`

# Source any other function support scripts: functions only so no ordering.
# Do this before the etc_initd_ routines below :-)

for i in `ls functions\.*`; do . $i; done

POSTINSTALLS=`declare -F | awk '/_postinstall$/ {print $3}'`
CONFIGURES=`declare -F | awk '/_configure$/ {print $3}'`
UNCONFIGURES=`declare -F | awk '/_unconfigure$/ {print $3}'`
PREUNINSTALLS=`declare -F | awk '/_preuninstall$/ {print $3}'`

function action() {
	# echo action \"$1\" \"$2\" \"$3\"

	# Idiot checks from design phase, just leave them in
	MSG="$0::$FUNCNAME() bad arg "
	[ $# -ne 3 ] && echo $MSG count && exit 99

	# $1 Either "$SCRIPTS" or "$RSCRIPTS"; must be passed in quotes
	[ "$1" != "$SCRIPTS" -a "$1" != "$RSCRIPTS" ] && echo $MSG 1 && exit 99

	# $2 One of the approved keywords from /etc/init.d/PRODACRO, it
	#    usually is the $1 passed into this script from there
	[ -z "$2" ] &&  echo $MSG 2 && exit 99
	ACTION=$2

	# $3 Either "silent" or explicit empty string.  There are 4 args here
	[ -n "$3" -a "$3" != "silent" ] && echo "$MSG 3 ($3)" && exit 99
	SILENT=
	[ -n "$3" ] && SILENT=">/dev/null 2>&1"

	RETVAL=0
	for SCRIPT in $1; do
	    cd $HPETC/rc.d	# Paranoia never killed anyone
	    if [ -x $SCRIPT ]; then
		eval "./$SCRIPT $ACTION $SILENT"
		R=$?
		[ $R -gt 0 ] && RETVAL=$R
		[ "$DEBUG" ] && echo "$H action($SCRIPT $ACTION) returned $R"
	    fi
	done
	return $RETVAL
}

RUNDAEMON=$HPETC/rundaemon.$DISTROVENDOR
[ ! -x $RUNDAEMON ] && echo "No rundaemon for $DISTROVENDOR" >&2 && exit 99
export RUNDAEMON
export PNAME="helper"

RETHELPER=0	# Avoid name collision in sub-scripts
H="$H($1)"
export H
case "$1" in

	# These cases support deployment and are typically only called by 
	# a packager (ie, the scriptlets in RPM-based distributions)

	postinstall)
		for xyzzy in $POSTINSTALLS; do
			[ "$DEBUG" ] && echo "$H eval($xyzzy)"
			eval "$xyzzy"
			RET=$?
			[ "$DEBUG" ] && echo "$H $xyzzy returned $RET"
			[ $RET -ne 0 ] && RETHELPER=1	# but keep going
		done
		if [ $RETHELPER -eq 0 ]; then
			#if [ $number -eq 7 ]; then
			if ( ([ "$DISTROVENDOR"x = "RedHat"x ] && [ $number -eq 7 ]) ||
			     ([ "$DISTROVENDOR"x = "SuSE"x ] &&  [ $number -eq 12 ]) ); then
				# On Rhel7 Suse12
				systemctl enable --quiet $PRODACRO.service
			else
				# On SuSE, chkconfig prints out status--get rid of that.
				# chkconfig --add $PRODACRO >/dev/null
				# Avoiding Service network is missed in the runlevels 4 to use service HP message
				chkconfig --level 35 $PRODACRO on
			fi
		fi
		hpbmc SDRcache_destroy 2>/dev/null	# paranoid
		;;

	configure|reconfigure)
		action "$RSCRIPTS" stop silent # and don't even announce it
		for xyzzy in $CONFIGURES; do 
			[ "$DEBUG" ] && echo "$H eval ($xyzzy)"
			eval "$xyzzy $1"
			RET=$?
			[ "$DEBUG" ] && echo "$H $xyzzy returned $RET"
			[ $RET -ne 0 ] && RETHELPER=1	# but keep going
		done
		;;

	silentstart)
		action "$SCRIPTS" start silent 
		RETHELPER=$?
		;;

	silentstop)
		action "$RSCRIPTS" stop silent 
		RETHELPER=$?
		;;

	unconfigure)
		echo "Stopping $PRODNAME, please wait..."
		hpbmc SDRcache_destroy 2>/dev/null
		action "$RSCRIPTS" stop silent
		RETHELPER=$?
		for xyzzy in $UNCONFIGURES; do
			[ "$DEBUG" ] && echo "$H eval($xyzzy)"
			eval "$xyzzy $1"
			RET=$?
			[ "$DEBUG" ] && echo "$H $xyzzy returned $RET"
			[ $RET -ne 0 ] && RETHELPER=1
		done
		#if [ $number -eq 7 ]; then
		if ( ([ "$DISTROVENDOR"x = "RedHat"x ] && [ $number -eq 7 ]) ||
		     ([ "$DISTROVENDOR"x = "SuSE"x ] &&  [ $number -eq 12 ]) ); then
			# On Rhel7
			systemctl disable --quiet $PRODACRO.service
                else
			# On SuSE, chkconfig prints out status--get rid of that.
			chkconfig --del $PRODACRO >/dev/null
		fi
		;;

	preuninstall)
		hpipmid -r	# Remove MQ
		for xyzzy in $PREUNINSTALLS; do eval "$xyzzy"; done
		;;

	# Cases called both from spec file and /etc/init.d

	start)
		action "$SCRIPTS" "$1" ""	# never silent
		RETHELPER=$?
		;;

	status)
		action "$SCRIPTS" "$1" ""	# never silent
		RETHELPER=$?
		;;

	stop)
		action "$RSCRIPTS" "$1" ""	# never silent
		RETHELPER=$?
		;;

	*)	# Restart is unrolled in /etc/init.d/PRODACRO
		echo "Unknown command \"$1\""
		RETHELPER=99
		;;
esac

exit $RETHELPER
