#!/bin/sh
# Startup script for the ipsmd
#
# chkconfig: 2345 90 10
# description: ipsmd is a daemon for Novell iPrint
# processname: ipsmd

# pidfile: /var/opt/novell/run/ipsmd.pid
# config: /etc/opt/novell/iprint/conf/ipsmd.conf

DAEMON="/opt/novell/iprint/bin/ipsmd"
OPTIONS=""
CONF_FILE="/etc/opt/novell/iprint/conf/ipsmd.conf"

if [ -f "/var/opt/novell/run/iprint/ipsmd.pid" ]; then
   # The new location
   PIDFILE="/var/opt/novell/run/iprint/ipsmd.pid"
elif [ -f "/var/opt/novell/run/ipsmd.pid" ]; then
   # The old location
   PIDFILE="/var/opt/novell/run/ipsmd.pid"
else
   # Default to our new location
   PIDFILE="/var/opt/novell/run/iprint/ipsmd.pid"
fi

### BEGIN INIT INFO
# Provides: novell-ipsmd
# Required-Start: $local_fs $network $syslog ndsd namcd
# Required-Stop:
# Default-Start: 2 3  5
# Default-Stop: 1 4 6
# Short-Description: Novell iPrint Printer Manager
# Description: ipsmd Novell iPrint module
### END INIT INFO

#
# LSB and RH have killproc and pidofproc in common

# 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.

if [ -f /lib/lsb/init-functions ]; then
  . /lib/lsb/init-functions
  alias START_DAEMON=start_daemon
  alias STATUS=MyStatus
  alias LOG_SUCCESS=log_success_msg
  alias LOG_FAILURE=log_failure_msg
  alias LOG_WARNING=log_warning_msg
  alias LOG_SKIPPED="rc_status -s"
elif [ -f /etc/init.d/functions ]; then
  . /etc/init.d/functions
  alias START_DAEMON=daemon
  alias STATUS=MyStatus # for now, we report status with MyStatus()
  alias LOG_SUCCESS="success; echo"
  alias LOG_FAILURE="failure; echo"
  alias LOG_WARNING="passed; echo"
  alias LOG_SKIPPED="skipped; echo"
else
  echo "Error: your platform is not supported by $0" > /dev/stderr
  exit 1
fi

GetChildren ()
{
  # Store the parent pid.
  _ppid=$1;
  # A list for the pids found in present call.
  _plist=""
  # Immediate children of 'ppid'.
  _cpid=$(ps --ppid ${_ppid} -o pid=);
  if [ "${_cpid}" != "" ]
  then
    # Iterate over each child and get grand child.
    for _epid in ${_cpid}
    do
      _plist="${_plist} ${_epid}";
      # Grand children.
      _gcpid=$(GetChildren ${_epid})
      _plist="${_plist} ${_gcpid}"
    done
  fi
  echo "${_plist}"
}

GetPidList ()
{
  _pidlist=$1;
  _retList="";
  for _ipid in ${_pidlist}; do
      _retList="${_retList} ${_ipid} $(GetChildren ${_ipid})";
  done
  echo "${_retList}"
}

GetUnqList ()
{
  _dupList=$1;
  _unqList="";
  _unqList=$(echo $(for _upid in ${_dupList};do echo "${_upid}"; done | sort -u));
  echo "${_unqList}"
}

ExecutableExists ()
{
    _exeName=$1;
    _exists=0;
    if pidof ${_exeName} > /dev/null 2>&1; then
        _exists=1;
    fi
    echo "${_exists}"
}

VerifyAndCleanUp ()
{
    RVAL=0;
    # Known set of executables to look for are : ipsmd, iprintgw, ilprsrvrd and acctg.
    # Assumption : name of the executable for accouting module is 'acctg'.
    _exeList="ipsmd iprintgw ilprsrvrd acctg";
    for _exe in ${_exeList}; do
        if [ "$(ExecutableExists ${_exe})" != "0" ]; then
            RVAL=$(CleanUpModule ${_exe});
            if [ "$RVAL" != "0" ]; then
                break;
            fi
        fi
    done
    echo "$RVAL"
}

