#!/bin/sh
#
# newrelic-daemon <summary>
#
# chkconfig:   2345 90 10
# description: Starts and stops the New Relic Proxy Daemon.
# processname: newrelic-daemon
# config:      /etc/newrelic/newrelic.cfg

LANG=C
NAME=newrelic-daemon
DESC="New Relic Daemon"

# Source function library.
. /etc/init.d/functions

ulimit -n 2048 > /dev/null 2>&1

id=`id -u 2> /dev/null`
if [ "$id" != "0" ]; then
  if [ -z "${NR_SILENT}" -a -z "${SILENT}" ]; then
    echo "INFO: $0 should normally be run by root"
  fi
fi

nrdaemon=
cfgfile=
nrmode="$1"

#
# This is a hack to get around the fact that RPM attempts to be "friendly"
# and moves aside the daemon config file during an upgrade. The last thing
# done during the post-removal step in the old 2.x scripts is a condrestart
# so we trap that here and clean up after RPM's unwelcome "help".
#
if [ "${nrmode}" = "condrestart" ]; then
  if [ -f /etc/newrelic/newrelic.cfg.rpmsave ]; then
    if [ ! -f /etc/newrelic/newrelic.cfg ]; then
      mv -f /etc/newrelic/newrelic.cfg.rpmsave /etc/newrelic/newrelic.cfg > /dev/null 2>&1
      nrmode="start"
    fi
  fi
fi

# Source defaults
if [ -f /etc/sysconfig/${NAME} ]; then
  . /etc/sysconfig/${NAME}
fi

if [ -z "${nrdaemon}" ]; then
  if [ -x /usr/bin/newrelic-daemon ]; then
    nrdaemon=/usr/bin/newrelic-daemon
  elif [ -x /usr/local/bin/newrelic-daemon ]; then
    nrdaemon=/usr/local/bin/newrelic-daemon
  fi
fi

if [ -z "${cfgfile}" ]; then
  if [ -f /etc/newrelic/newrelic.cfg ]; then
    cfgfile=/etc/newrelic/newrelic.cfg
  elif [ -f /usr/local/etc/newrelic/newrelic.cfg ]; then
    cfgfile=/usr/local/etc/newrelic/newrelic.cfg
  fi

  if [ -z "${cfgfile}" ]; then
    cfgfile=`echo "${nrdaemon}" | sed -e 's/newrelic-daemon/newrelic.cfg/' 2> /dev/null`
  fi

  [ -f "${cfgfile}" ] || cfgfile=
fi

pidfile=
if [ -n "${cfgfile}" -a -f "${cfgfile}" ]; then
  pidfile=`sed -n -e 's/^[ 	]*pidfile[ 	]*=[ 	]*//p' -e 's/[ 	]*$//' "${cfgfile}" 2> /dev/null`
fi

pidarg=
if [ -z "${pidfile}" ]; then
  if [ -d /var/run ]; then
    pidfile=/var/run/newrelic-daemon.pid
  elif [ -d /var/pid ]; then
    pidfile=/var/pid/newrelic-daemon.pid
  fi
  if [ -n "${pidfile}" ]; then
    pidarg=" --pidfile ${pidfile}"
  fi
fi

cfgarg=
if [ -n "${cfgfile}" -a -f "${cfgfile}" ]; then
  cfgarg=" -c ${cfgfile}"
fi

nrdaemonopts="${cfgarg}${pidarg}"

#
# It's just cosmetic but let's figure how to suppress newlines in echo
#
if echo ' \c' | grep 'c' > /dev/null 2>&1; then
  en='-n'
  ec=''
else
  en=''
  ec='\c'
fi

#
# Time to wait for the daemon to die, in seconds. If you set this too low the
# daemon may not have enough time to flush pending data with the New Relic
# servers, and the restart command may not work.
#
DODTIME=15

# Find running daemon processes.
pgrep_newrelic_daemon()
{
  # Criteria:
  #
  #   1. Command name contains newrelic-daemon
  #   2. Command is not this script
  #   3. Parent process is init
  #
  # Note this will not find daemons running in foreground mode and not started by init.
  ps -eo pid,ppid,args | grep '/newrelic-daemon ' | sed -e '/grep/d' -e '/init.d/d' -e '/rc.d/d' | awk '{ if ($2 == 1) {print $1}}'
}

# Check if a given process pid's cmdline matches a given name
running_pid()
{
  pid=$1
  name=$2
  [ -z "$pid" ] && return 1
  [ ! -d /proc/$pid ] && return 1
  [ ! -f /proc/$pid/cmdline ] && return 1
  cmd=`cat /proc/$pid/cmdline 2> /dev/null | tr "\000" "\n"|head -n 1 |cut -d : -f 1`
  # Is this the expected child?
  [ "$cmd" = "$name" ] || return 1
  return 0
}

