#!/bin/sh
#
# (c) Copyright 2000-2010 Stonebranch, Inc.  All rights reserved.
#
# Stonebranch, Inc.
# Universal Broker
# Daemon Initialization Script
# $Id: ubrokerd,v 1.11 2011/09/23 15:11:55 webb Exp $

#
### BEGIN INIT INFO
# Provides:          ubrokerd
# Required-Start:    $syslog $network  
# Should-Start: $time $time
# Required-Stop:     $syslog $network  
# Should-Stop: $time $time
# Default-Start:     3 5
# Default-Stop:      0 1 2 6
# Short-Description: ubroker daemon providing network access 
#   to Universal Products
# Description:       Start ubrokerd to allow Universal Product
#   managers access through the network to Universal Product 
#   servers to run remote jobs as needed.
### END INIT INFO
# 
# Synopsis:
#   ubrokerd {start|stop|status|restart}
#
# Description:
#   Universal Broker manages network requests for all Universal product
#   components.  The broker starts and stops Universal components 
#   as requested.  
#
#   The daemon should be running whenever the system is at a normal 
#   networking run-level (typically 2 or 3).
#
# Return:
#   Exit code 0 if successful, else 1.
#
# Files:
#   /var/opt/universal/ubroker.pid

PATH=/bin:/usr/bin:/etc:/sbin:/usr/sbin:/usr/ucb:/usr/local/bin:/usr/local/sbin:/opt/universal/bin:.
export PATH

UBR_DAEMON=${UBR_DAEMON:=/opt/universal/ubroker/bin/ubrokerd}
UBR_PIDFILE=${UBR_PIDFILE:=/var/opt/universal/ubroker.pid}
UBR_MAX_WAIT=${UBR_MAX_WAIT:=60}
UBR_MINOPENFILES=512

#
# Determine if a PID is for the broker deamon or broker console process.
#
# Synopsis:
#   IsBrokerPid PID
#
# Parameters:
#   PID    The process ID to check.
#
# Returns:
#   Return 0 if it is a broker PID, else return 1.
#
IsBrokerPid()
{
  psline=`${PS_CMD} | grep "^[ 	]*$1[ 	]"`
  if [ "$psline" != "" ]; then
    if echo $psline | grep "ubroker" ; then
      return 0
    else
      return 1  
    fi
  fi

    return 1

} >/dev/null


#
# Determine if a PID is for the listed server.
#
# Synopsis:
#   IsSrvPid PID SRV
#
# Parameters:
#   PID    The process ID to check.
#   SRV    The server to check on (uemsrv or uacsrv)
#
# Returns:
#   Return 0 if it is a server PID, else return 1.
#
IsSrvPid()
{
  pid=$1
  srv=$2

  $PS | grep $i | grep $srv 
  pc=$?
  if [ $pc -ne 0 ]; then
    return 0
  else 
    return 1
  fi
  return 1

} >/dev/null



#
# Get the broker daemon or broker console process ID.
#
# Synopsis:
#   GetBrokerPid
#
# Parameters:
#   None
#
# Returns:
#   Returns 0 if success and writes the PID to stdout.  If the PID
#   is not found, 0 is written to stdout.  Returns 1 if unsuccessful 
#   and writes nothing to stdout.
#
GetBrokerPid()
{
  brokerPid=0

  if [ -f $UBR_PIDFILE ]; then

    # There is a window of opportunity where the file can be
    # removed between the test above and the cat below.  If
    # cat fails, check for the file again.

    pid=`cat $UBR_PIDFILE 2> /dev/null`
    if [ $? -ne 0 -a -f $UBR_PIDFILE ]; then
        # Reproduce error message.
        cat $UBR_PIDFILE > /dev/null
        return 1;
    fi

    if [ "$pid" != "" ]; then
      if IsBrokerPid $pid ; then
        brokerPid=$pid
      fi
    fi
  fi

  echo $brokerPid

  return 0
}




#
# Start the ubroker daemon.
#
# Synopsis:
#   Start
#
# Parameters:
#   None
#
# Returns:
#   Returns 0 if successful else non-zero.
#
Start()
{

  if [ "$ID" != "0" ]; then
    echo "Must be root to START the ubrokerd daemon."
    return 1
  fi

  SD_Rogue uemsrv
  SD_Rogue uacsrv

  if [ -x $UBR_DAEMON ]; then
    pid=`GetBrokerPid` || return 1
    if [ $pid -eq 0 ]; then
      echo "Starting ubrokerd daemon."
      SetUlimit
      rm -f $UBR_PIDFILE
      $UBR_DAEMON || return 1
sleep 3;chmod -R o-w /var/opt/universal
    else 
      echo "Already running as process ID $pid." >&2
      echo "PID file: $UBR_PIDFILE" >&2
      return 1
    fi
  else 
    echo "File $UBR_DAEMON is not executable." >&2
    return 1
  fi

  return 0
}



#
# Stop the ubroker daemon.  Wait upto UBR_MAX_WAIT seconds for it
# to stop.  If not stopped by then, use SIGKILL.
#
# Synopsis:
#   Stop
#
# Parameters:
#   None
#
# Returns:
#   Returns 0 if successful else non-zero.
#
Stop()
{

  if [ "$ID" != "0" ]; then
    echo "Must be root to STOP the ubrokerd daemon."
    return 1
  fi

  pid=`GetBrokerPid` || return 1
  if [ $pid -ne 0 ]; then
    # Try SIGTERM first.
    kill -TERM $pid || return 1
    secs=0
    while [ $secs -lt $UBR_MAX_WAIT ]; do
      secs=`expr $secs + 1`
      pid=`GetBrokerPid` || return 1
      if [ $pid -eq 0 ]; then
        break;
      else 
        sleep 1
      fi
    done

    if [ $secs -eq $UBR_MAX_WAIT ]; then
      # Use SIGKILL now.
      echo "Broker is not responding.  Sending SIGKILL."
      kill -KILL $pid || return 1
    fi
  fi

  rm -f $UBR_PIDFILE
  SD_Rogue uemsrv
  SD_Rogue uacsrv

  return 0
}



