#!/bin/ksh -pu

#
# ident "@(#)utsunmcinstall.ksh	1.7 02/10/08 SMI"
#
# Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
#

PATH="/usr/sbin:/usr/bin"

PROGRAM_ID=$(basename $0)

###
#
# Description
#       This script will install and un-install
#       Sun Ray module for Sun Management Center (SunMC)
#	only on the SunMC server and only if SRSS is not
#	installed on that server. (For SRSS use utinstall.)
#       See manpage for details.
#
###

###
#
# CAUTION:
#       This script contains functions found in support_lib
#	libraries, however they are not installed in /opt
#	on a SunMC server so need to be duplicated here
#	for utsunmcinstall -u to work.
#
#	Following are from support_lib/master_lib.ksh but
#	the functions here differ to some extent:
#		CheckMediaDir
#		CheckWorkingDir
#		CheckAdminFile
#
#	Following are from support_lib/master_lib.ksh and
#	the functions here should be the same:
#		CheckTmpDir
#
#	Following are from support_lib/iu_lib.ksh and the
#	functions here should be the same:
#		AnyPackageInstalled
#		ProductPartiallyInstalled
#		RemoveMsg
#		RemoveProduct
#
###

InstallUsage() {
  print -u2 "Usage: $PROGRAM_ID $PROGRAM_OPTS"
  print -u2 ""
  print -u2 " -u            : uninstall the software"
           
  CleanupAndExit 1
}

CleanupAndExit() {
  rm -f $ERRFILE $TMP_ADMIN_FILE
  exit $1
}

#
# CheckMediaDir()
#
# Description:
#    Check that media directory is valid
#
# Parameters:
#    (none)
#
# Globals used:
#    G_MEDIA_DIR

CheckMediaDir() {
   if [[ ! -d ${G_PRODUCT_DIR} || ! -d ${G_MEDIA_DIR} || \
         ! -d ${G_MEDIA_DIR}/support_lib ]]; then
      # CAVEAT:	No support functions have not been sourced yet
      # 	Fatal does not yet exist so fake it...
      print -u2 "$PROGRAM_ID: fatal, $G_MEDIA_DIR is not a valid directory"
      exit 1
   fi

   return 0
}

#
# CheckWorkingDir()
#
# Description:
#    Check that the working directory is not in one of the reserved 
#    directory (where the product is installed)
#
# Parameters:
#    (none)
#
# Globals used:
#    (none)

