#!/bin/sh
# +--------------------------------------------------------------------------+
# | Copyright 1993 - 2002 Rational Software Corporation. All Rights Reserved.|
# | This software contains proprietary and confidential information of       |
# | Rational and its suppliers. Use, disclosure or reproduction is           |
# | prohibited without the prior express written consent of Rational.        |
# +--------------------------------------------------------------------------+
#
#@(#)$Revision: 1.78 $  $Date: 03/14/2002 12:47:10 $
#**************************************************************************
#SOHT
#
#NAME
#     uninstall - Rational Software's UNIX uninstall utility.
#
#SYNOPSIS
#     uninstall [<options>] [<product> <version>]
#
#DESCRIPTION
#
#     Uninstall products in the 'rational_dir'.
#     Looks for product releases under the 'releases' directory.
#     Looks for any subsystem views and cots products under base.
#     Asks you if you want to uninstall them.
#
#     You need to be in the 'rational_dir' directory where config,
#     releases and base are located.
#
#OPTIONS
#     -help  (alias: -h)
#          Show this usage message.
#
#     -arch <arch>  (alias: -a)
#          Use the -arch option if you wish to uninstall only <arch>
#          directories and views.
#
#     -force  (alias: -f)
#          Use this option to run uninstall even if you are not the
#          original installer.  Note that if you are not the original
#          installer you will not be able to uninstall a product. This
#          option should only be used if you think uninstall is incorrect
#          in determining your ownership of the product.
#
#     -license  (alias: -l)
#          Use this option to uninstall licenses.  This uninstall program
#          will check the config directory for any license files and prompt
#          you for the license file to remove.  Before removing the file,
#          this command will stop the corresponding license server.
#          The FLEXlm distribution under base/cots will also be uninstalled.
#          You have the option of removing all FLEXlm distributions, a
#          specific version (if more than one installed) or a specific
#          version and platform (if more than one installed).
#
#EOHT
#**************************************************************************

FILE=$0
CMD=`basename $0`
TMP=/tmp/$CMD.$$
TMP2=/tmp/$CMD.2.$$
ARCHS="alpha_osf1 hppa_hpux hp_ux10 hp_ux11 mips_irix5 mips_irix_n32 rs6k rs6k_aix sun4_sunos sun4_solaris2 i386_linux2 ia64_linux2"
alpha_osf1_os="Compaq Tru64"
hp_ux10_os="HP-UX B.10.20"
hp_ux11_os="HP-UX B.11.00"
hppa_hpux_os=HP-UX
ia64_linux2_os="Linux/Intel ia64"
rs6k_os=AIX
rs6k_aix_os=AIX
mips_irix5_os=IRIX
mips_irix_n32_os=IRIX/N32
sun4_sunos_os=SunOS
sun4_solaris2_os=Solaris
i386_linux2_os="Linux/Intel i386"
uninstall_type=product
obs_flexlm_vers="5.0b 5.0 4.1 4.0 3.0b 2.4"
force=false
do_license_uninstall=false
OK_TO_RUN=false
GOT_OTHERS=false
GOT_OTHER_SUITES=false
USER=${USER:-$LOGNAME}
DEFAULT=No
MARK="Remove"
MARKING="Removing"
UNMARK="Spare "
UNMARKING="Sparing "
WS=" 	"
SPACES="                                                                  "
PROD_NAME_IS_SET=false
Revision=Revision
delim="------------------------------------------------------------------------------"
umask 002

#------------------------------------------------------------------------
Usage() {
#------------------------------------------------------------------------
# Extract the text between #SOHT and #EOHT in this script
 
    if [ $1 = 0 ]
    then
        sed -e '1,/^#SOHT/d' -e '/^#EOHT/,$d' -e 's/^#//' $FILE | more
    else
        echo "Run '$CMD -help' for usage information."
    fi
    exit $1
}

#------------------------------------------------------------------------
pause() {
#------------------------------------------------------------------------

    echo
    $ECHON "Press return to continue: $NOCR"
    read cr
}

#------------------------------------------------------------------------
cleanup() {
#------------------------------------------------------------------------

    /bin/rm -f $TMP $TMP2
    exit $?
}

#------------------------------------------------------------------------
ui_banner() {
#------------------------------------------------------------------------

    xx=
    clear
    echo "$Title"
    echo "$delim"
}

#------------------------------------------------------------------------
display_important() {
#------------------------------------------------------------------------

   echo "
   =================         =================         =================
   I M P O R T A N T         I M P O R T A N T         I M P O R T A N T
   =================         =================         ================="
}

#------------------------------------------------------------------------
get_owner() {
#------------------------------------------------------------------------

    /bin/ls -ld $1 | awk '{print $3}'
}

#------------------------------------------------------------------------
get_result() {
#------------------------------------------------------------------------

    result=
    read input
    input=`echo "$input" | sed -e "s?,? ?g"`
    for str in $input
    do
        case "$str" in
            [1-9]*-[1-9]* )
                set -- `echo "$str" | sed -e "s?-? ?"`
                b=$1
                end=$2
                if [ $end -gt $N ]
                then
                    echo "Number $end out of range--will use $b-$N."
                    end=$N
                    pause
                fi
                if [ $b -gt $end ]
                then
                    echo "Range '$str' invalid--$b is greater than $end."
                    pause
                    result="$result ignore"
                    continue
                fi
                while [ $b -le $end ]
                do
                    result="$result $b"
                    b=`expr $b + 1`
                done
                ;;
            * )
                if [ -n "$result" ]
                then
                    result="$result $str"
                else
                    result="$str"
                fi
                ;;
        esac
    done
}

#------------------------------------------------------------------------
set_dir() {
#------------------------------------------------------------------------

    DIR=`pwd`
    if [ "`basename $DIR`" = config ]
    then
        OK_TO_RUN=true
    fi
}

