#!/bin/bash
#install_server - controls the installation of the TSM Server on Linux
# 5765-303 (C) Copyright IBM Corporation 1990, 2003                    
#
# Creation: Fraser McCartney, IBM - 12/10/2003
#
# Change history:
#
# 2 Dec 2004 ipouerie IC42812
# use the prefix given at cmd line during an upgrade
#
# 9 Aug 2004 fraserm 15300
# changed running server check (dsmserv) to remove false positives
#
# 5 May 2004 fraserm 14583
# forced unconditional exit if user is not root
#
#

BASIC_INST_PACKAGES="TIVsm-server TIVsm-license TIVsm-webadmin TIVsm-webhelp.en_US"

###############
#function section
###############

function ask()
{
  ASK_TEXT="$1"; ASK_CHOICES="$2"

   while echo "$ASK_TEXT"
   do
    read ASK_ANS
    echo "$ASK_ANS" | awk -v chs=$ASK_CHOICES '{ if(length($0)>1) exit 0; \
        ua="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; la="abcdefghijklmnopqrstuvwxyz"; \
        i=index(la,$1); if(i) $1=substr(ua,i,1); \
        i=index(chs,$1); exit i;}'; ret=$?
 
    if test $ret -ne 0; then return $ret; fi
  done
}


function kill_dir_apps()
{
  CMDDIR="$1"

  #return now if bug allows call without command name (dangerous)
  if test -z "$CMDDIR" ; then return 1; fi

  #get the PID column number, no guessing allowed, error if not found
  PIDCOL=`ps -f | awk '{ if(NR>2) exit 1; for(i=1;i<=NF;i++) \
           if($(i)=="PID"){ print i; exit 0;}}'`
  CMDCOL=`ps -f | awk '{ if(NR>2) exit 1; for(i=1;i<=NF;i++) \
           if($(i)=="CMD" || $(i)=="COMMAND"){ print i; exit 0;}}'`
  if test -z "$PIDCOL" -o -z "$CMDCOL"; then return 2; fi

  KLIST=`ps -ef | \
         awk -v pc="$PIDCOL" -v cc="$CMDCOL" -v cmdd="$CMDDIR" '{ \
           if(substr($(cc),1,length(cmdd))==cmdd) printf "%i\n",$(pc)}'`

  #for each pid in the kill list, issue kill-9s
  for K in $KLIST
  do kill -9 $K 2>/dev/null >/dev/null
  done
  #if any were killed, give kill some time to clean up
  if test -n "$KLIST"; then sleep 3; fi
}


function inst_rpm()
{
  INST_RPM_FILE=$1
  INST_RPM_NAME=`rpm -qp $INST_RPM_FILE --queryformat %{NAME}`
  INST_RPM_VER=`rpm -pq $INST_RPM_FILE`

  #INST_RPM_OLD_VER will be "" if rpm package is not installed
  INST_RPM_OLD_VER=""
  if rpm -q $INST_RPM_NAME >/dev/null 2>/dev/null
  then INST_RPM_OLD_VER=`rpm -q $INST_RPM_NAME`
  fi

  #if the same package is already installed, return
  if test "$INST_RPM_OLD_VER" = "$INST_RPM_VER"
  then echo " "
       echo "$INST_RPM_VER already installed."
       return 0
  fi
  
  #if there is another version installed update it
  if test -n "$INST_RPM_OLD_VER"
  then echo " "
       echo "Updating the currently installed $INST_RPM_OLD_VER."
       if test -n "$ALT_PREFIX"
       then
          rpm -Uvh $INST_RPM_FILE --prefix $ALT_PREFIX; ret=$?
       else
          rpm -Uvh $INST_RPM_FILE; ret=$?
       fi
       if test $ret -ne 0
       then echo " "
            echo "\"rpm -Uvh $INST_RPM_FILE\" was not successful ."
            echo "The rpm issues must be resolved to continue the installation."
            return 1
       fi
  fi

  #if this is a fresh install, ask for alternate dir and install
  if test -z "$INST_RPM_OLD_VER"
  then echo "Installing $INST_RPM_VER."

       if test -n "$ALT_PREFIX"
       then INST_RPM_RUN="rpm -ivh $INST_RPM_FILE --prefix $ALT_PREFIX"
       else INST_RPM_RUN="rpm -ivh $INST_RPM_FILE"
       fi
       $INST_RPM_RUN; ret=$?
       if test $ret -ne 0
       then echo " "
            echo "\"$INST_RPM_RUN\" was not successful."
            echo "The rpm issues must be resolved to continue the installation."
            return 1
       fi
  fi
  return 0
}


