#!/bin/bash
# Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
#
# Component: SGD server startup script
#

RESET_SGD_JAVA_HOME=1

. "common-env.sh"
. "common.sh"

# This is a generic product script used to establish an environment
# before starting/stopping a product or component.
# This script was built from shell library
#   $Id$
# This script has to run on every platform we support.  Any suggestions
# for improvement are welcome (but must be portable!)

# Version numbers
PRODUCT_VERSION="5.60.514"
PRODUCT_VERSION_FULL="5.60.514"
PRODUCT_VERSION_MAJOR=5
PRODUCT_VERSION_FEATURE=6
PRODUCT_VERSION_BUG=0
PRODUCT_VERSION_BUILD=514
PRODUCT_VERSION_BUILD_DECIMAL=514
PRODUCT_VERSION_AS_NUMBER=560514
PRODUCT_VERSION_CAB=5,6,0,514
PRODUCT_VERSION_RPM=5.60-514

# Product names
PRODUCT_FULL_NAME="Oracle Secure Global Desktop"
PRODUCT_SHORT_NAME="Secure Global Desktop"
PRODUCT_IDENT="SSGD"
PRODUCT_SHORT_FILENAME="Tarantella"
PRODUCT_LSBSCRIPTNAME="sun.com-sgd-base"
PRODUCT_LSBSCRIPT_RUN_LEVEL="90"
TSP_FULL_NAME="Oracle Secure Global Desktop Security Pack"
TSP_SHORT_NAME="Security Pack"
WCP_FULL_NAME="Oracle Secure Global Desktop Windows Connectivity Pack"
WCP_SHORT_NAME="Windows Connectivity Pack"
TN3270_FULL_NAME="Oracle Secure Global Desktop Mainframe Connectivity Pack"
TN3270_SHORT_NAME="Mainframe Connectivity Pack"
AS400_FULL_NAME="Oracle Secure Global Desktop AS/400 Connectivity Pack"
AS400_SHORT_NAME="AS/400 Connectivity Pack"
S1PSTK_FULL_NAME="Oracle Secure Global Desktop Channel for Sun ONE Portal Server"
S1PSIP_FULL_NAME="Oracle Secure Global Desktop Integration Pack for Sun ONE Portal Server"
S1PSTK_SHORT_NAME="Secure Global Desktop Channel for Sun ONE Portal Server"
S1PSIP_SHORT_NAME="Secure Global Desktop Integration Pack for Sun ONE Portal Server"

OBJECT_MGR_NAME="Object Manager"
ARRAY_MGR_NAME="Array Manager"
NATIVE_WIN16_FULL_NAME="Oracle Secure Global Desktop Native Client for Windows 3.1"
NATIVE_WIN16_SHORT_NAME="Native Client for Windows 3.1"
NATIVE_WIN32_FULL_NAME="Oracle Secure Global Desktop Native Client for Windows 95, 98 and NT"
NATIVE_WIN32_SHORT_NAME="Native Client for Windows 95, 98 and NT"
NATIVE_WYSE_FULL_NAME="Oracle Secure Global Desktop Native Client for Wyse"
NATIVE_WYSE_SHORT_NAME="Native Client for Wyse"
NATIVE_FULL_NAME="Oracle Secure Global Desktop Native Client"
NATIVE_SHORT_NAME="Native Client"
NATIVE_REGISTRY_NAME="Tarantella Native Client"
INTCLI_FULL_NAME="Oracle Secure Global Desktop Client"
INTCLI_SHORT_NAME="Client"
TCC_FULL_NAME="Oracle Secure Global Desktop Client"
TCC_HELPER_NAME="Oracle Secure Global Desktop Client Helper"
TCC_ACTIVEX_NAME="Oracle Secure Global Desktop ActiveX Control"
TCC_PLUGIN_NAME="Oracle Secure Global Desktop Netscape Plug-in"
T3COMPONENT_WIN_NAME="Oracle Secure Global Desktop Enhancement Module for Windows"
T3COMPONENT_UNIX_NAME="Oracle Secure Global Desktop Enhancement Module for UNIX(TM) and Linux Platforms"
T3COMPONENT_SHORT_UNIX_NAME="tem"
T3COMPONENT_NAME="Oracle Secure Global Desktop Enhancement Module"
T3COMPONENT_LSBSCRIPTNAME="sun.com-sgd-em"
T3COMPONENT_LSBSCRIPT_RUN_LEVEL="90"
GWCOMPONENT_UNIX_NAME="Oracle Secure Global Desktop Gateway for UNIX(TM) and Linux Platforms"
GWCOMPONENT_NAME="Oracle Secure Global Desktop Gateway"
GWCOMPONENT_SHORTNAME="SGD Gateway"
GWCOMPONENT_LSBSCRIPTNAME="sun.com-sgd-gw"
GWCOMPONENT_LSBSCRIPT_RUN_LEVEL="91"

# Watch the length of these names: IE refuses to remove packages if
# the name is too long.
ARCHIVE_NAME_ttalw="TCC Helper, version"
ARCHIVE_NAME_asad="3.x Framework Java Archive"
#ARCHIVE_NAME_tta="3.x Java Archive"
#ARCHIVE_NAME_tta="3.x Combined Java Archive"
ARCHIVE_NAME_tta="Client, "
ARCHIVE_NAME_tsp="3.x Security Java Archive"
ARCHIVE_NAME_proxy="3.x Proxy Java Archive"
WEBSTART_JAR_NAME="sgdwscs"
ARCHIVE_SUFFIX="K"

NS_REGKEY="java/download/com/tarantella/tta"

PRODUCT_VENDOR="Oracle Corporation, Inc."
PRODUCT_SHORT_VENDOR="Oracle"

# Capabilities:
# The format for the capabilities required by the client end of a
# connection is: CAPABILITIES_protocol_type_REQUIRED="expression"

# The format for the capabilities provided by the server end of a
# connection is: CAPABILITIES_protocol_type_PROVIDED="c1 c2 ... c3"

# Asad between a webtop client and server:
CAPABILITIES_ASAD_WEBTOPCLIENT_REQUIRED="(1.1 || 1.2)"
CAPABILITIES_ASAD_WEBTOPCLIENT_PROVIDED="1.1 1.2"

# Asad between two peer servers, or an admin tool and a server:
# 1.1 is core E3 array functionality.
# 1.2 is 3.01 array interoperability functionality.
# 2.1 is core Pisa client device mapping functionality (not a requirement)
CAPABILITIES_ASAD_PEER_REQUIRED="(1.1 || 1.2)"
CAPABILITIES_ASAD_PEER_PROVIDED="1.1 1.2 2.1"

# Client versions of server strings; same format, name prefixed by CLIENT
# Asad between a webtop client and server:
CLIENTCAPABILITIES_ASAD_WEBTOPCLIENT_REQUIRED="(1.1 || 1.2)"
CLIENTCAPABILITIES_ASAD_WEBTOPCLIENT_PROVIDED="1.1 1.2"

# Top-level item names in ENS datastore
DEFAULT_ROOT_ENS="organization"
SYSTEM_ROOT_ENS="Tarantella System Objects"
APP_ROOT_ENS="applications"
APPSERVER_ROOT_ENS="appservers"

WEB_SERVICES_VERSION=1.9


