#
# Copyright (c) 2006 Mellanox Technologies. All rights reserved.
#
# This Software is licensed under one of the following licenses:
#
# 1) under the terms of the "Common Public License 1.0" a copy of which is
#    available from the Open Source Initiative, see
#    http://www.opensource.org/licenses/cpl.php.
#
# 2) under the terms of the "The BSD License" a copy of which is
#    available from the Open Source Initiative, see
#    http://www.opensource.org/licenses/bsd-license.php.
#
# 3) under the terms of the "GNU General Public License (GPL) Version 2" a
#    copy of which is available from the Open Source Initiative, see
#    http://www.opensource.org/licenses/gpl-license.php.
#
# Licensee has the right to choose one of the above licenses.
#
# Redistributions of source code must retain the above copyright
# notice and one of the license notices.
#
# Redistributions in binary form must reproduce both the above copyright
# notice, one of the license notices in the documentation
# and/or other materials provided with the distribution.
#
#  $Id: build_env.sh 9751 2006-10-09 17:10:08Z vlad $
#
# Description: OFED building environment

PACKAGE="OFED"

ARCH=${ARCH:-$(uname -m)}
K_VER=${K_VER:-$(uname -r)}
K_SRC=${K_SRC:-/lib/modules/${K_VER}/build}
KERNEL_TREE_ROOT=${K_SRC%*/*}

RPMK_VER=$(echo -n ${K_VER} | tr -s '-' '_')
IB_PORTS_NUM=2

NULL=/dev/null
curr_dir=$PWD

RM=/bin/rm
CP=/bin/cp
MV=/bin/mv
MKDIR=/bin/mkdir
RPM=/bin/rpm
IFCONFIG=/sbin/ifconfig
CHMOD=/bin/chmod
LSMOD=/sbin/lsmod
WHICH=/usr/bin/which
FIND=/usr/bin/find
DF=/bin/df
REBOOT="/sbin/shutdown -r 0"
SUPPORTED=0
NEED_REBOOT=0
EXECUTING=0
RUNNING_CLEANUP=0
INCLUDE_IFCFG=${INCLUDE_IFCFG:-1}

BASIC=1
HPC=2
ALL=3
CUSTOM=4

prog=`basename $0`

# Disk space required for building ${PACKAGE} RPMs (300 MB)
BUILD_SPACE_REQ=307200

# Disk space required for installing ${PACKAGE} RPMs (200 MB)
RUN_SPACE_REQ=204800

# Default vendor is "ts" (second - mtl)
VENDOR="ts"
build_arch=$(rpm --eval '%{_target_cpu}')

RPM_DIR_DFT="/var/tmp/${PACKAGE}RPM"
RPM_DIR=${RPM_DIR:-"${RPM_DIR_DFT}"}
if [ -d $RPM_DIR ]; then
    find $RPM_DIR -type d | sort -r | xargs rmdir > $NULL 2>&1
fi
mkdir -p $RPM_DIR/{BUILD,RPMS,SOURCES,SPECS,SRPMS}

# # Set RPM build tree  
# RPM_DIR=$(rpm --eval '%{_topdir}')
# if [ -z ${RPM_DIR} ]; then
#         echo Build rpm on this system is not supported...
#         exit 1
# fi

# Default Fortran compiler for MPI installation
MPI_SUPPORTED_COMPILERS="gcc pgi intel pathscale"

# Version definition:

OPENIB_NAME="openib"
OPENIB_VER=1.1

# OpenIB sub-packages
BASIC_IB_KERNEL_PACKAGES="ib_verbs ib_mthca ib_ipoib"
KERNEL_TECHNOLOGY_PREVIEW=""

case ${ARCH} in
    x86_64)
    # ipath driver is supported only on x86_64 for OFED 1.1
    case ${K_VER} in
        2.6.5-7.*)
        # ipath driver is not supported under SLES9 SP3 for OFED 1.1
        ;;
        *)
        BASIC_IB_KERNEL_PACKAGES="${BASIC_IB_KERNEL_PACKAGES} ib_ipath"
        ;;
    esac
    ;;
esac

case ${ARCH} in
    ppc|ppc64)
        case ${K_VER} in
            2.6.1[6-9]*)
            KERNEL_TECHNOLOGY_PREVIEW="${KERNEL_TECHNOLOGY_PREVIEW} ib_ehca"
            ;;
            *)
            ;;
        esac
    ;;
esac
 
IB_KERNEL_PACKAGES="$BASIC_IB_KERNEL_PACKAGES $KERNEL_TECHNOLOGY_PREVIEW ib_sdp ib_srp" #ib_rds 

case ${K_VER} in
    2.6.16.21-0.8-smp)
    # Currently ISER is supported only on SLES10
    IB_KERNEL_PACKAGES="$IB_KERNEL_PACKAGES ib_iser"
    ;;
    2.6.5-7.244*)
    # Currently ib_verbs, ib_mthca, ib_ipoib and ib_srp are supported on SLES9 SP3
    BASIC_IB_KERNEL_PACKAGES="ib_verbs ib_mthca ib_ipoib"
    IB_KERNEL_PACKAGES="$BASIC_IB_KERNEL_PACKAGES ib_sdp ib_srp"
    ;;
    *)
    ;;
esac

IB_KERNEL_UTILS="oiscsi"

IB_BASIC_PACKAGES="kernel-ib kernel-ib-devel libibverbs libibverbs-devel libibverbs-utils"
IB_BASIC_PACKAGES="$IB_BASIC_PACKAGES libibcm libibcm-devel libmthca libmthca-devel perftest mstflint"

# Add libipathverbs package only if IPATH driver can be installed
if (echo -n ${BASIC_IB_KERNEL_PACKAGES} | grep -w "ib_ipath" > $NULL); then
    IB_BASIC_PACKAGES="$IB_BASIC_PACKAGES libipathverbs libipathverbs-devel"
fi

# Add libehca package only if EHCA driver can be installed
if (echo -n ${IB_KERNEL_PACKAGES} | grep -w "ib_ehca" > $NULL); then
    IB_BASIC_PACKAGES="$IB_BASIC_PACKAGES libehca libehca-devel"
fi

# Add oiscsi-iser package only if ISER can be installed
if (echo -n ${IB_KERNEL_PACKAGES} | grep -w "ib_iser" > $NULL); then
    IB_BASIC_PACKAGES="${IB_BASIC_PACKAGES} oiscsi-iser"
fi

MISC_PACKAGES="ofed-docs ofed-scripts"

IB_ALL_PACKAGES="$IB_BASIC_PACKAGES $MISC_PACKAGES"

# Add libsdp package only if SDP module can be installed
if (echo -n ${IB_KERNEL_PACKAGES} | grep -w "ib_sdp" > $NULL); then
    IB_ALL_PACKAGES="${IB_ALL_PACKAGES} libsdp"
fi
IB_ALL_PACKAGES="$IB_ALL_PACKAGES srptools ipoibtools tvflash"
IB_ALL_PACKAGES="$IB_ALL_PACKAGES libibcommon libibcommon-devel libibmad libibmad-devel libibumad libibumad-devel"
IB_ALL_PACKAGES="$IB_ALL_PACKAGES libopensm libopensm-devel opensm"
IB_ALL_PACKAGES="$IB_ALL_PACKAGES libosmcomp libosmcomp-devel libosmvendor libosmvendor-devel"
IB_ALL_PACKAGES="$IB_ALL_PACKAGES openib-diags"
IB_ALL_PACKAGES="$IB_ALL_PACKAGES librdmacm librdmacm-devel librdmacm-utils dapl dapl-devel"

MANAGEMENT_LIBS="libibcommon libibmad libibumad"
OPENSM_PACKAGES="$MANAGEMENT_LIBS libopensm libopensm-devel opensm"
DIAGS_PACKAGES="$MANAGEMENT_LIBS openib-diags ibutils"

###
### Installation Types
###

BASIC_PACKAGES="${IB_BASIC_PACKAGES} ${MISC_PACKAGES}"
HPC_PACKAGES="${BASIC_PACKAGES} ${MANAGEMENT_LIBS} openib-diags mpi_osu openmpi mpitests ibutils"
HPC_PACKAGES="${HPC_PACKAGES} librdmacm librdmacm-devel librdmacm-utils dapl dapl-devel"
# The list of ALL_PACKAGES should preserve the order of dependencies
ALL_PACKAGES="${IB_ALL_PACKAGES} mpi_osu openmpi mpitests ibutils" # pdsh

PREV_RELEASE_PACKAGES="opensm-devel opensm-libs ibtsal openib mpi_ncsa thca ib-osm osm ibadm ib-diags"
PREV_RELEASE_PACKAGES="$PREV_RELEASE_PACKAGES diags ibgdiag ibdiag ib-management"
PREV_RELEASE_PACKAGES="$PREV_RELEASE_PACKAGES ib-verbs ib-ipoib ib-cm ib-sdp"
PREV_RELEASE_PACKAGES="$PREV_RELEASE_PACKAGES ib-dapl udapl udapl-devel"
PREV_RELEASE_PACKAGES="$PREV_RELEASE_PACKAGES libdat libibat ib-kdapl ib-srp ib-srp_target"
PREV_RELEASE_PACKAGES="$PREV_RELEASE_PACKAGES oiscsi-iser-support libipathverbs libipathverbs-devel"
PREV_RELEASE_PACKAGES="$PREV_RELEASE_PACKAGES libehca libehca-devel"

MPI_OSU_NAME="mpi_osu"
MPI_OSU_VER="0.9.7-mlx2.2.0"
MPI_OSU_MPICH_NAME="mpich_mlx"
MPI_OSU_MPICH_VER="0.9.7_mlx2.2.0"
MPI_OSU_MPICH_REL="1"

# Source path definitions
PKG_SOURCE_DIR=${PWD}

OPENIB_SOURCE=${PKG_SOURCE_DIR}/SOURCES/${OPENIB_NAME}-${OPENIB_VER}.tgz
OSU_SOURCE=${PKG_SOURCE_DIR}/SOURCES/${MPI_OSU_NAME}-${MPI_OSU_VER}.tgz

# PDSH_SRC_RPM=${PKG_SOURCE_DIR}/SOURCES/${PDSH_NAME}-${PDSH_VERSION}.src.rpm
SCRIPTS_SOURCE=${PKG_SOURCE_DIR}
DOCS_SOURCE=${PKG_SOURCE_DIR}/docs

PROPEL=${PKG_SOURCE_DIR}/SOURCES/propel.sh

# Set Distribuition dependency environment
dist_rpm=""
if [ -f /etc/SuSE-release ]; then
    dist_rpm=$($RPM -qf /etc/SuSE-release)
    DISTRIBUTION="SuSE"
elif [ -f /etc/fedora-release ]; then
    dist_rpm=$($RPM -qf /etc/fedora-release)
    DISTRIBUTION="fedora"
elif [ -f /etc/rocks-release ]; then
    dist_rpm=$($RPM -qf /etc/rocks-release)
    DISTRIBUTION="Rocks"
elif [ -f /etc/redhat-release ]; then
    dist_rpm=$($RPM -qf /etc/redhat-release)
    DISTRIBUTION="redhat"
else
    dist_rpm="Unknown"
    DISTRIBUTION=$(ls /etc/*-release | head -n 1 | xargs -iXXX basename XXX -release 2> $NULL)
    [ -z "${DISTRIBUTION}" ] && DISTRIBUTION="Unknown"
fi

# Voltaire uses kernel version and not dist_rpm
RPMS=${PKG_SOURCE_DIR}/RPMS/`uname -r`
SRPMS=${PKG_SOURCE_DIR}/SRPMS

if [ ! -d ${RPMS} ]; then
    $MKDIR -p ${RPMS} || exit 1
fi

DOCS_SRC_RPM=$(/bin/ls -1 ${SRPMS}/ofed-docs*.src.rpm 2> $NULL)
if [[ -n "${DOCS_SRC_RPM}" && -s ${DOCS_SRC_RPM} ]]; then
    DOCS_NAME=$(rpm --queryformat "[%{NAME}]" -qp $DOCS_SRC_RPM)
    DOCS_VER=$(rpm --queryformat "[%{VERSION}]" -qp $DOCS_SRC_RPM)
    DOCS_REL=$(rpm --queryformat "[%{RELEASE}]" -qp $DOCS_SRC_RPM)
    DOCS_VERSION=${DOCS_VER}-${DOCS_REL}
fi

SCRIPTS_SRC_RPM=$(/bin/ls -1 ${SRPMS}/ofed-scripts*.src.rpm 2> $NULL)
if [[ -n "${SCRIPTS_SRC_RPM}" && -s ${SCRIPTS_SRC_RPM} ]]; then
    SCRIPTS_NAME=$(rpm --queryformat "[%{NAME}]" -qp $SCRIPTS_SRC_RPM)
    SCRIPTS_VER=$(rpm --queryformat "[%{VERSION}]" -qp $SCRIPTS_SRC_RPM)
    SCRIPTS_REL=$(rpm --queryformat "[%{RELEASE}]" -qp $SCRIPTS_SRC_RPM)
    SCRIPTS_VERSION=${SCRIPTS_VER}-${SCRIPTS_REL}
fi

OPENMPI_SRC_RPM=$(/bin/ls -1 ${SRPMS}/openmpi*src.rpm 2> $NULL)
if [[ -n "${OPENMPI_SRC_RPM}" && -s ${OPENMPI_SRC_RPM} ]]; then
    OPENMPI_NAME=$(rpm --queryformat "[%{NAME}]" -qp $OPENMPI_SRC_RPM)
    OPENMPI_VER=$(rpm --queryformat "[%{VERSION}]" -qp $OPENMPI_SRC_RPM)
    OPENMPI_REL=$(rpm --queryformat "[%{RELEASE}]" -qp $OPENMPI_SRC_RPM)
    OPENMPI_VERSION=${OPENMPI_VER}-${OPENMPI_REL}
fi
 
MPITESTS_SRC_RPM=$(/bin/ls -1 ${SRPMS}/mpitests*src.rpm 2> $NULL)
if [[ -n "${MPITESTS_SRC_RPM}" && -s ${MPITESTS_SRC_RPM} ]]; then
    MPITESTS_NAME=$(rpm --queryformat "[%{NAME}]" -qp $MPITESTS_SRC_RPM)
    MPITESTS_VER=$(rpm --queryformat "[%{VERSION}]" -qp $MPITESTS_SRC_RPM)
    MPITESTS_REL=$(rpm --queryformat "[%{RELEASE}]" -qp $MPITESTS_SRC_RPM)
    MPITESTS_VERSION=${MPITESTS_VER}-${MPITESTS_REL}
fi

IBUTILS_SRC_RPM=$(/bin/ls -1 ${SRPMS}/ibutils*src.rpm 2> $NULL)
if [[ -n "${IBUTILS_SRC_RPM}" && -s ${IBUTILS_SRC_RPM} ]]; then
    IBUTILS_NAME=$(rpm --queryformat "[%{NAME}]" -qp $IBUTILS_SRC_RPM)
    IBUTILS_VER=$(rpm --queryformat "[%{VERSION}]" -qp $IBUTILS_SRC_RPM)
    IBUTILS_REL=$(rpm --queryformat "[%{RELEASE}]" -qp $IBUTILS_SRC_RPM)
    IBUTILS_VERSION=${IBUTILS_VER}-${IBUTILS_REL}
fi

OISCSI_ISER_SRC_RPM=$(/bin/ls -1 ${SRPMS}/oiscsi-iser*src.rpm 2> $NULL)
if [[ -n "${OISCSI_ISER_SRC_RPM}" && -s ${OISCSI_ISER_SRC_RPM} ]]; then
    OISCSI_ISER_NAME=$(rpm --queryformat "[%{NAME}]" -qp $OISCSI_ISER_SRC_RPM)
    OISCSI_ISER_VER=$(rpm --queryformat "[%{VERSION}]" -qp $OISCSI_ISER_SRC_RPM)
    OISCSI_ISER_REL=$(rpm --queryformat "[%{RELEASE}]" -qp $OISCSI_ISER_SRC_RPM)
    OISCSI_ISER_VERSION=${OISCSI_ISER_VER}-${OISCSI_ISER_REL}
fi

###
### Check the configuration file and include its info if it exists
###
CONFIG=${CONFIG:-"${PKG_SOURCE_DIR}/ofed.conf"}

if [ $INTERACTIVE -eq 0 ]; then
	
        if [ -s "$CONFIG" ]; then
            . $CONFIG 
        else	
            echo "$CONFIG file does not exist or empty"
            exit 1
        fi
        TT_COLOR=no
else
        touch $CONFIG || exit 1
        TT_COLOR=yes
fi

# Set network environment configuration
case ${DISTRIBUTION} in
    SuSE)
    NETWORK_CONF_DIR=${NETWORK_CONF_DIR:-"/etc/sysconfig/network"}
    ;;
    fedora|redhat|Rocks)
    NETWORK_CONF_DIR=${NETWORK_CONF_DIR:-"/etc/sysconfig/network-scripts"}
    ;;
    *)
    NETWORK_CONF_DIR=${NETWORK_CONF_DIR:-"/etc/infiniband"}
    ;;
esac


###
### Build Environment definition
###
BUILD_ROOT_DFT=${BUILD_ROOT:-/var/tmp/${PACKAGE}}
BUILD_ROOT=${BUILD_ROOT_DFT}
BUILD_TMP=/tmp
rpms_cache=$BUILD_TMP/rpms_installed.cache

###
### Destination path definitions
###
STACK_PREFIX=${STACK_PREFIX:-/usr/local/ofed}


###
### Required definitions per package
###


###
### Functions Area
###
LOG=/tmp/${PACKAGE}.$$.log

# COLOR SETTINGS
SETCOLOR_SUCCESS="echo -en \\033[1;34m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_WARNING="echo -en \\033[1;35m"
SETCOLOR_NORMAL="echo -en \\033[0;39m"

# Print message with "ERROR:" prefix
err_echo()
{
   [ "$TT_COLOR" = "yes" ] && $SETCOLOR_FAILURE
   echo -n "ERROR: $@" | tee -a $LOG
   echo >> $LOG
   [ "$TT_COLOR" = "yes" ] && $SETCOLOR_NORMAL
   echo
   return 0
}

# Print message with "WARNING:" prefix
warn_echo()
{
   [ "$TT_COLOR" = "yes" ] && $SETCOLOR_WARNING
   echo -n "WARNING: $@" | tee -a $LOG
   echo >> $LOG
   [ "$TT_COLOR" = "yes" ] && $SETCOLOR_NORMAL
   echo
   return 0
}

# Print message (bold)
pass_echo()
{
   [ "$TT_COLOR" = "yes" ] && $SETCOLOR_SUCCESS
   echo -n "$@" | tee -a $LOG
   echo >> $LOG
   [ "$TT_COLOR" = "yes" ] && $SETCOLOR_NORMAL
   echo
   return 0
}
                    

# Remove the LOG file if it exists and create a new one                    
open_log()
{
        $RM -f $LOG    
        touch $LOG
}

close_log()
{
    echo "`basename $0` finished: `date`" >> $LOG    
}

# Wait for user to press any key and continue
getch()
{
        local ans
        
        echo -n "Press Enter to continue..."
        read ans
        return 0
}


# Clean the temporary files upon failure or after cancelling installation
cleanup()
{
        local ACTION=""
        local ans=""

        if [ $RUNNING_CLEANUP -eq 1 ]; then
            return 0
        fi
        
        RUNNING_CLEANUP=1
        
        if [ $INTERACTIVE -eq 1 ]; then
                # IF in install mode run uninstall
                if [ "$prog" == "install.sh" ]; then
                        echo
                        read -p  "Do you want to remove the already installed ${PACKAGE} packages? [Y/n]:" ans
                        if ! [[ "$ans" == "" || "$ans" == "y" || "$ans" == "Y" || "$ans" == "yes" ]]; then
                                return 0
                        fi   
                        ACTION="uninstall"
                else
                        # IF in build mode delete BUILD_ROOT
                        echo
                        if [ -d "$BUILD_ROOT" ]; then
                                read -p  "Do you want to remove the temporary build directory ${BUILD_ROOT}? [Y/n]:" ans
                                if ! [[ "$ans" == "" || "$ans" == "y" || "$ans" == "Y" || "$ans" == "yes" ]]; then
                                        return 0
                                fi   
                        fi
                        ACTION="delete"
                fi
        else # Non interactive mode
                if [ "$prog" == "install.sh" ]; then
                        ACTION="leave" # ACTION="uninstall"
                else
                        ACTION="leave"
                fi
        fi
        
        case "$ACTION" in
              "uninstall")
                      rmInstalled
              ;;
              "delete")
                      [ -d "$BUILD_ROOT" ] && $RM -rf $BUILD_ROOT
              ;;
              *)
              ;;
        esac
        
        if [ $INTERACTIVE -eq 1 ]; then
                getch
        fi
        
}

# Returns "0" if $1 is integer and "1" otherwise
is_integer() 
{
        printf "%s\n" $1 |grep -E "^[+-]?[0-9]+$" > $NULL
        return $?
}

# Stop running propeller
kill_propel()
{
        [ -z $PR_PID ] && return 0
        if ! is_integer $PR_PID; then
                return 0
        fi
        if ! ( ps -p $PR_PID > $NULL 2>&1 ); then
                return 0
        fi
        
        kill -15 $PR_PID  > $NULL 2>&1
        sleep 1
}

trap_handler()
{
        kill_propel
        exit 1

}

# Get user's trap (Ctrl-C or kill signals)
trap 'trap_handler' 2 9 15

# Execute the command $@ and check exit status
ex()
{
        EXECUTING=1

        perl -e 'exit((-t STDOUT) ? 0:1)'
        if [ $? -eq 0 ]; then
            $PROPEL &
            PR_PID=$!
        fi
     
        echo Running $@
        eval "$@" >> $LOG 2>&1
        if [ $? -ne 0 ]; then
             echo
             err_echo Failed executing \"$@\"
             echo
             cd ${curr_dir}
             echo See log file: $LOG
             echo
     
             kill_propel
     
             if [ $INTERACTIVE -eq 1 ]; then
                getch
             fi
             cleanup
             exit 5
        fi
     
        kill_propel
        
        EXECUTING=0   
}

# Execute the command $@ in silent mode and check exit status
ex_silent()
{
        EXECUTING=1
        
        #   echo Running $@
        eval "$@" >> $LOG 2>&1
        if [ $? -ne 0 ]; then
             echo
             err_echo Failed in execution \"$@\"
             echo
             cd ${curr_dir}
             echo See log file: $LOG
             echo
        
             if [ $INTERACTIVE -eq 1 ]; then
                getch
             fi
             cleanup
             exit 5
        fi
        
        EXECUTING=0   
}

# Check that "root" is the current user
check_user()
{
        local user
        user=`/usr/bin/id -u`
        if [ $user -ne 0 ] && [ "$prog" == "install.sh" ]; then
            err_echo "You must be root to run this install program"
            echo
            echo "Note: In order to build RPMs as $(whoami) run ./build.sh script"
            echo
            exit 1
        fi
}

# Check input from user (default is "No")
get_ans()
{
read ans
case $ans in
    Y|YES|y|yes)
        ans=""
        return 0
    ;;    
    *)
        ans=""
        return 1    
    ;;
esac        
}

# Show README or the ${PACKAGE} Installation guide file
view_readme()
{
        local prog=`basename $0`
        
        if [ "$prog" == "install.sh" ]; then
                if [ -e $PKG_SOURCE_DIR/docs/${PACKAGE}_Installation_Guide.txt ]; then
                    less $PKG_SOURCE_DIR/docs/${PACKAGE}_Installation_Guide.txt
                else
                    warn_echo $PKG_SOURCE_DIR/docs/${PACKAGE}_Installation_Guide.txt does not exist
                    getch
                fi                        
        else
                if [ -e $PKG_SOURCE_DIR/README.txt ]; then
                    less $PKG_SOURCE_DIR/README.txt
                else
                    warn_echo $PKG_SOURCE_DIR/README.txt does not exist
                    getch
                fi                        
        	
        fi
        
        return 0
}

# Check disk space requirments $1 - required size $2 - directory to check
check_space_req()
{
        local space_req=$1
        local dir=$2
        
        shift 2
        
        while [ ! -d $dir ]
        do
                dir=${dir%*/*}
        done
        
        local avail_space=`$DF $dir | tail -1 | awk '{print$4}' | tr -d '[:space:]'`
        
        if ! is_integer $avail_space; then
                # Wrong avail_space found
                return 0
        fi
        
        if [ $avail_space -lt $space_req ]; then
                echo
                err_echo "Not enough disk space in the ${dir} directory. Required ${space_req}KB"
                echo
                if [ $INTERACTIVE -eq 1 ]; then
                    getch
                fi
                exit 1
        fi

        return 0
}

