
# $Copyright$
# Copyright (C) Fujitsu Technology Solutions 2009, 2010, 2011, 2012, 2013, 2014
# All rights reserved
#
# $Copyright$
# Copyright (C) Fujitsu Siemens Computers GmbH 2007, 2008
# All rights reserved
#
# This function library is part of ServerView Linux Agents

# isXenServer - test if this is an instance of CentOS-based XenServer
#
# Return 0 or 1 if the test succeeds or fails

isXenServer () {
    [ -f /etc/redhat-release ] && ( grep -q "xenenterprise" /etc/redhat-release ) && return 0
	return 1
}

isOVMServer () {
    [ -f /etc/redhat-release ] && ( grep -q "Oracle VM server" /etc/redhat-release ) && return 0
	return 1
}

function toUpper() {
  echo $1 | tr "[:lower:]" "[:upper:]" 
} 

# LSB function library does not exist on ESX 3. CentOS uses a different
# syslog and so the LSB functions won't work. Emulate what is necessary.

[ -f /lib/lsb/init-functions ] || {
	. /etc/init.d/functions

	function log_success_msg () {
		echo -n $*
		success "$*"
		echo
		return 0
	}

	function log_failure_msg () {
		echo -n $*
		failure "$*"
		echo
		return 0
	}
}

MYNAME=$(basename $0)

# log - append log for script $MYNAME with time stamp to $LOGFILE

function log () {
	echo -e "$(LC_ALL=C date +'%b %e %T') $HOSTNAME $MYNAME: $*" >>$LOGFILE
}

# mylog_success_msg() - log to stdout and into /var/log/messages
# mylog_failure_msg() - log to stdout and into /var/log/messages
#
# We should use LSB function log_{success,failure}_msg.
# But on RHEL5, LSB log_{success,failure}_msg no longer logs to syslog.
# Since the init activity is important, reintroduce it privately
#
# $*		log message
# Returns always 0.

function mylog_success_msg() {
	log_success_msg $*
	logger -p daemon.notice  -t $MYNAME "$* succeeded"
	return 0
}

function mylog_failure_msg() {
	log_failure_msg $*
	logger -p daemon.err -t $MYNAME "$* failed"
	return 0
}

# mypidof() - get the pid of processes
#
# We should use LSB function pidofproc.
# But on RHEL5, LSB pidofproc exposes problems in the GA release with
# /etc/init.d/eecd init script, because it has the same name as
# /usr/sbin/eecd daemon.
# This problem does not appear if pidof is used instead of pidofproc.
# pidof is also available on SLES.
#
# $1		absolute name of process's program file
# stdout	pid of process
# Returns 0 or 1 if process exists or not.