#------------------------------------------------------------------------
check_sym_link() {
#------------------------------------------------------------------------

    set -- `basename $dir | sed -e "s?\.? ?"`
    product_n=$1
    rel_product=`/bin/ls -dtr1 releases/$product_n.* 2>/dev/null | tail -1`
    if [ -z "$rel_product" ]
    then
        /bin/rm -f $product_n
        return
    fi

    if [ $sym_link $product_n ]
    then
        set -- `/bin/ls -ld $product_n`
        _args=`expr $# - 1`
        shift $_args
        if [ -d "$1" ]
        then
            link_to=$1
        else
            # Link no longer points a directory--clean up.
            /bin/rm $product_n
            unset link_to
        fi
    else
        return
    fi

    if [ "$rel_product" = "$link_to"  -o  $product_n = rose ]
    then
        return
    fi

    /bin/rm -f $product_n
    if /bin/ln -s $rel_product $product_n
    then
        echo
        echo "NOTE: The link '$product_n' has been created to point to the latest release:"
        ls -ld $product_n | sed -e "s?.* $product_n ?      $product_n ?"
    fi
}

#------------------------------------------------------------------------
not_owner_of() {
#------------------------------------------------------------------------

    if $force
    then
        return 1
    fi

    owner=`get_owner $1`
    if [ "$owner" = $USER ]
    then
        # USER is the owner of the directory.
        return 1
    fi
    return 0
}

#------------------------------------------------------------------------
other_suites_using_prod() {
#------------------------------------------------------------------------

    if $GOT_OTHER_SUITES
    then
        :
    else
        other_suites=`/bin/ls releases/*/extras/install_data/suite_list 2>/dev/null | grep -v /$product.$version/`
        GOT_OTHER_SUITES=true
    fi

    if [ -z "$other_suites" ]
    then
        # No other suite lists to check.
        return 1
    fi

    if other_suite_list=`grep -l $1 $other_suites`
    then
        return 0
    fi
    return 1
}

#------------------------------------------------------------------------
other_releases_using_base() {
#------------------------------------------------------------------------

    if $GOT_OTHERS
    then
        :
    else
        others=`/bin/ls releases/*/install/*/base_components* \
                        releases/*/install/share/alt_components 2>/dev/null |
                grep -v /$product.$version/`
        GOT_OTHERS=true
    fi

    if [ -z "$others" ]
    then
        # No other base_component files to check.
        return 1
    fi

    if grep $1 $others >/dev/null
    then
        return 0
    fi
    return 1
}

#------------------------------------------------------------------------
check_installed() {
#------------------------------------------------------------------------

    if [ -z "$2" ]
    then
        return
    fi
 
    cmp_root=$1
    shift
    comps="$*"

    Other_Suites="Other products are using these products--will not uninstall:"
    for dir in $comps
    do
        if [ ! -r $dir ]
        then
            continue
        fi

        if [ $cmp_root = base ]
        then
            if other_releases_using_base $dir
            then
                # Other releases are using dir
                continue
            fi
        elif [ $cmp_root = suite ]
        then
            if other_suites_using_prod $dir
            then
                if [ -n "$Other_Suites" ]
                then
                    echo "$Other_Suites"
                    unset Other_Suites
                fi
                echo "   $dir"
                for other_suite in $other_suite_list
                do
                    other_suite=`echo $other_suite |
                        sed -e "s?releases/??" -e "s?/.*??"`
                    echo "      (In use by $other_suite)"
                done
                continue
            fi
        fi

        if not_owner_of $dir
        then
            echo "
Warning: You ($USER) are not the owner of $dir.
         You must run this command as $owner,
         since $owner installed $product $version.

         If you think that the $CMD command is incorrect
         and you are the owner, you can override this check
         by running this command with the -force option.
         "
            cleanup 1
        fi

        N=`expr $N + 1`
        eval dir_$N=$dir
        eval dir_rm_$N=\"$SPEC\"
    done

    if [ -z "$Other_Suites" ]
    then
        echo
    fi
}

#------------------------------------------------------------------------
check_common_bins() {
#------------------------------------------------------------------------

    for extras in releases/*/extras
    do
        test -d $extras || continue
        suite_release=`dirname $extras`
        test -x $suite_release/bin_setup || continue
        for common_bin in $suite_release/*/bin
        do
            case $common_bin in
            */extras/bin ) continue ;;
            esac
            test -d $common_bin || continue
            if /bin/ls -l $common_bin | grep "$release" >/dev/null
            then
                arch_path=`dirname $common_bin`
                the_arch=`basename $arch_path`
                if [ "$the_arch" = "$ARCH" ]
                then
                    (
                    echo "
Need to run the bin_setup command because a common bin directory contains
links to a $ARCH release that was just uninstalled.
"
                    echo "    cd $suite_release"
                    cd $suite_release
                    echo "    ./bin_setup"
                    ./bin_setup
                    )
                else
                    display_important
                    echo "
You need to run the bin_setup command on a $the_arch machine
because a common bin directory contains links to a $the_arch release
that was just uninstalled:

    rlogin \"${the_arch}-machine\"
    cd `pwd`/$suite_release
    ./bin_setup
"
                    pause
                fi
            fi
        done
    done
}

#------------------------------------------------------------------------
check_startup() {
#------------------------------------------------------------------------

    # Show any other products in this products startup file that might
    # be uninstalled.
    if [ -f config/$product.$version.startup ]
    then
        (cat config/$product.$version.startup; echo END) |
        while read _prod_ver _loc _misc
        do
            if [ "$_prod_ver" = END ]
            then
                echo "$_mesg"
                echo "$_prod_list"
                break
            fi

            if [ "$_prod_ver" = "$product.$version" ]
            then
                continue
            fi

            if [ -d "$_loc" ]
            then
                if [ -z "$_mesg" ]
                then
                    _prod_list="          $_prod_ver"
                    echo
                    echo "NOTE: $product.$version uses other products."
                   _mesg="      If you are going to uninstall $product.$version, you should probably
      uninstall these products too:"
                else
                    _prod_list="$_prod_list
          $_prod_ver"
                fi
            fi
        done
    fi
}

