#!/bin/ksh -p
#
# ident "@(#)$Id: utsvtd.ksh 12 2008-05-19 22:32:03Z mk94373 $ SMI"
#
# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
# Script to add create a ServiceTag entry for for the caller.
# This will first check if a tag has already been created. If not this,
# script will create a new one.


ME=$0

verbose=0
umask 0022
unset LD_LIBRARY_PATH
PATH=/bin:/usr/bin:
export PATH


ETCDIR=/etc/opt/SUNWutsvt
VARDIR=/var/opt/SUNWutsvt
REQDIR=/var/opt/SUNWutsvt-req

LOGFILE=$VARDIR/utsvtd.log
CACHE_PREFIX=stlog
REQ_PREFIX=streq
CONF_FILE=$ETCDIR/utsvtd.conf.defaults
SLEEPTIME="86400" ## 86400 seconds in day.


RM="rm -f"
TR=tr
GREP=grep
BASENAME=basename
PGREP=pgrep
LS=ls

#
# Set default values
#
ENABLE=YES
DAEMON=YES

set -u	# All vars must be set from now on

OS=`uname -s`
if [ "$OS" = "Linux" ];  then
	AWK=/usr/bin/gawk
	STCLIENT=/opt/sun/servicetag/bin/stclient
else
	AWK=/usr/bin/nawk
	STCLIENT=/usr/bin/stclient
	ZONENAME=/usr/bin/zonename
fi

function usage {
if [ "$1" != "1" ] &&  [ "$1" != "2" ]; then 
	OUT=2
else
	OUT=$1
fi
print -u$OUT "
Usage: $ME  {start|restart|stop|remove|help}
Parameters:
 start		# Starts a new daemon.
 restart	# Restarts the daemon.
 stop		# Stop the current daemon.
 remove		# Remove all Service Tag registrations before stopping the 
		# daemon.
 help		# help.
 "
if [ "$1" = "1" ] ; then
	exit 0
else
	exit 1
fi
}
#


# delete servicetag.
function delete_svt {

	#
	# Delete the ServiceTag
	#
	if [ -z $1 ]
	then
		return 1
	fi
	cache_file="$1"

	#
	# Check whether we already created servicetag for this installation.
	#
	if [ -s $cache_file ] 
	then 
		producturn=`${AWK} -F'>' '{print $1}' $cache_file`
		${GREP} -w $producturn $cache_file > /dev/null
		if [ $? -eq 0 ]
		then
			#
			# Registration is locally stored.
			# Remove the instance from cache file
			#
			instance=`${GREP} -w  $producturn $cache_file\
					|${AWK} -F'>' '{print $2}' `
			if [ ! -z $instance ]
			 then
				${STCLIENT}  -d -i $instance >/dev/null 
				${RM} $cache_file 
			fi
		fi
	fi
	return 0
}




# Cleanup stale entries.
function clean_svt  {

	# We cleanup the cache entry if its request file is missing.
	CACHE_FILES=`${LS} ${VARDIR}/${CACHE_PREFIX}.* 2>/dev/null`
	for FILE in $CACHE_FILES
	do
		FILE_SUFFIX=`print $FILE | ${AWK} -F'.' '{print $2}'`
		# Build the request file name
		REQ_FILE=${REQDIR}/${REQ_PREFIX}.$FILE_SUFFIX
		if [ ! -s $REQ_FILE ]
		then 
			delete_svt $FILE
			print $REQ_FILE
		fi
	done
	return 0
}




# Check for existing service Tag entries in cache files
function check_svt {
	#
	# Check whether we already created servicetag for this installation.
	#
	producturn=$1
	cache_file="${VARDIR}/${CACHE_PREFIX}.$producturn"
	if [ ! -z "$cache_file" ] 
	then 
		A=`${GREP} -w $producturn $cache_file 2> /dev/null`
		if [ $? -eq 0 ]
		then
			#
			# Registration already done.
			# No need to register again.
			#
			return 0
		else
			# We should not get here.
			return 1
		fi
	else
		return 1
		
	fi

}

function extract_kv {


# extract_kv reads stdin and for each plausible key=value assignment detected
# emits (on stdout) a shell variable assignment statement suitable for execution
# by a shell 'eval' statement.

	$AWK -F= '
	{	sub("#.*","");
	}
	/^[ 	]*$/ {
		next;
	}
	/^[ 	]*[a-zA-Z][a-zA-Z0-9_]*[ 	]*=/ {
		LINE=$0;
		sub("[ 	]*=[ 	]*","=",LINE);
		if (DEBUG) { print "LINE after sub is",LINE | "cat 1>&2"; }
		IX = index(LINE,"=");
		KEY = substr(LINE,0,IX-1);
		VALUE = substr(LINE,IX+1);
		if (DEBUG) { print "KEY and VALUE are",KEY,VALUE | "cat 1>&2"; }
		printf("%s=\"%s\"; ",KEY,VALUE);
		next;
	}
	{
		next;
	}
	END { exit 0 }
	' $1 

}

