#!/bin/sh
# Copyright (c) 2005, GECAD Technologies
# For any feedback, please contact:
# "AXIGEN Developement Team" <team@axigen.com>

# Init script for Axigen Mail Server daemon
# Unified for the following distros:
# - RedHat, Fedora, SUSE, Mandrake/Mandriva
# - Debian, Ubuntu
# - Slackware and other Linux Distros

# chkconfig:    345 80 20
# description:  Axigen Mail Server.
# processname:  axigen
# pidfile:      /var/opt/axigen/run/axigen.pid
# config:       /var/opt/axigen/run/server.cfg

### BEGIN INIT INFO
# Provides:       axigen
# Required-Start: $network $syslog $time
# Default-Start:  3 4 5
# Default-Stop:   0 1 2 6
# Description:    Start/Stop the Axigen MTA
### END INIT INFO

AXIBIN="/opt/axigen/bin/axigen"
AXIOPT=""
PIDFILE="/var/opt/axigen/run/axigen.pid"
RCAXIGEN_INIT="no"

[ -f /etc/sysconfig/axigen ] && RCCONF=/etc/sysconfig/axigen
[ -f /etc/default/axigen ] && RCCONF=/etc/default/axigen
[ -f /etc/rc.d/rc.axigen.conf ] && RCCONF=/etc/rc.d/rc.axigen.conf
[ -n "${RCCONF}" ] && source ${RCCONF}

_check_wrapper() {
  wrapper=""
  handlewrapper=""
  if [[ -f /etc/init.d/functions ]]; then # Redhat-like functions system
    source /etc/init.d/functions
    [[ \
      "$(type -t success)" && \
      "$(type -t failure)" \
    ]] && wrapper="functions"
  elif [[ -f /etc/rc.status ]]; then # SUSE-like rc.status system
    source /etc/rc.status
    [[ \
      "$(type -t rc_reset)" && \
      "$(type -t rc_failed)" && \
      "$(type -t rc_status)" \
    ]] && wrapper="rc.status"
    rc_reset
  elif [[ -f /lib/lsb/init-functions && "$(lsb_release -is 2>/dev/null)" == "Ubuntu" ]]; then # Ubuntu
    source /lib/lsb/init-functions
    [[ \
      "$(type -t log_success_msg)" && \
      "$(type -t log_failure_msg)" && \
      "$(type -t log_begin_msg)" == "function" && \
      "$(type -t log_end_msg)" == "function" \
    ]] && wrapper="ubuntu-lsb"
  fi
  if [[ "$(type -t startproc)" && "$(type -t killproc)" && "$(type -t checkproc)" ]]; then
    handlewrapper="skc" # {Start,Kill,Check}PROC
  elif [[ "$(type -t start-stop-daemon)" ]]; then
    handlewrapper="ssd"
  fi
}

_check_wrapper

_print_ok() {
  case "${wrapper}" in
    "ubuntu-lsb")
      log_end_msg 0
      ;;
    "functions")
      success
      echo
      ;;
    "rc.status")
      rc_failed 0
      rc_status -v
      ;;
    *)
      echo " => done"
  esac
}

_print_fail() {
  case "${wrapper}" in
    "ubuntu-lsb")
      log_end_msg 1
      ;;
    "functions")
      failure
      echo
      ;;
    "rc.status")
      rc_failed 1
      rc_status -v
      ;;
    *)
      echo " => failed"
  esac
}

_check_print() {
  local code=
  if [[ -z "$1" ]]; then
    code=0
  else
    code=$1
  fi
  if [[ "$1" == "0" ]]; then # sanity check: test value of $1 as string, not as number
    _print_ok
  else
    _print_fail
  fi
}

_echo_wrapper() {
  if [[ "$1" == "-n" ]]; then
    local ep="-n"
    shift
  fi
  case "${wrapper}" in
  "ubuntu-lsb")
    log_begin_msg "$@"
    ;;
  *)
    echo ${ep} "$@"
  esac
}