CheckWorkingDir() {

   typeset -r workdir="$(pwd)"

   case "$workdir" in
      ${UT_BASEDIR}/SUNWut/*)
         Fatal "current working directory can not be within" \
               "${UT_BASEDIR}/SUNWut"
         ;;
   esac
}

# CheckAdminFile()
#
# Description:
#    Check admin file to be used by pkgadd
#	CAVEAT: there won't be one in /opt/SUNWut/lib so we must
#		create one to do an uninstall successfully
#
# Parameters:
#    (none)
#
# Globals used:
#    G_ADMIN_FILE

CheckAdminFile() {
  if [[ -r "$G_ADMIN_FILE" ]] ; then

    cp "$G_ADMIN_FILE" "$TMP_ADMIN_FILE"
    G_ADMIN_FILE="$TMP_ADMIN_FILE"

  else
    cat > "$TMP_ADMIN_FILE" << EOF
# Dynamically generated admin file
mail=
instance=unique
partial=quit
runlevel=nocheck
idepend=nocheck
rdepend=nocheck
space=quit
setuid=nocheck
conflict=nocheck
action=nocheck
basedir=default
EOF
    G_ADMIN_FILE="$TMP_ADMIN_FILE"

  fi

  return 0
}

#
# CheckTmpDir()
#
# Description:
#    Check temporary directory exists and set G_TMP_DIR.
#
# Parameters:
#    (none)
#
# Globals used:
#    G_TMP_DIR

CheckTmpDir() {
   
   if [[ -d /var/tmp ]]; then
      G_TMP_DIR=/var/tmp
      return 0
   fi
   if [[ -d /tmp ]]; then
      G_TMP_DIR=/tmp
      return 0
   fi
   if [[ -d /usr/tmp ]]; then
      G_TMP_DIR=/usr/tmp
      return 0
   fi
   Fatal "cannot find a temporary directory"
}


#
# AnyPackageInstalled()
#
# Description:
#    to check if one of the listed packages is installed correctly
#
# Parameters:
#    $* : list of packages names
#
# Globals used:
#    (none)

AnyPackageInstalled() {
  pkginfo -q $*
  return $?
}

#
# ProductPartiallyInstalled()
#
# Description:
#    to check if a package has not been completely installed
#
# Parameters:
#    $* : list of packages names
#
# Globals used:
#    (none)

ProductPartiallyInstalled() {
  typeset pkg=""
  typeset -r all_partials="$(pkginfo -p 2>&-) "

  [[ $(echo "$all_partials" | sed 's/ //g') == "" ]] && return 1

  for pkg in $*; do
    echo "$all_partials" | grep "$pkg " 2>&1 >/dev/null && return 0
  done

  return 1
}


#
# GetAvailablePackages()
#
# Get a list of available packages currently available on the cdrom
# based on the list specified in UT_L10N_LIST.
#
# Parameters:
#	$*	: list of packages names
#
# Returns:
#	Module specific variable _SW_PKG_LIST gets the list of packages
#	currently available on the cdrom.
#
GetAvailablePackages() {
    typeset pkg=""
    _SW_PKG_LIST=""

    for pkg in $UT_L10N_LIST; do
	if [[ -d ${UT_DIR}/Packages/${pkg} ]]; then
	    _SW_PKG_LIST="${_SW_PKG_LIST} ${pkg}"
	fi
    done
}

#
# function RemoveMsg()
#
# Description:
#    to print a message before removing a product
#
# Parameters:
#    $1 : product name
#    $2 : product version
#
# Globals used:
#    (none)

RemoveMsg() {
  print "\nRemoving $1 version $2 ..."
  return 0
}

#
# function RemoveProduct()
#
# Description:
#    to remove a specific product
#
# Parameters:
#    $1            : admin file (used for pkgrm)
#    $* (after $1) : list of packages names
#
# Globals used:
#    G_DEBUG

RemoveProduct() {
  typeset -r admin_file="$1"
  shift
  typeset -r all_pkgs="$*"
  typeset -r pkg_list=$(echo "$all_pkgs" | sed -e 's; ;/\|/var/sadm/pkg/;g')
  typeset pkg=""
  typeset deplist=""
  typeset errlist=""
  typeset errdep=""
  typeset deppkg=""
  typeset status=0
  typeset vflag=""

  if [[ G_DEBUG = "yes" ]]; then
     vflag = "-v"
  fi

  for pkg in $all_pkgs; do
    pkginfo -q $pkg || continue
    deplist=$(grep "${pkg}[ 	]" /var/sadm/pkg/*/install/depend | 
        egrep -v '/var/sadm/pkg/'${pkg_list}'/' | grep '/install/depend:P' |
        awk -F/ '{print $5}')
    if [[ -z "$deplist" ]]; then
      pkginfo -q $pkg && pkgrm $vflag -n -a $admin_file $pkg
      pkginfo -q $pkg && {
        status=1
        errlist="${errlist}${pkg} "
      }
    else
      status=1
      for deppkg in $deplist; do
        errdep="${errdep}${deppkg} depends on ${pkg}	"
      done
    fi
  done

  if [[ "$status" != "0" ]]; then
    if [[ -n "$errlist" ]]; then
      print "\nThe following packages were not successfully removed:"
      print "${errlist}\n"
    fi
    if [[ -n "$errdep" ]]; then
      print "\nThe following packages were not removed due to dependencies:"
      echo "${errdep}" | tr '	' '\n'
      print -n "\nPlease manually remove packages listed in the first "
      print "column above.\n"
    fi
  fi

  return $status
}


