#!/bin/bash
#
#   StorViewInstall :: installs StorView on *nix  
#
#   See usage() for command line arguments.
#
#   Operation:  
#              Locate the rpm file.
#              Detects the OS version.
#              Determines if the version is Ok.
#              Selects a StorView rpm file.
#              Uninstall any previous StorView.
#              Installs StorView.
#              Checks the install and reports.
#
#

NAME=StorView
EXTENT=sv
OPT=/opt/${NAME}
RELDIR="/etc/"
RELPOSTFIX="release"
DASHES="-----------------------------------------------------------------------------"
iNAME=storview
RPMFILE=""
OVERRIDE=0
RPM_NODEPS=--nodeps

OS_PREFIX="" 
OS_BASE=""
OS_REL=""
OS_CODE=""
OS=""
OS_BITS=""
OS_LONG=""
     
nrpm=0
nbos=""
nbplat=""
nbbits=""
nname=""

err=0
hit=0  

# known Release File Prefixes, I.E.: SuSE-release
#  if we find one of these we use it, otherwise we try lsb_release
knownReleaseFilePrefixes=(SuSE redhat)

# temp files
T1=/tmp/tmpfile_1_$$
T2=/tmp/tmpfile_2_$$
T3=/tmp/tmpfile_3_$$
TD=/tmp/tmpfile_D_$$


#######################################################

echo
echo "    ${NAME} installation script for Linux"
echo

#######################################################

# add . to path      
PATH=.:$PATH

# get into the package directory     
packdir=$(dirname $0)
if [ ! -z $packdir ]; then
   cd $packdir
fi

if [ ! -d /tmp ]; then
    echo "ERROR: No /tmp directory." 
    exit
fi
 
#######################################################

usage()
{   
    #              1         2         3         4         5         6         7         8
    #     12345678901234567890123456789012345678901234567890123456789012345678901234567890
    echo "  usage:"
    echo "    ./${NAME}Install [-h] [-override] [package]" 
    echo "      -h         - Help. You're looking at it."
    echo "      -override  - Override machine word size checking. Use this when "
    echo "                   installing a 32 bit package on a 64 bit machine that "
    echo "                   has 32 bit compatibility."
    echo "      package    - Optional name of a package file to install. Use this when"
    echo "                   installing a package not named in the standard way."
    echo "      When package is omitted the package is selected from the available"
    echo "      package files (*.${EXTENT}) in the directory where ${NAME}Install"
    echo "      is located. If none of those packages is an exact match with the"
    echo "      current machine a menu of packages is presented for the user to choose"
    echo "      from (assuming more than package is available)."
    echo ""
} 

 
#######################################################

tmpbegone()
{
    rm -f /tmp/tmpfile_*_$$
} 

########################################################################

platformSetup()
{

    # get the platform - something like i386 or x86_64 - use what rpm knows  
    PLATFORM=`rpm --showrc | grep "^build arch" | sed 's,^.*: ,,'`

    hit=0
    for r in ${knownReleaseFilePrefixes[@]}
    do         
        R=${RELDIR}$r-${RELPOSTFIX}  
        if [ -r $R ] ; then
            hit=1
            parseReleaseDescription $R
            break
        fi
    done   
    if [ $hit -eq 0 ] ; then
        # try the lsb_release command
        rel=`which lsb_release`
        if [ -x $rel ] ; then
            $rel -d | grep Description: | sed -e 's,Description:[[:space:]]*,,' > $TD
            parseReleaseDescription $TD
            rm -f $TD
        fi         
    fi 

    # now we have OS set - lets check the bits

    y=`echo $PLATFORM | grep -c 64`   # known 64 bit platform has x86_64 for its machine
    if [ $y -eq 1 ] ; then
        OS_BITS=64
    else
        OS_BITS=32
    fi
    echo "Installing on platform: ${OS_LONG} ${OS_BITS} bits"
}


########################################################################