###############
#command-line parse section
###############

#get optional parms from the command line
PLATFORM=`echo "$*" | awk '{plat="ppc64 i686 s390 s390x"; \
              for(i=1;i<=NF;i++){ s=" "$(i)" "; if(index(plat,s)){ \
              print $(i); exit 0}}}'`
ALT_PREFIX=`echo "$*" | awk '{for(i=1;i<=NF;i++) \
                           if(substr($(i),1,1)=="/"){ print $(i); exit 0}}'`

#if any options did not match (bad options) print help and exit
if echo "$*" | awk -v a="$PLATFORM" -v b="$ALT_PREFIX" '{ \
   ct=0; if(length(a)) ct=ct+1; if(length(b)) ct=ct+1; \
   if(ct!=NF) exit 0; exit 1}'
then echo " "
     echo "Usage:" 
     echo "install_server [prefix], where prefix is optional and it denotes the file system where product is to be installed. The default install location is /opt."
     exit 1
fi


###############
#pre-check section
###############

#check to see if the user is root and ask to quit if not
if test "$UID" != ""
then if test $UID != "0"
     then echo " "
          echo "Your user ID is \"$UID\" and not \"0\" for root. rpm package"
          echo "installation is limited to the user root."
          exit 0
     fi
fi

#check to see if the server is running and ask to quit if it is
#post installs fail if it is running
if ps -ae | grep "dsmserv"
then echo " "
     echo "It looks like the server is running now."
     echo "No installations should be attempted with the server running."
     ask "Can I stop this installation? (Y/N)" "YN"; ret=$?
     if test $ret -eq 1
     then exit 0
     fi
fi


###############
#environment section
###############

#aquire a usable install path without trailing "/" (relative ok)
INST_PATH=`echo "$0" | awk '{ s=$0; \
	if(substr(s,1,1) != "/" && substr(s,1,2) != "./") s="./"s; \
	while(substr(s,length(s)) != "/") s=substr(s,1,length(s)-1); \
	print substr(s,1,length(s)-1);}'`

#echo "INST_PATH=$INST_PATH"


#determine the platform to install (could be from command line)
if test -z "$PLATFORM"
then PLATFORM=`uname -m 2>/dev/null`
fi

PLATFORM=`echo "$PLATFORM" | awk '{ if($1=="ppc64") print "ppc64"; \
                            if($1=="s390") print "s390"; \
                            if($1=="s390x") print "s390x"; \
                            if(index($1,"86")) print "i686";}'`

#echo "PLATFORM=$PLATFORM"

if test -z "$PLATFORM"
then echo " "
     echo "Not a recognized platform. $PLATFORM"
     echo "Use install_server [platform] [prefix], where platform is ppc64, s390, s390x, or i686. Prefix is optional and it denotes the file system where product is to be installed."
     exit 1
fi

###############
#lap tool section
###############

#call the LAP tool to force agreement to license
licensedir=$INST_PATH/license
lapapp=/tmp/license/LAPApp.jar
jre=/tmp/license/jre


