#!/bin/sh
# Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
#
# Component: Wrapper script for the TTA 2.n Java server

. "common-env.sh"

case "$trace" in
x) set -x
esac

# cd to the directory containing this script, so that we can use
# relative pathnames
ttacommand=$0
case "$ttacommand" in
/*) cd `dirname $ttacommand`
    ;;
*)  fullpath=`pwd`/$ttacommand
    cd `dirname $fullpath`
esac


# Where are we relative to top of tta2 tree?
top=.
for _i in 0 1 2 3 4 5 6 7 8 9; do
    [ -d $top/bin/java -a -x $top/bin/tarantella ] && break
    [ -f $top/etc/passwd ] && { top=.; break; }
    top=../$top
done

# Source the Java development environment variables:

# Set port numbers. Start by sourcing info/ports.properties.
if [ -r $top/var/info/ports.properties ]; then
	. $top/var/info/ports.properties
fi

# Use these as defaults for config
tarantella_config_array_externalport=${externalport:-3144}
tarantella_config_array_port=${peerport:-5427}
tarantella_config_array_secureport=${secureport:-5307}
#also include proxiedhttpsurl for firewall traversal
tarantella_config_server_proxiedhttpsurl=${proxiedhttpsurl:-""}
tarantella_config_array_privilegeduser=${privilegeduser:-""}
tarantella_config_array_privilegedgroup=${privilegedgroup:-""}
#also include privileged username for web authentication
tarantella_config_array_webserveruser=${webserveruser:-""}
# Include web auth key refresh
tarantella_config_login_webauth_refreshkeyonrestart=${refreshkeyonrestart:-""}

#Include attribute to tell ttawebtop whether to be verbose or not
tarantella_config_server_cgiverbose=${cgiverbose:-""}

#Include attribute used to modify the archive names
tarantella_config_server_archivemodifier=${archivemodifier:-""}

#Attribute for cgi-bin to tell client to bootstrap from
tarantella_config_server_cgibin_bootscript=${bootscript:-""}

#Attribute passed to client so it knows the route to the server.
tarantella_config_array_netservice_proxy_routes=${routes:-""}

#Attribute passed to client so it knows the correct external name of the server
tarantella_config_server_netservice_proxy_externalnames=${externalnames:-""}

#SHould we use ssl on peer connections? Admin tools need to know
tarantella_config_security_peerssl_enabled=${peerssl:-"0"}

# Use the bootstrap.properties file if we can.
_propfile="$top/var/serverconfig/global/bootstrap.properties"
[ -s "${_propfile}" -a -r "${_propfile}" ] && {
eval `tr -d '\\\\' <"${_propfile}" | egrep -v "^[ 	]*#|'|^tarantella\.config\.(name|type)=" | sed "/=/!d
:dotloop
s/^\([^=]*\)\.\([^=]*=.*\)\$/\1_\2/
tdotloop
s/^\([^=]*\)=\(.*\)/\1='\2'/"`
}

# Set the values in the expected variables.
externalport=$tarantella_config_array_externalport
secureport=$tarantella_config_array_secureport
peerport=$tarantella_config_array_port

# Set DNS names. Use the bootstrap.properties file if we can.
_propfile="$top/var/serverconfig/local/bootstrap.properties"
[ -s "${_propfile}" -a -r "${_propfile}" ] && {
eval `tr -d '\\\\' <"${_propfile}" | egrep -v "^[ 	]*#|'|^tarantella\.config\.(name|type)=" | sed "/=/!d
:dotloop
s/^\([^=]*\)\.\([^=]*=.*\)\$/\1_\2/
tdotloop
s/^\([^=]*\)=\(.*\)/\1='\2'/"`
}

# We need defaults if the properties file is unreadable or corrupt.
peerhost=${tarantella_config_server_dns_peer:-`$top/bin/bin/ttahostname`}
externalhost="${tarantella_config_server_dns_external:-$peerhost}"
auxhost="$peerhost"

# Get the value of proxiedhttpsurl/cgiverbose/archivemodifier/bootscript from 
# server.properties
_propfile="$top/var/serverconfig/local/server.properties"
[ -s "${_propfile}" -a -r "${_propfile}" ] && {
eval `tr -d '\\\\' <"${_propfile}" | egrep -v "^[ 	]*#|'|^tarantella\.config\.(name|type)=" | sed "/=/!d
:dotloop
s/^\([^=]*\)\.\([^=]*=.*\)\$/\1_\2/
tdotloop
s/^\([^=]*\)=\(.*\)/\1='\2'/"`
}

# Get the properties from array.properties
_propfile="$top/var/serverconfig/global/array.properties"
[ -s "${_propfile}" -a -r "${_propfile}" ] && {
eval `tr -d '\\\\' <"${_propfile}" | egrep -v "^[ 	]*#|'|^tarantella\.config\.(name|type)=" | sed "/=/!d
:dotloop
s/^\([^=]*\)\.\([^=]*=.*\)\$/\1_\2/
tdotloop
s/^\([^=]*\)=\(.*\)/\1='\2'/"`
}

# Get web auth properties
_propfile="$top/var/serverconfig/global/webauth.properties"
[ -s "${_propfile}" -a -r "${_propfile}" ] && {
eval `tr -d '\\\\' <"${_propfile}" | egrep -v "^[ 	]*#|'|^tarantella\.config\.(name|type)=" | sed "/=/!d
:dotloop
s/^\([^=]*\)\.\([^=]*=.*\)\$/\1_\2/
tdotloop
s/^\([^=]*\)=\(.*\)/\1='\2'/"`
}

# Get peerssl properties
_propfile="$top/var/serverconfig/global/security.properties"
[ -s "${_propfile}" -a -r "${_propfile}" ] && {
eval `tr -d '\\\\' <"${_propfile}" | egrep -v "^[ 	]*#|'|^tarantella\.config\.(name|type)=" | sed "/=/!d
:dotloop
s/^\([^=]*\)\.\([^=]*=.*\)\$/\1_\2/
tdotloop
s/^\([^=]*\)=\(.*\)/\1='\2'/"`
}

proxiedhttpsurl=$tarantella_config_server_proxiedhttpsurl
privilegeduser=$tarantella_config_array_privilegeduser
privilegedgroup=$tarantella_config_array_privilegedgroup
webauthrefresh=$tarantella_config_login_webauth_refreshkeyonrestart
cgiverbose=$tarantella_config_server_cgiverbose
archivemodifier=$tarantella_config_server_archivemodifier
bootscript=$tarantella_config_server_cgibin_bootscript
routes=$tarantella_config_array_netservice_proxy_routes
externalnames=$tarantella_config_server_netservice_proxy_externalnames
peerssl=$tarantella_config_security_peerssl_enabled
peersslciphers=$tarantella_config_security_peerssl_ciphers
webserveruser=$tarantella_config_array_webserveruser

INSTALLDIR=$top
export INSTALLDIR

[ -f $top/bin/scripts/javaprops ] && . $top/bin/scripts/javaprops
JAVADIR=${INSTALLDIR}/bin/java
CLASSPATH=${JAVADIR}/jserver.jar:${JAVADIR}/lib/*:${JAVADIR}:${JAVADIR}/ext/*:${INSTALLDIR}/var/serverresources/adminconfig


cwd=`pwd`
cd "$top"
installdir=`pwd`
cd "$cwd"

# Get the port numbers from command line:
peerport=$1
externalport=$2
secureport=$3
auxport=$4

# Get the FQ host names from command line:
peerhost=$5
auxhost=$6

# And remove those 6 args from our command line:
shift 6

# Output some kind of help message if appropriate:
if [ "$1" = "help" -o "$1" = "-help" -o "$1" = "--help" -o "$1" = "?" ]
then
  ${SGD_JAVA_DIR}/java -classpath $CLASSPATH TTAServer --help
  exit 15
fi

# System properties.
JAVA_SYSTEM_PROPERTIES="${JAVA_SYSTEM_PROPERTIES}
-Djava.naming.tfn.flavour=jserver-tta2
-Dtarantella.config.access=server
-Dcom.sco.jndi.provider.asad.ttl=30
-Djava.naming.diskens.indexing=true
-Dcom.sco.tta.common.config.events=true
-Djava.util.logging.config.file=$installdir/bin/java/logging.properties
-Dsun.security.krb5.msinterop.kstring=true
-Djdk.tls.rejectClientInitiatedRenegotiation=true
-Dcom.sco.tta.common.config.peerssl.ciphers.order=true
"

# Write the PID to a file, so we know to kill it when we do tarantella stop:
echo $$" " >> $installdir/var/info/jserver.pid
chmod 0640 $installdir/var/info/jserver.pid
 
# echo "PID is " $$


# if the auxserver has suggested we use more memory, then use that number.

memfile=$installdir/var/serverconfig/local/tuning.properties

[ -s "$memfile" -a -r "$memfile" ] && {
eval `tr -d '\\\\' <"$memfile" | egrep -v "^[ 	]*#|'|^tarantella\.config\.(name|type)=" | sed "/=/!d
:dotloop
s/^\([^=]*\)\.\([^=]*=.*\)\$/\1_\2/
tdotloop
s/^\([^=]*\)=\(.*\)/\1='\2'/"`
}


memval=${tarantella_config_tuning_heapsize_max:-16}

# echo Previous memory was $memval

if [ ${tarantella_config_tuning_initialised:-0} = 0 ] ; then 
    MINMEM=58
    # maximim tested
    MAXMEM=96
    MAXOBJ=5000

    diff=`expr $MAXMEM \- $MINMEM`

    # enterprise database object count
    count=`find $installdir/var/ens -type f -name .object -print | wc -l`

    # assume linear scaling of memory space
    estmemval=`expr $count \* $diff \/ $MAXOBJ`
    estmemval=`expr $estmemval + $MINMEM`

    # TODO: take into account max session and webtop connections (watermarks)
    if [ $estmemval -gt $memval  ] ; then
	memval=$estmemval
    fi
    sed "s/^tarantella.config.tuning.initialised=.*/tarantella.config.tuning.initialised=1/" $memfile > $memfile.tmp.1
