#!/bin/sh
#
# Check what's installed on a PCP/PCPQA VM looking for missing apps
# and packages
#

_usage()
{
    echo "Usage: $0 [-v]"
    exit 1
}

verbose=false
while getopts 'v?' p
do
    case "$p"
    in
	v)	verbose=true
		;;

	?)	_usage
		# NOTREACHED
    esac
done
shift `expr $OPTIND - 1`
[ $# -eq 0 ] || _usage

tmp=/var/tmp/$$
trap "rm -f $tmp.*; exit 0" 0 1 2 3 15

# add additional and optional directories
for dir in /sbin /usr/sbin
do
    if [ -d "$dir" ]
    then
	if echo ":$PATH:" | grep -q ":$dir:"
	then
	    :
	else
	    export PATH="$PATH:$dir"
	    #debug# echo add $dir to \$PATH
	fi
    fi
done

# perl ? apt-get install -qqy --force-yes libxml-tokeparser-perl
# perl ? apt-get install -qqy --force-yes libspreadsheet-read-perl
cat <<End-of-File >$tmp.control
# one line per app, alternate items separated by white space
# first item ending in ? means this item is a guard, if it does not
# exist silently ignore the rest of the line
# tests items can be
#	starting with a /	test for existence of file or directory
#                               (alternates separated by |)
#	containing ::		test for presence of the associated Perl module
#	otherwise		test for an executable with which(1)
#                               (alternates separated by |)
#
# text after # is treated as a comment
# text after [ is treated as annotation
#
# executables
ed
git
make
gcc
autoconf
flex
bison
gdb
mktemp
gawk
# optional executables
dpkg?	dpkg-buildpackage	[dpkg-dev]
dpkg?	dh			[debhelper]
dpkg?	chrpath			[chrpath]
dpkg?	sysv-rc-conf		[sysv-rc-conf]
rpm?	rpmbuild		[rpm-build]
# other build prerequisites
dpkg?	/usr/share/doc/pkg-config	[pkg-config]
dpkg?	/usr/share/doc/python-all-dev	[python-all-dev]
dpkg?	/usr/include/microhttpd.h	[libmicrohttpd-dev]
rpm?	/usr/include/microhttpd.h	[libmicrohttpd-devel]
dpkg?	/usr/include/sasl/sasl.h	[libsasl2-dev]
rpm?	/usr/include/sasl/sasl.h	[cyrus-sasl-devel]
rpm?	/usr/include/systemd/sd-daemon.h	[systemd-devel but not for CentOS 5.8]
dpkg?	/usr/include/infiniband/umad.h	[libibumad-dev]
rpm?	/usr/include/infiniband/umad.h	[libibumad-devel]
dpkg?	/usr/include/infiniband/mad.h	[libibmad-dev]
rpm?	/usr/include/infiniband/mad.h	[libibmad-devel]
dpkg?	/usr/include/avahi-common	[libavahi-common-dev]
rpm?	/usr/include/avahi-common	[avahi-devel]
dpkg?	g++				[g++]
rpm?	g++				[gcc-c++]
# files
dpkg?	/usr/include/readline/readline.h	[libreadline-dev]
rpm?	/usr/include/readline/readline.h	[readline-devel]
rpm?	/usr/include/ncurses.h	[ncurses-devel] # is this a bug in the spec file?
# perl modules
Time::HiRes			[Perl Time-HiRes perl-Time-HiRes(rpm)]
Date::Format			[Perl TimeDate perl-TimeDate(rpm)]
Date::Parse			[Perl TimeDate perl-TimeDate(rpm)]
Getopt::Std			[base Perl]
dpkg?	ExtUtils::MakeMaker	[libextutils-autoinstall-perl]
rpm?	ExtUtils::MakeMaker	[perl-ExtUtils-MakeMaker]
dpkg?	XML::TokeParser		[libxml-tokeparser-perl]
rpm?	XML::TokeParser		[perl-XML-TokeParser]
Spreadsheet::Read		[libspreadsheet-read-perl(dpkg)]
dpkg?	Spreadsheet::WriteExcel	[libspreadsheet-writeexcel-perl]
rpm?	Spreadsheet::WriteExcel	[perl-Spreadsheet-WriteExcel]
Spreadsheet::ReadSXC		[cpan?]
# other run-time
sadf				[sysstat]
# QA
bc
curl
Spreadsheet::XLSX		[libspreadsheet-xlsx-perl(dpkg)]
dpkg?	Text::CSV_XS		[Text-CSV_XS]
rpm?	Text::CSV_XS		[perl-Text-CSV_XS]
crontab				[from vixie-cron?]
valgrind
dpkg?	mail			[bsd-mailx]
rpm?	mail			[mailx]
host				[bind-utils(redhat)]
dpkg?	apache2			[apache2]
rpm?	httpd			[httpd]
time				[time(redhat)]
dpkg?	realpath		[realpath]
# pcp-gui
dpkg?	qmake			[qt4-qmake]
rpm?	qmake|qmake-qt4			[qt-devel]
dpkg?	/usr/lib/libQtCore.so|/usr/lib/*/libQtCore.so	[libqt4-dev]
dpkg?	/usr/lib/libSoQt4.so|/usr/lib/*/libSoQt4.so	[libsoqt4-dev]
rpm?	/usr/lib/libQtCore.so|/usr/lib*/libQtCore.so	[qt-devel]
dpkg?	/usr/include/Inventor/Qt/SoQt.h	[libsoqt-dev-common]
dpkg?	/usr/include/Inventor/SoPath.h	[libcoin60-dev or libcoin80-dev]
# python
rpm?	/usr/include/python*/Python.h		[python-devel]
dpkg?	/usr/include/python*/Python.h		[python-dev]
# nss
dpkg?	/usr/include/nspr/nspr.h	[libnspr4-dev]
rpm?	/usr/include/nspr4/nspr.h	[nspr-devel]
dpkg?	/usr/include/nss/nss.h		[libnss3-dev]
rpm?	/usr/include/nss3/nss.h		[nss-devel]
dpkg?	certutil			[libnss3-tools]
rpm?	certutil			[nss-tools]
End-of-File

if which python >/dev/null 2>&1
then
    # For python-ctypes, check for python before 2.5 ... expect something like
    # Python 2.7.3
    eval `python -V 2>&1 | sed -e 's/Python //' -e 's/^/maj=/' -e 's/\./ min=/' -e 's/\..*//'`
    if [ -n "$maj" -a -n "$min" ]
    then
	rm -f $tmp.need
	if [ "$maj" -lt 2 ]
	then
	    touch $tmp.need
	elif [ "$maj" -eq 2 -a "$min" -lt 5 ]
	then
	    touch $tmp.need
	fi
	[ -f $tmp.need ] && \
	    echo "rpm?	/usr/share/doc/packages/python-ctypes	[python-ctypes]" >>$tmp.control
    fi
fi

cat $tmp.control \
| sed -e 's/#.*//' -e '/^[ 	]*$/d' \
| while read apps
do
    rm -f $tmp.ok
    for app in $apps
    do
	case $app
	in
	    \[*)
	    	break
		;;
	    *\?)
	    	app=`echo $app | sed -e 's/?$//'`
		optional=true
		;;
	    *)
		optional=false
		;;
	esac
	case $app
	in
	    \[*)
	    	break
		;;
	    /*)
		rm -f $tmp.tmp
		for file in `echo "$app" | sed -e 's/|/ /g'`
		do
		    if [ -f "$file" -o -d "$file" ]
		    then
			touch $tmp.tmp
			break
		    fi
		done
		[ -f $tmp.tmp ]
		ok=$?
		;;
	    *::*)
		echo "use $app;" | perl >/dev/null 2>&1
		ok=$?
		;;
	    *)
		rm -f $tmp.tmp
		for exec in `echo "$app" | sed -e 's/|/ /g'`
		do
		    if which $exec >/dev/null 2>&1
		    then
			touch $tmp.tmp
			break
		    fi
		done
		[ -f $tmp.tmp ]
		ok=$?
		;;
	esac
	if $verbose
	then
	    echo -n " .. $app"
	    $optional && echo -n "[optional]"
	    if [ $ok = 0 ]
	    then
		echo -n " yes"
	    else
		echo -n " no"
	    fi
	fi
	if [ $ok = 0 ]
	then
	    $optional && continue
	    touch $tmp.ok
	    break
	else
	    if $optional
	    then
		# guard not true, skip checks for other apps
		touch $tmp.ok
		break
	    fi
	fi
    done
    $verbose && echo
    if [ ! -f $tmp.ok ]
    then
	echo "Missing: `echo $apps \
	    | sed \
		-e 's/[ 	][ 	]*/ /g' \
		-e '/ /{
s/? /?@/
:loop1
s/\(\[.*\) /\1@/
t loop1
:loop2
s/ \([^[]\)/@|@\1/
t loop2
s/@/ /g
}'`"
    fi
done

# Some platform-specific and special case tests
#
if which dpkg >/dev/null 2>&1
then
    # Debian based
    #
    dpkg -l >$tmp.tmp
    for pkg in python-all python-all-dev
    do
	if grep "^ii *$pkg" <$tmp.tmp >/dev/null
	then
	    :
	else
	    echo "Need # apt-get install $pkg"
	fi
    done
fi

# Networking goo
#
_check_host()
{
    ipaddr=`sed -n </etc/hosts -e '/^#/d' -e '/::/d' -e 's/$/ /' -e "/[ 	]$1[ 	]/"'{
s/[ 	].*//
p
}'`
    if [ -z "$ipaddr" ]
    then
	echo "No /etc/hosts entry for $1"
	return
    fi

    if [ `echo "$ipaddr" | wc -l | sed -e 's/  *//g'` -gt 1 ]
    then
	echo "Multiple /etc/hosts entries for $1"
	return
    fi

    ifconfig \
    | awk '
/^[^ 	]/	{ iface = $1; next }
/inet addr:'$ipaddr' / || /inet '$ipaddr' / {
			  if (iface == "lo")
			    print "Warning: '$1' associated with loopback network interface"
			  found = 1
			  exit
			}
END		{ if (found != 1)
		    print "Warning: '$1' ('$ipaddr') not associated with a network interface"
		}'
}

host=`hostname`
_check_host $host
if which pmhostname >/dev/null 2>&1
then
    pmhost=`pmhostname`
    if [ -z "$pmhost" ]
    then
	echo "Warning: pmhostname returns nothing!"
    else
	case $pmhost
	in
	    $host|$host.*)
		    ;;
	    *)
		    echo "Warning: hostname ($host) is not a prefix of pmhostname ($pmhost)"
		    ;;
	esac
	_check_host $pmhost
    fi
fi

if [ -f /etc/pcp.conf ]
then
    . /etc/pcp.conf

    # need QA access to pmlogger via pmlc
    #
    if [ -f $PCP_SYSCONF_DIR/pmlogger/config.default ]
    then
	if grep -q 'allow 192\.168\.1\.\*' $PCP_SYSCONF_DIR/pmlogger/config.default
	then
	    :
	else
	    echo "Missing: \"allow 192.168.1.* : all;\" [access] in $PCP_SYSCONF_DIR/pmlogger/config.default"
	fi
    else
	echo "Warning: \"$PCP_SYSCONF_DIR/pcp/pmlogger/config.default\" is missing"
    fi
else
    echo "Warning: \"/etc/pcp.conf\" is missing"
fi