function mypidof() {
	local pid

	pid=$(pidof $1) || pid=$(pidof ${1##*/}) || return 1
	echo "$pid"
	return 0
}

# testVersionViewFile - test VersionView.sav for consistency and force its rebuild if not
#
# No argument or return value.

function testVersionViewFile() {

	[ -f /etc/srvmagt/VersionView.sav ] && {
		gawk -f /etc/srvmagt/vvcheck.awk /etc/srvmagt/VersionView.sav >/dev/null || \
			rm -f /etc/srvmagt/VersionView.sav
	}
}

# writeAuthConf - write authentication configuration to eecd /etc/srvmagt/config
#                 to eecd for use with the Remote SCU
#
# No argument or return value.

function writeAuthConf() {

	if [ "$NoAccountCheck" == "" -o "$NoAccountCheck" == "0" ]; then
		eecdcp -c oc=e002 oe=3812 01 >/dev/null
	else
		eecdcp -c oc=e002 oe=3812 00 >/dev/null
	fi
	eecdcp -c oc=e002 oe=3813 \"$UserGroup\" >/dev/null
}

# MibSetEnabled - write MIB SET allowed from configuration /etc/srvmagt/config
#                 to eecd for use in (currently only) sc2agt
#
# No argument or return value.

function MibSetEnabled() {

	if [ "$AgentPermission" == "3" ]; then
		eecdcp -c oc=e002 oe=3810 01 >/dev/null
	else
		eecdcp -c oc=e002 oe=3810 00 >/dev/null
	fi
}

# MibSetAgentShutEnabled - write AgentShut allowed from configuration /etc/srvmagt/config
#                          to eecd for use in (currently only) sc2agt
#
# No argument or return value.

function MibSetAgentShutEnabled() {

	if [ "$AgentShut" == "3" ]; then
		eecdcp -c oc=e002 oe=3811 01 >/dev/null
	else
		eecdcp -c oc=e002 oe=3811 00 >/dev/null
	fi
}

# mapAgtState - map the subagent's operational state from int to string
#
# $1		name of the subagent
# stdout	status value as string
# No return value.

# Agent state according to their /etc/srvmagt/agent_table/{agt}agt
#  1=running, 2=degraded, 3=error, 4=failed, 5=unused, else=unknown
agtstate=("unknown" "running" "degraded" "error" "failed" "unused")

function mapAgtState() {
	local state

	# Show what status the subagents holds about itself from line 3 of its status file

	state=0
	[ -f /etc/srvmagt/agent_table/${1}agt ] && {
		line=0
		while read state; do
			line=$((line + 1))
			[ $line -eq 3 ] && break
		done < /etc/srvmagt/agent_table/${1}agt

		#  1=running, 2=degraded, 3=error, 4=failed, 5=unused, else=unknown

		[ $state -lt 1 -o $state -gt 5 ] && state=0
	}
	echo ${agtstate[$state]}
}

# wait4eecd - have some patience with eecd initialization
#
# No return value.

function wait4eecd() {
	local count

	echo -e "Waiting for eecd ready ..\c"
	count=25	# If >99 adjust \b's below
	while [ $count -gt 0 ]; do
		sleep 1
		:
		count=$(($count - 1))
		if [ $count -ge 10 ]; then
			echo -e "\b\b$count\c"
		else
			echo -e "\b\b$count \c"
		fi
	done
	echo -e "\b\bdone ($count)"
}


# getAgentXsocket - get the AgentX socket used by the running snmpd
#
# stdout	name of AgentX socket or ""
# Returns 0 or 1 if the AgentX socket name exists or not

function getAgentXsocket() {
	local snmpd_pid=0
	local sleep_count=5

	# Particularly during reboot give snmpd time to complete initialization
	# and to establish the AgentX socket

	while [ $sleep_count -gt 0 ]; do
		[ -f /var/run/snmpd.pid ] && snmpd_pid=$(cat /var/run/snmpd.pid) && break # SLES 9+10
		[ -f /var/run/snmpd ] && snmpd_pid=$(cat /var/run/snmpd) && break # RHEL 3+4
		sleep 1
		let sleep_count--
	done

	[ ${Voption:=0} -eq 1 ] && logger -t $MYNAME "getAgentXsocket pid = [$snmpd_pid], sleep_count = $sleep_count "
	[ $snmpd_pid -gt 0 ] && {
		socket=$(LC_ALL=C netstat -nlpx | awk -v PID=$snmpd_pid '
			# unix 2 [ ACC ] STREAM LISTENING 3399511 1074/snmpd /var/agentx/master
			$7 == "LISTENING" && $9 == PID"/snmpd" {
				print $NF
				exit 0
			}
		')
		printf "$socket"
		return 0
	}

	printf ""
	return 1
}

# SetSvEnv - setup the ServerView environment
#
# environment
#	various variable with example values
#	SV_AGENT_X_SOCKET="/var/agentx/master"
#	SV_HOSTNAME="SM3RX220"
#	SV_HOSTOSREVMAJOR=2
#	SV_HOSTOSREVMINOR=6
#	SV_HWPLATFORM="x86_64"
#	SV_NICKNAME="SLES9"
#	SV_OS="SUSE LINUX Enterprise Server 9"
#	SV_RELEASE="V2.6.5-7.191-smp"
#	SV_SYSNAME="Linux"
#	SV_SYSTEM="suse"
#	SV_VENDOR="SuSE Linux AG, Nuernberg, Germany"
#	SV_VERSION="#1 SMP Tue Jun 28 14:58:56 UTC 2005"
#	SV_VVOS="SUSE Enterprise Server 9"
#	SV_VMREL="3.5"
#	SV_INSTALL_DATE="m/d/Y HH:MM:SS" of eecd package
#
# rc return value:
#  0    version is fully supported
#  1    only main version supported
#  2    unsupported version 

# Minimal versions of supported OS (still missing OL CentOS Asianux) 
RedHatMinVers="055 064 070"
SLESMinVers="112 120"
XenMinVers="560 610 620" 
#VMMinVers="4.00 4.10"

function SetSvEnv() {
	local i line rc=2 release= 

	release="$(uname -r)"
	SV_RELEASE="V$release"
	SV_HOSTOSREVMAJOR=${release%%.*}
	SV_HOSTOSREVMINOR=${release#*.} && SV_HOSTOSREVMINOR=${SV_HOSTOSREVMINOR%%.*}

	SV_HOSTNAME="$(uname -n)" && SV_HOST=${SV_HOST%%.*}
	SV_SYSNAME="$(uname -s)"
	SV_VERSION="$(uname -v)"
	SV_HWPLATFORM="$(uname -i)"
	SV_ARCH="$(uname -m)"

	SV_IS_PRIMEQUEST=0
	SV_IS_PRIMEQUEST2000=0
	model=$(isPRIMEQUEST) && {
		SV_IS_PRIMEQUEST=1
		[ $model ==  "PRIMEQUEST2000" ] && 
			SV_IS_PRIMEQUEST2000=1
	}

	SV_AGENT_X_SOCKET=$(getAgentXsocket)
	SV_VME_WAIT_TIME_FOR_VMSERVER=0

	if [ -f /etc/SuSE-release ]; then
		# SUSE LINUX Enterprise Server 9 (i586)
		# VERSION = 9
		# PATCHLEVEL = 2
		# ->   SV_OS="SUSE LINUX Enterprise Server 9"
		# -> SV_VVOS="SUSE Enterprise Server 9"
		# SuSE SLES-8 (i386)
		# VERSION = 8.1
		# ->   SV_OS="SUSE SLES-8"
		# -> SV_VVOS="SUSE Enterprise Server 9"

		SV_SYSTEM="suse"
		for i in 1 2 3; do
			read line[i]
		done < /etc/SuSE-release
		SV_OS=${line[1]%% (*}
		SV_VVOS=${SV_OS/LINUX /}
		SV_NICKNAME="SLES${line[2]##* }"
		SV_OS_MAJOR="${line[2]##* }"
		SV_OS_MINOR=${line[3]##* }
		SV_OS=$(printf "%s SP%s" "$SV_OS" $SV_OS_MINOR)
		SV_VENDOR="$(rpm -qf --queryformat %{vendor} /etc/SuSE-release 2>/dev/null)"
		for vers in $SLESMinVers; do
			if [ "${vers:0:2}" -eq ${line[2]##* } ]; then
				# main version supported
				rc=1                 
				[ ${vers:2} -le $SV_OS_MINOR ] && {
					# supported Version
					rc=0
				}
				break
			fi
		done

		tmpstr=`echo $SV_NICKNAME | tr '[:upper:]' '[:lower:]'`
		SV_REPO=$(printf "%s-sp%s" $tmpstr $SV_OS_MINOR)
		
		# special case: Business Servers of the SQ Series
		if [ -f /etc/FUJITSU-release ]; then                                    
			# Fujitsu SW appliance                                      
			# -> SV_OS = Appliance Version / SV_NICKNAME                
			read line < /etc/FUJITSU-release                            
			SV_OS="$line / $SV_NICKNAME"                                
			SV_VENDOR="$(rpm -qf --queryformat % vendor /etc/FUJITSU-release 2>/dev/null)"
		fi            

	elif [ -f /etc/vmware-release ]; then
		rc=2  # no longer supported

	elif isOVMServer; then
		SV_SYSTEM="ovmserver"
		read line < /etc/redhat-release
		SV_OS=${line/release /}
		SV_VVOS=$SV_OS
		line=${line#*release }
		SV_OS_MAJOR=${line:0:1}
		SV_OS_MINOR=${line:2:1}
		SV_NICKNAME="OVM$SV_OS_MAJOR$SV_OS_MINOR"
		SV_VENDOR="Oracle"
		rc=0

	elif [ -f /etc/oracle-release ]; then
		SV_SYSTEM="oraclelinux"
		read line < /etc/oracle-release
		SV_OS=${line/release /}
		SV_VVOS=$SV_OS
		line=${line#*release }
		SV_NICKNAME="OL${line:0:1}"
		SV_VENDOR="Oracle"
		rc=0

	elif [ -f /etc/redhat-release ]; then
		# NOTE: Do this AFTER the VMware tests!

		if isXenServer; then
			# XenServer release 3.2.0-2004d (xenenterprise)
			# XenServer release 4.0.1-4066p (xenenterprise)
			# ->   SV_OS=SV_VVOS="XenServer 4.0.1-4066p"

			SV_SYSTEM="xenserver"
			read line < /etc/redhat-release
			line=${line%% (*}
			SV_OS=${line/release /}
			SV_VVOS=${SV_OS/Linux /}
			line=${line#*release }
			SV_OS_MAJOR=${line:0:1}
			SV_OS_MINOR=${line:2:1}
#			upd=${line:4:1}
			SV_NICKNAME="XS$SV_OS_MAJOR$SV_OS_MINOR"
			SV_VENDOR="XenServer"
			for vers in $XenMinVers; do
				if [ "${vers:0:2}" -eq $SV_OS_MAJOR$SV_OS_MINOR ]; then
					# main version supported - no update check
					rc=0               
					#[ ${vers:2} -le $upd -a $((${vers:2} + 2)) -gt $upd ] && {
					#    # supported Version
					#    rc=0
					#}
					break
				fi
			done  

			[ -d /var/log/FTS ] || (mkdir -p /var/log/FTS)
			[ -d /var/log/srvmagt ] || mkdir -p /var/log/srvmagt
			ln -sf /var/log/srvmagt /var/log/FTS
			
			# set environment variables for ring buffer size
			[ -z "$SV_LOG_RINGBUF_WEIGHT_EECD" ] && export SV_LOG_RINGBUF_WEIGHT_EECD=10
			[ -z "$SV_LOG_RINGBUF_WEIGHT_SCAGT" ] && export SV_LOG_RINGBUF_WEIGHT_SCAGT=1
			[ -z "$SV_LOG_RINGBUF_WEIGHT_SC2AGT" ] && export SV_LOG_RINGBUF_WEIGHT_SC2AGT=1
			[ -z "$SV_LOG_RINGBUF_WEIGHT_BUSAGT" ] && export SV_LOG_RINGBUF_WEIGHT_BUSAGT=1
			[ -z "$SV_LOG_RINGBUF_WEIGHT_HDAGT" ] && export SV_LOG_RINGBUF_WEIGHT_HDAGT=1
			[ -z "$SV_LOG_RINGBUF_WEIGHT_UNIXAGT" ] && export SV_LOG_RINGBUF_WEIGHT_UNIXAGT=0
			[ -z "$SV_LOG_RINGBUF_WEIGHT_ETHERAGT" ] && export SV_LOG_RINGBUF_WEIGHT_ETHERAGT=0
			[ -z "$SV_LOG_RINGBUF_WEIGHT_BIOSAGT" ] && export SV_LOG_RINGBUF_WEIGHT_BIOSAGT=0
			[ -z "$SV_LOG_RINGBUF_WEIGHT_SECURAGT" ] && export SV_LOG_RINGBUF_WEIGHT_SECURAGT=0
			[ -z "$SV_LOG_RINGBUF_WEIGHT_STATUSAGT" ] && export SV_LOG_RINGBUF_WEIGHT_STATUSAGT=1
			[ -z "$SV_LOG_RINGBUF_WEIGHT_INVAGT" ] && export SV_LOG_RINGBUF_WEIGHT_INVAGT=0
			[ -z "$SV_LOG_RINGBUF_WEIGHT_THRAGT" ] && export SV_LOG_RINGBUF_WEIGHT_THRAGT=0
			[ -z "$SV_LOG_RINGBUF_WEIGHT_VVAGT" ] && export SV_LOG_RINGBUF_WEIGHT_VVAGT=1
			[ -z "$SV_LOG_RINGBUF_WEIGHT_HPSIMAGT" ] && export SV_LOG_RINGBUF_WEIGHT_HPSIMAGT=1
			[ -z "$SV_LOG_RINGBUF_WEIGHT_SVUPDATEAGT" ] && export SV_LOG_RINGBUF_WEIGHT_SVUPDATEAGT=0
			[ -z "$SV_LOG_RINGBUF_WEIGHT_OSAGT" ] && export SV_LOG_RINGBUF_WEIGHT_OSAGT=0
			[ -z "$SV_LOG_RINGBUF_WEIGHT_SVREMCONSCCI" ] && export SV_LOG_RINGBUF_WEIGHT_SVREMCONSCCI=1
			[ -z "$SV_LOG_RINGBUF_WEIGHT_SVREMCONXFER" ] && export SV_LOG_RINGBUF_WEIGHT_SVREMCONXFER=0
			[ -z "$SV_LOG_RINGBUF_WEIGHT_SVREMCONVME" ] && export SV_LOG_RINGBUF_WEIGHT_SVREMCONVME=0
			[ -z "$SV_LOG_RINGBUF_WEIGHT_PRIMECOLLECTPROVIDER" ] && export SV_LOG_RINGBUF_WEIGHT_PRIMECOLLECTPROVIDER=0
			[ -z "$SV_LOG_RINGBUF_WEIGHT_PCSysScan" ] && export SV_LOG_RINGBUF_WEIGHT_PCSysScan=0
			[ -z "$SV_LOG_RINGBUF_WEIGHT_SVRemConVME" ] && export SV_LOG_RINGBUF_WEIGHT_SVRemConVME=0

		else
			# Red Hat Enterprise Linux AS release 3 (Taroon Update 4)
			# ->   SV_OS="Red Hat Enterprise Linux AS 3"
			# -> SV_VVOS="Red Hat Enterprise AS 3"

			SV_SYSTEM="redhat"
			read line < /etc/redhat-release
			tmpline=${line%% (*}
			SV_OS=${tmpline/release /}
			SV_VVOS=${SV_OS/Linux /}
			tmpvers=${tmpline#*release }
			SV_OS_MAJOR="${tmpvers%%.*}"
			SV_NICKNAME="RHEL$SV_OS_MAJOR"
			SV_OS_MINOR=${tmpvers#*.}
			SV_OS_MINOR=${SV_OS_MINOR% *}
			[ -z "${line/*Update*}" ] && {
				SV_OS_MINOR=${line#*Update }
				SV_OS_MINOR=${SV_OS_MINOR%)*}
				SV_OS=$(printf "%s.%s" "$SV_OS" ${SV_OS_MINOR%%.*})
			}
			SV_VENDOR="$(rpm -qf --queryformat %{vendor} /etc/redhat-release 2>/dev/null)"

			for vers in $RedHatMinVers; do
				if [ "${vers:0:2}" -eq ${tmpvers:0:1} ]; then
					# main version supported
					rc=1                                
					[ ${vers:2} -le ${SV_OS_MINOR} ] && {
						# supported Version
						rc=0
					}
					break
				fi
			done       
			tmpstr=`echo $SV_NICKNAME | tr '[:upper:]' '[:lower:]'`
			SV_REPO=$(printf "%s-u%s" $tmpstr $SV_OS_MINOR)
		fi
	elif [ -f /etc/turbolinux-release  ]; then
		SV_SYSTEM="turbolinux"
		read line < /etc/turbolinux-release
		SV_OS=${line%% (*}
		SV_VVOS=${SV_OS}
		SV_OS_MAJOR=${SV_OS#*Server }
		SV_NICKNAME="TLX$SV_OS_MAJOR"
		SV_VENDOR="Turbolinux"
		#SV_VENDOR="$(rpm -qf --queryformat %{vendor} /etc/turbolinux-release 2>/dev/null)"   
		rc=0 
	else
		SV_SYSTEM=$Unknown
		SV_OS="$(uname -s)"
		SV_NICKNAME=$Unknown
		SV_VENDOR=$Unknown
		echo "Cannot fully identify this OS from '/etc/*-release'!\n"
	fi

	[ "$SV_VENDOR" ] || SV_VENDOR=$SV_VVOS

	SV_RUNNINGONVM=$(isVM)

	lsmod | grep -q 'egenera_' && SV_RUNNINGONPAN="PRIMERGY PAN BLADE"

	datearr=($(LC_ALL=C rpm -q --queryformat '%{INSTALLTIME:date}\n' srvmagt-eecd))  || datearr=($(LC_ALL=C date +%c))
	i=0
	for month in "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
	do
		i=$(($i + 1))
		[ "$month" = "${datearr[1]}" ] && break
	done
	SV_INSTALL_DATE=$(printf "%d/%d/%d %s" $i ${datearr[2]} ${datearr[4]} ${datearr[3]})


	export SV_OS SV_OS_MAJOR SV_OS_MINOR SV_VVOS SV_RELEASE SV_VENDOR SV_HOSTNAME SV_HOSTOSREVMAJOR \
		SV_HOSTOSREVMINOR SV_SYSNAME SV_VERSION SV_SYSTEM SV_HWPLATFORM \
		SV_AGENT_X_SOCKET SV_NICKNAME SV_RUNNINGONVM SV_RUNNINGONPAN SV_VMREL \
		SV_INSTALL_DATE SV_ARCH SV_VME_WAIT_TIME_FOR_VMSERVER SV_REPO \
		SV_IS_PRIMEQUEST SV_IS_PRIMEQUEST2000
	return $rc
}

# exportConfVars - exports all keywords from srvmagt.config
#	

function exportConfVars () {
	export AgentPermission AgentShut ShutdownDelay UserGroup ScanTapeDevices \
		TraceFileLimit NoAccountCheck InventoryRescan \
		CDPollInterval AgentsToBeStarted WaitForEecdSockets WaitForEecdTerm InvAgtPollNetUtilization

}

# checkArch - check if the architecture of a package matches the systems processor architecture
#
# $1		package name
# $2		Processor architecture (uname -m)
# stdout	package architecture
# Return    0 or 1 if the architecture matches or not

function checkArch () {
	local thePkgArch arch

	thePkgArch=$(rpm -q  --queryformat '%{ARCH}' $1)
	for arch in $thePkgArch; do
		if [ "$arch" = "noarch" ]; then
			printf "$arch"
			return 0
		elif [ "${arch:0:1}" = "i" ]; then
			[ "${arch:1}" -le "${2:1}" ] && {
				printf "$arch"
				return 0
			}
		else
			[ "$arch" = "$2" ] && {
				printf "$arch"
				return 0
			}
		fi
	done
	return 1
}

# checkKernelSource - check the existence and the architecture of the kernel source package
#                     and determine path to kernel source
#
# $1		OS nick name SLESx | RHELx | ESXx | XSx
# $2		Processor architecture (uname -m)
# stdout	calculated path with kernel source on return 0
# Return    0 kernel found and package ok
#           1 no kernel source found
#           2 wrong architecture of the kernel source package

function checkKernelSource () {
	local release=${SV_RELEASE:1} thePkgs aPkg pkg pkgArch path

	case $1 in
	SLES*)
		# kernel source is in symbolic link /lib/modules/$(uname -r)/source
		#
		# /lib/modules/2.6.5-7.97-smp/source -> /usr/src/linux-2.6.5-7.97/
		#
		# The additional checks address problems very rarely seen.

		thePkgs=$(rpm -q kernel-source) || return 1
		for pkg in $thePkgs; do
			path=/lib/modules/$(uname -r)/source
			[ -L $path ] && [ -d $path ] && {
				pkgArch=$(checkArch $pkg $2)
				if [ $? -eq 0 ]; then
					path=$(readlink $path)
					printf "%s:%s:%s" $path $pkg $pkgArch
					return 0
				else
					return 2
				fi
			}
		done ;;

	ESX3*)
		# kernel-source-|2.4.21-27|.EL     kernel-source-|2.4.21-37.0.2|.EL.23447
		#               |2.4.21-27|.ELsmp                |2.4.21-37.0.2|.ELvmnix
		# kernel path /usr/src/linux-2.6.5-7.191

		thePkgs=$(rpm -q kernel-source) || return 1
		for aPkg in $thePkgs; do
			SV_KERNEL_PKG=$aPkg
			pkg=${aPkg#kernel-source-}
			pkg=${pkg#303.}		# ESX 3.0.3: kernel-source-303.|2.4.21-57|.EL.104629
			pkg=${pkg#350.}		# ESX 3.5.0: kernel-source-350.|2.4.21-47.0.1|.EL.82663
			pkg=${pkg%.EL*}		# |2.4.21-37.0.2|.ELvmnix
			[ "$pkg" = "${release%.EL*}" ] && {
				pkgArch=$(checkArch $aPkg $2)
				if [ $? -eq 0 ]; then
					path="/usr/src/linux-${release%.EL*}.EL"
					printf "%s:%s:%s" $path $pkg $pkgArch
					[ -d "$path" ] && return 0
				else
					return 2
				fi
			}
		done ;;
		
	ESX4)
		return 1 ;; # no kernel sources available

	RHEL*|XS*)
		# kernel source is in symbolic link /lib/modules/$(uname -r)/source -> build -> <target dir>
		#
		# RHEL 4.7: /lib/modules/2.6.9-78.ELsmp/source -> build -> /usr/src/kernels/2.6.9-78.EL-smp-i686
		# RHEL > 5  : /lib/modules/$(uname -r)/source  -> build -> ../../../usr/src/kernels/$(uname -r)
		#
		# The additional checks address problems very rarely seen.

		thePkgs=$(rpm -qa | grep 'kernel-.*devel')
		for pkg in $thePkgs; do
			path=/lib/modules/$(uname -r)/build
			[ -L $path ] && [ -d $path ] && {
				pkgArch=$(checkArch $pkg $2)
				if [ $? -eq 0 ]; then
					path=$(readlink $path)
					printf "%s:%s:%s" $path $pkg $pkgArch
					return 0
				else
					return 2
				fi
			}
		done ;;

	esac
	return 1
}


# checkJavaVersion - check the existence and version of java interpreter
# Return    0 found and version ok
#           1 no java interpreter found
#           2 wrong version (too old)

function checkJavaVersion () {
	#Check if java interpreter exists
	java -version > /tmp/java_version 2>&1 || {
		rm -f /tmp/java_version
		return 1
	}

	minVers=$1
	Java_major=${minVers%.*}
	Java_minor=${minVers#*.}
	

	read line < /tmp/java_version
	line=${line#*java version \"}
	mm=${line%.*}
	major=${mm%.*}
	minor=${mm#*.}

	rm -f /tmp/java_version
	[ "$major" -lt $Java_major ] && return 2
	[ "$major" -eq $Java_major ] && 
		# major version fits, check minor version
		[ "$minor" -lt $Java_minor ] && return 2
	printf "${line%\"*}"
	return 0

}

# checkSVRAIDVersion - check the version of ServerView_RAID
# Return    0 version ok or not installed
#           1 wrong version (too old)

function checkSVRAIDVersion () {

	minVers=$1
	RAID_MinMajor=${minVers%.*}
	RAID_MinMinor=${minVers#*.}
	RAID_MinMinor=${RAID_MinMinor%-*}
	RAID_MinRel=${minVers#*-}
	
	RAIDVers=$(rpm -q --qf "%{VERSION}-%{RELEASE}" ServerView_RAID)
	[ $? -ne 0 ] && return 0

	RAID_Major=${RAIDVers%%.*}
	RAID_Minor=${RAIDVers#*.}
	RAID_Minor=${RAID_Minor%-*}
	RAID_Rel=${RAIDVers#*-}
	RAID_Rel=${RAID_Rel%.*}

	(( $RAID_Major < $RAID_MinMajor )) && return  1
	(( $RAID_Major == $RAID_MinMajor )) &&  {
		# major version fits, check minor version
		(( $RAID_Minor < $RAID_MinMinor )) && return 1
		(( $RAID_Minor == $RAID_MinMinor )) &&  {
			# major and minor version fit, check release
			(( $RAID_Rel < $RAID_MinRel )) && return  1
		}
	}
	return 0;
}


# isVM - on what type of virtual machine (VM), if any,  do we operate?
#
# A virtual machine (VM) is operated by a host OS that is not
# easily detectable from within the VM. Hosts OSs include:
#
#	o VMware ESX Server 3x
#	o XEN
#	o MS Hyper-V
#
# A VM can be "fully virtualiuzed", ie.e running out of the box
# or "paravirtualized", i.e. running with optimized drivers to
# improve performance.
#
# For VMs the following models are defined:
#
#   Name of model                           Assumed host
#	1) PRIMERGY VIRTUAL MACHINE				VMware
#	2) PRIMERGY XEN VM PARAVIRTUALIZED		XEN
#	3) PRIMERGY XEN VM FULLY VIRTUALIZED	XEN
#	4) PRIMERGY KVM							KVM
#   5) <more to come>
#
# No arguments.
# stdout	calculated model of VM
# Returns 0 or 1 if this IS or IS NOT a VM

_VMmodel[0]="No VM"
_VMmodel[1]="PRIMERGY VIRTUAL MACHINE"
_VMmodel[2]="PRIMERGY XEN VM PARAVIRTUALIZED"
_VMmodel[3]="PRIMERGY XEN VM FULLY VIRTUALIZED"
_VMmodel[4]="PRIMERGY KVM"

_IsVM=		# not set or 0, no VM; otherwise index into above array

function isVM () {
	local DMIDECODE="" model=""

	# Use a naive cache and complement it to meet return status conventions

	[ -n "$_IsVM" ] && printf "${_VMmodel[$_IsVM]}" && return $((! $_IsVM))

	# If DMI examination returns as FIRST "Serial Number: VMware*",
	# this is "PRIMERGY VIRTUAL MACHINE".

	DMIDECODE=$(type /etc/srvmagt/dmidecodeSV 2> /dev/null) || DMIDECODE=$(type dmidecode 2> /dev/null)
	[ -n "$DMIDECODE" ] && {
        serial=$(${DMIDECODE#*is } 2>/dev/null  | awk -F: '
                        $1 ~ /Serial Number$/ {
                                print substr($2,match($2,/[[:alpha:]]/));
                                exit 0
                        }')
       [ -n "$serial" ] && {
			[ -z "${serial##VMware-*}" ] && {
				_IsVM=1
				printf "${_VMmodel[$_IsVM]}"
				return 0
			}
		}
    }

	# Now check if Product Name starts with PRIME.  
	# If it does, this is a real system (PRIMERGY or PRIMEQUEST). 
	# Otherwise remember model for later.
    
	[ -n "$DMIDECODE" ] && {
		model=$(${DMIDECODE#*is } 2>/dev/null  | awk -F: '
			$1 ~ /Product Name$/ {
				print substr($2,match($2,/[[:alpha:]]/));
				exit 0
			}')
		[ -n "$model" ] && {
			[ -z "${model##PRIME*}" ] && {
				_IsVM=0
				printf "${_VMmodel[$_IsVM]}"
				return 1
			}
		}
	}

	# This is really some kind of VM
	# The order below is significant and subject to change!

	# Not used any longer, as open-vm-tools also owns 'etc/vmware-tools'
	# Assume VMware (fully virt.) VM if "vmware-tools" are present,
	#[ -d "/etc/vmware-tools" ] && {
	#	_IsVM=1
	#	printf "${_VMmodel[$_IsVM]}"
	#	return 0
	#}

	# Assume a Xen Virtual Machine this can be either XEN para- or full virtualized or Pan VM
	[ -z "$model" ] && {
		# XEN para virtualized
		_IsVM=2
		printf "${_VMmodel[$_IsVM]}"
		return 0
	}

	[ "$model" = "HVM domU" ] && {
		# XEN full virtualized
			_IsVM=3
			printf "${_VMmodel[$_IsVM]}"
			return 0
	}

	[ "$model" = "KVM" ] && {
		# KVM
			_IsVM=4
			printf "${_VMmodel[$_IsVM]}"
			return 0
	}

	# Unknown assume no virtual machine
	_IsVM=0
	printf "${_VMmodel[$_IsVM]}"
	return 1
}

# isPRIMEQUEST
#
# No arguments.
# Returns 0 or 1 if this IS or IS NOT a PRIMEQUEST

_PQType[0]="no PRIMEQUEST"
_PQType[1]="PRIMEQUEST1000"
_PQType[2]="PRIMEQUEST2000"

_IsPQ=		# not set or 0, no PRIMEQUEST; otherwise index into above array

function isPRIMEQUEST () {
	local DMIDECODE="" model=""

	# Use a naive cache and complement it to meet return status conventions
	[ -n "$_IsPQ" ] && printf "${_PQType[$_IsPQ]}" && return $((! $_IsPQ))

	# Check, if DMI examination returns as FIRST "Product Name: PRIMEQUEST*",

	DMIDECODE=$(type /etc/srvmagt/dmidecodeSV 2> /dev/null) || DMIDECODE=$(type dmidecode 2> /dev/null)
	[ -n "$DMIDECODE" ] && {
		model=$(${DMIDECODE#*is } 2>/dev/null  | awk -F: '
			$1 ~ /Product Name$/ {
				print substr($2,match($2,/[[:alpha:]]/));
				exit 0
			}')
		[ -n "$model" ] && {
			[ -z "${model##PRIMEQUEST *2*}" ] && {
				_IsPQ=2
				printf "${_PQType[$_IsPQ]}"
				return 0
			}
			[ -z "${model##PRIMEQUEST*}" ] && {
				_IsPQ=1
				printf "${_PQType[$_IsPQ]}"
				return 0
			}
		}
	}

	# Unknown or something different: assume no PRIMEQUEST
	_IsPQ=0
	printf "${_PQType[$_IsPQ]}"
	return 1
} 

function edac_disable () {
	local edac_mods mod

	edac_mods=$(lsmod | grep edac_mc)
	[ -z "$edac_mods" ] && return 2

	mod=${edac_mods#* [0-9] }
	modprobe -s -r $mod || return 1

	echo -e "$mod" >/etc/srvmagt/edacModule
	return 0
}

function edac_enable () {
	local mod
	[ -s "/etc/srvmagt/edacModule" ] || return 2

	read mod </etc/srvmagt/edacModule
	modprobe -s $mod || return 1

	 >/etc/srvmagt/edacModule
	return 0
}

#	getcommunity.sh - get configured SNMP community from snmpd configuration file
#
#	ServerView Linux Agents expect community information in the token "com2sec"
#	for SOURCE "localhost" (or "127.0.0.1"), for example:
#
#	com2sec NAME     SOURCE       COMMUNITY	# COMMENT
#	com2sec svSec    localhost    internal	# map internal request to svSec name
#
#	The COMMENT field is optional, the NAME, SOURCE, COMMUNITY fields MUST exist.
#	Return the community from the FIRST occurence of "localhost" or "127.0.0.1"
#	(as string) to stdout, use "public" as default.
#
# FILES
#	/etc[/snmp]/snmpd.conf		snmpd configuration file
#
# RETURN STATUS
#	0	return (default) community
#	1	no snmpd configuration file found

function getcommunity () {
for SNMPCONFPATH in "/etc" "/etc/snmp"; do
	[ -f ${SNMPCONFPATH}/snmpd.conf ] && {
		awk '
			BEGIN { community = "public" }
			$1 == "com2sec" && NF >= 4 {
				if ($3 == "localhost" || $3 == "127.0.0.1") {
					community = $4
					exit
				}
			}
			END { print community }
		' ${SNMPCONFPATH}/snmpd.conf
		return 0
	}
done
return 1
}

# searchCDROMs - search mounted CD-ROMs for ServerView RPM path
#
# No arguments.
# stdout	the existing RPM package path on the CD-ROM
# Returns 0 or 1 if ServerView RPM path IS or IS NOT available

function searchCDROMs() {
	local dev mnt fstype

	# Look into /etc/mtab, if a CD/DVD is mounted. Then test
	# if the ServerView RPM path from the mount point is available.
	# NOTE: The assumption that there is only one CD/DVD drive!

	[ -r /etc/mtab ] && {
        while read dev mnt fstype rest; do
            [ "$fstype" = "udf" ] && break
        done < /etc/mtab

        [ -n "$mnt" ] &&
            
            mnt=$(echo $mnt | sed  "s/040/ /g")

        [ -n "$mnt" -a -d "$mnt/$CDPATH" ] && {
                ln -sf "$mnt/$CDPATH" /tmp/srvmagtDVDinstall 2>/dev/null
                printf "/tmp/srvmagtDVDinstall" 
                return 0
        }
    }
    return 	1
}

# validateIPaddr - validate an IP address in dotted decimal notation
#                  (four dot-separated numbers 0 thru 255)
#
# $1		the string to validate
# Returns	0|1 if OK or not OK.

function validateIPaddr() {
	local ipaddr i invalid=1

	[ -z "$1" ] && return 1

	ip=(${1//./ })	# replace '.' by ' ' and put fields into ip[]
	[ ${#ip[@]} -eq 4 ] && {
		invalid=0
		for i in 0 1 2 3; do
			case ${ip[$i]} in
			[0-9]|[0-9][0-9]|[0-2][0-9][0-9])
				[ ${ip[$i]} -gt 255 ] && invalid=1 ;;
			*)	invalid=1 ;;
			esac
		done
	}
	[ $invalid -eq 1 ] && printf "$IPaddrIsInvalid" "$1"
	return $invalid
}

# askDialog - dialog with string as response
#
# $1		prompt string
# stdout	prompt
# Output	user's response (on return 0) into GLOBAL variable AnswerOfDialog
# Returns	0|1 if OK|Cancel

AnswerOfDialog=""
function askDialog() {
	local answer tries
	
	tries=3
	while [ $tries -gt 0 ]; do

		printf "$Cancel" "$1"
		read answer

		[ -z "$answer" ] && let tries-- && continue
		case "$answer" in
			[cC])	return 1 ;;
			*)      AnswerOfDialog="$answer" ; return 0 ;;
		esac
	done
	return 1
}

# makeDottedIPaddr - transform $1 into familiar dotted IP address
#
# $1		a string of four IFS-separated hexdigit pairs
# stdout	result to stdout

function makeDottedIPaddr() {
	local a b c d

	[ -z "$1" ] && {
		printf ""
		return
	}
	set $1
	let a=16#$1 b=16#$2 c=16#$3 d=16#$4
	printf "$a.$b.$c.$d"
}

# chkAndGetCommunity - validate the community return hostname and the valid community
# $ipMMB $snmpLog $SV_COMMUNITY
# $1		IP-Address of MMB or local address
# $2		Logfile
# $3		community
#
# stdout	hostname and community "<hostname>:<community>"
# Returns	0|1 if OK or not OK.

function chkAndGetCommunity () {
	local ipAddr logfile community defCommunity="public"

	ipAddr=$1
	logfile=$2
	community=$3
	if [ -z "$community" ]; then
		community=$(getcommunity)
		if [ $? -eq 0 ]; then
			hostname=$(snmpget -v1 -c $community $ipAddr system.sysName.0 2>>$logfile) || return 1
		else
			hostname=$(snmpget -v1 -c $defCommunity $ipAddr system.sysName.0 2>/dev/null)
			if [ $? -ne 0 ]; then
				return 1
			else
				community=$defCommunity
			fi
		fi
	else
		hostname=$(snmpget -v1 -c $community $ipAddr system.sysName.0 2>>$logfile) || return 1
	fi
	printf "%s:%s"  ${hostname#*: } $community
	return 0
}
# EOF
