#! /bin/sh
#
#	Copyright 03/31/97 Sun Microsystems, Inc.  All Rights Reserved.
#
# @(#)hainformix_fmon_start.shi	1.10 97/03/31 SMI
#
# hainformix_fmon_start - start an Informix fault monitor (hainformix_fmon)
#			  for the Informix OnLine Server #1
#
# Environment:
# HA_ENV - file name of HA environment file
# HA_METASETSERVE - list of the logical hosts to run on the local host
# HA_SIBLING_METASETSERVE - list of the logical hosts not on local host
#

# make sure we reread HA_ENV (might have changed)
# setting HA_CLUSTER to "" forces a re-read in informix_boiler
HA_CLUSTER=""

#	Copyright 03/31/97 Sun Microsystems, Inc.  All Rights Reserved.
#
# @(#)informix_boiler	1.8 97/03/31 SMI

# begin of common ha-dbms boilerplate

# remember our name
argv0=`basename $0`


LOGGER=/usr/bin/logger

# if HA_CLUSTER is not set, read the environment
# NOTE: hainformix_fmon_start unsets HA_CLUSTER to force re-building the env.
if [ "$HA_CLUSTER" = "" ] ; then
	if [ ! -r "$HA_ENV" ] ; then
		$LOGGER -p local7.err -t "$HA_CLUSTER" "$argv0: Cannot determine correct HA environment"
		exit 1
	fi
	. $HA_ENV
	if [ $? -ne 0 ] ; then
		$LOGGER -p local7.err -t "$HA_CLUSTER" "$argv0: cannot include ha_env file $HA_ENV"
		exit 1	
	fi
fi

# include HA utilities library
. utilities
if [ $? -ne 0 ]; then
	$LOGGER -p local7.err -t "$HA_SLOGTAG" "$argv0: Cannot find HA utilities library"
	exit 1
fi

# usage
#if [ "$USAGE_PARMS" != "" ] ; then
#  	if [ $# -ne $USAGE_PARMS ] ; then
#    		$LOGGER -p local7.err -t "$HA_SLOGTAG" "$argv0: Incorrect number of command line parameters"
#    		exit 2
#  	fi
#fi


# some default files and locations
# don't move this up - it depends on HA_FILES, which gets set above
HA_DATABASES=${HA_FILES}/hainformix_databases
HA_DB_SUPPORT=${HA_FILES}/hainformix_support


# verify that we have the hainformix_databases files
if [ ! -r $HA_DATABASES ] ; then
  logerr "file ${HA_DATABASES} does not exist or is not readable!"
  exit 2
fi

# verify that we have the hainformix_support file
if [ ! -r $HA_DB_SUPPORT ] ; then
  logerr "file ${HA_DB_SUPPORT} does not exist or is not readable!"
  exit 2
fi


# talk_start ... - echo the args, run them, and evaluate return value
talk_start() {
  	lognotice "$$: $*"
  	if $* ; then
    		return 0
  	else
    		logerr "$$: $* ... failed"
    		return 1
  	fi
}


# talk_start_bg ... - print the args, then run them in the background
talk_start_bg() {
  	lognotice "$$: $*"
  	$* &
  	}


# get_pid [ -u userid ] pattern - find the process id of a running program
# if called with "-u userid", only process for that user will be considered
get_pid() {
	if [ "$1" = "-u" ] ; then
		ps_args="-f -u $2"
		shift
		shift
	else
		ps_args="-ef"
	fi
	PID=`/usr/bin/ps $ps_args | grep "\<$*\>" | nawk -v pat="$*" '
 BEGIN { 
   search_pat = substr(pat, 0, 79)
   }
 { if ( match($0, search_pat) )
     if ( ! match($0, "nawk -v pat=") )
       print $2
  }
'`
}


# kill_proc pattern - find and terminate a process
kill_proc() {
  	lognotice "Killing $*..." 
  	get_pid $*
  	if [ "$PID" ] ; then
    		for p in ${PID} ; do
      			lognotice "Killing process id $p"
      			kill $p
    		done
    		echo
  	else
    		lognotice "process \"$*\" could not be located..." 
  	fi
}