# Compare package versions $1 and $2. Return 0 if $1=$2, 1 if $1 > $2, 2 - if $1 < $2
compare()
{
        local ver1=$(echo $1 | tr -d '[:alpha:]')
        local ver2=$(echo $2 | tr -d '[:alpha:]')
        local dots1=0
        local dots2=0
        local dots=0
        local diff=0
        
        if [ "$ver1" == "$ver2" ]; then
            return 0
        fi
        
        [ "$ver1" == "" ] && ver1=0
        [ "$ver2" == "" ] && ver2=0
        
        dots1=$(echo $ver1 | tr -d '[:digit:]' | tr -d '[:space:]' | wc -c | tr -d '[:space:]')
        dots2=$(echo $ver2 | tr -d '[:digit:]' | tr -d '[:space:]' | wc -c | tr -d '[:space:]')
        
        if [ $dots1 -gt $dots2 ]; then
            dots=$dots2
            diff=1
        elif [ $dots1 -lt $dots2 ]; then
            dots=$dots1
            diff=2
        else
            dots=$dots1
            diff=0    
        fi
        
        let dots++
        for (( i=1 ; i <= $dots ; i++ ))
        do
            [ $(echo $ver1 | cut -d . -f $i | tr -d '[:space:]') -gt $(echo $ver2 | cut -d . -f $i | tr -d '[:space:]') ] && return 1
            [ $(echo $ver1 | cut -d . -f $i | tr -d '[:space:]') -lt $(echo $ver2 | cut -d . -f $i | tr -d '[:space:]') ] && return 2
        done
        
        [ $diff -eq 1 ] && return 1
        [ $diff -eq 2 ] && return 2
        
        return 3
}

