#!/usr/dt/bin/dtksh
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
#
#   COMPONENT_NAME: desktop
#
#   FUNCTIONS: none
#
#   ORIGINS: 27
#
#   This module contains                  code. -- (IBM
#   Confidential Restricted when combined with the aggregated
#   modules for this product)
#   OBJECT CODE ONLY SOURCE MATERIALS
#
#   (C) COPYRIGHT International Business Machines Corp. 1995
#   All Rights Reserved
#   US Government Users Restricted Rights - Use, duplication or
#   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
#
########################################################################
#
#	Check for things that may cause the desktop to fail, then report it.
#	Either run "dtsanity" directly at the command line, or copy the file
#	to "/usr/dt/config/Xsession.d/dtsanity".
#
#	This new functionality will add approximately 4 seconds to
#	the user's login time.
#
########################################################################

status=0
verbose=0
hello=0
portmapper=0
infailsafe=0

if [ "$0" = "/usr/dt/bin/Xsession" ]; then
	prelogin=1
	nonwindows=1
else
	prelogin=0
	nonwindows=0
fi

MOTD="/usr/tmp/dt.motd.$DISPLAY"
LOG="$HOME/.dt/errorlog"
PATH=/usr/dt/bin:/usr/bin:/usr/bin/X11:/etc:$PATH

trap "/bin/rm -f $MOTD" 1 2 3

###############################################################################

isfailsafe()
{
	if [ $infailsafe -eq 1 ]; then
		return 0
	else
		return 1
	fi

}

###############################################################################

