#!/bin/bash
# description: The Cyrus IMAPD master serves as a master process for the Cyrus \
#              IMAP and POP servers.
# config: /etc/cyrus.conf
# config: /etc/imapd.conf
# pidfile: /var/run/cyrus-master.pid

# Detect our basename and instance name
# $INSTANCE is '2' if $BASENAME is 'cyrus-imapd2'
TMP_NAME=$0
TMP_PWD=$PWD
while [ -L $TMP_NAME ]; do
  if [ ${TMP_NAME/\/} != $TMP_NAME ]; then
    cd ${TMP_NAME%/*}
  fi
  INSTANCE=${TMP_NAME##*/}
  INSTANCE=${INSTANCE/*cyrus-imapd}
  TMP_NAME=$(readlink ${TMP_NAME##*/})
done
cd $TMP_PWD
declare -r BASENAME=${TMP_NAME##*/rc.}${INSTANCE}
unset TMP_NAME
unset TMP_PWD

# instance config
CYRUSCONF=/etc/cyrus${INSTANCE}.conf
IMAPDCONF=/etc/imapd${INSTANCE}.conf
PIDFILE=/var/run/cyrus-master${INSTANCE}.pid

# make sure what we have is a valid instance
# and that config files are present
if [ -n "$INSTANCE" ]; then
  [ -L /etc/rc.d/rc.${BASENAME} ] || exit 0
fi
[ -f $CYRUSCONF ] || exit 0
[ -f $IMAPDCONF ] || exit 0

# expand_config [path]
# handle "@include" sections from imapd style config file
expand_config() {
  while read line; do
    if printf "%s\n" "${line}" | grep -q '^@include:'; then
      expand_config "$( printf "%s\n" "${line}" | cut -d : -f 2- | sed -e 's/^ *//' )"
    else
      printf "%s\n" "${line}"
    fi
  done < $1
}

# get_config [config default]
# extracts config option from config file
get_config() {
  searchstr=$1
  if config=$(expand_config $IMAPDCONF | egrep "^$searchstr:"); then
    printf "%s\n" "$config" | cut -d : -f 2- | sed -e 's/^ *//'
  else
    echo $2
  fi
}

# default values
CONFIGDIRECTORY=$(get_config configdirectory /var/lib/imap${INSTANCE})
CYRUSMASTER=LIB/cyrus-imapd/cyrus-master
QUIT_TIMEOUT=10

QUICK=0

ALWAYS_CONVERT=1

# Source service configuration.
if [ -f /etc/rc.d/rc.$BASENAME.conf ]; then
  . /etc/rc.d/rc.$BASENAME.conf
else
  echo "$BASENAME: configfile /etc/rc.d/rc.$BASENAME.conf does NOT exist !"
fi

RETVAL=0
RETVAL2=0

is_running() {
  RUNNING=1
  if [ -f $PIDFILE ]; then
    read CYRUS_PID < $PIDFILE
    if [ -n "$CYRUS_PID" ]; then
      ps -p $CYRUS_PID > /dev/null 2>&1
      RUNNING=$?
    fi
  fi
  return $RUNNING
}

start() {
  echo -n $"Starting $BASENAME: "
  if is_running; then
    echo -n "$BASENAME already running."
  else
    if [ $QUICK -eq 0 ]; then
      echo -n "Importing $BASENAME databases: "
      cd $CONFIGDIRECTORY
      su - cyrus -s /bin/bash -c "umask 166 ; INSTANCE=$INSTANCE LIB/cyrus-imapd/cvt_cyrusdb_all > /var/log/imap/db_import.log 2>&1" < /dev/null
      RETVAL=$?
      if [ $RETVAL -eq 0 ]; then
        logger -t $BASENAME -s "Succes importing databases"
      else
        logger -t $BASENAME -s "Error importing databases, check /var/log/imap/db_import.log"
      fi
    fi
    if [ $RETVAL -eq 0 ]; then
      $CYRUSMASTER -C $IMAPDCONF -M $CYRUSCONF -p $PIDFILE -d $CYRUSOPTIONS 2>/dev/null 1>&2
      RETVAL=$?
      [ $RETVAL -eq 0 ] && echo -n "Started OK. " || echo -n "Did not start OK. "
    echo "Done."
    fi
  fi
  return $RETVAL
}

stop() {
  echo -n "Shutting down ${BASENAME}: "
  if ! is_running; then
    echo -n "$BASENAME not running."
  else
    read CYRUS_PID < $PIDFILE
    kill -QUIT $CYRUS_PID > /dev/null 2>&1
    for ((QUIT=0; QUIT < $QUIT_TIMEOUT; QUIT++)); do
      if is_running; then
        sleep 1
      else
        break
      fi
    done
    if is_running; then
      kill -TERM $CYRUS_PID > /dev/null 2>&1
    fi
    rm -f $PIDFILE
  fi
  RETVAL=$?
  if [ $QUICK -eq 0 ]; then
    if ! is_running; then
      echo
      echo -n "Exporting $BASENAME databases: "
      cd $CONFIGDIRECTORY
      su - cyrus -s /bin/bash -c "umask 166 ; INSTANCE=$INSTANCE LIB/cyrus-imapd/cvt_cyrusdb_all export > /var/log/imap/db_export.log 2>&1" < /dev/null
      RETVAL2=$?
      if [ $RETVAL2 -eq 0 ]; then
        logger -t $BASENAME -s "Succes exporting databases"
      else
        logger -t $BASENAME -s "Error exporting databases, check /var/log/imap/db_export.log"
      fi
    fi
  fi
  echo "Done."
  return $RETVAL
}

restart() {
  stop
  start
}

reload() {
  if ! is_running; then
    echo "$BASENAME not running. "
  else
    echo -n "Reloading $BASENAME configuration: "
    read CYRUS_PID < $PIDFILE
    kill -HUP $CYRUS_PID > /dev/null 2>&1
    echo "Done."
    RETVAL=$?
  fi
  return $RETVAL
}

status() {
  if [ -f $PIDFILE ]; then
    read CYRUS_PID < $PIDFILE
    if ps -p $CYRUS_PID > /dev/null 2>&1; then
      echo "$BASENAME (pid $CYRUS_PID) is running..."
      RETVAL=0
    else
      echo "$BASENAME dead but pid file exists"
      RETVAL=1
    fi
  else
    echo $"$BASENAME is stopped"
    RETVAL=3
  fi
  return $RETVAL
}

case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart)
    restart
    ;;
  reload)
    reload
    ;;
  status)
    status
    ;;
  quickstart)
    QUICK=1
    start
    ;;
  quickstop)
    QUICK=1
    stop
    ;;
  quickrestart)
    QUICK=1
    restart
    ;;
  *)
    echo $"Usage: $BASENAME {start|stop|restart|reload|status|quickstart|quickstop|quickrestart}"
    RETVAL=1
esac

exit $RETVAL