#
# Restart the ubroker daemon by stopping it and starting it.
#
# Synopsis:
#   Stop
#
# Parameters:
#   None
#
# Returns:
#   Returns 0 if successful else non-zero.
#
Restart()
{

  if [ "$ID" != "0" ]; then
    echo "Must be root to RESTART the ubrokerd daemon."
    return 1
  fi

  rc=0

  Stop
  rc=$?

  if [ $rc -eq 0 ]; then
    Start;
    rc=$?
  fi

  return $rc
}



#
# Echo the status of the ubroker daemon.
#
# Synopsis:
#   Status
#
# Parameters:
#   None
#
# Returns:
#   Returns 0 and writes the status to stdout.
#
Status()
{
  rc=0

  pid=`GetBrokerPid` || return 1

  if [ $pid -ne 0 ]; then
    echo "running ($pid)"
  else
    echo "stopped"
  fi

  return $rc
}

# 
# Shut down any rogue uemsrv or uacsrv instances
# 
# Parameters:
#   server type 
#     uemsrv or uacsrv
#  SD_Rogue uemsrv
#
# Returns:
#   Returns 0 unless an error in shutting down a server
#   then returns a 1
# 
SD_Rogue()
{
  rc=0
  srv=$1
  
  for i in `$PS | grep $srv | grep -v grep | awk '{ print $1 }'`
  do
    pid=$i
    ppid=`$PS1 | grep $pid | awk '{ print $3 }'`
    if [ $ppid -eq 1 ]; then
      kill -TERM $pid || return 1
      secs=0
      while [ $secs -lt $UBR_MAX_WAIT ]; do
        secs=`expr $secs + 1`
        IsSrvPid $pid $srv
        kpid=$?
        if [ $kpid -eq 0 ]; then
          break
        else
          sleep 1
        fi
      done
      if [ $secs -eq $UBR_MAX_WAIT ]; then
        # Use SIGKILL now.
        echo "$srv is not responding.  Sending SIGKILL."
        kill -KILL $pid || return 1
      fi
    fi
  done
  return 0

}


#
# Checks and set the ulimit for 'nofiles'.
#
# Parameters:
#   None
#
# Returns:
#   Returns 0
#
SetUlimit()
{

  # Not modifying the ulimit for OSF and UNIX_SV systems.
  if [ "$HOST" != "OSF1" ] && [ "$HOST" != "UNIX_SV" ]; then

    HARDLIMIT=`ulimit -H -n`
    HARDLIMIT_LC=`echo $HARDLIMIT | tr '[A-Z]' '[a-z]'`
    SOFTLIMIT=`ulimit -S -n`
    SOFTLIMIT_LC=`echo $SOFTLIMIT | tr '[A-Z]' '[a-z]'`

    if [ "$SOFTLIMIT_LC" != "unlimited" ]; then
      if [ "$SOFTLIMIT" -lt "$UBR_MINOPENFILES" ]; then
        if [ "$HARDLIMIT_LC" = "unlimited" ] || [ "$HARDLIMIT" -ge "$UBR_MINOPENFILES" ]; then
          echo "Ulimit for 'nofiles' is currently: $SOFTLIMIT"
          echo " and is being modified and set to: $UBR_MINOPENFILES"
          ulimit -S -n $UBR_MINOPENFILES
        else
          echo "Ulimit for 'nofiles' is currently: $SOFTLIMIT"
          echo " and is being modified and set to: $HARDLIMIT"
          ulimit -S -n $HARDLIMIT
        fi
      fi
    fi
  fi

  return 0

}



#
# Main routine.
#

rc=0

# Get system information.

SYS=`uname -s`-`uname -r`
HOST=`uname -s`
# Set the ps command for this system.

case "$SYS" in
    Linux-2.0* ) PS_CMD="ps ax" ;;
    * ) PS_CMD="ps -e" ;;
esac

case "$HOST" in
  HP-UX) PS="ps -e";
         PS1="ps -ef";;
  *) PS="ps -eo pid,comm";
         PS1="ps -eo pid,comm,ppid";;
esac

if [ "$HOST" = "SunOS" ]; then
  ID=`id | awk '{ print $1 }' | awk -F"(" '{ print $1 }' | awk -F"=" '{ print $2 }'`
else
  if [ -x /usr/bin/id ]; then
    ID=`/usr/bin/id -u`
  elif [ -x /bin/id ]; then
    ID=`/bin/id -u`
  else
    echo "No id program found on the system cannot verify if user is root"
    echo "/n/n"
    exit 1
  fi
fi


# Process the request.

case $1 in

  'start')
    Start
    rc=$?
    ;;

  'stop')
    Stop
    rc=$?
    ;;

  'status')
    Status
    rc=$?
    ;;

  'restart')
    Restart
    rc=$?
    ;;

  *)
    # Invalid argument or no argument.
    echo "Usage: $0 {start|stop|status|restart}" >&2
    rc=1
    ;;
esac

exit $rc