#------------------------------------------------------------------------
uninstall_commands() {
#------------------------------------------------------------------------

    if [ "$product" = rose ]
    then
        if [ -x $release/bin/clearcase.sh ] 
        then
            (
            cd $release
            bin/clearcase.sh uninstall -modelint_setup
            )
        fi
    fi

    if [ -x $release/install/uninstall.$product ]
    then
        (
        cd $release
        install/uninstall.$product
        )
    fi
}

#------------------------------------------------------------------------
uninstall_configs() {
#------------------------------------------------------------------------

    configs=base/ada/configs
    if [ ! -d $configs ]
    then
        return
    fi

    if [ -n "$only_arch" ]
    then
        /bin/rm -f $configs/$product*$only_arch*$version.cfg
    else
        /bin/rm -f $configs/$product.*.$version.cfg
    fi

    while rmdir $configs 2>/dev/null
    do
        configs=`dirname $configs`
        if [ -z "$configs" -o "$configs" = '.' ]
        then
            break
        fi
    done
}

#------------------------------------------------------------------------
uninstall_ss() {
#------------------------------------------------------------------------
# Remove subsystem if the only thing in it is 
# .Rational, .Rational_Location and Policy.

    case $parent_dir in
        *.ss ) ;;
        * ) return 1 ;;
    esac

    for _file in `ls -A $parent_dir`
    do
        case $_file in
            .Rational|.Rational_Location|Policy ) ;;
            * ) return 1 ;;
        esac
    done

    $ECHON "  $MARKING empty `basename $parent_dir` subsystem...$NOCR"
    (cd $parent_dir; /bin/rm -fr .Rational .Rational_Location Policy)
    return 0
}

#------------------------------------------------------------------------
rm_dir() {
#------------------------------------------------------------------------
# Recursively remove directories if they are empty.
 
    parent_dir=`dirname $1`
    while rmdir $parent_dir 2>/dev/null
    do
        parent_dir=`dirname $parent_dir`
    done

    if uninstall_ss $parent_dir
    then
        if rmdir $parent_dir 2>/dev/null
        then
            echo done.
            rm_dir $parent_dir
        else
            echo could not be removed.
        fi
    fi
}

#------------------------------------------------------------------------
uninstall_dirs() {
#------------------------------------------------------------------------

    n=1
    while [ $n -le $N ]
    do
        eval remove=\"\$dir_rm_$n\"
        eval dir=\$dir_$n
        if [ $remove != "$MARK" ]
        then
            echo "$UNMARKING $n of $N:
  $dir."
            n=`expr $n + 1`
            continue
        fi

        $ECHON "$MARKING $n of $N:
  $dir...$NOCR"
        /bin/rm -fr  $dir 2>/dev/null
        if [ -d $dir ]
        then
            chmod -R +w  $dir 2>/dev/null
            /bin/rm -fr  $dir 2>/dev/null
        fi

        if [ -d $dir ]
        then
            echo could not be removed.
        else
            echo done.
            # Remove empty directories above this one.
            rm_dir $dir
            check_sym_link
        fi
        n=`expr $n + 1`
    done

    if [ -f config/$product.$version.startup ]
    then
        /bin/rm -f config/$product.$version.startup
    fi
}

#------------------------------------------------------------------------
show_dirs_to_remove() {
#------------------------------------------------------------------------

    f=$1
    L=$2
    while [ $f -le $L ]
    do
        eval dir=\$dir_$f
        eval remove=\"\$dir_rm_$f\"

        if [ $f -lt 10 ]
        then
            echo "    $f) $remove $dir"
        elif [ $f -lt 100 ]
        then
            echo "   $f) $remove $dir"
        else
            echo "  $f) $remove $dir"
        fi
        f=`expr $f + 1`
    done
}

#------------------------------------------------------------------------
base_links_cleanup() {
#------------------------------------------------------------------------
# Cleanup obsolete base/lang/keys and base/Links.

    echo
    echo "Checking base keys links--will remove obsolete ones..."
    n_libs=0
    x_libs=0
    for lang in ada c++
    do
        keys=base/$lang/keys
        test -d $keys || continue
        for _link in $keys/*
        do
            if [ $sym_link $_link ]
            then
                n_libs=`expr $n_libs + 1`
                if [ ! -d $_link/. ]
                then
                    x_libs=`expr $x_libs + 1`
                    /bin/rm -f $_link
                fi
            fi
        done
    done
    report_cleanup keys

    if [ ! -d base/Links ]
    then
        return
    fi

    if [ -d $release ]
    then
        return
    fi

    if [ $sym_link base/Links/$product.$version ]
    then
        /bin/rm -f base/Links/$product.$version
    fi
}

#------------------------------------------------------------------------
report_cleanup() {
#------------------------------------------------------------------------
 
    lib_type=$1
    case $lib_type in
    API|ORB* )
         lib_refs="library references"
         lib_ref="library reference"
         ;;
    keys )
         lib_refs="$lang/keys links"
         lib_ref="$lang/keys link"
         ;;
    esac

    if [ $x_libs -gt 0 ]
    then
        echo "Total number of $lib_type  $lib_refs: $n_libs"
        echo "Obsolete $lib_type $lib_refs removed: $x_libs"
    elif [ $n_libs -gt 1 ]
    then
        echo "The $n_libs $lib_type $lib_refs are okay."
    elif [ $n_libs -eq 1 ]
    then
        echo "The 1 $lib_type $lib_ref is okay."
    else
        echo "There are no $lib_type $lib_refs."
    fi
    echo
}

#------------------------------------------------------------------------
api_lib_cleanup() {
#------------------------------------------------------------------------

    api_lib=base/api/lib
    if [ ! -d $api_lib ]
    then
        return
    fi

    echo
    echo "Checking API library references--will remove obsolete ones..."
    n_libs=0
    x_libs=0
    unset show_mesg
    for lib in $api_lib/*/*.a
    do
        if [ $sym_link $lib ]
        then
            n_libs=`expr $n_libs + 1`
            if [ ! -f $lib ]
            then
                x_libs=`expr $x_libs + 1`
                if [ -z "$show_mesg" ]
                then
                    echo "$MARKING obsolete lib references:"
                    show_mesg=yes
                fi
                if [ $x_libs -lt 10 ]
                then
                    echo "    $x_libs. $lib"
                else
                    echo "   $x_libs. $lib"
                fi
                /bin/rm -f $lib
            fi
        fi
    done
    report_cleanup API
}

