# Init file for the NorduGrid/ARC Information System
#
# chkconfig: 2345 55 25
# description: NorduGrid/ARC Information system
#
# Originally based on globus-mds v0.27.
#
# Written by:
#    Anders Waananen <waananen@nbi.dk>
#    Daniel Johansson <daniel@nsc.liu.se>
#    Mattias Ellert <mattias.ellert@fysast.uu.se>
#
# description:
#   generates BDII config and starts up the BDII
#   starts up the GIIS replacement server
#   generates GIIS registration config and starts up the registration
#
# config: /etc/sysconfig/nordugrid
# config: /etc/arc.conf
#
######################################################################

### BEGIN INIT INFO
# Provides:          grid-infosys
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: NorduGrid/ARC Information system
# Description:       LDAP based grid information system for the ARC middleware
### END INIT INFO

# Helper functions
if [ -f /etc/init.d/functions ]; then
    . /etc/init.d/functions
    log_success_msg() {
	echo -n "$@"
	success "$@"
	echo
    }
    log_warning_msg() {
	echo -n "$@"
	warning "$@"
	echo
    }
    log_failure_msg() {
	echo -n "$@"
	failure "$@"
	echo
    }
elif [ -f /lib/lsb/init-functions ]; then
    . /lib/lsb/init-functions
else
    echo "Error: Cannot source neither init.d nor lsb functions"
    exit 1
fi

# Overall defaults
RETVAL=0
prog=grid-infosys
debug=${debug:-0}
RUN=yes

# sysconfig files
if [ -r /etc/sysconfig/nordugrid ]; then
    . /etc/sysconfig/nordugrid
elif [ -r /etc/default/nordugrid ]; then
    . /etc/default/nordugrid
fi
if [ -r /etc/sysconfig/grid-infosys ]; then
    . /etc/sysconfig/grid-infosys
elif [ -r /etc/default/grid-infosys ]; then
    . /etc/default/grid-infosys
fi

if [ "x$RUN" != "xyes" ]; then
    echo "$prog disabled, please adjust the configuration to your needs "
    echo "and then set RUN to 'yes' in /etc/default/$prog to enable it."
    exit 0
fi

debug_echo () {
    if [ $debug -gt 0 ]; then
	info_string="`date +'%b %d %H:%M:%S'` `hostname` `basename $0`[$$]"
	echo "${info_string} $*" >> ${infosyslog}
    fi
}

error_echo () {
    info_string="`date +'%b %d %H:%M:%S'` `hostname` `basename $0`[$$]"
    echo "${info_string} $*" >> ${infosyslog}
}

std_header () {
    debug_echo "Creating file: $1"
    echo "# This file was automatically generated by the $prog startup script." > $1
    echo "# Do not modify." >> $1
    echo >> $1
}

printregldif () {

    cat <<-EOF

	# Registration "$rootdn" -> "$targetsuffix"
	dn: Mds-Vo-Op-name=register, $targetsuffix
	regtype: mdsreg2
	reghn: $reghn
	regport: $regport
	regperiod: $regperiod
	type: ldap
	hn: $hn
	port: $port
	rootdn: $rootdn
	ttl: $ttl
	timeout: $timeout
	mode: cachedump
	cachettl: $cachettl
	bindmethod: $bindmethod
	EOF
}

# Function checks if you have a bad current working directory
# (i.e. one that will be removed by running this script.)
# The function must be run after bdii_var_dir and bdii_tmp_dir have
# been set.
check_cwd () {
    current_dir=`pwd`
    case "$current_dir" in
       $bdii_var_dir*|$bdii_tmp_dir* )
         log_failure_msg "Checking current working directory: "
         echo "You are not allowed to be at or below these directories: "
         echo "$bdii_var_dir , $bdii_tmp_dir "
         echo "when starting or stopping grid-infosys since they will be removed."
         exit 1
         ;;
    esac
}

###############  Standard configuration  ######################

# Set ARC location
ARC_LOCATION=${ARC_LOCATION:-/usr}
if [ ! -d "$ARC_LOCATION" ]; then
    log_failure_msg "ARC_LOCATION ($ARC_LOCATION) not found"
    exit 1
fi
export ARC_LOCATION

# source the config parsing routines
if [ -r "$ARC_LOCATION/share/arc/config_parser_compat.sh" ]; then
    . $ARC_LOCATION/share/arc/config_parser_compat.sh || exit $?
else
    log_failure_msg "Could not find $ARC_LOCATION/share/arc/config_parser_compat.sh"
    exit 1
fi

ARC_CONFIG=${ARC_CONFIG:-/etc/arc.conf}

if [ ! -r "$ARC_CONFIG" ]; then
    echo "ARC configuration file arc.conf was not found (usually /etc/arc.conf)"
    if [ -r "/etc/nordugrid.conf" ]; then
	echo "Fallback /etc/nordugrid.conf was found, trying to use that one"
	ARC_CONFIG="/etc/nordugrid.conf"
    else
	log_warning_msg "arc.conf was not found. If this file is in a non-standard place,"
	log_warning_msg "  it can be set with the ARC_CONFIG environment variable"
	exit 0
    fi
fi

# Check for OpenLDAP bug existing on some RHEL4 installations and warn about it
if [ -s /etc/openldap/ldap.conf ]; then
    TLS_CACERTDIR=`cat /etc/openldap/ldap.conf | grep -E "^TLS_CACERTDIR" | sed -e 's/TLS_CACERTDIR[ \t]*//g'`
    if [ "x${TLS_CACERTDIR}" != "x" ] && [ ! -d ${TLS_CACERTDIR} ]; then
	log_warning_msg "TLS_CACERTDIR=${TLS_CACERTDIR} is set in /etc/openldap/ldap.conf but directory does not exist"
	log_warning_msg "This is a bug in OpenLDAP, please create the directory"
	exit 0
    fi
fi

config_set_defaults () {
    CONFIG_hostname=`hostname`
    CONFIG_port="2135"
    CONFIG_provider_loglevel=1
}

# Read arc.conf
export pkgdatadir=$ARC_LOCATION/share/arc
config_parse_file $ARC_CONFIG || exit $?

# Check for infosys-block
if ! config_match_section infosys; then
    log_warning_msg "Missing infosys configuration block"
    exit 0
fi

config_hide_all
config_set_defaults
config_import_section common

# These options need to come from the infosys-block, not from common
unset CONFIG_logfile
unset CONFIG_user
unset CONFIG_port

config_import_section infosys

debug=${CONFIG_debug:-$debug}

