#!/bin/sh
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License, Version 1.0 only
# (the "License").  You may not use this file except in compliance
# with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END

# Note: This is only a template!
#
# Fill all parts of the script marked with '???' with your code
#

# 
# Note: In Solaris prior to Solaris 10 the start/stop scripts are 
#       always executed by /bin/sh!
#
# start/stop script for ${APPLICATION_NAME}
#
# Defined return codes:
#

# parameter start, restart
RC_DAEMON_STARTED=0
RC_DAEMON_NOT_STARTED=1

# parameter stop, restart
RC_DAEMON_STOPPED=0
RC_DAEMON_NOT_STOPPED=1

# parameter stop
RC_DAEMON_KILLED=0
RC_DAEMON_NOT_KILLED=1

# parameter status, start, stop, kill
RC_DAEMON_IS_RUNNING=101
RC_DAEMON_IS_NOT_RUNNING=100

RC_DAEMON_PRINT_USAGE=10

# RCs in case of an error
#
RC_DAEMON_APPLICATION_DETECTION_ERROR=50
RC_DAEMON_NO_REFRESH_METHOD_DEFINED=51

# RCs of the signal handler
#
RC_DAEMON_SCRIPT_QUIT_SIGNAL_RECEIVED=251
RC_DAEMON_SCRIPT_ABORTED_BY_THE_USER=252
RC_DAEMON_SCRIPT_ABORTED_BY_EXTERNAL_SIGNAL=253
RC_DAEMON_UNKNOWN_SIGNAL_CATCHED=254

#
# History: 
#   22.08.2006 /bs initial release
#   20.09.2006 /bs added more features
#
# Author
#   Bernd.Schemmer@gmx.de
#

# ---------------------------------------
# constants

  __TRUE=0
  __FALSE=1

# ---------------------------------------
#
# set DAEMON_USER to the user that should execute this script
#   ("" = do not check the user executing this script)
#
  DAEMON_USER=""

# set APPLICATION_NAME to the name of the application to start/stop with this script
#
  APPLICATION_NAME="dsmc"

# binary to start the daemon 
#
  DAEMON_BINARY="/opt/tivoli/tsm/client/ba/bin/dsmc"

# command to start the daemon
#
  DAEMON_START_CMD="${DAEMON_BINARY}"

# command to refresh the daemon
# (""  =  use kill -HUP ; use "none" if no refresh method is defined)
#
  DAEMON_REFRESH_CMD="none"

# command to stop the daemon
# (""  =  kill the process using kill -TERM)
#
  DAEMON_STOP_CMD=""

# command to kill the daemon
# (""  =  kill the process using kill -KILL)
#
  DAEMON_KILL_CMD=""

# startup time for the daemon in seconds
#
  DAEMON_STARTUP_WAITTIME="5"

# shutdown time for the daemon in seconds
#
  DAEMON_SHUTDOWN_WAITTIME="5"

# kill wait time
#
  DAEMON_KILL_WAITTIME="5"


# Logfile for the daemon
# ("" - do not use a logfile for the daemon
  DAEMON_LOGFILE="/var/log/${APPLICATION_NAME}.log"

# Note: Use either DAEMON_PID_FILE or DAEMON_PROCESS_NAME!
#

# process name
# 
  DAEMON_PROCESS_NAME=""

# PID file for the daemon
#
  DAEMON_PID_FILE="/var/tmp/${APPLICATION_NAME}.pid"

# Is the PID file created by the daemon itself?
#
  DAEMON_PID_FILE_CREATED_BY_DAEMON="${__FALSE}"

# ---------------------------------------

  __THISSCRIPT=` basename $0` 