# read_ha_databases onconfig - find an entry in the HA_DATABASES file,
# 	parse it apart, and return in variables. Assumes that INFORMIXDIR
#	is set!
read_ha_databases() {
	conf_line=`grep "^o[nf][f]*	$1	" $HA_DATABASES`
	if [ "$conf_line" = "" ] ; then
		logerr "$1 missing from $HA_DATABASES!"
		return 1
	fi
	onconfig=`echo "$conf_line" | cut -s -f 2`
	logical_host=`echo "$conf_line" | cut -s -f 3`
	poll_cycle=`echo "$conf_line" | cut -s -f 4`
	connect_cycle=`echo "$conf_line" | cut -s -f 5`
	timeout=`echo "$conf_line" | cut -s -f 6`
	restart_delay=`echo "$conf_line" | cut -s -f 7`
	dbname=`echo "$conf_line" | cut -s -f 8`
	DB_LOGIN=$dbname
	export DB_LOGIN
	informixserver=`echo "$conf_line" | cut -s -f 9`
	return 0
}

# find_informix onconfig - finds and sets various Informix related variables:
#	INFORMIXDIR ONINIT INFORMIXSERVER ONCONFIG
# in case of a problem, it returns with an empty INFORMIXDIR variable
find_informix() {
  	INFTAB=/var/opt/informix/inftab
	
	INFORMIXDIR=""
	ONINIT=""
	ONCONFIG=""
	INFORMIXSERVER=""

        if inftab_line=`grep "^[	 ]*$1:" $INFTAB` ; then
                informixdir=`echo $inftab_line | awk -F: '{print $2}' -`
                if [ -d $informixdir ] ; then
                        if [ -x ${informixdir}/bin/oninit ] ; then
                                read_ha_databases $1
                                INFORMIXDIR="$informixdir"
                                ONINIT="${INFORMIXDIR}/bin/oninit"
                        else
                                logerr "No oninit executable in ${INFORMIXDIR}/bin!"
                        fi
                else
                        logerr "Invalid value for INFORMIXDIR: ${INFORMIXDIR}"
                fi
        else
                logerr "Database '$1' not found in ${INFTAB}"
        fi
 
        if [ -r ${informixdir}/etc/${onconfig} ] ; then
                ONCONFIG="$onconfig"
                ONCONFIGFILE=${informixdir}/etc/${onconfig}
        else
                logerr "Database '$1' onconfig file not found or is not readable!"
                INFORMIXDIR=""
        fi
 
        if [ -r ${informixdir}/etc/sqlhosts ] ; then
                INFORMIXSQLHOSTS=${informixdir}/etc/sqlhosts
        else
                logerr "sqlhosts file not found or is not readable!"
                INFORMIXDIR=""
        fi

#       INFORMIXSERVER=`grep DBSERVERNAME ${INFORMIXDIR}/etc/${ONCONFIG} | nawk
#'{print $2}'`                 

        INFORMIXSERVER="$informixserver"
	sqlhosts_informixserver=`grep "^${informixserver} " ${INFORMIXSQLHOSTS} | awk '{print $1}'`

#Maybe a TAB is placed after the informixserver entry in the sqlhosts

	if [ ! "${sqlhosts_informixserver}" ] ; then
		sqlhosts_informixserver=`grep "^${informixserver}	" ${INFORMIXSQLHOSTS} | awk '{print $1}'`
	fi 

 
        if [ "${INFORMIXSERVER}" != "${sqlhosts_informixserver}" ] ; then                        
                logerr "Informixserver $INFORMIXSERVER not found in ${INFORMIXSQLHOSTS}"
                INFORMIXDIR="" 
        fi

        export INFORMIXDIR ONINIT ONCONFIG INFORMIXSERVER

}


make_rpc_call() {
  	lognotice "Calling $3 for onconfig $2 on host $1..."
  	ha_dbms_call $1 $2 $3 informix
  	}


get_remote_host(){
        RSHHOST=""
        for X in `haget  -f private_links -h $HA_REMOTEHOST` ; do
          net_pinghost $X > /dev/null 2>&1
          if [ $? -eq 0 ] ; then
                RSHHOST=$X
                export RSHHOST
                return 0
          fi
        done
        return 1
        }


