#!/usr/bin/ksh
# Copyright (c) 2000 Sun Microsystems, Inc.  All Rights Reserved.
#
#
# Module Name:
#
#      instancecfg.sh
#
# Abstract:
#
# This module is the shell script for creating PCNL instances --
# assigning instance numbers and creating the data files and
# directories.
#
#
# Revision History:
#


#
# Remove all (unwanted) aliases
#
unalias -a


#
# Prevent the callers umask from altering file mode
#
umask 0


PATH=/sbin:/usr/sbin:/usr/bin:/opt/SUNWcluster/bin:/etc/opt/SUNWlznb/sbin:/opt/lanman/bin:/opt/lanman/sbin:/opt/lanman/lib:/opt/lanman/lib/ha

# initialze the common shell variables
ILIMIT=10
MAXINST=50

CLcfg=/opt/lanman/lib/ha/ha_config
CLuncfg=/opt/lanman/lib/ha/ha_unconfig
CLlist=/opt/lanman/lib/ha/ha_list

OnCluster="no"
TargetLogicalHost=""
LogicalIP=""
ConfiguredMaster=""
LogicalHosts=""
ClusterNodes=""
FileSystems=""
if [ "$Runjoindomain" = "" ]
then
      Runjoindomain="yes"
fi
if [ "$AddNonClusterNode" = "" ]
then
    AddNonClusterNode=0
fi

PCNL_INSTANCE=""
SharedDataDir=""
IPAddress=""


Service="pc_netlink"

TEMPFILE=/tmp/.lmxpsfile$$

LMPATHS="`/bin/dirname $0`/../lib/lmpaths"

if [ -f ${LMPATHS} ]
then
    . ${LMPATHS}
else
    . lmpaths
fi

LIB=/opt/lanman/lib

#
# Function to run gettext with TEXTDOMAINDIR set.
# TEXTDOMAINDIR is not set in the exported environment so subprocesses 
# do not inadvertently use it.
#

pgettext () {
	gttext=gettext #Trick to fool shgettext
	TEXTDOMAINDIR=${textdomaindir} ${gttext} ${textdomain} "$1"
}

Sig_Handler() {
    if [ "$action" != "add" -o "${PCNL_INSTANCE}" = "" ]
    then
	exit 1
    fi

    IDIR="`instlist $PCNL_INSTANCE | nawk '{print $2}'`"

    if [ $OnCluster = "yes" ]
    then
        ${CLuncfg} -d ${PCNL_INSTANCE} $TargetLogicalHost ${IDIR:-""}
    else
	instdirs -f -d $PCNL_INSTANCE ${IDIR:-"/"} 
	instset -d $PCNL_INSTANCE
    fi

    exit 1
}

#
# if not root then exit
#
ID="`id | cut -d\( -f1`"
if [ "${ID}" != "uid=0" ]
then
	eval echo "\"`pgettext '\nYou must be root to run instancecfg.\n'`\""
	exit 1
fi

# Simple yes or no prompter
#
Is_Answer_Yes()
{
        while [ /bin/true ]
        do
                read answer ignore_extra_words

                case "$answer" in

                y|Y|yes|YES|Yes)
                        true; return
                        ;;
                n|N|no|NO|No)
                        false; return
                        ;;
                *)
                        pgettext "Please answer Yes or No: "
                        ;;
                esac
        done
}

Prompt_For_LogicalHost()
{

   while [ /bin/true ]
    do
        # prompt for logical host
	LHosts=`${CLlist} -l`
	if [ "$LHosts" = "" ]
	then
		OnCluster="no"
		return
	fi

# Don't list logical hosts which have already been assigned 
# to an instance.
	for lh in $LHosts
	do 
		lused=`instlist | while read n f l
		do
			if [ "$l" = "$lh" ]
			then
				echo y 
			fi
		done`

		if [ "$lused" = "" ]
		then
			LogicalHosts="$LogicalHosts $lh"
		fi
	done

	if [ "$LogicalHosts" = "" ]
	then
		OnCluster="no"
		return
	fi

	pgettext "The logical hosts available on this cluster are: "
	echo $LogicalHosts
        pgettext "Enter the logical host to be used for clustered installation \
	\n(or <Return> if this instance should not be configured on a cluster) : "
        read answer ignore_extra_words
        case "$answer" in

        "")
	  OnCluster="no"
	  break
          ;;

        *)
          TargetLogicalHost=$answer
	  ConfiguredMaster=`${CLlist} -m ${TargetLogicalHost}`
	  if [ "${ConfiguredMaster}" = "`uname -n`" ]
	  then
	    return
	  else
	    echo "${TargetLogicalHost} is not currently mastered on this system.\nCurrent logical hosts mastered are:\n\t${MasterList}\n"
	  fi
        esac
	LogicalHosts=""
    done
}



