#!/bin/bash
# 
# ***** BEGIN LICENSE BLOCK *****
# Zimbra Collaboration Suite Server
# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc.
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software Foundation,
# version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
# You should have received a copy of the GNU General Public License along with this program.
# If not, see <https://www.gnu.org/licenses/>.
# ***** END LICENSE BLOCK *****
# 

if [ x`whoami` != xzimbra ]; then
  echo Error: must be run as zimbra user
  exit 1
fi

if [ ! -x "/opt/zimbra/common/sbin/amavisd" ]; then
  exit 0
fi

source `dirname $0`/zmshutil || exit 1
zmsetvars

platform=`/opt/zimbra/libexec/get_plat_tag.sh`

if [ ! -d "/opt/zimbra/data/amavisd/.spamassassin" ]; then
    mkdir -p /opt/zimbra/data/amavisd/.spamassassin
fi

rewriteconfig() {
  /opt/zimbra/libexec/configrewrite amavis antispam > /dev/null 2>&1
  /opt/zimbra/libexec/zmaltermimeconfig > /dev/null 2>&1
}

checkrunning() {
  # Get PID from scanning the proc table.
  if [ "x$PID" = "x" ]; then
    # PID file is NULL.  Get info from proc table.
    PID=`/bin/ps axo user,pid,ppid,command | awk '{ if ((($4 ~ /^amavisd$/) || ($4 ~ /^\/opt\/zimbra\/common\/sbin\/amavisd$/)) && ($5 ~ /^\(master\)$/)) { print $2 } }'`
  fi
  # If PID is still not set, then we cannot find any amavisd (master) process.  Assume amavisd is not running.
  if [ "x$PID" = "x" ]; then
    RUNNING=0
    return
  fi

  # If we get to this point the PID was defined in the PID file.  But we're not sure we trust it's validity
  # so we're going the verify it from /bin/ps output!
  PID=`/bin/ps axo user,pid,ppid,command | awk '{ if (($2 == '$PID') && (($4 ~ /^amavisd$/) || ($4 ~ /^\/opt\/zimbra\/common\/sbin\/amavisd$/)) && ($5 ~ /^\(master\)$/)) { print $2 } }'`
  # If PID is NULL now, then the PID stored in the PID file was bogus!
  # Let's try to find the true amavisd (master) process ID
  if [ "x$PID" = "x" ]; then
    PID=`/bin/ps axo user,pid,ppid,command | awk '{ if ((($4 ~ /^amavisd$/) || ($4 ~ /^\/opt\/zimbra\/common\/sbin\/amavisd$/)) && ($5 ~ /^\(master\)$/)) { print $2 } }'`
  fi
  # If the PID is still NULL now, it really must not be running.
  if [ "x$PID" = "x" ]; then
    RUNNING=0
    return
  else
    RUNNING=1
    return
  fi
}

checkrunning-mc() {
  #  Get PID from scanning the proc table.
  if [ "x$MCPID" = "x" ]; then
    # PID file is NULL.  Get info from proc table.
    MCPID=`/bin/ps axo user,pid,ppid,command | awk '{ if ((($6 ~ /amavis-mc$/) || ($6 ~ /\/opt\/zimbra\/common\/sbin\/amavis-mc$/))) { print $2 } }'`
  fi
  # If PID is still not set, then we cannot find any amavisd (master) process.  Assume amavisd is not running.
  if [ "x$MCPID" = "x" ]; then
    MCRUNNING=0
    return
  fi

  MCRUNNING=1
  return
}


#
# Main
#
case "$1" in
  'start')
    checkrunning-mc
    echo -n "Starting amavisd-mc..."
    if [ $MCRUNNING = 1 ]; then
      echo "amavisd-mc is already running."
    else
      if [ $MCRUNNING = 0 ]; then
        sudo /opt/zimbra/common/sbin/amavis-mc
        for ((i=0; i < 30; i++)); do
          checkrunning-mc
          if [ $MCRUNNING = 1 ]; then 
            break
          fi  
          sleep 1
        done
      fi
      if [ "x$MCPID" = "x" ]; then
        echo "failed."
        exit
      else 
        echo "done."
      fi 
    fi
    checkrunning
    echo -n "Starting amavisd..."
    if [ $RUNNING = 1 ]; then
      echo "amavisd is already running."
      exit 0
    else
      if [ ! -d /opt/zimbra/data/amavisd/quarantine ]; then
        mkdir /opt/zimbra/data/amavisd/quarantine
      fi
      if [ ! -d /opt/zimbra/data/amavisd/tmp ]; then
        mkdir /opt/zimbra/data/amavisd/tmp
      else 
        find /opt/zimbra/data/amavisd/tmp -maxdepth 1 -type d -name 'amavis-*' -exec rm -rf {} \; > /dev/null 2>&1
      fi
      if [ ! -d /opt/zimbra/data/amavisd/var ]; then
        mkdir /opt/zimbra/data/amavisd/var
      fi
      if [ x$2 = "x" ]; then
        rewriteconfig
      fi
      /opt/zimbra/common/sbin/amavisd -X no_conf_file_writable_check -c \
        /opt/zimbra/conf/amavisd.conf &
      for ((i=0; i < 30; i++)); do
        checkrunning
        if [ $RUNNING = 1 ]; then 
          break
        fi  
        sleep 1
      done
      if [ "x$PID" = "x" ]; then
        echo "failed."
      else 
        echo "done."
      fi 
    fi
  ;;

  'kill')
    $0 stop
  ;;

  'stop')
    checkrunning
    echo -n "Stopping amavisd..."
    if [ $RUNNING = 0 ]; then
      echo "amavisd is not running."
    else 
      kill -TERM $PID 2> /dev/null
      for ((i=0; i < 300; i++)); do
        sleep 5
        kill -0 $PID 2> /dev/null
        if [ $? != 0 ]; then
          break
        fi
      done
      kill -TERM $PID 2> /dev/null
      if [ $? != 0 ]; then
        echo " done."
      else 
        echo " failed to stop $PID"
        exit 1
      fi
    fi
    checkrunning-mc
    echo -n "Stopping amavisd-mc..."
    if [ $MCRUNNING = 0 ]; then
      echo "amavisd-mc is not running."
    else
      kill -TERM $MCPID 2> /dev/null
      for ((i=0; i < 300; i++)); do
        sleep 5
        kill -0 $MCPID 2> /dev/null
        if [ $? != 0 ]; then
          break
        fi
      done
      kill -TERM $MCPID 2> /dev/null
      if [ $? != 0 ]; then
        echo " done."
      else 
        echo " failed to stop $PID"
        exit 1
      fi
    fi
    exit 0
  ;;
    
  'restart'|'reload')
    $0 stop
    $0 start $2
  ;;
  
  'status')
    checkrunning
    echo -n "amavisd is "
    if [ $RUNNING = 0 ]; then
      echo "not running."
      exit 1
    else
      echo "running."
    fi
    checkrunning-mc
    echo -n "amavisd-mc is "
    if [ $MCRUNNING = 0 ]; then
      echo "not running."
      exit 1
    else
      echo "running."
      exit 0
    fi
  ;;
    
  *)
    echo "Usage: $0 start|stop|kill|reload|restart|status"
    exit 1
  ;;
esac
