#!/bin/ksh
#
# ident "@(#)idxgen.ksh	1.46 04/07/01 SMI"
#
# Copyright 1996-1999,2001,2003-2004 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

PATH="/bin:/usr/sbin:/usr/bin"
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=`basename $0`
DIRNAME=`dirname $0`
REFRESH=$DIRNAME/$BASENAME
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 | awk 'NR == 2 { print $4; }')
	Used=$(du -k $DBDIR/id2entry.dbb | awk '{ print $1; }')

	# compute free size in kilo-bytes
	#
	Free=$(expr $Free - $Used)
	#
	# must use expr(1), tries to use '$(( .... ))' get syntax error - ssr

	if [ $Free -lt 0 ]
	then
		echo "$BASENAME: 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 "$BASENAME: 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=`awk '/^directory/ { print $2 }' $SLAPDCONF | cat -n \
		| grep "$DBDIR" | awk '{ print $1 }'`
	if [ -z "$DBNUM" ]
	then
		echo  "$BASENAME: Cannot get the database index"
		echo "to perform index generation"
		status=1
		return=1
	fi
	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 | egrep '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="_"

if [[ $# -eq 0 ]]; then
	usage
fi

case $1 in
-*)	;;
*)	# backend directory name
	DBNAME=$1
	shift 1;;
esac

while getopts ":ah" c
do
        case $c in
        h)      usage;;

        a)      if [ "$ATTFOUND" = 1 ]
                then
                        usage
                else
                        ATTFOUND=1
                fi;;
        ?)      usage;;
        esac
done
shift `expr $OPTIND - 1`

if [ "$ATTFOUND" = 1 ]
then
	if [[ $# -ne 0 ]]; then
        	ATTLIST="$ATTLIST $*"
	else
		echo "$BASENAME: missing attribute types"
		usage
	fi
else
        if [ $# -ne 0 ]
        then
		echo "$BASENAME: extra arguments found"
                usage
        fi
fi

#
# Make sure utdsd is stopped
#

pid=`ps -fe | grep lib/utdsd | grep -v grep|awk '{print $2}'`
if [ -n "$pid" ]
then
        echo "$BASENAME: 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 `awk '/^directory/ { print $2 }' $SLAPDCONF`
	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 "$BASENAME: Index generation failed: child process $i exited with status $theRes"
	    status=1
	  fi
	done
	for i in `awk '/^directory/ { print $2 }' $SLAPDCONF`
	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 "$BASENAME: 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 "$BASENAME: 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