else
    cp $memfile $memfile.tmp.1
fi

initialheap=${tarantella_config_tuning_heapsize_initial:-12}

if [ $initialheap -gt $memval ] ; then
   memval=$initialheap
fi

if [ $memval -gt ${tarantella_config_tuning_heapsize_absmax:=2048} ] ; then
    memval=$tarantella_config_tuning_heapsize_absmax
fi

sed "s/^tarantella.config.tuning.heapsize.max=.*/tarantella.config.tuning.heapsize.max=$memval/" $memfile.tmp.1 > $memfile.tmp

rm $memfile.tmp.1

mv -f $memfile.tmp $memfile

# echo "Starting Jserver with $initialheap Mb, maximum $memval Mb"



getChildrenOfPid() 
{
## Warning - the following code is Linux specific.  (And if 
## /proc/<pid>/exe changes, will break)
## PS: It was changed. And it did break. [Fitz 605468]
ppid="$1"
exepattern="$2"
exclpattern="$3"
childrenpids=""
# Get children of ppid
ALLCHILDPIDS=`echo "$ps_output" | grep "^ *$ppid " | awk '{ print $2 }'`

if [ -z "$exepattern" ] ; then 
    childrenpids="$ALLCHILDPIDS" 
else 
    if [ ! -z "$ALLCHILDPIDS" ] ; then 
	for p in $ALLCHILDPIDS ; do
	    # is the executable one we worry about?
	    if [ -n "`find /proc/$p -name exe -lname \"$exepattern\" 2>/dev/null | sort | sed 1q`" ] ; then
		# yes 
                if [ -z "$exclpattern" ]; then
                    childrenpids="$childrenpids $p"
                else
                    check=`ps --noheading --pid $p -ww -o args | egrep -- "$exclpattern"`
                    [ -z "$check" ] && childrenpids="$childrenpids $p"
                fi
	    fi
	done
    fi
fi
echo $childrenpids
}

