#!/bin/sh                                                      
#                                                              
# Description:  Manages Postfix Service provided by NTT OSSC as an 
#               OCF High-Availability resource under Heartbeat/LinuxHA control
#                                                                             
# 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; either version 2              
# of the License, or (at your option) any later version.                      
#                                                                             
# 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, write to the Free Software                 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA               
# 02110-1301, USA.                                                            
#                                                                             
#mailto : stephane.neveu@thalesgroup.com                                      
#                                                                             
#######################################################################       
# OCF parameters:                                                             
#   OCF_RESKEY_postfix_bin    : Executable file                               
#   OCF_RESKEY_postfix_pidfile: Process id file                               
#   OCF_RESKEY_postfix_port   : Port number                                   
#   OCF_RESKEY_postfix_user    : postfix user                                 
#                                                                             
#   OCF_RESKEY_postfix_bin, OCF_RESKEY_postfix_conf, OCF_RESKEY_postfix_pidfile
#   OCF_RESKEY_postfix_port OCF_RESKEY_postfix_user must be specified.         
###############################################################################

. ${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs

#########INITIALIZATION HERE###################################################
POSTFIX_BIN="${OCF_RESKEY_postfix_bin-/usr/sbin/postfix}"                      
POSTFIX_PIDFILE="${OCF_RESKEY_postfix_pidfile-/var/spool/postfix/pid/master.pid}"
POSTFIX_CONFFILE="${OCF_RESKEY_postfix_conffile-/etc/postfix/main.cf}"           
POSTFIX_PORT="${OCF_RESKEY_postfix_port-25}"                                     
POSTFIX_USER="${OCF_RESKEY_postfix_user-root}"                                   
POSTFIX_NAME="${OCF_RESKEY_postfix_opts-postfix}"                                
##############################################################################   


usage() 
{       
        cat <<-!
usage: $0 action

action:
        start       : start a new POSTFIX instance

        stop        : stop the running POSTFIX instance

        status      : return the status of POSTFIX, run or down

        monitor     : return TRUE if POSTFIX appears to be working.

        meta-data   : show meta data message

        validate-all : validate the instance parameters
!                                                      
        return $OCF_ERR_ARGS                           
}                                                      

metadata_postfix() {
    cat <<END       
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="postfix">                
<version>1.0</version>                         
<longdesc lang="en">The OCF resource agent for  postfix</longdesc>
<shortdesc lang="en">The RA for postfix</shortdesc>               

<parameters>

<parameter name="postfix_bin" required="1" unique="0">
<longdesc lang="en">                                  
This is a required parameter. This parameter specifies postfix's
bin file                                                        
</longdesc>                                                     
<shortdesc>Binary</shortdesc>                                   
<content type="string" default=""/>                             
</parameter>                                                    

<parameter name="postfix_pidfile" required="1" unique="1">
<longdesc lang="en">                                      
This is a required parameter. This parameter specifies a process id file
for a postfix instance managed by this RA.                              
</longdesc>                                                             
<shortdesc>Pidfile</shortdesc>                                          
<content type="string" default=""/>                                     
</parameter>                                                            

<parameter name="postfix_port" required="1" unique="1">
<longdesc lang="en">                                   
This is a required parameter. This parameter specifies a port number
for a postfix instance managed by this RA. If plural ports are used,
you must specifiy the only one of them.                             
</longdesc>                                                         
<shortdesc>Port number</shortdesc>                                  
<content type="integer" default=""/>                                
</parameter>                                                        

<parameter name="postfix_user" required="1" unique="1">
<longdesc lang="en">                                   
This is a required parameter. This parameter specifies a user
to start the postfix instance managed by this RA.            
</longdesc>                                                  
<shortdesc>User</shortdesc>                                  
<content type="string" default=""/>                          
</parameter>                                                 

</parameters>

<actions>
<action name="start" timeout="20s" />
<action name="stop" timeout="20s" /> 
<action name="status" timeout="30" />
<action name="monitor" depth="0" timeout="30s" interval="20s" start-delay="10s" />
<action name="meta-data" timeout="20s" />                                         
<action name="validate-all" timeout="20" />                                       
</actions>                                                                        
</resource-agent>                                                                 
END                                                                               
        exit $OCF_SUCCESS                                                         
}                                                                                 

get_pid()
{        
        POSTFIX_PID=$(netstat -laputen   | awk  '/.*[0-9]+\.[0-9]+\.+[0-9]+\.[0-9]+:'$POSTFIX_PORT'[^0-9].*LISTEN/ {print $9}' | cut -d '/' -f 1)                                 
}                                                                                        

is_pid_found()
{             
        get_pid
        if [ -n "${POSTFIX_PID}" ] ; then
                return $OCF_SUCCESS      
        else                             
                return 1                 
        fi                               
}                                        

is_postfix_dead()
{                
        get_pid  
        if [[ -z "${POSTFIX_PID}" ]] && [[ -f "${POSTFIX_PIDFILE}" ]]; then
                return $OCF_SUCCESS                                        
        elif [[ -n "${POSTFIX_PID}" ]] && [[ ! -f "${POSTFIX_PIDFILE}" ]]; then
                return $OCF_NOT_RUNNING                                        
        else                                                                   
                return 1                                                       
        fi                                                                     

}

monitor_postfix()
{                
                get_pid
                if is_postfix_dead; then
                        return $OCF_ERR_GENERIC
                elif is_pid_found; then        
                        return $OCF_SUCCESS    
                else                           
                        return $OCF_NOT_RUNNING
                fi                             
}                                              

start_postfix()
{              
        typeset status

        monitor_postfix
        status=$?      
        if [[ $status != $OCF_NOT_RUNNING ]]; then
            return $status                        
        fi                                        
        /usr/bin/newaliases >/dev/null 2>&1       
        ocf_run $POSTFIX_BIN start                
        status=$?                                 
        sleep 1                                   
        if [[ $status != $OCF_SUCCESS ]]; then    
                return $status                    
        fi                                        

        while true; do
                get_pid
                if is_pid_found; then
                        return $OCF_SUCCESS
                else                       
                        ocf_log info "$POSTFIX_BIN:No pid found after start"
                fi                                                          
        done                                                                

        return $OCF_ERR_GENERIC
}                              

stop_postfix()
{             
                monitor_postfix
                ocf_run $POSTFIX_BIN stop
                while true; do           
                        sleep 1          
                        get_pid          
                        if [ is_postfix_dead != "1" ]; then
                                rm -f ${POSTFIX_PIDFILE}   
                                return $OCF_SUCCESS        
                        fi                                 
                        ocf_log info "POSTFIX stopped"     
                done                                       

}

status_postfix()
{               
        monitor_postfix
        return $?      
}                      


validate_all_postfix()
{                     
        return $OCF_SUCCESS
}                          


if [ -z "$POSTFIX_BIN" ]; then
        ocf_log err "POSTFIX_BIN is not defined"
        exit $OCF_ERR_CONFIGURED                
fi                                              
if [ ! -x "$POSTFIX_BIN" ]; then                
        ocf_log err "$POSTFIX_BIN is not found" 
        exit $OCF_ERR_CONFIGURED                
fi                                              

if [ -z "$POSTFIX_PIDFILE" ]; then
        ocf_log err "POSTFIX_PIDFILE is not defined"
        exit $OCF_ERR_CONFIGURED                    
fi                                                  

if [ -z "$POSTFIX_PORT" ]; then
        ocf_log err "POSTFIX_PORT is not defined"
        exit $OCF_ERR_CONFIGURED                 
fi                                               

if [ -z "$POSTFIX_USER" ]; then
        ocf_log err "POSTFIX_USER is not defined"
        exit $OCF_ERR_CONFIGURED                 
fi                                               


COMMAND=$1

case "$COMMAND" in
        start)    
                start_postfix
                status=$?    
                exit $status 
                ;;           
        stop)                
                stop_postfix 
                status=$?    
                exit $status 
                ;;           
        status)              
                status_postfix
                status=$?     
                if status; then
                        ocf_log info "postfix is running"
                elif [status -eq 7]; then
                        ocf_log info "postfix is stopped"
                else
                        ocf_log info "postfix is dead"
                fi
                ;;
        monitor)
                monitor_postfix
                status=$?
                exit $status
                ;;
        meta-data)
                 metadata_postfix
                ;;
        validate-all)
                validate_all_postfix
                exit $?
                ;;
        *)
                usage
                ;;
esac