#end of common ha-dbms boiler plate
#include_boiler

# process_parm_file - process an Informix onconfig file $1, 
#    references, and echo the value for MSGPATH
process_parm_file() {
	if [ -r "$1" ] ; then
		grep -v '^#' $1 | \
		while read var value ; do
				case "$var" in
					MSGPATH) atmp=`echo "$value" | awk '{print $1}'`;
					echo $atmp;;
					*) ;;
				esac
		done
	else
		logerr "Informix onconfig file $1 does not exist or is not readable!"
	fi
	}

#
# copy_lib_files - this routine copy the libraries needed by fault monitor to
#  		   /usr/lib
#
copy_lib_files () {

	inf_version=$1
	# this flag indicate that this is a remote host and the Informix 
	# binaries is on logical host if this flag is 1
	flag=$2
	informix_home=$3

	# The runtime libraries for fault monitor are different in 7.13 and 7.20
	# If the version is 7.20, copy the needed libraries to /usr/lib
	v=`echo $inf_version | grep 7.2`
	if [ "$v" != "" ]; then
		lib_files="iasfs07b.so libnetstub.so libixasf.so libixgen.so libixgls.so libixos.so libixsql.so"
	fi

	for LIB in  $lib_files ; do
       		ls /usr/lib/$LIB > /dev/null 2>&1
       		if [ $? -ne 0 ] ; then
			filename=$LIB
			if [ "$v" != "" ]; then
				# library files prefix with "libix" are
				# in $INFORMIXDIR/lib/esql directory
				match=`echo $LIB | grep libix` 
				if [ "$match" != "" -a "$LIB" != "libixasf.so" ]; then
					filename="esql/$LIB"
				fi
			fi
			
			# this flag indicates that this is a remote host and
			# binaries are on the logical host
			if [ "$flag" -eq 1 ] ; then
                                # If this host does not own the logical
                                # host, copy the libraries from the host                                        # which own the logical host
				rcp -p $RSHHOST:$informix_home/lib/$filename /usr/lib/$LIB 2> /dev/null
			else
				rcp -p $INFORMIXDIR/lib/$filename /usr/lib/$LIB 2> /dev/null
			fi
		fi
	done

}			