Prompt_For_SharedDirectory()
{


   if [ $OnCluster = "yes" ]
   then
       FileSystems=`${CLlist} -f ${TargetLogicalHost}`
       pgettext "The file systems available for the logical host ${TargetLogicalHost} are:\n "
       echo $FileSystems
   fi
   while [ /bin/true ]
    do
        # prompt for directory path for shared data
        pgettext "Enter the directory path to be used:"
        read answer ignore_extra_words
        case "$answer" in

        "")
          ;;

        *)
          SharedDataDir=$answer
          return
        esac
    done
}

Prompt_For_IPAddress() 
{
        pgettext "\nEnter the IP address to be assigned to this instance or  \
	\n<Return> if the IP address(es) of the physical adapter(s) should be used: "
        read answer ignore_extra_words
        case "$answer" in

        "")
	  IPAddress=""
	  break
          ;;

        *)
	  srvconfig -I $PCNL_INSTANCE -s "lmxserver,ipaddress=$answer"
        esac
}



	

GetSharedFS()
{
    TmpTargetDir=$1
    while [ -n "${TmpTargetDir}" -a ! -d "${TmpTargetDir}" ]
    do
	TmpTargetDir=`echo ${TmpTargetDir} | sed -e 's-/[^/]*$--'`
    done

    if [ -z "${TmpTargetDir}" ]
    then
	TmpTargetDir=/
    fi

    SharedDataFS="`df -n ${TmpTargetDir} | cut -d':' -f1`"
}

CheckFSIsShared()
{
    FsMntPt=$1
    LogicalHost=$2

    if [ "${FileSystems}" = "" ]
    then 
	return 1
    fi

    for Fs in ${FileSystems}
    do
	if [ "${FsMntPt}" = "${Fs}" ]
	then
	    return 0
	fi
    done
    return 1
}


CheckClusterComplete() {
HAGET=/opt/SUNWcluster/bin/haget
	notdone=0
        Myname=`uname -n`
        ClusterNodes=`$HAGET -f all_physical_hosts`
        for node in ${ClusterNodes}
        do
            if [ ${node} != "$Myname" ]
            then

                #
                # grab first private link for physical host
                #
                NodePrivateLinks=`$HAGET -f private_links -h $node`
                IpAddress=`echo $NodePrivateLinks | cut -d" " -f1`

                ping $IpAddress >/dev/null 2>&1
                if [ $? = 1 ]
                then
                    eval print "\"`pgettext '\n\nAll physical nodes in the cluster must be running.  Please start node ${node}.\n'`\""
                    exit 1
                fi

		#
                # get the instance list for each physical host
                #
                Finished=`rsh $IpAddress cat /opt/lanman/haupgrade.conf 2>/dev/null | grep 1`
                if [ "$Finished" != "" ]
                then
                    notdone=1
                fi
            fi
        done
        if [ $notdone = 1 ]
        then
        	eval print "\"`pgettext '\n\nAll physical nodes in the cluster must be Upgraded \nbefore creating/deleting an instance.\n'`\""
                    exit $notdone
         fi
}

QueryCluster() {
	if [ -f ${CLlist} ]
	then
		${CLlist} -l > $DEV_NULL_PATH 2>&1
		if [ $? -eq 0 ]
		then 		
		    if [ ${AddNonClusterNode} -eq 0 ]
		    then
			OnCluster="yes"
		    fi
		fi
	fi
}

GetDirectory() {

    # prompt for shared directory path
    while [ /bin/true ]
    do
	Prompt_For_SharedDirectory

	if [ $OnCluster = "yes" ]
	then
	    pgettext "The path of the shared directory you entered was: ${SharedDataDir}\n"
	    GetSharedFS ${SharedDataDir}
	    if CheckFSIsShared ${SharedDataFS} ${TargetLogicalHost}; [ $? != 0 ]
	    then
	        pgettext "${SharedDataDir} is on filesystem ${SharedDataFS}\nwhich is not part of the disk group for logical host ${TargetLogicalHost}\n\n"
	        continue
	    fi
	else
	    pgettext "The path of the directory you entered was: ${SharedDataDir}\n"
	fi

	if [ ! -d "${SharedDataDir}" ]
	then
	    pgettext "This directory does not exist - would you like to create it? [y/n]: "

	    if Is_Answer_Yes; then
		if ( umask 022; mkdir -p "${SharedDataDir}" ) ; then
		:
		else
		    pgettext "Error creating directory -- try again\n\n"
		fi
	    fi
	fi

	if [ -d "${SharedDataDir}" ]
	then
	    break
	fi
   done
}