# ---------------------------------------
# check the user executing this script

  if [ -x "/usr/ucb/whoami" ] ; then
    [ "${__VERBOSE}"x -eq "${__TRUE}"x ] && echo "${__THISSCRIPT} - INFO: Using /usr/ucb/whoami to get the current user ..."
    __THISUSER="`/usr/ucb/whoami`"
  else
    [ "${__VERBOSE}"x -eq "${__TRUE}"x ] && echo  "${__THISSCRIPT} - INFO: /usr/ucb/whoami not found -u sing \$LOGNAME to get the current user"
    __THISUSER="${LOGNAME}"
  fi
  
  if [ "${DAEMON_USER}"x != ""x ] ; then
    if [ "${DAEMON_USER}"x != "${__THISUSER}"x ] ; then
      [ "${__VERBOSE}"x -eq "${__TRUE}"x ] && echo  "${__THISSCRIPT} - INFO: Restarting the script as user \"${DAEMON_USER}\" ..."
      su - "${DAEMON_USER}" -c "cd ` pwd` ; $0 $*"
      exit $?
    fi
  fi

# ---------------------------------------
#
# check for -v and save the parameter
#
#
# set __VERBOSE to __TRUE for debugging (use LogInfo for debugging messages)
#
  [ "${__VERBOSE}"x = ""x ] && __VERBOSE=${__FALSE}

  if [ "$1"x = "-v"x ] ; then
    __VERBOSE=${__TRUE}
    shift
  fi
      
  __ACTION="$1"
  [ $# -ne 0 ] && shift

  if [ "$1"x = "-v"x ] ; then
    __VERBOSE=${__TRUE}
    shift
  fi

  __ACTION_PARAMETER="$*"

# ---------------------------------------
#
# predefined variables
#

# return code of the script
  __mainRC=0

  __EXIT_VIA_DIE=${__FALSE}


#
#    change the name of the logfile to your need; use __LOGFILE=""
#    to suppress using a logfile at all
#
#  __LOGFILE="/var/tmp/${__THISSCRIPT}.log"
  __LOGFILE=""
  
  __HOSTNAME=` uname -n `

# operating system (e.g. "SunOS")
#
  __OS=` uname -s `

# __OS_VERSION - Operating system version (e.g 5.8)
#
  __OS_VERSION=` uname -r `

# __RUNLEVEL - current runlevel
#
  __RUNLEVEL=`who -r | tr -s " " | cut -f8 -d " " `

#
# set __USER_BREAK_ALLOWED to __FALSE to suppress user aborts with CTRL-C
#
  __USER_BREAK_ALLOWED=${__TRUE}

# ---------------------------------------
#
# define variables here
#
# Note: Do not use leading underscores (__) for variable names -
#      these names are reserved for internal variables
#
 
# ---------------------------------------
#
# sub routines
#

# ---------------------------------------
#
# Usage: automatically called in the sub routine die
#
cleanup() {

  LogInfo "Doing house keeping ..."

  case ${__ACTION} in
    "start" ) :  ;;
    "stop" ) : ;;
    "kill" ) : ;;
    "refresh" ) : ;;
    "restart" ) : ;;
    "status" ) : ;;
  esac
    
  if [ "${PROCESS_RUNNING}" = "${__FALSE}" ] ; then
    if [ "${DAEMON_PID_FILE}"x != ""x ] ; then
      if [ -f  "${DAEMON_PID_FILE}" ] ; then
        rm "${DAEMON_PID_FILE}" 2>/dev/null
      fi
    fi
  fi
}

# ---------------------------------------
# 
# Usage: LogMsg [message]
#
LogMsg() {
  LogMsg_THISMSG="$*"
  echo "${__THISSCRIPT} - ${LogMsg_THISMSG}"
  [ "${__LOGFILE}"x != ""x ] && echo "${__THISSCRIPT} - ${LogMsg_THISMSG}" >>"${__LOGFILE}"
}

# ---------------------------------------
# 
# Usage: LogInfo [message]
#
# Note: LogInfo only prints messages if __VERBOSE is true
#
LogInfo() {
  [ "${__VERBOSE}"x -eq "${__TRUE}"x ] && LogMsg "INFO: $*"
}