CleanUpModule ()
{
    _modName=$1;
    RVAL=0;
    PIDLIST="";
    if pidof ${_modName} > /dev/null 2>&1; then
        PIDLIST=$(GetUnqList "$(GetPidList "$(pidof ${_modName})")");
    fi
    for epid in $PIDLIST; do
      kill -9 $epid;
      if [ "$?" != "0" ]; then
        RVAL=1;
        break;
      fi
    done
    echo "$RVAL"
}

MyStatus()
{
  if ! [ -f "$CONF_FILE" ] ; then
     RVAL=6
  elif [ -f $PIDFILE ]; then
    MYPID=`cat $PIDFILE`
    ps -p $MYPID | grep $MYPID > /dev/null 2>&1
    if [ "x$?" = "x0" ]; then
      RVAL=0
    else
      RVAL=3
    fi
  else
    RVAL=3
  fi
  return $RVAL
}


StartIPSMD()
{
  echo -n "Setting NDS environment."
  source /etc/profile.d/ndssource.sh
  
  echo -n "Starting Novell iPrint Manager:"
  if ! [ -f "$CONF_FILE" ] ; then
     echo -e -n " ... service not configured"
     RVAL=6
  else
     $DAEMON $OPTIONS
     RVAL=$?
  fi
  if [ $RVAL -eq 0 ]; then
    LOG_SUCCESS
  elif [ $RVAL -eq 6 ]; then
    LOG_SKIPPED
  else
    LOG_FAILURE
  fi
}

# Procedure to Stop the IPMSD and its child processes.
# - Try for gracefull shutdown, by raising a SIGTERM.
# - After 60 secs, if process still exists then try by raising SIGKILL.
# - Verify if successfully stoped, if not explicitly kill the processes. 
StopIPSMD()
{
  echo -n "Shutting down Novell iPrint Manager"
  if [ -f $PIDFILE ]; then
      PID=`cat $PIDFILE`
      #(kill `cat $PIDFILE` && rm -f $PIDFILE) > /dev/null 2>&1
      kill $PID > /dev/null 2>&1
      RVAL=$?

      # Attempt to shudown gracefully
      ITTR=0
      while ps -C ipsmd > /dev/null 2>&1 ; do
         echo -n "."
         if [ ${ITTR} -gt 59 ]; then
            break
         fi
         ITTR=$(( ${ITTR} + 1 ))
         sleep 1
      done
      # Kill all the processes under the $PID
      if [ ${ITTR} -gt 59 ]; then
         kill -9 -$PID > /dev/null 2>&1
      fi
  fi
  RVAL=$(VerifyAndCleanUp);
  if [ $RVAL -eq 0 ]; then
    LOG_SUCCESS
  else
    LOG_FAILURE
  fi
}

case "$1" in
start)
  StartIPSMD
  ;;
stop)
  StopIPSMD
  ;;
restart)
  StopIPSMD
  sleep 1
  StartIPSMD
  ;;
try-restart|condrestart)
  ## Do a restart only if the service was active before.
  ## Note: try-restart is now part of LSB (as of 1.9).
  ## RH has a similar command named condrestart.
  if test "$1" = "condrestart"; then
    echo "${attn} Use try-restart ${done}(LSB)${attn} rather than condrestart ${warn}(RH)${norm}"
  fi
  $0 status
  if test $? = 0; then
    $0 restart
  else
    rc_reset	# Not running is not a failure.
  fi
  # Remember status and be quiet
  rc_status
  ;;
reload|force-reload)
  # for now, we do the same as restart.
  StopIPSMD
  sleep 1
  StartIPSMD
  ;;
status)
  STATUS
  if [ $RVAL -eq 0 ]; then
     echo "$(basename $DAEMON) is running: $(grep PSMObjectDN /etc/opt/novell/iprint/conf/ipsmd.conf | sed -e "s/PSMObjectDN \(.*$\)/\1/g")"
  elif [ $RVAL -eq 3 ]; then
     echo "$(basename $DAEMON) is not running"
  elif [ $RVAL -eq 6 ]; then
     echo "$(basename $DAEMON) is not configured"
  fi
  ;;
*)
  echo "Usage: $0 start|stop|restart|try-restart|reload|force-reload|status" > /dev/stderr
  RVAL=1
  ;;
esac


exit $RVAL


