#!/bin/sh
#
# init.d script for Torrus
#
# Stanislav Sinyagin <ssinyagin@yahoo.com>

### BEGIN INIT INFO
# Provides:          torrus-collector torrus-monitor
# Required-Start:    $local_fs $remote_fs $syslog $named $network $time
# Required-Stop:     $local_fs $remote_fs $syslog $named $network
# Should-Start:
# Should-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Torrus collectors and monitors
# Description:       Start/stop Torrus collectors and monitors
### END INIT INFO

set -e

if [ -r "/lib/lsb/init-functions" ]; then
  . /lib/lsb/init-functions
else
  echo "E: /lib/lsb/init-functions not found, lsb-base (>= 3.0-6) needed"
  exit 1
fi

# this is from madduck on IRC, 2006-07-06
# There should be a better possibility to give daemon error messages
# and/or to log things
log()
{
  case "$1" in
    [[:digit:]]*) success=$1; shift;;
    *) :;;
  esac
  log_action_begin_msg "$1"; shift
  log_action_end_msg ${success:-0} "$*"
}

sysconfdir=/home/mh/torrus/build-area/torrus-1.0.6/debian/tmp/etc
cmddir=/usr/share/torrus/bin
piddir=/var/run/torrus
sitedir=/etc/torrus
torrus_config_pl=/usr/share/torrus/conf_defaults/torrus-config.pl

. /usr/share/torrus/conf_defaults/initscript.conf
if test -f ${sitedir}/conf/initscript.siteconf; then
  . ${sitedir}/conf/initscript.siteconf
fi

if test "$TORRUS_CHANGE_UID" = yes -a \
        "${LOGNAME:-root}" = root -a \
        "/bin/su" != "no"; then
  user=Debian-torrus
  su="/bin/su ${user} -c"
else
  su="/bin/bash -c"
fi

# Second argument can be the daemon name
if test x"$2" = x; then
  daemons="collector monitor"
  monitor_cmdopts="$TORRUS_MONITOR_DELAY"
else
  daemons=$2
  # Third and fourth arguments may be the tree name and instance
  if test x"$3" != x -a x"$4" != x; then
    eval trees_${daemons}=$3
    eval col_inst_${3}=$4
    read_treenames=no
  fi
fi

if test x"$TORRUS_COLLECTOR_CMDOPTS" != x; then
  collector_cmdopts="$TORRUS_COLLECTOR_CMDOPTS"
fi

if test x${read_treenames} != xno; then

  # Get the names of the trees for each daemon
  for d in ${daemons}; do
    eval trees_${d}=\"`/usr/bin/perl -e 'require "'$torrus_config_pl'";
    while((my $key, $val) = each %Torrus::Global::treeConfig) {
      print "$key " if $val->{run}{'${d}'};
    };'`\"
  done

  # Get the collector instance numbers for each tree
  eval trees=\"\$\{trees_collector\}\"
  for t in ${trees}; do
    eval col_inst_${t}=\"`/usr/bin/perl -e 'require "'$torrus_config_pl'";
    print join(" ",
    (0 .. $Torrus::Global::treeConfig{'${t}'}{run}{collector}-1))'`\"
  done
fi

start_daemons () {
  for d in ${daemons}; do
    eval trees=\"\$\{trees_${d}\}\"
    eval daemon_cmdopts=\"\$\{${d}_cmdopts\}\"

    # /var/run might be a tmpfs, recreate the pid directory if necessary
    if ! test -d ${piddir} ; then
      mkdir -p ${piddir}
      test "${user}" && chown ${user} ${piddir}
    fi

    for t in ${trees}; do
      if test ${d} = collector; then
        eval instances=\"\$\{col_inst_${t}\}\"
	for i in ${instances}; do
          if pidofproc -p "${piddir}/${d}.${t}_${i}.pid" > /dev/null; then
            log_progress_msg "${d} (${i} ${t}) already running"
	  else
            log_progress_msg "${d} (${i} ${t})"
	    # we cannot use start_daemon here since its specification does not
	    # include --chuid, which we need.
            start-stop-daemon --start --quiet \
	                  --chuid "Debian-torrus:Debian-torrus" \
	                  --exec "${cmddir}/${d}" \
	                  --pidfile "${piddir}/${d}.${t}_${i}.pid" \
	                  -- --tree="${t}" --instance=${i} \
			     ${daemon_cmdopts} ${TORRUS_CMDOPTS}
	  fi
	done
      else
        if pidofproc -p "${piddir}/${d}.${t}.pid" > /dev/null; then
          log_progress_msg "${d} (${t}) already running"
        else
          log_progress_msg "${d} (${t} ${daemon_cmdopts})"
          start-stop-daemon --start --quiet \
	                  --chuid "Debian-torrus:Debian-torrus" \
	                  --exec "${cmddir}/${d}" \
	                  --pidfile "${piddir}/${d}.${t}.pid" \
	                  -- --tree="${t}" \
			     ${daemon_cmdopts} ${TORRUS_CMDOPTS}
	fi
      fi
    done
  done
}

