#!/bin/bash
#
# chkconfig: 345 98 02
# description: This script starts the local BOINC client as a daemon
#         For more information about BOINC (the Berkeley Open Infrastructure
#         for Network Computing) see http://boinc.berkeley.edu
# processname: boinc
# config: /etc/default/boinc
#
########################################################################

## These 4 installation dirs set by autoconf. ##########################
prefix=`dirname /usr/.`
exec_prefix=`dirname /usr/.`
bindir=`dirname /usr/bin/.`
sysconfdir=`dirname ${prefix}/etc/.`
########################################################################

# set the basic PATH
PATH=/sbin:/bin:/usr/sbin:/usr/bin
export PATH

BOINCUSER=boinc
BOINCDIR=/var/lib/boinc
BOINCEXE_NAME=boinc_client
BOINCEXE=${bindir}/${BOINCEXE_NAME}
BOINCCMD_NAME=boinccmd
BOINCCMD=${bindir}/${BOINCCMD_NAME}
LOGFILE=/var/log/${BOINCEXE_NAME}.log
ERRORLOG=/var/log/${BOINCEXE_NAME}_err.log
PIDFILE=/var/run/${BOINCEXE_NAME}.pid
BOINCOPTS="--daemon"

# Subsys lock file ...

# If there is the subsys directory, then use it ...
if [ -d /var/lock/subsys/ ]; then
        LOCKFILE=/var/lock/subsys/${BOINCEXE_NAME}
elif [ -d /var/lock ]; then
        LOCKFILE=/var/lock/${BOINCEXE_NAME}
elif [ -d /var/run ]; then
        LOCKFILE=/var/run/${BOINCEXE_NAME}.lock
fi

# su on Linux seems to need this to be set to work properly in a script
export TERM=dumb

# define the output string colors and text
        ESC=`echo -en "\033"`
  RESULT_OK="${ESC}[\061;32m${ESC}[70G[\040\040\040OK\040\040\040]${ESC}[m"
RESULT_FAIL="${ESC}[\061;31m${ESC}[70G[\040FAILED\040]${ESC}[m"
RESULT_WARN="${ESC}[\061;33m${ESC}[70G[\040\040WARN\040\040]${ESC}[m"

function echo_success () { echo -e -n $RESULT_OK ; }
function echo_failure () { echo -e -n $RESULT_FAIL ; }
function echo_warning () { echo -e -n $RESULT_WARN ; }

function killproc() {
     PID=`local_pidof $1`
     [ -z $PID ] && kill $PID
}

# check if we have pidof.  If not use ps and grep for the same job.
if [ -x /bin/pidof ] ; then
  function local_pidof() {
    pidof -s -x -o $$ -o $PPID -o %PPID $1
  }
else
  function local_pidof() {
    ps xaugww | sed 's/$/ /' | grep "[ /]$1 " | grep -v $$ | grep -v $PPID | grep -v %PPID | grep -v grep | awk '{print $2}'
  }
fi

# overwrite settings from conf file
if [[ -f /etc/default/boinc-client ]] ; then
  . /etc/default/boinc-client
elif [[ -f /etc/sysconfig/boinc-client ]] ; then
  . /etc/sysconfig/boinc-client
fi

## Check what user we are running as:
USERNOW=`ps u $$ | tail -1 | awk '{print $1}'`
if [ -z "$BOINCUSER" ] ; then
  BOINCUSER="${USERNOW}"
fi

## Check that BOINCUSER actually exists
if [ -z "`grep ^${BOINCUSER}: /etc/passwd`" ] ; then
  if [ -z "`ypcat passwd 2>/dev/null | grep ^${BOINCUSER}:`" ] ; then
    if [ -z "`nidump passwd / 2>/dev/null | grep ^${BOINCUSER}:`" ] ; then
       echo -n ERROR: user ${BOINCUSER} does not exist.
       echo_failure
       echo
       exit 9
    fi
  fi
fi

# if we are running as root, print a warning.
if [ "x$NOWARNING" != "xyes" -a  "$BOINCUSER" = "root" ] ; then
  echo -n WARNING: boinc-client will be running as root
  echo_warning
  echo
fi

# check whether we will be able to write to the BOINC directory
if [ "${USERNOW}" = "${BOINCUSER}" ] ; then
  if [ ! -O ${BOINCDIR} ] ; then
    echo -n ERROR: $BOINCDIR is not owned by $BOINCUSER.
    echo_failure
    echo
    exit 8
  fi
elif [ "${USERNOW}" = "root" ] ; then
  cmd="if test -O ${BOINCDIR} ; then echo success ; fi"
  if [ -z `su $BOINCUSER -c "$cmd"` ]; then
    echo -n ERROR: $BOINCDIR is not owned by $BOINCUSER.
    echo_failure
    echo
    exit 8
  fi
fi


## Locate the executable, either boinc_client, boinc,
## or boinc_M.mm_.... with highest version number
## We only do this if BOINCEXE set above isn't found or is not executable.
if [ ! -x $BOINCEXE ]; then
  BOINCEXE=`$WHICH $BOINCEXE_NAME 2>/dev/null`
  if [ ! -x "$BOINCEXE" ]; then
    BOINCEXE=`$WHICH boinc 2>/dev/null`
  fi
