#!/bin/ksh
#
# ident "@(#)idxgen.sh	1.42 01/11/28 SMI"
#
# Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
#

#
#Update LDBM database indexes
#

abort() {

	echo "$0: Interrupted. "
	for i in $PIDS
	do
		echo "Killing process $i"
		kill -TERM $i > /dev/null
	done
	exit 1
}


trap 'abort' INT QUIT

usage() {
	echo
	echo "Usage:"
	echo "  `basename $0` [backend_directory] [-a attribute_name [attribute_name...]]"
	echo
	echo "  Regenerate the index files of the specified datastore. If"
	echo "  <backend_directory> is not specified, index files of every"
	echo "  datastore declared in /var/opt/SUNWut/srds/current/utdsd.conf"
	echo "  are regenerated."
	echo
	echo "  -a: List of indexes to regenerate. If not specified,"
	echo "      every index file is regenerated."
	echo
	exit 1
}

BASEDIR=`/bin/pkgparam SUNWsds BASEDIR 2>/dev/null`
if [ -z "$BASEDIR" ]    # pkg not installed
then
        BASEDIR=/opt    # set default
fi

LDBMCAT=$BASEDIR/SUNWut/srds/lib/utldbmcat
LDIFINDEX=$BASEDIR/SUNWut/srds/lib/utldif2index
LDIFLDBM=$BASEDIR/SUNWut/srds/lib/utldif2ldbm
ETCDIR=$BASEDIR/SUNWut/srds/lib
SLAPDCONF=/etc/opt/SUNWut/srds/current/utdsd.conf
BASENAME=`/usr/bin/basename $0`
DIRNAME=`/usr/bin/dirname $0`
REFRESH=$DIRNAME/$BASENAME
GREP=/usr/xpg4/bin/grep
CAT=/bin/cat
LS=/bin/ls
AWK=/bin/awk
RM=/bin/rm
TEST=/bin/test
NICE=/bin/nice
PIDS=

NICE_LEVEL=-10
COUNT=0
status=0

#
# Refresh indexes of a given LDBM backend
#

refresh() {

# generate LDIF file

	DBDIR=$1
	LDIFFILE=$DBDIR/utidxgen.tmp$$.

	#backslash the slash
	BSDBDIR=`echo $DBDIR | sed -e 's/\//{\\\}/g' |sed -e 's/{//g' | sed -e 's/}/\//g' `

	$TEST -f "$LDIFFILE$COUNT" && $RM "$LDIFFILE$COUNT"
	#
	# test if enough space to generate the ldif file
	#
	Free=`df -k $DBDIR | tail -1 | awk '{print $4}'`
	Used=`ls -l $DBDIR/id2entry.dbb | awk '{print $5}'`

	# compute free size in kilo-bytes
	Free=$(($Free-($Used/1024)))

	if [ $Free -lt 0 ]
	then
		echo "No more disk space under $DBDIR"
		echo "to perform index generation"
		status=1
		return 1
	fi

	$LDBMCAT $DBDIR/id2entry.dbb > $LDIFFILE$COUNT
	
	# Make sure the db cat is OK
	if [ $? -ne 0 ]
	then
		echo "Command $LDBMCAT $DBDIR/id2entry.dbb failed."
		echo "Can't update indexes for datastore $DBDIR"
		$RM -f $LDIFFILE$COUNT
		status=1
		return 1
	fi

	# Get ldbm backend index in utdsd.conf file
	DBNUM=`$CAT $SLAPDCONF | $GREP "\^directory" | $CAT -n | $GREP \""$DBDIR\"" | $AWK '{ print $1 }'`
	if [ "$DBNUM" -eq 1 ]
	then 
		DBNUM=""
	else
		DBNUM="-n $DBNUM"
	fi

	# Extract index list for that backend
	# i.e all indexes between 2 <suffix> tokens

	for idx in `$CAT $SLAPDCONF | $GREP -E 'database|index|directory' | $AWK "/^directory[ 	]*$BSDBDIR/ { flag = 1 ; while ( flag = 1 ) { getline; if ( \\$1 != \"index\" ) { exit } else { print \\$2 } } } "`
	do

	# attribute separated by commas

		for index in `echo $idx | $AWK " BEGIN { FS=\",\" } { for ( i = NF; i> 0; --i) print \\$i }  END {} "`
		do
			# regenerate index

			if [ "$ATTLIST" ] 
			then
				ETL=`echo $ATTLIST | grep -i -w $index`
			else 
				if [ "$index" = default ]
				then
					ETL=
				else
					ETL=1
				fi
			fi
			if [ "$ETL" ]
			then 
				echo "Index $index... \c"
				$RM -f $DBDIR/$index.dbb
				$NICE $NICE_LEVEL $LDIFINDEX -i $LDIFFILE$COUNT -f $SLAPDCONF $DBNUM $index &
				PIDS="$PIDS $!"
				echo "(pid $!)"
			fi
		done
	done

	COUNT=`expr $COUNT + 1`
}

#
# main
#


ATTFOUND=0
ATTLIST=""
DBNAME="_"

for i
do
	if [ "$i" = "-?" -o "$i" = "-h" ]
	then
		usage
	fi
	if [ "$i" = "-a" ]
	then
		if [ "$ATTFOUND" = 1 ]
		then
			usage
		else 
			ATTFOUND=1
		fi
	else if [ "$ATTFOUND" = 1 ]
		then
			ATTLIST="$ATTLIST $i"
		else if [ "$DBNAME" = "_" ]
			then
				DBNAME=$i
			else
				usage
			fi
		fi
	fi
done

#
# Make sure utdsd is stopped
#

pid=`ps -fe | grep lib/utdsd | grep -v grep|awk '{print $2}'`
if [ -n "$pid" ]
then
        echo "utdsd is running. Please stop it by running /etc/init.d/utds stop"
        echo "then run this command to regenerate the indexes."
        exit 1
fi

if [ "$DBNAME" = "_" ]
then
	#refresh all ldbm backends
	for i in `$CAT $SLAPDCONF | $GREP \^directory | $AWK " { print \\$2 } END {} "`
	do

		if [ -d "$i" ]
		then
			echo "Regenerating indexes for datastore $i ..."
			refresh $i
		else
			echo "Index regeneration failed for datastore $i (invalid directory)"
		fi
	done
	for i in `echo $PIDS`
	do
	  wait $i
	  theRes=$?
	  if [ $theRes -ne 0 -a $theRes -ne 127 ]
	  then
	    echo "Index generation failed: child process $i exited with status $theRes"
	    status=1
	  fi
	done
	for i in `$CAT $SLAPDCONF | $GREP \^directory | $AWK " { print \\$2 } END {} "`
	do
		if [ -d "$i" ]
		then
			$RM -f $i/utidxgen.tmp*
		fi
	done
	
else
	if [ -d "$DBNAME" ]
	then
		echo "Regenerating indexes for datastore $DBNAME ..."
		refresh $DBNAME
	else
		echo "Index regeneration failed for datastore $DBNAME (invalid directory)"
	fi
	for i in `echo $PIDS`
	do
	  wait $i
	  theRes=$?
	  if [ $theRes -ne 0 -a $theRes -ne 127 ]
	  then
	    echo "Index generation failed: child process $i exited with status $theRes"
	    status=1
	  fi
	done
#	wait
	if [ -d "$DBNAME" ]
	then 
		$RM -f $DBNAME/utidxgen.tmp*
	fi
fi

exit $status