# ############# Main ########################## Main ##########################
if [ $# -ne 1 ] ; then
	logerr "usage: $argv0 informix_server"
	exit 2
fi

ONCONFIG=$1
read_ha_databases $ONCONFIG

find_logical_host=`/opt/SUNWhadf/bin/haget -f all_logical_hosts | grep $logical_host`
if [ "$find_logical_host" = "" ] ; then
        logerr "logical host $logical_host is not in the cluster configuration"
	logerr "Fault monitor for Informix OnLine Server ${INFORMIXSERVER} NOT started"
	exit 1
fi

matches=`expr " $HA_METASETSERVE " : ".* $logical_host "`
if [ "$matches" -eq 0 ] ; then
    	remote_args="-r $logical_host"
fi

INFTAB=/var/opt/informix/inftab
if inftab_line=`grep "^[	 ]*$1:" $INFTAB` ; then
        informix_home=`echo $inftab_line | awk -F: '{print $2}' -`
fi

if [ "$remote_args" != "" ] ; then
        binaries_on_logical=`echo "$informix_home" | grep "$logical_host"`
fi

get_remote_host
# starting up remote fault monitor when the Informix binaries are
# installed on the logical host then the remote server does not
# have access to version and error log, thus, we hard coded here
# The remote fmon will be started and exit from here
if [ "$remote_args" != ""  -a "$binaries_on_logical" != "" ] ; then
        alert_file="none"
        INFORMIXDIR="/var/opt/informix"

        if [ ! -f $INFORMIXDIR/etc/sqlhosts ] ; then
		if [ ! -d $INFORMIXDIR/etc ] ; then
			mkdir $INFORMIXDIR/etc
		fi
		rcp -p $RSHHOST:$informix_home/etc/sqlhosts $INFORMIXDIR/etc 2> /dev/null
        fi

	if [ ! -d $INFORMIXDIR/msg ] ; then
		logerr "INFORMIX Global Language Support (MSG) files have not been properly installed under /var/opt/informix"
		logerr "Fault monitor for Informix OnLine Server ${informixserver} NOT started"
		exit 1
	fi

        INFORMIXSQLHOSTS=$INFORMIXDIR/etc/sqlhosts
        INFORMIXSERVER="$informixserver"
        export INFORMIXDIR INFORMIXSQLHOSTS INFORMIXSERVER ONCONFIG

	if [ ! -f $INFORMIXDIR/bin/dbaccess ] ; then
		if [ ! -d $INFORMIXDIR/bin ] ; then
			mkdir $INFORMIXDIR/bin
		fi
		rcp -p $RSHHOST:$informix_home/bin/dbaccess $INFORMIXDIR/bin/dbaccess 2> /dev/null
	fi
		
      	version=`$INFORMIXDIR/bin/dbaccess -v` 
	if [ $? -ne 0 ] ; then
		logerr "can not retrieve Informix binaries version number"
		logerr "Fault monitor for Informix OnLine Server ${informixserver} NOT started"
		exit 1
	fi

      	inf_version=`echo "$version" | grep Version | awk '{print $3}'`

	if [ ! -d $INFORMIXDIR/gls ] ; then
		logerr "INFORMIX Global Language Support (GLS) files have not been properly installed under /var/opt/informix"
		logerr "Fault monitor for Informix OnLine Server ${informixserver} NOT started"
		exit 1
	fi
else
	find_informix $1
  
	if [ "$INFORMIXDIR" != "" ] ; then
		#  Lets figure out the Informix version number
      		version=`$INFORMIXDIR/bin/dbaccess -v`
        	if [ $? -ne 0 ] ; then
       	        	logerr "can not retrieve Informix binaries version number"
               		logerr "Fault monitor for Informix OnLine Server ${informixserver} NOT started" 
               		exit 1
        	fi
		inf_version=`echo "$version" | grep Version | awk '{print $3}'`
	fi
fi

grep -v "^#" ${HA_DB_SUPPORT} | \
while read support_line ; do
	pattern="\("`echo "$support_line" | cut -f 1`"\)"
	result=`expr "$inf_version" : ${pattern}`
	if [ "$result" != "" ] ; then
		ha_executable=`echo "$support_line" | cut -f 2`
		action_file=`echo "$support_line" | cut -f 3`
		if [ "$ha_executable" = "" ] ; then
			logerr "Informix OnLine Server ${INFORMIXSERVER}: executable file name missing in line '$support_line' in file $HA_DB_SUPPORT"
			exit 1
		fi

		if [ "$action_file" = "" ] ; then
			logerr "Informix OnLine Server ${INFORMIXSERVER}: action file name missing in line '$support_line' in file $HA_DB_SUPPORT"
			exit 1
		fi

      		if [ "$remote_args" = "" ] ; then
       			alert_file=`process_parm_file $ONCONFIGFILE`
       			if [ "$alert_file" = "" ] ; then
       				logerr "Could not find the value for MSG
PATH in $ONCONFIGFILE"
				exit 1
       			fi
       		else
       			alert_file="none"
       		fi

		if [ "$remote_args" != ""  -a "$binaries_on_logical" != "" ] ; then
			copy_lib_files $inf_version 1 $informix_home 
		else
			copy_lib_files $inf_version 0
		fi
	
		talk_start ${ha_executable} $remote_args $onconfig $poll_cycle $connect_cycle $timeout $restart_delay $HA_FILES/$action_file $alert_file 
       		exit 3
	fi
done

case $? in
	1) ;;
        3) exit 0 ;;
        *) logerr "Informix ${inf_version} not supported!" ;;
esac

# if we reach here, then a fault monitor did not get started
# the reason did already get logged in the various logerr calls above
# Note: The "exit" statements in the while statement above do not
#       cause an exit of the entire script, but just the subshell that
#	executes the while command as part of a pipe!
logerr "Fault monitor for Informix OnLine Server ${INFORMIXSERVER} NOT started"
exit 1