failsafe()
{
	isfailsafe && return

	if [ $# -eq 1 ]; then
		if [ $1 -eq 0 ]; then
#			exit status was okay
			return
		fi
	fi

	infailsafe=1
	xdmstart_hello="/usr/dt/bin/dtpad -viewOnly -standAlone $LOG &"
	SESSIONTYPE="xdm"
}

###############################################################################

verbose()
{
	if [ $verbose -eq 0 ]; then
		return
	fi

	echo "$@"
}

###############################################################################

assert()
{
	if [ $1 -eq 0 ]; then
		return
	fi

	((status = status + 1))

	echo "$2"	>> /dev/console
	echo "$2"	>> $MOTD
	echo ""		>> $MOTD 
	
	if [ $nonwindows -eq 1 ]; then
		echo $2
	else
		verbose "$2"
		(/usr/dt/bin/dterror.ds "$2" "Desktop Sanity Check" "okay" &)
	fi
}

###############################################################################

log()
{
	if [ -f "$MOTD" -a $status -gt 0 ]; then
		date							>> $LOG
		echo "The following desktop anomilies were found:"	>> $LOG
		echo ""							>> $LOG
		cat $MOTD						>> $LOG
	fi
}

###############################################################################

check_nameserver()
{
	isfailsafe && return

	verbose "Checking nameserver"

	r=/etc/resolv.conf
	if [ -s $r ]; then
		a=`awk '/nameserver/ {print $2; exit}' $r`
	fi

	nslookup ${a:=localhost} > /dev/null 2>&1
	lookup=$?

	failsafe $lookup

	assert $lookup "Unable to reach nameserver at $a!"
}

###############################################################################

check_portmapper()
{
	isfailsafe && return

	verbose "Checking portmapper"

	c=`ps augwx | egrep -e portmap | egrep -v grep | wc -l`
	if [ $c -eq 0 ]; then
		portmapper=1
	fi

	if [ ! $portmapper ]; then
		out=`rpcinfo -t localhost 100000 2>&1`
		portmapper=$?
	fi

	failsafe $portmapper

	assert $portmapper "`uname -n`'s portmapper is unavailable!"
}

###############################################################################

check_loopback()
{
	isfailsafe && return

	verbose "Checking loopback"

	ping localhost 1 1 > /dev/null 2>&1
	l=$?

	failsafe $l

	assert $l "`uname -n`'s network loopback failed!"
}

###############################################################################

check_calendar()
{
	isfailsafe && return

	verbose "Checking calendar"

	out=`rpcinfo -u localhost dtcalendar 2>&1`
	S=$?
	
	if [ $prelogin -eq 1 ]; then
		if [ $S -eq 0 ]; then
			assert 1 "`uname -n`'s dtcm is already running."
		fi
		return
	fi

	assert $S "`uname -n`'s dtcm is unavailable!"
}

###############################################################################

check_ttsession()
{
	isfailsafe && return

	verbose "Checking ttsession"

	out=`xlsatoms -name TT_SESSION 2>&1`
	echo $out | grep -v "no atom named" > /dev/null
	s=$?

	c=`ps augwx | egrep -e ttsession | egrep -v grep | wc -l`

	if [ $c -gt 1 ]; then
		assert $c "More that one ttsession is running!"
	fi

	if [ $prelogin -eq 0 ]; then
		assert $s "$out"
		assert "!$c" "No ttsession is running!"
	fi

	if [ $prelogin -eq 1 ]; then
		assert "!$s" "`uname -n`'s ToolTalk is already running!"
		assert $c "A ttsession is already running!"
	fi
}

###############################################################################

check_nfs()
{
	isfailsafe && return

	verbose "Checking NFS"

	out=`rpcinfo -u localhost nfs 2>&1`
	assert $? "`uname -n`'s NFS is unavailable!"
}

###############################################################################

check_ttdbserver()
{
	isfailsafe && return

	verbose "Checking ttdbserver"

	out=`rpcinfo -t localhost tooltalk 2>&1`
	assert $? "`uname -n`'s ToolTalk database server is unavailable!"
}

###############################################################################

check_tmp()
{
	isfailsafe && return

	verbose "Checking /tmp filesystem"

	df /tmp | awk ' /dev/ {if (length($(NF-4)) <= 4) {exit 1}} '
	assert $? "`uname -n`'s /tmp filesystem is full!"
}

###############################################################################

usage()
{

cat << USAGE

dtsanity [-V] [-A | -X] [-P | -R] [-a | [-b] [-c] [-f] [-l] [-n] [-p] [-s] [-t]]

-A  ASCII mode.  No X Window dialogues.
-P  Test in pre-dtlogin mode.
-R  Test in desktop-is-running mode.
-V  Verbosely print to stdout.
-X  X Window dialogues enabled.
-a  Test everything available.
-b  Test if there is enough free blocks in /tmp.
-c  Test the desktop calendar.
-f  Test the NFS service.
-l  Test the loopback service.
-n  Test the name server.
-p  Test the portmapper (portmap) service.
-s  Test the desktop ToolTalk session (ttsession).
-t  Test the desktop ToolTalk server (rpc.ttdbserver).

USAGE

exit 0
}

###############################################################################

main()
{
	rm -f $MOTD

	if [ $# -eq 0 ]; then
		set -- "-a"
	fi

	while getopts "APRVXacfhlnpst" opt; do
		case $opt in
			A)
				nonwindows=1
				verbose "Mode: ASCII"
				;;
			V)
				verbose=1
				verbose "Mode: verbose"
				;;
			X)
				nonwindows=0
				verbose "Mode: windows"
				;;
			P)
				prelogin=1
				verbose "Mode: prelogin"
				;;
			R)
				prelogin=0
				verbose "Mode: running"
				;;
			a)
				verbose "Check everything"
				check_tmp
				check_loopback
				check_nameserver
				check_portmapper 
				check_ttdbserver
				check_ttsession
				check_nfs
				;;
			b)
				check_tmp
				;;
			c)
				check_calendar
				;;
			f)
				check_nfs
				;;
			h)
				usage
				;;
			l)
				check_loopback
				;;
			n)
				check_nameserver
				;;
			p)
				check_portmapper
				;;
			s)
				check_ttsession
				;;
			t)
				check_ttdbserver
				;;
			*)
				echo "unknown option: $opt"
				;;
		esac
	done
	shift $(($OPTIND -1))

}

###############################################################################

main "$@"

log

if [ $status -gt 0 ]; then
	dtstart_hello[0]="/usr/dt/bin/dthello -file $MOTD &"
fi

(sleep 20 && rm -f $MOTD &)

if [ $prelogin -eq 0 ]; then
	exit $status
fi
