#!/bin/sh
#  Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
#  This software code contains proprietary information
#  and should be treated as confidential.
#
#  Component: Secure Global Desktop Gateway
#  Author: Bill Weir

RESET_GW_JAVA_HOME=1

. "${INSTDIR}/bin/scripts/common"

[ "${trace}" = "x" ] && set -x

usage() {
    echo "${i18n_startusage10_gw}"
    exit 1
}

[ -n "$1" ] && usage

# Must be root user to bind to privileged port
u="`LANG=C LC_ALL=C id | sed 's/.*uid=\([0-9][0-9]*\).*/\1/'`"
if [ "$u" = "0" ]
then
  : # all is okay
else
  echo "You must be root to run this program"
  exit 15
fi


_setsid=''
for _dir in `echo "$PATH" | tr : ' '`; do
    case "${_dir}" in
    /*) [ -x "${_dir}/setsid" ] && { _setsid="${_dir}/setsid"; break; }
    esac
done

privusr="sgdgsys"
privgrp="sgdgserv"

mode=750


. ${INSTDIR}/etc/version

ApPath="${INSTDIR}/httpd/httpd-${VERSION_APACHE}"
ApBin=${ApPath}/bin/apachectl
ApEnv=${ApPath}/bin/envvars

ApStart="-D SSL -k start"
ApStop="-D SSL -k stop"
fApPid="${ApPath}/logs/httpd.pid"

# Source Appropriate Env for apache
if [ -f "${ApEnv}" ]; then 
    . $ApEnv
fi

# Work out the platform library path
case `uname` in
    "Linux")
        LIBDIR="lib64"
    ;;
    "SunOS")
        LIBDIR="lib/`isainfo -k 2>/dev/null`"
    ;;
esac

fPxRun="${INSTDIR}/proxy/var/run"
fPxPid="${fPxRun}/proxy.pid"
fPxStatus="${fPxRun}/proxy.status"
fPxExit="${TMPDIR:-/tmp}/SUNWsgdg.$$"
PxSysId=`su ${privusr} -c "/usr/bin/id -a | sed -n 's/.*uid=\([0-9]*\).*/\1/p'"`
PxExit="" PxExitEx=""

Tuning=`grep -v '^#' ${INSTDIR}/proxy/etc/tuning_parameters | tr '\012' ' '`
Ipv6Prefs=`grep -v '^#' ${INSTDIR}/proxy/etc/ipv6_parameters | tr '\012' ' '`
JavaArgs="-server ${Tuning} ${Ipv6Prefs} \
-Djava.library.path="${INSTDIR}/${LIBDIR}/" \
-Dcom.sun.jarp.pidfile=${fPxPid} \
-Dcom.sun.jarp.statusfile=${fPxStatus} \
-Djava.util.logging.config.file=${INSTDIR}/proxy/etc/logging.properties \
-Djdk.tls.rejectClientInitiatedRenegotiation=true \
-jar ${INSTDIR}/proxy/jarp.jar"
PxArgs="--user=${PxSysId} ${INSTDIR}/etc/gateway.xml"
PxLog="${INSTDIR}/proxy/var/log/proxy.log"
Password=""
PasswordAttempts=0

GetApachePid() {
    _pid=""
    [ -s "${fApPid}" ] && _pid=`tr -cd '0123456789' <"${fApPid}"`
    [ -n "${_pid}" ] && [ -n "`ps -p${_pid} | grep \"${_pid}\"`" ] && echo "${_pid}"
    return 0
}

GetProxyPid() {
    _pid=""
    [ -s "${fPxPid}" ] && _pid=`tr -cd '0123456789' <"${fPxPid}"`
    [ -n "${_pid}" ] && [ -n "`ps -p${_pid} | grep \"${_pid}.*java\"`" ] && echo "${_pid}"
    return 0
}


# Is it running already?
[ -n "`GetProxyPid`" -o -n "`GetApachePid`" ] && {
    printf "${i18n_alreadyrunning12_gw}" "${fApPid}" "${fPxPid}" 
    exit 1
}

rm -rf ${fPxPid} ${fPxStatus} ${fPxExit} 2>/dev/null

CleanExit() {
    # Make sure Apache and the proxy are both running. If only one is running,
    # stop the other one too so that the running state is consistent.
    ret=1
    ApPid=`GetApachePid`
    PxPid=`GetProxyPid`
    [ -n "$2" ] && echo "$2"	# caller supplied message
    case "${PxExit}" in
    ''|0) [ -z "$2" ] && echo "${i18n_jarpstarted10_gw}"
	  [ -n "${ApPid}" -a -n "${PxPid}" ] && ret=0	# everything is OK
	  ;;
    *)    [ -z "$2" ] && printf "${i18n_jarpstatus11_gw}" "${PxExit}${PxExitEx}"
	  PxPid=""
    esac

    if [ -n "${ApPid}" -a -z "${PxPid}" ]; then
	# started Apache but not proxy: stop Apache
	${ApBin} -d ${ApPath} ${ApStop}
    elif [ -z "${ApPid}" -a -n "${PxPid}" ]; then
	# started proxy but not Apache: stop proxy
	n=10
	while [ -n "${PxPid}" -a "${n}" -gt 0 ]; do
	    [ "${n}" -eq 10 -o "${n}" -eq 5 ] && kill "${PxPid}" 2>/dev/null
	    sleep 1
	    PxPid=`GetProxyPid`
	    n=`expr "${n}" - 1`
	done
	[ -n "${PxPid}" ] && {
	    kill -9 "${PxPid}" 2>/dev/null
	    sleep 5
	    PxPid=`GetProxyPid`
	}
	if [ -n "${PxPid}" ]; then
	    echo "${i18n_cantstop10_gw}"
	else
	    rm -f ${fPxPid} ${fPxStatus} ${fPxExit} 2>/dev/null
	fi
    fi

    case "${PxExitEx}" in
    *CONFIG*) echo; echo "${i18n_setupnext_gw}"
    esac

    rm -f ${fPxExit} 2>/dev/null
    [ -n "$1" ] && ret="$1"
    exit ${ret}
}

