#!/bin/bash
##
## OpenLDAP: Run slapd with parameters via environment variables
## Copyright (c) 2019 SATOH Fumiyasu @ OSS Technology Corp., Japan
##
## License: GNU General Public License version 3
##

set -u

run() {
  if [[ -n ${SLAPD_RUN_INFO-set} ]]; then
    echo "$0: INFO: Run: $*"
  fi
  "$@"
}

run_or_die() {
  run "$@" || exit $?
}

debug() {
  sed "s#^#$0: DEBUG: #" 1>&2
}

envdir() {
  local envname_prefix='SLAPD_'

  local envdir="$1"; shift
  local envfile envname

  for envfile in "$envdir"/*; do
    [[ -f $envfile ]] || continue
    envname="$envname_prefix${envfile##*/}"
    [[ $envname =~ ^[A-Za-z_][A-Za-z_0-9]*$ ]] || continue
    if [[ -s $envfile ]]; then
      ## Prefer external environment variables to envdir
      if eval '[[ -z ${'"$envname"'+set} ]]'; then
	IFS= read -r "$envname" <"$envfile" || return $?
	export "$envname"
      fi
    else
      unset "$envname"
    fi
  done

  return 0
}

if [[ -n ${SLAPD_RUN_DEBUG-} ]]; then
  PS4="$0: DEBUG: "
  set -x
fi

## ======================================================================

envdir="${SLAPD_RUN_ENVDIR-/opt/osstech/etc/openldap/service/slapd/env}"

if [[ -n $envdir ]]; then
  run_or_die envdir "$envdir"

  ## Backward compatibility for the old envdir (slapd-svconf for daemontools)
  [[ -n ${SLAPD_CONFIGFILE-} ]] && export SLAPD_CONF="$SLAPD_CONFIGFILE"
  [[ -n ${SLAPD_DEBUGLEVEL-} ]] && export SLAPD_DEBUG_LEVEL="$SLAPD_DEBUGLEVEL"
  [[ -n ${SLAPD_SYSLOGLEVEL-} ]] && export SLAPD_SYSLOG_LEVEL="$SLAPD_SYSLOGLEVEL"
  [[ -n ${SLAPD_SYSLOGFACILITY-} ]] && export SLAPD_SYSLOG_FACILITY="$SLAPD_SYSLOGFACILITY"
  if [[ -n ${SLAPD_DEBUGGER-} ]]; then
    export SLAPD_WRAPPER_COMMAND="env"
    export SLAPD_WRAPPER_OPTIONS="$SLAPD_DEBUGGER"
  fi
  if [[ -n ${SLAPD_MEMORYLIMIT-} ]]; then
    export SLAPD_LIMIT_DATA="$SLAPD_MEMORYLIMIT"
    export SLAPD_LIMIT_STACK="$SLAPD_MEMORYLIMIT"
    export SLAPD_LIMIT_MEMLOCK="$SLAPD_MEMORYLIMIT"
    export SLAPD_LIMIT_AS="$SLAPD_MEMORYLIMIT"
  fi
  [[ -n ${SLAPD_DATALIMIT-} ]] && export SLAPD_LIMIT_DATA="$SLAPD_DATALIMIT"
  [[ -n ${SLAPD_STACKLIMIT-} ]] && export SLAPD_LIMIT_STACK="$SLAPD_STACKLIMIT"
  [[ -n ${SLAPD_OPENFILELIMIT-} ]] && export SLAPD_LIMIT_NOFILE="$SLAPD_OPENFILELIMIT"
  [[ -n ${SLAPD_COREFILELIMIT-} ]] && export SLAPD_LIMIT_CORE="$SLAPD_COREFILELIMIT"
fi

## ======================================================================

${SLAPD_RUN_PRE:+run_or_die source "$SLAPD_RUN_PRE"}

command_default="${SLAPD_COMMAND_DEFAULT:-/opt/osstech/sbin/slapd}"
config_default="${SLAPD_CONF_DEFAULT:-/opt/osstech/etc/openldap/slapd.conf}"
user_default="${SLAPD_USER_DEFAULT-ldap}"
ldapi_service_default="${SLAPD_LDAPI_SERVICE_DEFAULT-ldapi:///}"
services_default="${SLAPD_SERVICES_DEFAULT-ldap:/// ldaps:///}"
debug_level_default="${SLAPD_DEBUG_LEVEL_DEFAULT-none}"