ConfigureInstance() {
	# select an instance number
	i=1
	while [ $i -le $MAXINST ]
	do
		mask[$i]=1
		i=`expr $i + 1`
	done
	ilist=`instget`
	if [ "$ilist" != "" ]
	then
	    limit=1
	    for j in $ilist
	    do
		if [ $limit -ge $ILIMIT ]
		then
		    instset -c
		    pgettext "Error creating instance -- No more than ${ILIMIT} instances allowed\n"
		    return 1
		fi
		limit=`expr $limit + 1`
		mask[$j]=0
	    done
	fi

	k=1
	while [ $k -le $MAXINST ]
	do
		if [ mask[$k] -eq 1 ]
		then
			PCNL_INSTANCE=$k
			break
		fi
		k=`expr $k + 1`
	done

	# allocate the instance number and create instance directories
	if [ "$PCNL_INSTANCE" == "" ]
	then
	    pgettext "Error creating instance -- Could not allocate instance number\n"
	    return 1
	fi	
		
	
	instset -a $PCNL_INSTANCE $SharedDataDir
        if [ $? -ne 0 ] 
        then
	    pgettext "Error creating instance -- Could not assign instance number\n"
	    return 1
	fi

	if [ "$SharedDataDir" == "/" ]
	then 
		SharedDataDir=""
	fi

	# Make sure that there is no old shared memory segment
	$DELSHMEM_PATH -I $PCNL_INSTANCE -f >/dev/null 2>&1

	pgettext "Creating instance data in ${SharedDataDir}/var/opt/lanman/${PCNL_INSTANCE}\n"
	instdirs -a $PCNL_INSTANCE $SharedDataDir
	if [ $? -ne 0 ]
	then
	    rm -rf ${SharedDataDir}/var/opt/lanman/${PCNL_INSTANCE}
	    rm -rf ${SharedDataDir}/etc/opt/lanman/${PCNL_INSTANCE}
	    instset -d ${PCNL_INSTANCE}
	    pgettext "Error creating instance -- Could not create instance directories\n"
	    return 1
	fi

	if [ "${IPAddress}" = "" ]
	then
	    Prompt_For_IPAddress
	elif [ "${IPAddress}" != "default" ]
	then
	    srvconfig -I $PCNL_INSTANCE -s "lmxserver,ipaddress=${IPAddress}"
	fi

	if [ "$Runjoindomain" = "yes" ]
	then
	    IDIR=$SharedDataDir
	    export IDIR
	    export PCNL_INSTANCE
	    joindomain
	fi
	return 0
}

Instance_Exists() {

	if [ $1 -gt 0 -a $1 -le $MAXINST ]
	then
		inst="`instlist $PCNL_INSTANCE`"
		if [ "${inst:-""}" != "" ]
		then
			return 0
		fi
	fi
	return 1
}

Instance_IsLocal() {
	TargetLogicalHost="`instlist $1 | nawk '{print $3}'`"
	if [ ${TargetLogicalHost:-""} = "" ]
	then
		OnCluster="no"
		return 0
	fi
	master=`${CLlist} -m $TargetLogicalHost`
	if [ "${master}" != "`uname -n`" ]
	then
		return 1
	fi
	return 0
}

Instance_NotRunning() {

	ps -ef -o pid,args | fgrep lmx > $TEMPFILE
	pidlist=`while read pid cmd dashi inst rest
	do
		if [ ${dashi:-"0"} = "-I" -a ${inst:-"0"} = $1 ]
		then 
			rm -rf $TEMPFILE
			return 1
		fi
	done < $TEMPFILE`
	rm -rf $TEMPFILE
	return 0
}

UnconfigureInstance() {

	instdirs -d $1 $2
	if [ $? -eq 0 ] 
	then
		instset -d $1
	fi
	return 0
}

# Routine to get instance number using given instance name.
convert_instance() {
if [[ "$1" < "1" || "$1" > "99" ]]
then
	ilist=`/opt/lanman/lib/instlist |awk -e ' { print $1 }'`
	for i in $ilist
	do
		name=`/opt/lanman/sbin/srvconfig -I $i -g "server,listenname"`
		if [ "$name" = "$1" ]
		then
			PCNL_INSTANCE=$i
			return 0
		fi
	done
	return 1
fi
}

usage() {
	pgettext "Usage: instancecfg [-a] [-d instance] [-l {instance}]\n"
}

### MAIN 

if [ $# -eq 0 ]
then
	usage
	exit 1
fi

trap Sig_Handler INT QUIT TERM

while getopts ald:h:p:i: option
do
	case $option in
		a)
			action=add
			;;
		d)
			action=delete
			if [ "${OPTARG:-""}" = "" ]
			then
				pgettext "Must specify instance number.\n"
				exit 1
			else
				PCNL_INSTANCE=$OPTARG
			fi
			;;
		l)
			action=list
			shift $(($OPTIND -1))
			PCNL_INSTANCE="$*"
			;;