echo "${i18n_starting10_gw}"

# start Apache
${_setsid} ${ApBin} -d ${ApPath} ${ApStart}
ret=$?
[ "${ret}" -ne 0 ] && {
    # Unable to start Apache, so don't bother trying Proxy
    echo; printf "${i18n_jarpstatus11_gw}" "${ret}"
    exit 1
}
# wait for the Apache pid file to be created
n=10
while [ "${n}" -gt 0 -a ! -s "${fApPid}" ]; do
    sleep 1
    n=`expr "${n}" - 1`
done
[ ! -s "${fApPid}" ] && {
    # Unable to start Apache, so don't bother trying Proxy
    echo; printf "${i18n_jarpstatus11_gw}" "1"
    exit 1
}
chmod ${mode} ${fApPid} 2>/dev/null
chown ${privusr}:${privgrp} ${fApPid} 2>/dev/null

# Wait for a file to be present within the specified timeout.
# Args: $1 - Path to file
#       $2 - Timeout length in seconds
WaitFile() {
    local file="$1"; shift
    local waitseconds="${1:-10}"; shift # 10 seconds as default timeout

    until test $((waitseconds--)) -eq 0 -o -f "$file" ; do sleep 1; done

    # Returns an exit code of zero (true) if waitseconds
    # is nonzero (i.e. file found before timeout expired) or returns 1
    # if waitseconds is zero (i.e timeout expired) 
    ((++waitseconds))
}

ProxyRun() {
    rm -f ${fPxPid} ${fPxStatus} ${fPxExit} 2>/dev/null
    cat /dev/null >${fPxExit}

    # The time to wait for the proxy to start
    local WaitTime=30

    case "${PxArgs}" in
    *--defaultPassword*)
       echo "Starting routing proxy `date`" >> ${PxLog}
       ( echo "${Password}" | nohup /bin/sh -c "${GW_JAVA_DIR}/java ${JavaArgs} ${PxArgs} >>${PxLog} 2>&1;x=\$?;[ -f ${fPxExit} ] && echo \$x >${fPxExit}" >/dev/null 2>&1 ) &
       # Wait for JARP pidfile to be present before continuing
       WaitFile "${fPxPid}" "${WaitTime}" || {
           echo "Routing proxy pidfile not found after waiting for ${WaitTime} seconds: '${fPxPid}'" >> ${PxLog}
           exit 1
       }
       echo "Routing proxy started on `date` (PID:`GetProxyPid`)" >> ${PxLog}
	;;
    *) echo "Starting routing proxy `date`" >> ${PxLog}
       ( nohup /bin/sh -c "${GW_JAVA_DIR}/java ${JavaArgs} ${PxArgs} >>${PxLog} 2>&1;x=\$?;[ -f ${fPxExit} ] && echo \$x >${fPxExit}" >/dev/null 2>&1 ) &
       WaitFile "${fPxPid}" "${WaitTime}" || {
           echo "Routing proxy pidfile not found after waiting for ${WaitTime} seconds: '${fPxPid}'" >> ${PxLog}
           exit 1
       }
       echo "Routing proxy started on `date` (PID:`GetProxyPid`)" >> ${PxLog}
    esac
}

# start proxy
mkdir -p ${fPxRun} 2>/dev/null
chown ${privusr}:${privgrp} ${fPxRun} 2>/dev/null
while :; do
    ProxyRun

    n=5 PxExit="" PxStatus=""
    while [ "${n}" -gt 0 ]; do
	sleep 1
	PxExit=`cat "${fPxExit}" 2>/dev/null`
	[ -n "${PxExit}" ] && break	# Proxy has exited
	PxStatus=`egrep -i running "${fPxStatus}" 2>/dev/null`
	n=`expr "${n}" - 1`
    done

    [ -z "${PxExit}" ] && break	# Proxy has not exited

    # Proxy has exited.  What reason did it give?
    rm -f ${fPxPid} ${fPxStatus} ${fPxExit} 2>/dev/null
    case "${PxExit}" in
    5|6) [ "${PasswordAttempts}" -ge 3 ] && CleanExit 1 "${i18n_keystorepasswordtoomany_gw}"
	while :; do
	    case ${PxExit} in
	    5) printf "${i18n_keystorepassword_gw}" ;;
	    6) printf "${i18n_keystorepasswordwrong_gw}" ;;
	    esac
	    stty -echo; read Password; stty echo
	    echo
	    [ -n "${Password}" ] && break	# keep prompting until they enter something
	done
	[ "${Password}" = "q" ] && break
	PxArgs="--user=${PxSysId} --defaultPassword ${INSTDIR}/etc/gateway.xml"
	;;
    *)	case "${PxExit}" in
	0) PxExitEx=": OK";;
	1) PxExitEx=": CONFIG_FILENOTFOUND";;
	2) PxExitEx=": CONFIG_OPENFAILED";;
	3) PxExitEx=": CONFIG_INVALID";;
	4) PxExitEx=": UNHANDLED";;
    7) PxExitEx=": PIDFILE_CREATEFAILED";;
	esac
	break
    esac
    PasswordAttempts=`expr "${PasswordAttempts}" + 1`
done

chmod ${mode} ${fPxPid} 2>/dev/null
chown ${privusr}:${privgrp} ${fPxPid} ${fPxStatus} 2>/dev/null

CleanExit