if [ -f $TTAMSG/common -a -f $TTAMSG/tta_start ]; then
  . $TTAMSG/common
  . $TTAMSG/tta_start
else
  echo "Unable to open message file: $TTAMSG/tta_start"
  exit 1
fi


xflag=""; case "$trace" in x|X) set -x; xflag="-x";; esac


# Environment configuration
# SGD_START_COREFILES   1 iff core files should be enabled.
# SGD_START_OPTS        Additional options to ttaauxserv execution.


### Constants ###

SUBSVC_SGD=sgd
SUBSVC_CDM=cdm
SUBSVC_WEBSERVER=webserver

EXIT_SUCCESS=0
EXIT_INVALID_USAGE=1



### Local Functions ###

# $1 - exit code
function ExitUsage()
{
    echo "${lf_usage}" 1>&2
    exit $1
}

function ExitInvalidUsage()
{
    echo "${l_invalid_arg1}$1${l_invalid_arg2}" 1>&2
    echo "${sf_usage}" 1>&2
    exit ${EXIT_INVALID_USAGE}
}


# Parse the command line arguments
# Accepted syntaxes:
#     1) tarantella start
#     2) tarantella start --help
# Deprecated syntaxes:
#     3) tarantella start cdm | sgd | webserver [--http | --https] [--servlet]
#     4) tarantella start [--http | --https] [--servlet]
# Internal:
#     5) tarantella start --debug
#
# Input parameters:
#     $0 ...  Command line parameters.
#
# Output globals:
#     opt_subservice - the subservice to start (sgd, webserver) or empty (both)
#     opt_ishelp     - true iff --help is specified
#     opt_isdebug    - true iff --debug is specified [internal]
#     opt_ishttp     - true iff --http is specified [deprecated]
#     opt_ishttps    - true iff --https is specified [deprecated]
#     opt_isservlet  - true iff --servlet is specified [deprecated]
#     
# Returns: An exit code
#     EXIT_SUCCESS        on success
#     EXIT_INVALID_USAGE  if a syntax error is encountered
# 
function ParseOptions()
{
    opt_subservice=
    opt_ishelp=false
    opt_isdebug=false
    opt_ishttp=false
    opt_ishttps=false
    opt_isservlet=false

    case "$1" in
        # all subservices are deprecated
        sgd|webserver)
            opt_subservice="$1"
            shift
            ;;
    esac

    local http_or_https=
    while [ $# -gt 0 ]
    do
        case "$1" in
            --help)
                opt_ishelp=true
                return $EXIT_SUCCESS
                ;;
            --debug)
                opt_isdebug=true
                ;;
            --http|--https|--servlet)
                # Deprecated. Valid only for webserver start.
                [ -z "${opt_subservice}" -o \
                  "${opt_subservice}" = $SUBSVC_WEBSERVER ] ||
                    return $EXIT_INVALID_USAGE
                if [ "$1" != "--servlet" ]
                then
                     # Syntax only allows one of --http or --https
                     if [ -z "${http_or_https}" -o "${http_or_https}" = $1 ]
                     then
                         http_or_https=$1
                     else
                         return $EXIT_INVALID_USAGE
                     fi
                     [ "$1" = "--http" ] && opt_ishttp=true || opt_ishttps=true
                else
                     opt_isservlet=true
                fi
                ;;
            *)
                return $EXIT_INVALID_USAGE
                ;;
        esac
        shift
    done
    return $EXIT_SUCCESS
}


# Check whether a process is running
# Input Parameters:
#     $1 - pathname of pid file
#     $2 - pattern to look for in ps output
# Output globals:
#     ThePid
# Returns: 0 if running, else 1
function CheckPid()
{
    ThePid=`tail -1 "$1" 2>/dev/null | sed 's/ //g'`
    [ -n "${ThePid}" ] && \
    [ -n "`ps -fp${ThePid} 2>/dev/null | egrep \"$2\" | egrep -v egrep`" ] && \
        return 0
    return 1
}


# Check whether the pid files have old pids and delete as appropriate
# Input parameters:
#     $1 - pathname of pid file
#     $2 - pattern to look for in ps output
# Output globals:
#     ThePid
# Returns:
#     0  if running
#     1  if pid exists but not running
#     2  if the file does not exist or is empty
#     3  if multiple pids are running
function CheckPidFile()
{
    # ps output only gives limited characters in the command so truncate
    # the install directory if it's too long 
    match=`echo $2 | cut -c1-25`

    # Count the number of lines in the file 
    entries=`wc -l "$1" 2> /dev/null | awk '{print $1}'`
    if [ ! -s "$1" ]
    then
        # Delete an empty file
        rm -f "$1" 2> /dev/null 
        return 2;
    elif [ $entries -eq 1 ]
    then
        ThePid=`tail -1 "$1" 2>/dev/null | sed 's/ //g'`
        if [ -z "${ThePid}" ]
        then
            # No pid in the file  
            rm -f "$1" 2> /dev/null
            return 1 
        elif [ -n "`ps -fp${ThePid} 2>/dev/null | egrep \"$match\" | \
                       egrep -v egrep`" ]
        then
            # Single pid and the process is still running 
            return 0
        fi

        # The file exists but the process isn't one we expect 
        rm -f "$1" 2> /dev/null 
        return 1
    else
        # Multiple entries in the file - write all the pids for our processes
        # into a "running" file
        while read Pid
        do
            [ -n "`ps -fp${Pid} 2>/dev/null | egrep \"$match\" | \
                       egrep -v egrep`" ] && echo ${Pid} >> running
        done < $1

        if [ -s running ]
        then
            # Move the "running" file back to the correct location 
            mv -f running $1
            running_entries=`wc -l "$1" 2> /dev/null | awk '{print $1}'`
            ThePid=`tail -1 "$1" 2>/dev/null | sed 's/ //g'` 
            if [ $running_entries -eq 1 ]
            then
                # Single running process
                return 0 
            else
                # Multiple running processes
                return 3
            fi 
        else
            rm -f "$1" 2> /dev/null
            return 1
        fi
    fi
}


# Checks for a deployment script and validates that it contains the required
# functions.
# Input parameters:
#     $1 - SGD installation path
# Output globals:
#     deployment_script
function CheckDeploymentScript()
{
    local sgd_install_path="$1"

    deployment_script="`GetDeploymentScript "${sgd_install_path}"`"
    if [ $? -eq ${COMMON_EXIT_ERROR} ]
    then
        warn_on_error "${tta_start_no_deployment_script}"
        return ${COMMON_EXIT_ERROR}
    fi

    # Attempt to valid the deployment script
    ValidateDeploymentScript "${sgd_install_path}" "${deployment_script}"
    validated=$?
    
    if [ ${validated} -eq ${COMMON_RETURN_ERROR} ]
    then
        # Error - the deployment script is missing
        warn_on_error "${tta_start_missing_deployment_script}"
        return ${COMMON_EXIT_ERROR}
    elif [ ${validated} -ne ${COMMON_RETURN_TRUE} ]
    then
        # The deployment script is found but but is missing required functions.
        warn_on_error "${tta_start_invalid_deployment_script}"
    fi

    # The deployment script is available to use
    return ${COMMON_EXIT_SUCCESS}
}