parseReleaseDescription()
{
    rfile=$1 
    head -1 $rfile > $T1 

    if [ `grep -c "Red Hat Enterprise Linux" $T1` -eq 1 ] ; then
        OS_BASE="rhel"    
        OS_REL=`sed -e 's,Red Hat Enterprise Linux,,' \
                    -e 's,ES,,' \
                    -e 's,AS,,' \
                    -e 's,release,,' \
                    -e 's,(.*),,' \
                    -e 's, *,,g' $T1`
        OS_CODE=`sed -e 's,.*(\(.*\)).*,\1,' $T1`
        OS=${OS_BASE}${OS_REL}
        OS_LONG="${OS} (${OS_CODE})"   

    elif [ `grep -c "SuSE SLES-8" $T1` -eq 1 ] ; then
        OS_BASE="sles"    
        OS_REL="8"
        OS_CODE=""
        OS=${OS_BASE}${OS_REL}
        OS_LONG="${OS} (${OS_CODE})"   
                                              # SUSE LINUX Enterprise Server 9 (i586)
    elif [ `grep -c "SUSE LINUX Enterprise Server" $T1` -eq 1 ] ; then
        OS_BASE="sles"    
        OS_REL=`sed -e 's,SUSE LINUX Enterprise Server,,' \
                    -e 's,(.*),,' \
                    -e 's, *,,g' $T1`
        OS_CODE=""
        OS=${OS_BASE}${OS_REL}
        OS_LONG="${OS} (${OS_CODE})"   

    else
        echo ${DASHES}
        echo "WARNING: Unknown OS." 
        echo ${DASHES}

        OS_BASE="unidentified"    
        OS_REL=""
        OS_CODE=""
        OS=${OS_BASE}${OS_REL}
        OS_LONG="${OS} (${OS_CODE})"   

        #tmpbegone
        #exit 1
    fi

    rm -f $T1
}   


#######################################################
#
#  RPM selection
#

rpmselect()
{

    hit=0 
    n=0      
    cp="${OS}-${OS_BITS}"
    #echo cp=$cp

    # scan all the rpm files

    for f in *.${EXTENT} ; do   
    #echo $f   

        # gather up the special strings put in at build time

        RPMFILE=$f
        rpm -qi -p ${RPMFILE} > $T1
        if [ $? -eq 0 ] ; then 
            bos=`     cat $T1 | grep JBIBuildOS       | sed 's,JBIBuildOS: ,,'`
            bplatfrm=`cat $T1 | grep JBIBuildPlatform | sed 's,JBIBuildPlatform: ,,'`
            b__bits=` cat $T1 | grep JBIBuildBits     | sed 's,JBIBuildBits: ,,'`      
            bsupps=`  cat $T1 | grep JBIBuildSupports | sed 's,JBIBuildSupports: ,,'` 

            #echo $f = $bos $bplatfrm $b__bits $bsupps
        fi
        rm -f $T1 

        nbos[$n]=$bos
        nbplat[$n]=$bplatfrm
        nbbits[$n]=$b__bits
        nname[$n]=$f

        if [ $b__bits -eq $OS_BITS ] ; then  

            # if we're on the build platform
            #echo PLATFORM=$PLATFORM   cp=$cp
            if [ $bplatfrm = $PLATFORM ] ; then
                if [ $bos = $OS ] ; then
                    nrpm=$n ;
                    hit=1 ;
                fi
            fi
            
            # if we're on a known supported platform

            fnd=`echo ${bsupps} | grep -c ${cp} `
            if [ $fnd -eq 1 ] ;  then
                nrpm=$n ;
                hit=1 ;
            fi


        fi
        let n=$((n+1))
        if [ $hit -eq 1 ] ; then
            break ;
        fi
    done  
    
    # if no exact match found

    if [ $hit -ne 1 ] ; then

        # if multiple rpm files

        if [ $n -gt 1 ] ; then
            rpmuserguess
        fi
    fi

    if [ ${nbbits[$nrpm]} -ne $OS_BITS ] ; then 
        if [ $OVERRIDE -eq 0 ] ; then
            echo ${DASHES}
            echo "ERROR: Word size mismatch. Package file is ${nbbits[$nrpm]} bits, machine is $OS_BITS bits."
            echo ${DASHES}
            tmpbegone
            exit 1                       
        else
            echo ${DASHES}
            echo "WARNING: Word size mismatch. Override in effect, installing ${nbbits[$nrpm]} on $OS_BITS bits."
            echo ${DASHES}
        fi
    fi 

    echo "Installing package: ${nbbits[$nrpm]}bits ${nbplat[$nrpm]} ${nbos[$nrpm]} ${RPMFILE}."   
}


######################################################
#
#  RPM selection when not a perfect match
#          uses the 'n' arrays

