#!/usr/bin/ksh -p

# Copyright (c) 05/15/02 Sun Microsystems, Inc. All Rights Reserved
# %WW 02/05/15

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

UTLIB="$(/bin/pkginfo -r SUNWuto)/SUNWut/lib"

ME=$0
ARGS=$*

#############################################################################
# Subroutines
#

#
# Usage message
#
function usage {

print "
Usage: $ME [-a | -e enetAddr] [-r] [-n networks] [-s source] [-f facility] 
	   [-d destination]
Parameters:
 -c			# cleanup log files
 -a | -e enetAddr	# all terminals, or only enetAddr terminal, affected
 -r			# remove logging
 -n interface		# symbolic names of SunRay interconnect interfaces
 -N subnetworks		# the subnetwork address for the SunRay network
 -s {all|kernel|network|usb|video|application}
 			# source within terminal
 -f {user|local[0-7]}.{panic|alert|crit|error|warn|notice|info|debug}
 			# syslog facility id used to send terminal messages
 -d {emailAddress | /fileName | @remoteLogHost }
 			# tells syslog where to file messages. multiple
			# comma separated destinations may be specified
"

exit 2
}

#
# Translate string to syslog facility ID
#
function facilityId {
case $1 in
	kern)	print $((0<<3));;	# kernel messages
	user)	print $((1<<3));;	# random user-level messages
	mail)	print $((2<<3));;	# mail system
	daemon)	print $((3<<3));;	# system daemons
	auth)	print $((4<<3));;	# security/authorization messages
	syslog)	print $((5<<3));;	# internal syslogd messages
	lpr)	print $((6<<3));;	# line printer subsystem
	news)	print $((7<<3));;	# netnews subsystem
	uucp)	print $((8<<3));;	# uucp subsystem
	cron)	print $((15<<3));;	# cron/at subsystem
	local0)	print $((16<<3));;	# reserved for local use
	local1)	print $((17<<3));;	# reserved for local use
	local2)	print $((18<<3));;	# reserved for local use
	local3)	print $((19<<3));;	# reserved for local use
	local4)	print $((20<<3));;	# reserved for local use
	local5)	print $((21<<3));;	# reserved for local use
	local6)	print $((22<<3));;	# reserved for local use
	local7)	print $((23<<3));;	# reserved for local use
	*)	usage;;
esac
}

#
# Translate string to syslog priority ID
#
function priorityId {
case $1 in
	emerg|panic)
		print 0;;	# system is unusable
	alert)	print 1;;	# action must be taken immediately
	crit*)	print 2;;	# critical conditions
	err*)
		print 3;;	# error conditions
	warn*)
		print 4;;	# warning conditions
	notice)	print 5;;	# normal but signification condition
	info)	print 6;;	# informational
	debug)	print 7;;	# debug-level messages
	*)	usage;;
esac
}

#
# Translate syslog facility.priority string to decimal number
#
LOG_PRIMASK=7		# mask to extract priority part (internal)
LOG_FACMASK=1016	# mask to extract facility part

function facPri {
	fac=$(facilityId $1)
	pri=$(priorityId $2)
	print $(( ($fac & $LOG_FACMASK) | ($pri & $LOG_PRIMASK) ))
}


#
# get the current dhcp table info
#
GetCurrentCfg () {
	rm -f $DHTADM_P 2> /dev/null
	dhtadm -P 2>/dev/null | sed -e "1,2d" > $DHTADM_P
	return $?
}