# Determine is SGD server is currently running
# Input globals:
#     opt_subservice       The subserver (sgd, webserver) to start, or empty.
#     webserver_startopts  The webserver startup options.
#     install_dir          The SGD server installation path.
# Output:
#     stdout  Message indicating which processes are running (not localized).
# Returns:
#     0 server is running, 1 server is NOT running.
# Todo:
#     - Move messages out of this function and i18n
function ServerIsRunning()
{
    local RUNNING=1
    [ "${opt_subservice}" = ${SUBSVC_WEBSERVER} ] &&
    {
        # Do an Apache pid check unless we are *only* starting Tomcat
        # (ie. if $webserver_startopts contains only --servlet.)
        doCheckPid='t'
        case "${webserver_startopts}" in
            *--servlet*)
                case "${webserver_startopts}" in
                    *--http*) ;;
                    *)
                        doCheckPid=''
            esac
        esac
        [ -n "${doCheckPid}" ] &&
            CheckPid "${installdir}/webserver/apache/`cat ${installdir}/var/info/apacheversion`/logs/httpd.pid" "${installdir}" && \
        {
            echo "webserver pid ${ThePid} already running" >&2
            RUNNING=0
        }
    }
    [ -z "${TTA_CONFIGURE}" -a "${opt_subservice}" != ${SUBSVC_WEBSERVER} ] &&
    {
        CheckPidFile "${installdir}/var/info/auxserver.pid" "${installdir}"
        result=$?
        if [ $result -eq 0 -o $result -eq 3 ]
        then
            echo "auxserver pid ${ThePid} already running" >&2
            RUNNING=0
        fi

        [ "${RUNNING}" = 0 ] && return 0

        CheckPidFile "${installdir}/var/info/jserver.pid" "${installdir}/bin/java/jserver.jar"
        result=$?
        if [ $result -eq 0  -o $result -eq 3 ]
        then
            echo "jserver pid ${ThePid} already running" >&2
            RUNNING=0
        fi
    }
    return $RUNNING
}


# Start Instance Preparation.

# Determine if instance preparation is pending.
# The instance flags are evaluated using getconfig and not config list, for
# speed and safety. The server might not yet be in a coherent state, so config
# commands could fail or be slow.
#
# Output:
#     stdout  = 0  if no instance flags set or
#             > 0  when one or more flags set.
function PrepareInstanceIsRequired()
{
    local REQUIRE_PREFIX="--tarantella.config.server.template.instance.require"
    local REQUIRE_DHPARAMS_CONF="${REQUIRE_PREFIX}${DEPLOYCONF_DHPARAMS}"
    local REQUIRE_PASSWORD_CONF="${REQUIRE_PREFIX}${DEPLOYCONF_PASSWORD}"
    local REQUIRE_EXTERNALNAME_CONF="${REQUIRE_PREFIX}${DEPLOYCONF_EXTERNAL_NAME}"
    local REQUIRE_EXTERNALACCESSPORT_CONF="${REQUIRE_PREFIX}${DEPLOYCONF_EXTERNAL_PORT}"
  
    local INSTANCE_DHPARAMS_VALUE="`$TTADIR/bin/scripts/getconfig ${REQUIRE_DHPARAMS_CONF}`"
    local INSTANCE_PASSWORD_VALUE="`$TTADIR/bin/scripts/getconfig ${REQUIRE_PASSWORD_CONF}`"
    local INSTANCE_EXTERNALNAME_VALUE="`$TTADIR/bin/scripts/getconfig ${REQUIRE_EXTERNALNAME_CONF}`"
    local INSTANCE_EXTERNALACCESSPORT_VALUE="`$TTADIR/bin/scripts/getconfig ${REQUIRE_EXTERNALACCESSPORT_CONF}`"

    # Guard against non-numeric values # 
    # Valid values 1 = true, 0 = false #
    [ -z "`isNumber ${INSTANCE_DHPARAMS_VALUE}`" ] &&
    {
        INSTANCE_DHPARAMS_VALUE=0
    }

    [ -z "`isNumber ${INSTANCE_PASSWORD_VALUE}`" ] &&
    {
        INSTANCE_PASSWORD_VALUE=0
    }

    [ -z "`isNumber ${INSTANCE_EXTERNALNAME_VALUE}`" ] &&
    {
        INSTANCE_EXTERNALNAME_VALUE=0
    }

    [ -z "`isNumber ${INSTANCE_EXTERNALACCESSPORT_VALUE}`" ] &&
    {
        INSTANCE_EXTERNALACCESSPORT_VALUE=0
    }

    echo `expr $INSTANCE_DHPARAMS_VALUE + $INSTANCE_PASSWORD_VALUE + $INSTANCE_EXTERNALNAME_VALUE + $INSTANCE_EXTERNALACCESSPORT_VALUE`
}


# Get the arguments for the prepare instance command from the configured
# deployment values.
# Output:
#     stdout  the arguments to use for "prepare instance"
function PrepareInstanceGetArgs()
{
    local req_externalname="`getServerConfig "template.image.require${DEPLOYCONF_EXTERNAL_NAME}"`"
    if [ "${req_externalname}" = "1" ]
    then
        new_external_name="`GetDeploymentValue "${TTADIR}" "${DEPLOYCONF_EXTERNAL_NAME}"`"
        if [ $? -eq 0 -a -n "${new_external_name}" ]
        then
            instance_args="--external-name ${new_external_name}"
        fi
    fi

    local req_externalaccessport="`getServerConfig "template.image.require${DEPLOYCONF_EXTERNAL_PORT}"`"
    if [ "${req_externalaccessport}" = "1" ]
    then
        new_external_access_port="`GetDeploymentValue "${TTADIR}" "${DEPLOYCONF_EXTERNAL_PORT}"`"
        if [ $? -eq 0 -a -n "${new_external_access_port}" ]
        then
            instance_args="${instance_args} --external-access-port ${new_external_access_port}"
        fi
    fi

    local req_password="`getServerConfig "template.image.require${DEPLOYCONF_PASSWORD}"`"
    if [ "${req_password}" = "1" ]
    then
        new_admin_passwd="`GetDeploymentValue "${TTADIR}" "${DEPLOYCONF_PASSWORD}"`"
        if [ $? -eq 0 -a -n "${new_admin_passwd}" ]
        then
            instance_args="${instance_args} --deployment-script ${deployment_script}"
        fi
        unset new_admin_passwd
    fi

    local req_dhparams="`getServerConfig "template.image.require${DEPLOYCONF_DHPARAMS}"`"
    if [ "${req_dhparams}" = "1" ]
    then
        disable_dh_params="`GetDeploymentValue "${TTADIR}" "${DEPLOYCONF_DHPARAMS}"`"
        if [ $? -eq 0 -a "${disable_dh_params}" = "true" ]
        then
            instance_args="${instance_args} --no-dhparam-regen"
        fi
    fi

    # If we have some instance args, output them to stdout.
    if [ -n "${instance_args}" ]
    then
        echo "${instance_args}"
    fi
}


