#-------------------------------------------------------------------------------
# Library for handling xrootd daemons on RHEL
# Author: Lukasz Janyst <ljanyst@cern.ch> (09.03.2011)
#-------------------------------------------------------------------------------

. /etc/rc.d/init.d/functions

#-------------------------------------------------------------------------------
# Add the user accounts if needed and set up the directory ownership
#-------------------------------------------------------------------------------
function setupInstallation()
{
  XROOTD_USER=$1
  XROOTD_GROUP=$2
  getent group $XROOTD_GROUP >/dev/null || groupadd -r $XROOTD_GROUP
  getent passwd $XROOTD_USER >/dev/null || \
    useradd -r -g $XROOTD_GROUP -c "XRootD runtime user" \
    -s /sbin/nologin -d /var/spool/xrootd $XROOTD_USER

  chown $XROOTD_USER:$XROOTD_GROUP -R /var/spool/xrootd
  chown $XROOTD_USER:$XROOTD_GROUP -R /var/log/xrootd
}

#-------------------------------------------------------------------------------
# Check if a file has the right permissions
#-------------------------------------------------------------------------------
function checkFile()
{
  FILE=$1
  XROOTD_USER=$2
  XROOTD_GROUP=$3

  if test x"`stat -c %U $FILE`" != x$XROOTD_USER; then
    echo "$FILE has wrong user ownership: \"`stat -c %U $FILE`\" instead of \"$XROOTD_USER\""
    return 1
  fi
}

#-------------------------------------------------------------------------------
# Check a directory and it's permissions
#-------------------------------------------------------------------------------
function checkDirectory()
{
  DIRECTORY=$1
  XROOTD_USER=$2
  XROOTD_GROUP=$3

  if test ! -d $DIRECTORY; then
    echo "Directory: $DIRECTORY does not exist"
    return 1
  fi

  for i in `find $DIRECTORY`; do
    checkFile $i $XROOTD_USER $XROOTD_GROUP
    if test $? -ne 0; then
      return 1
    fi
  done
  return 0
}

#-------------------------------------------------------------------------------
# Check if the installation is in a sane state
#-------------------------------------------------------------------------------
function checkSanity()
{
  XROOTD_USER=$1
  XROOTD_GROUP=$2

  #-----------------------------------------------------------------------------
  # Check if the user account exist
  #-----------------------------------------------------------------------------
  getent passwd $XROOTD_USER >/dev/null
  if test $? -ne 0; then
    echo "User account for: $XROOTD_USER doesn't exist"
    return 1
  fi

  getent group $XROOTD_GROUP >/dev/null
  if test $? -ne 0; then
    echo "Group account for: $XROOTD_GROUP doesn't exist"
    return 2
  fi

  #-----------------------------------------------------------------------------
  # We need these directories to be owned by the xroot user for the init
  # scripts to work properly, and we can safely change the ownership if
  # it is wrong.
  #-----------------------------------------------------------------------------
  checkDirectory /var/spool/xrootd $XROOTD_USER $XROOTD_GROUP
  if test $? -ne 0; then
    chown $XROOTD_USER:$XROOTD_GROUP -R /var/spool/xrootd
  fi

  mkdir -p /var/run/xrootd
  chown $XROOTD_USER:$XROOTD_GROUP -R /var/run/xrootd
  checkDirectory /var/run/xrootd $XROOTD_USER $XROOTD_GROUP
  if test $? -ne 0; then
    chown $XROOTD_USER:$XROOTD_GROUP -R /var/run/xrootd
  fi
}

#-------------------------------------------------------------------------------
# Start a daemon
#-------------------------------------------------------------------------------
function startDaemon()
{
  ulimit -n 65536

  DAEMON=$1
  EX=$2
  XROOTD_USER=$3
  XROOTD_GROUP=$4
  INSTANCE=$5
  PIDFILE="/var/run/xrootd/$DAEMON-$INSTANCE.pid"

  # check sanity of the installation
  checkSanity $XROOTD_USER $XROOTD_GROUP
  if test $? -ne 0; then
    echo "Please run: service xrootd setup"
    return 1
  fi

  echo -n "Starting xrootd ($DAEMON, $INSTANCE): "
  shift 5

  # useful for storing coredumps
  cd /var/spool/xrootd
  daemon --user $XROOTD_USER --pidfile $PIDFILE $EX $@ -b -s $PIDFILE -n $INSTANCE
  RETVAL=$?
  echo
  return $RETVAL
}

#-------------------------------------------------------------------------------
# Stop a daemon
#-------------------------------------------------------------------------------
function stopDaemon()
{
  echo -n "Shutting down xrootd ($1, $5): "
  PIDFILE="/var/run/xrootd/$1-$5.pid"
  if [ -e $PIDFILE ]; then
    killproc -p $PIDFILE $1
    RETVAL=$?
    echo
    return $RETVAL
  fi
  echo -n "$1-$5 not running"
  echo
  return 0
}