_check_run() {
  # return 0 -> AXIGEN is running
  # return 1 -> AXIGEN is not running
  PFNF=
  case "${handlewrapper}" in
  "skc")
    checkproc -p "${PIDFILE}" "${AXIBIN}"
    ret=$?
    [[ -f "${PIDFILE}" ]] && PID="$(<"${PIDFILE}")"
    return ${ret}
    ;;
  *)
    local p
    if [[ -f "${PIDFILE}" ]]; then
      PID=$(<"${PIDFILE}")
      # sanity check if PID actually points to AXIBIN
      for p in $(pgrep -f "${AXIBIN}"); do
        if [[ ${p} -eq ${PID} ]]; then
          return 0
        fi
      done
    else
      PFNF=" - PID file not found"
      PID="$(pgrep -f -n "${AXIBIN}")"
      [[ "${PID}" ]] && return 0
    fi
    ;;
  esac
  return 1
}

_wait_daemon() {
  local ct=0 t=15
  if [[ "$1" == "start" ]]; then
    while ! _check_run; do
      ct=$((${ct}+1));
      [[ ${ct} -gt ${t} ]] && return 1
      sleep 1
    done
  else
    while _check_run; do
      ct=$((${ct}+1));
      [[ ${ct} -gt ${t} ]] && return 1
      sleep 1
    done
  fi
  return 0
}

_start_daemon() {
  local ret=
  case "${handlewrapper}" in
  "skc")
    startproc -p ${PIDFILE} ${AXIBIN} ${AXIOPT} 2>/dev/null
    ret=$?
    ;;
  "ssd")
    start-stop-daemon --start --quiet --exec ${AXIBIN} --pidfile ${PIDFILE} -- ${AXIOPT}
    ret=$?
    ;;
  *)
    ${AXIBIN} ${AXIOPT}
    ret=$?
  esac
  return ${ret}
}

_stop_daemon() {
  local ret=
  case "${handlewrapper}" in
  "skc")
    killproc -p "${PIDFILE}" -t15 "${AXIBIN}"
    ret=$?
    ;;
  "ssd")
    start-stop-daemon --stop --quiet --retry 15 --exec ${AXIBIN} >/dev/null
    ret=$?
    ;;
  *)
    if [[ ${PFNF} ]]; then
      pkill -f ${AXIBIN}
    else
      kill ${PID}
    fi
    ret=$?
  esac
  return ${ret}
}

_reload_daemon() {
  local ret=
  case "${handlewrapper}" in
  "skc")
    killproc -p "${PIDFILE}" -t15 -HUP "${AXIBIN}"
    ret=$?
    ;;
  "ssd")
    start-stop-daemon --stop --quiet --signal 1 --exec ${AXIBIN} --pidfile ${PIDFILE}
    ret=$?
    ;;
  *)
    if [[ ${PFNF} ]]; then
      pkill -HUP -f ${AXIBIN}
    else
      kill -HUP ${PID}
    fi
    ret=$?
  esac
  return ${ret}
}

_ddb_init() {
  local ret
  local ddbloc=/var/opt/axigen/domains
  sleep 1
  _echo_wrapper "Initialzing domain database"
  _echo_wrapper -n "  Creating DDB in /var/opt/axigen/domains..."
  /opt/axigen/bin/provisioner --create-ddb "${ddbloc}" 0 >/dev/null
  ret=$?
  _check_print "${ret}"
  if [[ ${ret} -ne 0 ]]; then
    return ${ret}
  fi
  _echo_wrapper -n "  Registering created DDB..."
  /opt/axigen/bin/provisioner --register-ddb "${ddbloc}" >/dev/null
  ret=$?
  _check_print "${ret}"
  return ${ret}
}