fi

if [ ! -x "$BOINCEXE" ]; then
  echo -n "Cannot find an executable for the BOINC client."
  echo_failure
  echo
  exit 2
fi

## boinccmd will probably be in the same place as the boinc_client
if [ ! -x $BOINCCMD ]; then
  BOINCCMD=`$WHICH $BOINCCMD_NAME 2>/dev/null`
  if [ ! -x "$BOINCCMD" ]; then
    BOINCCMD=`dirname $BOINCEXE 2>/dev/null`/${BOINCCMD_NAME}
  fi
fi


if [ "x$NOWARNING" != "xyes" -a ! -x $BOINCCMD ]; then
  echo -n "Cannot find the boinccmd executable.  Reload will fail."
  echo_warning
  echo
fi

## Functions: $1 is one of  start|stop|status|reload|restart

export NOWARNING=yes

case "$1" in
  start)
        cd $BOINCDIR
        PID=`local_pidof $BOINCEXE_NAME`

        if [ -f lockfile -o -f $LOCKFILE ] ; then
          if [ -z "$PID" ] ; then
            # a lockfile exists, but boinc_client isn't running
            /bin/rm -f lockfile $LOCKFILE $PIDFILE 2>&1 > /dev/null
          else
            echo -n "Another instance of BOINC is running (PID=${PID})."
            echo_failure
            echo
            exit 1
          fi
        fi

        if [ ! -d projects ] ; then
          echo -n "The BOINC client requires initialization."
          echo_warning
          echo
        fi

        touch ${LOGFILE} ${ERRORLOG}
        NOCORE="ulimit -c 0 2>&1 >/dev/null"
        echo -n "Starting BOINC client as a daemon:  "
        if [ "${BOINCUSER}" = "${USERNOW}" ] ; then
           # I am BOINCUSER.  Just start client as me.
           $NOCORE
           $BOINCEXE $BOINCOPTS >>$LOGFILE 2>>$ERRORLOG &
        else
           chown ${BOINCUSER} ${LOGFILE} ${ERRORLOG}
           if [ -f gui_rpc_auth.cfg ] ; then
              chmod g+r gui_rpc_auth.cfg
           fi
           su - $BOINCUSER -c "$NOCORE ; $BOINCEXE $BOINCOPTS >>$LOGFILE 2>>$ERRORLOG" 2>/dev/null > /dev/null &
        fi
        sleep 3
        PID=`local_pidof $BOINCEXE_NAME`
        if [ "$PID" != "" ]; then
          echo $PID > $PIDFILE
          touch $LOCKFILE && echo_success || ( echo_failure ; echo )
        fi
        echo
        ;;
  stop)
        cd $BOINCDIR
        if [ ! -f $PIDFILE -a ! -f lockfile -a ! -f $LOCKFILE ] ; then
          echo -n "BOINC is not running (no lockfiles found)."
          echo_success
        else
          echo -n "Stopping BOINC client daemon:  "
          if [ -f $PIDFILE ] ; then
            PID=`cat $PIDFILE`
            if [ -n "`ps $PID | grep $PID`" ] ; then
              kill `cat $PIDFILE`
              sleep 5
            fi
            if [ -z "`ps $PID | grep $PID`" ] ; then
              echo_success
            else
              echo_failure
              echo
            fi
          else
            killproc $BOINCEXE_NAME  && echo_success  || echo_failure
          fi
          # clean up in any case
          rm -f lockfile 2>/dev/null >/dev/null
          rm -f $LOCKFILE 2>/dev/null
          rm -f $PIDFILE 2>/dev/null
        fi
        echo
        ;;
  reload)
        if [ ! -f lockfile -a ! -f $LOCKFILE ] ; then
          echo  "BOINC is not running (no lockfiles found) -- starting service."
          $0 start
        else
          $BOINCCMD --read_cc_config >>$LOGFILE 2>>$ERRORLOG && echo_success || $0 restart
        fi
        ;;
  restart)
        $0 stop
        $0 start
        ;;

  status)
        PID=`cat $PIDFILE 2>/dev/null`
        if [ "$PID" != "" ]; then
          # is it still running?
          if [ -z "`ps $PID | grep $PID`" ]; then
            # not running.  Try the other tests.
            PID=""
          fi
        fi
        if [ "$PID" == "" ]; then
          PID=`local_pidof $BOINCEXE_NAME`
        fi
        if [ "$PID" == "" ]; then
          PID=`local_pidof $BOINCEXE`
        fi
        if [ "$PID" != "" ]; then
          echo "BOINC client is running (pid $PID)."
        else
          if [ -f $BOINCDIR/lockfile -o -f $LOCKFILE ]; then
             echo "BOINC is stopped but lockfile(s) exist."
             exit 2
          else
             echo "BOINC client is stopped."
             exit 3
          fi
        fi
        ;;

  *)
        echo "Usage: boinc {start|stop|restart|reload|status}"
        exit 1
esac

exit

#EOF#