count_ib_ports()
{
    local cnt=0
    local tmp_cnt=0
    
    tmp_cnt=$(/sbin/lspci -n 2> $NULL | grep "15b3:6282" | wc -l | tr -d '[:space:]') # InfiniHost III Ex mode
    cnt=$[ $cnt + 2*${tmp_cnt} ]
    
    tmp_cnt=$(/sbin/lspci -n 2> $NULL | grep -E "15b3:5e8c|15b3:6274" | wc -l | tr -d '[:space:]') # InfiniHost III Lx mode
    cnt=$[ $cnt + ${tmp_cnt} ]

    tmp_cnt=$(/sbin/lspci -n 2> $NULL | grep -E "15b3:5a44|15b3:6278" | wc -l | tr -d '[:space:]') # InfiniHost mode
    cnt=$[ $cnt + 2*${tmp_cnt} ]

    # TBD insert count for ipath devices
    
    return $cnt
}

print_package_info()
{
    local package=$1
    shift
    local DESCR=$($RPM --queryformat "[%{DESCRIPTION}]" -q $package)
    local VERSION=$($RPM --queryformat "[%{VERSION}]" -q $package)
    echo
    echo "NAME: $package"
    echo "VERSION: $VERSION"
    echo "Description: $DESCR"
}

# View installed packages
showInstalled()
{
        local RC=0
        local mpi_packs=""
        local package=""

        for package in $ALL_PACKAGES $PREV_RELEASE_PACKAGES
        do
            case $package in
                mpi_osu)
                    mpi_packs=$($RPM -qa | grep ${MPI_OSU_MPICH_NAME})
                    if [ -n "${mpi_packs}" ]; then
                        for mpi_pack in ${mpi_packs}
                        do
                            if ( $RPM -q $mpi_pack > $NULL 2>&1 ); then
                                print_package_info $mpi_pack
                                let RC++
                            fi
                        done
                    fi
                ;;
                openmpi)
                    mpi_packs=$($RPM -qa | grep ${OPENMPI_NAME})
                    if [ -n "${mpi_packs}" ]; then
                        for mpi_pack in ${mpi_packs}
                        do
                            if ( $RPM -q $mpi_pack > $NULL 2>&1 ); then
                                print_package_info $mpi_pack
                                let RC++
                            fi
                        done
                    fi
                ;;
                *)
                    if ( $RPM -q $package > $NULL 2>&1 ); then
                        print_package_info $package
                        let RC++
                    fi
                ;;
            esac
        done    
        
        if [ $RC -eq 0 ]; then
            echo
            echo    There are no ${PACKAGE} Software Installed
            echo
        fi
  
        return 0
}