#------------------------------------------------------------------------
orb_lib_cleanup() {
#------------------------------------------------------------------------
# Remove any links to the OIS ORBexpress library that were put in APEX_HOME
# if the library was removed by uninstall.

    echo
    echo "Checking ORBexpress library references--will remove obsolete ones..."

    n_libs=0
    x_libs=0
    unset show_mesg
    for orb_link in releases/apex.*/*/lib/libOISnetada*.a
    do
        if [ $sym_link $orb_link ]
        then
            n_libs=`expr $n_libs + 1`
            if [ ! -f $orb_link ]
            then
                x_libs=`expr $x_libs + 1`
                if [ -z "$show_mesg" ]
                then
                    echo "$MARKING obsolete lib references:"
                    show_mesg=yes
                fi
                if [ $x_libs -lt 10 ]
                then
                    echo "    $x_libs. $orb_link"
                else
                    echo "   $x_libs. $orb_link"
                fi
                /bin/rm -f $orb_link
            fi
        fi
    done
    report_cleanup ORBexpress
}

#------------------------------------------------------------------------
check_install_status_all() {
#------------------------------------------------------------------------
    echo
    echo "Checking the install status of $prod_name..."
    echo

    # B=total base, R=first release, N=Total
    N=0
    if [ "$uninstall_type" = suite ]
    then
        check_installed suite $base_comps
    else
        check_installed base $base_comps
    fi
    B=$N
    if [ "$embedded" = yes ]
    then
        eval Target=\$Target_$prod_n
        base_rel=`dirname $release`
        target_files=`ls -d $base_rel/bin/$Target* \
                            $base_rel/lib/$Target* \
                            $base_rel/lib.src/$Target* \
                            2>/dev/null`
        check_installed release $target_files
        B=$N
    fi
    check_installed release $release
    R=$N
}

#------------------------------------------------------------------------
check_install_status_arch() {
#------------------------------------------------------------------------
    echo
    echo "Checking the install status of $prod_name..."
    echo

    # B=total base, R=first release, N=Total
    N=0
    arch_comps=`echo "$base_comps" | grep $only_arch`
    check_installed base    $arch_comps
    B=$N
    case $only_arch in
    sun4_sunos )
        check_installed release $release/sun4
        ;;
    rs6k* )
        check_installed release $release/rs6k_aix $release/rs6k
        ;;
    * )
        check_installed release $release/$only_arch
        ;;
    esac
    R=$N
}

#------------------------------------------------------------------------
check_install_status_target() {
#------------------------------------------------------------------------
    echo
    echo "Checking the install status of $prod_name..."
    echo

    # B=total base, R=first release, N=Total
    N=0
    arch_comps=`echo "$base_comps" | grep "$only_target"`
    check_installed base    $arch_comps
    B=$N
    case $only_arch in
    sun4_sunos )
        check_installed release $release/sun4
        ;;
    rs6k* )
        check_installed release $release/rs6k $release/rs6k_aix
        ;;
    * )
        check_installed release $release/$only_arch
        ;;
    esac
    R=$N
}

#------------------------------------------------------------------------
set_embedded_name() {
#------------------------------------------------------------------------

    case $p1 in
    lx* )
        embedded_name="LynxOS"
        ;;
    rt*|rx* )
        embedded_name="Rational Exec"
        ;;
    vw* )
        embedded_name="VxWorks"
        ;;
    * )
        embedded_name="$p1"
        return
        ;;
    esac

    case $p1 in
    *ppc )
        embedded_name="$embedded_name/PowerPC"
        Target=power
        ;;
    *mips )
        embedded_name="$embedded_name/MIPS"
        Target=mips
        ;;
    *i386 )
        embedded_name="$embedded_name/Intel/Pentium"
        Target=i386
        ;;
    *m68k )
        embedded_name="$embedded_name/Motorola 68K"
        Target=m68k
        ;;
    *rh32 )
        embedded_name="$embedded_name/rh32"
        Target=rh32
        ;;
    esac
}

#------------------------------------------------------------------------
set_prod_name() {
#------------------------------------------------------------------------

    $PROD_NAME_IS_SET && return

    has_target=no
    embedded=no
    has_ss=no
    case $1 in
    ada_anal*) prod_name="Ada Analyzer" ; has_ss=yes ;;
         axi ) prod_name="Ada X/Interface" ; has_ss=yes ;;
  apex_clear*) prod_name="Rational Apex/Clearcase" ;;
  apex_embed*) prod_name="Rational Apex Embedded"
               embedded=yes ; has_target=yes ; has_ss=yes ;;
      apexlx ) prod_name="Rational Apex for LynxOS"
               embedded=yes ; has_target=yes ; has_ss=yes ;;
      apexrt ) prod_name="Rational Apex for Rational Exec"
               embedded=yes ; has_target=yes ; has_ss=yes ;;
      apexvw ) prod_name="Rational Apex for VxWorks"
               embedded=yes ; has_target=yes ; has_ss=yes ;;
        apex ) prod_name="Rational Apex" ; has_ss=yes ;;
    ClearQuestClient)
               prod_name="Rational ClearQuest Client" ;;
    ClearQuestOracleSupport )
               prod_name="Rational ClearQuest OracleSupport" ;;
     purecov ) prod_name="Rational PureCoverage for UNIX" ;;
      purify ) prod_name="Rational Purify for UNIX" ;;
  PurifyPlus ) prod_name="Rational PurifyPlus for UNIX" ;;
    quantify ) prod_name="Rational Quantify for UNIX" ;;
    rose_cpp ) prod_name="Rational Rose C/C++ for Apex" ;;
    rose_dev ) prod_name="Rational Rose Developer" ;;
    rose_ada ) prod_name="Rational Rose Ada" ;;
        rose ) case "$v" in
               7.1.* )
                   prod_name="Rational Rose 2001 for UNIX"
                   ;;
               7.0.* )
                   prod_name="Rational Rose 2000e for UNIX"
                   ;;
               6.5.* )
                   prod_name="Rational Rose 98i for UNIX"
                   ;;
               * )
                   prod_name="Rational Rose for Unix"
                   ;;
               esac
               ;;
      RoseRT ) prod_name="Rational Rose RealTime" ;;
RUP_ibm|RUP_IBM )
               prod_name="Rational Unified Process (IBM)" ;;
RUP_msft|RUP_MSFT )
               prod_name="Rational Unified Process (Microsoft)" ;;
     RUP_Gen ) prod_name="Rational Unified Process (Generic)" ;;
        RUP* ) prod_name="Rational Unified Process (classic)" ;;
    SiteLoad ) prod_name="Rational SiteLoad" ;;
        soda ) prod_name="Rational SoDA" ;;
    testmate ) prod_name="Rational TestMate" ; has_ss=yes ;;
TestRealTime ) prod_name="Rational Test RealTime" ;;
   DevelopmentStudioUNIXRT )
               prod_name="Rational Suite DevelopmentStudio RealTime for UNIX" ;;
   DevelopmentStudioUNIX )
               prod_name="Rational Suite DevelopmentStudio for UNIX" ;;
           * ) prod_name="$1" ;;
    esac
}

#------------------------------------------------------------------------
set_Title() {
#------------------------------------------------------------------------

    set_prod_name $product
    if [ -n "$only_arch" ]
    then
        eval OS=\$${only_arch}_os
        prod_name="$prod_name $version for $OS"
    elif [ -n "$only_target" ]
    then
        prod_name="$prod_name $version ($only_target target only)"
    else
        if $PROD_NAME_IS_SET
        then
            :
        else
            prod_name="$prod_name $version"
        fi
    fi

    if [ `echo "$prod_name" | wc -c` -gt 42 ]
    then
        Title=`echo "Rational Uninstall: $SPACES" | cut -c1-63`
        Title="$Title $Revision: 1.78 $xx
$prod_name"
    else
        Title=`echo "Rational Uninstall: ${prod_name}$SPACES" | cut -c1-63`
        Title="$Title $Revision: 1.78 $xx"
    fi
}

#------------------------------------------------------------------------
list_archs() {
#------------------------------------------------------------------------

    an=0
    a_list=
    for arch in $ARCHS
    do
        case $arch in
        sun4_sunos )
            _dir=$release/sun4/bin
            ;;
        rs6k* )
            _dir=$release/rs6k/bin
            test -d $_dir || _dir=$release/rs6k_aix/bin
            ;;
        * )
            _dir=$release/$arch/bin
            ;;
        esac

        if [ -d $_dir ]
        then
            an=`expr $an + 1`
            if [ $an -eq 1 ]
            then
                echo
                echo "Here is the list of $prod_name architectures to uninstall:"
                echo
            fi

            eval OS=\$${arch}_os
            eval aos_$an=$arch
            echo "    $an) $arch  ($OS)"
            a_list="$a_list $an,"
        fi
    done

    if [ $an -eq 0 ]
    then
        return
    fi

    echo "    a) all"
    a_list="$a_list or a"

    if [ $an -eq 1 ]
    then
        an_range="1,a"
    else
        an_range="1..$an,a"
    fi
}

#------------------------------------------------------------------------
select_arch_to_uninstall() {
#------------------------------------------------------------------------

    list_archs
    if [ $an -eq 0 ]
    then
        echo
        echo There are no architecture specific directories to uninstall.
        pause
        return
    fi

    while true
    do
        echo
        $ECHON "Enter one architecture (O/S) number to uninstall ($an_range): $NOCR"
        get_result
        case $result in
        a|A )
            if [ -n "$only_arch" ]
            then
                unset only_arch
                set_Title
                check_install_status_all
            fi
            break
            ;;
        [1-9]* )
            eval arch=\$aos_$result
            if [ -n "$arch" ]
            then
                if [ "$only_arch" != "$arch" ]
                then
                    only_arch=$arch
                    set_Title
                    check_install_status_arch
                    break
                fi
            fi
            ;;
        esac
        echo "'$result' must be one of:$a_list"
    done
}

#------------------------------------------------------------------------
list_targets() {
#------------------------------------------------------------------------

    tn=0
    t_list=
    for comp_file in $comp_files
    do
        target=`basename $comp_file | sed -e 's?base_components\.??'`
        tn=`expr $tn + 1`
        if [ $tn -eq 1 ]
        then
            echo
            echo "Here is the list of $prod_name targets to uninstall:"
            echo
        fi

        eval target_$tn=$target
        echo "    $tn) $target"
        t_list="$t_list $tn,"
    done

    if [ $tn -eq 0 ]
    then
        return
    fi

    echo "    t) all targets"
    t_list="$t_list or t"

    if [ $tn -eq 1 ]
    then
        tn_range="1,t"
    else
        tn_range="1..$tn,t"
    fi
}

#------------------------------------------------------------------------
select_target_to_uninstall() {
#------------------------------------------------------------------------

    list_targets
    if [ $tn -eq 0 ]
    then
        echo
        echo There are no target specific directories or views to uninstall.
        pause
        return
    fi

    while true
    do
        echo
        $ECHON "Enter one target number to uninstall ($tn_range): $NOCR"
        get_result
        case $result in
        t|T )
            if [ -n "$only_target" ]
            then
                unset only_target
                set_Title
                check_install_status_all
            fi
            break
            ;;
        [1-9]* )
            eval target=\$target_$result
            if [ -n "$target" ]
            then
                if [ "$only_target" != "$target" ]
                then
                    only_target=$target
                    set_Title
                    check_install_status_target
                    break
                fi
            fi
            ;;
        esac
        echo "'$result' must be one of:$t_list"
    done
}

#------------------------------------------------------------------------
sort_suite_list() {
#------------------------------------------------------------------------
# Have the releases show up first, then the stuff in base.

    grep /releases/ $Suite_List |
      grep -v $release |
        sed -e 's?.*/releases/?releases/?'

    grep /base/ $Suite_List |
      sed -e 's?.*/base/?base/?'
}