check_ownership () {
    if [ $# != 2 ]; then
	error_echo "Wrong number of arguments to check_ownership"
	exit 1
    fi
    file=$1
    user=$2

    res=$(find `dirname $file`/ -maxdepth 1 -user $user -name `basename $file`)
    if [ "x${res}" = "x" ]; then
	log_failure_msg "ERROR: ${file} is not owned by ${user}"
	exit 1
    fi
}

get_ldap_user () {
    ldap_user=`getent passwd | grep ldap | sed 's/\([az]*\):.*/\1/g'`
    if [ ! "xldap" = "x$ldap_user" ] && [ ! "xopenldap" = "x$ldap_user" ]; then
	debug_echo "Warning, could not find ldap or openldap user"
	debug_echo "resorting to using the root user."
	ldap_user=root
    fi
}

# These values may be set in arc.conf, otherwise use sensible defaults

slapd_loglevel=${CONFIG_slapd_loglevel:-0}
hostname_f=$(hostname -f)
hostname=${CONFIG_hostname:-$hostname_f}
slapd_hostnamebind=${CONFIG_slapd_hostnamebind:-$hostname}
threads=${CONFIG_threads:-32}
providerlog=${CONFIG_providerlog:-/var/log/arc/infoprovider.log}
infosyslog=${CONFIG_logfile:-/var/log/arc/$prog.log}

mkdir -p `dirname $providerlog`
mkdir -p `dirname $infosyslog`

# Use this command to change user, needs to be paired with -s "/bin/sh" to handle users without a shell
if [ -x /sbin/runuser ]; then
    RUNUSER=runuser
else
    RUNUSER=su
fi

# If missing, we have a problem
USERSHELL=${USERSHELL:-"/bin/sh"}
if [ ! -x ${USERSHELL} ]; then
    error_echo "Could not find /bin/sh"
    exit 1
fi

# Get ldap user from passwd
get_ldap_user
bdii_user=${CONFIG_user:-$ldap_user}

bdii_location=${CONFIG_bdii_location:-/usr}
giis_location=${CONFIG_giis_location:-$ARC_LOCATION}

bdii_update_cmd=${CONFIG_bdii_update_cmd:-"${bdii_location}/sbin/bdii-update"}
if [ ! -e $bdii_update_cmd ]; then
    log_failure_msg "Can not find bdii-update command at: $bdii_update_cmd."
    log_failure_msg "Please set bdii_update_cmd in arc.conf"
    exit 1
fi

bdii_tmp_dir=${CONFIG_bdii_tmp_dir:-/var/tmp/arc/bdii}
if grep -q BDII_PID_FILE $bdii_update_cmd ; then
bdii_var_dir=${CONFIG_bdii_var_dir:-/var/lib/arc/bdii}
bdii_run_dir=${CONFIG_bdii_run_dir:-/var/run/arc/bdii}
else
bdii_var_dir=${CONFIG_bdii_var_dir:-/var/run/arc/bdii}
bdii_run_dir=$bdii_var_dir
fi
bdii_log_dir=${CONFIG_bdii_log_dir:-/var/log/arc/bdii}
bdii_log_file="${bdii_log_dir}/bdii-update.log"

mkdir -p $bdii_log_dir

bdii_slapd_conf=$bdii_run_dir/bdii-slapd.conf

bdii_default_ldif_ng=${bdii_tmp_dir}/provider/arc-default.ldif.pl
bdii_ldif_dir=${bdii_tmp_dir}/ldif
bdii_provider_dir=${bdii_tmp_dir}/provider
bdii_plugin_dir=${bdii_tmp_dir}/plugin

bdii_port=${CONFIG_port:-2135}

# Using uppercase characters in bdii_bind will break infosys.
bdii_bind="o=grid"

bdii_db_config=${CONFIG_bdii_db_config:-"/etc/bdii/DB_CONFIG"}
bdii_database=${CONFIG_bdii_database:-"hdb"}
bdii_archive_size=${CONFIG_bdii_archive_size:-0}

infosys_compat=${CONFIG_infosys_compat:-"disable"}
infosys_nordugrid=${CONFIG_infosys_nordugrid:-"enable"}
infosys_glue12=${CONFIG_infosys_glue12:-"disable"}
infosys_glue2_ldap=${CONFIG_infosys_glue2_ldap:-"disable"}

provider_timeout=${CONFIG_provider_timeout:-300}
gm_wakeupperiod=$(config_print_option grid-manager wakeupperiod)
gm_wakeupperiod=${gm_wakeupperiod:-120}

if [ "x$infosys_compat" = "xenable" ]; then
    bdii_breathe_time=${CONFIG_bdii_breathe_time:-120}
    bdii_read_timeout=${CONFIG_bdii_read_timeout:-300}
else
    # The infoprovider does the waiting, no need for BDII to do it too.  Use
    # some small timeout to protect the system in case there is a problem with
    # the provier
    bdii_breathe_time=${CONFIG_bdii_breathe_time:-10}

    # $provider_timeout refers to a-rex's infoprovider. BDII must also include
    # the wait time till the next info collection cycle of a-rex.
    max_cycle=$(( $provider_timeout + $gm_wakeupperiod ))
    bdii_read_timeout=${CONFIG_bdii_read_timeout:-$max_cycle}
fi
bdii_delete_delay=${CONFIG_bdii_delete_delay:-0}

update_pid_file=${CONFIG_bdii_update_pid_file:-$bdii_run_dir/bdii-update.pid}
slapd_pid_file=${CONFIG_slapd_pid_file:-$bdii_run_dir/db/slapd.pid}

# Debian does not have /var/lock/subsys
if [ -d /var/lock/subsys ]; then
    update_lock_file=${update_lock_file:-/var/lock/subsys/arc-bdii-update}
    slapd_lock_file=${slapd_lock_file:-/var/lock/subsys/arc-bdii-slapd}
    lockfile=/var/lock/subsys/$prog
else
    update_lock_file=${update_lock_file:-/var/lock/arc-bdii-update}
    slapd_lock_file=${slapd_lock_file:-/var/lock/arc-bdii-slapd}
    lockfile=/var/lock/$prog
fi

# Check directories and permissions
registrationlog=${CONFIG_registrationlog:-/var/log/arc/inforegistration.log}
mkdir -p `dirname $registrationlog`

touch ${registrationlog}
chown ${bdii_user} ${registrationlog}

touch ${providerlog}
chown ${bdii_user} ${providerlog}

chown ${bdii_user} ${bdii_log_dir}

arc_runtime_config="/var/run/arc/infosys"
mkdir -p ${arc_runtime_config}
chown ${bdii_user} ${arc_runtime_config}

check_ownership ${arc_runtime_config} ${bdii_user}
check_ownership ${registrationlog} ${bdii_user}
check_ownership ${bdii_log_dir} ${bdii_user}
check_ownership ${providerlog} ${bdii_user}

# If the new code path is selected...
if [ "x$infosys_nordugrid" = "xenable" ] || [ "x$infosys_glue12" = "xenable" ] || [ "x$infosys_glue2_ldap" = "xenable" ]; then
    if [ "x$infosys_compat" != "xenable" ] && [ ! -f "$pkgdatadir/InfosysHelper.pm" ]; then
	log_warning_msg "A-REX is not installed"
	log_warning_msg "For operation without A-REX, disable publishing of cluster information"
	log_warning_msg "(infosys_nordugrid, infosys_glue12 and infosys_glue2_ldap)"
	log_warning_msg "or enable infosys_compat in configuration"
	exit 0
    fi
fi

if [ "x$infosys_compat" = "xenable" ]; then
    if [ "x$infosys_glue2_ldap" = "xenable" ]; then
	log_failure_msg "GLUE2 cannot be published when infosys_compat=enable"
	exit 1
    fi
fi

# Check for existance of core ldap schema
coreschema=$(find /etc/ -name core.schema -printf "%h/%f\n" 2>/dev/null)
if [ "x" = "x$coreschema" ]; then
    log_failure_msg "Error, could not find ldap core schema file under /etc"
    exit 1
fi

# Check for existence of a system ldap, this command will be used by bdii
slapd_cmd=""
if [ "x" = "x$CONFIG_slapd" ]; then
    O_IFS=$IFS
    IFS=:
    for dir in $PATH; do
	if [ -x "$dir/slapd" ]; then
	    slapd_cmd="$dir/slapd"
	    break
	fi
    done
    IFS=$O_IFS
else
    slapd_cmd=$CONFIG_slapd
fi

if [ ! -x $slapd_cmd ]; then
    log_failure_msg "Could not find ldap server binary, usually /usr/bin/slapd"
    log_failure_msg "Please update your PATH-variable."
    exit 1
fi


# If gris modules are not compiled into slapd, we will need to add variables to the config-file.
if [ $(grep -Ec "${bdii_database}_db_init|${bdii_database}_back_db_init" "$slapd_cmd") -eq 0 ]; then

    # Guess a likely directory for ldap modules
    ldaplib=$(find /usr/lib -name "back_${bdii_database}.so" -printf "%h/\n" 2>/dev/null)
    if [ "x" = "x$ldaplib" ]; then
	log_failure_msg "Could not find ldap libraries under /usr/lib"
	exit 1
    fi

    # This will get written to bdii slapd.conf:
    slapd_modulepath="modulepath      $ldaplib"
    slapd_moduleload="moduleload      back_${bdii_database}"
fi

# If giis modules are not compiled into slapd, we will need to add variables to the config-file.
if [ "`config_subsections infosys/index`" ]; then
    if [ $(grep -Ec "shell_db_init|shell_back_db_init" "$slapd_cmd") -eq 0 ]; then

	# Guess a likely directory for ldap modules
	ldaplib=${ldaplib:-$(find /usr/lib -name "back_shell.so" -printf "%h/\n" 2>/dev/null)}
	if [ "x" = "x$ldaplib" ]; then
	    log_failure_msg "Could not find ldap libraries under /usr/lib"
	    exit 1
	fi

	# This will get written to bdii slapd.conf:
	if [ -r ${giis_location}/lib64/arc/arc-infoindex-slapd-wrapper.so ]; then
	    pkglibdir=${giis_location}/lib64/arc
	elif [ -r ${giis_location}/lib/arc/arc-infoindex-slapd-wrapper.so ]; then
	    pkglibdir=${giis_location}/lib/arc
	else
	    error_echo "Error, could not find infoindex slapd wrapper"
	    exit 1
	fi
	slapd_modulepath="modulepath      $ldaplib:$pkglibdir"
	slapd_moduleload_index1="moduleload      back_shell"
	slapd_moduleload_index2="moduleload      arc-infoindex-slapd-wrapper"
    fi
fi

resource_location=""
resource_latitude=""
resource_longitude=""
cpuscalingreferencesi00=""
processorotherdescription=""
gluesiteweb=""
gluesiteuniqueid=""
provide_glue_site_info="true"

if [ "x$infosys_glue12" = "xenable" ]; then

    if ! config_match_section infosys/glue12 ; then
	log_failure_msg "infosys_glue12 is set to enable, but infosys/glue12 block is missing."
	exit 1
    fi

    config_import_section infosys/glue12
    resource_location=${CONFIG_resource_location}
    resource_latitude=${CONFIG_resource_latitude}
    resource_longitude=${CONFIG_resource_longitude}
    cpuscalingreferencesi00=${CONFIG_cpu_scaling_reference_si00}
    processorotherdescription=${CONFIG_processor_other_description}
    gluesiteweb=${CONFIG_glue_site_web}
    gluesiteuniqueid=${CONFIG_glue_site_unique_id}
    provide_glue_site_info=${CONFIG_provide_glue_site_info:-$provide_glue_site_info}

    if [ "x$resource_location" = "x" ]; then
	log_failure_msg "If infosys_glue12 is enabled, then resource_location must be set."
	log_failure_msg "It should be set to a free-form string describing the location,"
	log_failure_msg "for example: 'Kastrup, Denmark'"
	exit 1
    fi
    if [ "x$resource_latitude" = "x" ]; then
	log_failure_msg "If infosys_glue12 is enabled, then resource_latitude must be set."
	log_failure_msg "It should be set to the latitude for the location,"
	log_failure_msg "for example: '55.75000'"
	exit 1
    fi
    if [ "x$resource_longitude" = "x" ]; then
	log_failure_msg "If infosys_glue12 is enabled, then resource_longitude must be set."
	log_failure_msg "It should be set to the longitude for the location,"
	log_failure_msg "for example: '12.41670'"
	exit 1
    fi
    if [ "x$cpuscalingreferencesi00" = "x" ]; then
	log_failure_msg "If infosys_glue12 is enabled, then cpu_scaling_reference_si00 must be set."
	log_failure_msg "It should be set to the SI00 value,"
	log_failure_msg "for example: '2400'"
	exit 1
    fi
    if [ "x$processorotherdescription" = "x" ]; then
	log_failure_msg "If infosys_glue12 is enabled, then processor_other_description must be set."
	log_failure_msg "It should be set to a value like in the example,where cores is the average number"
	log_failure_msg "of cores in the machine"
	log_failure_msg "for example: 'Cores=3,Benchmark=9.8-HEP-SPEC06'"
	exit 1
    fi
    if [ "x$gluesiteweb" = "x" ]; then
	log_failure_msg "If infosys_glue12 is enabled, then glue_site_web must be set."
	log_failure_msg "It should be set to a url for the website belonging to the institution holding the resource,"
	log_failure_msg "for example: 'http://www.ndgf.org'"
	exit 1
    fi
    if [ "x$gluesiteuniqueid" = "x" ]; then
	log_failure_msg "If infosys_glue12 is enabled, then glue_site_unique_id must be set."
	log_failure_msg "It should be set to a unique id to the resource, this should be entered into the GocDb"
	log_failure_msg "for example: 'NDGF-T1'"
	exit 1
    fi

fi

# bdii.conf is put into nordugrid runtime directory
# together with other temporary files, needs to be exported so bdii can start
BDII_CONF=${CONFIG_bdii_conf:-${arc_runtime_config}/bdii.conf}
export BDII_CONF

giis_fifo=${CONFIG_giis_fifo:-$arc_runtime_config/giis-fifo}

# Call with: create_bdii_conf bdii_dir var_dir slapd_conf default_ldif port
# Will create bdii.conf file in /var/run/arc/infosys/bdii.conf
create_bdii_conf () {
    if [ $# != 7 ]; then
	error_echo "Wrong number of arguments to create_bdii_conf"
	error_echo "Arguments were: $*"
	exit 1
    fi
    bdii_location=$1
    bdii_var_dir=$2
    bdii_slapd_conf=$3
    bdii_port=$4
    bdii_ldif_dir=$5
    bdii_provider_dir=$6
    bdii_plugin_dir=$7

    rm -f ${BDII_CONF}
    std_header ${BDII_CONF}
    cat <<-EOF >> ${BDII_CONF}
	BDII_LOG_FILE=$bdii_log_file
	BDII_PID_FILE=$update_pid_file
	BDII_LOG_LEVEL=ERROR
	BDII_LDIF_DIR=$bdii_ldif_dir
	BDII_PROVIDER_DIR=$bdii_provider_dir
	BDII_PLUGIN_DIR=$bdii_plugin_dir
	BDII_PORT=$bdii_port
	BDII_BREATHE_TIME=$bdii_breathe_time
	BDII_READ_TIMEOUT=$bdii_read_timeout
	BDII_ARCHIVE_SIZE=$bdii_archive_size
	BDII_DELETE_DELAY=$bdii_delete_delay
	BDII_USER=$bdii_user
	BDII_VAR_DIR=$bdii_var_dir
	SLAPD_CONF=$bdii_slapd_conf
	EOF
}

# Call with: create_arc_slapd_conf bdii_dir bdii_slapd_conf_file
# Will create file $bdii_slapd_conf, normally located at:
# $bdii_run_dir/arc-slapd.conf
create_arc_slapd_conf () {
    if [ $# != 2 ]; then
	error_echo "Wrong number of arguments to create_arc_slapd_conf"
	error_echo "Arguments were: $*"
	exit 1
    fi
    bdii_location=$1
    bdii_slapd_conf=$2

    for i in "/etc/bdii/BDII.schema" \
	     "${bdii_location}/etc/BDII.schema" \
	     "$ARC_LOCATION/share/arc/ldap-schema/BDII.schema"; do

	if [ -r $i ]; then
	    bdii_schema=$i
	    break
	fi
    done

    rm -f $bdii_slapd_conf

    # ensure the configuration file is not world-readable,
    # as it contains the slapd database password
    (umask 077; > $bdii_slapd_conf)
    std_header $bdii_slapd_conf
    cat <<-EOF >> $bdii_slapd_conf
	include ${coreschema}

	#bdii specific schemas
	include $bdii_schema

	#nordugrid specific schemas
	include $ARC_LOCATION/share/arc/ldap-schema/nordugrid.schema
	#glue schemas
	include /etc/ldap/schema/Glue-CORE.schema
	include /etc/ldap/schema/Glue-CE.schema
	include /etc/ldap/schema/Glue-CESEBind.schema
	#glue2 schema
	include /etc/ldap/schema/GLUE20.schema

	$slapd_modulepath
	$slapd_moduleload
	$slapd_moduleload_index1
	$slapd_moduleload_index2

	allow bind_v2

	pidfile         $bdii_run_dir/db/slapd.pid
	argsfile        $bdii_run_dir/db/slapd.args
	loglevel        $slapd_loglevel
	threads         $threads
	idletimeout     120
	sizelimit       unlimited
	timelimit       2400
	EOF
}

add_info_service () {
    if [ $# != 2 ]; then
	error_echo "Wrong number of arguments to add_info_service"
	error_echo "Arguments were: $*"
	exit 1
    fi
    suffix=$1
    rootdn=$2
    cat <<-EOF >> $bdii_slapd_conf

	# ${bdii_database} database definitions for $rootdn
	database        ${bdii_database}
	cachesize       150000
	dbnosync
	suffix          "$suffix"
	checkpoint      131072 60
	rootdn          "$rootdn"
	rootpw          secret
	directory       $bdii_var_dir/db/arc

	# ${bdii_database} database definitions for o=glue
	database        ${bdii_database}
	cachesize       150000
	dbnosync
	suffix          "o=glue"
	checkpoint      131072 60
	rootdn          "o=glue"
	rootpw          secret
	directory       $bdii_var_dir/db/glue2

	# Infosys database definitions
	database        ${bdii_database}
	cachesize       60
	dbnosync
	suffix          "o=infosys"
	checkpoint      131072 60
	rootdn          "o=infosys"
	rootpw          secret
	directory       $bdii_var_dir/db/stats
	EOF
}

# Call with: create_default_ldif bdii_default_ldif_file
# Will create file $bdii_default_ldif, normally located at:
# ${bdii_tmp_dir}/arc-default.ldif.pl
create_default_ldif () {
    if [ $# != 1 ]; then
	error_echo "Wrong number of arguments to create_default_ldif"
	error_echo "Arguments were: $*"
	exit 1
    fi

    bdii_default_ldif=$1

    debug_echo Creating file: $bdii_default_ldif

    cat <<-EOF > $bdii_default_ldif
	#!/usr/bin/perl

	# This file was automatically generated by $prog startup script.
	# Do not modify.

	use POSIX;

	print "\n";
	print "dn: o=Grid\n";
	print "objectClass: organization\n";
	print "o: Grid\n";
	print "\n";

	print "dn: Mds-Vo-name=local,o=Grid\n";
	print "objectClass: Mds\n";
	print "objectClass: MdsVo\n";
	print "Mds-Vo-name: local\n";
	print "Mds-validfrom: " . strftime("%Y%m%d%H%M%SZ\n", gmtime());
	print "Mds-validto: " . strftime("%Y%m%d%H%M%SZ\n", gmtime(time() + 3600));
	print "\n";

	print "dn: Mds-Vo-name=resource,o=Grid\n";
	print "objectClass: Mds\n";
	print "objectClass: MdsVo\n";
	print "Mds-Vo-name: resource\n";
	print "Mds-validfrom: " . strftime("%Y%m%d%H%M%SZ\n", gmtime());
	print "Mds-validto: " . strftime("%Y%m%d%H%M%SZ\n", gmtime(time() + 3600));
	print "\n";

	print "dn: o=glue\n";
	print "objectClass: top\n";
	print "objectClass: organization\n";
	print "o: glue\n";
	EOF

    chmod +x $bdii_default_ldif
}

# Call with create_arc_ldif_generator_compat bdii_tmp_dir ldif_generator_file_ng
# Will create $ldif_generator_file_ng, normally located at:
# ${bdii_tmp_dir}/arc-nordugrid-bdii-ldif
create_arc_ldif_generator_compat () {
    if [ $# != 2 ]; then
	error_echo "Wrong number of arguments to create_arc_ldif_generator_compat"
	error_echo "Arguments were: $*"
	exit 1
    fi

    bdii_tmp_dir=$1
    ldif_generator_file=$2

    rm -f ${ldif_generator_file}
    touch ${ldif_generator_file}
    std_header ${ldif_generator_file}

    if config_match_section cluster; then
	(
	    config_hide_all
	    config_set_defaults
	    config_import_section common
	    config_import_section infosys
	    if [ ! -f $providerlog ]; then
		touch $providerlog
	    fi
	    chown ${bdii_user}:${bdii_user} ${providerlog}
	    config_import_section cluster
	    cachetime=${CONFIG_cachetime:-$bdii_breathe_time}

	    cat <<-EOF >> ${ldif_generator_file}
		$ARC_LOCATION/share/arc/cluster.pl --valid-to $cachetime --config $ARC_CONFIG --loglevel $CONFIG_provider_loglevel --dn nordugrid-cluster-name=$hostname,Mds-Vo-name=local,o=Grid 2>> "$providerlog"
		EOF

	    # Create entries for all queues
	    for queue in `config_subsections queue`; do
		(
		    config_import_section queue/$queue
		    cachetime=${CONFIG_cachetime:-$bdii_breathe_time}

		    cat <<-EOF >> ${ldif_generator_file}
			$ARC_LOCATION/share/arc/qju.pl --valid-to $cachetime --config $ARC_CONFIG --loglevel $CONFIG_provider_loglevel --dn nordugrid-queue-name=$queue,nordugrid-cluster-name=$hostname,Mds-Vo-name=local,o=Grid --queue $queue 2>> "$providerlog"
			EOF
		)
	    done
	)
    fi

    for se in `config_subsections se`; do
	(
	    config_hide_all
	    config_set_defaults
	    config_import_section common
	    config_import_section infosys
	    if [ ! -f $providerlog ]; then
		touch $providerlog
	    fi
	    chown ${bdii_user}:${bdii_user} ${providerlog}
	    config_import_section se/$se
	    cachetime=${CONFIG_cachetime:-$bdii_breathe_time}

	    cat <<-EOF >> ${ldif_generator_file}
		$ARC_LOCATION/share/arc/se.pl -valid-to $cachetime -config $ARC_CONFIG -dn nordugrid-se-name=$se:$hostname,Mds-Vo-name=local,o=Grid -se $se 2>> "$providerlog"
		EOF
	)
    done

    chmod +x ${ldif_generator_file}
}

# Call with create_arc_ldif_generator arc_runtime_config ldif_generator_file_ng ldif_generator_file_glue
# Will create $ldif_generator_file, normally located at:
# ${bdii_tmp_dir}/arc-nordugrid-bdii-ldif
create_arc_ldif_generator () {
    if [ $# != 3 ]; then
	error_echo "Wrong number of arguments to create_arc_ldif_generator"
	error_echo "Arguments were: $*"
	exit 1
    fi

    arc_runtime_config=$1
    ldif_generator_file=$2
    ldif_glue12_generator=$3

    ldif_script="$arc_runtime_config/ldif-provider.sh"

    rm -f ${ldif_generator_file}
    touch ${ldif_generator_file}

    cat <<-EOF > ${ldif_generator_file}
	#!/usr/bin/perl

	# This file was automatically generated by the $prog startup script.
	# Do not modify.
	EOF

    for se in `config_subsections se`; do
	(
	    config_hide_all
	    config_set_defaults
	    config_import_section common
	    config_import_section infosys
	    if [ ! -f $providerlog ]; then
		touch $providerlog
	    fi
	    chown ${bdii_user}:${bdii_user} ${providerlog}
	    config_import_section se/$se
	    cachetime=${CONFIG_cachetime:-$max_cycle}

	    cat <<-EOF >> ${ldif_generator_file}
			BEGIN {
			    print "\n";
			    system('$ARC_LOCATION/share/arc/se.pl -valid-to $cachetime -config $ARC_CONFIG -dn nordugrid-se-name=$se:$hostname,Mds-Vo-name=local,o=Grid -se $se 2>> "$providerlog"');
			}
			EOF
	)
    done

    # NG and GLUE2 come directly from a-rex infoprovider
    cat <<-EOF >> ${ldif_generator_file}

	BEGIN { unshift @INC, '$pkgdatadir'; }
	use InfosysHelper;
	exit 1 unless InfosysHelper::ldifIsReady('$arc_runtime_config', '$max_cycle');
	EOF

    if [ "x$infosys_nordugrid" = "xenable" ] || [ "x$infosys_glue2_ldap" = "xenable" ]; then
	echo "system('$ldif_script');" >> ${ldif_generator_file}
    fi

    if [ "x$infosys_glue12" = "xenable" ]; then
	# Call with create_glue_ldif_generator bdii_tmp_dir ldif_generator_file_ng ldif_generator_file_glue
	create_glue_ldif_generator $bdii_tmp_dir $ldif_script $ldif_glue12_generator
	echo "system('$ldif_glue12_generator');" >> ${ldif_generator_file}
    fi

    chmod +x ${ldif_generator_file}
}

create_registration_config_file () {
    std_header $arc_runtime_config/grid-info-resource-register.conf
    (
	config_hide_all
	config_set_defaults
	config_import_section common
	config_import_section infosys

	# Start with the Cluster registration blocks
	for p in `config_subsections infosys/cluster/registration`; do
	(
	    config_import_section infosys/cluster/registration/$p

	    targetsuffix=${CONFIG_targetsuffix:-"Mds-Vo-name=$p,o=Grid"}
	    reghn=${CONFIG_targethostname:-"targethostname.not.set"}
	    regport=${CONFIG_targetport:-2135}
	    hn=${CONFIG_registranthostname:-$hostname}
	    port=${CONFIG_registrantport:-$CONFIG_port}
	    rootdn=${CONFIG_registrantsuffix:-"nordugrid-cluster-name=$hn,Mds-Vo-name=local,o=Grid"}
	    regperiod=${CONFIG_regperiod:-120}
	    ttl=${CONFIG_ttl:-$(( $regperiod * 2 ))}
	    timeout=${CONFIG_timeout:-45}
	    cachettl=${CONFIG_cachettl:-0}
	    sizelimit=${CONFIG_sizelimit:-0}
	    bindmethod=${CONFIG_bindmethod:-ANONYM-ONLY}

	    debug_echo "Cluster Tree on $hn:$port/$rootdn REGISTERS to $reghn:$regport/$targetsuffix"
	    printregldif >> $arc_runtime_config/grid-info-resource-register.conf

	)
	done

	# Now process the SE registration blocks
	for seentry in `config_subsections infosys/se`; do
	(
	    config_import_section infosys/se
	    CONFIG_name=
	    config_import_section se/$seentry
	    sename=${CONFIG_name:-$seentry}
	    config_import_section infosys/se/$seentry

	    for p in `config_subsections infosys/se/$seentry/registration`; do
	    (
		config_import_section infosys/se/$seentry/registration
		config_import_section infosys/se/$seentry/registration/$p

		targetsuffix=${CONFIG_targetsuffix:-"Mds-Vo-name=$p,o=Grid"}
		reghn=${CONFIG_targethostname:-"targethostname.not.set"}
		regport=${CONFIG_targetport:-2135}
		hn=${CONFIG_registranthostname:-$hostname}
		port=${CONFIG_registrantport:-$CONFIG_port}
		rootdn=${CONFIG_registrantsuffix:-"nordugrid-se-name=$sename:$hn,Mds-Vo-name=local,o=Grid"}
		regperiod=${CONFIG_regperiod:-120}
		ttl=${CONFIG_ttl:-$(( $regperiod * 2 ))}
		timeout=${CONFIG_timeout:-45}
		cachettl=${CONFIG_cachettl:-0}
		sizelimit=${CONFIG_sizelimit:-0}
		bindmethod=${CONFIG_bindmethod:-ANONYM-ONLY}

		debug_echo "$seentry SE Tree on $hn:$port/$rootdn REGISTERS to $reghn:$regport/$targetsuffix"
		printregldif >> $arc_runtime_config/grid-info-resource-register.conf

	    )
	    done

	)
	done # loop over SEs
    )
}

add_index_services () {
    (
	config_hide_all
	config_set_defaults
	config_import_section common
	config_import_section infosys

	# Defaults for the Index Service slapd.conf block

	access="access to * by * write"

	for vo in `config_subsections infosys/index`; do
	(
	    debug_echo "Enabling the Index Service $vo"

	    CONFIG_name=
	    config_import_section infosys/index/$vo
	    indexname=${CONFIG_name:-$vo}

	    cat <<-EOF >> $bdii_slapd_conf

		# Index Service: $vo
		database        shell
		suffix          "Mds-Vo-name=$indexname,o=Grid"
		bind            $giis_location/sbin/arc-infoindex-relay $giis_fifo
		add             $giis_location/sbin/arc-infoindex-relay $giis_fifo
		search          $giis_location/sbin/arc-infoindex-relay $giis_fifo
		$access
		EOF

	    # Registrations of the Index Services

	    # grid-info-resource-register.conf

	    for r in `config_subsections infosys/index/$vo/registration`; do
	    (
		config_import_section infosys/index/$vo/registration/$r

		targetsuffix=${CONFIG_targetsuffix:-"Mds-Vo-name=$r,o=Grid"}
		reghn=$CONFIG_targethostname
		regport=${CONFIG_targetport:-2135}
		hn=${CONFIG_registranthostname:-$hostname}
		port=${CONFIG_registrantport:-$CONFIG_port}
		rootdn=${CONFIG_registrantsuffix:-"Mds-Vo-name=$indexname,o=Grid"}
		regperiod=${CONFIG_regperiod:-120}
		ttl=${CONFIG_ttl:-$(( $regperiod * 2 ))}
		timeout=${CONFIG_timeout:-120}
		cachettl=${CONFIG_cachettl:-0}
		sizelimit=${CONFIG_sizelimit:-0}
		bindmethod=${CONFIG_bindmethod:-ANONYM-ONLY}

		if [ -n "$targetsuffix" -a -n "$reghn" ]; then
		    printregldif >> $arc_runtime_config/grid-info-resource-register.conf
		    debug_echo "Index Service $hn:$port/$rootdn REGISTERS to $reghn:$regport/$targetsuffix"
		fi

	    )
	    done

	)
	done
    )
}

# Call with create_glue_ldif_generator bdii_tmp_dir ldif_generator_file_ng ldif_generator_file_glue
# Will create $ldif_generator_file_glue, normally located at:
# ${bdii_tmp_dir}/arc-glue-bdii-ldif
create_glue_ldif_generator () {
    if [ $# != 3 ]; then
	error_echo "Wrong number of arguments to create_glue_ldif_generator"
	error_echo "Arguments were: $*"
	exit 1
    fi

    bdii_tmp_dir=$1
    ldif_generator_file_ng=$2
    ldif_generator_file_glue=$3

    rm -f ${ldif_generator_file_glue}
    touch ${ldif_generator_file_glue}

    # We use , instead of / here to allow for / in path, resource_location though, can contain commas..
    sed "s,\$LDIF_GENERATOR_FILE_NG,$ldif_generator_file_ng,g;
	 s/\$LOC/\"$resource_location\"/g;
	 s/\$LAT/$resource_latitude/g;
	 s/\$LONG/$resource_longitude/g;
	 s/\$CPUSCALINGREFERENCESI00/$cpuscalingreferencesi00/g;
	 s/\$PROCESSOROTHERDESCRIPTION/$processorotherdescription/g;
	 s,\$GLUESITEWEB,$gluesiteweb,g;
	 s,\$BDIIPORT,$bdii_port,g;
	 s,\$GLUESITEUNIQUEID,$gluesiteuniqueid,g;
	 s,\$PROVIDE_GLUE_SITE_INFO,$provide_glue_site_info,g;
	" $ARC_LOCATION/share/arc/glue-generator.pl > ${ldif_generator_file_glue}

    chmod +x ${ldif_generator_file_glue}
}

# Function to create a directory, removes it if it exist and then
# creates it and checks permissions.
# Call with create_directory dir context
create_directory () {
    if [ $# != 2 ]; then
	error_echo "Wrong number of arguments to create_directory"
	error_echo "Arguments were: $*"
	exit 1
    fi

    dir=$1
    string=$2
    id=`id -u`

    if [ ${#dir} -le "1" ]; then
	error_echo "$string error: directory string: $dir is too short"
	exit 1
    fi

    if [ -e ${dir} ]; then
	rm -rf $dir
    fi

    #set rights
    umask 0022
    mkdir -p ${dir}

    #check ownership just to be sure
    if [ ! -O ${dir} ]; then
	error_echo "$string error: $dir should be owned by uid:$id"
	exit 1
    fi
}

# A call to this function will create necessary config-files for bdii to be used
create_bdii_config_files () {

    # Create bdii.conf
    # Call with: create_bdii_conf bdii_dir var_dir slapd_conf default_ldif bdii_port
    create_bdii_conf $bdii_location $bdii_var_dir $bdii_slapd_conf $bdii_port $bdii_ldif_dir $bdii_provider_dir $bdii_plugin_dir

    # Create arc-slapd.conf, will be copied to dirs where slapd is run
    # Call with: create_arc_slapd_conf bdii_dir bdii_slapd_conf_file
    create_arc_slapd_conf $bdii_location $bdii_slapd_conf

    # Create bdii default ldif
    # Call with: create_default_ldif bdii_default_ldif_file
    create_default_ldif $bdii_default_ldif_ng

    if [ "x$infosys_compat" = "xenable" ]; then

	# Create arc-nordugrid-bdii-ldif, generates ldif-files for nordugrid schema.
	if [ "x$infosys_nordugrid" = "xenable" ]; then
	    # Call with create_arc_ldif_generator_compat bdii_tmp_dir ldif_generator_file
	    create_arc_ldif_generator_compat $bdii_tmp_dir ${bdii_tmp_dir}/provider/arc-nordugrid-bdii-ldif
	fi
    
	# Create arc-glue-bdii-ldif, generates ldif-files for glue schema
	if [ "x$infosys_glue12" = "xenable" ]; then
	    # Call with create_glue_ldif_generator bdii_tmp_dir ldif_generator_file_ng ldif_generator_file_glue
	    create_glue_ldif_generator $bdii_tmp_dir ${bdii_tmp_dir}/provider/arc-nordugrid-bdii-ldif ${bdii_tmp_dir}/provider/arc-glue-bdii-ldif
	fi

    else

	# Call with create_arc_ldif_generator arc_runtime_config ldif_generator_file_ng ldif_generator_file_glue
	create_arc_ldif_generator $arc_runtime_config ${bdii_tmp_dir}/provider/arc-nordugrid-bdii-ldif ${arc_runtime_config}/arc-glue-bdii-ldif

    fi

    # Site BDII
    for site_bdii in `config_subsections infosys/site`; do

      config_import_section infosys/site/$site_bdii
      unique_id=${CONFIG_unique_id:-$site_bdii}
      site_config="${bdii_tmp_dir}/${site_bdii}.conf"
      site_provider="$bdii_provider_dir/site_${site_bdii}.sh"
      # We should have a loop over urls here
      # LOOP START
	url=${CONFIG_url}
	echo "$unique_id $url" > "$site_config"
      # LOOP END 
      # Create script
      printf "#!/bin/sh\n/$ARC_LOCATION/share/arc/glite-info-provider-ldap -m \"$site_bdii\" -c $site_config\n" > $site_provider
      chmod +x $site_provider
    done

    # Resource (cluster or SE) registrations
    # grid-info-resource-register.conf
    create_registration_config_file

    # Index Services: generating the config files
    add_index_services

    # Local Information Service
    add_info_service $bdii_bind $bdii_bind

}

# Print some information about where to find bdii logs
notify_about_bdii () {
    debug_echo "Nordugrid ARC as of version 0.8 uses BDII for"
    debug_echo "information handling instead of the globus based infosys"
    debug_echo "that was used before. The change is backwards compatible."
    debug_echo "BDII writes logs here that you may want to check if something"
    debug_echo "is not working: "
    debug_echo " ${bdii_log_dir}"
    debug_echo "Also, if the BDII run-directory is here:"
    debug_echo " ${bdii_var_dir}"
    debug_echo "That can also be worth checking up on if something is broken."
}

# Checks status, if unclean shutdown occured, clean up
check_clean_status () {
    if [ -f "${slapd_lock_file}" ]; then
	if [ -f "${slapd_pid_file}" ]; then
	    slapd_pid=`cat "${slapd_pid_file}"`
	    if ps -p "$slapd_pid" > /dev/null; then
		# running
		log_success_msg "Starting $prog"
		log_success_msg "$prog already started"
		exit 0
	    else
		rm -f "${slapd_pid_file}"
	    fi
	fi
	rm -f "${slapd_lock_file}"
    fi
    if [ -f "${update_lock_file}" ]; then
	if [  -f "${update_pid_file}" ]; then
	    update_pid=`cat "${update_pid_file}"`
	    if ps -p "$update_pid" > /dev/null; then
		# running
		log_success_msg "Starting $prog"
		log_success_msg "$prog already started"
		exit 0
	    else
		rm -f "${update_pid_file}"
	    fi
	fi
	rm -f "${update_lock_file}"
    fi
}

start () {
    # Check status
    check_clean_status

    # Print help-message about new logs
    notify_about_bdii

    # Check that you are not in a directory that will be removed by the script
    check_cwd

    # Create directories for storing temporary scripts and check permissions etc
    create_directory $bdii_var_dir "BDII_VAR_DIR"
    create_directory $bdii_tmp_dir "BDII_TMP_DIR"
    create_directory $bdii_tmp_dir/ldif "BDII_TMP_DIR/ldif"
    create_directory $bdii_tmp_dir/provider "BDII_TMP_DIR/provider"
    create_directory $bdii_tmp_dir/plugin "BDII_TMP_DIR/plugin"
    create_bdii_config_files

    #Initialize the database directory
    create_directory $bdii_run_dir/db "BDII_RUN_DIR/db"
    chown -R $bdii_user:$bdii_user $bdii_run_dir
    [ -x /sbin/restorecon ] && /sbin/restorecon -R $bdii_run_dir/db
    create_directory $bdii_var_dir/db/arc "BDII_VAR_DIR/db/arc"
    create_directory $bdii_var_dir/db/glue2 "BDII_VAR_DIR/db/glue2"
    create_directory $bdii_var_dir/db/stats "BDII_VAR_DIR/db/stats"
    chown -R $bdii_user:$bdii_user $bdii_var_dir/db
    [ -x /sbin/restorecon ] && /sbin/restorecon -R $bdii_var_dir/db
    create_directory $bdii_var_dir/archive "BDII_VAR_DIR/archive"
    chown -R $bdii_user:$bdii_user $bdii_var_dir
    chown -R $bdii_user:$bdii_user $bdii_tmp_dir
    if [ ! -f $bdii_log_file ]; then
	touch $bdii_log_file
    fi
    chown $bdii_user:$bdii_user $bdii_log_file
    $RUNUSER -s "$USERSHELL" -c "cp ${bdii_db_config} ${bdii_var_dir}/db/arc" $bdii_user
    $RUNUSER -s "$USERSHELL" -c "cp ${bdii_db_config} ${bdii_var_dir}/db/glue2" $bdii_user
    $RUNUSER -s "$USERSHELL" -c "cp ${bdii_db_config} ${bdii_var_dir}/db/stats" $bdii_user
    #Need to remove / from mkpasswd, otherwise sed will break.
    pass=`/usr/bin/mkpasswd -s 0 2> /dev/null` || pass=$RANDOM$RANDOM
    pass=${pass//\//x}

    if [ ! -f ${bdii_slapd_conf} ]; then
	log_failure_msg "Can not find slapd file: ${bdii_slapd_conf}"
	exit 1
    fi

    sed -i "s/secret/${pass}/g" $bdii_slapd_conf
    [ -x /sbin/restorecon ] && /sbin/restorecon $bdii_slapd_conf

    # Finished with the config file generation.
    # Time to start the whole infosys

    # If index-server configured, start it
    if [ "`config_subsections infosys/index`" ]; then
	$RUNUSER -s "$USERSHELL" -c "${giis_location}/sbin/arc-infoindex-server -c $ARC_CONFIG -f $giis_fifo" ${bdii_user}
    fi

    # Start BDII

    chown -R $bdii_user "${bdii_var_dir}/"

    echo -n "Starting $prog: "

    if [ "`config_subsections infosys/index`" ]; then
	if [ -r ${giis_location}/lib64/arc/arc-infoindex-slapd-wrapper.so ]; then
	    pkglibdir=${giis_location}/lib64/arc
	elif [ -r ${giis_location}/lib/arc/arc-infoindex-slapd-wrapper.so ]; then
	    pkglibdir=${giis_location}/lib/arc
	else
	    error_echo "Error, could not find infoindex slapd wrapper"
	    exit 1
	fi
	# The -d 0 is important for the GIIS to ensure that the binary doesn't fork.
	if [ "x$slapd_hostnamebind" = "x*" ]; then
	    ARC_LDAPLIB_SHELL=${ldaplib}/back_shell.so \
		LD_PRELOAD=${pkglibdir}/arc-infoindex-slapd-wrapper.so \
		${slapd_cmd} -d 0 -f ${bdii_slapd_conf} -h "ldap://${slapd_hostnamebind}:${bdii_port}" \
		-u ${bdii_user} </dev/null 1>/dev/null 2>/dev/null &
	else
	    ARC_LDAPLIB_SHELL=${ldaplib}/back_shell.so \
		LD_PRELOAD=${pkglibdir}/arc-infoindex-slapd-wrapper.so \
		${slapd_cmd} -d 0 -f ${bdii_slapd_conf} -h "ldap://localhost:${bdii_port} ldap://${slapd_hostnamebind}:${bdii_port}" \
		-u ${bdii_user} </dev/null 1>/dev/null 2>/dev/null &
	fi
    else
	if [ "x$slapd_hostnamebind" = "x*" ]; then
	    ${slapd_cmd} -f ${bdii_slapd_conf} -h "ldap://${slapd_hostnamebind}:${bdii_port}" -u ${bdii_user}
	else
	    ${slapd_cmd} -f ${bdii_slapd_conf} -h "ldap://localhost:${bdii_port} ldap://${slapd_hostnamebind}:${bdii_port}" -u ${bdii_user}
	fi
    fi

    touch ${slapd_lock_file}

    iterlimit=30
    while [ $iterlimit -ge 0 ] && ! [ -f ${slapd_pid_file} ]; do
    echo -n "*"
        sleep 1
        iterlimit=$(expr $iterlimit - 1)
    done

    if [ -f "${slapd_pid_file}" ]; then
	ps $(cat ${slapd_pid_file}) >/dev/null 2>&1
	RETVAL=$?
    else
	RETVAL=1
    fi

    if [ ${RETVAL} -gt 0 ]; then
	log_failure_msg
	log_failure_msg "$prog SLAPD failed to start"
	rm -f ${slapd_lock_file}
	log_failure_msg "Error was: "
	if [ "x$slapd_hostnamebind" = "x*" ]; then
	    ${slapd_cmd} -d 1 -f ${bdii_slapd_conf} -h "ldap://${slapd_hostnamebind}:${bdii_port}" -u ${bdii_user}
	else
	    ${slapd_cmd} -d 1 -f ${bdii_slapd_conf} -h "ldap://localhost:${bdii_port} ldap://${slapd_hostnamebind}:${bdii_port}" -u ${bdii_user}
	fi
	exit 1
    fi

    $RUNUSER -s "$USERSHELL" -c "${bdii_update_cmd} -c ${BDII_CONF} -d" ${bdii_user}
    touch ${update_lock_file}

    if [ ! -f ${update_pid_file} ]; then
	sleep 2
    fi
    if [ -f ${update_pid_file} ]; then
	ps $(cat ${update_pid_file}) >/dev/null 2>&1
	RETVAL=$?
    else
	log_failure_msg
	exit 1
    fi

    if [ ${RETVAL} -gt 0 ]; then
	log_failure_msg
	log_failure_msg "$prog update process failed to start"
	rm -f ${update_lock_file}
	exit 1
    else
	touch $lockfile
	RETVAL=0
    fi

    # Info registration
    if [ "x$infosys_nordugrid" = "xenable" ]; then
	$ARC_LOCATION/share/arc/grid-info-soft-register -log $registrationlog -f $arc_runtime_config/grid-info-resource-register.conf -p `cat ${update_pid_file}` 1>/dev/null 2>/dev/null &
    fi

    log_success_msg
}

stop () {
    # Stop GRIS

    # Check that you are not in a directory that will be removed by this script.
    check_cwd

    # Check the existance of the lock file
    if [ ! -f "${slapd_lock_file}" ] &&  [ ! -f "${update_lock_file}" ]; then
	echo -n "Stopping $prog: "
	result=$($0 status)
	if [ $? -gt 0 ]; then
	    log_failure_msg
	    echo ${result} 1>&2
	    return 1
	else
	    log_success_msg "$prog already stopped"
	    return 0
	fi
    fi

    echo -n "Stopping $prog: "

    # Kill waiting provider script
    killall -u ${bdii_user} -15 arc-nordugrid-bdii-ldif 2>/dev/null

    if [ -f "${update_pid_file}" ]; then
	update_pid=$(cat ${update_pid_file})
    else
	log_failure_msg
	log_failure_msg "$prog update process has no pid-file"
	return 1
    fi

    if [ -n "${update_pid}" ]; then
	$RUNUSER -s "$USERSHELL" -c "kill -15 ${update_pid} 2>/dev/null" ${bdii_user}

	ps ${update_pid} >/dev/null 2>&1
	if [ $? = 0 ]; then
	    sleep 2
	    ps ${update_pid} >/dev/null 2>&1
	    if [ $? = 0 ]; then
		$RUNUSER -s "$USERSHELL" -c "kill -9 ${update_pid} 2>/dev/null" ${bdii_user}
		sleep 2
		ps ${update_pid} >/dev/null 2>&1
		if [ $? = 0 ]; then
		    RETVAL=1
		fi
	    fi

	fi
    fi

    if [ ${RETVAL} = 0 ];  then
	rm -f ${update_pid_file}
	rm -f ${update_lock_file}
    else
	log_failure_msg
	log_failure_msg "Could not kill $prog update process with pid ${update_pid}"
    fi

    if [ -f "${slapd_pid_file}" ]; then
	slapd_pid=$(cat ${slapd_pid_file})
    else
	log_failure_msg
	log_failure_msg "$prog SLAPD process has no pid-file"
	return 1
    fi

    if [ -n "${slapd_pid}" ]; then
	$RUNUSER -s "$USERSHELL" -c "kill -15 ${slapd_pid} 2>/dev/null" ${bdii_user}
	ps ${slapd_pid} >/dev/null 2>&1
	if [ $? = 0 ]; then
	    sleep 2
	    ps ${slapd_pid} >/dev/null 2>&1
	    if [ $? = 0 ]; then
		$RUNUSER -s "$USERSHELL" -c "kill -9 ${slapd_pid} 2>/dev/null" ${bdii_user}
		sleep 2
		ps ${slapd_pid} >/dev/null 2>&1
		if [ $? = 0 ]; then
		    RETVAL=2
		else
		    rm -f {slapd_pid_file}
		fi

	    fi
	fi
    fi

    if [ ${RETVAL} = 2 ];  then
	log_failure_msg
	log_failure_msg "Error, could not stop $prog slapd with pid: $slapd_pid"
    else
	rm -f ${slapd_lock_file}
    fi

    # Stop GIIS
    [ -p $giis_fifo ] && echo STOP > $giis_fifo

    # Clean up
    rm -rf ${bdii_var_dir}
    rm -rf ${bdii_tmp_dir}
    rm -f ${arc_runtime_config}/arc-glue-bdii-ldif

    if [ ! ${RETVAL} = 0 ];  then
	log_failure_msg
	return 1
    else
	# lockfile is to make sure that bdii gets a clean shutdown with system
	rm -f $lockfile
    fi

    log_success_msg
    return ${RETVAL}
}

status ()  {
    if [ ! -f "${slapd_lock_file}" ] && [ ! -f "${update_lock_file}" ]; then
	log_success_msg "BDII Stopped"
	RETVAL=3
	return ${RETVAL}
    fi

    if [ -f ${slapd_pid_file} ]; then
	ps $(cat ${slapd_pid_file}) >/dev/null 2>&1
	if [ ! $? = 0 ]; then
	    log_failure_msg "slapd pid file exists: ${slapd_pid_file} but the process died"
	    RETVAL=1
	    return ${RETVAL}
	fi
    else
	log_failure_msg "slapd lock file: ${slapd_lock_file} and/or"
	log_failure_msg "bdii-update lock file: ${update_lock_file} exists but"
	log_failure_msg "slapd pid file: ${slapd_pid_file} does not exist."
	log_failure_msg "Maybe you had an unclean shutdown, please remove"
	log_failure_msg "lockfiles and retry starting $prog"
	RETVAL=1
	return ${RETVAL}
    fi

    if [ -f ${update_pid_file} ]; then
	ps $(cat ${update_pid_file}) >/dev/null 2>&1
	if [ ! $? = 0 ]; then
	    log_failure_msg "bdii-update pid file exists: ${update_pid_file} but the update process died"
	    RETVAL=1
	    return ${RETVAL}
	fi
    else
	log_failure_msg "slapd lock file: $slapd_lock_file and/or"
	log_failure_msg "bdii-update lock file: ${update_lock_file} exists but"
	log_failure_msg "update process pid file: ${update_pid_file} does not exist"
	log_failure_msg "maybe you had an unclean shutdown, please remove"
	log_failure_msg "lockfiles and retry starting $prog"
	RETVAL=1
	return ${RETVAL}
    fi

    log_success_msg "BDII Running"
    RETVAL=0
    return ${RETVAL}
}