#-------------------------------------------------------------------------------
# Get the status of a daemon
#-------------------------------------------------------------------------------
function statusOfTheDaemon()
{
  PIDFILE="/var/run/xrootd/$1-$5.pid"
  echo -n "[$5] "
  status -p $PIDFILE $1
  return $RETVAL
}

#-------------------------------------------------------------------------------
# Conditionally restart a daemon
#-------------------------------------------------------------------------------
function condrestartDaemon()
{
  PIDFILE="/var/run/xrootd/$1-$5.pid"
  status -p $PIDFILE $1 > /dev/null
  if test $? -ne 0; then
     return 0
  fi

  stopDaemon $@
  if test $? -ne 0; then
     return 1
  fi

  startDaemon $@
  if test $? -ne 0; then
     return 2
  fi

  return 0
}

#-------------------------------------------------------------------------------
# Do things to daemons
#-------------------------------------------------------------------------------
function handleDaemons()
{
  #-----------------------------------------------------------------------------
  # Check if the user account is specified
  #-----------------------------------------------------------------------------
  if test x"$XROOTD_USER" = x; then
     XROOTD_USER="daemon"
  fi

  if test x"$XROOTD_GROUP" = x; then
     XROOTD_GROUP="daemon"
  fi

  #-----------------------------------------------------------------------------
  # Determine the command to be run
  #-----------------------------------------------------------------------------
  COMMAND=$1;
  shift
  case "$COMMAND" in
    'start')
      CMD_HANDLER=startDaemon
      ;;
    'stop')
      CMD_HANDLER=stopDaemon
      ;;
    'status')
      CMD_HANDLER=statusOfTheDaemon
      ;;
    'condrestart')
      CMD_HANDLER=condrestartDaemon
      ;;
    'setup')
      setupInstallation $XROOTD_USER $XROOTD_GROUP
      return $?
      ;;
    *)
      echo "Unrecognized command: $COMMAND"
      return 1
      ;;
  esac

  #-----------------------------------------------------------------------------
  # Select the daemon to be started
  #-----------------------------------------------------------------------------
  DAEMON=$1;
  shift

  case "$DAEMON" in
    'xrootd' | 'cmsd')
      EXEC=/usr/bin/$DAEMON
      CONFIG_NAME=`echo $DAEMON |  tr '[[:lower:]]' '[[:upper:]]'`
      ;;
    'frm_purged')
      EXEC=/usr/bin/$DAEMON
      CONFIG_NAME=PURD
      ;;
     'frm_xfrd')
      EXEC=/usr/bin/$DAEMON
      CONFIG_NAME=XFRD
      ;;
    *)
      echo "Unrecognized daemon: $DAEMON"
      return 1
      ;;
  esac

  #-----------------------------------------------------------------------------
  # Select the instances to run
  #-----------------------------------------------------------------------------
  if test $# -eq 0; then
    eval INSTANCES=\$${CONFIG_NAME}_INSTANCES
  else
    INSTANCES=$@
  fi

  eval INSTANCES_XROOTD3=\$${CONFIG_NAME}3_INSTANCES

  INSTANCES=`echo $INSTANCES | tr '[[:upper:]]' '[[:lower:]]'`
  INSTANCES_XROOTD3=`echo $INSTANCES_XROOTD3 | tr '[[:upper:]]' '[[:lower:]]'`

  #-----------------------------------------------------------------------------
  # Exec the command on the instances
  #-----------------------------------------------------------------------------
  STATUS=0
  for INSTANCE in $INSTANCES; do
    INSTANCE_UPPER=`echo $INSTANCE | tr '[[:lower:]]' '[[:upper:]]'`
    eval OPTS=\$${CONFIG_NAME}_${INSTANCE_UPPER}_OPTIONS

    #---------------------------------------------------------------------------
    # Check if the instance is xrootd3 or xrootd4, if a xrootd3 binary is
    # installed
    #---------------------------------------------------------------------------
    EXEC_RUN=$EXEC
    if test -x $EXEC-3; then
      for INS in $INSTANCES_XROOTD3; do
        if test $INS = $INSTANCE; then
          EXEC_RUN=$EXEC-3
        fi
      done
    fi

    #---------------------------------------------------------------------------
    # Run the instance
    #---------------------------------------------------------------------------
    if test x"$OPTS" = x; then
      continue
    fi
    $CMD_HANDLER $DAEMON $EXEC_RUN "$XROOTD_USER" "$XROOTD_GROUP" $INSTANCE "$OPTS"
    STATUS=$?
    if test $? -ne 0 && "$CMD_HANDLER" != "statusOfTheDaemon"; then
      STATUS=1
    fi
  done
  return $STATUS
}
