#!/bin/sh
#
# Copyright (c) 2013 NetIQ Corporation and its affiliates. All Rights Reserved. 
#
# Startup for Server
#
# Do not put runlevel info. for ndsd since it is started by "nds" 
# Add LSB INIT and chkconfig Info to ndsd script
# chkconfig: 35 75 54
# description: NetIQ eDirectory Server
# processname: ndsd
# config: /etc/opt/novell/eDirectory/conf/nds.conf

### BEGIN INIT INFO
# Provides: ndsd
# Required-Start: $local_fs $network
# Should-Start: $time
# Should-Stop: $null
# Required-Stop: $null 
# Default-Start: 2 3 5
# Default-Stop: 0 1 4 6
# Short-Description: NetIQ eDirectory Server
# Description: NetIQ eDirectory Server
### END INIT INFO

PRINT_SUCCESS="echo \`gettext nds \"Done\"\`"
PRINT_FAILED=
PRINT_SKIPPED=

#NonRoot_RHEL7() If this method returns anything apart from 3, we'll fall back to initd system
#update: if 4 is returned, no instance is started, script exits with success - for instance start by systemd unit file

NonRoot_RHEL7() {
	    ps -p 1 | grep systemd >/dev/null
	    if [ $? -ne 0 ]
	    then
	        return 2
	    fi
        for file in $(ls /etc/*release);
        do
            version_RHEL=`grep -Fi -m 1 "Red Hat Enterprise Linux" $file`
            version_SLES=`grep -Fi -m 1 "SUSE Linux Enterprise Server" $file`
            if [[ $version_SLES == *"SUSE Linux Enterprise Server"* ]];
            then
                    if [[ $version_SLES == *"11"* || $version_SLES == *"10"* ]];
                    then
                            return 2;
                    else
                            export SYSTEMCTL_SKIP_REDIRECT=1
                            return 3;
                    fi
            elif [[ $version_RHEL == *"Red Hat Enterprise Linux"* ]];
            then
                    if [[ $version_RHEL == *"Maipo"* ]] && [[ $UID != 0 ]]; #RHEL7 non root user
                    then
                            export SYSTEMCTL_SKIP_REDIRECT=1
                            return 2;
                    elif [[ $version_RHEL == *"Maipo"* ]] && [[ $UID == 0 ]]; #RHEL7 root user
                    then
                    	return 4;  #systemd unit file to takecare
                    elif [[ $version_RHEL == *"Santiago"* ]]; #Santiago is RHEL 6, falling back to init.d for both root and nonroot RHEL6
                    then
                            export SYSTEMCTL_SKIP_REDIRECT=1
                            return 2;
                    elif [[ $version_RHEL == *"Ootpa"* ]] && [[ $UID != 0 ]]; #RHEL8 non root user
                    then
                            export SYSTEMCTL_SKIP_REDIRECT=1
                            return 2;
                    elif [[ $version_RHEL == *"Ootpa"* ]] && [[ $UID == 0 ]]; #RHEL8 root user
                    then
                    	return 4;  #systemd unit file to takecare
                    elif [[ $version_RHEL == *"Plow"* ]] && [[ $UID != 0 ]]; #RHEL9 non root user
                    then
                            export SYSTEMCTL_SKIP_REDIRECT=1
                            return 2;
                    elif [[ $version_RHEL == *"Plow"* ]] && [[ $UID == 0 ]]; #RHEL9 root user
                    then
                    	return 4;  #systemd unit file to takecare
                    fi
            fi
        done
        return 3;  #It'll try falling back to systemd
}

StatusNdsdSystemd () {
	firstchar_systemd=`echo $0 | cut -c1`
	dir_systemd=`dirname $0`
	if [ "$firstchar_systemd" != "/" ]
	then
	  dir_systemd="`pwd`/$dir_systemd"
	fi

	AWK=awk
	NDSHOME_systemd=`echo $dir_systemd | $AWK -F"/etc" '{print $1}'`

	basenam_systemd=`basename $0`
	if [ "$basenam_systemd" = "rcndsd" ]
	then
	NDSHOME_systemd=""
	fi

	default_conf_systemd=$NDSHOME_systemd/etc/opt/novell/eDirectory/conf
	default_prefix_systemd=$NDSHOME_systemd/opt/novell/eDirectory
	default_vardir_systemd=$NDSHOME_systemd/var/opt/novell/eDirectory/data

	prefix_systemd=$default_prefix_systemd
	exec_prefix_systemd=${prefix_systemd}
	sbindir_systemd=${exec_prefix_systemd}/sbin
	bindir_systemd=${exec_prefix_systemd}/bin

	ownername_systemd=`ls -l  $0 |awk '{print $3;}'`
	ownerUid_systemd=`id $ownername_systemd | cut -d'=' -f2|cut -d'(' -f1 2>/dev/null`
	default_config_file_systemd=`head -1 $default_conf_systemd/.edir/instances.$ownerUid_systemd 2> /dev/null`

	if [ -f $bindir_systemd/ndsstat ] ; then
		$bindir_systemd/ndsstat  --config-file $default_config_file_systemd > /tmp/nds.stat.$$ 2>&1

		cat /tmp/nds.stat.$$
		rm /tmp/nds.stat.$$
	fi
} # StatusNdsdSystemd

NonRoot_RHEL7
Result=$?
if [ $Result -eq 3 ]
then
	if [[ "$1" = "start" || "$1" = "status" || "$1" = "stop" || "$1" = "restart" || "$1" = "reload" ]]; then
		nds_operation=$1
	else
		echo "Unknown Operation."
		exit 1
	fi

	if [[ "$nds_operation" = "restart" || "$nds_operation" = "reload" ]]; then
		nds_operation="stop"
		systemctl $nds_operation ndsd.service

		nds_operation="start"
		systemctl $nds_operation ndsd.service
	elif [[ "$nds_operation" = "start" || "$nds_operation" = "status" || "$nds_operation" = "stop" ]]; then
		systemctl $nds_operation ndsd.service

		if [[ "$nds_operation" = "status" ]]; then
			echo ""
			StatusNdsdSystemd
		fi
	fi
	echo `gettext nds "Note: SysVinit eDirectory system is not recommended on this platform. Refer to documentation for eDirectory usage on this platform"`
	exit 0
elif [ $Result -eq 4 ]
then
	echo "Skipped SysVinit for Systemd startup"
	exit 0  #return success to avoid failure in system status
fi
#set systemd specific env variable for /etc/rc.status to not use systemctl on systems with no active systemd
export SYSTEMD_NO_WRAP=1

if [ -f /etc/sysconfig/language ]; then
        . /etc/sysconfig/language

        locale_vars="\
        LANG         \
        LC_ALL       \
        LC_MESSAGES  \
        LC_CTYPE     \
        LC_COLLATE   \
        LC_TIME      \
        LC_NUMERIC   \
        LC_MONETARY"

        for var in $locale_vars
        do
        if eval test -z "\$$var"; then
                eval $var="\$RC_$var"
                export $var
        fi
        done
fi

# Store the language as there is every chance it being reset
tmpLANG=$LANG
tmpLC_ALL=$LC_ALL

if [ -f /etc/rc.status ]; then
	. /etc/rc.status
	PRINT_SUCCESS="rc_reset;rc_status -v"
	PRINT_FAILED="rc_failed 1;rc_status -v"
	PRINT_SKIPPED="rc_status -s"
else
if [ -f /etc/rc.d/init.d/functions ]; then
	. /etc/rc.d/init.d/functions
	PRINT_SUCCESS="echo_success;echo """
	PRINT_FAILED="echo_failure;echo """
	PRINT_SKIPPED="echo_failure;echo """
else
if [ -f /etc/init.d/functions ]; then
	. /etc/init.d/functions
	PRINT_SUCCESS="echo_success;echo """
	PRINT_FAILED="echo_failure;echo """
	PRINT_SKIPPED="echo_failure;echo """
fi
fi
fi
LANG=$tmpLANG
LC_ALL=$tmpLC_ALL
export LANG
export LC_ALL
userID=`id -u`
if [ -d /opt/novell/xad/lib/nds-modules -o -d /opt/novell/xad/lib64/nds-modules ]; then
NDSD_TRY_NMASLOGIN_FIRST=true
export NDSD_TRY_NMASLOGIN_FIRST
fi
if [ -d /opt/novell/afptcpd ]; then
NDSD_TRY_NMASLOGIN_FIRST=true
export NDSD_TRY_NMASLOGIN_FIRST
fi

export NDSD_TRY_NMASLOGIN_FIRST=true

# Template configuration variables
AWK=awk

firstchar=`echo $0 | cut -c1`
dir=`dirname $0`
if [ "$firstchar" != "/" ]
then
  dir="`pwd`/$dir"
fi

#echo $dir
NDSHOME=`echo $dir | $AWK -F"/etc" '{print $1}'`
basenam=`basename $0`
if [ "$basenam" = "rcndsd" ]
then
  NDSHOME=""
fi


default_conf=$NDSHOME/etc/opt/novell/eDirectory/conf
default_prefix=$NDSHOME/opt/novell/eDirectory
default_vardir=$NDSHOME/var/opt/novell/eDirectory/data
TEXTDOMAINDIR="$NDSHOME/opt/novell/eDirectory/share/locale"
export TEXTDOMAINDIR

ownername=$USER
ownerUid=$UID
default_config_file=`head -1 $default_conf/.edir/instances.$ownerUid 2> /dev/null` 

if [ "$default_config_file" = "" ]
then
        default_config_file=$default_conf/nds.conf
fi

: ${NDS_CONF=$default_config_file}
: ${prefix=$default_prefix}

export NDS_CONF

configdir=`cat ${NDS_CONF=$default_config_file} |grep "^n4u.*configdir" | head -n 1 | sed 's/^.*=//'`
if [ -z "$configdir" ]; then
	 configdir=$default_conf
fi

localstatedir=`cat ${NDS_CONF=$default_config_file} |grep "^n4u.*vardir" | head -n 1 | sed 's/^.*=//'`
if [ -z "$localstatedir" ]; then
	 localstatedir=$default_vardir
fi

locallogfile=`cat ${NDS_CONF=$default_config_file} |grep "^n4u.server.log-file" | head -n 1 | sed 's/^.*=//'`
if [ -z "$locallogfile" ]; then
	locallogfile=`echo $localstatedir | sed 's/data$/log\/ndsd.log/'`
fi
libdir=`cat ${NDS_CONF=$default_config_file} |grep "^n4u.*libdir" | head -n 1 | sed 's/^.*=//'`

prefix=$default_prefix
exec_prefix=${prefix}
sbindir=${exec_prefix}/sbin
bindir=${exec_prefix}/bin
sysconfdir=/etc
libfldr=lib64
libdir=${default_prefix}/$libfldr 
node=`hostname`
now="`date +"%b %d %T"`"

initdir=$NDSHOME/etc/init.d

trap 'rm -f /tmp/nds.stat.$$' 0 1 15

LD_LIBRARY_PATH=$libdir:$libdir/nds-modules:$libdir/apr:/$NDSHOME/opt/novell/$libfldr:/opt/novell/$libfldr:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
PATH=$PATH:/usr/local/bin

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/nds-modules:/opt/novell/xad/$libfldr/nds-modules:/opt/novell/xad/$libfldr:$default_prefix/lib/nds-modules/jre/lib/i386
export LD_LIBRARY_PATH




#
# Start the ndsd daemon
#

StartNdsd () {

	migrateOldScripts
	export RTLD_DEEPBIND=0

	# Call custom settings before ndsd start
	if [ -f $sbindir/pre_ndsd_start ]; then
		echo `gettext nds "Executing customized settings before starting the NetIQ eDirectory server..."`
		. $sbindir/pre_ndsd_start

		if [ "$?" -ne 0 ]; then
			echo `gettext nds "Validation failed in pre_ndsd_start script."`
			string=`gettext nds "Please refer to the following script: "`
                        echo "$string$sbindir/pre_ndsd_start ."
			echo `gettext nds "NetIQ eDirectory server could not start."`
			eval $PRINT_SKIPPED
			exit 1
		fi
	fi

	#log hostname into logfle
	str=`gettext nds "About to start NetIQ eDirectory server on host:"`
	echo "$now $str $node." >> $locallogfile

    if [ -f $sbindir/ndsd ]; then 
		echo `gettext nds "Starting Opentext eDirectory server..."`



	if [ "$MALLOC_CHECK_" = "" ] ; then
		if [ -f /etc/novell-release ]; then
			LD_PRELOAD="/usr/$libfldr/libtcmalloc_minimal.so.4" startproc $sbindir/ndsd
		else 
			LD_BIND_NOW=1 LD_PRELOAD="$libdir/libtcmalloc_minimal.so.4" $sbindir/ndsd
		fi
	else
		$sbindir/ndsd
	fi
		rc="$?"
		if [ $rc != 0 ]; then
			if [ $rc != 2 ]; then
				echo `gettext nds "NetIQ eDirectory server startup failed."`
				str=`gettext nds "For more information view the following log file :"`
                                echo "$str $locallogfile"
				eval $PRINT_FAILED
				exit 1
			fi
			eval $PRINT_SUCCESS
			exit 0
		fi
		sleep 5				# wait for server to initialize
		eval $PRINT_SUCCESS
 if [ -d /var/lock/subsys ] && [ "$userID" = "0" ]
 then 
 touch /var/lock/subsys/ndsd
 fi
    else
		str=`gettext nds "The following NetIQ eDirectory server is not found."`
                echo "$str : $sbindir/ndsd"
		eval $PRINT_FAILED
		exit 1
    fi

	#If container mode is not null, then sleep until the s-n4ucmd file is created
        #sleep 1 
        if [ ! -z "$CONTAINER_MODE" ]; then
                counter=0
                custom_socket_file="/var/opt/novell_docker/eDirectory/data/s-n4ucmd"
                while :
                do
                        echo "Waiting for the socket file to be created.."

                        if [ -e $custom_socket_file ]; then
                                break
                        fi
                        sleep 1
                        ((counter++))

                        if [[ $counter -gt 60 ]]; then
                                echo "Timeout! s-n4ucmd socket file not created.."
                                str= "s-n4ucmd file creation timeout! For more information view the following log file :"
                                echo "$str $locallogfile"
                                eval $PRINT_FAILED
                                exit 1
                        fi
                done
                echo " s-n4ucmd socket file created.."
        fi

	# Call custom settings after ndsd start

	if [ -f $sbindir/post_ndsd_start ]; then
		echo `gettext nds "Executing customized settings after starting the NetIQ eDirectory server..."`
		. $sbindir/post_ndsd_start
		
		if [ "$?" -ne 0 ]; then
			echo `gettext nds "Validation failed in post_ndsd_start script."`
			echo "$string$sbindir/post_ndsd_start."
		fi
	fi
	#log hostname into logfle
	str=`gettext nds " Started NetIQ eDirectory server on host: "`
    echo "$now$str$node" >> $locallogfile

}	# StartNdsd

#
# Stop the ndsd daemon
# Take care of ccs unloading 
#

StopNdsd () {

	# Call custom settings before ndsd stop
	if [ -f $sbindir/pre_ndsd_stop ]; then

		echo `gettext nds "Executing customized settings before stopping the NetIQ eDirectory server..."`
		. $sbindir/pre_ndsd_stop

		if [ "$?" -ne 0 ]; then
			echo `gettext nds "Validation failed in pre_ndsd_stop script."`
			echo "$string$sbindir/pre_ndsd_start ."
			echo `gettext nds "NetIQ eDirectory server could not stop."`
			eval $PRINT_SKIPPED
			exit 1
		fi
	fi 
	#log hostname into logfle
	str=`gettext nds " About to stop NetIQ eDirectory server on host:  "`
    echo "$now$str$node" >> $locallogfile


	if [ ! -f $localstatedir/ndsd.pid ]; then 
		echo `gettext nds "NetIQ eDirectory server is not running."`
		eval $PRINT_FAILED
		exit 1
	fi

	echo `gettext nds "Stopping Opentext eDirectory server..."`   # no newline

	# Get the pid from the pid file
	pid=`cat $localstatedir/ndsd.pid`
	sess=`ps -o session -p $pid --no-headers`

	kill -INT $pid > /dev/null 2>&1
	if [ "$?" -ne 0 ]; then 
		echo `gettext nds "NetIQ eDirectory server is not running."`
		eval $PRINT_FAILED
		exit 1
	fi

	count=360
	pidexists=`ps -p $pid | grep -c ndsd`
	while [ $pidexists -ne 0 ] && [ -f $localstatedir/ndsd.pid -a $count -ne 0 ]
	do
		sleep 1                        # wait for maximum 30 seconds
		printf `gettext nds "."`
		count=`expr $count - 1`  
		pidexists=`ps -p $pid | grep -c ndsd`
	done

	if [ -f $localstatedir/ndsd.pid ]; then
		echo `gettext nds "WARNING: ndsd process is still running. Killing ndsd."` >> $locallogfile
		kill -KILL $pid > /dev/null 2>&1 # we can't wait any longer
		rm $localstatedir/ndsd.pid
	fi

	kill -KILL `ps -o pid -s $sess --no-headers` > /dev/null 2>&1
    # some threads are still hanging though the mother thread has got killed.

 if [ -f /var/lock/subsys/ndsd ] && [ "$userID" = "0" ]
 then 
 rm -f /var/lock/subsys/ndsd
 fi
	eval $PRINT_SUCCESS
	# Call custom settings after ndsd stop

	if [ -f $sbindir/post_ndsd_stop ]; then
		echo `gettext nds "Executing customized settings after stopping the NetIQ eDirectory server..."`
		. $sbindir/post_ndsd_stop

		if [ "$?" -ne 0 ]; then
			echo `gettext nds "Validation failed in post_ndsd_stop script."`
			echo "$string$sbindir/post_ndsd_start ."
		fi
	fi
	#log hostname into logfle
	str=`gettext nds " Stopped NetIQ eDirectory server on host:  "`
    echo "$now$str$node ." >> $locallogfile

}	# StopNdsd

# Migrate the old scripts (post_ndsd_start/stop and pre_ndsd_start/stop) from initdir to sbindir
migrateOldScripts(){
	scripts="pre_ndsd_start pre_ndsd_stop post_ndsd_start post_ndsd_stop"
	for script in $scripts
	do
	if [ -f  "$initdir/$script" ]; then
		cat $initdir/$script >> $sbindir/$script 
		rm -f $initdir/$script >/dev/null
	fi
	done
}

#
# print the right usage
# exit with 1
#

Usage () {
str=`gettext nds "Usage"`
 echo "$str: $0 { start | stop | status | restart | reload }"
	exit 1
}	# Usage

#
# Get status of ndsd running on current host
#
StatusNdsd () {
	netstat -enp | grep ndsd > /tmp/nds.netstat.$$ 2>&1
	if [ "$?" -eq 0 ]; then
 		if [ -f $bindir/ndsstat ] ; then
 			$bindir/ndsstat  --config-file $default_config_file > /tmp/nds.stat.$$ 2>&1
 			if [ "$?" -ne 0 ]; then
 				cat /tmp/nds.stat.$$
				eval $PRINT_FAILED
 				exit 1
 			fi
 			cat /tmp/nds.stat.$$
 			rm /tmp/nds.stat.$$
 		else
 			echo `gettext nds "Unable to get server status"`
 		fi
 	else
		echo `gettext nds "Unable to get server status"` 
          	exit 1
 	fi
 	rm /tmp/nds.netstat.$$	
} # StatusNdsd

RestartNdsd () {
 if [ -f $localstatedir/ndsd.pid ]; then
 	kill -0 `cat $localstatedir/ndsd.pid ` > /dev/null 2>&1
 	if [ "$?" -ne 1 ]; then
 		StopNdsd	
 	fi
 fi
 StartNdsd
}

#
# Reload not supported currently
#

ReloadNdsd ()  {
  RestartNdsd  
}

#
# Display version information
#

VersionNdsd ()   {
	$sbindir/ndsd --version
}

#
# MAIN FUNCTION
# check number of args
# call start, stop functions 
# 
case "$#" in
'1')
	#valid number of arguments 
	if [ "$1" = "start" ]; then
		StartNdsd
	elif [ "$1" = "stop" ]; then
		StopNdsd
	elif [ "$1" = "status" ]; then
	    StatusNdsd
	elif [ "$1" = "restart" ]; then
	    RestartNdsd
	elif [ "$1" = "reload" ]; then
	    ReloadNdsd	
	elif [ "$1" = "--version" ]; then
		 VersionNdsd
	else
		 Usage
	fi
	;;
'2')
	if [ "$1" = "start" ]; then
		if [ "$2" = "-ndb" ]; then
			NDSD_DONT_OPEN_AGENT=Y
			export NDSD_DONT_OPEN_AGENT
			StartNdsd
		elif [ "$2" = "-rdb" ]; then
			RESTRICTED_MODE=Y
			export RESTRICTED_MODE
			StartNdsd
		elif [ "$2" = "-igrfl" ]; then
			NDSD_IGNORE_RFL=Y
			export NDSD_IGNORE_RFL
			StartNdsd
		else
			Usage
		fi
	else
		Usage
	fi
	;;
*)
	#invalid number of arguments
	Usage
	;;
esac
if [ -f /etc/rc.status ]; then 
	rc_exit
fi