# Check if the required compiler - $1 exist
# In case of the Open MPI package, the Fortran compiler is not required
is_compiler()
{
    local compiler=$1
    local mpipackage=$2
    shift 2

    case ${compiler} in
        gcc)
            is_gpp=0
            is_gcc_g77=0
            is_gfortran=0
            if ! ( $WHICH gcc > $NULL 2>&1 ); then
                return 1
            fi
            if [ "${mpipackage}" == "mpi_osu" ]; then
                if ( $WHICH gfortran > $NULL 2>&1 ); then
                    is_gfortran=1
                    return 0
                elif ( $WHICH g77 > $NULL 2>&1 ); then
                    is_gcc_g77=1
                    return 0
                else
                    return 1
                fi
            else
                if ( $WHICH g++ > $NULL 2>&1 ); then
                    is_gpp=1
                fi
                if ( $WHICH g77 > $NULL 2>&1 ); then
                    is_gcc_g77=1
                fi
                if ( $WHICH gfortran > $NULL 2>&1 ); then
                    is_gfortran=1
                fi
                return 0
            fi
        ;;
        pathscale)
            is_pathCC=0
            is_pathf90=0
            if ! ( $WHICH pathcc > $NULL 2>&1 ); then
                return 1
            fi
            if [ "${mpipackage}" == "mpi_osu" ]; then
                if ( $WHICH pathCC > $NULL 2>&1 && $WHICH pathf90 > $NULL 2>&1 ); then
                    is_pathCC=1
                    is_pathf90=1
                    return 0
                else
                    return 1
                fi
            else
                if ( $WHICH pathCC > $NULL 2>&1 ); then
                    is_pathCC=1
                fi
                if ( $WHICH pathf90 > $NULL 2>&1 ); then
                    is_pathf90=1
                fi
                return 0
            fi
        ;;
        pgi)
            is_pgCC=0
            is_pgf77=0
            is_pgf90=0
            if ! ( $WHICH pgcc > $NULL 2>&1 ); then
                return 1
            fi
            if [ "${mpipackage}" == "mpi_osu" ]; then
                if ( $WHICH pgf77 > $NULL 2>&1 && $WHICH pgf90 > $NULL 2>&1 ); then
                    is_pgf77=1
                    is_pgf90=1
                    return 0
                else
                    return 1
                fi
            else
                if ( $WHICH pgCC > $NULL 2>&1 ); then
                    is_pgCC=1
                fi
                if ( $WHICH pgf77 > $NULL 2>&1 ); then
                    is_pgf77=1
                fi
                if ( $WHICH pgf90 > $NULL 2>&1 ); then
                    is_pgf90=1
                fi
                return 0
            fi
        ;;
        intel)
            is_icpc=0
            is_ifort=0
            if ! ( $WHICH icc > $NULL 2>&1 ); then
                return 1
            fi
            if [ "${mpipackage}" == "mpi_osu" ]; then
                if ( $WHICH icpc > $NULL 2>&1 && $WHICH ifort > $NULL 2>&1 ); then
                    is_icpc=1
                    is_ifort=1
                    return 0
                else
                    return 1
                fi
            else
                if ( $WHICH icpc > $NULL 2>&1 ); then
                    is_icpc=1
                fi
                if ( $WHICH ifort > $NULL 2>&1 ); then
                    is_ifort=1
                fi
                return 0
            fi
        ;;
        *)
            warn_echo "This compiler is not supported"
            return 1
        ;;
    esac
    
}

