#!/bin/sh
#
# Copyright (c) 2004-2007 - Consultas, PKG.fr
#
# This file is part of A2P.
#
# A2P is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# A2P is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with A2P; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
# $Id: a2p.sh 3 2007-10-18 16:20:19Z root $
#
# a2p: This is the init script for starting up a2p.pl
#
# chkconfig: 345 99 10
# description: Starts and stops afp2print backend daemon
#              that handles threads to process AFPSPOOL
# processname: a2p
# pidfile: /var/run/a2p.pid

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

# A2P_SYS_CONF must be a full pathname, daemon need at least this variable
# to know which file to read when reloading conf
A2P_SYS_CONF="/etc/afp2print/afpds2tex.conf"

# See how we were called.

# Strip service name from Sxx/Kxx if started during boot or during shutdown
prog="`basename $0|sed -re 's/^S[0-9]{2}//' -e 's/^K[0-9]{2}//'`"
pid="`pidof $prog`"

# Delete PID file if service is not running
[ -z "$pid" -a -s /var/run/$prog.pid ] && rm -f /var/run/$prog.pid

# System configuration integration if not integrated in environment
if [ -e "$A2P_SYS_CONF" -a -z "$AFPSPOOL" ]; then
    . "$A2P_SYS_CONF"
fi

# Optional conf integration
if [ -n "$prog" -a -e "/etc/afp2print/${prog}.conf" ]; then
    . "/etc/afp2print/${prog}.conf"
fi

[ -z "$LOCKID" ] && LOCKID="`hostname -s|tr 'a-z' 'A-Z'`"
export LOCKID

# Perl library path options to help service to found its needed modules
PERLOPT=""
[ -d "$AFP2PRINT_PATH/A2P" ] && PERLOPT="$PERLOPT -I$AFP2PRINT_PATH"
[ -d "$AFP2PRINT_PATH/printlib/perllib" ] && PERLOPT="$PERLOPT -I$AFP2PRINT_PATH/printlib"
[ -d "$PRINTLIB_PATH/perllib" ] && PERLOPT="$PERLOPT -I$PRINTLIB_PATH"

# Prepare Perl binary environment
# Also unset JAVA_HOME in case it is in our ENV as it should exist only during
# launch by Eclipse IDE
PERLENV="unset JAVA_HOME ; LANG=C LOCKID=\"$LOCKID\" A2P_SYS_CONF=\"$A2P_SYS_CONF\""

# These defaults can be overided in confs
: ${AFP2PRINT_USER:=afp2print}
: ${SERVICE_PROG:=$AFP2PRINT_PATH/a2p.pl}
: ${SERVICE_DEBUG:=0}
: ${PERL:=/usr/bin/perl}
: ${NICE:=nice --5}
: ${LOGFILENAME:=/var/log/a2p.debug}