DoInstall() {
  typeset sunmc_version=""
  typeset NEED_START=false
  typeset NEED_AGENT=true
  typeset vflag=""

  if [[ G_DEBUG = "yes" ]]; then
     vflag = "-v"
  fi


  # make sure SUNMC is installed on this machine
  #
  if ( ! ProductInstalled SUNWescom ) ; then
    print "\nNOTE:\tSun Management Center not installed."
    print "\tTo implement monitoring install Sun Management Center"
    print "\tthen run ${UT_BASEDIR}/SUNWut/sbin/${PROGRAM_ID}\n"
    TouchErrFile
    return
  fi

  # make sure SUNMC is at least 2.1.1
  #
  sunmc_version="$(pkgparam SUNWescom VERSION 2>&-)"
  if [[ "$sunmc_version" < "2.1" ]]; then
    print "\nNOTE:\tSun Management Center version ${sunmc_version} installed."
    print "\tMinimum version required is 2.1.1"
    TouchErrFile
    return
  fi

  # make sure SUNMC directories exist
  #
  if ( ProductInstalled SUNWessrv ) ; then
    if [[ ! -d $sunmc_instdir/classes/com/sun/symon/base/modules ]]; then
      Note "Required Sun Management Center server directory missing: " \
	"$sunmc_instdir/classes/com/sun/symon/base/modules"
      TouchErrFile
      return
    fi
  else
    print "\nNOTE:\tSun Management Center server not installed."
    print "\t${PROGRAM_ID} is only used to install properties and"
    print "\tMetaData on SunMC servers."
    TouchErrFile
    return
  fi

  if ( AnyPackageInstalled $UT_SRSS_PKG_LIST ); then
      # If any SRSS packages other than SunMC modules are present
      # utinstall should be used instead of utsunmcinstall
      print "\nSun Ray server server software present\n"
      print "Please use utinstall, not ${PROGRAM_ID}"
      TouchErrFile
      return
  fi

  if ( AnyPackageInstalled $UT_OLD_PKG_LIST ); then
    if [[ "${G_SR_CURRENT_VERSION}" = "1.3" ]] ; then
      # If current installed version is 1.3 the package is SUNWutesa
      print "\nRemoving Sun Ray server ${G_SR_CURRENT_VERSION} module for SunMC\n"
      RemoveProduct $G_ADMIN_FILE $UT_OLD_PKG_LIST
    fi
  fi

  #
  # determine which L10N packages are present
  #
  GetAvailablePackages

  print \
    "Installing $G_UT_PROD_NAME $G_UT_VERSION module for SunMC, server components\n"
  pkgadd $vflag -a $G_ADMIN_FILE -d ${UT_DIR}/Packages $UT_PKG_LIST

  #
  # if the add didn't succeed, we exit
  # going...
  #
  if [[ $? != 0 ]]; then
    TouchErrFile
    return
  fi

  if [[ -n $_SW_PKG_LIST ]]; then
    print \
      "Installing $G_UT_PROD_NAME $G_UT_VERSION Localized files\n"
    pkgadd $vflag -a $G_ADMIN_FILE -d ${UT_DIR}/Packages $_SW_PKG_LIST

    #
    # if the pkgadd didn't succeed...
    #
    if [[ $? != 0 ]]; then
      TouchErrFile
    fi

  else
    print "\n$G_UT_PROD_NAME Localized packages not available\n"
  fi

  return
}

DoUninstall() {

  if ( AnyPackageInstalled $UT_SRSS_PKG_LIST ); then
      # If any SRSS packages other than SunMC modules are present
      # utinstall should be used instead of utsunmcinstall
      print "\nSun Ray server server software present\n"
      print "Please use utinstall -u to remove software, not ${PROGRAM_ID}"
      return 1
  fi

  if ( AnyPackageInstalled $UT_OLD_PKG_LIST ); then
    if [[ "${G_SR_CURRENT_VERSION}" = "1.3" ]] ; then
      # If current installed version is 1.3 the package is SUNWutesa
      print "\nRemoving Sun Ray server ${G_SR_CURRENT_VERSION} module for SunMC\n"
      RemoveProduct $G_ADMIN_FILE $UT_OLD_PKG_LIST
      return 0
    fi
  fi

  if ( ! AnyPackageInstalled $UT_PKG_LIST $UT_L10N_LIST ); then
    print "\nSun Ray server module for SunMC not installed\n"
    return 0
  fi

  print "\nRemoving Sun Ray server module for SunMC\n"

  if ( AnyPackageInstalled $UT_L10N_LIST ); then

    RemoveMsg "$G_UT_PROD_NAME Localized files" "$G_SR_CURRENT_VERSION"

    RemoveProduct $G_ADMIN_FILE $UT_L10N_LIST

    #
    # if the removal didn't succeed...
    #
    if [[ $? != 0 ]]; then
      TouchErrFile
    fi

  fi

  if ( AnyPackageInstalled $UT_PKG_LIST ); then

    RemoveMsg "$G_UT_PROD_NAME" "$G_SR_CURRENT_VERSION module for SunMC"

    RemoveProduct $G_ADMIN_FILE $UT_PKG_LIST

    #
    # if the removal didn't succeed...
    #
    if [[ $? != 0 ]]; then
      TouchErrFile
    fi

  fi

  return
}

# main 

typeset -r UT_BASE="$(pkginfo -r SUNWutesc 2>&-)"
typeset -r UT_BASEDIR="${UT_BASE:-/opt}"

# get the full pathname of the command
typeset command=$(whence $0)

