#!/usr/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

if [[ -n ${JOURNAL_STREAM-} || $PPID -eq 1 ]]; then
  PNAME=""
else
  PNAME="$0"
fi

run() {
  if [[ -n ${SLAPD_RUN_INFO-set} ]]; then
    echo "${PNAME:+$PNAME: }INFO: Run: $*" >&2
  fi
  "$@"
}

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

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

warn() {
  echo "${PNAME:+$PNAME: }WARNING: $*" >&2
}

envdir() {
  local envdir="$1"; shift
  local envfile envname

  for envfile in "$envdir"/*; do
    [[ -f $envfile ]] || continue
    envname="${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="${PNAME:+$PNAME: }DEBUG: "
  set -x
fi

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

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

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

if [[ -n ${SLAPD_SYSLOG_SOCKET_PATH-} ]]; then
  if [[ -S $SLAPD_SYSLOG_SOCKET_PATH ]]; then
    exec &> >(logger -t slapd-logger --socket-errors=off -u ${SLAPD_SYSLOG_SOCKET_PATH})
  else
    warn "No syslog socket at SLAPD_SYSLOG_SOCKET_PATH environment: $SLAPD_SYSLOG_SOCKET_PATH"
  fi
fi

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

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

## ----------------------------------------------------------------------

## default settings
command_default="/opt/osstech/sbin/slapd"
config_default="/opt/osstech/etc/openldap/slapd.conf"
user_default="ldap"
ldapi_service_default="ldapi:///"
services_default="ldap:/// ldaps:///"

SLAPD_DEBUG_LEVEL=${SLAPD_DEBUG_LEVEL:-stats}
SLAPD_SYSLOG_LEVEL=${SLAPD_SYSLOG_LEVEL:-0}
SLAPD_LIMIT_CORE=${SLAPD_LIMIT_CORE:-unlimited}
SLAPD_LIMIT_NOFILE=${SLAPD_LIMIT_NOFILE:-16384}

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}"
  ${SLAPD_DEBUG_LEVEL:+-d "$SLAPD_DEBUG_LEVEL"}
  ${SLAPD_SYSLOG_LEVEL:+-s "$SLAPD_SYSLOG_LEVEL"}
  ${SLAPD_SYSLOG_FACILITY:+-l "$SLAPD_SYSLOG_FACILITY"}
  "${config_opts[@]}"
  -u "${SLAPD_USER:-$user_default}"
  ${SLAPD_GROUP:+-g "$SLAPD_GROUP"}
  -h "${SLAPD_LDAPI_SERVICE:-$ldapi_service_default} ${SLAPD_SERVICES:-$services_default}"
  ${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[@]}"