# Prepare instance.
# TTA_CONFIGURE checked as a precaution, ServerPrepareInstanceIsRequired
# shouldn't return anything other than 0 at install time.
# "prepare instance" should never be run on a non configured installed.
# TODO:
#     1. TODO POSTINSTALL REMOVE - remove TTA_CONFIGURE check?
#     2. TODO POSTINSTALL REMOVE - add task: test prepare. should start prompt
#     3. TODO function should not exit directly
function PrepareInstance()
{
    local instance_args=""
    if [ "`PrepareInstanceIsRequired`" -gt 0 ]
    then
        # Check if we have a deployment script available
        CheckDeploymentScript "${TTADIR}"
        check_completed=$?

        # If we have loaded a deployment script, get arguments for a prepare
        # instance call
        instance_args=""
        if [ ${check_completed} -eq ${COMMON_EXIT_SUCCESS} ]
        then
            instance_args="`PrepareInstanceGetArgs`"
        fi

        # Check if script is being run from a non-interactive context
        # we assume interactivity i.e. admin can be prompted. Unless
        # caller sets otherwise, by setting the no-prepare option.
        if [ -n "${no_prepare}" ]
        then
            # Non-Interactive - Make sure "prepare instance" call doesn't prompt
            instance_args="${instance_args} --no-prompt"
        fi

        # Run prepare instance and attempt to auto configure using deployment script values
        $TTADIR/bin/tarantella prepare instance ${instance_args} >&2
        exit_on_error "${tta_start_prep_instance_fail}" $?

        #  Have all required values been set? If not, exit and need to run start manually.
        if [ "`PrepareInstanceIsRequired`" -gt 0 ]
        then
            # Need to run start manually so admin can be prompted for missing information
            echo "${tta_start_instance_prep_req}" >&2
            exit_on_error "${tta_start_run_manaully}"
        fi
    fi
}

# End Instance Preparation.


# TODO POSTINSTALL REMOVE - all initial configuration in this section?
# Begin initial configuration

function DoSecurityEnable()
{
    exec 8>&1 9>&2; SGD_STARTLOOP="8:9" export SGD_STARTLOOP  # save stdout/err
    ${INSTDIR}/bin/tarantella security enable --quiet --firewalltraversal 0 ${InstSecureArgs} >>${INSTDIR}/var/log/setup.log 2>&1
    exec 8>&- 9>&-; unset SGD_STARTLOOP       # restore stdout/err
}


# Prints the full path to `httpd.conf`.
function GetApacheConfigPath()
{
    read apacheversion < $installdir/var/info/apacheversion
    echo "${installdir}/webserver/apache/${apacheversion}/conf/httpd.conf"
    return 0
}


function DoGenerateSelfSignedCertificates()
{
    T="${INSTDIR}/bin/tarantella"
    TSPDIR="${INSTDIR}/var/tsp"

    # Make sure certificates don't exist already
    if [ -s "${TSPDIR}/csr.pem" -o -s "${TSPDIR}/cert.pem" -o -s "${TSPDIR}/key.pem" -o -s "${TSPDIR}/key.pending.pem" ]
    then
        return 0
    fi

    # Request certificate
    $T security certrequest \
        --orgname "${PRODUCT_VENDOR}" --country US \
        --state CA </dev/null >>"${INSTDIR}/var/log/setup.log" 2>&1
    if [ $? -ne 0 ]
    then
        exit_on_error "security certrequest failed: status=${ret}"
    fi

    # Self-sign certificate
    $T security selfsign >>"${INSTDIR}/var/log/setup.log" 2>&1
    if [ $? -ne 0 ]
    then
        exit_on_error "security selfsign failed: status=${ret}"
    fi

    # Set certificate as its own root
    $T security customca --rootfile "${TSPDIR}/cert.pem" >>"${INSTDIR}/var/log/setup.log" 2>&1
    if [ $? -ne 0 ]
    then
        exit_on_error "security customca failed: status=${ret}"
    fi

    # Copy certificates and keys with ".ss" extension
    for pem in ca.pem cert.pem csr.pem key.pem key.pending.pem
    do
        if [ -s "${TSPDIR}/${pem}" ]
        then
            cp -p "${TSPDIR}/${pem}" "${CERTDIR}/${pem}.ss"
        fi
    done
}


function DoGenerateMobileTLSProfile()
{
    TSPDIR="${INSTDIR}/var/tsp"

    # create h5c configuration profiles and related folders
    profile_dir="${INSTDIR}/var/docroot/certs"

    if [ ! -d "${profile_dir}" ]; then
      mkdir -p "${profile_dir}"
      chgrp ${privgrp} "${profile_dir}"
      chmod 750 "${profile_dir}"
    fi

    cert_dir="${TSPDIR}/certs"
    gw_cert_dir="${cert_dir}/gateway"
    sgd_cert_dir="${cert_dir}/array"
    hostname_with_dashes="`echo ${HOSTNAME} | sed 's|\.|-|g'`"

    if [ ! -d "${sgd_cert_dir}" ]
    then
        mkdir -p "${sgd_cert_dir}"
    fi
    if [ ! -d "${gw_cert_dir}" ]
    then
        mkdir -p "${gw_cert_dir}"
    fi

    chmod -R 751 "${cert_dir}"

    if [ -f "${TSPDIR}/cert.pem" ]
    then
        if [ -f "${sgd_cert_dir}/${hostname_with_dashes}.pem" ]
        then
            rm -f "${sgd_cert_dir}/${hostname_with_dashes}.pem"
        fi
        ln -s "${TSPDIR}/cert.pem" "${sgd_cert_dir}/${hostname_with_dashes}.pem"
    fi

    chown -R ${privusr} "${cert_dir}"
    chgrp -R ${privgrp} "${cert_dir}"

    # Create a mobile profile  (using a temporary DNS)
    hostname=`$TTADIR/bin/scripts/getconfig --peerdns`
    echo "${hostname}" > "${installdir}/var/info/primary"
    "${TTADIR}/bin/scripts/mobile_profile_create.sh" --quiet 
    rm "${installdir}/var/info/primary"
}


# Configure server prior to initial startup.
#
# Input globals:
#     install_dir  The SGD installation path.
# Output globals:
#     InstSecure
#     InstSecureAlready
# Output environment:
#     INSTDIR
# To do:
#    TODO POSTINSTALL REMOVE -- delete this function and usage, but set output
#                               globals?
function Configure()
{
    INSTDIR=$installdir export INSTDIR

    # Secure by default
    InstSecure='t'
    InstSecureAlready='t'
    
    # Generate self-signed TLS certificate and mobile profile
    DoGenerateSelfSignedCertificates
    DoGenerateMobileTLSProfile
    
    # Run postinstall scripts
    "${installdir}/bin/scripts/postinstall"
    
    # If postinstall returns an error exit now
    rVal=$?
    [ $rVal -ne 0 ] && exit
    find ${INSTDIR} -type d -print |
	egrep -v "${INSTDIR}/var/spool" |
	xargs chmod o-rw
    [ -s "${INSTDIR}/etc/pkg/tta/install/en-us_setup" ] && {
	# source localized messages
	. "${INSTDIR}/etc/pkg/tta/install/en-us_setup"
    }
}

# End initial configuration