# Set Compilation environment for MPI
set_mpi_env()
{

        local mpipackage=$1
        shift
        local COMPILERS_FOUND=""
        local EXCLUDED_COMPILERS=""
        local mpi_compiler=""
        local ans=""

        if [ $INTERACTIVE -eq 1 ]; then

                for mpi_compiler in ${MPI_SUPPORTED_COMPILERS}
                do
                    if is_compiler ${mpi_compiler} ${mpipackage}; then
                        COMPILERS_FOUND="$COMPILERS_FOUND ${mpi_compiler}"
                    fi
                done

            # COMPILERS_FOUND=$(echo $COMPILERS_FOUND | tr -s ' ' '\n' | sort -rn | uniq | tr -s '\n' ' ')
            if [ -n "$COMPILERS_FOUND" ]; then
                echo
                echo "The following compiler(s) on your system can be used to build/install ${mpipackage}: $COMPILERS_FOUND"
                echo
            fi

            printed_msg0=${printed_msg0:-0}
            if [ $printed_msg0 -eq 0 ]; then
                if [ $(echo -n ${COMPILERS_FOUND} | wc -w) -gt 1 ]; then
                    echo "Next you will be prompted to choose the compiler(s) with which to build/install the MPI RPM(s)"
                    echo
                fi
                printed_msg0=1
            fi

            MPI_COMPILER=""

            for mpi_compiler in $COMPILERS_FOUND
            do
                read -p "Do you wish to create/install an ${mpipackage} RPM with ${mpi_compiler}? [Y/n]:" ans
                if [[ "$ans" == "" || "$ans" == "y" || "$ans" == "Y" || "$ans" == "yes" ]]; then
                    MPI_COMPILER="$MPI_COMPILER ${mpi_compiler}"
                fi
            done

        else # Unattended mode
            case ${mpipackage} in
                mpi_osu)
                    if [ ! -z "${MPI_COMPILER_mpi_osu}" ]; then
                        MPI_COMPILER=${MPI_COMPILER_mpi_osu}
                    fi
                ;;
                openmpi)
                    if [ ! -z "${MPI_COMPILER_openmpi}" ]; then
                        MPI_COMPILER=${MPI_COMPILER_openmpi}
                    fi
                ;;
            esac

            if [ ! -n "${MPI_COMPILER}" ]; then
                MPI_COMPILER=gcc
                echo "The MPI_COMPILER_${mpipackage} variable is not defined. Trying the default compiler: ${MPI_COMPILER}"
            fi
            for mpi_compiler in ${MPI_COMPILER}
            do
                if ! is_compiler ${mpi_compiler} ${mpipackage}; then
                    if [ "${mpi_compiler}" == "gcc" ] && [ "${mpipackage}" == "mpi_osu" ]; then
                        mpi_compiler="gcc-g77"
                    fi
                    EXCLUDED_COMPILERS="$EXCLUDED_COMPILERS ${mpi_compiler}"
                else
                    COMPILERS_FOUND="$COMPILERS_FOUND ${mpi_compiler}"
                fi
            done

            MPI_COMPILER=$(echo $COMPILERS_FOUND | tr -s ' ' '\n' | sort -rn | uniq | tr -s '\n' ' ')

            if [ -n "${EXCLUDED_COMPILERS}" ]; then
                warn_echo "The following compiler(s) for ${mpipackage} were not found on the system: ${EXCLUDED_COMPILERS}"
            fi

        fi


        case ${mpipackage} in
            mpi_osu)
                if [ ! -n "${MPI_COMPILER}" ]; then
                    warn_echo "No compilers for ${mpipackage} were found"
                    return 1
                fi

                MPI_COMPILER_mpi_osu=${MPI_COMPILER}
                if ! ( grep -w MPI_COMPILER_mpi_osu $CONFIG > $NULL 2>&1 ); then
                    echo "MPI_COMPILER_mpi_osu=\"${MPI_COMPILER_mpi_osu}\"" >> $CONFIG
                fi
                echo
                echo "The following compiler(s) will be used to ${prog%*.*} the ${mpipackage} RPM(s): $MPI_COMPILER_mpi_osu"
            ;;
            openmpi)
                if [ ! -n "${COMPILERS_FOUND}" ]; then
                    warn_echo "No compilers for ${mpipackage} were found"
                    return 1
                fi
                MPI_COMPILER_openmpi=${MPI_COMPILER}
                if ! ( grep -w MPI_COMPILER_openmpi $CONFIG > $NULL 2>&1 ); then
                    echo "MPI_COMPILER_openmpi=\"${MPI_COMPILER_openmpi}\"" >> $CONFIG
                fi
                echo
                echo "The following compiler(s) will be used to ${prog%*.*} the ${mpipackage} RPM(s): $MPI_COMPILER_openmpi"
            ;;
        esac
        MPI_COMPILER=""
        return 0
}

# Select the packages to install
select_packages()
{

        if [ $INTERACTIVE -eq 1 ]; then

                local package=""
                local package_var=""
                local ans_select=""
                # Configuration parameters initialization
                touch $CONFIG

                # Save previous configuration file
                [ -s $CONFIG ] && $MV -f $CONFIG ${CONFIG}.save

                cat $NULL > $CONFIG

                echo STACK_PREFIX=$STACK_PREFIX >> $CONFIG
                echo BUILD_ROOT=$BUILD_ROOT >> $CONFIG

                show_menu "select_mode_menu"

                read ans_select
                case $ans_select in
                        $BASIC)
                                SELECTED_PACKAGES="$BASIC_PACKAGES $BASIC_IB_KERNEL_PACKAGES"
                                for package in $SELECTED_PACKAGES
                                do
                                        package_var=$(echo -n ${package} | sed -e 's/-/_/g')
                                        echo "${package_var}=y" >> $CONFIG
                                done
                        ;;
                        $HPC)
                                SELECTED_PACKAGES="$HPC_PACKAGES $IB_KERNEL_PACKAGES"
                                for package in $SELECTED_PACKAGES 
                                do
                                        package_var=$(echo -n ${package} | sed -e 's/-/_/g')
                                        echo "${package_var}=y" >> $CONFIG
                                done
                        ;;
                        $ALL)
                                SELECTED_PACKAGES="$ALL_PACKAGES $IB_KERNEL_PACKAGES"
                                for package in $SELECTED_PACKAGES
                                do
                                        package_var=$(echo -n ${package} | sed -e 's/-/_/g')
                                        echo "${package_var}=y" >> $CONFIG
                                done
                        ;;
                        $CUSTOM)
                                echo
                                echo "RPM packages:"
                                for package in $ALL_PACKAGES
                                do
                                        pack_descr=$(eval echo \$\{${package}_descr\})
                                        package_var=$(echo -n ${package} | sed -e 's/-/_/g')
                                        if [ "${package}" == "libibverbs" ]; then
                                            echo "User level libraries/applications:"
                                        fi
                                        echo -n "Install ${package}: [y/N]:"

                                        if get_ans; then
                                            if [ "$SELECTED_PACKAGES" == "" ]; then
                                                SELECTED_PACKAGES="${package}"
                                            else
                                                SELECTED_PACKAGES="$SELECTED_PACKAGES ${package}"
                                            fi
                                            echo "${package_var}=y" >> $CONFIG
                                            if [ "${package}" == "kernel-ib" ]; then
                                                echo "Kernel level modules:"
                                                for package in $IB_KERNEL_PACKAGES
                                                do
                                                        pack_descr=$(eval echo \$\{${package}_descr\})
                                                        package_var=$(echo -n ${package} | sed -e 's/-/_/g')
                                                        echo -n "Install ${package}: [y/N]:"

                                                        if get_ans; then
                                                            if [ "$SELECTED_PACKAGES" == "" ]; then
                                                                SELECTED_PACKAGES="${package}"
                                                            else
                                                                SELECTED_PACKAGES="$SELECTED_PACKAGES ${package}"
                                                            fi
                                                            echo "${package_var}=y" >> $CONFIG
                                                        else
                                                            echo "${package_var}=n" >> $CONFIG
                                                        fi
                                                done
                                            fi
                                        else
                                            echo "${package_var}=n" >> $CONFIG
                                        fi
                                done
                        ;;
                        q|Q)
                                # Exit from install/build script
                                exit 0
                        ;;
                        *)
                                select_packages
                        ;;
                esac
                . $CONFIG
        else # Unatended mode
            # Read configuration from CONFIG file
            # . $CONFIG
            SELECTED_PACKAGES=$(perl -n -e 'if(m@^\s*#.*@) { $filter = 1; } elsif (m@^\s*ib_.*@) { $filter = 1; } else { $filter = 0; }' -e 'if(m@^\s*(.*)=y@ and $filter == 0) { print "$1 " }' $CONFIG)
            SELECTED_OPENIB_KERNEL_PACKAGES=$(perl -n -e 'if(m@^\s*#.*@) { $filter = 1; } else { $filter = 0; }' -e 'if(m@^\s*(ib_.*)=y@ and $filter == 0) { print "$1 " }' $CONFIG)
            SELECTED_PACKAGES="$SELECTED_OPENIB_KERNEL_PACKAGES $SELECTED_PACKAGES"
            # echo "DEBUG: SELECTED_PACKAGES=$SELECTED_PACKAGES"
        fi
}

# Display installation/build menus
show_menu()
{

    clear
     case "$1" in
                 "main_menu")
cat << EOF_INST

         InfiniBand ${PACKAGE} Distribution Software Installation Menu

          1) View ${PACKAGE} Installation Guide
          2) Install ${PACKAGE} Software 
          3) Show Installed Software
          4) Configure IPoIB Network Interface and OpenSM Server
          5) Uninstall InfiniBand Software
          6) Build ${PACKAGE} Software RPMs

          Q) Exit

EOF_INST
          
    echo -n   "Select Option [1-6]:"
                         ;;
                 "build_menu")
cat << EOF_BUILD

         InfiniBand Software Build Menu

          1) View README (read "Building IB SW RPM packages")
          2) Build InfiniBand Software RPMs

          Q) Exit