# location of the support_lib and modules directories
export G_MEDIA_DIR=${command%/*}/../lib

# location of the bundles (SWS,SDS,LDAP,...) 
# (cdrom root directory)
export G_PRODUCT_DIR=${command%/*}/..

# Perform sanity checks on directories
CheckMediaDir

#
# include shared library
. "${G_MEDIA_DIR}/support_lib/utsunmc_lib"

trap "CleanupAndExit 1" HUP INT QUIT TERM

# Perform more sanity checks on directories
CheckUidIsZero

CheckTmpDir

export G_ADMIN_FILE="${G_MEDIA_DIR}/admin_default"

export G_MODE="install"
export G_DEBUG="no"
export G_QUICK_INSTALL="no"

export G_UT_PROD_NAME="Sun Ray server"
export G_UT_VERSION="2.0"
export G_PID="$$"

# Current installed Sun Ray version.  It will be empty if not installed.
export G_SR_CURRENT_VERSION=$(pkgparam SUNWutesc VERSION 2>&- | cut -d_ -f1)
if [[ "${G_SR_CURRENT_VERSION}" = "" ]] ; then
  # If current installed version is 1.3 the package is SUNWutesa
  export G_SR_CURRENT_VERSION=$(pkgparam SUNWutesa VERSION 2>&- | cut -d_ -f1)
fi

# Sun Ray Server Software directory
export G_SUNRAY_SERVER_DIR="Sun_Ray_Server_Software_2.0"

typeset -r TMP_ADMIN_FILE="${G_TMP_DIR}/${PROGRAM_ID}.${G_PID}.admin_default"
typeset -r ERROR_FILE="${G_TMP_DIR}/.${PROGRAM_ID}.${G_PID}.errcode"
# typeset UT_DIR="/opt/SUNWut"
typeset G_MODE="install"
typeset FORCE=false
typeset -r UT_DIR="${G_PRODUCT_DIR}/${G_SUNRAY_SERVER_DIR}/Solaris_8+"

G_ADMIN_FILE=${G_PRODUCT_DIR}/admin_default
if [[ ! -f ${G_ADMIN_FILE} ]]; then
   G_ADMIN_FILE="${UT_DIR}/etc/admin_default"
fi

typeset -r OPTSTR=":uvf"
typeset -r PROGRAM_OPTS="[-u]"

#
# parse the command line
#
while getopts $OPTSTR OPT; do
  case "$OPT" in
    f) FORCE=true;;
    u) G_MODE="uninstall";;
    v) G_DEBUG="yes";;
   \?) InstallUsage;;
    :) print "\nArgument missing" ; InstallUsage;; # to handle missing argument
  esac
done
shift $(($OPTIND - 1))

if (( $# != 0 )); then
  InstallUsage
fi

export _MODULE_NAME=$(basename $0)
export _VARS_LIST=""
export _EXIT_CODE=0
export _RETURN_VAL=0
export _VAR_STORAGE_FILE="${G_TMP_DIR}/.${PROGRAM_ID}.${_MODULE_NAME#???}"

typeset _DO_INSTALL="no"
typeset _DO_REMOVE="no"
typeset _SW_INSTALLED="no"
typeset _SW_COMPATIBLE="yes"
typeset _SW_PKG_LIST=""

#
# UT_L10N_LIST lists the possible locale packages that could be present
##	pl locale not supported at this time
#
export UT_L10N_LIST="SUNWcutes SUNWdutes SUNWeutes \
	SUNWfutes SUNWhutes SUNWiutes SUNWjutes SUNWkutes"

export UT_PKG_LIST="SUNWutesc"

export UT_OLD_PKG_LIST="SUNWutesa"

export UT_SRSS_PKG_LIST="SUNWuto SUNWutr SUNWuta SUNWutk SUNWutkx \
	SUNWutu SUNWutux"


typeset OSMINOR=""

# This version of SRSS is supported on 5.8 and 5.9.  However,
# the SunMC server may be a different release, as early as 5.6 and
# part of the SunRay module must be installed on the SunMC server.
# Therefor it is necessary to allow 5.6 through 5.9. Proceed without
# comment if this OS is that range.  If the OS is 5.N where N is
# greater than 9 then this is probably someone trying an experiment,
# so just emit a warning and allow the install to proceed.  If the
# OS is earlier than 5.6 or if the major release number is something
# other than 5 then report an error and terminate the install.
#
MINSUPP=6		# lowest supported minor release
MAXSUPP=9		# highest supported minor release

ValidOS

#
# SunMC uses OS release specific library directories.
# Instead of 5.x, it uses 2.x and it only uses major and minor.
#
typeset OS_LIB_DIR="sparc-sun-solaris2.${OSMINOR}"

# Perform sanity checks on directories
CheckWorkingDir

CheckAdminFile

print "# Script: ${PROGRAM_ID}\tVersion: 2.0_37.b,REV=2002.12.19.07.46\n" >> $LOGFILE

# return code from DoInstall() and DoUninstall() will not be visible
# due to outputs piped (| tee') for logging purpose
case "$G_MODE" in
  install)   DoInstall   2>&1 | tee -a $LOGFILE;;
  uninstall) DoUninstall 2>&1 | tee -a $LOGFILE;;
esac

# pass error conditions from DoInstall() and DoUninstall()
# by using $ERRFILE file
if [[ -f $ERRFILE ]]; then
   echo "Please check the log file, $LOGFILE, for errors.\n"
   CleanupAndExit 1
fi
CleanupAndExit 0