# ---------------------------------------
#
# Usage: LogWarning [message]
#
LogWarning() {
  LogWarning_THISMSG="${__THISSCRIPT} - WARNING: $*!"
  echo "${LogWarning_THISMSG}" >&2
  [ "${__LOGFILE}"x != ""x ] && echo "${LogWarning_THISMSG}" >>${__LOGFILE}
}


# ---------------------------------------
#
# Usage: LogError [message]
#
# Note: Error messages are written to STDERR
#
LogError() {
  LogError_THISMSG="${__THISSCRIPT} - ERROR: $*!"
  echo "${LogError_THISMSG}" >&2
  [ "${__LOGFILE}"x != ""x ] && echo "${LogError_THISMSG}" >>${__LOGFILE}
}


# ---------------------------------------
#
# Usage: die [returncode] [message]
# 
die() {  
  die_THISRC=$1
  [ $# -ne 0 ] && shift
  die_THISMSG="$*"
  __EXIT_VIA_DIE=${__TRUE}

  cleanup

  if [ $# -ne 0 ] ; then
    if [ "${die_THISRC}"x = "0"x ] ; then
      LogMsg "${die_THISMSG}"
    else
      LogError "${die_THISMSG}"
    fi
  fi

  exit ${die_THISRC}
}


# ---------------------------------------
# GENERAL_SIGNAL_HANDLER
#
# general trap handler 
#
# usage: called automatically (parameter $1 is the signal number)
#
# returns: -
#
GENERAL_SIGNAL_HANDLER() {

  case $1 in 

    1 )
        LogInfo "HUP signal received."
        ;;

    2 )
        if [ ${__USER_BREAK_ALLOWED} -eq ${__TRUE} ] ; then
          die ${RC_DAEMON_SCRIPT_ABORTED_BY_THE_USER} "Script aborted by the user via signal BREAK (CTRL-C)" 
        else
          LogInfo "Break signal (CTRL-C) received and ignored (Break is disabled)."
        fi
        ;;

    3 )
        die ${RC_DAEMON_SCRIPT_QUIT_SIGNAL_RECEIVED} "QUIT signal received" 
        ;;

   15 )
        die ${RC_DAEMON_SCRIPT_ABORTED_BY_EXTERNAL_SIGNAL} "Script aborted by the external signal TERM" 
        ;;

   "exit" | 0 )
        if [ "${__EXIT_VIA_DIE}"x != "${__TRUE}"x ] ; then
          LogWarning "You should use the function \"die\" to end the program"
        fi    

        ;;
       
    * ) die ${RC_DAEMON_UNKNOWN_SIGNAL_CATCHED} "Unknown signal catched: $1 "
        ;;

  esac
}



# ---------------------------------------
# sample subroutine
#
mysubroutine() {
  mysubroutine_THISRC=0

  return ${mysubroutine_THISRC}
}


# ---------------------------------------
# wait n seconds
#
wait_n_seconds() {
  if [ "$1"x  != ""x ] ; then
    LogInfo "Waiting $1 seconds ..."
    sleep $1
  fi    
}


# ---------------------------------------
# check_daemon
#
check_daemon() {

  PROCESS_RUNNING=${__FALSE}

  if [ "${DAEMON_PID_FILE}"x != ""x ] ; then

# use a PID file 
    LogInfo "Using the PID file \"${DAEMON_PID_FILE}\" to check if the daemon is running ..."
    [ -f "${DAEMON_PID_FILE}" ]  && PROCESS_PID=` cat "${DAEMON_PID_FILE}" `
    [ "${PROCESS_PID}"x != ""x ] && PROCESS_PID=`/usr/bin/ps -p ${PROCESS_PID} -o pid=`
    [ "${PROCESS_PID}"x != ""x ] && PROCESS_RUNNING=${__TRUE} || PROCESS_RUNNING=${__FALSE} 
  elif [ "${PROCESS_NAME}"x != ""x ] ; then

# use a process name 
    if [ -x "/usr/ucb/ps" ] ; then
      LogInfo "Using /usr/ucb/ps to check if the daemon is running ..."
      PROCESS_PID=` /usr/ucb/ps -wwwax | grep "${PROCESS_NAME}" | grep -v grep | awk '{print $1}' `
    else      
      LogInfo "Using /usr/bin/ps to check if the daemon is running ..."
      PROCESS_PID=` /usr/bin/ps -ef | grep "${PROCESS_NAME}" | grep -v grep | awk '{print $2}' `
    fi      
    [ "${PROCESS_PID}"x != ""x ] && PROCESS_RUNNING=${__TRUE} || PROCESS_RUNNING=${__FALSE}
  else

# neither pidfile nor process name was found
    die ${RC_DAEMON_APPLICATION_DETECTION_ERROR} "Can not detect if the application is running"
  fi

  return ${PROCESS_RUNNING}
}