config="${SLAPD_CONF:-$config_default}"
if [[ -d $config ]]; then
  config_opts=(-F "$config")
else
  config_opts=(-f "$config")
fi

SLAPD_RUN_ARGS=(
  ${SLAPD_NO_RUN:+true}
  ${SLAPD_NICE:+nice -n "$SLAPD_NICE"}
  ${SLAPD_IONICE:+ionice ${SLAPD_IONICE_CLASS:+-c "$SLAPD_IONICE_CLASS"} -n "$SLAPD_IONICE"}
  ${SLAPD_WRAPPER_COMMAND:+"$SLAPD_WRAPPER_COMMAND" ${SLAPD_WRAPPER_OPTIONS-}}
  "${SLAPD_COMMAND:-$command_default}"
  -d "${SLAPD_DEBUG_LEVEL:-$debug_level_default}"
  "${config_opts[@]}"
  -u "${SLAPD_USER:-$user_default}"
  ${SLAPD_GROUP:+-g "$SLAPD_GROUP"}
  -h "${SLAPD_LDAPI_SERVICE:-$ldapi_service_default} ${SLAPD_SERVICES:-$services_default}"
  ${SLAPD_SYSLOG_LEVEL:+-s "$SLAPD_SYSLOG_LEVEL"}
  ${SLAPD_SYSLOG_FACILITY:+-l "$SLAPD_SYSLOG_FACILITY"}
  ${SLAPD_OPTIONS-}
)

## ======================================================================

${SLAPD_UMASK:+run_or_die umask "$SLAPD_UMASK"}
${SLAPD_WORKINGDIR:+run_or_die cd "$SLAPD_WORKINGDIR"}

## Seconds
${SLAPD_LIMIT_CPU:+run_or_die ulimit -t "$SLAPD_LIMIT_CPU"}
## Bytes
${SLAPD_LIMIT_FSIZE:+run_or_die ulimit -f "$SLAPD_LIMIT_FSIZE"}
## Bytes
${SLAPD_LIMIT_DATA:+run_or_die ulimit -d "$SLAPD_LIMIT_DATA"}
## Bytes
${SLAPD_LIMIT_STACK:+run_or_die ulimit -s "$SLAPD_LIMIT_STACK"}
## Bytes
${SLAPD_LIMIT_CORE:+run_or_die ulimit -c "$SLAPD_LIMIT_CORE"}
## Bytes
${SLAPD_LIMIT_RSS:+run_or_die ulimit -m "$SLAPD_LIMIT_RSS"}
## Number of File
${SLAPD_LIMIT_NOFILE:+run_or_die ulimit -n "$SLAPD_LIMIT_NOFILE"}
## Bytes
${SLAPD_LIMIT_AS:+run_or_die ulimit -v "$SLAPD_LIMIT_AS"}
## Number of Processes
${SLAPD_LIMIT_NPROC:+run_or_die ulimit -u "$SLAPD_LIMIT_NPROC"}
## Bytes
${SLAPD_LIMIT_MEMLOCK:+run_or_die ulimit -l "$SLAPD_LIMIT_MEMLOCK"}
## Number of Locks
${SLAPD_LIMIT_LOCKS:+run_or_die ulimit -x "$SLAPD_LIMIT_LOCKS"}
## Number of Queued Signals
${SLAPD_LIMIT_SIGPENDING:+run_or_die ulimit -i "$SLAPD_LIMIT_SIGPENDING"}
## Bytes
${SLAPD_LIMIT_MSGQUEUE:+run_or_die ulimit -q "$SLAPD_LIMIT_MSGQUEUE"}
## Nice Level
${SLAPD_LIMIT_NICE:+run_or_die ulimit -e "$SLAPD_LIMIT_NICE"}
## Realtime Priority
${SLAPD_LIMIT_RTPRIO:+run_or_die ulimit -r "$SLAPD_LIMIT_RTPRIO"}

${SLAPD_RUN_POST:+run_or_die source "$SLAPD_RUN_POST"}

if [[ -n ${SLAPD_RUN_DEBUG-} ]]; then
  { umask; pwd; ulimit -a; env; } |debug
fi

run_or_die exec "${SLAPD_RUN_ARGS[@]}"