EOF_BUILD

    echo -n   "Select Option [1-2]:"

                 ;;
                 "select_mode_menu")
cat << EOF_MODE_MENU

          Select ${PACKAGE} Software

          1) Basic (InfiniBand modules and basic user level libraries)
          2) HPC (InfiniBand modules and libraries, mpi and diagnostic tools)
          3) All packages (all of openib, mpi)
          4) Customize

          Q) Exit

EOF_MODE_MENU

    echo -n   "Select Option [1-4]:"

                 ;;
                 *)
                     return 1
                 ;;
     esac
    return 0
}


OPENIB_DEST=${STACK_PREFIX}
OPENSM_DEST=${STACK_PREFIX}
OSU_DEST=${STACK_PREFIX}/mpi/osu
SCRIPTS_DEST=${STACK_PREFIX}/scripts
FW_DEST=${STACK_PREFIX}

###
### Required definitions per package
###

kernel_ib_RUN_REQ=""
kernel_ib_devel_RUN_REQ=""
libibverbs_RUN_REQ=""
libibverbs_devel_RUN_REQ=""
libibverbs_utils_RUN_REQ=""
libibcm_RUN_REQ=""
libmthca_RUN_REQ=""
libmthca_devel_RUN_REQ=""
libehca_RUN_REQ=""
libehca_devel_RUN_REQ=""
libipathverbs_RUN_REQ=""
libipathverbs_devel_RUN_REQ=""
libsdp_RUN_REQ=""
srptools_RUN_REQ=""
ipoibtools_RUN_REQ=""
tvflash_RUN_REQ=""
libibcommon_RUN_REQ=""
libibmad_RUN_REQ=""
libibumad_RUN_REQ=""
openib_diags_RUN_REQ=""
ibutils_RUN_REQ="tcl_8.4 tcl-devel_8.4"
opensm_RUN_REQ=""
libopensm_RUN_REQ=""
libopensm_devel_RUN_REQ=""
libosmcomp_RUN_REQ=""
libosmcomp_devel_RUN_REQ=""
libosmvendor_RUN_REQ=""
libosmvendor_devel_RUN_REQ=""
perftest_RUN_REQ=""
mstflint_RUN_REQ=""
librdmacm_RUN_REQ=""
oiscsi_iser_RUN_REQ="open-iscsi"
mpi_osu_RUN_REQ=""
openmpi_RUN_REQ=""
mpitests_RUN_REQ=""
ofed_docs_RUN_REQ=""

kernel_ib_BUILD_REQ=""
kernel_ib_devel_BUILD_REQ=""
libibverbs_BUILD_REQ="gcc_3.3.3"
libibverbs_devel_BUILD_REQ=""
libibverbs_utils_BUILD_REQ=""
libibcm_BUILD_REQ=""
libmthca_BUILD_REQ=""
libmthca_devel_BUILD_REQ=""
libehca_BUILD_REQ=""
libehca_devel_BUILD_REQ=""
libipathverbs_BUILD_REQ=""
libipathverbs_devel_BUILD_REQ=""
libsdp_BUILD_REQ=""
srptools_BUILD_REQ=""
ipoibtools_BUILD_REQ=""
tvflash_BUILD_REQ="pciutils-devel"
libibcommon_BUILD_REQ=""
libibmad_BUILD_REQ=""
libibumad_BUILD_REQ=""
openib_diags_BUILD_REQ=""
ibutils_BUILD_REQ="tcl_8.4 tcl-devel_8.4"
opensm_BUILD_REQ=""
libopensm_BUILD_REQ=""
libopensm_devel_BUILD_REQ=""
libosmcomp_BUILD_REQ=""
libosmcomp_devel_BUILD_REQ=""
libosmvendor_BUILD_REQ=""
libosmvendor_devel_BUILD_REQ=""
perftest_BUILD_REQ=""
mstflint_BUILD_REQ=""
librdmacm_BUILD_REQ=""
oiscsi_iser_BUILD_REQ="db-devel open-iscsi"
mpi_osu_BUILD_REQ=""    
openmpi_BUILD_REQ=""    
mpitests_BUILD_REQ=""
ofed_docs_BUILD_REQ=""

pdsh_RUN_REQ="readline"
pdsh_BUILD_REQ="readline"

case ${DISTRIBUTION} in
        "SuSE")
        libibverbs_BUILD_REQ="${libibverbs_BUILD_REQ} rpm"
        if (grep "SUSE LINUX Enterprise Server 9" /etc/issue > $NULL 2>&1); then
            libibverbs_devel_BUILD_REQ="${libibverbs_devel_BUILD_REQ} udev"
        else
            libibverbs_devel_BUILD_REQ="${libibverbs_devel_BUILD_REQ} sysfsutils"
        fi
        ;;
        *)
        libibverbs_BUILD_REQ="${libibverbs_BUILD_REQ} rpm-build"
        libibverbs_devel_BUILD_REQ="${libibverbs_devel_BUILD_REQ} sysfsutils-devel"
        ;;
esac


# Check the $1 package RPM Build Requirements ( Like kernel sources ... )
check_build_req()
{
        local RC=0
        local mode=$2
        local breq_pack
        local breq_pack_name
        local breq_pack_ver
        local breq_pack_rel
        local curr_pack_ver
            
        # Create cache files with RPM names and the list of capabilities
        for breq_pack in `eval echo \$\{${1}_BUILD_REQ\}`
        do
                if ( echo $breq_pack | grep '_' > $NULL 2>&1 ); then
                        breq_pack_name=`echo $breq_pack | cut -d '_' -f 1`
                        breq_pack_ver=`echo $breq_pack | cut -d '_' -f 2`
                        breq_pack_rel=`echo $breq_pack | cut -d '_' -f 3`
                else
                        breq_pack_name=$breq_pack
                        breq_pack_ver=""
                        breq_pack_rel=""
                fi    
                
                if ! ( grep -w $breq_pack_name ${rpms_cache} > $NULL 2>&1 ); then
                        [ "$mode" == "warn" ] && warn_echo "The $breq_pack_name package is required to build $1 RPM"
                        [ "$mode" == "err" ] && err_echo "The $breq_pack_name package is required to build $1 RPM"
                        let RC++
                else
                    if [ "$breq_pack_ver" != "" ]; then
                            curr_pack_ver=$($RPM --queryformat "[%{VERSION}]" -q $breq_pack_name)
                            compare $breq_pack_ver $curr_pack_ver
                            if [ $? -eq 1 ]; then
                                    [ "$mode" == "warn" ] && warn_echo "The $breq_pack_name >= $breq_pack_ver package is required to build $1"
                                    [ "$mode" == "err" ] && err_echo "The $breq_pack_name >= $breq_pack_ver package is required to build $1"
                                    let RC++
                            fi
                    fi
                
                fi
        done

        # Check for 64-bit libraries on 64-bit machines
        if [ "$ARCH" == "x86_64" ] || [ "$ARCH" == "ppc64" ]; then
            case $1 in
                libibverbs)
                    if (grep "SUSE LINUX Enterprise Server 9" /etc/issue > $NULL 2>&1); then
                        if ! ( grep libsysfs.so ${rpms_cache} | grep 64bit > $NULL 2>&1 ); then
                            err_echo "udev 64-bit version is required to build libibverbs package"
                            let RC++
                        fi
                    else
                        if ! ( grep libsysfs.so ${rpms_cache} | grep 64bit > $NULL 2>&1 ); then
                            err_echo "sysfsutils 64-bit version is required to build libibverbs package"
                            let RC++
                        fi
                    fi
                    if ! ( grep libsysfs.so ${rpms_cache} | grep -v 64bit > $NULL 2>&1 ); then
                        warn_echo "sysfsutils 32-bit version is required to build 32-bit libibverbs package."
                        warn_echo "Skiping build of 32-bit libraries."
                        build_32bit=0
                    else
                        build_32bit=1
                    fi
                ;;
                openmpi|mpi_osu|ibutils)
                    if ! ( grep libstdc++.so ${rpms_cache} | grep 64bit > $NULL 2>&1 ); then
                        err_echo "libstdc++ 64-bit version is required to build $1 packages"
                        let RC++
                    fi
                ;;
            esac
        fi

        return $RC    
}