# ---------------------------------------
# start_daemon
#
start_daemon() {

  if [ "${DAEMON_LOGFILE}"x = ""x ] ; then
    DAEMON_LOGFILE="/dev/null"
  fi

  LogInfo "Starting the daemon using the command \"${DAEMON_START_CMD}\" ..."
  ${DAEMON_START_CMD}  >>"${DAEMON_LOGFILE}" 2>&1 &

  if [ "${DAEMON_PID_FILE}"x != ""x -a "${DAEMON_PID_FILE_CREATED_BY_DAEMON}"x = "${__FALSE}"x ] ; then
    LogInfo "Creating the PID file \"${DAEMON_PID_FILE}\" ..."
    echo $! >"${DAEMON_PID_FILE}" 
  fi

  return 0
}


# ---------------------------------------
# stop_daemon
#
stop_daemon() {

  if [ "${DAEMON_STOP_CMD}"x != ""x ] ; then
    LogInfo "Stopping the daemon using the command \"${DAEMON_STOP_CMD}\" ..."
    ${DAEMON_STOP_CMD}
  else
    LogInfo "Stopping the daemon using the command \"kill -TERM ${PROCESS_PID}\" ..."
    kill -TERM ${PROCESS_PID}
  fi

  return 0
}


# ---------------------------------------
# kill_daemon
#
kill_daemon() {

  if [ "${DAEMON_KILL_CMD}"x != ""x ] ; then
    LogInfo "Stopping the daemon using the command \"${DAEMON_KILL_CMD}\" ..."
    ${DAEMON_KILL_CMD}
  else
    LogInfo "Stopping the daemon using the command \"kill -KILL ${PROCESS_PID}\" ..."
    kill -KILL ${PROCESS_PID}
  fi

  return 0
}


# ---------------------------------------
# refresh_daemon
#
refresh_daemon() {

  if [ "${DAEMON_REFRESH_CMD}"x = "none"x ] ; then
    die ${RC_DAEMON_NO_REFRESH_METHOD_DEFINED} "No refresh method defined for this daemon"
  elif [ "${DAEMON_REFRESH_CMD}"x != ""x ] ; then
    LogInfo "Refreshing the daemon using the command \"${DAEMON_REFRESH_CMD}\" ..."
    ${DAEMON_REFRESH_CMD}
  else
    LogInfo "Refreshing the daemon using the command \"kill -HUP ${PROCESS_PID}\" ..."
    kill -HUP ${PROCESS_PID}
  fi

  return 0
}

# ---------------------------------------
#
# main code
#

# install trap handler
  trap "GENERAL_SIGNAL_HANDLER  1"  1
  trap "GENERAL_SIGNAL_HANDLER  2"  2
  trap "GENERAL_SIGNAL_HANDLER  3"  3
  trap "GENERAL_SIGNAL_HANDLER 15" 15
  trap "GENERAL_SIGNAL_HANDLER exit" 0

