#!/bin/bash

### BEGIN INIT INFO
# Provides:          db2inst
# Required-Start:    $syslog $local_fs $network $db2das
# Should-Start:      $time
# Required-Stop:     $syslog $local_fs $network
# Should-Stop:       $time
# Default-Start:     3 5
# Default-Stop:      0 1 2 6
# Short-Description: The DB2 Instance
# Description:       The DB2 Instance
### END INIT INFO

# chkconfig: 35 98 02
# description: DB2 Instance

# Place this file at /etc/init.d/db2inst (or
# /etc/rc.d/init.d/db2inst) and make symlinks to
#   /etc/rc.d/rc0.d/K02db2inst
#   /etc/rc.d/rc1.d/K02db2inst
#   /etc/rc.d/rc2.d/K02db2inst
#   /etc/rc.d/rc3.d/S98db2inst
#   /etc/rc.d/rc4.d/S98db2inst
#   /etc/rc.d/rc5.d/S98db2inst
# Or check out the chkconfig program, if you have it.
#
## EDIT FROM HERE, if you absolutely must. Rather use /etc/sysconfig/db2inst, though.

# Installation prefix
DB2DIR=/opt/IBM/db2/V8.1

# Do we autoctl the instance?
DBI_AUTO[0]=no
DBI_AUTO[1]=no
DBI_AUTO[2]=no

# DB2 Instance Owner Username
DBI_USER[0]=db2inst1
DBI_USER[1]=db2inst2
DBI_USER[2]=db2inst3

# Renice it, if necessary
DBI_NICE[0]=0
DBI_NICE[1]=0
DBI_NICE[2]=0

## STOP EDITING HERE

# The name of this script
MYNAME="db2inst"

# Source the sysconfig file, if present
if [ -f /etc/sysconfig/db2inst ]; then
    . /etc/sysconfig/db2inst
else
    echo "${MYNAME}: Please create /etc/sysconfig/db2inst"
fi

# Return values acc. to LSB for all commands but status:
# 0 - success
# 1 - generic or unspecified error
# 2 - invalid or excess argument(s)
# 3 - unimplemented feature (e.g. "reload")
# 4 - insufficient privilege
# 5 - program is not installed
# 6 - program is not configured
# 7 - program is not running
# 
# Note that starting an already running service, stopping
# or restarting a not-running service as well as the restart
# with force-reload (in case signalling is not supported) are
# considered a success.

# Check for echo -n vs echo \c
if echo '\c' | grep -s c >/dev/null 2>&1 ; then
    ECHO_N="echo -n"
    ECHO_C=""
else
    ECHO_N="echo"
    ECHO_C='\c'
fi

# get_variables
#
# Initializes environment variables to those of the currently
# processed instance (DBI_START, DBI_STOP, DBI_CMD, DBI_NICE and DBI_LOG)
#
# Arguments: the consecutive number of the configured instance
# Returns:
# 0 - success
# 4 - insufficient privilege
# 5 - program is not installed
# 6 - program is not configured
get_variables() {
    SEQ=$1

    # Obtain instance owner's homedir
    local DBI_HOME=`eval echo ~${DBI_USER[${SEQ}]}`

    # Missing user?
    if [ "${DBI_HOME}" = "~${DBI_USER[${SEQ}]}" ]; then
	return 6
    fi

    # See if all commands exist
    DBI_START=${DBI_HOME}/sqllib/adm/db2start
    DBI_STOP=${DBI_HOME}/sqllib/adm/db2stop
    DBI_CMD=${DBI_HOME}/sqllib/bin/db2
    DBI_NICE=${DBI_NICE[${SEQ}]}
    DBI_LOG=${DBI_HOME}/sqllib/db2dump/startup.log

    # Check if the log exists and create & chown it if not yet so
    if [ ! -e "${DBI_LOG}" ]; then
	if [ ! -d "`dirname ${DBI_LOG}`" ]; then
	    return 5
	elif [ ! -w "`dirname ${DBI_LOG}`" ]; then
	    return 4
	fi
	touch ${DBI_LOG}

	# This is not a fatal error, actually. It may prevent us from
	# actually being able to write to the log, but we check that
	# elsewhere.
	chown ${DBI_USER[${SEQ}]} ${DBI_LOG} >/dev/null 2>&1
    fi

    return 0
}

# start_instance
#
# Will start an instance
#
# Arguments: the consecutive number of the configured instance
# Returns:
# 0 - success
# 4 - insufficient privilege
# 5 - program is not installed
# 6 - program is not configured
start_instance() {
    get_variables $1
    case $? in
	4)
	    echo "insufficient privileges to manipulate ${DBI_LOG}!"
	    return 4
	;;
	5)
	    echo "log directory `dirname ${DBI_LOG}` does not exist!"
	    return 5
	;;
	6)
	    echo "user ${DBI_USER[$1]} does not exist!"
	    return 6
	;;
    esac

    if [ ! -x "${DBI_START}" ]; then
	echo "cannot execute ${DBI_START}!"
	return 5
    fi

    if [ ! -w "${DBI_LOG}" ]; then
	echo "log file not writable: ${DBI_LOG}!"
	return 4
    fi

    # TODO:
    #  - check if the instance is already running prior to starting it up
    #  - after starting this instance up, check if it indeed is running
    #  - redirect all output to ${DBI_LOG} and only output startup status
    #  - implement renicing of the process tree leader
    #  - fix return values
    /bin/su - ${DBI_USER[$1]} -c ${DBI_START}

    return 0
}