rpmuserguess()
{
     
    echo ${DASHES}
    echo "NOTE: Exact machine - package match not found."      
    echo ${DASHES}
    echo
    echo "Choose a package from the following list that is a close"
    echo "match to the machine."
    echo
    echo "Machine attributes are: ${OS_LONG} ${OS_BITS} bits."
    echo
    echo "    #    bits  platform  os        filename"
    n=0
    for (( n=0 ; n < ${#nbos[*]} ; n++ )) ; do  

        xbos=`  echo "${nbos[$n]}    "   | sed 's,\(........\).*,\1,'`
        xbplat=`echo "${nbplat[$n]}    " | sed 's,\(........\).*,\1,'`
        xbbits=`echo "${nbbits[$n]}  "   | sed 's,\(....\).*,\1,'`

        echo "    $n)   ${xbbits}  ${xbplat}  ${xbos}  ${nname[$n]}"
    done
    echo "    q)   Quit" 
    read -p "    Enter selection > "
    echo ${DASHES}
    case ${REPLY} in
        q | Q )
            tmpbegone
            exit 1
            ;;
        [0-9]* )
            n=${REPLY}
            if [ $n -ge ${#nbos[*]} ] ; then
                echo ${DASHES}
                echo "ERROR: Input out of range."
                echo ${DASHES}
                tmpbegone
                exit 1
            fi 
            nrpm=$n ;
            RPMFILE=${nname[$n]}
            ;; 
        * )
            echo ${DASHES}
            echo "ERROR: Input not understood."
            echo ${DASHES}
            exit 1
    esac
}

#######################################################
#
#  RPM check
#       arg1 = rpm file
#

rpmcheck()
{           
    RPMFILE=$1
    if [ ! -e ${RPMFILE} ] ; then
        echo "Package file, ${RPMFILE}, does not exist."
        exit 1
    else
        rpm -qi -p ${RPMFILE} > $T1
        if [ $? -eq 1 ] ; then
            echo ${DASHES}
            echo "ERROR: Supplied file, $RPMFILE, is not a package file."
            echo ${DASHES}
            tmpbegone
            exit 1
        else
            bos=`     cat $T1 | grep JBIBuildOS       | sed 's,JBIBuildOS: ,,'`
            bplatfrm=`cat $T1 | grep JBIBuildPlatform | sed 's,JBIBuildPlatform: ,,'`
            b__bits=` cat $T1 | grep JBIBuildBits     | sed 's,JBIBuildBits: ,,'`
#echo BUILD = $bos $bplatfrm $b__bits
        fi
        rm -f $T1

        if [ $b__bits -ne $OS_BITS ] ; then 
            if [ $OVERRIDE -eq 0 ] ; then
                echo ${DASHES}
                echo "ERROR: Word size mismatch. Package file is $b__bits bits, OS is $OS_BITS bits."
                echo ${DASHES}
                tmpbegone
                exit 1                       
            else
                echo ${DASHES}
                echo "WARNING: Word size mismatch. Override in effect, installing $b__bits on $OS_BITS bits."
                echo ${DASHES}
            fi
        fi 

        echo "Package file selection confirmation:" 
        echo "          Bits     Platform   OS             "
        echo "Machine   $OS_BITS       $PLATFORM       $OS  "
        echo "Package   $b__bits       $bplatfrm       $bos "
        echo "                                     "
        read -p "Confirm this information.  [y/n] ? "
        echo ${DASHES}
        #echo reply=${REPLY}
        case ${REPLY} in
            n | N )   tmpbegone ; exit 1    ;;
            y | Y )   n=1       ;; 
            *     )   tmpbegone ; exit 1    ;;          
        esac

        echo "Installing package ${RPMFILE}."
    fi

}



#######################################################
#
#    checks for existing SV installation
#
checkexisting()
{
   # checking for existing installation
   OLDSV=`rpm -qa | grep ${NAME}`
   if [ x"$OLDSV" != x ] ; then
       echo ${DASHES}
       echo "Warning: There is an existing ${NAME} installation."
       echo "    Any existing ${NAME} installation must be removed before" 
       echo "    installing or reinstalling a ${NAME} release."
       echo ${DASHES}
       echo 
       echo "    The existing installation is:"
       echo "      $OLDSV "
       echo 
       read -p "Do you want to remove $OLDSV  [y/n] ? " input other
       case $input in
           y* | Y*)
               echo "Removing $OLDSV "
               rpm -e --allmatches --nodeps ${NAME}  > $T3
               echo "Old installation removed. Continuing."
               ;;
           * )
               echo
               echo "    Cannot continue."
               echo "    Use one of the following to uninstall ${NAME}:"  
               echo "      ${OPT}/Uninstall${NAME} "
               echo "        or       "
               echo "      rpm -e --allmatches --nodeps ${NAME} "
               echo
               tmpbegone
               exit   
               ;;
       esac
   fi
} 


#######################################################

confirminstall()
{
                                                                   

   echo $DASHES
   read -p "Paused, <Enter> to continue. > " input other 
   echo $DASHES
} 
   

#######################################################

