#! /bin/sh
#
# OPENDJ SERVICE SCRIPT
#

#
# The contents of this file are subject to the terms of the Common Development and
# Distribution License (the License). You may not use this file except in compliance with the
# License.
#
# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
# specific language governing permission and limitations under the License.
#
# When distributing Covered Software, include this CDDL Header Notice in each file and include
# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
# Header, with the fields enclosed by brackets [] replaced by your own identifying
# information: "Portions Copyright [year] [name of copyright owner]".
#
# Copyright 2013-2015 ForgeRock AS.
# Portions Copyright 2025-2026 3A Systems, LLC


# chkconfig: 2345 80 05
# description: Starts and stops opendj LDAPv3 service.
#
### BEGIN INIT INFO
# Provides:          opendj
# Required-Start:
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: This is the opendj daemon
# Description:       OpenDJ is an LDAPv3 compliant directory service, developed for the Java
#                    platform, providing a high performance, highly available and secure store
#                    for the identities managed by enterprises. Its easy installation process,
#                    combined with the power of the Java platform makes OpenDJ one of the
#                    simplest and fastest directory servers to deploy and manage.
### END INIT INFO

# Set up the source function library by checking which one actually exists
# (detecting the distribution is not enough: e.g. a RHEL-family system without
# the optional initscripts package has /etc/redhat-release but no functions).
if [ -f /etc/init.d/functions ] ; then
    # RedHat-family (initscripts)
    . /etc/init.d/functions
    LOCKFILE=/var/lock/subsys/opendj
elif [ -f /etc/rc.status ] ; then
    # SuSE
    . /etc/rc.status
    LOCKFILE=/var/run/rcopendj
elif [ -f /lib/lsb/init-functions ] ; then
    # Debian/LSB
    . /lib/lsb/init-functions
    LOCKFILE=/var/lock/opendj
elif [ -f /etc/init.d/functions.sh ] ; then
    # Other dist.
    . /etc/init.d/functions.sh
    LOCKFILE=/tmp/unused-lockfile-opendj
else
    # No init function library: the script is self-contained anyway.
    LOCKFILE=/tmp/opendj.lockfile
fi
# LOCKFILE is used by the service subsystem to know whether the opendj service is started and act upon it


# Optional admin overrides (OPENDJ_JAVA_HOME / OPENDJ_JAVA_BIN / OPENDJ_JAVA_ARGS),
# exported so they survive the runuser switch to the service account in run_as().
# The same files feed systemd's EnvironmentFile=, whose syntax is not shell (no
# expansion, optional quotes) - so extract the known keys instead of sourcing.
for _envfile in /etc/default/opendj /etc/sysconfig/opendj ; do
    [ -r "$_envfile" ] || continue
    for _key in OPENDJ_JAVA_HOME OPENDJ_JAVA_BIN OPENDJ_JAVA_ARGS ; do
        _val=`sed -n "s/^$_key=//p" "$_envfile" | tail -n 1 \
            | sed -e 's/^"\(.*\)"$/\1/' -e "s/^'\(.*\)'\$/\1/"`
        [ -n "$_val" ] && export "$_key=$_val"
    done
done

# Sets the script vars
INSTALL_ROOT="/opt/opendj"
export INSTALL_ROOT
DAEMON=opendj

# The instance root may have been relocated with instance.loc (split layout):
# resolve it the way the server scripts (_script-util.sh) do.
INSTANCE_ROOT="$INSTALL_ROOT"
if [ -f /etc/opendj/instance.loc ] ; then
    read INSTANCE_ROOT < /etc/opendj/instance.loc