# Check if the process is running looking at /proc
running()
{
  if [ -n "${pidfile}" -a -f "${pidfile}" ]; then
    pid=`cat "${pidfile}" 2> /dev/null`
    running_pid "${pid}" "${nrdaemon}" || return 1
    return 0
  else
    maybepid=`pgrep_newrelic_daemon`
    if [ -z "${maybepid}" ]; then
      return 1
    else
      return 0
    fi
  fi
}

start() {
  if running ; then
    if [ -z "${NR_SILENT}" -a -z "${SILENT}" ]; then
      echo "$NAME already running"
    fi
    return 0
  fi

  if [ ! -f "${cfgfile}" ]; then
    if [ -z "${NR_SILENT}" -a -z "${SILENT}" ]; then
      cat <<EOF
INFO: newrelic.cfg not found - daemon must be launched by the agent.
      If you want to start the daemon via this script then please copy the
      file /etc/newrelic/newrelic.cfg.template to /etc/newrelic/newrelic.cfg,
      edit it to taste, and then re-run this script. For more information
      please refer to https://newrelic.com/docs/php/new-relic-for-php.
EOF
    fi
    exit 0
  fi

  if [ -z "${nrdaemon}" ]; then
    if [ -z "${NR_SILENT}" -a -z "${SILENT}" ]; then
      echo "ERROR: newrelic-daemon not found"
    fi
    exit 6
  fi

  if [ ! -x "${nrdaemon}" ]; then
    if [ -z "${NR_SILENT}" -a -z "${SILENT}" ]; then
      echo "ERROR: ${nrdaemon} not executable"
    fi
    exit 6
  fi

  if [ -z "${NR_SILENT}" -a -z "${SILENT}" ]; then
    echo ${en} "Starting $NAME: ${ec}"
  fi

  RETVAL=0
  "${nrdaemon}" ${nrdaemonopts} || RETVAL=1
  sleep 1
  if [ "x${RETVAL}" = "x0" ]; then
    if running ; then
      RETVAL=0
    else
      RETVAL=1
    fi
  fi

  if running ; then
    if [ -z "${NR_SILENT}" -a -z "${SILENT}" ]; then
      success
      echo
    fi
    return 0
  else
    if [ -z "${NR_SILENT}" -a -z "${SILENT}" ]; then
      failure
      echo
    fi
    return 1
  fi
}

stop() {
  if running ; then
    if [ -z "${NR_SILENT}" -a -z "${SILENT}" ]; then
      echo ${en} "Stopping $DESC ($NAME) ... ${ec}"
    fi

    # First try the pid file.
    if [ -n "${pidfile}" -a -f "${pidfile}" ]; then
      pid=`cat "${pidfile}" 2>/dev/null`
      if running_pid "${pid}" "${nrdaemon}"; then
        kill -15 $pid > /dev/null 2>&1
      fi
    fi
    sleep 1

    for pid in `pgrep_newrelic_daemon`; do
      kill -15 $pid > /dev/null 2>&1
    done
    sleep 1

    tleft=0
    while test $tleft -lt $DODTIME; do
      if running ; then
        sleep 1
        tleft=`expr $tleft + 1`
      else
        break
      fi
    done

    for pid in `pgrep_newrelic_daemon`; do
      kill -9 $pid > /dev/null 2>&1
    done

    if running ; then
      if [ -z "${NR_SILENT}" -a -z "${SILENT}" ]; then
        failure
        echo
      fi
      return 1
    else
      if [ -z "${NR_SILENT}" -a -z "${SILENT}" ]; then
        success
        echo
      fi
      return 0
    fi
  else
    if [ -z "${NR_SILENT}" -a -z "${SILENT}" ]; then
      echo "$DESC ($NAME) not running"
    fi
  fi

  return 0
}

restart() {
  stop || return 1
  sleep 1
  start || return 1
  return 0
}

reload() {
  restart
}

force_reload() {
  restart
}

rh_status() {
  if running ; then
    if [ -z "${NR_SILENT}" -a -z "${SILENT}" ]; then
      echo "$NAME is running..."
    fi
    return 0
  else
    if [ -z "${NR_SILENT}" -a -z "${SILENT}" ]; then
      echo "$NAME is stopped..."
    fi
    return 3
  fi
}

rh_status_q() {
  rh_status >/dev/null 2>&1
}

case "${nrmode}" in
  start)
    rh_status_q && exit 0
    start
    RETVAL=$?
    ;;
  stop)
    rh_status_q || exit 0
    stop
    RETVAL=$?
    ;;
  restart)
    restart
    RETVAL=$?
    ;;
  reload)
    rh_status_q || exit 7
    reload
    RETVAL=$?
    ;;
  force-reload)
    force_reload
    RETVAL=$?
    ;;
  status)
    rh_status
    RETVAL=$?
    ;;
  condrestart|try-restart)
    rh_status_q || exit 0
    restart
    RETVAL=$?
    ;;
  *)
    if [ -z "${NR_SILENT}" -a -z "${SILENT}" ]; then
      echo "Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" >&2
    fi
    exit 2
    ;;
esac
exit $RETVAL