installing()
{
   echo
   echo $DASHES
   echo "Installing ${NAME}"
   echo $DASHES
   
   
   # installing 
   rpm -U --force $RPM_NODEPS $RPMFILE  
   if [ $? != 0 ] ; then
       echo $DASHES
       echo "ERROR: Install failed. Exiting." 
       echo $DASHES
       tmpbegone
       exit 1
   fi     
   sleep 3
}


#######################################################
    
postcheck()
{       
    echo
    echo $DASHES
    echo "Checking install"
    echo
   
    # checking installation
    if [ ! -d $OPT ] ; then
        echo $DASHES
        echo "ERROR: ${NAME} did not install into $OPT. Exiting."
        echo "       ${NAME} must be installed into $OPT for all the components to"
        echo "       work together properly."
        echo "       Please investigate the problem and reinstall."
        echo $DASHES
        tmpbegone
        exit 1
    fi
    err=0
    if [ ! -x $OPT/${NAME}Server ] ; then
        echo $DASHES
        echo "ERROR: ${NAME}Server did not install properly."
        echo $DASHES
        err=1
    fi
    if [ ! -x $OPT/html/cgi-bin/cgiloader.cgi ] ; then
        echo $DASHES
        echo "ERROR: cgiloader.cgi did not install properly."
        echo $DASHES
        err=1
    fi
    if [ ! -x $OPT/webs/bin/httpd ] ; then
        echo $DASHES
        echo "ERROR: Apache did not install properly."
        echo $DASHES
        err=1
    fi  
    if [ $err -ne 0 ] ; then
        tmpbegone
        exit 1
    fi 
    
    (  
        declare -x LD_LIBRARY_PATH=/opt/${NAME}:/opt/${NAME}/webs/lib
        hit=0  
        cd $OPT
        for f in ${NAME}Server mods/*/*.so webs/bin/* ; do    
            # could also look for ELF
            x=`file $f | grep -c text`
            if [ \( -x $f \) -a \( ! -d $f \) -a \( $x -eq 0 \) ] ; then  
                # examine libraries used by each executable
                ldd $f | grep 'not found' > $T1 
                z=`wc -l < $T1` 
                if [ $z -gt 0 ] ; then
                    # got some 'not found's
                    echo $DASHES
                    echo "ERROR: file $f, missing OS support libraries."
                    cat $T1 
                    echo $DASHES  
                    hit=1
                fi
            fi 
        done
        if [ $hit -ne 0 ] ; then
            echo ""
            echo "    These missing libraries may indicate an incompatibility between the build"
            echo "    environment and the runtime environment. The runtime environment may"
            echo "    not be supported for this release. This installation may not run or "
            echo "    may not run reliably."
            echo ""
            echo "    You may attempt to run ${NAME} by using the following commands:"
            echo "        cd $OPT"
            echo "        Start${NAME}"
            echo ""
            echo "    If ${NAME} does not run successfully contact Technical Support for"
            echo "    assistance. To assist Technical Support please run the gatherinfo "
            echo "    script in the $OPT directory and catch the output in a file. E.g:"
            echo "        cd $OPT"
            echo "        gatherinfo > output.txt"
            echo "    Send the output file to Technical Support."
            echo ""
            echo "    Technical Support may direct you to remove this installation. The"
            echo "    following commands do that:"
            echo "        cd $OPT"
            echo "        Uninstall${NAME}"
            echo ""
            exit 1
        fi 
    )
    if [ $? -ne 0 ] ; then
        tmpbegone
        exit 1
    fi 
}       


#######################################################

startstorview()
{   
   
   echo "Starting ${NAME}"  
   $OPT/Start${NAME}
   sleep 10
}


#######################################################    

checkstart()
{
   
   k=`ps ax | grep StorViewServer | grep -v grep | wc -l`
   err=0
   if [ $k -lt 1 ] ; then
       echo "Error: ${NAME}Server did not start."
       err=1
   fi 
   k=`pgrep httpd | wc -l`
   if [ $k -lt 1 ] ; then
       echo "Error: httpd did not start."
       err=1
   fi
   if [ $err -ne 0 ] ; then
       echo "Installation Complete - with errors."
       tmpbegone
       exit 1
   fi 
   
   echo "Installation Complete - no errors detected."
}  


#######################################################   
# main
#######################################################

if [ x$1 = "x-h" ] ; then
    usage
    exit
fi
if [ x$1 = "x-override" ] ; then
    OVERRIDE=1
    shift
fi

platformSetup

if [ $# -eq 0 ] ; then
    #no arg
   
    rpmselect

else
    # arg

    rpmcheck $1       
fi


checkexisting
confirminstall
installing        
postcheck
startstorview
checkstart
   
tmpbegone
exit