# if the LAP tool is not available, do not try to run it
if test -d $licensedir
then echo "Preparing License Agreement"

     #kill any rogue java exes from prior aborted installation attempts
     kill_dir_apps $jre

     #linux is special. It has more than one JRE on the CD.
     #only copy the license files and not the JRE yet
     rm -rf /tmp/license 2>/dev/null
     mkdir /tmp/license 2>/dev/null
     cp $licensedir/* /tmp/license 2>/dev/null >/dev/null

     #get the directory of the jre, note some of our platform names don't match
     JRE_PLATFORM="$PLATFORM"
     if test $PLATFORM = "ppc64"; then JRE_PLATFORM="ppc32"; fi
     if test $PLATFORM = "s390x"; then JRE_PLATFORM="s390"; fi
     if test $PLATFORM = "i686"; then JRE_PLATFORM="i386"; fi

     #copy the proper jre in and check for copy failure
     cp -r $licensedir/$JRE_PLATFORM/jre /tmp/license

     ret=$?
     if test $ret -ne 0
     then echo "Error copying $licensedir to /tmp."
          echo "Check that /tmp has more than 120MBs free and allows full access."
          exit 1
     fi

     $jre/bin/java -classpath $lapapp:$jre/lib/rt.jar:$jre/lib/i18n.jar com.ibm.lex.lapapp.LAP -l /tmp/license -s /tmp/license -text_only 

     ret=$?
     if test $ret -eq 3 -o $ret -eq 130
     then echo "License terms not agreed to."
          rm -rf /tmp/license 2>/dev/null; exit 1
     fi
     if test $ret -ge 10
     then echo "Java error code $ret."
          exit 1
     fi
     if test $ret -ne 9
     then echo "JRE error attempting to evoke the license acceptance tool."
          echo "Error code $ret."
          exit 1
     fi
     echo "License Agreement Accepted"
fi
  
###############
#menu / main section
###############

#declare the detected platform and the given alt prefix (dir) just for diag
echo "Ready to install RPM packages for $PLATFORM."
if test -n "$ALT_PREFIX"
then echo "Using alternate directory prefix $ALT_PREFIX."
fi

#compile a list of rpms for installation
RPM_FILE_LIST=`ls $INST_PATH/$PLATFORM/*.rpm $INST_PATH/noarch/*.rpm`
RPM_NAME_LIST=`for name in $RPM_FILE_LIST; do rpm -pq $name 2>/dev/null; done`

if test -z "$RPM_NAME_LIST"
then echo "Unable to query RPM for package names. RPM must be installed and functioning for package installations."
     rm -rf /tmp/license; exit 1
fi

#create the menu of packages for later display
RPM_MENU=`echo $RPM_NAME_LIST | awk '{ \
    for(i=1;i<=NF;i++){ sp=" "; if(i<10) sp=sp" "; if(i<100) sp=sp" "; \
    printf "\t%i%s%s\n",i,sp,$(i);} \
    printf "\tB   BASIC INSTALL\n"; \
    printf "\tQ   QUIT\n"}'`


#the rpm package install menu (loops until q/Q or package install failure)
while echo " "
do  LIST_COUNT=`echo $RPM_NAME_LIST | awk '{for(i=0;i<NF;i=i)i++}END{print i}'`

    #display list of packages
    echo " "
    echo "Please select a package to install or \"Q\" to quit."

    #use "more" to display the menu because it can tell the disp length
    echo "$RPM_MENU" | more

    #ask user for package or q/Q to quit
    read ans
    echo "$ans" | awk -v ct=$LIST_COUNT '{if(NF>1) exit 1; \
        if($1=="q"|| $1=="Q") exit 1; \
        if($1=="b"|| $1=="B") exit 2; \
        if($1<0 || $1>ct) exit 3;}'; ret=$?

    #if package selected, install
    if test $ret -eq 0
    then RPM_FILE=`echo $RPM_FILE_LIST | awk -v num=$ans '{print $(num)}'`

         #attempt to install the package (return of 1 is failure)
         inst_rpm "$RPM_FILE"; ret=$?

         #if the installation failed exit the script
         if test $ret -ne 0
         then exit 1
         fi

         #success, wait a moment before showing the menu again
         sleep 3
    fi


    #check for quit exit if it is given
    if test $ret -eq 1
    then exit 0
    fi


    #if the default set of packages was requested, install them
    if test $ret -eq 2
    then echo "The basic install includes the following packages:"

         #compile a list of the packages' base names for comparison
         BASE_NAME_LIST=`for name in $RPM_FILE_LIST; \
             do rpm -qp $name --queryformat %{NAME}; echo ""; done`

         #get a list of numbers that index basic packages in RPM_FILE/NAME_LIST
         BASIC_NUM_LIST=`for name in $BASIC_INST_PACKAGES; \
            do echo $BASE_NAME_LIST | awk -v n=$name '{ \
            for(i=1;i<=NF;i++) if(n==$(i)){ print i; exit 0}}'; \
            done`

         #get the basic install rpm packages names and display them
         for num in $BASIC_NUM_LIST
         do echo $RPM_NAME_LIST | awk -v n=$num '{ print $(n)}'
         done

         #ask if the user wants to continue and install them
         echo " "
         ask "Should I continue with the basic install? (Y/N)" "YN"; ret=$?

         #if Y then compile a file list and install each
         if test $ret -eq 1
         then  BASIC_INST_FILE_LIST=`for num in $BASIC_NUM_LIST; \
                   do echo $RPM_FILE_LIST | awk -v n=$num '{ print $(n)}'; done`

               #attempt to install each file, exit if error on any
               for name in $BASIC_INST_FILE_LIST
               do inst_rpm "$name"; ret=$?
                  if test $ret -ne 0
                  then exit 1
                  fi
                  #give rpm time to clear
                  sleep 2
               done
         fi
    fi

done