daemon_status () {
  RET=3
  for d in ${daemons}; do
    eval trees=\"\$\{trees_${d}\}\"

    for t in ${trees}; do
      eval instances=\"\$\{col_inst_${t}\}\"
      for i in ${instances}; do
        log_action_begin_msg "Checking ${d} (${i} ${t})"
        if pidofproc -p "${piddir}/${d}.${t}_${i}.pid" > /dev/null; then
          log_action_end_msg 0 "running"
	  if [ "$RET" -eq "3" ]; then
	    RET=0
	  fi
        else
          if [ -e "${piddir}/${d}.${t}_${i}.pid" ]; then
            log_action_end_msg 0 "${d} (${i} ${t}) failed"
	    RET=1
          else
            log_action_end_msg 0 "not running"
          fi
        fi
      done
    done
  done
  return $RET
}

stop_daemons () {
  tokill=""
  for d in ${daemons}; do
    eval trees=\"\$\{trees_${d}\}\"
    for t in ${trees}; do
      if test ${d} = collector; then
        eval instances=\"\$\{col_inst_${t}\}\"
	
	for i in ${instances}; do
          pidfile="${piddir}/${d}.${t}_${i}.pid"
          if test -r "${pidfile}"; then
            tokill=${tokill}' t='${t}'_'${i}';d='${d}
	    log_action_cont_msg "TERM ${d} (${i} ${t})"
	    killproc -p "${pidfile}" $d TERM
	  fi
        done
      else
        pidfile="${piddir}/${d}.${t}.pid"
        if test -r "${pidfile}"; then
          tokill=${tokill}' t='${t}';d='${d}
	  log_action_cont_msg "TERM ${d} (${t})"
	  killproc -p "${pidfile}" $d TERM
	fi
      fi
    done
  done
  
  killed=$(echo "${tokill}" | wc -w)
  notdead=1
  kc=${TORRUS_KILL_COUNT}
  while test $killed -gt 0 -a $kc -gt 0; do
    log_action_cont_msg "sleep"
    /bin/sleep $TORRUS_KILL_SLEEP
    kc=$(expr $kc - 1)
    for tuple in ${tokill}; do
      eval ${tuple}
      pidfile="${piddir}/${d}.${t}.pid"
      if test -r "${pidfile}"; then
	log_action_cont_msg "TERM ${d} (${t})"
	killproc -p "${pidfile}" $d TERM
      else
        killed=$(expr $killed - 1)
      fi
    done
  done

  if test \( $killed -gt 0 \); then
   for tuple in $tokill; do
     eval $tuple
     pidfile="${piddir}/${d}.${t}.pid"
     if test -r "${pidfile}"; then
       log_action_cont_msg "KILL ${d} (${t})"
       killproc -p "${pidfile}" $d KILL
     fi
   done
  fi
}

restart_apache () {
  for apachedir in apache2
  do
    if test -L /etc/${apachedir}/conf.d/torrus-apache2.conf; then
       test -x /etc/init.d/${apachedir} && invoke-rc.d ${apachedir} restart
    fi
  done
}

clear_cache () {
  if test -x /usr/sbin/torrus ; then
    /usr/sbin/torrus clearcache > /dev/null 2>&1 || true
  fi
}

case "$1" in
  start)
    log_progress_msg "Starting Torrus daemons:" ""
    start_daemons
    log_end_msg 0
  ;;
  stop)
    log_action_begin_msg "Stopping Torrus daemons (this may take a while)"
    stop_daemons
    log_end_msg 0
  ;;
  restart)
    log_action_begin_msg "Stopping Torrus daemons for restart (this may take a while)..."
    stop_daemons
    log_end_msg 0
    log_progress_msg "Restarting Torrus daemons" ""
    start_daemons
    log_end_msg 0
  ;;
  force-reload) 
    log_action_begin_msg "Stopping Torrus daemons for restart (this may take a while)..."
    stop_daemons
    log_end_msg 0
    log_action_begin_msg "Clearing Torrus cache"
    clear_cache
    log_end_msg 0
    log "Restarting apache web server"
    restart_apache
    log_progress_msg "Restarting Torrus daemons" ""
    start_daemons
    log_end_msg 0
  ;;
  status)
    daemon_status
  ;;
  *)  echo "Usage: $0 {start|stop|restart|force-reload|status}"
      exit 1
  ;;
esac

exit 0