# check the logfile of the start/stop script
#
  if [ "${__LOGFILE}"x != ""x ] ; then
    touch ${__LOGFILE}
    [ $? -ne 0 ] && __LOGFILE=""
  fi

  check_daemon
    
  LogInfo "Action is \"${__ACTION}\""
  LogInfo "Actionparameter are \"${__ACTION_PARAMETER}\""
  
  case ${__ACTION} in

    start ) 
      if [ ${PROCESS_RUNNING} = ${__TRUE} ] ; then
        LogMsg "${APPLICATION_NAME} already running; the PID is ${PROCESS_PID}"
        __mainRC=${RC_DAEMON_IS_RUNNING}
      else
        LogMsg "Starting ${APPLICATION_NAME} ..." 
        start_daemon

        wait_n_seconds ${DAEMON_STARTUP_WAITTIME}

        check_daemon && __mainRC=${RC_DAEMON_STARTED} || __mainRC=${RC_DAEMON_NOT_STARTED}
      fi
      ;;

    status )
      if [ ${PROCESS_RUNNING} = ${__TRUE} ] ; then
        LogMsg "${APPLICATION_NAME} is running; the PID is ${PROCESS_PID}"
        __mainRC=${RC_DAEMON_IS_RUNNING}
      else
        LogMsg "${APPLICATION_NAME} is not running"
        __mainRC=${RC_DAEMON_IS_NOT_RUNNING}
      fi
      ;;

    stop )
      if [ ${PROCESS_RUNNING} != ${__TRUE} ] ; then
        LogMsg "${APPLICATION_NAME} is not running"
        __mainRC=${RC_DAEMON_IS_NOT_RUNNING}
      else
        LogMsg "Stopping ${APPLICATION_NAME} ..." 
        stop_daemon

        wait_n_seconds ${DAEMON_SHUTDOWN_WAITTIME}

        check_daemon && __mainRC=${RC_DAEMON_NOT_STOPPED}  || __mainRC=${RC_DAEMON_STOPPED} 
      fi
      ;;

    kill )
      if [ ${PROCESS_RUNNING} != ${__TRUE} ] ; then
        LogMsg "${APPLICATION_NAME} is not running"
        __mainRC=${RC_DAEMON_IS_NOT_RUNNING}
      else
        LogMsg "Killing ${APPLICATION_NAME} ..." 
        kill_daemon

        wait_n_seconds ${DAEMON_KILL_WAITTIME}

	check_daemon && __mainRC=${RC_DAEMON_NOT_KILLED} || __mainRC=${RC_DAEMON_KILLED}
      fi
      ;;

    "restart" )
      if [ ${PROCESS_RUNNING} = ${__TRUE} ] ; then
        LogMsg "Stopping ${APPLICATION_NAME} ..." 
        stop_daemon 

        wait_n_seconds ${DAEMON_SHUTDOWN_WAITTIME}

        check_daemon && die ${RC_DAEMON_NOT_STOPPED} "Can not stop the daemon"
      fi
      
      if [ ${PROCESS_RUNNING} != ${__TRUE} ] ; then
        LogMsg "Starting ${APPLICATION_NAME} ..." 
        start_daemon

        wait_n_seconds ${DAEMON_STARTUP_WAITTIME}

        check_daemon && __mainRC=${RC_DAEMON_STARTED} || __mainRC=${RC_DAEMON_NOT_STARTED}
      fi
      ;;

    "refresh" )
      if [ ${PROCESS_RUNNING} != ${__TRUE} ] ; then
        LogMsg "${APPLICATION_NAME} is not running"
        __mainRC=${RC_DAEMON_IS_NOT_RUNNING}
      else
        LogMsg "Refreshing ${APPLICATION_NAME} ..." 
        ${DAEMON_REFRESH_CMD}
        __mainRC=$?
      fi
      ;;
      
    * ) 
      LogMsg "Usage: ${__THISSCRIPT} [-v] [start|stop|restart|status|kill|refresh]"
      __mainRC=${RC_DAEMON_PRINT_USAGE}
      ;;

  esac

# ---------------------------------------
 
  die ${__mainRC}

# ---------------------------------------