# private options start here
		h)
			TargetLogicalHost=$OPTARG
			;;
		p)
			SharedDataDir=$OPTARG
			Runjoindomain="no"
			if [ "$IPAddress" = "" ]
			then
				IPAddress="default"
			fi
			;;
		i)
			IPAddress="$OPTARG"
			;;
		?)
			usage
			exit 1
			;;
	esac
done

if [ ! -f $LMICONFIG_PATH ]
then
	cp /dev/null $LMICONFIG_PATH
fi

QueryCluster

if [ "$OnCluster" = "yes" ]
then
	if [ "$action" = "add" ]
	then
		CheckClusterComplete
	fi
fi

if [ $action = "add" ]
then
    #prompt for logical host
    if [ "$OnCluster" = "yes" -a "${TargetLogicalHost}" = "" ]
    then
        Prompt_For_LogicalHost
    fi
    #prompt for directory
    if [ "${SharedDataDir}" = "" ]
    then
	GetDirectory
    fi
    #create the instance
    if [ $OnCluster = "yes" ]
    then 
        Runjoindomain=$Runjoindomain ${CLcfg} -a $SharedDataDir $TargetLogicalHost
    else
	ConfigureInstance
    fi
    if [ $? -ne 0 ]
    then 
	pgettext "Instance creation failed\n\n"
	exit 0
    else
	if [ $OnCluster = "yes" ]
	then
	    tempvar=`/opt/lanman/lib/instlist | grep -w $TargetLogicalHost | grep -v grep | awk '{print $1}'`
	    if [ "${tempvar}" != "" ]
	    then
		PCNL_INSTANCE=${tempvar}
	    fi
	fi
	pgettext "Instance ${PCNL_INSTANCE} created\n\n"
	exit ${PCNL_INSTANCE}
    fi

elif [ $action = "delete" ]
then
	
    # Get instance number if the instance name is supplied.
    convert_instance $PCNL_INSTANCE
    if [ $? -ne 0 ]
    then
	pgettext "The instance $PCNL_INSTANCE is not a valid instance \n\n"
	exit 1
    fi
    
    Instance_Exists $PCNL_INSTANCE
    if [ $? -ne 0 ]
    then
	pgettext "The instance $PCNL_INSTANCE is not a valid instance number\n\n"
	exit 1
    fi

    ps -ef -o pid,args | egrep "${LMXCTRL_NAME} -I ${PCNL_INSTANCE}$" | grep -v grep > $DEV_NULL_PATH 2>&1

    if [ $? = 0 ]
    then
	pgettext "The instance is running and must be stopped before deleting it.\n"
	exit 0
    fi

    if [ $OnCluster = "yes" ]
    then
	Instance_IsLocal $PCNL_INSTANCE
	if [ $? -ne 0 ]
	then
	    pgettext "The instance $PCNL_INSTANCE is not hosted by this system\n\n"
	    exit 0
	fi
    fi

    Instance_NotRunning $PCNL_INSTANCE
    if [ $? -ne 0 ]
    then
	pgettext "The instance $PCNL_INSTANCE can not be deleted while it is running\n\n"
	exit 0
    fi

    IDIR="`instlist $PCNL_INSTANCE | nawk '{print $2}'`"

    if [ $OnCluster = "yes" ]
    then
        ${CLuncfg} -d ${PCNL_INSTANCE} $TargetLogicalHost ${IDIR:-""}
    else
	UnconfigureInstance $PCNL_INSTANCE ${IDIR:-"/"}
    fi
    if [ $? -ne 0 ]
    then 
	pgettext "Instance deletion failed\n\n"
	exit 0
    fi
    # delete the temporary file.
    rm -f /tmp/.pcnl_instance_${PCNL_INSTANCE}_stopped > $DEV_NULL_PATH 2>&1
    exit 1
else
    if [ "${PCNL_INSTANCE}" != "" ]
    then
	# Get instance number if the instance name is supplied.
	convert_instance $PCNL_INSTANCE
	if [ $? -ne 0 ]
	then
		pgettext "The instance $PCNL_INSTANCE is not a valid instance \n\n"
		exit 1
	fi
    fi
	
   printf "%-18s %-3s  %-30s %-18s\n\n" ServerName No. DataPath LogicalHost

   instlist $PCNL_INSTANCE | while read in path lh rest
   do 
	if [ -f ${path}/etc/opt/lanman/${in}/lanman.ini ]
	then
		srv=`srvconfig -I $in -g "server,listenname"`
	else 
		srv="(unknown)"
	fi
	printf "%-18s %3s  %-30s %-18s\n" "$srv" $in $path $lh
   done
fi

exit 0