# Autorename the server, if enabled.
# Returns:
#     0  Server was renamed
#     1  Server was not renamed
# To do:
#     1. Should not exit directly
function AutoRename()
{
    local autorename="`${TTADIR}/bin/scripts/getconfig --tarantella.config.server.autorenameonstart`"
    [ "${autorename}" != "1" ] && return 1

    # Get the peer and external DNS names to see if any changes are required
    local new_external_dns="`GetServerRenameExternal "${TTADIR}" "${GW_INSTALL_PATH}"`"
    local ext_changed=$?
    if [ ${ext_changed} -eq ${COMMON_RETURN_ERROR} ]
    then
        exit_on_error "${tta_start_missing_external}"
    fi
    
    local new_peer_dns="`GetServerRenamePeer "${TTADIR}"`"
    local peer_changed=$?
    if [ ${peer_changed} -eq ${COMMON_RETURN_ERROR} ]
    then
        exit_on_error "${tta_start_missing_peer}"
    fi

    # If either the external or peer DNS have changed, need to run serverrename
    if [ ${peer_changed} -eq ${COMMON_RETURN_TRUE} -o \
         ${ext_changed} -eq ${COMMON_RETURN_TRUE} ]
    then
        printf "${tta_start_server_rename}" "${new_peer_dns}" "${new_external_dns}"
        # Call the serverrename command
        ${TTADIR}/bin/tarantella serverrename --quiet \
            --extdns "${new_external_dns}" --peerdns "${new_peer_dns}" \
            >> "${installdir}/var/log/stderrout.log" 2>&1
        if [ $? -ne 0 ] 
        then
            # The rename has failed - abort the start
            exit_on_error "${tta_start_rename_failed}"
        fi
    fi

    return 0
}




### Main ###

# Process command line arguments
ParseOptions "$@" || ExitInvalidUsage $?
${opt_ishelp} && ExitUsage
webserver_startopts=""
${opt_ishttp}    && webserver_startopts="${webserver_startopts} --http --nossl"
${opt_ishttps}   && webserver_startopts="${webserver_startopts} --http --ssl"
${opt_isservlet} && webserver_startopts="${webserver_startopts} --servlet"


# TODO POSTINSTALL REMOVE
ans_host=`hostname`
if [ -f "$TTADIR/$ans_host.answers" ]
then
    . "$TTADIR/$ans_host.answers"
fi

# Make sure that they are running as root
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


# By default we don't want our server to drop core.
# COMMENT OUT THE FOLLOWING LINE IF YOU WANT THE SERVER TO DROP CORE FILES
[ "${SGD_START_COREFILES}" = 1 ] || ulimit -c 0

# 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 tta 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


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

ThePid=""

# TODO POSTINSTALL REMOVE - remove this declaration and all references?
TTA_CONFIGURE=`cat ${installdir}/var/configure 2>/dev/null`

# Check if SGD server is already running
[ -z "${TTA_CONFIGURE}" -o -f $installdir/var/configure_ws ] &&
    ServerIsRunning && exit 1

# Prepare instance, if required
[ -z "${TTA_CONFIGURE}" ] && PrepareInstance

# Get ${prvusr} and ${prvgrp}
GetPrivUsrGrp()
{
    cat $installdir/var/serverconfig/global/array.properties 2>/dev/null | awk -F= \
	'BEGIN { u="ttasys"; wu="ttaserv"; g="ttaserv" }
	$1 == "tarantella.config.array.privilegeduser" { u = $2 }
	$1 == "tarantella.config.array.webserveruser" { wu = $2 }
	$1 == "tarantella.config.array.privilegedgroup" { g = $2 }
	END { print u " " wu " " g }'
}
_privusrgrp=`GetPrivUsrGrp`
privusr=`expr "$_privusrgrp" : '\([^ ]*\) .*'`
webservusr=`expr "$_privusrgrp" : '.* \([^ ]*\) .*'`
privgrp=`expr "$_privusrgrp" : '.* \([^ ]*\)$'`


# Perform first-start configuration
# TODO POSTINSTALL REMOVE
InstSecure=''
InstSecureAlready=''
[ -n "${TTA_CONFIGURE}" ] && Configure

# Start webservers
[ -z "${opt_subservice}" -o "${opt_subservice}" = ${SUBSVC_WEBSERVER} ] &&
{
    ${TTADIR}/bin/scripts/webserver .start ${webserver_startopts}
    [ "${opt_subservice}" = ${SUBSVC_WEBSERVER} ] && exit $EXIT_SUCCESS
}


# Start server

# 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


MkTtaDir()
{
    _newdirs="" _pflag=""
    case "$1" in
    -p) _pflag="-p"; shift
    esac
    for _d in "$@"; do
	while [ -n "$_d" ]; do
	    [ -d "$_d" ] && break
	    _newdirs="$_newdirs $_d"
	    _d=`dirname $_d`
	done
    done
    mkdir $_pflag "$@"
    [ -n "$_newdirs" ] && { chgrp $privgrp $_newdirs 2>/dev/null; chown $privusr $_newdirs 2>/dev/null; }
}

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


# Create writeable log files for the lp/lpr interface script
#
(
    cd ${installdir}/var/log
    :>>print.log; :>>print_error.log; chmod 600 print.log print_error.log 2>/dev/null
)

# Pick a suitable JServer start script:
if ${opt_isdebug}
then
    jserver_script=$installdir/var/info/debugjserverstart
    # We'll be starting the JServer ourselves but need
    # to keep the ttaauxserv happy when it launches us:
    echo "#!/bin/sh\n# Dummy JServer wrapper\nwhile true; do sleep 30000; done" > $jserver_script
    chmod ug+x $jserver_script
else
    jserver_script=$installdir/bin/scripts/jserverstart
fi

# 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


# Set the PATH so that it will find an auxserver in the new TTA2 tree:
TTAAUXSERV=$installdir/bin/bin/ttaauxserv
[ ! -x "$TTAAUXSERV" ] && TTAAUXSERV=`echo $installdir/bin/????????/ttaauxserv`
[ ! -x "$TTAAUXSERV" ] && exit 1
TTABINDIR=`expr $TTAAUXSERV : '\(.*\)/ttaauxserv$'`

cwd=`pwd`
cd $TTABINDIR
TTABINDIR=`pwd`
cd $cwd

PATH=${PATH}:${TTABINDIR}
export PATH

# The server wants a umask of 077
umask 077

# Write port number files (auxport asadport secureport) etc
# This is for the benefit of the ttawebtop CGI-bin and for
# when we are in "--debug" mode, etc.
# The JServer start script gets them from its command line.
PORTSFILE="$installdir/var/info/ports.properties"

now=`date`
cat >"$PORTSFILE" <<EOF
# These port numbers reflect the state of the server when
# it was last run. This file is created each time the
# server starts, and reflects the server configuration
# which is not available to CGI-BIN programs.
# $now
externalport=$externalport
secureport=$secureport
peerport=$peerport
externalhost=$externalhost
proxiedhttpsurl=$proxiedhttpsurl
cgiverbose=$cgiverbose
archivemodifier=$archivemodifier
bootscript=$bootscript
routes=$routes
externalnames=$externalnames
EOF

# Make sure the ports file is world readable (for the benefit of CGI)
chmod 644 "$PORTSFILE"

# Create empty key.file with correct owner/group/permissions.
touch $installdir/var/info/key.file
chmod 640 $installdir/var/info/key.file
MkTtaDir $installdir/var/info 2>/dev/null
chown $privusr $installdir/var/info/key.file 2> /dev/null
chgrp $privgrp $installdir/var/info/key.file 2> /dev/null