start() {
    # For SELinux we need to use 'runuser' not 'su'
    SU=su
    if [ -s /etc/redhat-release ]; then
        if ! fgrep -q "Red Hat Enterprise Linux ES release 3" /etc/redhat-release; then
            [ -x /sbin/runuser ] && SU=runuser
        fi
    fi

    echo -n "Starting $prog: "
    if [ -e /var/lock/subsys/$prog ]; then
        if [ -s /var/run/$prog.pid ] && [ -e /proc/`< /var/run/$prog.pid` ]; then
            echo -n "cannot start $prog: $prog is already running.";
            failure "cannot start $prog: $prog already running.";
            echo
            return 1
        fi
    fi

    # Prepare pid file
    touch /var/run/${prog}.pid
    chown $AFP2PRINT_USER /var/run/${prog}.pid
    chmod 664 /var/run/${prog}.pid

    # Check user will be able to output in LOGFILENAME
    if (( DEBUG_IN_FILE > 0 || LOGFILE_VS_SYSLOG > 0 )); then
        touch $LOGFILENAME
        chown $AFP2PRINT_USER $LOGFILENAME
        chmod 664 $LOGFILENAME
    fi

    # Touch the service debug file in case we need to keep some information
    # Usefull when debugging Perl compilation problems
    if (( SERVICE_DEBUG > 0 )); then
        touch /var/run/${prog}.debug
        chown $AFP2PRINT_USER /var/run/${prog}.debug
        if [ "$1" == "debug" ]; then
            PERLOPT="$PERLOPT -dt"
            echo -n "" >/var/run/${prog}.trace
            chown $AFP2PRINT_USER /var/run/${prog}.trace
            chmod 664 /var/run/${prog}.trace
            PERLENV="$PERLENV PERLDB_OPTS=\"NonStop=1 LineInfo=/var/run/${prog}.trace frame=4 dieLevel=2\""
        fi
    else
        rm -f /var/run/$prog.debug
    fi

    # Start service
    $NICE $SU - $AFP2PRINT_USER -c "$PERLENV $PERL $PERLOPT $SERVICE_PROG /var/run/$prog.pid"
    RETVAL=$?
    [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog && success $prog;
    echo
    while [ ! -s /var/run/$prog.pid -a $RETVAL -eq 0 ]
    do
        usleep 100000
    done
    if [ -n "$1" -a -x "/usr/bin/$1" -a -s /var/run/$prog.pid ]; then
        pid=`</var/run/$prog.pid`
        if [ "$1" == "strace" ]; then
            strace -T -a 120 -s 64 -tt -p $pid -f -q -o /var/log/a2p.strace&
        elif [ "$1" == "ltrace" ]; then
            ltrace -C -f -T -s 64 -tt -p $pid -o /var/log/a2p.ltrace&
        fi
    fi
    return $RETVAL
}

stop() {
    echo -n "Stopping $prog: "
    if [ ! -e /var/lock/subsys/$prog ]; then
        echo -n "cannot stop $prog: $prog is not running."
        failure "cannot stop $prog: $prog is not running."
        echo
        return 1;
    fi

    let RETVAL=0 TOTALRETVAL=0
    pid="`pidof $prog`"

    for p in $pid
    do
        # Send signal to process group
        kill -TERM $p
        RETVAL=$?
        let TOTALRETVAL+=RETVAL
    done

    [ $TOTALRETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog && echo_success;
    # Wait max 3 minutes for the service to update its pid to 0 when really quitting
    let TIMEOUT=1800
    while [ -s /var/run/$prog.pid -a $RETVAL -eq 0 ]
    do
        [ "`< /var/run/$prog.pid`" == "0" ] && break
        usleep 100000
        (( --TIMEOUT == 0 )) && break
    done
    [ -s /var/run/$prog.pid ] && [ "`< /var/run/$prog.pid`" -gt 0 -a $RETVAL -eq 0 ] && RETVAL=1
    echo
    return $RETVAL
}

abort() {
    pid="`pidof $prog`"
    echo -n "Aborting any $prog process: $pid"

    for p in $pid
    do
        # Send signal to process group
        kill -ABRT -$p
    done

    rm -f /var/lock/subsys/$prog
    echo_success
    echo
    return 0
}

a2pkill() {
    pid="`pidof $prog`"
    echo -n "Killing any $prog process: $pid"

    for p in $pid
    do
        # Send signal to process group
        kill -KILL -$p
    done

    rm -f /var/lock/subsys/$prog
    echo_success
    echo
    return 0
}

check() {
    pid="`pidof $prog`"
    echo -n "Debugging any $prog process: $pid"

    for p in $pid
    do
        # Send signal to process group
        kill -USR1 -$p
    done

    sleep 1

    echo_success
    echo
    for p in $pid
    do
        echo "Check for $p:"
        for file in /tmp/$prog-*$pid-self$1.log
        do
            if [ -s $file ]; then
                name=${file/*\/}
                name=${name/-$pid-self$1.log}
                echo "====================$name===================="
                cat $file
            fi
        done
    done
    rm -f /tmp/$prog-*$pid-self*.log
    return 0
}

rhstatus() {
    status $prog
}

restart() {
      stop
      sleep 1
    start
}

reload() {
    echo -n "Reloading $prog daemon configuration: "
    killproc $prog -HUP
    RETVAL=$?
    echo
    return $RETVAL
}

case "$1" in
  start)
      start $2
    ;;
  stop)
      stop
    ;;
  abort)
      abort
    ;;
  kill)
      a2pkill
    ;;
  restart)
      restart
    ;;
  reload)
      reload
    ;;
  status)
      rhstatus
    ;;
  test)
      check "test"
    ;;
  debug)
      check "debug"
    ;;
  check)
      check $1
    ;;
  ask)
      shift
    exec $PERL $PERLOPT -we '
    BEGIN { use A2P::Globals; our $Progname = $ARGV[0] }
      use A2P::Client;
      print "\nTesting: " . join(", ",@ARGV) . "\n" ;
      &DoJob( $ARGV[1] => $ARGV[2] )' "$prog-ask" $prog "$1"
    ;;
  condrestart)
      [ -f /var/lock/subsys/$prog ] && restart || :
    ;;
  *)
    echo "Usage: ${prog} {start|stop|abort|ask|kill|status|reload|restart|condrestart|test|debug}"
    exit 1
esac

# Check debug output
if [ -s /var/run/${prog}.debug ]; then
    echo "Debug output for $prog service:"
    cat /var/run/${prog}.debug
    [ "$1" == "stop" -o "$1" == "abort" -o "$1" == "kill" ] && rm -f /var/run/${prog}.debug
fi
