#!/bin/sh
#
# ident "@(#)utsyscfg.sh	1.13	05/06/01 SMI"
#
# Copyright 2001-2004 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
###########################################
# chkconfig header info for RH
#
# chkconfig: 5 11 83
# description: Sets up Sun Ray network ports
#
###########################################
# insserv header info for JDS/SuSE
### BEGIN INIT INFO
# Provides:			utsyscfg
# Required-Start:		$network
# X-UnitedLinux-Should-Start:
# Required-Stop:
# X-UnitedLinux-Should-Stop:
# Default-Start:                5
# Default-Stop:			1 2 3 4
# Short-Description:
# Description:			Sets up Sun Ray network ports
### END INIT INFO

############################################################################
#
# This script performs one-time setup activities for Sun Ray.  It tailors
# the Sun Ray configuration to match the system's features (eg Xinerama
# capability) and adjusts the system to accomodate Sun Ray quirks.  The
# things that happen here can be done once as the system goes multi-user
# and don't need to be repeated whenever the Sun Ray suite is restarted.
# Anything that needs to be done on every Sun Ray restart belongs
# someplace else, traditionally in the utsvc script.  The script runs
# every time we go up to multi-user, and not just once per boot, because
# some of things we're looking for may have been affected by patches that
# may have been applied in single-user mode.
#
# This script runs fairly early in rc2.d.  On the very first boot we want
# to run before inetd gets started so that we can mark the Sun Ray ports
# 'privileged' before there's any chance of anyone getting into the
# machine and binding a non-root process to those ports.

############################################################################
##
## Function Definitions 
##

# Tell the world (via stdout by historical precedent, although it should
# really be via stderr) how to invoke this script.
#
# Syntax: 'usage'
#
usage() {
	echo "Usage: $0 { start | stop }"
}


# Print a message on stdout if the VERBOSE flag is non-zero.
#
# Syntax: 'vecho text ...'
#
vecho() {
	if [ $VERBOSE -ne 0 ] ; then
		echo "# ${MYNAME}: $@"
	fi
}


# Print the port number corresponding to a given service name, as retrieved
# by 'getent' or, if that fails, by the contents of /etc/services.
#
# Syntax: serv2port servicename
#
serv2port() {

	PORTNUM=`getent services "$1" | awk '{print $2}' | sed 's@/.*@@'`
	if [ -n "$PORTNUM" ] ; then
		echo "$PORTNUM"
		return
	fi

	# nothing found by the configured naming services, try reading
	# /etc/services directly.

        nawk -v SERVICE="$1" '{ \
		sub(/#.*/,""); \
		for (I=1; I<=NF; ++I) { \
			if ($I==SERVICE) { \
				sub(/\/.*/,"",$2); \
				print $2;
				exit; \
			} \
		} \
	}' /etc/services 
}

# Print a list of the Sun Ray port numbers that should be declared
# privileged.  Each line of the table in the inline 'here document'
# contains the name of a Sun Ray service and the port number to be
# used for that service if no port number is returned for that service
# by the service-name-to-port lookup function.
#
# Syntax: privportnums
#
privportnums() {

	while read SERVICE DEFAULTPORT ; do

		# If serv2port can't find a port number for this service we
		# use the default port number held in $DEFAULTPORT
		#
		PORT=`serv2port "$SERVICE"`
		if [ -z "$PORT" ] ; then
			PORT="$DEFAULTPORT"
		fi

		# Emit the (partial) result
		#
		echo "$PORT \c"

	done << EndOfPortList
		utsessiond	7007
		utrcmd		7008
		utauthd		7009
		utauthd-cb	7010
		utdevmgrd	7011
		utdsd		7012
		utscreventd	7013
EndOfPortList

}


# Mark the Sun Ray ports 'privileged' so that they can't be used by a
# non-root user.
#
# Syntax: privports
#
privports() {

        # Mark the Sun Ray daemon ports 'privileged' so that they can't be
        # grabbed by non-root users.  Strictly speaking we only need one
        # UDP port (7009) but we grab both TCP and UDP in all cases, partly
        # for symmetry and partly to leave headroom for feature creep.
        #
        TCP_EXTRA_PRIVS=`/usr/sbin/ndd /dev/tcp tcp_extra_priv_ports`
        UDP_EXTRA_PRIVS=`/usr/sbin/ndd /dev/udp udp_extra_priv_ports`

        for PORT in `privportnums` ; do
            echo "$TCP_EXTRA_PRIVS" | grep -w "$PORT" > /dev/null
            if [ $? -ne 0 ] ; then
		vecho "marking port ${PORT}/tcp privileged"
                /usr/sbin/ndd -set /dev/tcp tcp_extra_priv_ports_add ${PORT}
            else
		vecho "port ${PORT}/tcp is already privileged"
	    fi
            echo "$UDP_EXTRA_PRIVS" | grep -w "$PORT" > /dev/null
            if [ $? -ne 0 ] ; then
		vecho "marking port ${PORT}/udp privileged"
                /usr/sbin/ndd -set /dev/udp udp_extra_priv_ports_add ${PORT}
            else
		vecho "port ${PORT}/udp is already privileged"
            fi
        done
}