#
# Get the DHCP type string for a particular symbol
#
function dhcpGetSymType {
	print $(nawk '
			{
				if($1 == symbol) {
					print $3;
				}
			}
		' symbol=$1 ${DHTADM_P})
}

#
# Get the current DHCP value of a symbol
# Parameters:
#	$1 the symbol for the value to be returned
#	$2 (new) if exists, use it as the Macro name
#
function dhcpGetSymValue {
	typeset Macro=${MACRO}
	if [ $# -eq 2 ]; then
	    Macro=$2
	fi
	nawk '
		{
			if (($1 == macro) && ($2 == "Macro")) {
				print $3;
			}
		}
	' macro=$Macro ${DHTADM_P} |
	tr ':' '\012' |
	grep -w $1 |
	sed -e 's/^[^=]*=//'
}

#
# Set the value of a DHCP symbol. Define a new symbol if needed
# dhcpSetSym name type value
#
CORONA_NAME="SunRay"
function dhcpSetSym {

  # do this for each of the given interfaces
  NETWORKS="/etc/inet/networks";
  for INTF in ${INTF_LIST} ${SUBNET}; do
    CheckIPA ${INTF}
    if [[ $? -eq 0 ]]; then
	# subnetworks
	INTF_NET=${INTF}
    else
	INTF_NET=`/usr/bin/netstat -n -I ${INTF} -f inet | /usr/bin/awk 'NR == 2 { print $3 }'`;
    fi
    INTF_NETNAME=${CORONA_NAME}-${INTF}
    MACRO=`grep "^${INTF_NETNAME}" ${DHTADM_P} | awk '{ print $1 }'`
    if [ -z "$MACRO" ]; then
      continue
    fi
    AUTHSRVR=$(dhcpGetSymValue AuthSrvr)

	Symbol=$1
	Pvalue=$(dhcpGetSymValue $Symbol)	# present value
	if [ -z "${Pvalue}" ]; then
		# try looking up in the SunRay Macro
		Pvalue=$(dhcpGetSymValue $Symbol ${CORONA_NAME})
	fi
	Nvalue="$2"			# new value

	# print "_______________"
	# print "Symbol=$Symbol"
	# print "Pvalue=$Pvalue"
	# print "Nvalue=$Nvalue"

	if [ "$Pvalue" != "$Nvalue" ]
	then
		# Set symbol value 
		/usr/sbin/dhtadm -M -m $MACRO -e "$Symbol=$2"
		DHCPchanged=true
	fi
  done
}

#
# Verify a dotted IP address
#  usage:  CheckIPA <ipaddr>
# returns a 0 if a good ipa is given, and a 1 otherwise
#
function CheckIPA {
  typeset IP_ADDR=`expr ${1} : '^\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)$'`
  if [ ! "${IP_ADDR}" ]; then
    return 1
  fi
  NNO1=${1%%.*}
  tmp=${1#*.}
  NNO2=${tmp%%.*}
  tmp=${tmp#*.}
  NNO3=${tmp%%.*}
  tmp=${tmp#*.}
  NNO4=${tmp%%.*}
  if [ ${NNO1} -gt 255 -o ${NNO2} -gt 255 -o ${NNO3} -gt 255 -o ${NNO4} -gt 255 ]; then
    return 1
  fi
  return 0
}

#
# Utility functions to set various symbols
#

# logkern FacId
function LogKern {
	dhcpSetSym LogKern $1
}

function LogNet {
	dhcpSetSym LogNet $1
}

function LogUSB {
	dhcpSetSym LogUSB $1
}

function LogVid {
	dhcpSetSym LogVid $1
}

function LogAppl {
	dhcpSetSym LogAppl $1
}

function GetPid {
  pid=`/usr/bin/ps -e |
	/usr/bin/grep $1 |
	/usr/bin/sed -e 's/^  *//' -e 's/ .*//'`
}


#
# HupDHCP - send a HUP signal to the dhcp daemon
#
HupDHCP () {

    pkill -HUP in.dhcpd
    case $? in
    0)	# signal sent succesfully
	print "### reinitialized DHCP daemon"
	;;
    1)	# dhcp is not currently running
	print "#### DHCP daemon not reinitialized because it is not currently running.\
	    \nYou may want to start one manually using \"${INIT_DHCP} start\"."
	;;
    *)	# failed with some other error
	print -u2 "Warning: failed to initialize the DHCP daemon.\
	\nYou may want to restart it manually."
	;;
    esac
}


############################################################################
# Begin main part of script
#

#
# Constants
#
CONF=/etc/syslog.conf
DHTADM_P="${TMPDIR}/utlog-dhtadm-P.$$"
trap "rm -f ${TMPDIR}/*.$$; exit" 0 1 2 3 14 15


# XXX How do we select the correct IPA? Does it matter?
# XXX need to fix multi-corona-network configuration
#IPA=$(/usr/sbin/ifconfig -a |
#	/usr/bin/sed -e 'N' -e 's/:.*inet//' -e 's/ net.*$//' |
#	/usr/bin/grep -v lo0 |
#	head -1 | cut '-d ' -f2
#	)

#
# Default values
#
ALL=1		# command affects all Coronas
EA=""
REMOVE=0	# Add logging
SOURCE="all"	# log everything
FACILITY="user.info"	# XXX this should come out of a configuration file
DESTINATION="/var/opt/SUNWut/log/messages"
CLEANUP=0;
MESSAGE=0;	# By default, no message, just configure
DODHCP="Y";
DHCPchanged=false
INTF_LIST=""
SUBNET=""

#
# need to run after dhcpconfig runs
#
GetCurrentCfg
if [ ${?} -ne 0 ]; then
	print "Error: DHCP has not been configured. Please run dhcpconfig"
	exit 1
fi

#
# Parse and validate command line options
#
while getopts ace:rn:N:s:f:d:z name
do
	case $name in
	a)	if [ -n "$EA" ] ; then usage; fi;
		ALL=1;;
	e)	if [ $ALL -eq 1 ] ; then usage; fi;
		ALL=0
		EA="$OPTARG";;
	n)	INTF_LIST="$OPTARG";;
	N)	SUBNET="$OPTARG";;
	r)      REMOVE=1;;
	s)	SOURCE="$OPTARG";; # XXX should allow comma separated list
	f)	FACILITY="$OPTARG";;
	d)	DESTINATION="$OPTARG";;
	c)	CLEANUP=1;;
	z)	DODHCP="N";;
	?)	usage;;
	esac