# stop_instance
#
# Will stop an instance
#
# Arguments: the consecutive number of the configured instance
# Returns:
# 0 - success
# 4 - insufficient privilege
# 5 - program is not installed
# 6 - program is not configured
stop_instance() {
    get_variables $1
    case $? in
	4)
	    echo "insufficient privileges to create ${DBI_LOG}!"
	    return 4
	;;
	5)
	    echo "log directory `dirname ${DBI_LOG}` does not exist!"
	    return 5
	;;
	6)
	    echo "user ${DBI_USER[$1]} does not exist!"
	    return 6
	;;
    esac

    if [ ! -x "${DBI_CMD}" ]; then
	echo "cannot execute ${DBI_CMD}!"
	return 5
    fi

    if [ ! -x "${DBI_STOP}" ]; then
	echo "cannot execute ${DBI_STOP}!"
	return 5
    fi

    if [ ! -w "${DBI_LOG}" ]; then
	echo "log file not writable: ${DBI_LOG}!"
	return 6
    fi

    # TODO:
    #  - check if the instance is running prior to shutting it down
    #  - after shutting this instance down, check if it indeed has quit
    #  - redirect all output to ${DBI_LOG} and only output startup status
    #  - fix return values
    /bin/su - ${DBI_USER[$1]} -c "${DBI_CMD} force application all; ${DBI_STOP}"

    return 0
}

# Parse command line parameters.
case $1 in
  start|stop)
	CTR=0
	MAX=256

	if [ "$1" = "start" ]; then
	    ACTION="Starting"
	    SUB=start_instance
	else
	    ACTION="Stopping"
	    SUB=stop_instance
	fi

	# Were there additional parameters (instance number?)
	if [ -n "$2" ]; then
	    CTR=$2
	    MAX=$((CTR + 1))
	    if [ -z "${DBI_USER[${CTR}]}" ]; then
		echo "${MYNAME}: DB2 instance number ${CTR} not configured."
		exit 6
	    fi
	    ${ECHO_N} "${MYNAME}: ${ACTION} DB2 Instance \"${DBI_USER[${CTR}]}\": "${ECHO_C}
	else
	    echo "${MYNAME}: ${ACTION} DB2 Instances:"
	fi

	# There's a little trick here: if there was an instance number specified
	# as the second argument, we set MAX to this number and quit immediately
	# after processing the one instance desired; otherwise we proceed until
	# we run out of instances or reach 256 (hopefully, there will be less
	# then 256 instances configured on a single machine! :))
	while [ -n "${DBI_USER[${CTR}]}" -a ${CTR} -lt ${MAX} ]; do
	    # Present it if we're in a sequence
	    if [ -z "$2" ]; then
		${ECHO_N} "${MYNAME}:  - ${DBI_USER[${CTR}]}: "${ECHO_C}
	    fi

	    # Is this instance configured to autoctl?
	    # (another little bit of trickery - autoctl is honored only if instance
	    # is processed as part of a sequence involving all configured instances,
	    # otherwise we ignore it)
	    if [ "${DBI_AUTO[${CTR}]}" = "no" -a $((CTR + 1)) -ne ${MAX} ]; then
		echo "autoctl off."
		CTR=$((CTR + 1))
		continue
	    fi

	    ${SUB} ${CTR}

	    CTR=$((CTR + 1))
	done
	;;
  restart)
	$0 stop $2
	$0 start $2
	;;
  status)
	CTR=0
	MAX=256

	# Were there additional parameters (instance number?)
	if [ -n "$2" ]; then
	    CTR=$2
	    MAX=$((CTR + 1))
	    if [ -z "${DBI_USER[${CTR}]}" ]; then
		echo "${MYNAME}: DB2 instance number ${CTR} not configured."
		exit 6
	    fi
	    ${ECHO_N} "${MYNAME}: Checking DB2 Instance \"${DBI_USER[${CTR}]}\": "${ECHO_C}
	else
	    echo "${MYNAME}: Checking DB2 Instances:"
	fi

	# There's a little trick here: if there was an instance number specified
	# as the second argument, we set MAX to this number and quit immediately
	# after processing the one instance desired; otherwise we proceed until
	# we run out of instances or reach 256 (hopefully, there will be less
	# then 256 instances configured on a single machine! :))
	while [ -n "${DBI_USER[${CTR}]}" -a ${CTR} -lt ${MAX} ]; do
	    # Present it if we're in a sequence
	    if [ $((CTR + 1)) -ne ${MAX} ]; then
		${ECHO_N} "${MYNAME}:  - ${DBI_USER[${CTR}]}: "${ECHO_C}
	    fi

	    if /sbin/pidof db2sysc >/dev/null 2>&1; then
		DBI_PID="`ps xau | grep db2sysc | \
				    grep -v grep | \
				    grep ${DBI_USER[${CTR}]} | \
				    head -1 | tr -s ' ' | cut -f 2 -d ' '`"
		if [ -n "${DBI_PID}" ]; then
		    echo "running (PID ${DBI_PID})."
		else
		    echo "missing."
		fi
	    else
		echo "missing."
	    fi

	    CTR=$((CTR + 1))
	done
	;;
  *)
	# Print help
	echo "Usage: $0 {start|stop|restart|status} [<instance-number>]" 1>&2
	exit 1
	;;
esac

exit 0
