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

# Init script for Axigen Mail Server daemon
# Unified (and tested) *only* for the supported Linux distros.
# See http://www.axigen.com for a full list of supported Linux distros.
# Running on other Linux distros/versions should be possible, but is not
# officially supported.

# chkconfig:    345 80 20
# description:  Axigen Mail Server.
# processname:  axigen
# pidfile:      /var/opt/axigen/run/axigen.pid
# config:       /var/opt/axigen/run/axigen.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

BINPATH="/opt/axigen/bin"
DATAPATH="/var/opt/axigen"
AXIBIN="${BINPATH}/axigen"
AXIOPT=""
PIDFILE="${DATAPATH}/run/axigen.pid"

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

_check_wrapper() {
  wrapper=""
  handlewrapper=""
  if [ -f /etc/init.d/functions ]; then # Redhat-like functions system
    . /etc/init.d/functions
    [ "$(type -t success)" ] && \
    [ "$(type -t failure)" ] && \
      wrapper="functions"
  elif [ -f /etc/rc.status ]; then # SUSE-like rc.status system
    . /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
    . /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"
  elif [ -f /etc/rc.d/functions ] && [ -f /etc/tfm-release ]; then # TFM
    . /etc/rc.d/functions
    [ "$(type -t success)" ] && \
    [ "$(type -t failure)" ] && \
      wrapper="functions-tfm"
  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
      ;;
    "functions-tfm")
      success
      ;;
    "rc.status")
      rc_failed 0
      rc_status -v
      ;;
    *)
      echo "   [ OK ]"
  esac
}

_print_fail() {
  case "${wrapper}" in
    "ubuntu-lsb")
      log_end_msg 1
      ;;
    "functions")
      failure
      echo
      ;;
    "functions-tfm")
      failure
      ;;
    "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}
}

_gen_cert() {
  local ret
  local _cert_file="${DATAPATH}/axigen_cert.pem"
  if [ "$1" != "force" ]; then
    if [ -f "${_cert_file}" ]; then
      return 0
    fi
  fi
  _echo_wrapper -n "Generating self-signed SSL certificate..."
  ${AXIBIN} --gen-cert ${_cert_file} >/dev/null 2>&1
  ret=$?
  _check_print ${ret}
  chown axigen:axigen ${_cert_file} >/dev/null 2>&1
  return ${ret}
}

start() {
  local ret=
  _gen_cert
  _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
  ret=$?
  _check_print ${ret}
  return ${ret}
}

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" ret=
  _check_run
  ret=$?
  if [ ${ret} -eq 0 ]; then
    _echo_wrapper "${msg} running (pid: ${PID}${PFNF})."
  else
    _echo_wrapper "${msg} stopped."
  fi
  return ${ret}
}


case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart)
    _check_run && stop
    _check_run || start
    ;;
  reload)
    reload
    ;;
  force-reload)
    reload || {
      _check_run && stop
      _check_run || start
    }
    ;;
  status)
    status
    ;;
  quiet-status)
    _check_run
    ;;
  init)
    _gen_cert force
    ;;
  condinit)
    _gen_cert
    ;;
  help)
    echo "Usage: $0 <action>"
    echo "where <action> may one of:"
    echo "  start         - starts the server"
    echo "  stop          - stops the server"
    echo "  restart       - restarts the server"
    echo "  reload        - reloads configuration"
    echo "  force-reload  - force reload"
    echo "  status        - prints server status"
    echo "  quiet-status  - returns 0 if server is running, 1 otherwise"
    echo "  init          - force performing of some initialization tasks"
    echo "  condinit      - perform some initialization tasks"
    echo "  help          - displays this help"
    ;;
  *)
    echo "Basic usage: $0 {start|stop|restart|reload|help}"
    echo "Type \`$0 help' for extended help"
    exit 1
    ;;
esac

exit $?