removeSurplusJVMs() 
{
# this will kill any instances of our JVM whose parent is init.
case "$SCOARCH" in
    i3li*|ppli*)
	## cache the output of ps, as it may be called several times, and can
	## be slow.
	ps_output=`ps --no-heading -ax -o ppid,pid 2>/dev/null`
	
	PIDSTOKILL=""
	PPIDS=`getChildrenOfPid 1 "$TTABINDIR/j*" "-classpath[ :]*$TTADIR/webserver"`
	while [ ! -z "$PPIDS" ] ; do
	    CHILDPIDS=""
	    PIDSTOKILL="$PIDSTOKILL $PPIDS"
	    for pp in $PPIDS ; do 
		CHILDPIDS="$CHILDPIDS `getChildrenOfPid $pp`"
	    done
	    PPIDS="$CHILDPIDS"
	done
	if [ ! -z "$PIDSTOKILL" ] ; then 
	    for p in $PIDSTOKILL ; do 
		if [ -d /proc/$p ] ; then 
		    kill $p 2>/dev/null
		    # give it time to exit
		    sleep 1
		    if [ -d /proc/$p ]; then
			kill -9 $p 2>/dev/null
			echo -n "(Using SIGKILL)"
		    fi
		echo "Killed pid $p (surplus JVM thread)"
		fi
	    done
	fi
	;;
esac
}



# due to SIGCHILD handling, we need to do this in the foreground

# Set the $TTABINDIR to the correct value.
cwd=`pwd`
cd $TTABINDIR/..
TTABINDIR=`pwd`
cd $cwd

removeSurplusJVMs

# Create a secure key for web login
webauthfile=$installdir/var/serverconfig/global/webauth.properties

dokeygeneration=`grep 'tarantella.config.login.webauth.refreshkeyonwarmrestart' < $webauthfile | cut -d= -f2-`

if [ -n "$dokeygeneration" ] && [  "$dokeygeneration" -eq 1 ]; then
  touch $installdir/var/info/weblogin.key
  chmod 600 $installdir/var/info/weblogin.key
  $installdir/bin/bin/ttarandom --keysize 16 > $installdir/var/info/weblogin.key
fi

# Create the watchers directory, if it doesn't exist
watcher_dir="$installdir/var/watchers"
if [ ! -d "$watcher_dir" ]
then
    mkdir "$watcher_dir"
    chmod 750 "$watcher_dir"
fi

# Stop the JServer from exiting on HUP signals
trap "" 1

# (Note - we don't use the $execcommand construct here, as we need an exec and
# our parent is the ttaauxserv, not init)

exec ${SGD_JAVA_DIR}/java $RUNTIME_ARGS -Djava.library.path=$installdir/lib -classpath $CLASSPATH -mx"$memval"m -ms"$initialheap"m \
     -Dlog4j.configuration=file:$installdir/bin/java/log4j.properties \
     $RUNTIME_ARGS $JAVA_SYSTEM_PROPERTIES $TTA_USER_CMD \
     TTAServer externalport=$externalport secureport=$secureport \
     peerport=$peerport auxport=$auxport \
     peerhost=$peerhost auxhost=$auxhost \
     installdir=$installdir pid=$$ "$@"