elif [ -f "$INSTALL_ROOT/instance.loc" ] ; then
    read _loc < "$INSTALL_ROOT/instance.loc"
    case "$_loc" in
        /*) INSTANCE_ROOT=$_loc ;;
        *)  INSTANCE_ROOT=$INSTALL_ROOT/$_loc ;;
    esac
fi

# Original PID file
ORIGINPIDFILE=$INSTANCE_ROOT/logs/server.pid

# Pid file is a symlink to /opt/opendj/log/server.pid
# /run is the canonical location (/var/run is a compatibility symlink to it).
PIDFILE=/run/opendj.pid
RETVAL=0

# The dedicated service account the server runs as (created by the package).
RUNASUSER=opendj

# Runs the given command as $RUNASUSER when that account exists and we are root;
# otherwise runs it as the current user (keeps old root-only installs working).
run_as() {
    if [ "$(id -un)" = "$RUNASUSER" ] || ! getent passwd "$RUNASUSER" >/dev/null 2>&1 ; then
        "$@"
    elif command -v runuser >/dev/null 2>&1 ; then
        runuser -u "$RUNASUSER" -- "$@"
    else
        # Pass the argv through untouched: $1 becomes $0 of the -c script,
        # the rest arrive as "$@", so arguments with spaces survive.
        su -s /bin/sh "$RUNASUSER" -c 'exec "$0" "$@"' "$@"
    fi
}

# If the daemon is not there, then exit / LSB return code.
test -x "$INSTALL_ROOT/bin/start-ds" || exit 5

# Recreates the symlink if needed (/var/run is deleted after reboot (eg. debian)).
test -h "$PIDFILE" || ln -s $ORIGINPIDFILE $PIDFILE

# Succeeds when the instance has been configured with setup. Keyed on
# buildinfo + config.ldif, not on archived-configs (which can legitimately be
# empty) - otherwise the runlevel K-script would skip stopping a live server.
instance_configured() {
    [ -f "$INSTANCE_ROOT/config/buildinfo" ] && [ -f "$INSTANCE_ROOT/config/config.ldif" ]
}

# Starts the server and creates pid file.
start() {
    if ! instance_configured ; then
        echo "Instance is not configured. Please run $INSTALL_ROOT/setup"
        return 1
    fi

    echo -n "Starting $DAEMON: "
    # Server is running
    if [ -e $PIDFILE ] ; then
        echo "> Already running."
        return 0
    else
        run_as "$INSTALL_ROOT"/bin/start-ds --quiet
        RETVAL=$?
        if [ $RETVAL = 0 ] ; then
            touch $LOCKFILE
            echo "> SUCCESS."
        else
            echo "> FAILURE."
        fi
        echo ""
        return $RETVAL
    fi
}

# Stops the server and removes pid file.
stop() {
    if ! instance_configured ; then
        echo "Instance is not configured. Please run $INSTALL_ROOT/setup"
        return 1
    fi

    echo -n "Stopping $DAEMON: "
    if [ -e $PIDFILE ]
    then
        # Server is running
        run_as "$INSTALL_ROOT"/bin/stop-ds --quiet
        RETVAL=$?
        if [ $RETVAL = 0 ] ; then
            echo "> SUCCESS."
        else
            echo "> FAILURE."
        fi
        rm -f $LOCKFILE
        echo ""
        return $RETVAL
    else
        echo "> Already stopped."
        echo ""
        return 3
    fi
}

# Displays the service status
status() {
    if ! instance_configured ; then
        echo "Instance is not configured. Please run $INSTALL_ROOT/setup"
        return 1
    fi

    echo -n $"$DAEMON status: "
    if [ -e $PIDFILE ] ; then
        echo "> Running."
        return 0
    else
        echo "> Stopped."
        return 3
    fi
}

case "$1" in
    start)
        start
    ;;
    stop)
        stop
    ;;
    restart)
        if ! instance_configured ; then
            echo "Instance is not configured. Please run $INSTALL_ROOT/setup"
            exit 1
        else
            stop
            sleep 5
            start
        fi
    ;;
    force-reload)
        # Not implemented.
        echo "Not implemented."
    ;;
    status)
        status
    ;;
    *)
        echo "Usage: /etc/init.d/$DAEMON {start|restart|stop|force-reload|status}"
        exit 1
    ;;
esac

exit $RETVAL