#------------------------------------------------------------------------
uninstall_license() {
#------------------------------------------------------------------------

    n=0
    unset dat_list
    for dat in $DIR/config/*.dat
    do
        test -s $dat || continue
        if grep "[$WS]rational[$WS]" $dat >/dev/null 2>&1
        then
            n=`expr $n + 1`
            eval dat$n=$dat
            if [ $n -gt 9 ]
            then
                dat_list="$dat_list
   $n) $dat"
            else
                dat_list="$dat_list
    $n) $dat"
            fi
        fi
    done

    case $n in
    0 )
        echo "There are no license files in $DIR/config."
        return
        ;;
    1 )
        echo "Found one license file:"
        echo "  $dat1"
        echo
        $ECHON "Uninstall this license file? [no] $NOCR"
        read rm_license
        case $rm_license in
        y*|Y* )
            dat=$dat1
            ;;
        * )
            return 0
            ;;
        esac
        ;;
    * )
        echo "
Found $n license files.  Select one license from the list to uninstall:
$dat_list
   No) Do not uninstall any licenses.
"
        while true
        do
            echo
            $ECHON "Enter number from 1 to $n or [No]: $NOCR"
            read rm_license in
            case $rm_license in
            ""|N*|n* )
                return 0
                ;;
            [1-9]|[1-9][0-9] )
                if [ "$rm_license" -gt 0 -a "$rm_license" -le $n ]
                then
                    eval dat=\$dat$rm_license
                    test -n "$dat" && break
                fi
                ;;
            esac
            echo "Please enter a number from 1 to $n or No."
        done
        ;;
    esac

    if [ "$ARCH" = rs6k_aix ]
    then
        END="base/cots/flexlm.*/rs6k END"
    else
        END=END
    fi

    for FLEXlm in base/cots/flexlm.*/$ARCH $END
    do
        if [ "$FLEXlm" = END ]
        then
            echo "
Cannot stop server.  No FLEXlm for $ARCH installed under base/cots."
            return 1
        fi
        test -d $FLEXlm && break
    done

    echo "Stopping license server, if running..."
    echo "$FLEXlm/lmdown -q \\"
    echo "  -c $dat"
    if $FLEXlm/lmdown -q -c $dat
    then
        echo "License server shutdown completed successfully."
    fi

    $ECHON "$MARKING $dat...$NOCR"
    /bin/rm -fr $dat
    if [ -f $dat ]
    then
        echo could not be removed.
    else
        echo done.
    fi

    n=0
    v=0
    unset flex_dirs flex_list arch_list ver_list
    for flex in base/cots/flexlm.*
    do
        flex_dirs="$flex_dirs $flex/* $flex"
    done

    for flex in $flex_dirs
    do
        test -d $flex || continue
        n=`expr $n + 1`
        case $flex in
        */flexlm.*/* )
            arch_list="$arch_list $n"
            ;;
        * )
            v=`expr $v + 1`
            ver_list="$ver_list $flex"
            ;;
        esac

        eval flex$n=$flex
        if [ $n -gt 9 ]
        then
            flex_list="$flex_list
   $n) $flex"
        else
            flex_list="$flex_list
    $n) $flex"
        fi
    done

    case $n in
    0 )
        echo "There are no FLEXlm distributions under base/cots."
        return 0
        ;;
    1 )
        echo "Found one FLEXlm distribution directory:"
        echo "  $flex1"
        echo
        $ECHON "Uninstall this directory? [no] $NOCR"
        read rm_flex
        case $rm_flex in
        y*|Y* )
            flex=$flex1
            ;;
        * )
            return 0
            ;;
        esac
        ;;
    * )
        if [ "$v" -gt 1 ]
        then
            n=`expr $n + 1`
            if [ $n -gt 9 ]
            then
                flex_list="$flex_list
   $n) Uninstall all FLEXlm directories listed above."
            else
                flex_list="$flex_list
    $n) Uninstall all FLEXlm directories listed above."
            fi
        fi

        echo "
Found $n FLEXlm distribution directories.  Select one directory from the list
to uninstall:
$flex_list
   No) Do not uninstall any FLEXlm distribution directories.
"
        while true
        do
            echo
            $ECHON "Enter number from 1 to $n or [No]: $NOCR"
            read rm_flex in
            case $rm_flex in
            ""|N*|n* )
                return 0
                ;;
            [1-9]|[1-9][0-9] )
                if [ "$rm_flex" -eq $n ]
                then
                    flex=$ver_list
                    break
                fi

                if [ "$rm_flex" -gt 0 -a "$rm_flex" -le $n ]
                then
                    eval flex=\$flex$rm_flex
                    test -n "$flex" && break
                fi
                ;;
            esac
            echo "Please enter a number from 1 to $n or No."
        done
        ;;
    esac

    status=0
    for dir in $flex
    do
        $ECHON "$MARKING $dir...$NOCR"
        /bin/rm -fr $dir
        if [ -d $dir ]
        then
            echo could not be removed.
            status=1
        else
            echo done.
        fi
    done
    return $status
}

#------------------------------------------------------------------------
# Main
#------------------------------------------------------------------------

while [ $# -gt 0 ]
do
    case "$1" in
    -a|-arch )
        only_arch=$2
        shift
        ;;
    -f|-force )
        force=true
        ;;
    -h|-help )
        Usage 0
        ;;
    -l|-license )
        do_license_uninstall=true
        ;;
    -* )
        echo "$CMD: Option '$1' not recognized."
        Usage 1
        ;;
    * )
        break
        ;;
    esac
    shift
done

args=$#
product=$1
version=$2

# Determine which echo command to use.
if echo "look for \c" | grep c >/dev/null
then
    ECHON="echo -n"
    NOCR=
else
    ECHON=echo
    NOCR='\c'
fi

# Run the script located in the config directory only.
# Run the script from the parent directory of the config dir.
DIR=`dirname $0`
SYS=`uname -s`
REL=`uname -r`
sym_link='-h'

case ${SYS}$REL in
AIX* )
    ARCH=rs6k_aix
    sym_link='-L'
    ;;
 
SunOS4.* )
    ARCH=sun4
    ;;

SunOS5.* )
    ARCH=sun4_solaris2
    ;;
 
OSF1* )
    ARCH=alpha_osf1
    sym_link='-L'
    ;;
 
IRIX*[6789].* )
    ARCH=`uname -p`_irix5
    ;;

IRIX* )
    ARCH=`uname -p`_irix5
    ;;
 
HP-UX*A.09.* )
    ARCH=hppa_hpux
    ;;

HP-UX*B.1?.* )
    ARCH=hppa_hpux
    ;;
Linux*2.*)
    sym_link='-L'
    MACH=`uname -m`
    case $MACH in
    i[3456]86 )
        ARCH=i386_linux2
        ;;
    ia64 )
        ARCH=ia64_linux2
        ;;
    esac
esac

# Visit the directory where this script exists.
cd $DIR
set_dir

# Search up the directory path looking for the 'releases' dir.
while [ ! -d releases ]
do
    if [ "$DIR" = '/' ]
    then
        echo
        echo
        echo "Error: The 'releases' directory could not be found."
        Usage 1
    else
        cd ..
        set_dir
    fi
done

if [ $OK_TO_RUN = false ]
then
    if [ -x $DIR/config/$CMD ]
    then
        $DIR/config/$CMD $*
        exit $?
    fi

    if [ -f $DIR/config/$CMD ]
    then 
        echo "$DIR/config/$CMD not executeable."
    else
        echo "$DIR/config/$CMD not found."
    fi
    exit 1
fi

if $do_license_uninstall
then
    uninstall_license
    exit $?
fi

trap 'cleanup 0' 0
trap 'cleanup 1' 0 1 2 3 4 15

if [ -z "$product" ]
then
    n=0
    /bin/ls releases 2>/dev/null | sed -e "s?\.? ?" |
    while read p v
    do
        if [ -z "$v" ]
        then
            continue
        fi
        case "$p" in
        *-* )
            case "$v" in
            *-* )
                set -- `echo $p.$v | sed -e 's?-? ?g'`
                p=$1
                v=$2.$3
                ;;
            esac
            ;;
        esac
        set_prod_name $p
        if [ "$embedded" = yes ]
        then
            primary_name="$prod_name"
            t=0
            /bin/rm -f $TMP.3
            /bin/ls releases/$p.$v 2>/dev/null |
            sed -e "s?\.? ?" |
            while read p1 v1
            do
                test -d releases/$p.$v/$p1.$v1/install || continue
                set_embedded_name
                prod_name="$primary_name $v ($embedded_name $v1)"
                n=`expr $n + 1`
                echo "n=$n product_$n=$p.$v/$p1 version_$n=$v1
                prod_name_$n='$prod_name' embedded_$n=yes
                Target_$n=$Target" >> $TMP.3
                if [ $n -lt 10 ]
                then
                    echo "    $n) $prod_name" >> $TMP2
                else
                    echo "   $n) $prod_name" >> $TMP2
                fi
            done
            if [ -s $TMP.3 ]
            then
                . $TMP.3
                cat $TMP.3 >> $TMP
                /bin/rm -f $TMP.3
                continue
            fi
        fi
        n=`expr $n + 1`
        prod_name="$prod_name $v"
        if [ -f releases/$p.$v/.prod_name_ver ]
        then
            . releases/$p.$v/.prod_name_ver
            prod_name=${prod_name_ver:-$prod_name}
        fi
        if [ $n -lt 10 ]
        then
            echo "    $n) $prod_name" >> $TMP2
        else
            echo "   $n) $prod_name" >> $TMP2
        fi
        echo "n=$n product_$n=$p version_$n=$v
        prod_name_$n='$prod_name' embedded_$n=no" >> $TMP
    done

    if [ ! -s $TMP ]
    then
        Usage 0
    fi

    . $TMP
    if [ $n -eq 1 ]
    then
        product=$product_1
        version=$version_1
        prod_name="$prod_name_1"
    else
        while true
        do
            echo
            echo "These products appear to be installed."
            echo "Select a product by number to uninstall it:"
            echo
            cat $TMP2
            echo "    q) Quit $CMD."
            echo
            $ECHON "Enter product number (1 to $n) or [q]: $NOCR"
            read result
            set -- $result
            if [ $# -gt 1 ]
            then
                echo "
You must only select one product at a time.  Do not enter more than one number.
Enter a single number (1 to $n) corresponding to the product to uninstall."
                continue
            fi

            case $result in
            ""|*q*|*Q* )
                cleanup 0
                ;;
            [0-9]*-[0-9]* )
                echo "
You must only select one product at a time.  Do not enter a range.
Enter a single number (1 to $n) corresponding to the product to uninstall."
                continue
                ;;
            [0-9]* )
                if [ "$result" -gt 0 -a "$result" -le "$n" ]
                then
                    eval product=\$product_$result
                    if [ -n "$product" ]
                    then
                        prod_n=$result
                        eval version=\$version_$result
                        eval prod_name=\"\$prod_name_$result\"
                        eval embedded=\"\$embedded_$result\"
                        PROD_NAME_IS_SET=true
                        break
                    fi
                fi
                ;;
            esac
            echo "You must enter a number from 1 to $n."
        done
    fi
fi

if [ -z "$product"  -o -z "$version" ]
then
    Usage 0
fi

set_Title
release=releases/$product.$version
install_dir=$release/install
if [ "$embedded" = yes ]
then
    # Check if there is more than one install directory.
    # If so, keep the releases directory as is,
    # otherwise, the releases directory is the parent
    # directory.
    parent_dir=`dirname $release`
    set -- 1 `/bin/ls -d $parent_dir/*/install`
    if [ $# -le 2 ]
    then
        release=$parent_dir
    fi
fi

echo
if [ "$has_ss" = yes ]
then
    echo "
You are about to uninstall $prod_name and any base
subsystem libraries that were installed with it.  Before
doing so, make sure that all subsystem views that are still
under development get upgraded to use the new release.  The
apex_upgrade script describes how to do this.  Just enter
the command without specifying any parameters.  You need to
be in the new Apex environment when you run apex_upgrade."

else
    echo
    echo "You are about to uninstall $prod_name."
fi

SPEC="$MARK"
Suite_List=$release/extras/install_data/suite_list
if [ -f $Suite_List ]
then
    uninstall_type=suite
    base_comps=`sort_suite_list`
else
    comp_files=`ls $install_dir/*/base_components* \
                   $install_dir/*/alt_components \
                   2>/dev/null`
    if [ -n "$comp_files" ]
    then
        base_comps=`sort -u $comp_files`
    elif [ -f $install_dir/base_components ]
    then
        comp_files=$install_dir/base_components
        base_comps=`cat $comp_files`
    else
        base_comps=`/bin/ls -d1 base/*/*.ss/*.$version.rel 2>/dev/null`
    fi
fi

if [ -n "$only_arch" ]
then
    check_install_status_arch
else
    check_install_status_all
fi

# If there are HTML docs for this release,
# will need to run make_menus_links command to
# clean up the Apex release.
update_doc_links=no
if [ -d $release/doc/html  -a  \
     -f $release/.apex_home -a \
     -x config/make_menus_links ]
then
    apex_home=`cat $release/.apex_home`
    if [ -d "$apex_home" ]
    then
        update_doc_links=yes
        run_make_menus_links="config/make_menus_links $apex_home"
    fi
fi

if [ $N -eq 0 ]
then
    echo "Nothing to uninstall"
    cleanup 0
fi

$ECHON "Press return to view the directories to be uninstalled: $NOCR"
read cr

DIR_LIST=
while true
do
    ui_banner
    show_dirs_to_remove  1  $B
    show_dirs_to_remove $R  $N
    echo

    if [ "$uninstall_type" = product ]
    then
    if [ -n "$only_arch" ]
    then
        echo "    a) Specify architecture to uninstall ($OS only)."
    else
        echo "    a) Specify architecture to uninstall."
    fi
    fi

    if [ "$has_target" = yes ]
    then
        t_opt="t, "
        echo "    t) Specify a target to uninstall."
    else
        t_opt=""
    fi
    if [ $R -eq $N ]
    then
        echo "    e) Expand listing of $release."
    else
        echo "    e) Elide  listing of $release."
    fi
    echo "    U) Uninstall the directories marked '$MARK' now."
    echo "   $DEFAULT) do not uninstall. Quit $CMD."

    case $N in
    1 )
        range=1
        a_list_or_range=1
        ;;
    2 )
        range="1, 2"
        a_list_or_range="a list (eg. 1 2)"
        ;;
    3 )
        range="1, 2, 3"
        a_list_or_range="a list (eg. 1 2) or a range of numbers (eg. 1-$N)"
        ;;
    * )
        range="1-$N"
        a_list_or_range="a list (eg. 1 2) or a range of numbers (eg. 1-4)"
        ;;
    esac

    echo
    echo "Enter $a_list_or_range to toggle $MARK/$UNMARK."
    echo
    if [ "$uninstall_type" = product ]
    then
        choice="$range, a, ${t_opt}e, U or $DEFAULT."
        $ECHON "Enter 1-$N, a, ${t_opt}e, U or [$DEFAULT]: $NOCR"
    else
        choice="$range, ${t_opt}e, U or $DEFAULT."
        $ECHON "Enter 1-$N, ${t_opt}e, U or [$DEFAULT]: $NOCR"
    fi

    get_result
    for n in ${result:-$DEFAULT}
    do
        case "$n" in
            [1-9]* )
                if [ $n -gt 0  -a  $n -le $N ]
                then
                    eval remove=\$dir_rm_$n
                    if [ "$remove" = "$MARK" ]
                    then
                        eval dir_rm_$n=\"$UNMARK\"
                    else
                        eval dir_rm_$n=\"$MARK\"
                    fi
                else
                    echo "Choice '$n' not valid. You must enter $choice"
                    pause
                fi
                ;;
            ignore )
                ;;
            n*|N*|*q*|*Q* )
                cleanup 0
                ;;
            a|A )
                select_arch_to_uninstall
                ;;
            t|T )
                if [ "$has_target" = yes ]
                then
                    select_target_to_uninstall
                else
                    echo "Choice '$n' not valid. You must enter $choice"
                    pause
                fi
                ;;
            e|E )
                if [ $R -eq $N ]
                then
                    # Expand the listing of the release directory.
                    eval SPEC=\$dir_rm_$N
                    SAVE_SPEC="$SPEC"
                    N=$B
                    check_installed release $release/*
                    if [ $N -gt $B ]
                    then
                        R=`expr $B + 1`
                    fi
                else
                    # Elide the listing of the release directory.
                    N=$B
                    R=$B
                    SPEC="$SAVE_SPEC"
                    check_installed release $release
                    R=$N
                fi
                ;;
            U )
                break 2
                ;;
            * )
                echo "Choice '$n' not valid. You must enter $choice"
                pause
                ;;
        esac
    done
done

uninstall_commands
uninstall_dirs
check_startup
uninstall_configs
check_common_bins

if [ "$update_doc_links" = yes ]
then
    echo
    echo "Running on-line document setup to remove links in Apex"
    echo "to $prod_name..."
    eval $run_make_menus_links
fi


if [ -f config/install_db  -a  ! -d $release ]
then
    if grep "^$product.$version " config/install_db > /dev/null
    then
        echo
        echo "NOTE: $MARKING $product.$version entry from
                  config/install_db" 
        grep -v "^$product.$version " config/install_db > $TMP
        cp $TMP config/install_db
    fi
fi

base_links_cleanup
api_lib_cleanup
if [ "$prod_name" = "ORBexpress" ]
then
    orb_lib_cleanup
fi

