#!/bin/ksh -p

# Copyright (c) 1999-2003 Sun Microsystems, Inc. All Rights Reserved
# "@(#)utload.sh	1.24 03/12/01 SMI"

#
# Default values
#
DISPLAY_DIR=/var/opt/SUNWut/displays
CONTROL_IPA=0.0.0.0
CONTROL_PORT=7010
# fd number 8 is used for IO to utauthd
FILE=_
FLASH=false
USEFB=false
SID=""
# TIMEOUT=20

#
# Subroutines
#

function usage {
	print -u2 "Usage: ${0##*/} [-h host] [-p port] [-d display] [-S fwServer] [-f firmwareFile] [-w] [-b] [-c CID] [-m num]"
	exit 1
}

function checkFile {
	print -u2 checkFile not implemented
}

function getIPA {
	if [ $1 = "0" ]
	then
		print 0
		return
	fi
	IP=`getent hosts $1`

	# If null string, check for dotted notation for an
	# interconnect address not in /etc/hosts.
	if [ -z "$IP" ]
	then
		IP=`print $1 | grep '^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*$'`
		if [ -z "$IP" ]
		then
			print "BAD"
			return
		fi
	fi

	# Convert dotted IP address to hex
	print $IP | nawk '{
		split($1, bytes, ".")
		for (i = 1; i <= 4; i++) {
			if (bytes[i] == "")
				bytes[i] = 0
			printf "%02x", bytes[i]
		}
		printf "\n"
	}'
}

# Open utauthd control port for reading and writing
# Args are IPA, PORT, and FD
function openControl {
	exec 8<> /dev/tcp/$1/$2
}

# Find out the current firmware version from the terminal
function queryTerminal {
	print -u2 queryTerminal is not implemented
}

# Get the session ID of the current session
function getMySid {
	/usr/openwin/bin/xprop -root _SUN_SUNRAY_SESSION 2> /dev/null \
		| sed -e 's/.*"\(.*\)"/\1/'
}

# Get the session ID from the display number
function getDisplaySid {
	case "$(id)" in
		'uid=0('*) ;;
		*) print -u2 "Must be root to use -d option"
		   exit;;
	esac

	# Strip off any leading hostname, and trailing screen number as
	# a courtesy in case a $DISPLAY value is used. The display number
	# will always be interpreted as being on the CONTROL_HOST.

	D=$(print $1 | sed -e 's/.*://' -e 's/\..*//')
	nawk '
		/SESSION=/ {
			sub("SESSION=", "", $1)
			print $1
		}' $DISPLAY_DIR/$D 2>/dev/null
}

# translate a host name to its IP address
function getHostIPA {
	host=$1
	if [ "$host" = "$(</etc/nodename)" ]
	then
		print 0.0.0.0
		return
	fi
	case $host in
	localhost | 127.0.0.1 | 0.0.0.0)
		print 0.0.0.0
		return;;
	esac

	hostipa=$(ypmatch $host hosts 2>/dev/null | cut -f1 -d' ')
	if [ -z "$hostipa" ]
	then
		hostipa=$(nslookup $host 2>/dev/null |
		    sed -n \
			-e '/^Server:/,/^$/d'	\
			-e 's/^Address:[ 	]*\([0-9].*\)$/\1/p')
	fi
	print $hostipa
}

#
# Main program
#

#
# Parse and validate command line options
#
while getopts :f:h:p:d:S:c:m:wb name
do
	case $name in
	b)	USEFB="true";;
	c)	CID="$OPTARG";;
	d)	DISP="$OPTARG";;
	f)	FILE="$OPTARG";;
	h)	CONTROL_HOST="$OPTARG";;
	m)	HEAD="$OPTARG";;
	p)	CONTROL_PORT="$OPTARG";;
	w)	FLASH="true";;
	S)	SRVR="$OPTARG";;
	?)	usage;;
	esac
done
shift $(expr $OPTIND - 1)

if [ $# -ne  0 ]
then
    usage
fi

if [ -z $DISP ]
then
	SID=$(getMySid)
else
	SID=$(getDisplaySid $DISP)
fi

if [ -z $SID ] 
then
	echo "Session ID cannot be determined."
	usage
fi

if [ -n "$CONTROL_HOST" ]
then
	ipa=$(getHostIPA "$CONTROL_HOST")

	if [ -n "$ipa" ]
	then
		CONTROL_IPA=$ipa
	fi
fi

if [ -n "$SRVR" ]
then
	fwIPA=$(getIPA "$SRVR")
	if [ $fwIPA = "BAD" ]
	then
		usage
		exit 1
	fi
	server="server=$fwIPA\nend"
else
	server="end"
fi

if [ -n "$CID" ]
then
	if [ -n "$HEAD" ]
	then
		print -u2 "Must specify only one of -c or -m"
	fi
	CID=$(print $CID | nawk '{
			if ($0 ~ "\\." || $0 == "all") {
				print $0
			} else {
				print "IEEE802." $0
			}
		}')	
	server="cid=$CID\n$server"
fi

if [ -n "$HEAD" ]
then
	if [ -n "$CID" ]
	then
		print -u2 "Must specify only one of -c or -m"
	fi
	server="head=$HEAD\n$server"
fi

openControl $CONTROL_IPA $CONTROL_PORT

print -u8 "control $SID
request load
file=$FILE
flash=$FLASH
usefb=$USEFB
$server
"

cat < /dev/fd/8 | while read line
do
	case $line in
	(ok*|end*)
		print -u8 quit 2>/dev/null
		exit 0;
		;;
	(error*)
		print -u2 -- $line
		exit 1;
		;;
	(quit*)
		exit 0;
		;;
	*)
		;;
	esac
done

exit 0