_gen_cert() {
  local ret
  local _prefix="/var/opt/axigen/axigen_cert"
  local _o="AXIGEN Mail Server"
  local _ou="Auto-generated test certificate"
  local _cn="AXIGEN"
  _echo_wrapper "Generating self-signed certificate"
  command -vp openssl >/dev/null 2>&1
  ret=$?
  if [ ${ret} -ne 0 ]; then
    _echo_wrapper "  The \`openssl' command has not been found."
    _echo_wrapper -n "  Cannot generate certificates."
    _print_fail
    return ${ret}
  fi
  _echo_wrapper -n "  Generating server key..."
  openssl genrsa -out ${_prefix}.key 1024 >/dev/null 2>&1
  ret=$?
  _check_print "${ret}"
  if [ ${ret} -ne 0 ]; then
    return ${ret}
  fi
  _echo_wrapper -n "  Generating server crt..."
  openssl req -new -x509 -key ${_prefix}.key -out ${_prefix}.crt <<< ".
.
.
${_o}
${_ou}
${_cn}
" >/dev/null 2>&1
  ret=$?
  _check_print "${ret}"
  if [ ${ret} -ne 0 ]; then
    return ${ret}
  fi
  _echo_wrapper -n "  Creating pem certificate (${_prefix}.pem)..."
  cat ${_prefix}.key ${_prefix}.crt > ${_prefix}.pem
  ret=$?
  _check_print "${ret}"
  if [ ${ret} -ne 0 ]; then
    return ${ret}
  fi
  _echo_wrapper -n "  Removing key and crt files..."
  rm -f ${_prefix}.key ${_prefix}.crt
  _check_print "${ret}"
  return ${ret}
}

_write_noinit() {
  [ -f "${RCCONF}" ] || return 0
  local testvar="$(grep "^[[:space:]]*RCAXIGEN_INIT[[:space:]]*=[[:space:]]*.*" ${RCCONF})"
  local TMPFILE="$(mktemp /tmp/axigenrc.XXXXXX)"
  if [ -z "${testvar}" ]; then
    echo -e "\nRCAXIGEN_INIT=\"no\"" >> ${RCCONF}
  else
    sed -e "s|^[[:space:]]*RCAXIGEN_INIT[[:space:]]*=[[:space:]]*.*|RCAXIGEN_INIT=\"no\"|g" ${RCCONF} > ${TMPFILE}
    cat ${TMPFILE} > ${RCCONF}
    rm -f ${TMPFILE}
  fi
}

_init() {
  if [ "$1" != "-f" ]; then # no force
    if [ "${RCAXIGEN_INIT}" == "yes" ]; then
      _write_noinit
    else
      return
    fi
  fi
  _ddb_init
  _gen_cert
}

start() {
  local ret=
  _echo_wrapper -n "Starting AXIGEN Mail Server..."
  if _check_run; then
    _echo_wrapper
    _echo_wrapper -n "   already running (pid: ${PID}${PFNF})"
    _print_fail
    return $?
  fi
  _start_daemon
  ret=$?
  if [[ ${ret} -ne 0 ]]; then
    _check_print "${ret}"
    return ${ret}
  fi
  # if daemon stopped after it started successfully
  _wait_daemon start
  _check_print $?
  _init
}

stop() {
  local ret=
  _echo_wrapper -n "Stopping AXIGEN Mail Server..."
  if ! _check_run; then
    _echo_wrapper
    _echo_wrapper -n "   already stopped"
    _print_fail
    return $?
  fi
  _stop_daemon
  ret=$?
  if [[ ${ret} -ne 0 ]]; then
    _check_print "${ret}"
    return ${ret}
  fi
  _wait_daemon stop
  _check_print $?
}

reload() {
  local ret=
  _echo_wrapper -n "Reloading AXIGEN configuration..."
  if ! _check_run; then
    _echo_wrapper
    _echo_wrapper -n "   daemon is stopped"
    _print_fail
    return $?
  fi
  _reload_daemon
  _check_print $?
}

status() {
  local msg="AXIGEN Mail Server is"
  if _check_run; then
    _echo_wrapper "${msg} running (pid: ${PID}${PFNF})."
  else
    _echo_wrapper "${msg} stopped."
  fi
  return 0
}


case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart)
    stop
    start
    ;;
  reload)
    reload
    ;;
  force-reload)
    reload || { stop; start; }
    ;;
  status)
    status
    ;;
  quiet-status)
    _check_run
    ;;
  init)
    _init -f
    ;;
  *)
    echo "Usage: $0 { start | stop | restart | reload | force-reload | status | quiet-status | init }"
    exit 1
esac

exit $?