done

case $FACILITY in
	user.* | local1.info)
		;;
	*)
		print "user.* facilities are the only ones that work"
		exit 2
		;;
esac

shift $(($OPTIND - 1))
if [ $# -ne 0 ]
then
	# Log a message and exit
	MESSAGE="$*"
	/usr/bin/logger -p $FACILITY -t SUNWut $MESSAGE
	exit 0
fi

if [ "$CLEANUP" -eq 1 ]
then
	logdir=$(dirname $DESTINATION)
	logfile=$(basename $DESTINATION)
	cd $(dirname $DESTINATION) || usage;
	if [ -f $logfile ]
	then
		# move old log
		$UTLIB/utagelog $logfile 5
		kill -HUP `cat /etc/syslog.pid`
	fi
	exit 0
fi

if [ -z "$SOURCE" ]
then
	print "Error: must supply a message source";
	usage;
fi

#
# Translate facility name to numeric constant
#
FACILITYID=$(facPri $(print $FACILITY | sed -e 's=\.= ='))
FACILITYID=$(( ~$LOG_FACMASK & $FACILITYID )) # XXX NewT forces facility to be "user"

if [ $REMOVE -eq 0 ]
then
	#
	# Set the facility IDs at the UltraTerminal end
	#
	case "$SOURCE" in
	all)
		LogKern $FACILITYID
		LogNet $FACILITYID
		LogUSB $FACILITYID
		LogVid $FACILITYID
		LogAppl $FACILITYID
		;;
	kernel)
		LogKern $FACILITYID
		;;
	network)
		LogNet $FACILITYID
		;;
	usb)
		LogUSB $FACILITYID
		;;
	video)
		LogVid $FACILITYID
		;;
	application)
		LogAppl $FACILITYID
		;;
	*)
		usage;;
	esac


	#
	# Update /etc/syslog.conf
	#

	syslog_changed=false
	# Syslog complains if the file isn't there.
	# XXX will syslog create the file anyway?
	if [ ! -f $DESTINATION ]; then
		mkdir -p $(dirname $DESTINATION)
		touch $DESTINATION
		syslog_changed=true
	fi

	# check to see if this log entry is already there
	N=$(/usr/bin/grep -c "${FACILITY}.*${DESTINATION}" $CONF)
	if [ $N -eq 0 ]
	then
		# print "# $ME $ARGS"
		print "$FACILITY\t\t\`${DESTINATION}'" >> $CONF
		syslog_changed=true
	fi
	# Need to kick syslog
	if $syslog_changed; then
		pkill -HUP syslogd
	fi

	# Need to kick dhcp if DODHCP is "Y"
	if ${DHCPchanged} && [[ $DODHCP = "Y" ]]; then
		HupDHCP
	fi

else # Remove an entry
	print REMOVING AN ENTRY IS NOT YET IMPLEMENTED # XXX
fi
