#!/bin/sh

#
# Skeleton sh script suitable for starting and stopping
# "wrapped" Java apps.
#
# Make sure that PIDFILE points to the correct location,
# if you have changed the default location set in the
# wrapper configuration file.
#
# Note that the wrapper only supports Windows, Mac, and
# certain Linux architectures.
# It may also fail on some 64-bit platforms.
# If this script fails to successfully invoke i2psvc on your platform,
# try the runplain.sh script instead.
#

#-----------------------------------------------------------------------------
# These settings can be modified to fit the needs of your application

# Paths
# Note that (percent)INSTALL_PATH and (percent)SYSTEM_java_io_tmpdir
# should have been replaced by the izpack installer.
# If you did not run the installer, replace them with the appropriate path.
I2P="%INSTALL_PATH"
I2PTEMP="%SYSTEM_java_io_tmpdir"
# PORTABLE installation:
# Use the following instead.
#I2PTEMP="%INSTALL_PATH"

WRAPPER_URL="http://www.i2p2.de/manualwrapper"

# Application
APP_NAME="i2p"
APP_LONG_NAME="I2P Service"

# Wrapper
WRAPPER_CMD="$I2P/i2psvc"
WRAPPER_CONF="$I2P/wrapper.config"

unsupported() {
    echo "The most likely reason is that a supported version of the java"
    echo "wrapper is not available in the I2P installation package for your"
    echo "platform. It may be possible to manually download and install"
    echo "a compatible wrapper for your system."
    echo "See ${WRAPPER_URL} for hints."
    echo 
    echo "In the meantime, you may start I2P by running the script"
    echo "${I2P}/runplain.sh"
    echo
}

if [ ! -r ${WRAPPER_CMD} ]; then
    echo "Unable to locate i2psvc in ${I2P}!"
    echo
    unsupported
    echo
    exit 1
fi

# Priority at which to run the wrapper.  See "man nice" for valid priorities.
#  nice is only used if a priority is specified.
PRIORITY=

# Location of the pid file.
PIDDIR="$I2PTEMP"

# If uncommented, causes the Wrapper to be shutdown using an anchor file.
#  When launched with the 'start' command, it will also ignore all INT and
#  TERM signals.
#IGNORE_SIGNALS=true

# If specified, the Wrapper will be run as the specified user when the 'start'
#  command is passed to this script.  When running with the 'console' command
#  the current user will be used.
# IMPORTANT - Make sure that the user has the required privileges to write
#  the PID file and wrapper.log files.  Failure to be able to write the log
#  file will cause the Wrapper to exit without any way to write out an error
#  message.
# NOTE - This will set the user which is used to run the Wrapper as well as
#  the JVM and is not useful in situations where a privileged resource or
#  port needs to be allocated prior to the user being changed.
#RUN_AS_USER=

# Do not modify anything beyond this point
#-----------------------------------------------------------------------------

# Process ID
ANCHORFILE="$PIDDIR/$APP_NAME.anchor"
PIDFILE="$PIDDIR/$APP_NAME.pid"
pid=""

# Resolve the location of the 'ps' command
PSEXE="/usr/bin/ps"
if [ ! -x $PSEXE ]
then
    PSEXE="/bin/ps"
    if [ ! -x $PSEXE ]
    then
        echo "Unable to locate 'ps'."
        echo "Please report this with the location on your system."
        exit 1
    fi
fi

# Build the nice clause
if [ "X$PRIORITY" = "X" ]
then
    CMDNICE=""
else
    CMDNICE="nice -$PRIORITY"
fi

# Check the configured user
if [ "X$RUN_AS_USER" != "X" ]
then
    if [ "`id -u -n`" = "$RUN_AS_USER" ]
    then
        # Already running as the configured user.  Avoid password prompts by not calling su.
        RUN_AS_USER=""
    fi
fi

getpid() {
    if [ -f $PIDFILE ]
    then
        if [ -r $PIDFILE ]
        then
            pid=`cat $PIDFILE`
            if [ "X$pid" != "X" ]
            then
                # Verify that a process with this pid is still running.
                pid=`$PSEXE -p $pid | grep $pid | grep -v grep | awk '{print $1}' | tail -n 1`
                if [ "X$pid" = "X" ]
                then
                    # This is a stale pid file.
                    rm -f $PIDFILE
                    echo "Removed stale pid file: $PIDFILE"
                fi
            fi
        else
            echo "Cannot read $PIDFILE."
            exit 1
        fi
    fi
}

testpid() {
    pid=`$PSEXE -p $pid | grep $pid | grep -v grep | awk '{print $1}' | tail -n 1`
    if [ "X$pid" = "X" ]
    then
        # Process is gone so remove the pid file.
        rm -f $PIDFILE
    fi
}

console() {
    echo -n "Running $APP_LONG_NAME..."
    getpid
    if [ "X$pid" = "X" ]
    then
        if [ "X$IGNORE_SIGNALS" = "X" ]
        then
	     trap "exit 1" INT
	     (exec $CMDNICE $WRAPPER_CMD $WRAPPER_CONF i2psvc.pidfile=$PIDFILE 2> /dev/null ) || failed
        else
	     (exec $CMDNICE $WRAPPER_CMD $WRAPPER_CONF i2psvc.pidfile=$PIDFILE wrapper.anchorfile=$ANCHORFILE 2> /dev/null) || failed
        fi
    else
        echo "$APP_LONG_NAME is already running."
        exit 1
    fi
}