# Select packages following their dependencies inside ${PACKAGE}
set_package_deps()
{        
        OPENIB_PACKAGES=""
        OPENIB_KERNEL_PACKAGES=""
        # IB_EXTRA_PACKAGES=""
        EXTRA_PACKAGES=""

        # Set default for low level driver
        # Can be defined as an environment variable or placed in the ofed.conf file for unattended installation
        ll_driver=${ll_driver:-"ib_mthca"}
        
        # Create list of packages to build
        for package in $SELECTED_PACKAGES
        do
                package_var=$(echo -n ${package} | sed -e 's/-/_/g')
                case ${package_var} in
                    ib_verbs)
                        OPENIB_KERNEL_PACKAGES=$(echo "$OPENIB_KERNEL_PACKAGES ib_verbs" | tr -s ' ' '\n' | sort -n | uniq)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES kernel-ib" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    ib_mthca)
                        OPENIB_KERNEL_PACKAGES=$(echo "$OPENIB_KERNEL_PACKAGES ib_verbs ib_mthca" | tr -s ' ' '\n' | sort -n | uniq)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES kernel-ib" | tr -s ' ' '\n' | sort -n | uniq)
                        ll_driver=${ll_driver:-"ib_mthca"}
                    ;;
                    ib_ipath)
                        case ${ARCH} in
                            x86_64)
                                case ${K_VER} in
                                2.6.5-7.*)
                                    if [ "$prog" == "build.sh" ]; then
                                        warn_echo IPATH is not supported by this kernel
                                    fi
                                ;;
                                *)
                                    OPENIB_KERNEL_PACKAGES=$(echo "$OPENIB_KERNEL_PACKAGES ib_verbs ib_ipath" | tr -s ' ' '\n' | sort -n | uniq)
                                    OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES kernel-ib" | tr -s ' ' '\n' | sort -n | uniq)
                                    ll_driver=${ll_driver:-"ib_ipath"}
                                ;;
                                esac
                            ;;
                            *)
                                if [ "$prog" == "build.sh" ]; then
                                    warn_echo PathScale InfiniPath host channel adapters low level driver supports only a x86_64 architecture
                                fi
                            ;;
                        esac
                    ;;
                    ib_ehca)
                        case ${ARCH} in
                            ppc|ppc64)
                                case ${K_VER} in
                                    2.6.1[6-9]*)
                                        OPENIB_KERNEL_PACKAGES=$(echo "$OPENIB_KERNEL_PACKAGES ib_verbs ib_ehca" | tr -s ' ' '\n' | sort -n | uniq)
                                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES kernel-ib" | tr -s ' ' '\n' | sort -n | uniq)
                                        ll_driver=${ll_driver:-"ib_ehca"}
                                    ;;
                                    *)
                                        if [ "$prog" == "build.sh" ]; then
                                            warn_echo EHCA is not supported by this kernel
                                        fi
                                    ;;
                                esac
                            ;;
                            *)
                                if [ "$prog" == "build.sh" ]; then
                                    warn_echo EHCA is not supported on ${ARCH}
                                fi
                            ;;
                        esac
                   ;;
                    ib_ipoib)
                            OPENIB_KERNEL_PACKAGES=$(echo "$OPENIB_KERNEL_PACKAGES ib_verbs ${ll_driver} ib_ipoib" | tr -s ' ' '\n' | sort -n | uniq)
                            OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES kernel-ib" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    ib_sdp)
                            OPENIB_KERNEL_PACKAGES=$(echo "$OPENIB_KERNEL_PACKAGES ib_verbs ${ll_driver} ib_ipoib ib_sdp" | tr -s ' ' '\n' | sort -n | uniq)
                            OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES kernel-ib" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    ib_srp)
                            OPENIB_KERNEL_PACKAGES=$(echo "$OPENIB_KERNEL_PACKAGES ib_verbs ${ll_driver} ib_ipoib ib_srp" | tr -s ' ' '\n' | sort -n | uniq)
                            OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES kernel-ib" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    ib_iser)
                        # Currently ISER is supported only on SLES10 RC1
                        # 2.6.[1-9][6-9]*)
                        case ${K_VER} in
                        2.6.16.21-0.8-smp)
                            OPENIB_KERNEL_PACKAGES=$(echo "$OPENIB_KERNEL_PACKAGES ib_verbs ${ll_driver} ib_iser" | tr -s ' ' '\n' | sort -n | uniq)
                            OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES kernel-ib" | tr -s ' ' '\n' | sort -n | uniq)
                        ;;
                        *)
                            if [ "$prog" == "build.sh" ]; then
                                warn_echo ISER is not supported by this kernel
                            fi
                        ;;
                        esac
                    ;;
                    ib_rds)
                        warn_echo RDS is not supported by this release
                        # case ${K_VER} in
                        # 2.6.5-7.*)
                        #     if [ "$prog" == "build.sh" ]; then
                        #         warn_echo RDS is not supported by this kernel
                        #     fi
                        # ;;
                        # *)
                        #     OPENIB_KERNEL_PACKAGES=$(echo "$OPENIB_KERNEL_PACKAGES ib_verbs ${ll_driver} ib_ipoib ib_rds" | tr -s ' ' '\n' | sort -n | uniq)
                        #     OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES kernel-ib" | tr -s ' ' '\n' | sort -n | uniq)
                        # ;;
                        # esac
                    ;;
                    kernel_ib)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES kernel-ib" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    kernel_ib_devel)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES kernel-ib-devel" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    libibverbs)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    libibverbs_devel)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs libibverbs-devel" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    libibverbs_utils)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs libibverbs-utils" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    libibcm)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs libibcm" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    libibcm_devel)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs libibcm libibcm-devel" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    libmthca)
                        # Add libmthca package only if MTHCA driver selected to be installed
                        if (echo -n ${SELECTED_PACKAGES} | grep -w "ib_mthca" > $NULL); then
                            OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs libmthca" | tr -s ' ' '\n' | sort -n | uniq)
                        fi
                    ;;
                    libmthca_devel)
                        # Add libmthca-devel package only if MTHCA driver selected to be installed
                        if (echo -n ${SELECTED_PACKAGES} | grep -w "ib_mthca" > $NULL); then
                            OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs libmthca libmthca-devel" | tr -s ' ' '\n' | sort -n | uniq)
                        fi
                    ;;
                    libehca)
                        # Add libehca package only if EHCA driver selected to be installed
                        case ${ARCH} in
                            ppc|ppc64)
                                if (echo -n ${SELECTED_PACKAGES} | grep -w "ib_ehca" > $NULL); then
                                    OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs libehca" | tr -s ' ' '\n' | sort -n | uniq)
                                fi
                            ;;
                            *)
                                if [ "$prog" == "build.sh" ]; then
                                    warn_echo libehca is not supported on ${ARCH}
                                fi
                            ;;
                        esac
                    ;;
                    libehca_devel)
                        # Add libehca-devel package only if EHCA driver selected to be installed
                        case ${ARCH} in
                            ppc|ppc64)
                                if (echo -n ${SELECTED_PACKAGES} | grep -w "ib_ehca" > $NULL); then
                                    OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs libehca libehca-devel" | tr -s ' ' '\n' | sort -n | uniq)
                                fi
                            ;;
                            *)
                                if [ "$prog" == "build.sh" ]; then
                                    warn_echo libehca is not supported on ${ARCH}
                                fi
                            ;;
                        esac
                    ;;
                    libipathverbs)
                        # Add libipathverbs package only if IPATH driver selected to be installed
                        if (echo -n ${SELECTED_PACKAGES} | grep -w "ib_ipath" > $NULL); then
                            OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs libipathverbs" | tr -s ' ' '\n' | sort -n | uniq)
                        fi
                    ;;
                    libipathverbs_devel)
                        # Add libipathverbs-devel package only if IPATH driver selected to be installed
                        if (echo -n ${SELECTED_PACKAGES} | grep -w "ib_ipath" > $NULL); then
                            OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs libipathverbs libipathverbs-devel" | tr -s ' ' '\n' | sort -n | uniq)
                        fi
                    ;;
                    libsdp)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libsdp" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    srptools)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs libibumad libibcommon srptools" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    ipoibtools)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES ipoibtools" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    tvflash)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES tvflash" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    libibcommon)
                        # libibverbs added as a workaround to the configure issue
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibcommon libibverbs" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    libibcommon_devel)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibcommon libibcommon-devel libibverbs" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    libibmad)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibcommon libibmad libibumad" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    libibmad_devel)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibcommon libibmad libibmad-devel libibumad libibumad-devel" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    libibumad)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibcommon libibverbs libibumad" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    libibumad_devel)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibcommon libibverbs libibumad libibumad-devel" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    openib_diags)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibcommon libibverbs libibmad libibumad libosmcomp libosmvendor libopensm openib-diags" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    libosmcomp)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibcommon libibverbs libibumad libosmcomp" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    libosmcomp_devel)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibcommon libibverbs libibumad libosmcomp-devel" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    libosmvendor)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibcommon libibverbs libibumad libosmvendor" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    libosmvendor_devel)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibcommon libibverbs libibumad libosmvendor-devel" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    opensm)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibcommon libibverbs libibumad libosmcomp libosmvendor libopensm opensm" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    libopensm)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibcommon libibverbs libibumad libosmcomp libosmcomp-devel libosmvendor libosmvendor-devel libopensm" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    libopensm_devel)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibcommon libibverbs libibumad libosmcomp libosmvendor libopensm-devel" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    ibutils)
                        EXTRA_PACKAGES=$(echo "$EXTRA_PACKAGES ibutils" | tr -s ' ' '\n' | sort -rn | uniq)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibcommon libibcommon-devel libibverbs libibverbs-devel libibmad libibmad-devel libibumad libibumad-devel libosmcomp libosmcomp-devel libosmvendor libosmvendor-devel libopensm libopensm-devel" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    perftest)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs librdmacm perftest" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    mstflint)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES mstflint" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    librdmacm)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs librdmacm" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    librdmacm_devel)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs librdmacm librdmacm-devel" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    librdmacm_utils)
                        OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs librdmacm librdmacm-utils" | tr -s ' ' '\n' | sort -n | uniq)
                    ;;
                    dapl)
                        case $(uname -m) in
                            ppc64)
                                if [ "$prog" == "build.sh" ]; then
                                    warn_echo "Dapl is not supported on the PPC64 arcitecture"
                                fi
                            ;;
                            *)
                            OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs librdmacm librdmacm-devel dapl" | tr -s ' ' '\n' | sort -n | uniq)
                            ;;
                        esac
                    ;;
                    dapl_devel)
                        case $(uname -m) in
                            ppc64)
                                if [ "$prog" == "build.sh" ]; then
                                    warn_echo "Dapl-devel is not supported on the PPC64 arcitecture"
                                fi
                            ;;
                            *)
                            OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs librdmacm librdmacm-devel dapl dapl-devel" | tr -s ' ' '\n' | sort -n | uniq)
                            ;;
                        esac
                    ;;
                    oiscsi_iser)
                        # Add oiscsi-iser package only if ISER can be installed
                        if (echo -n ${SELECTED_PACKAGES} | grep -w "ib_iser" > $NULL); then
                            EXTRA_PACKAGES=$(echo "$EXTRA_PACKAGES oiscsi-iser" | tr -s ' ' '\n' | sort -rn | uniq)
                        fi
                    ;;
                    mpi_osu)
                            # Set compilation environment for OSU MPI                                    
                            if ! set_mpi_env mpi_osu; then
                                warn_echo "OSU MPI cannot be installed"
                                sed -i -e 's/mpi_osu=y/mpi_osu=n/g' $CONFIG
                                export mpi_osu=n
                            else                                 
                                EXTRA_PACKAGES=$(echo "$EXTRA_PACKAGES mpi_osu" | tr -s ' ' '\n' | sort -rn | uniq)
                                OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs libibverbs-devel" | tr -s ' ' '\n' | sort -n | uniq)
                            fi   
                    ;;
                    openmpi)
                            # Set compilation environment for Open MPI
                            if ! set_mpi_env openmpi; then
                                warn_echo "Open MPI cannot be installed"
                                sed -i -e 's/openmpi=y/openmpi=n/g' $CONFIG
                                export openmpi=n
                            else                                     
                                EXTRA_PACKAGES=$(echo "$EXTRA_PACKAGES openmpi" | tr -s ' ' '\n' | sort -rn | uniq)
                                OPENIB_PACKAGES=$(echo "$OPENIB_PACKAGES libibverbs libibverbs-devel" | tr -s ' ' '\n' | sort -n | uniq)
                            fi

                    ;;
                    mpitests)
                        if (echo -n ${SELECTED_PACKAGES} | grep -Ew "mpi_osu|openmpi" > $NULL 2>&1); then
                            EXTRA_PACKAGES=$(echo "$EXTRA_PACKAGES mpitests" | tr -s ' ' '\n' | sort -rn | uniq)
                        fi
                    ;;
                    pdsh)
                        warn_echo "PDSH is not included in the OFED release"
                        # EXTRA_PACKAGES=$(echo "$EXTRA_PACKAGES pdsh" | tr -s ' ' '\n' | sort -rn | uniq)
                    ;;
                    ofed_docs)
                        EXTRA_PACKAGES=$(echo "$EXTRA_PACKAGES ofed-docs" | tr -s ' ' '\n' | sort -rn | uniq)
                    ;;
                    ofed_scripts)
                        EXTRA_PACKAGES=$(echo "$EXTRA_PACKAGES ofed-scripts" | tr -s ' ' '\n' | sort -rn | uniq)
                    ;;
                    *) 
                        err_echo "Unknown package ${package}. Fix the ${CONFIG} file."
                        exit 1
                    ;;
                esac
        done

        EXTRA_PACKAGES=$(echo -n $EXTRA_PACKAGES | tr -s '\n' ' ')
	
        # Build the EXTRA_PACKAGES list from scratch following interpackage dependencies
        # in ALL_PACKAGES which has in the right order
        tmp_EXTRA_PACKAGES=""
        for pack in ${ALL_PACKAGES}
        do
            if ( echo -n ${EXTRA_PACKAGES} | grep -w ${pack} > $NULL 2>&1 ); then
                tmp_EXTRA_PACKAGES="${tmp_EXTRA_PACKAGES} ${pack}"
            fi
        done

        EXTRA_PACKAGES="${tmp_EXTRA_PACKAGES}"
	
        OPENIB_PACKAGES=$(echo -n $OPENIB_PACKAGES | tr -s '\n' ' ')
        OPENIB_KERNEL_PACKAGES=$(echo -n $OPENIB_KERNEL_PACKAGES | tr -s '\n' ' ')
        
        # SELECTED_PACKAGES="$OPENIB_PACKAGES $EXTRA_PACKAGES"
        if [ $INTERACTIVE -eq 1 ]; then
            echo
            pass_echo "Following is the list of ${PACKAGE} packages that you have chosen 
            (some may have been added by the installation program due to package dependencies):"
            echo "$OPENIB_KERNEL_PACKAGES $OPENIB_PACKAGES $EXTRA_PACKAGES" | tr -s ' ' '\n'
        fi    

}