# Decide whether this system's X server supports the Xinerama and DPMS
# options.
#
# Syntax: xsunoptions
#
xsunoptions() {

	# Create a flag file that indicates that the X server does not
	# support Xinerama.  If the X server in fact does support
	# Xinerama then the option '-xinerama' will appear in its usage
	# report and we will record that fact by removing the flag file.

	XINERAMAFLAGFILE=${SUNWUTETC}/ut_disable_xinerama
	(umask 022 && > ${XINERAMAFLAGFILE})

	# Create a flag file that indicates that the X server does not
	# support DPMS.  If the X server in fact does support DPMS then
	# the option '-dpms' will appear in its usage report and we will
	# record that fact by removing the flag file.

	DPMSFLAGFILE=${SUNWUTETC}/ut_disable_dpms
	(umask 022 && > ${DPMSFLAGFILE})

	# Examine the X server's usage message.

	XSUNOPTS=`/usr/openwin/bin/Xsun -help 2>&1 | /bin/awk '/^-/ {print $1}'`

	for OPT in $XSUNOPTS ; do

	    case "$OPT" in 

		'-xinerama')
			vecho "Xinerama is supported"
			rm -f ${XINERAMAFLAGFILE}
			;;

		'-dpms')
			vecho "DPMS is supported"
			rm -f ${DPMSFLAGFILE}
			;;
	    esac

	done

	[ -r ${XINERAMAFLAGFILE} ] && vecho "Xinerama is not supported"
	[ -r ${DPMSFLAGFILE}     ] && vecho "DPMS is not supported"
}

loadutadem() {
	if [[ -f ${INSTALLDIR}/utadem.o ]]; then
		rm -f /dev/utadem 2>/dev/null
		depmod -a >/dev/null 2>&1
		if [[ $? != "0" ]]; then
			vecho "Unable to create module dependencies for utadem."
			return 1
		fi
		modprobe utadem
		if [[ $? != "0" ]]; then
                        vecho "Unable to load utadem module."
                        return 1
                fi
		vecho "utadem module successfully loaded."
		MINOR_NUM=`grep dsp /proc/driver/utadem | awk '{print $2}'`
		if [[ -z $MINOR_NUM ]]; then
			vecho "Unable to get the utadem device minor number."
			return 1
		fi
		mknod -m 0777 /dev/utadem c 14 $MINOR_NUM 2>/dev/null
		if [[ $? = "0" ]]; then
			vecho "Created /dev/utadem device node."
		else
			vecho "Unable to create /dev/utadem."
			return 1
		fi	
	fi
	return 0
}

loadutio() {
	if [[ -f ${INSTALLDIR}/utio.o ]]; then
		rm -f /dev/utio 2>/dev/null
		depmod -a >/dev/null 2>&1
		if [[ $? != "0" ]]; then
			vecho "$MYNAME: Unable to create module dependencies for utio."
			return 1
		fi
		modprobe utio
		if [[ $? != "0" ]]; then
			vecho "$MYNAME: Unable to load utio module."
			return 1
		fi
		vecho "utio module successfully loaded."
		MAJOR_NUM=`cat /proc/driver/utio | awk '{print $2}'`
		if [[ -z $MAJOR_NUM ]]; then
			vecho "$MYNAME: Unable to get the utio device major number."
			return 1
		fi
		mknod -m 600 /dev/utio c  $MAJOR_NUM 0 
		if [[ $? = "0" ]]; then
			vecho "Created /dev/utio device node."
		else
			vecho "$MYNAME: Unable to create /dev/utio."
			return 1
		fi
	fi
	return 0
}


############################################################################
##
## Mainline execution starts here 
##

PATH=/bin:/sbin:/usr/bin
export PATH

MYNAME=`basename "$0"`

BASE=`/etc/opt/SUNWut/basedir/lib/utprodinfo -r SUNWuto`
SUNWUT=$BASE/SUNWut
SUNWUTLIB=$SUNWUT/lib
SUNWUTETC=/etc/opt/SUNWut

# We support a couple of undocumented options to help with debugging:
#   -v for verbose, -D for blow-by-blow shell echoing.

VERBOSE=0

while getopts Dv OPTCH; do

	case "$OPTCH" in
		v)	VERBOSE=1
			;;
		D)	set -x
			;;
		*)	usage
			exit 1
			;;
	esac
done
shift `expr "$OPTIND" - 1`

# Validate the (remaining) arguments

if [ $# -ne 1 ] ; then
	usage
	exit 1
fi

OS=`/bin/uname -s`

case "$1" in

	start)	
		VERSION=`/bin/uname -r`
		INSTALLDIR=/lib/modules/${VERSION}/misc
		if [ ! -f ${SUNWUTETC}/utctl.run ]; then
			# Only activatve the features once.  The utctl.run file
			# only exists when the features have been activated
			# after the software installation using "utctl enable".
			${SUNWUTLIB}/utctl enable
		fi
		case "$OS" in
		  	SunOS)		
				privports
				xsunoptions
			;;
			Linux)
				loadutadem
				UTADEMRET=$?
				loadutio
				UTIORET=$?
				if [[ $UTADEMRET != "0" || $UTIORET != "0" ]]; then
					exit 1
				fi
			;;
		esac
		;;

	stop)	
		case "$OS" in
			Linux)
				modprobe -r utio 2>/dev/null
				UTIORET=$?
				modprobe -r utadem 2>/dev/null
				UTADEMRET=$?
				if [[ $UTADEMRET != "0" || $UTIORET != "0" ]]; then
					exit 1
				fi
			;;
		esac
		;;

	*)	usage
		exit 1
		;;
esac

exit 0