start() {
    echo -n "Starting $APP_LONG_NAME..."
    getpid
    if [ "X$pid" = "X" ]
    then
        if [ "X$IGNORE_SIGNALS" = "X" ]
        then
	    if [ "X$RUN_AS_USER" = "X" ]
            then
	         (exec $CMDNICE $WRAPPER_CMD $WRAPPER_CONF i2psvc.pidfile=$PIDFILE wrapper.daemonize=TRUE > /dev/null 2>&1) || failed
            else
	         (su -m $RUN_AS_USER -c "exec $CMDNICE $WRAPPER_CMD $WRAPPER_CONF i2psvc.pidfile=$PIDFILE \
			 wrapper.daemonize=TRUE" > /dev/null 2>&1) || failed
            fi
        else
            if [ "X$RUN_AS_USER" = "X" ]
            then
	         (exec $CMDNICE $WRAPPER_CMD $WRAPPER_CONF i2psvc.pidfile=$PIDFILE wrapper.anchorfile=$ANCHORFILE \
			 wrapper.ignore_signals=TRUE wrapper.daemonize=TRUE > /dev/null 2>&1) || failed
            else
	         (su -m $RUN_AS_USER -c "exec $CMDNICE $WRAPPER_CMD $WRAPPER_CONF i2psvc.pidfile=$PIDFILE wrapper.anchorfile=$ANCHORFILE \
			 wrapper.ignore_signals=TRUE wrapper.daemonize=TRUE" > /dev/null 2>&1) || failed
            fi
        fi
    else
        echo "$APP_LONG_NAME is already running."
        exit 1
    fi
     echo "done." 
}

stopit() {
    echo "Stopping $APP_LONG_NAME..."
    getpid
    if [ "X$pid" = "X" ]
    then
        echo "$APP_LONG_NAME was not running."
    else
        if [ "X$IGNORE_SIGNALS" = "X" ]
        then
            # Running so try to stop it.
            kill $pid
            if [ $? -ne 0 ]
            then
                # An explanation for the failure should have been given
                echo "Unable to stop $APP_LONG_NAME."
                exit 1
            fi
        else
            rm -f $ANCHORFILE
            if [ -f $ANCHORFILE ]
            then
                # An explanation for the failure should have been given
                echo "Unable to stop $APP_LONG_NAME."
                exit 1
            fi
        fi

        # We can not predict how long it will take for the wrapper to
        #  actually stop as it depends on settings in wrapper.conf.
        #  Loop until it does.
        savepid=$pid
        CNT=0
        TOTCNT=0
        while [ "X$pid" != "X" ]
        do
            # Loop for up to 5 minutes
            if [ "$TOTCNT" -lt "300" ]
            then
                if [ "$CNT" -lt "5" ]
                then
                    CNT=`expr $CNT + 1`
                else
                    echo "Waiting for $APP_LONG_NAME to exit..."
                    CNT=0
                fi
                TOTCNT=`expr $TOTCNT + 1`

                sleep 1

                testpid
            else
                pid=
            fi
        done

        pid=$savepid
        testpid
        if [ "X$pid" != "X" ]
        then
            echo "Timed out waiting for $APP_LONG_NAME to exit."
            echo "  Attempting a forced exit..."
            kill -9 $pid
        fi

        pid=$savepid
        testpid
        if [ "X$pid" != "X" ]
        then
            echo "Failed to stop $APP_LONG_NAME."
            exit 1
        else
            echo "Stopped $APP_LONG_NAME."
        fi
    fi
}

status() {
    getpid
    if [ "X$pid" = "X" ]
    then
        echo "$APP_LONG_NAME is not running."
        exit 1
    else
        echo "$APP_LONG_NAME is running ($pid)."
        exit 0
    fi
}

dump() {
    echo "Dumping $APP_LONG_NAME..."
    getpid
    if [ "X$pid" = "X" ]
    then
        echo "$APP_LONG_NAME was not running."

    else
        kill -3 $pid

        if [ $? -ne 0 ]
        then
            echo "Failed to dump $APP_LONG_NAME."
            exit 1
        else
            echo "Dumped $APP_LONG_NAME."
        fi
    fi
}

failed() {
	echo "**Failed to load the wrapper**"
	case `uname -s` in
	     FreeBSD)
    		echo
    		echo "In an attempt to ensure that I2P will run on as many systems as possible, included in the"
    		echo "installation package is a version of the wrapper that was compiled for FreeBSD 6." 
    		echo "Necessary compatibility libraries may not be on your system."
    		echo
    		echo "Please install the misc/compat6x port and try running I2P again."
    		echo 
    		echo "If you cannot (or choose not to) install these libraries, I2P may be started with the"
    		echo "'runplain.sh' script. Another option would be to compile the java wrapper for your system."
		echo "Hints to accomplish this can be found at ${WRAPPER_URL}."
		echo
		exit 1
		;;
	     *)
		echo
		unsupported
		exit 1
		;;
	esac
}
case "$1" in

    'console')
        console
        ;;

    'start')
        start
        ;;

    'stop')
        stopit
        ;;

    'restart')
        stopit
	sleep 2
        start
        ;;

    'status')
        status
        ;;

    'dump')
        dump
        ;;

    *)
        echo "Usage: $0 { console | start | stop | restart | status | dump }"
        exit 1
        ;;
esac

exit 0