# Create a secure key for web login
if [ -n "$webserveruser" ] &&
   [ -n "$privilegeduser" ] &&
   [ -n "$webauthrefresh" ] &&
   [ "$webauthrefresh" -eq 1 ]
then
    touch $installdir/var/info/weblogin.key
    chmod 600 $installdir/var/info/weblogin.key
    MkTtaDir $installdir/var/info 2>/dev/null
    chown $privusr $installdir/var/info/weblogin.key 2> /dev/null
    chgrp $privgrp $installdir/var/info/weblogin.key 2> /dev/null
    $installdir/bin/bin/ttarandom --keysize 16 > $installdir/var/info/weblogin.key
fi

if [ -n "$privilegeduser" ]
then
    # Stomp the ttasshhelper binary with the path and uid
    # If you need to be able to make ssh connections when starting
    # applications, and if your ssh client program is NOT in one
    # of these standard locations:
    #   /usr/local/bin/ssh
    #   /usr/bin/ssh
    #   /usr/sbin/ssh
    #   /usr/lbin/ssh
    #   /bin/ssh
    #   /sbin/ssh
    # you should uncomment the TTASSHCLIENT in the file below and set
    # it to point to the correct location.
    customssh="${installdir}/bin/scripts/install_scripts/custom_ssh"
    . "${customssh}"

   $installdir/bin/bin/ttasshhelperstomp --file $installdir/bin/bin/ttasshhelper --username $privilegeduser
fi

# Touch the start file with the current time.
date >$installdir/var/info/started

# touch lockfile so we'll get shutdown
[ -d /var/lock/subsys -a -n "${PRODUCT_LSBSCRIPTNAME}" ] && touch /var/lock/subsys/${PRODUCT_LSBSCRIPTNAME}

# Before we launch the proxy server we need to determine the minimum
# number of file descriptors required to run SGD.
# This value is a a tunable server config property
tuningfile=$installdir/var/serverconfig/local/tuning.properties
[ -s "$tuningfile" -a -r "$tuningfile" ] && {
eval `tr -d '\\\\' <"$tuningfile" | egrep -v "^[ 	]*#|'|^tarantella\.config\.(name|type)=" | sed "/=/!d
:dotloop
s/^\([^=]*\)\.\([^=]*=.*\)\$/\1_\2/
tdotloop
s/^\([^=]*\)=\(.*\)/\1='\2'/"`
}

tuningval=${tarantella_config_tuning_maxfds:-4096}
if [ $tuningval -lt 4096 ]
then
    tuningval=4096
fi

## we aren't going to start cdm unless it's enabled
cdmfile=$installdir/var/serverconfig/global/cdm.properties
[ -s "$cdmfile" -a -r "$cdmfile" ] && {
eval `tr -d '\\\\' <"$cdmfile" | egrep -v "^[ 	]*#|'|^tarantella\.config\.(name|type)=" | sed "/=/!d
:dotloop
s/^\([^=]*\)\.\([^=]*=.*\)\$/\1_\2/
tdotloop
s/^\([^=]*\)=\(.*\)/\1='\2'/"`
}

cdmval=${tarantella_config_cdm_enabled:-0}

case "$SCOARCH" in
    i3sc*) ;;
    *)
        # We do not want to run out of file descriptors. 4096 per process is
        # the minimum acceptable value.
        n_fds=`ulimit -n`
        case $n_fds in
            unlimited ) n_fds=$tuningval;;
            [0-9]* );;
            * ) n_fds=0;; #???
        esac
        [  $n_fds -lt $tuningval ] && ulimit -SHn $tuningval
esac

# Find the host properties file
  HOST=""
  _localbootprops="${installdir}/var/serverconfig/local/bootstrap.properties"
  [ -s "${_localbootprops}" ] && HOST=`sed -n '/server\.dns\.peer=/s/.*=//p' "${_localbootprops}" | tail -1`
  [ -z "${HOST}" ] && HOST=`${installdir}/bin/bin/ttahostname`

HostProps=${installdir}/var/serverconfig/global/${HOST}.properties

# Sort out file ownership
:>>${installdir}/var/info/auxserver.pid; chmod ug+r ${installdir}/var/info/auxserver.pid
:>>${installdir}/var/log/stderrout.log; chmod 600 ${installdir}/var/log/stderrout.log

FIXOWNERSHIP=${TMPDIR:-/tmp}/fix$$
    rm -rf ${FIXOWNERSHIP} 2>/dev/null
    find ${installdir}/var/info ${installdir}/var/log ${installdir}/var/tmp \( ! -group $privgrp \) \( ! -type l \) -print >${FIXOWNERSHIP}
    find ${installdir}/var/info ${installdir}/var/log ${installdir}/var/tmp \( ! -group $privgrp \) -type l -print |
    xargs ls -ld |
    awk 'BEGIN {
	INCLUDE = "'"${installdir}"'"
	INCLUDELEN = length(INCLUDE)
	EXCLUDE = "'"_DUMMY_"'"
	EXCLUDELEN = length(EXCLUDE)
    }
    substr($NF,1,EXCLUDELEN) == EXCLUDE {
	next
    }
    substr($NF,1,1) != "/" || substr($NF,1,INCLUDELEN) == INCLUDE {
	src = NF-2
	print $src
    }' >>${FIXOWNERSHIP}

[ -s "${FIXOWNERSHIP}" ] && xargs chgrp $privgrp <${FIXOWNERSHIP} 2>/dev/null
    rm -rf ${FIXOWNERSHIP} 2>/dev/null
    find ${installdir}/var/info ${installdir}/var/log ${installdir}/var/tmp \( ! -user $privusr \) \( ! -type l \) -print >${FIXOWNERSHIP}
    find ${installdir}/var/info ${installdir}/var/log ${installdir}/var/tmp \( ! -user $privusr \) -type l -print |
    xargs ls -ld |
    awk 'BEGIN {
	INCLUDE = "'"${installdir}"'"
	INCLUDELEN = length(INCLUDE)
	EXCLUDE = "'"_DUMMY_"'"
	EXCLUDELEN = length(EXCLUDE)
    }
    substr($NF,1,EXCLUDELEN) == EXCLUDE {
	next
    }
    substr($NF,1,1) != "/" || substr($NF,1,INCLUDELEN) == INCLUDE {
	src = NF-2
	print $src
    }' >>${FIXOWNERSHIP}

[ -s "${FIXOWNERSHIP}" ] && xargs chown $privusr <${FIXOWNERSHIP} 2>/dev/null
rm -rf ${FIXOWNERSHIP} 2>/dev/null


GetLocalHTTPUrl()
{
    apacheconfig=`GetApacheConfigPath`
    apache_port=`awk '/^Listen[ 	][ 	]*[0-9]/{print $2;exit}' ${apacheconfig}`

    case "${apache_port}" in
        *:*)  hostname=`expr  "${apache_port}" : '\(.*\):.*'`
	      apache_port=`expr "${apache_port}" : '.*:\(.*\)'` ;;
        *)    # Get the sgd server name
	      hostname=`$TTADIR/bin/scripts/getconfig --extdns`
        esac

    echo "http://localhost:${apache_port}"

    return 0
}