# Checking dependencies for selected packages
check_build_dependencies()
{
        echo
        echo "Checking dependencies. Please wait ..."
        echo

        # Check if kernel sources exists (needed for packages compilation)
        if [ ! -d ${K_SRC} ] || [ ! -f ${K_SRC}/Makefile ]; then
            echo
            err_echo "There are no sources for the ${K_VER} kernel installed.
                       Please install ${K_VER} kernel sources to build RPMs on this system"
            echo
            exit 1
        fi
        
        
        # Check dependencies and print Warning messages
        local req_status=0

        touch ${rpms_cache}

        $RPM -qa > ${rpms_cache} 2>&1
        $RPM -qa --provides >> ${rpms_cache} 2>&1

        for package in $OPENIB_PACKAGES $EXTRA_PACKAGES
        do
            package_var=$(echo -n ${package} | sed -e 's/-/_/g')
            check_build_req $package_var err
            let req_status=$req_status+$?
        done

        # Exit if there is missing required software for mandatory packages
        if [ $req_status -gt 0 ]; then
#           getch
           exit 7
        fi   

}

check_run_dependencies()
{
        # Check dependencies and print Warning messages
        local req_status=0
        
        touch ${rpms_cache}

        $RPM -qa > ${rpms_cache} 2>&1
        $RPM -qa --provides >> ${rpms_cache} 2>&1

        for package in $OPENIB_PACKAGES $EXTRA_PACKAGES
        do
                package_var=$(echo -n ${package} | sed -e 's/-/_/g')
                check_run_req $package_var err
                let req_status=$req_status+$?
        done
        
        # Exit if there is missing required software for mandatory packages
        if [ $req_status -gt 0 ]; then
           exit 7
        fi   
}
 
include_ifcfg()
{
    if ( echo "$OPENIB_KERNEL_PACKAGES" | grep ipoib > $NULL 2>&1 ); then
        read -p "Do you want to include IPoIB configuration files (ifcfg-ib*)? [Y/n]:" ans_ip
        if ! [[ "$ans_ip" == "" || "$ans_ip" == "y" || "$ans_ip" == "Y" || "$ans_ip" == "yes" ]]; then
            export OPENIB_PARAMS="$OPENIB_PARAMS --without-ipoibconf"
            export INCLUDE_IFCFG=0
        fi
    fi
}