function process_svt {

	 # Initialize 
	product_urn=""
	product_version=""
	product_name=" "
	vendor=""
	parent_name=""
	parent_urn=""
	container=""
	source=""
	architecture=""
	


	eval $(extract_kv $1)
	if [ -z $product_urn ]  \
		|| [ -z $product_version ]  \
		|| [ -z $product_name ] \
		|| [ -z $vendor ] \
		|| [ -z $parent_name ] \
		|| [ -z $parent_urn ] \
		|| [ -z $container ] \
		|| [ -z $source ] \
		|| [ -z $architecture ] 
	then 
		print "Insufficient ServiceTag details from \
			request file %s", $1 >> ${LOGFILE}
		return 2
	fi

	# Check if this is already registered.
	check_svt  $product_urn

	check=$?
	if [ $check -eq 0 ] 
	then
		# Already registered.
		return 0
	else
		#New registration.
	        if [ ! -x "${STCLIENT}" ]
		then
                	return 0
		fi
		#Capture the instance to cache file
		result=`${STCLIENT} -a -p "$product_name"\
				 -e  "$product_version" \
				 -t "$product_urn" \
				 -F "$parent_urn"\
				 -P "$parent_name"  \
				 -m  "$vendor"  \
				 -A  "$architecture" \
				 -z  "$container" \
				 -S  "$source"`
	
		if [ $? -ne 0 ] 
		then 
			# Something failed. Let's log it & move on.
			print $result >> ${LOGFILE}
			return 1
		else
			#
			# ST registration succeeded. Let's cache the instance urn
			#
			instance_urn=`print $result | ${AWK} -F'=' '{print $2}'`
			cache_file="${VARDIR}/${CACHE_PREFIX}.$product_urn"
		
        		if [ ! -z $instance_urn ]
			then
				print " $product_urn > $instance_urn" >>  $cache_file
			fi
		fi
	fi
	return 0
}



#Main
if [ "$1" != "start" ] && [ "$1"  != "restart" ] && [ "$1"  != "remove" ] \
	&& [ "$1" != "stop" ]
then
	if [ "$1" = "help" ] ; then
		usage 1;
	else
		usage 2;
	fi
fi

mode=$1

#
# Now Look at our configuration
#

if [ -s $ETCDIR/utsvtd.conf ]; then
	CONF_FILE=$ETCDIR/utsvtd.conf
fi
eval $(extract_kv $CONF_FILE |$AWK '{print toupper($0)}')
if [ ! -z $ENABLE ] && [ "$ENABLE" = "NO" ]; then
	# Disabled, should exit right away.
	if [ "$mode" = "start" ] || [ "$mode" = "restart" ]; then 
		exit 0
	fi
fi

PROCESS=`${BASENAME} $0`
if [ "$OS" = "Linux" ];  then
	PIDS1=`${PGREP} -f "$PROCESS start"`
	PIDS2=`${PGREP} -f "$PROCESS restart"`
else
	ZONE=`${ZONENAME}` 
	PIDS1=`${PGREP} -z ${ZONE} -f "$PROCESS start"`
	PIDS2=`${PGREP} -z ${ZONE} -f "$PROCESS restart"`
fi
PIDS="$PIDS1 $PIDS2"

for PID in $PIDS ; do
	if [ $PID -eq $$ ] ; then
		continue
	fi
	if [ "$mode" = "start"  ]
	then
		# We might get PIDS of forked PGREP process as well.
		# So, send kill -0 to the PID. Return value of
		# 2 actually means ESRCH i.e., no such process.
		kill -0 $PID 2> /dev/null
		KILLSTATUS=$?
		if [ $KILLSTATUS -eq 2 ] ; then
			continue
		fi
		# There is already a process running. 
		# No need to start it again.
		exit 0
	else
		#
		# For restart & remove, we need to stop
		# the   current process.
		# 
		kill -KILL $PID
	fi
done


if [ "$mode" = "stop" ]; then
	exit 0
fi
	


# Remove ST entries.
if [ "$mode" = "remove" ]
then 
	CACHE_FILES=`${LS} ${VARDIR}/${CACHE_PREFIX}.* 2>/dev/null`
	for FILE in $CACHE_FILES
	do
		delete_svt $FILE
	done
	exit 0
fi
exec < /dev/null > /dev/null 2> $LOGFILE
# start fresh or restart mode
while [ 1 ]
do
	if [ -x ${STCLIENT} ]
	then
		REQ_FILES=`${LS} ${REQDIR}/${REQ_PREFIX}.*`
		for FILE in $REQ_FILES 
		do
 			 process_svt $FILE
		done
	fi
	clean_svt
	if [ ! -z $DAEMON ] && [ "$DAEMON" != "YES" ]; then
		exit 0
	fi
	sleep ${SLEEPTIME}
done      