# now we can run the server
# list of properties file includes the host.properties file
vsg="${installdir}/var/serverconfig/global" vsl="${installdir}/var/serverconfig/local"
arg0="${TTABINDIR}/ttaauxserv"
arg1="INSTALLDIR=$installdir"
arg2="PEERHOST=$peerhost"
arg3="${vsg}/bootstrap.properties ${vsg}/array.properties ${vsg}/cdm.properties `echo ${vsl}/*.properties` ${HostProps} ${jserver_script}"
case "${SGD_STARTLOOP}" in
    *:*)
        orig_stdout=`expr "${SGD_STARTLOOP}" : '\(.*\):.*'`
        orig_stderr=`expr "${SGD_STARTLOOP}" : '.*:\(.*\)'`
        unset SGD_STARTLOOP
        if [ -t 0 ]
        then
            # stdin is a terminal
            ${_setsid} "${arg0}" "${arg1}" "${arg2}" ${arg3} "${SGD_START_OPTS}" >&0 2>&0
        else
            # stdin is not a terminal
            ${_setsid} "${arg0}" "${arg1}" "${arg2}" ${arg3} "${SGD_START_OPTS}" >/dev/null 2>&1
        fi
        ;;
    *)
        ${_setsid} "${arg0}" "${arg1}" "${arg2}" ${arg3} "${SGD_START_OPTS}"
esac

tta_exit_code=$?

case "$tta_exit_code" in
    0)  # success
        if [ -n "${TTA_DEVINSTALL}" ]
        then
            DEFAULTPROFILE_FLAG="${installdir}/var/tmp/defaultprofile.tmp"
            [ -f ${DEFAULTPROFILE_FLAG} ] &&
            {
                DEFAULTPROFILE=".../_ens/o=Tarantella System Objects/_service/sco/tta/resources/Default"
                TTA_SESSIONIDFILE="${installdir}/var/info/soapsession.sid"
                TTA_URL=`GetLocalHTTPUrl`
                read tomcatversion < "${installdir}/var/info/tomcatversion"
                tomcatpath="${installdir}/webserver/tomcat/${tomcatversion}" 
                ${SGD_JAVA_DIR}/java $RUNTIME_ARGS -Djava.library.path=${installdir}/lib -classpath ${CLASSPATH}:"${tomcatpath}/webapps/sgd/WEB-INF/lib/activation.jar":"${tomcatpath}/webapps/sgd/WEB-INF/lib/mail.jar":"${tomcatpath}/webapps/sgd/WEB-INF/lib/sgd-webservices.jar":"${tomcatpath}/shared/classes" -mx54m -ms24m -noclassgc $RUNTIME_ARGS $JAVA_SYSTEM_PROPERTIES com.tarantella.tta.webservices.client.apps.util.createProfile $TTA_SESSIONIDFILE $TTA_URL "${DEFAULTPROFILE}"
                rm -f "${DEFAULTPROFILE_FLAG}" 2>/dev/null
            }
         fi
        ;;
    12) # Log file error
        exit_on_error "$tta_start_log_file_error" $tta_exit_code
        ;;
    13) # Unlicensed   TODO POSTINSTALL REMOVE
        # this is logged as a fatal error, so no need to print out anything here.
       exit $tta_exit_code
    ;;
    14) # server already started
        exit_on_error "$tta_start_already_running" $tta_exit_code
        ;;
    *)  # unknown
        exit $tta_exit_code
esac

[ -f ${installdir}/var/postpostinstall ] &&
{
#    This block of operations is for upgrades from SGD 4.6x.  Direct upgrades from those versions are not supported.
#    [ -n "`grep '^HELP_ja_cleanup$' ${installdir}/var/postpostinstall 2>/dev/null`" ] && \
#	/bin/sh ${xflag} ${installdir}/bin/scripts/install_scripts/postpostinstall --peerport ${peerport:-5427} HELP_ja_cleanup >>${installdir}/var/log/setup.log
#    [ -n "`grep '^RmDriveLetter$' ${installdir}/var/postpostinstall 2>/dev/null`" ] && \
#	/bin/sh ${xflag} ${installdir}/bin/scripts/install_scripts/postpostinstall --peerport ${peerport:-5427} RmDriveLetter >>${installdir}/var/log/setup.log
#    [ -n "`grep '^UpgradeLegacyVDIBrokers$' ${installdir}/var/postpostinstall 2>/dev/null`" ] && \
#	/bin/sh ${xflag} ${installdir}/bin/scripts/install_scripts/postpostinstall --peerport ${peerport:-5427} UpgradeLegacyVDIBrokers >>${installdir}/var/log/setup.log
#    [ -n "`grep '^AddCustomLaunchControlsDefaults$' ${installdir}/var/postpostinstall 2>/dev/null`" ] && \
#	/bin/sh ${xflag} ${installdir}/bin/scripts/install_scripts/postpostinstall --peerport ${peerport:-5427} AddCustomLaunchControlsDefaults >>${installdir}/var/log/setup.log

    rm -f ${installdir}/var/postpostinstall 2>/dev/null
}

# Flag the running server as up-to-date (upgrade state is HOT)
. ${installdir}/bin/scripts/upgrade
sgd_upgrade_state_set HOT

# successfully started
GoodInstall=''
if [ -z "${i18n_pf1_instsuccess}" ]
then
    echo $tta_start_successful
else
    MACHINEARCH="${SCOARCH}"
N=""
C=""
if echo -n | grep n > /dev/null
then
  C="\c"
else
  N="-n"
fi
case "$MACHINEARCH" in
i3li*|ppli*) N="$N -e" ;;
esac
_ss_headlines="--------------------------------------------------------------------------"

    GoodInstall=`printf "\n\n"; echo $N "${p_74}$C"; printf "${i18n_pf1_instsuccess}" "${PRODUCT_FULL_NAME}"; echo $N "${p_74}$C"`
fi

#Make sure the certificates in the host file are up to date
$installdir/bin/tarantella security setrootcerts

## the local disk access may want starting now
## just check for unixenabled once rdp cdm is implemented
#cdm_enabled=0
#[ $tarantella_config_cdm_unixenabled = 1 ] || [ $tarantella_config_cdm_windowsenabled = 1 ] && cdm_enabled=1

if [ ${tarantella_config_cdm_unixenabled:-0} = 1 -a \
     -x $TTADIR/bin/scripts/start_cdm ]
then
    ${_setsid} $TTADIR/bin/scripts/start_cdm --quiet
    cdm_exit_code=$?
    case "$cdm_exit_code" in
        0|1|2)
            # a valid return code
            ;;
        *)
            # an unexpected error
            exit_on_error "$tta_start_cdm_failed" 255
            ;;
    esac
fi

# enable TTA printer, unless printing services have been stopped
if [ -n "${HostProps}" ] &&
   [ -n "`grep 'tarantella.config.host.localprinting.status=2' ${HostProps}`" ]
then
    :
else
    ${TTADIR}/bin/scripts/lpenable >/dev/null 2>&1
fi

# Find out whether we are secure already (on upgrade) with a self-signed cert that may need refreshing
[ -n "${InstSecureAlready}" -a -s "${INSTDIR}/var/tsp/cert.pem" ] &&
{
    certtmp=${TMPDIR:-/tmp}/certtmp$$ parsetmp=${TMPDIR:-/tmp}/parsetmp$$
    rm -rf ${certtmp} ${parsetmp} 2>/dev/null
GetValidity() {
    grep -i '^valid from' | tail -1
}
GetIssuer() {
    grep -i '^issuer' | sed 's/.*[cC][nN]=//;s/[, 	].*//' | LANG=C LC_ALL=C tr '[A-Z]' '[a-z]' | tail -1
}
ParseCertValidity() {
    # This is a bit fiddly, and relies on being able to get English language info
    # on cert validity, such as the following string (which is passed into this
    # function as $1):
    #
    # Valid from: Mon Jul 05 09:07:32 BST 2010 until: Sun Oct 03 09:07:32 BST 2010
    #
    # In the calculations the variables have the following meanings:
    # yearStart	Year of "Valid from" date (2010 in the above example)
    # yearEnd	Year of "Valid until" date (2010 ditto)
    # dayStart	Days from year start in "Valid from" date (186 ditto)
    # dayEnd	Days from year start in "Valid until" date (276 ditto)
    # We are deliberately ignoring leap years to simplify computation (it's bad enough already).
    yearStart="" yearEnd="" dayStart="" dayEnd=""
    Validity="$1 __END__"
    daysToMonthStart=""
    while [ -n "${Validity}" -a "${Validity}" != "__END__" ]; do
	tok=`echo "${Validity}" | sed 's/ .*//'`
	# figures below below are total number of days up to start of corresponding month
	# ignoring leap years
	case "${tok}" in
	Jan) daysToMonthStart=0   ;;
	Feb) daysToMonthStart=31  ;;
	Mar) daysToMonthStart=59  ;;
	Apr) daysToMonthStart=90  ;;
	May) daysToMonthStart=120 ;;
	Jun) daysToMonthStart=151 ;;
	Jul) daysToMonthStart=181 ;;
	Aug) daysToMonthStart=212 ;;
	Sep) daysToMonthStart=243 ;;
	Oct) daysToMonthStart=273 ;;
	Nov) daysToMonthStart=304 ;;
	Dec) daysToMonthStart=334 ;;
	[0-3][0-9])	# looks like a day number
	    case "${tok}" in
	    0[1-9]) tok=`expr "${tok}" : '.\(.\)'`	# remove leading zero from 2-digit number
	    esac
	    [ -z "${dayStart}" ] && \
		dayStart=`expr ${daysToMonthStart:-0} + ${tok}` || \
		dayEnd=`expr ${daysToMonthStart:-0} + ${tok}`
	    ;;
	2[0-9][0-9][0-9])	# looks like a year (needs fixing in year 3000 :-) )
	    [ -z "${yearStart}" ] && yearStart=${tok} || yearEnd=${tok}
	    ;;
	esac
	Validity=`echo "${Validity}" | sed 's/^[^ ]*  *//'`
    done
_valid=false
_pp="`echo ${dayStart}|sed 's/[0-9]//g'`"
if [ -z "$_pp" ]
then
    _valid=true
fi
_valds=$_valid

_valid=false
_pp="`echo ${dayEnd}|sed 's/[0-9]//g'`"
if [ -z "$_pp" ]
then
    _valid=true
fi
_valde=$_valid

_valid=false
_pp="`echo ${yearStart}|sed 's/[0-9]//g'`"
if [ -z "$_pp" ]
then
    _valid=true
fi
_valys=$_valid

_valid=false
_pp="`echo ${yearEnd}|sed 's/[0-9]//g'`"
if [ -z "$_pp" ]
then
    _valid=true
fi
_valye=$_valid

    [ "${_valds}" = true -a "${_valde}" = true -a "${_valys}" = true -a "${_valye}" = true ] && {
	echo "dayStart=${dayStart} dayEnd=${dayEnd} yearStart=${yearStart} yearEnd=${yearEnd}"
	return 0
    }
    return 1
}

    ${SGD_JAVA_DIR}/keytool -printcert -file "${INSTDIR}/var/tsp/cert.pem" >${certtmp}
    CreateCert="t"
    if [ "`GetIssuer <${certtmp}`" != "${HOST}" ]; then
	CreateCert=""		# not self-signed
    else
	ParseCertValidity "`GetValidity <${certtmp}`" >${parsetmp} && {
	    . ${parsetmp}
	    thisYear=`date +%Y` thisDay=`date +%j | sed 's/^0*//'`
	    yearDiff=`expr ${yearEnd} - ${thisYear}`
	    if [ ${yearDiff:-0} -gt 1 ]; then
		CreateCert=""	# more than a year left
	    elif [ ${yearDiff:-0} -eq 1 -a `expr ${dayEnd} + 365 - ${thisDay}` -gt 90 ]; then
		CreateCert=""	# more than 90 days left
	    elif [ ${yearDiff:-0} -eq 0 -a `expr ${dayEnd} - ${thisDay}` -gt 90 ]; then
		CreateCert=""	# more than 90 days left
	    fi
	}
    fi
    rm -f ${certtmp} ${parsetmp} 2>/dev/null
}


InstSecureArgs=''
if [ -z "${SGD_STARTLOOP}" -a -n "${InstSecureAlready}" -a -n "${CreateCert}" ]
then
    # Upgrade: refresh self-signed certificate
    echo "${i18n_secenable}"
    ${INSTDIR}/bin/tarantella security disable --quiet >>${INSTDIR}/var/log/setup.log 2>&1
    DoSecurityEnable
elif [ -n "${InstSecureAlready}" -a -z "${InstSecure}" ]
then
    # Upgrade: create h5c configuration profiles even when self-signed certificates aren't being refreshed (normally done via security enable) 
    profile_dir="${installdir}/webserver/apache/`cat $installdir/var/info/apacheversion`/htdocs/certs"
    if [ ! -d "${profile_dir}" ]
    then
        mkdir ${profile_dir}
        chgrp ${privgrp} ${profile_dir}
        chmod 750 ${profile_dir}
    fi

    cert_dir="${installdir}/var/tsp/certs"
    gw_cert_dir="${cert_dir}/gateway"
    sgd_cert_dir="${cert_dir}/array"
    if [ ! -d "${sgd_cert_dir}" ]
    then
        mkdir -p ${sgd_cert_dir}
    fi
    if [ ! -d "${gw_cert_dir}" ]
    then
        mkdir -p ${gw_cert_dir}
    fi

    chown -R ${privusr} ${cert_dir}
    chgrp -R ${privgrp} ${cert_dir}
    chmod -R 751 ${cert_dir}
 
    if [ -f "${installdir}/var/tsp/cert.pem" ]
    then
        hostname_with_dashes="`echo ${HOSTNAME} | sed 's|\.|-|g'`"
        ln -sf ${installdir}/var/tsp/cert.pem \
               ${sgd_cert_dir}/${hostname_with_dashes}.pem
    fi

    ${TTADIR}/bin/scripts/mobile_profile_create.sh --quiet 
fi

[ "${tta_exit_code}" -eq 0 -a -n "${GoodInstall}" ] && echo "${GoodInstall}"

# use the main server exit code
exit $tta_exit_code
