#!/bin/ksh -p
RevN=189
#@(#)rs_install version: 2.189  Date: 9/8/2008 $
#@(#)(C) Copyright IBM Corporation. 1999, 2008. All Rights Reserved.
#------------------------------------------------------------------------
# Note: this script can be run under bash if ksh is not available.
#       A wrapper script is normally used to run this under one of the
#       two shells, depending on the availability of either one.
#------------------------------------------------------------------------
#SOHT
#
#NAME
#     CMD - HDLN
#
#SYNOPSIS
#     CMD [<options>]
#
#DESCRIPTION
#
#     This program is designed to help IBM Rational customers install
#     product suites or individual point products.
#
#     This program will do one or more of the following steps:
#
#        1. Do the licensing set up
#        2. Do the licensing verification
#        3. Install products based on what is licensed
#        4. Let the user customize the install
#        5. Do final post-install processing as required for each product
#        6. Uninstall products
#        7. Display on-line docs, if any.
#
#     The rs_install command is the main entry point.
#     It will do steps 1 through 5.
#
#     It may be convenient to run one of these commands as an alternative
#     to rs_install:
#
#        license_setup   (runs step 1 and 2 only)
#        license_check   (runs step 2 only)
#        post_install    (runs step 5 only)
#        uninstall       (runs step 6 only)
#        rs_help         (runs step 7 only)
#
#     These scripts need to be run from a directory where the CDROM
#     has been mounted.  They can be run from a CDROM image directory
#     or from the installed directory under the <Rational>/releases/<product>
#     directory.  They need to have access to files in the
#     extras/install_data directory.
#
#OPTIONS
#     -accept <LA_PATH>
#          Automatically accept the license agreement.  You must first
#          accept the license agreement once using the -save option.
#          The -save option is used to save the license agreement
#          information in a common dirctory (LA_PATH) that is
#          accessible by everyone else in the group.
#
#     -agree
#          Agree to the license agreement.  Do not display it.
#          This option is for backward compatibility.  It cannot be
#          used if the LAP Tool is used.  The LAP tool is kept in the
#          extras/LAP directory.  If this directory exists, you need
#          to use the -save option first and then the -accept option for
#          subsequent installs.
#
#     -cdrom <cdrom_dir> (alias: -c, -dir, -d)
#          Specify the CDROM directory.  This is useful to run
#          this command from another location and install from
#          a CDROM that is at <cdrom_dir>.  This is necessary
#          because this command assumes you are in the directory
#          where the product files are to be installed from.
#          You can also cd to this directory and run this command
#          from elsewhere (e.g. /tmp/CMD) and then you do not need
#          to use this option.
#
#     -force (alias: -f)   (applicable only to the uninstall command)
#          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.
#
#     -help (alias: -h)
#          Show this usage message.
#
#     -no_log (alias: -nl)
#          Do not produce a log file.
#          The default is to log to file: /tmp/rs_install.$HOST.$USER.log
#
#     -log <log_file>
#          Copy output to <log_file> instead of the default log file.
#
#     -locale <lc> (alias: -lo)
#           Use this to set the help file to another language.  The <lc>
#           parameter is a 2-character extension matching the help file in
#           the extras/install_data directory.  This option is only valid
#           if there is a help file with the matching extension.  This
#           option can be used to override the locale settings that are
#           considered when setting the on-line help.
#
#     -netscape (alias: -ns)
#          For the rs_help command, this option will start netscape, not
#          acrobat, as the documentation browser.  For most products
#          this is the default mode.  See -pdf.
#
#     -no_save (alias: -nos)
#          Do not save the defaults when exiting CMD.
#          The only exception is the Rational directory location
#          which is always saved.  This is useful in conjunction with
#          the -reset option.  This would allow you to start CMD
#          with no remembered inputs from the previous run and then to
#          preserve the previous run inputs upon exit.
#          This option is assumed if you use the -record or -play options.
#
#     -no_underlining (alias: -nu)
#          Do not use terminal underlining or highlighting.
#          CMD will try to use the UNIX tput command to determine
#          the escape sequences for underlining or highlighting
#          some text.  If your terminal does not support this or
#          causes strange or unwanted appearance, you can use
#          this option to disable the escape sequences.
#
#     -pdf
#          For the rs_help command, this option will start acrobat, not
#          netscape, as the documentation browser.  For some products
#          this may be the default switch.  In that case, you can start
#          netscape using the -netscape (or -ns) switch.
#
#     -playback <playback_file> (alias: -play, -p)
#          Specify a playback file to get inputs from.  The playback
#          file must be created using the -record option from a
#          previous run of CMD.  Input will be read from the
#          terminal for any inputs not found in the playback file.
#
#     +pl
#          Do not download the FTP product list if it has already been
#          downloaded.
#
#     -record [<playback_file>]  (alias: -rec)
#            Specify a file to create for later playback.  This is useful
#            to capture user inputs and then run CMD again with
#            the exact same inputs.  Use cases for this option include:
#              1. Replicate license setup and installs on multiple machines.
#              2. Automate testing of CMD.
#              3. Reproduce CMD command execution for diagnostics.
#
#          The <playback_file> is optional.  If you specify a file,
#          CMD will create it or overwrite it if it exists.
#          If you do not specify a file, CMD will create the file
#          in your home directory:
#              CMD.record.YYYY.MM.DD-HH:MM
#          or in /tmp if $HOME is not set or not writable:
#              /tmp/CMD.record.$USER.YYYY.MM.DD-HH:MM
#
#     -reset (alias: -re)
#          Reset all saved options to factory defaults.
#          This option causes CMD to not load previously saved
#          defaults.  Once you quit CMD, the defaults files are
#          overwritten with any new defaults from the current run.
#          You will loose whatever was saved from a previous run.
#          If you quit CMD without saving defaults, the previous
#          defaults are left unchanged.  This option allows you to
#          run CMD as if you had not previously run it.
#          Use the -no_save (-nos) option to disable saving all
#          defaults except the Rational directory location.
#          This option is assumed if you use the -record or -play options.
#
#     -save <LA_PATH>
#           This option allows an administrator to accept the product
#           license agreement on behave of the entire group or to accept
#           it on a machine that has a Java Runtime Environment.  The
#           LA_PATH argument must be a fully-qualified directory to store
#           the license agreement files.  The directory needs to be
#           accessible by everyone in the group.  Everyone else in the
#           group uses the -agree option once this is done.  The accepted
#           agreement is stored in this directory:
#             <LA_PATH>/<product_name>.<product_version>.lap
#
#     -size
#          Create a size file to indicate the size of the release.
#          This option is not valid for CDROM releases.
#          It is meant for release images being prepared for final
#          production.  This is not an end-user option.
#
#     -skip_license (alias: -sl)
#          Do not perform the search for pre-configured licenses.
#
#     -trace (alias: -x)
#          Turn on shell tracing.
#
#     -version (alias: -v)
#          Display the version of this command and exit.
#
#                    CMD Revision: 2.RevN
#EOHT
#**************************************************************************

#**************************************************************************
#SOIH
# These are the global variables used by rs_install. They are
# set or overridden in the extras/suite_description file.
#
# rs_Allow_Floating
#    Allow users to configure Floating licenses.
#       Type: yes,no
#    Default: yes
#
# rs_Allow_Multiple_Archs
#    If this flag is set to false it will prevent someone from using the
#    rational directory for a subsequent install of the same product or
#    suite for a different arch.  Allows products like Rose to prevent
#    the install of more than one architecture in the same rational
#    directory.
#       Type: true,false
#    Default: true
#
# rs_Allow_Node_Locked
#    Allow users to configure Node-Locked licenses.
#       Type: yes,no
#    Default: no
#
# rs_Allow_Sys_Release_Dir
#    If this flag is set to false it will keep a product from being installed
#    as <product>.<sys>.<version> in the releases directory.  Instead, it
#    will be installed in <product>.<version> (without .<sys> in the path).
#       Type: true,false
#    Default: true
#
# rs_Allow_User_Based
#    Allow users to configure Named-User licenses.
#       Type: yes,no
#    Default: no
#
# rs_Allow_purela_importing
#    Allow users to import user names from purela license files
#    when configuring Named-User licenses.
#       Type: true,false
#    Default: false
#
# rs_Auto_Help
#    Automatically display the help text for each prompt that has an
#    associated help message.
#       Type: true,false
#    Default: false
#
# rs_Check_Each_Key
#    Check each license key after all of its parameters are input by the user.
#       Type: true,false
#    Default: true
#
# rs_Eval_Quantity
#    Default quantity for temporary (eval/startup) licenses.
#       Type: positive integer (0,1,...,9999)
#    Default: 0
#
# rs_Fax_License_Request
#    Specify the pathname of the fax license request file.  This file
#    is used to print a fax request form, instead of using the
#    AccountLink web page.
#       Type: filename
#    Default: docs/html/fax/license_request.htm
#
# rs_Flex_Ver_Min
#    Specify the minimum FLEXlm/FLEXnet server version required for the
#    product.  If not set, will not check the license server version
#    for the minimum required.
#       Type: version string
#    Default: none
#
# rs_Flex_Ver_Rec
#    Specify the recommended FLEXlm/FLEXnet server version.
#    If the current version is less than this version,
#    display a warning that an upgrade is recommended.
#       Type: version string
#    Default: none
#
# rs_Highlighting
#    Use terminal escape sequences for highlighting display messages.
#    Escape sequences are determined from the UNIX tput command.
#       Type: true,false
#    Default: true
#
# rs_Install_No
#    List of product directory names or ids to not automatically select
#    for installation.
#       Type: Text list of directory names or product identifiers.
#    Default: null
#
# rs_Install_Point_Products
#    Allow the installation of point products from a suite release.
#       Type: yes,no
#    Default: yes
#
# rs_Install_In_Suite_Dir
#    Install all product tar files in the directory specified by
#    $rs_Suite_Dir.$rs_Suite_Ver
#       Type: true,false
#    Default: false
#
# rs_License_Map
#    Specify the name of the CLC license map file.  This file is
#    always installed in the rational_dir/config directory.
#       Type: filename
#    Default: License_Map
#
# rs_Link_Docs
#    If there is a UI directory under a product release directory,
#    create a link in this directory called html to the corresponding
#    product's html directory under docs.  Otherwise, create a symbolic
#    link to the common docs directory in each product directory under
#    releases that is being installed by this distribution.
#       Type: true,false
#    Default: false
#
# rs_Link_List_These_Docs
#    Under each product release directory,
#    create a link in a <sub_dir> directory for each doc in this
#    list that follows the <sub_dir> name.  Each doc must exist under
#    docs/html and be installed in the global product or suite directory.
#       Type: A sub_dir name and a list of document directory names
#    Default: null
#    Example: rs_Link_List_These_Docs="UI installing_and_gettingstarted"
#    Using this example, rs_install would create a link to the
#    installing_and_gettingstarted manual in the UI sub-directory of
#    each product release.
#
# rs_Make_Prod_Links
#    Create links to product dirs under releases, in rational_dir.
#       Type: true,false
#    Default: true
#
# The next 3 variables are used together to form the rules for generating
# a license map file.
#
# rs_Map_Name
#    Used by the rsf_update_license_map to generate a license map file
#    by this name.  The file is then copied to the config directory.
#       Type: file name
#    Default: null
#    Example: rs_Map_Name=PurifyPlus_License_Map"
#
# rs_Map_Licenses
#    Used by the rsf_update_license_map to generate a license map file.
#       Type: list of license names to map.
#    Default: null
#    Example: rs_Map_Licenses="purecov purify quantify"
#
# rs_Map_Order
#    Used by the rsf_update_license_map to generate a license map file.
#       Type: the order of licenses to map to.
#    Default: null
#    Example: rs_Map_Order="standalone PurifyPlusUNIX DevelopmentStudioUNIX"
#    With the previous 3 examples, a license map call PurifyPlus_License_Map
#    would get created in the config directory. It would contain 3 entries,
#    one each for purify, quantify, and purecov (rs_Map_Licenses) and
#    each would map to itself (standalone), then to PurifyPlusUNIX and
#    finally to DevelopmentStudioUNIX.  one entry would look like this:
#      purify:5.0 standalone, PurifyPlusUNIX:5.0, DevelopmentStudioUNIX:1.0
#
# rs_Max_users_per_group
#    The maximum number of users defined per GROUP in the rational.opt
#    file when configuring Named-User licenses.
#       Type: integer (1,2,...100)
#    Default: 100
#
# rs_NL_Quantity
#    Default quantity for permanent or TLA Node-Locked licenses.
#       Type: integer (0,1,...,9999)
#    Default: 0
#
# rs_Pre_Req_Version
#    Set this to specify a previous version of the product or suite that is
#    required to be installed before the current version can be installed.
#    The version can be a subset so that setting rs_Pre_Req_Version to
#    2003.06 will match 2003.06.00 or 2003.06.01, etc using 2003.06*
#    as a wildcard.
#       Type: version string
#    Default: none
#
# rs_Product_Selection
#    Title used on the menu for the product or suite selection function.
#       Type: menu title
#    Default: Specified in suite_description file.
#
# rs_Product_Selection_Desc
#       Type: menu title
#    Default: Specified in suite_description file.
#
# rs_Product_Selection_Title
#       Type: menu title
#    Default: Specified in suite_description file.
#
# rs_Req_Lic
#    Set this flag true to require an existing license for a product.  This
#    prevents the installer from doing license set up.  This is used for
#    patch releases that are to be used by existing customers.  If they are
#    using this product, they have an existing license.  If rs_install
#    cannot find a license it will tell the installer that it cannot install
#    the product.
#       Type: true,false
#    Default: false
#
# rs_SP
#    Release type such as product, suite, kit, bundle, etc.
#       Type: string
#    Default: suite
#
# rs_Short_Name
#    Product release short name
#       Type: string
#    Default: none
#
# rs_Show_Vers
#    Show product or suite version on menus.
#       Type: yes,no
#    Default: yes
#
# rs_Start_Page
#    The starting page for rs_help and netscape.
#       Type: file name
#    Default: docs/README.html
#
# rs_startup_server  (No longer used)
#    The decision to start a license server is now based on
#    whether the license file contains any counted keys, not
#    on the setting of this variable.
#
# rs_Suite_Abbr
#    The abbreviation of the suite, product, kit, bundle, etc.  This must be
#    set to something suitable for use in a shell variable.  You can use
#    letter, numbers and underscores, but no other punctuation or symbols
#    that are illegal in a shell variable name.  For example, R_2000 is okay,
#    but R.2000 is not.
#       Type: string
#    Default: Specified in suite_description file
#
# rs_Suite_Dir
#    The directory name for the suite, kit, product, or bundle.
#       Type: string
#    Default: none
#
# rs_Suite_Name
#    The name of the suite, product, kit, bundle, etc.
#       Type: string
#    Default: Specified in suite_description file
#
# rs_Suite_Ver
#    The version of the suite, product, kit, bundle, etc.
#       Type: string
#    Default: Specified in suite_description file
#
# rs_Update_Url
#    The web address where the product updates can be downloaded by the
#    end-user.  If the platform version is a mismatch, and this is set,
#    the user will be instructed to look for updates at this web address.
#    This is use in the rsf_check_os_level function.
#       Type: string
#    Default: Specified in suite_description file
#
#EOIH
#**************************************************************************

CMD=${0##*/}
FILE=$(cd $(dirname $0); pwd)/$CMD
CMD_OPTS="$*"
USER=`id | sed -e 's?).*??g' -e 's?.*(??g'`
export USER
REV="2.$RevN"
BackOfficeVer=1.0
Quit_CMD="Quit $CMD.  Enter q! to quit without saving your inputs."
export USER
CONTACT_URL=www.ibm.com/contact/us
SUPPORT_URL=www.ibm.com/software/rational/support
ACCT_LINK_URL=$SUPPORT_URL/licensing
HOSTNAME=$(uname -n)
HOST=${HOSTNAME%%.*}
LOG_NAME=rs_install.$HOST.$USER.log
LOG_TMP_NAME=rs_install.$$.$HOST.$USER.log
DEF_LOG_FILE=/tmp/$LOG_TMP_NAME
LOG_FILE=$DEF_LOG_FILE
RM_LIST=/tmp/$CMD.$USER.Cleanup
TEMP=/tmp/$CMD.tmp.$$
PROMPT_PID=/tmp/$CMD.help.prompt.$$
FTP_SERVER=ftp.software.ibm.com
FTP_SCRIPTS=/software/rational/scripts/
vendor_daemon=rational
trl_daemon=ibmratl
UPD=license.upd
PAGER=${PAGER:-more}
SPACES="                                                         "
delim="--------------------------"
help_delim="${delim}${delim}--------------------"
delim="${delim}${delim}${delim}"
LC2=en
oldIFS=$IFS
test "$batch_mode" = yes || batch_mode=no
SYS_LIST="sol solaris_x64 sol_x86 hp hpia sg32 axp aix i386_linux2 s390x"
ARCH_LIST="sun4_solaris2 i386_linux2 hppa_hpux mips_irix_n32 alpha_osf1 rs6k_aix i386_linux2 s390x"
os_name_aix="AIX"
os_name_axp="Tru64 UNIX"
os_name_hp="HP-UX PA-RISC"
os_name_hp64="HP-UX (64 bit)"
os_name_hp10="HP-UX B.10.20"
os_name_hp11="HP-UX B.11.00"
os_name_hpia="HP-UX IA64"
os_name_linux="Linux"
os_name_i386_linux2="Linux x86"
os_name_s390x="zLinux"
os_name_sgi="IRIX 5"
os_name_sg32="IRIX 6"
os_name_sol="Solaris SPARC"
os_name_solaris_x86="Solaris x86"
os_name_solaris_x64="Solaris x64"
os_name_sun="SunOS"
os_name_any="any UNIX O/S"
rs_suite=0
rs_product=0
rs_flex_ver_ok=no
USER_BASED=NamedUser
WSize=80
Max_rd_list_entries=20
Min_lines=48
Min_port_num=1025
Max_port_num=65534
Show_Lines=12
Startup_index=100
Trace_log=false
EDIT=${VISUAL:-${EDITOR:-vi}}
case $EDIT in
*vi ) Using_vi=true ;;
  * ) Using_vi=false ;;
esac
Install_errors=0
Post_install_errors=0
Doing_typical_install=false
Enable_product_defs=true
Enable_flexlm=true
Go_back=false
Imported_licenses=false
License_setup_other=false
Do_license_search=true
Use_existing_licenses=false
Using_UB_license=false
unset owner

rs_vendor_name="IBM Corporation"
rs_vendor="IBM"
rs_vendor_products="IBM Rational products"
rs_Fax_License_Request=docs/html/fax/license_request.htm
Temp_notice="Rational Startup License"

INSTALL=extras/install_data
I18N=$INSTALL/I18N
LICENSE_AGREEMENT_FILE=$INSTALL/license_agreement
ALT_LICENSE_AGREE_FILE=$INSTALL/shrink.txt
LEGAL_INFORMATION=$INSTALL/legal_information
ALT_LEGAL_INFO=$INSTALL/legal_information.txt
LICENSE_PACKAGE=$INSTALL/license_package
EXTRA_LICENSE=$INSTALL/.extra_license
SUITE_DESCRIPTION=$INSTALL/suite_description
BASE_PRODUCT_SIZES=$INSTALL/product_sizes
INI_FILE=$INSTALL/templates1.ini
INI2_FILE=$INSTALL/templates2.ini
ALT_PPLUS_LICENSES="DevelopmentStudioUNIX
DevelopmentStudioUNIXRT
purify
purecov
quantify"

Cmd_Aliases="
    license_setup
    license_check
"
Cond_Aliases="
    bin_setup
    cache_setup
    options_setup
    post_install
    rs_help
    uninstall
    web_setup
"
Cond_Copies="
    README*
    rs_hostinfo
    rs_versions
    .date
"

umask 02

# Determine if this script is running as ksh or bash.
# It has to be one or the other.  typeset -L does not work in bash
typeset -L1 -u _foo=bar 2>/dev/null
if [ "$_foo" = B ]
then
    inBash=false
    TAB=$(print "\t")
else
    inBash=true
    TAB=$(echo -e "\t")
fi
WS=" $TAB"

if $inBash
then
    # Print needs to be defined if this script is run by bash.
    # The -e option is required so the \n, \t, and other special chars work.
    #----------------------------------------------------------------
    function print
    {
        echo -e "$*"
    }
    #----------------------------------------------------------------
    function print_n
    {
        # Echo output without a new line (prompt)
        echo -en "$*"
    }
    #----------------------------------------------------------------
    function print_e
    {
        # Echo output to stderr.
        echo -e "$*" >&2
    }
    #----------------------------------------------------------------
    function rsf_lc
    {
        echo -e "$*" | tr '[A-Z]' '[a-z]'
    }
    #----------------------------------------------------------------
    function rsf_uc
    {
        echo -e "$*" | tr '[a-z]' '[A-Z]'
    }
    #----------------------------------------------------------------
    function rsf_typst
    {
        # Implement k-shell typeset -Rn and -Ln.
        # usage: rsf_typst -L 33 "$variable"
        # usage: rsf_typst -R 5  "$variable"
        set -- $1 $2 $3
        _arg1=$1; _arg2=$2; shift 2; _arg3=$*
        case $_arg1 in
        -L )
            printf "%-${_arg2}s" "$_arg3"
            ;;
        -R )
            printf "%${_arg2}s" "$_arg3"
            ;;
        esac
        unset _arg1 _arg2 _arg3
    }
    #----------------------------------------------------------------
    function rsf_turn_tracing
    {
        case $1 in
        on )
            set -x
            tracing=on
            ;;
        off )
            tracing=off
            set +x
            ;;
        esac
    }

else
    # In ksh: print is a built-in. print_n replaces print -n
    # and print_e replaces print -u2.
    #----------------------------------------------------------------
    function print_n
    {
        # Echo output without a new line (prompt)
        print -n -- "$*"
    }
    #----------------------------------------------------------------
    function print_e
    {
        # Echo output to stderr.
        print -u2 -- "$*"
    }
    #----------------------------------------------------------------
    function rsf_lc
    {
        typeset -l _LC_="$*"
        print -- "$_LC_"
        unset _LC_
    }
    #----------------------------------------------------------------
    function rsf_uc
    {
        typeset -u _UC_="$*"
        print -- "$_UC_"
        unset _UC_
    }
    #----------------------------------------------------------------
    function rsf_typst
    {
        # use k-shell typeset.
        case $1 in
        -L )
            typeset -L$2 _LR_="$3 $SPACES "
            ;;
        -R )
            typeset -R$2 _LR_=" $SPACES $SPACES $3"
            ;;
        * )
            return
            ;;
        esac
        print -- "$_LR_"
        unset _LR_
    }
    #----------------------------------------------------------------
    function rsf_turn_tracing
    {
        case $1 in
        on )
            typeset -ft $(typeset -f | awk '{print $2}')
            tracing=on
            ;;
        off )
            typeset +ft $(typeset -f | awk '{print $2}')
            tracing=off
            ;;
        esac
    }

fi

#------------------------------------------------------------------------
function rsf_is_int
{
    # Test if arg 1 is an integer with no leading + or -.
    # Echo 'int' if it is.  If not, echo the original arg.
    case "$1" in
    "" )
        echo ""
        ;;
    *[!0-9]* )
        echo "$1"
        ;;
    * )
        echo int
        ;;
    esac
}

#------------------------------------------------------------------------
function rsf_is_hex
{
    # Test if arg 1 is a hexidecimal number.
    # Echo 'hex' if it is.  If not, echo the original arg.
    case "$1" in
    "" )
        echo ""
        ;;
    *[!0-9a-fA-F]* )
        echo "$1"
        ;;
    * )
        echo hex
        ;;
    esac
}

#------------------------------------------------------------------------
function rsf_is_hex_oops
{
    # Test if arg 1 is a hex number or one that has weird chars.
    # Echo hex, if hexidecimal, echo oops to flag that the user
    # entered non-hex digits that might be mistaken.
    # Mistaken digits are l, i, or I for 1 and O or o for 0.
    case "$1" in
    "" )
        echo ""
        ;;
    *[!0-9a-fA-F]* )
        case $1 in
        *[!0-9a-filoA-FIO]* )
            echo "$1"
            ;;
        * )
            # Report using 'oops' flag so that it can be corrected.
            echo oops
            ;;
        esac
        ;;
    * )
        echo hex
        ;;
    esac
}

#------------------------------------------------------------------------
function rsf_exit
{
    /bin/rm -f $TEMP
    case $1 in
    HUP|INT|QUIT|ILL|TRAP|ABRT|BUS|SEGV|SYS|ALRM|TERM|PWR )
        sig_mesg="$CMD received signal: $1"
        exit_code=1
        ;;
    no_LA )
        echo "
    A Java Runtime Enviroment (JRE) is needed to install this product.
    Set JAVA_HOME to the location of a JRE or JDK, version 1.3 or later.
    Then run $CMD again."
        exit_code=1
        ;;
    * )
        unset sig_mesg
        exit_code=$1
        ;;
    esac

    if [ -s $PROMPT_PID ]
    then
        # Close the help prompt window.
        kill 15 $(cat $PROMPT_PID) 2>/dev/null
    fi

    test -n "$Restore_stty" && eval $Restore_stty

    if [ -n "$Record_in" ]
    then
        if [ -f $Record_in ]
        then
            print "    Record file created.  Use this option to play back:"
            print "      -play $Record_in"
        fi
    fi

    if [ "$save_option" = yes  -a \
         -n "$LA_PATH" -a \
         "$userAccepts" = yes ]
    then
        print "    Tell other people in the group to run $CMD like this:"
        print "      $CMD -agree $LA_PATH"
    fi

    if [ -z "$LOG_FILE" ]
    then
        print "\n    End of $CMD."
        exit $exit_code
    fi

    if [ ! -f $LOG_FILE ]
    then
        print "\n    End of $CMD."
        exit $exit_code
    fi

    if [ -n "$sig_mesg" ]
    then
        # Add this message to the log file.  Do this since signals have
        # severed the logging pipe setup when rsf_Main was invoked at the
        # bottom of this script.
        print "\n$delim\n    $sig_mesg" >> $LOG_FILE
    fi

    # Relocate the log file to the product release directory.
    # But only if using the default log file.
    unset NEW_LOG_FILE
    if [ -n "$Suite_Path" -a "$LOG_FILE" = "$DEF_LOG_FILE" ]
    then
        if [ -d $Suite_Path ]
        then
            NEW_LOG_FILE=$Suite_Path/$LOG_NAME
        fi
    fi

    print "    $CMD log file:"
    if [ -n "$NEW_LOG_FILE" ]
    then
        print "    $NEW_LOG_FILE"
        print "\n    End of $CMD."
        /bin/cat $LOG_FILE >> $NEW_LOG_FILE
        cat /dev/null > $LOG_FILE
    else
        print "    $LOG_FILE"
        print "\n    End of $CMD."
    fi

    # Remove any empty logs in /tmp that are owned by this user.
    for _log in /tmp/rs_install.*.$HOST.$USER.log
    do
        test -s $_log || /bin/rm -f $_log
    done

    exit $exit_code
}

#------------------------------------------------------------------------
function rsf_normalize_dir
{
    # Try to remove the /tmp_mnt prefix.
    case $1 in
    /tmp_mnt/* )
        if [ -d "${1#/tmp_mnt}" ]
        then
            print "${1#/tmp_mnt}"
            return
        fi
        ;;
    esac
    print "$1"
}

#------------------------------------------------------------------------
function rsf_set_install_flags
{
    # Set flag depending on where we are running from.
    # Cannot install if products directory not in DIR.
    if [ -d $DIR/products -a -x $DIR/rs_install ]
    then
        Okay_to_install=true
    else
        Okay_to_install=false
    fi

    if [ -f README.docs -a -d docs/. ]
    then
        Doc_install_only=true
    else
        Doc_install_only=false
    fi
}

#------------------------------------------------------------------------
function rsf_source
{
    test "$Show_source"  = true && echo "Loading file: $1"
    test "$Trace_source" = true && set -x
    . $1
}

#------------------------------------------------------------------------
function rsf_set_defaults
{
    tmp_defaults=/tmp/rs_install
    rs_ID=$rs_Suite_Abbr.$rs_Suite_Ver
    tmp_product_def=/tmp/rs_install.$rs_ID

    if ${Running_remote:-false}
    then
        for PROD_DEFAULTS in $Remote_id $tmp_product_def.$Remote_id
        do
            test -s $PROD_DEFAULTS || continue
            rsf_source $PROD_DEFAULTS
            USER_DEFAULTS=no_user_defaults_for_$CMD
            print /bin/rm -f $PROD_DEFAULTS >> $RM_LIST
            return
        done
    fi

    if [ "$HOME" = / ]
    then
        unset my_home
    else
        my_home=$HOME
    fi

    # Set the name of the defaults files and the Rational directory
    # location list file.  The defaults files will be renamed to the
    # config/defaults directory below if it exists.
    if [ -d $my_home/.Rational  -a  -w $my_home/.Rational ]
    then
        PROD_DEFAULTS=$my_home/.Rational/rs_install.$rs_ID
        RATL_LIST=$my_home/.Rational/rs_install.rd_list
    elif [ -n "$HOME"  -a  -w "$HOME" ]
    then
        PROD_DEFAULTS=$my_home/.rs_install.$rs_ID
        RATL_LIST=$my_home/.rs_install.rd_list
    else
        PROD_DEFAULTS=$tmp_product_def.$USER
        RATL_LIST=/tmp/rs_install.rd_list.$USER
    fi
    USER_DEFAULTS=$PROD_DEFAULTS
}

#------------------------------------------------------------------------
function rsf_set_owner_of_dir
{
    # If the owner of a directory is 8 or more characters,
    # there is a possibility that the name is truncated.  In that
    # case, will use the ypcat command and the numeric user id to
    # look up the owner's login name.

    set -- $($LSL -d $_rd)
    owner=$3

    # Determine the numeric user id (arg 3).
    set -- $($LSN $_rd)
    uid=$3

    test ${#owner} -lt 8 && return

    # Lookup the user name using the numeric user id, if it was set.
    test -z "$uid" && return
    set -- 1 $(ypcat passwd 2>/dev/null |
              awk -F: '{print $1, $3}' | grep " $uid\$")
    test $# -gt 2 && owner=$2
}

#------------------------------------------------------------------------
function rsf_check_user_is_owner
{
    # This function is called with 2 args.  The first is a keyword
    # to control what is done in the event that the user is not the
    # owner of the directory (arg 2).
    # Keyword:   Meaning:
    #    quiet - Just check ownership and return 0 if owner, 1 if not.
    #      ask - Prompt user if they want to use this directory anyway,
    #            but only if they have write permission on it.
    # dont_ask - Do not prompt.

    _keyword=$1
    _rd=$2
    chmod u+w $_rd 2>/dev/null && return 0
    test "$_keyword" = quiet && return 1

    case $CMD in
    rs_install|uninstall )
        install_products="${CMD#rs_} products"
        ;;
    *_* )
        install_products="do ${CMD%_*} ${CMD#*_}"
        ;;
    * )
        return 0
        ;;
    esac

    rsf_set_owner_of_dir
    if [ -n "$uid" ]
    then
        run_CMD_as="run $CMD as '$owner' (uid=$uid)"
    else
        run_CMD_as="run $CMD as '$owner'"
    fi

    if [ "$_keyword" = dont_ask -o  ! -w $_rd ]
    then
        print "
    You cannot $install_products in:
      $_rd

    Your user ID ('$USER') does not match that of the original
    installer ('$owner') into this area.
    You must $run_CMD_as.

    You will encounter permission problems if you do not consistently
    $install_products as the same installer in the same Rational directory.
"
        unset install_products _keyword
        return 1
    fi

    print "
    You should not $install_products in:
      $_rd

    Your user ID ('$USER') does not match that of the original
    installer ('$owner') into this area.
    You should $run_CMD_as
    or select a different Rational directory.

    IBM strongly recommends that you $install_products
    in a common Rational directory as the same user.
    You may run into permission problems if you do not consistently
    $install_products as the same installer in the same Rational directory.
"
    unset install_products _keyword
    if [ -w $_rd ]
    then
        yn_use_rd_anyway=no
        rsf_get_option yn_use_rd_anyway y_n \
            "Do you want to use this directory anyway?"
        test $yn_use_rd_anyway = yes && return 0
    fi
    return 1
}

#------------------------------------------------------------------------
function rsf_check_prerequisite_installed
{
    eval _suite_dir=\$rs_suite_dir$s
    eval _suite_ver=\$rs_suite_ver$s
    eval _suite_name=\$rs_suite_name$s

    test -n "$rs_Pre_Req_Version" || return 0
    test -z "$_suite_dir"         && return 0

    Pre_Req_Path="$Releases/$_suite_dir.$rs_Pre_Req_Version"
    test -d "$Pre_Req_Path"       && return 0

    # Not in the current rational_dir. Check all of them.
    _pre_rd_list=$rsu_rational_dir
    for _n in $rd_n_list
    do
        eval _rd_n=\$rational_dir$_n
        test -d $_rd_n/releases || continue
        cd $_rd_n/releases || continue
        for _pre_req_dir in $_suite_dir.$rs_Pre_Req_Version*
        do
            if [ -d "$_pre_req_dir" ]
            then
                cd $OLDPWD
                return 0
            fi
        done
        _pre_rd_list="$_pre_rd_list\n      $_rd_n"
        cd $OLDPWD
    done
    test "$1" = quiet && return 1

    print "
    $_suite_name $_suite_ver cannot be installed.

    $_suite_name $rs_Pre_Req_Version
    has not been installed.  The following locations were checked:

      $_pre_rd_list

    You must first install version $rs_Pre_Req_Version before installing
    $_suite_name $_suite_ver.
"
    return 1
}

#------------------------------------------------------------------------
function rsf_select_rational_dir
{
    if ${Running_remote:-false}
    then
        rsf_set_rational_dir_vars
        return
    fi

    # The Rational directory location file will have multiple entries,
    # one for each product install. This will allow installs of multiple
    # products into multiple locations by a singler installer and
    # will be able to select the correct one for each product.
    # If none match, the installer can select from a menu.
    if [ -f README.docs -a -d docs/. ]
    then
        rsf_rational_dir_menu E
        return
    fi

    if $Okay_to_install
    then
        # Display menu to get install location.
        # This function will call rsf_set_rational_dir_vars.
        rsf_rational_dir_menu E
        return
    fi

    # Compute the Rational directory from current directory.
    # This way the menu will not be needed.
    # It could be one or 2 directories up.
    if [ -s $LOG_NAME ]
    then
        # Rational dir is recorded in this file.
        set -- $(grep "^Ratl: " $LOG_NAME | tail -1)
        if [ -n "$2" ]
        then
            if [ -d $2 ]
            then
                _rd=$2
            fi
        fi
        if [ -z "$_rd" ]
        then
            _rd=$(dirname $DIR)
        fi
    else
        _rd=$(dirname $DIR)
    fi
    if [ -d $_rd/releases -a -d $_rd/config ]
    then
        if rsf_check_user_is_owner ask $_rd
        then
            rsu_rational_dir=$_rd
        fi
    else
        # It may be up one more directory up.
        _rd=$(dirname $_rd)
        if [ -d $_rd/releases -a -d $_rd/config ]
        then
            if rsf_check_user_is_owner ask $_rd
            then
                rsu_rational_dir=$_rd
            fi
        fi
    fi

    if  [ -n "$rsu_rational_dir" ]
    then
        # Set the script variables based on this location.
        rsf_set_rational_dir_vars
        return
    fi

    rsf_rational_dir_menu E
}

#------------------------------------------------------------------------
function rsf_set_banner
{
    # Set banner string.
    let WSize2=WSize-4
    let n=WSize2-${#rs_vendor_name}
    let n2=n/2

    case $CMD in
    rs_install )
        Allow_existing_licensing=true
        Command="RS Install"
        ;;
    license_check )
        Command="License Check"
        ;;
    license_setup )
        Allow_existing_licensing=true
        Command="License Setup"
        ;;
    post_install )
        Command="Post Install"
        ;;
    uninstall )
        Command="Uninstall"
        ;;
    rs_help|rs_docs )
        rsf_help
        exit 0
        ;;
    *)
        # Upper case each word in the name, where words are separated by _
        set -- $(IFS=_ ; echo $CMD)
        while [ $# -gt 0 ]
        do
            _C=$(rsf_typst -L 1 $1)
            _C=$(rsf_uc $_C)
            _cmd="$_cmd ${_C}${1#?}"
            shift
        done
        Command="$_cmd"
    ;;
    esac
    command=$(rsf_typst -L $n2 "$Command")
    rev=$(rsf_typst -R $n2 "Version: $REV")
    banner="$command $rs_vendor_name $rev"
    unset command rev n2 _cmd _C
}

#------------------------------------------------------------------------
function rsf_get_option_from_file
{
    # Extract the nth entry matching option name.
    eval _nth=\$pb_$Option_Name
    _nth=${_nth:-1}
    set -- 1 $(grep "^$_nth $Option_Name " $Play_back)
    if [ $# -eq 1 ]
    then
        # No value recorded in file for this option.
        # Get input from terminal.
        eval read option < /dev/tty
        if [ -n "$option" ]
        then
            # Must remove and double quotes from input.
            case "$option" in
            *\"* ) option=$(print "$option" | sed -e 's?"??g') ;;
            esac
        else
            option=$Default_Value
        fi
        print "$_nth $Option_Name $option" >> $Play_back
        unset log_$Option_Name
    elif [ $# -ge 3 ]
    then
        shift 3
        option="$*"
        case $Option_Name in
        lic_file_opt )
            if [ "$option" = last ]
            then
                option=$last_lic_file_opt
            fi
            ;;
        esac
        print "${option:-$Default_Value}"
        eval log_$Option_Name=false
    else
        option="$Default_Value"
        print "$option"
        eval log_$Option_Name=false
    fi
    let _nth=_nth+1
    eval pb_$Option_Name=$_nth
}

#------------------------------------------------------------------------
function rsf_input
{
    # Expects arg1 ::= {option|nothing}
    # Arg2 is the option name.
    # Arg3 is the default option value.
    Input_Type=$1
    Option_Name=$2
    Default_Value="$3"
    Go_back=false
    if [ -z "$Play_back" ]
    then
        # Not doing playback.  Get input from terminal.
        if ${Running_remote:-false}
        then
            eval read $Input_Type
        else
            eval read $Input_Type < /dev/tty
        fi
        # If option is nothing or not recording, we're done.
        if [ "$Input_Type" = nothing ]
        then
            nothing=${nothing:-$Default_Value}
            return
        elif [ -z "$Record_in" ]
        then
            if [ -n "$option" ]
            then
                # Must remove and double quotes from input.
                case "$option" in
                *\"* ) option=$(print "$option" | sed -e 's?"??g') ;;
                esac
            else
                option=$Default_Value
            fi
            return
        fi
    else
        # Doing playback.
        # If reading nothing, then don't need to get input or record input.
        test "$Input_Type" = nothing && return

        # Get input 'option' from file.
        rsf_get_option_from_file

        test -z "$Record_in" && return
    fi

    if [ -n "$option" ]
    then
        # Must remove and double quotes from input.
        case "$option" in
        *\"* ) option=$(print "$option" | sed -e 's?"??g') ;;
        esac
    else
        option=$Default_Value
    fi

    case $Option_Name in
    lic_file_opt )
        case "$option" in
        [1-9]|[1-9][0-9] )
             if [ "$option" = "$last_lic_file_opt" ]
             then
                 _opt=last
             else
                 eval _opt=\"\$lic_file_$option\"
             fi
             ;;
        last )
            option=$last_lic_file_opt
            _opt=last
            ;;
        * )
            _opt=$option
            ;;
        esac
        ;;
    rd_opt )
        case "$option" in
        [1-9] )
            eval _opt=\"\$rational_dir$option\"
            ;;
        * )
            _opt=$option
            ;;
        esac
        ;;
    * )
        _opt=$option
        ;;
    esac

    eval _nth=\$ri_$Option_Name
    _nth=${_nth:-1}
    print "# $menu_title" >> $Record_in
    print "$_nth $Option_Name ${_opt:-$Default_Value}" >> $Record_in
    let _nth=_nth+1
    eval ri_$Option_Name=$_nth
}

#------------------------------------------------------------------------
function rsf_explain_help
{
    print "    Enter a ? to get help."
}

#------------------------------------------------------------------------
function rsf_set_help_file
{
    # If there are localized help files, check locale variables
    # to set the correct one.
    if [ -d $I18N ]
    then
        # Use the locale to set the matching help file.
        # Check the first 2 letters of each of these env variables.
        # If there is a help file with the matching 2 letter extension,
        # use it for the help file.
        eval `locale`
        eval set -- 1 $LC_MESSAGES $LC_CTYPE
        shift
        while [ $# -gt 0 ]
        do
            lc2=$(echo "$1" | cut -c1-2)
            if [ -s $I18N/help_file.$lc2 ]
            then
                HELP_FILE=$I18N/help_file.$lc2
                if [ -f $I18N/welcome_file.$lc2 ]
                then
                    WELCOME_FILE=$I18N/welcome_file.$lc2
                fi
                LC2=$lc2
                return
            fi
            shift
        done
    fi

    # If there is an external help file with the en locale extension, use it.
    if [ -s $I18N/help_file.en ]
    then
        HELP_FILE=$I18N/help_file.en
    else
        # Use the help info embedded in this file.
        # This needs to stay for backward compatibility.
        HELP_FILE=$FILE
    fi
}

#------------------------------------------------------------------------
function rsf_view_help
{
    HELP_FILE=$1
    PID_FILE=$2

    /bin/stty intr 
    print /bin/rm -f $PID_FILE $HELP_FILE >> $RM_LIST
    print $$ > $PID_FILE
    if ${HELP_SCROLL:-false}
    then
        $PAGER $HELP_FILE
    else
        cat $HELP_FILE
    fi
    print_n "\n    Press Enter or Ctrl-C to close window: "
    rsf_input nothing
    exit 0
}

#------------------------------------------------------------------------
function rsf_launch_help_file
{
    if [ -s $PROMPT_PID ]
    then
        # Close the previous window
        kill 15 $(cat $PROMPT_PID) 2>/dev/null
    fi

    if [ -z "$XTERM"  -o  -z "$TERM" ]
    then
        XTERM=${XTERM:-xterm}
        TERM=${XTERM##*/}
        export XTERM TERM
        if [ ! -x $XTERM ]
        then
            if rsf_not_on_path $TERM
            then
                # Cannot use command to display help text.
                # Unset DISPLAY to avoid this the next time.
                unset DISPLAY
                return 1
            fi
        fi
    fi

    let help_size=help_size+2
    if [ $help_size -gt $Min_lines ]
    then
        HELP_SCROLL=true
        export HELP_SCROLL PAGER
        geometry="80x$Min_lines+750+30 -sb"
    else
        geometry=80x$help_size+750+30
    fi

    print "
    The help message for this prompt exceeds the size of this window.
    Launching an $TERM window for this help on
    DISPLAY $DISPLAY..."

    $XTERM -sb -geometry $geometry \
        -T "$CMD: Help Message" \
        -e $BKSH $FILE -rsf_view_help $TEMP $PROMPT_PID &
        # Note: BKSH can be set to ksh or bash.

    return $?
}

#------------------------------------------------------------------------
function rsf_create_help_file
{
    unset _opt_name
    if grep "^#START:$option_name:" $HELP_FILE >/dev/null
    then
        _opt_name=$option_name
    else
        if [ -n "$alternate_option_name" ]
        then
            if grep "^#START:$alternate_option_name:" $HELP_FILE >/dev/null
            then
                _opt_name=$alternate_option_name
            fi
        fi
    fi
    test -n "$_opt_name" || return

    set -- Help on: ${menu_title#*-}
    help_title="$*"
    if [ ${#help_title} -lt 72 ]
    then
        # Center title
        let n=72-${#help_title}
        let n=n/2
        indent=$(rsf_typst -R $n "$SPACES")
        help_title="${indent}$help_title"
    fi
    echo "    $help_delim
    $help_title
    $help_delim"

    if [ -f $DIR/$INSTALL/Help/$_opt_name-b ]
    then
        sed -e 's/^# //' -e 's/^#//' \
            -e "s?^?    ?" \
            -e "s?this command?$CMD?g" \
            -e "s?This command?The $CMD command?g" \
            -e "s?[Tt]his product?${rsu_product_name:-&}?g" \
            $DIR/$INSTALL/Help/$_opt_name-b
        print
    fi

    sed -e "1,/^#START:$_opt_name:/d" \
        -e "/^#END:$_opt_name:/,\$d" \
        -e 's/^# //' -e 's/^#//' \
        -e "s?^?    ?" \
        -e "s?this command?$CMD?g" \
        -e "s?This command?The $CMD command?g" \
        -e "s?[Tt]his product?${rsu_product_name:-&}?g" \
        $HELP_FILE

    if [ -f $DIR/$INSTALL/Help/$_opt_name-a ]
    then
        print
        sed -e 's/^# //' -e 's/^#//' \
            -e "s?^?    ?" \
            -e "s?this host?$HOST?g" \
            -e "s?this command?$CMD?g" \
            -e "s?This command?The $CMD command?g" \
            -e "s?[Tt]his product?$rs_Short_Name?g" \
            $DIR/$INSTALL/Help/$_opt_name-a
    fi

    echo "    $help_delim"
}

#------------------------------------------------------------------------
function rsf_set_LINES
{
    # Determine the size of the window this command is running in.
    # Use stty size first.  If that is not supported, try stty -a.
    # Then parse the output, looking for one of these patterns:
    #   rows = nn
    #   rows nn
    #   nn rows;
    # If not running in a terminal window, use default 24 lines.
    if [ ! -t 0 ]
    then
        LINES=24
        return
    fi

    set -- 1 $(/bin/stty size 2>/dev/null)
    if [ $# -eq 3 ]
    then
        LINES=$2
        return
    fi

    rows=$(/bin/stty -a 2>/dev/null | grep "rows =" |
           sed -e 's? ??g' -e 's?;.*??')
    if [ -n "$rows" ]
    then
        # rows = nn
        eval $rows
        LINES=$rows
        return
    fi

    set -- 1 $(/bin/stty -a 2>/dev/null | grep rows)
    while [ $# -gt 1 ]
    do
        if [ "$1" = rows ]
        then
            # rows nn
            LINES=$2
            return
        fi

        if [ "$1" = 'rows;' ]
        then
            # nn rows;
            LINES=$_prior
            return
        fi
        _prior=$1
        shift
    done

    # The stty commands do not work.
    # Use the previous value or assume 24 lines.
    LINES=${LINES:-24}
}

#------------------------------------------------------------------------
function rsf_show_help
{
    if ${rs_Auto_Help:-false}
    then
        rsf_create_help_file
        return
    fi

    rsf_create_help_file > $TEMP

    if [ ! -s $TEMP ]
    then
        print "\n    Sorry, there is no additional help for this prompt.\n"
        return 1
    fi

    set -- $(wc -l $TEMP)
    help_size=$1

    if [ "$help_size" -gt "$LINES"  -a -n "$DISPLAY"  -a  "$LC2" = en ]
    then
        rsf_launch_help_file && return 1
    fi

    cat $TEMP
    /bin/rm -f $TEMP
    help_prompt="    Press the Enter key when done reading help text: "
    print_n "$help_prompt"
    rsf_input nothing
    rsf_log_input "$nothing" "$help_prompt"
    return 0
}

#------------------------------------------------------------------------
function rsf_set_sp_vars
{
    rsu_sp=${rs_SP:-$1}
    case $rsu_sp in
    [A-Z]* )
        The_sp="$rsu_sp"
        the_sp="$rsu_sp"
        This_sp="$rsu_sp"
        this_sp="$rsu_sp"
        one_sp="one product release"
        ;;
    * )
        The_sp="The $rsu_sp"
        the_sp="the $rsu_sp"
        This_sp="This $rsu_sp"
        this_sp="this $rsu_sp"
        one_sp="one $rsu_sp"
        ;;
    esac

}

#------------------------------------------------------------------------
function rsf_read_defaults
{

    # Read the product size file.  First look for the one matching
    # this host's platform type ($sys).  If that does not exist, use
    # the Solaris size file.  And if that does not exist, look for any
    # other size file.  This allows certain functions to work regardless
    # of someone running on a platform that does not match the product in
    # this release.
    for PRODUCT_SIZES in \
        $BASE_PRODUCT_SIZES.$sys \
        $BASE_PRODUCT_SIZES.sol \
        $BASE_PRODUCT_SIZES.*
    do
        if [ -f $PRODUCT_SIZES ]
        then
            rsf_source $PRODUCT_SIZES
            break
        fi
        unset PRODUCT_SIZES
    done

    if ${Load_defaults:-true}
    then
        test -s $USER_DEFAULTS && . $USER_DEFAULTS
        for _pd in \
            $PROD_DEFAULTS \
            $Defaults_Dir/rs_install.$rs_ID.$owner \
            $Defaults_Dir/rs_install.$rs_ID.* \
            $Defaults_Dir/rs_install.$rs_ID
        do
            if [ -s $_pd ]
            then
                rsf_source $_pd
                break
            fi
        done
        unset _pd
    fi

    rsf_set_sp_vars product

    rs_Suite_Name_Ver="$rs_Suite_Name $rs_Suite_Ver"
    if [ $rs_suite -eq 1 ]
    then
        # Set default rsf_set_suite_vars
        rsu_product_num=1
        rsu_product_name="$rs_suite_name1"
        rsu_product_ver=$rs_suite_ver1
        default_lic_ver=$rs_suite_lic_ver1
        rs_allow_floating=${rs_suite_fl1:-${rs_Allow_Floating:-yes}}
        rs_allow_node_locked=${rs_suite_nl1:-${rs_Allow_Node_Locked:-no}}
        rs_allow_user_based=${rs_suite_ub1:-${rs_Allow_User_Based:-no}}
        product_dir=$rs_suite_dir1
        Prod_Name_Ver="$rsu_product_name $rsu_product_ver"
    elif [ -n "$rsu_product_name" ]
    then
        Prod_Name_Ver="$rsu_product_name $rsu_product_ver"
    else
        Prod_Name_Ver="$rs_Suite_Name $rs_Suite_Ver"
    fi

    _def_ps="Product Initialization"
    if [ -n "$rs_Product_Selection" ]
    then
        if [ "$rs_Product_Selection" = "Install Location" ]
        then
            rs_Product_Selection="$_def_ps"
        fi
    elif [ $rs_suite -gt 1 ]
    then
        rs_Product_Selection="Product and License Configuration Selection"
    elif [ "${rs_show_products_and_tools:-no}" = yes ]
    then
        rs_Product_Selection="Product Selection"
    else
        rs_Product_Selection="$_def_ps"
    fi
    orig_lic_file=$rsu_lic_file
    orig_license_file=$rsu_license_file
    unset _def_ps
    if [ "$Setvars" = yes ]
    then
        eval $varlist
    fi
}

#------------------------------------------------------------------------
function rsf_set_suite_var_list
{
    eval rs_suite_var_list=\$rs_suite_var_list$s
    for _set_var in $rs_suite_var_list
    do
        _var_name=${_set_var%%=*}
        eval $_set_var
        eval _value=\$$_var_name
        case $_value in
        *%s*|*%t* )
            _value=$(print "$_value" | sed -e "s?%s? ?g" -e "s?%t?$TAB?g")
            eval $_var_name=\$_value
            ;;
        esac
    done
    unset _set_var _var_name _value
}

#------------------------------------------------------------------------
function rsf_set_suite_vars
{
    $Enable_product_defs || return
    let s=rs_suite+1
    unset id_list
    show_error=print

    suite_full_name="$1"
    suite_name="$2"
    eval rs_suite_full_name$s=\"$1\"
    eval rs_suite_name$s=\"$2\"
    eval rs_suite_ver$s=\"$3\"
    eval rs_suite_lic_name$s=\"$4\"
    eval rs_suite_lic_ver$s=\"$5\"
    eval rs_suite_key_list$s=\"$6\"
    eval rs_suite_dir$s=\"$7\"
    case "$8" in
    yes|no )
        eval rs_suite_fl$s=\"$8\"
        ;;
    * )
        eval rs_suite_fl$s=${rs_Allow_Floating:-yes}
    ;;
    esac
    eval rs_suite_nl$s=${9:-${rs_Allow_Node_Locked:-no}}
    shift 9
    eval rs_suite_ub$s=${1:-${rs_Allow_User_Based:-no}}
    shift

    for prod_id in $1
    do
        eval id=\$$prod_id
        if [ -n "$id" ]
        then
            id_list="${id_list} ${id}"
        else
            $show_error "Error in the suite definition:"
            print "    Product '$prod_id' not defined for"
            print "    $s. $suite_full_name"
            suite_continue="exit 1"
            show_error=':'
        fi
    done
    eval rs_suite_prod$s=\"$id_list\"
    shift

    # Compute suite/product size from product sizes
    _s_size=0
    for p in $id_list
    do
        eval _size=\$rs_prod_size$p
        let _s_size=_s_size+_size
    done
    eval rs_suite_size$s=\"$_s_size\"

    unset _docs _var_list
    while [ $# -gt 0 ]
    do
        case "$1" in
        DOCS:* )
            if ${Check_doc_entries:-false}
            then
                for doc in $1
                do
                    test "$doc" = "DOCS:" && continue
                    Complete_doc_list="$Complete_doc_list $doc"
                    grep "^$doc|" docs/.control >/dev/null && continue
                    let size_error=size_error+1
                    print_e "*** $CMD: Error $size_error: DOCS: '$doc' for"
                    print_e "    $suite_full_name undefined in docs/.control."
                done
                return
            else
                for doc in $1
                do
                    test "$doc" = "DOCS:" && continue
                    _docs="$_docs $doc"
                done
                eval rs_suite_doc$s=\"$_docs\"
            fi
            ;;
        *=* )
            _var_list="$_var_list $1"
            eval rs_suite_var_list$s=\"$_var_list\"
            _var_name=${1%%=*}
            case $_var_name in
            rs_Pre_Req_Ver )
                ;;
            esac
            ;;
        esac
        shift
    done
    unset _docs _var_list _var_name

    rs_suites="$rs_suites $s"
    rs_suite=$s
}

#------------------------------------------------------------------------
function rsf_set_prod_vars
{
    $Enable_product_defs || return
    let p=rs_product+1
    eval rs_prod_name$p=\"$1\"
    eval rs_prod_ver$p=\"$2\"
    eval rs_prod_lic_name$p=\"$3\"
    eval rs_prod_dir$p=\"$5\"
    eval $5=$p
    eval rs_prod_size$p=\"$6\"
    if [ -n "$7" ]
    then
        eval rs_prod_pi_functions$p=\"$7\"
    fi
    rs_products="$rs_products $p"
    rs_product=$p
}

#------------------------------------------------------------------------
function rsf_set_prod_sys_vars
{
    $Enable_product_defs || return
    # This is for products with special system dependencies
    # like Rose that needs 2 different releases for HP-UX.

    let p=rs_product+1
    eval rs_prod_name$p=\"$1\"
    eval rs_prod_ver$p=\"$2\"
    eval rs_prod_sys$p=\"$3\"
    prod_sys=$3
    eval rs_prod_lic_name$p=\"$4\"
    eval rs_prod_dir$p=\"$6\"
    eval $7=$p
    eval rs_prod_size$p=\"$8\"
    if [ -n "$9" ]
    then
        eval rs_prod_pi_functions$p=\"$9\"
    fi
    rs_products="$rs_products $p"
    rs_product=$p

    if ${Do_prod_sys_check:-false}
    then
        (
        unset other_OS
        rsf_set_other_OS $prod_sys
        if [ -z "$other_OS" ]
        then
            print_e "
    $1 $2 prod sys is $3.
    This does not map to any known O/S in the rsf_set_other_OS function.
"
        fi
        )
    fi
}

#------------------------------------------------------------------------
function rsf_show_locales
{
    print
    set -- 1  $(/bin/ls $I18N/help_file.?? 2>/dev/null)
    shift
    if [ $# -eq 0 ]
    then
        print "There are no help files for other languages."
        print "This option is not supported with this release."
        return
    fi

    print "The following help files are available:"
    for hf in $*
    do
        print "    $hf  [use option: -locale ${hf##*.}]"
    done
    print
}

#------------------------------------------------------------------------
function rsf_usage
{
    # Extract the text between #SOHT and #EOHT in this script
    if [ $1 = 0 ]
    then
        case $CMD in
        rs_install )
           HDLN="License setup, license verification, install, post install."
           ;;
        license_check )
           HDLN="License verification only."
           ;;
        license_setup )
           HDLN="License setup and license verification only."
           ;;
        options_setup )
           HDLN="License option file updates and license verification only."
           ;;
        post_install )
           HDLN="Post install only."
           ;;
        uninstall )
           HDLN="Uninstall suites or products."
           ;;
        rs_help )
           HDLN="Launch browser to view on-line docs, if any."
           ;;
        esac

        sed -e '1,/^#SOHT/d' -e '/^#EOHT/,$d' -e 's/^#//' \
            -e "s?2.RevN?2.$RevN?" \
            -e "s?CMD?$CMD?" -e "s?HDLN?$HDLN?" $FILE | $PAGER
        exit 0
    else
        print_e "Run '$CMD -help' for usage information."
        exit $1
    fi
}

#------------------------------------------------------------------------
function rsf_internal_usage
{
    sed -e '1,/^#SOIH/d' -e '/^#EOIH/,$d' -e 's/^#//' $FILE | $PAGER
}

#------------------------------------------------------------------------
function rsf_set_doc_list
{
    n_docs=0
    set -- $(grep "^.*|" $DIR/docs/.doclist | awk -F\| '{print $1, $3}')
    l_desc=14
    while [ $# -gt 0 ]
    do
        _t=$1
        _f=$2
        shift 2
        test -f "docs/$_f" || continue
        let n_docs=n_docs+1
        eval doc_type$n_docs=$_t
        eval doc_file$n_docs=$_f
        doc_desc=$(grep "^$_t|.*|$_f\$" $DIR/docs/.doclist|awk -F\| '{print $2}')
        if [ ${#doc_desc} -gt $l_desc ]
        then
            l_desc=${#doc_desc}
        fi
        eval doc_desc$n_docs=\$doc_desc
    done
    unset _t _f
}

#------------------------------------------------------------------------
function rsf_PDF
{
    # Usage: rsf_PDF <description> <file>
    test "$showType" = HTML  && return
    test -f "docs/$2" || return
    let n_docs=n_docs+1
    eval doc_type$n_docs=PDF
    eval doc_desc$n_docs=\$1
    eval doc_file$n_docs=$2
    test ${#1} -gt $l_desc && l_desc=${#1}
}

#------------------------------------------------------------------------
function rsf_HTML
{
    # Usage: rsf_HTML <description> <file>
    test "$showType" = PDF   && return
    test -f "docs/$2" || return
    let n_docs=n_docs+1
    eval doc_type$n_docs=HTML
    eval doc_desc$n_docs=\$1
    eval doc_file$n_docs=$2
    test ${#1} -gt $l_desc && l_desc=${#1}
}

#------------------------------------------------------------------------
function rsf_select_doc
{
    if [ -f $DIR/docs/rs_help_list ]
    then
        n_docs=0
        l_desc=14
        showType=$1
        . $DIR/docs/rs_help_list

    elif [ -f $DIR/docs/.doclist ]
    then
        rsf_set_doc_list
    else
        return 1
    fi

    if [ $n_docs -eq 0 ]
    then
        print "\n    There are no documents to select for viewing.\n"
        exit 0
    fi

    DESC=$(rsf_typst -L $l_desc "Document Title")
    docList="
         $DESC   Format"
    DESC=$(rsf_typst -L $l_desc "--------------")
    docList="$docList
         $DESC   ------"

    havePdfProb=no
    haveHtmlProb=no
    n=1
    m=0
    while [ $n -le $n_docs ]
    do
        eval doc_type=\$doc_type$n
        eval doc_desc=\$doc_desc$n
        if [ "$doc_type" = HTML -a -z "$BROWSER_HOME" ]
        then
            haveHtmlProb=yes
            N="  +"
        elif [ "$doc_type" = PDF -a -z "$PDFVIEWER" ]
        then
            havePdfProb=yes
            N="  *"
        else
            let m=m+1
            eval dType$m=\$doc_type$n
            eval dFile$m=\$doc_file$n
            N=$(rsf_typst -R 3 $m)
        fi
        DESC=$(rsf_typst -L $l_desc "$doc_desc")
        docList="$docList
   $N)  $DESC   $doc_type"
        let n=n+1
    done
    last=$m
    docList="$docList

     q)  Quit $CMD."

    if [ "$haveHtmlProb" = yes ]
    then
        docList="$docList

     +These documents require a browser (mozilla/firefox/netscape) on your
      PATH.  Set BROWSER to a program on your PATH to view HTML files."
    fi
    if [ "$havePdfProb" = yes ]
    then
        docList="$docList

     *These documents require a PDF reader (acroread/xpdf/gpdf) on your PATH.
      Set PDFVIEWER to a program on your PATH to view PDF files."
    fi

    case $last in
    0 )
        print "$docList\n"
        print "    There are no programs to read the documents."
        exit 0
        ;;
    1 )
        print "    There is 1 document to select for viewing:"
        ;;
    * )
        print "    There are $last documents to select for viewing:"
        ;;
    esac

    print "$docList"
    while true
    do
        print
        print_n "    Enter the document you want to view: [q] "
        # Get input from terminal.
        read m < /dev/tty
        m=${m:-q}
        case $m in
        q|Q )
            exit 0
            ;;
        [0-9]|[1-9][0-9] )
            eval doc=\$dFile$m
            if [ -n "$doc" ]
            then
                doc=$DIR/docs/$doc
                eval type=\$dType$m
                if [ "$type" = PDF ]
                then
                    rsf_launch_pdf_reader $doc
                else
                    rsf_launch_browser $doc
                fi
                print "$docList"
                continue
            fi
            print "    Document '$m' is not defined."
            ;;
        esac
        case $last in
        1 ) print "    Please enter 1 or q." ;;
        2 ) print "    Please enter 1, 2, or q." ;;
        * ) print "    Please enter a number from 1 to $last, or q." ;;
        esac
    done
}

#------------------------------------------------------------------------
function rsf_launch_pdf_reader
{
    pdf_page=$1
    pdf_cmd=${PDFVIEWER##*/}
    print "Launching $pdf_cmd..."
    print "cd $DIR/docs/pdf"
    cd $DIR/docs/pdf
    print "$PDFVIEWER $pdf_page"
    $PDFVIEWER $pdf_page >>$pdf_log 2>&1 &
    sleep 5
    print "If $pdf_cmd fails to start, check the log file:"
    print "  $pdf_log"
}

#------------------------------------------------------------------------
function rsf_locate_pdf_reader
{
    # Locate a PDF reader.  If not found, will try for acrobat.
    pdf_log=/tmp/$CMD.pdf.$USER.log
    rm -f $pdf_log
    if [ -n "$PDFVIEWER" ]
    then
        pdf=$(rsf_find_on_path $PDFVIEWER)
        if [ -n "$_pdf" ]
        then
            PDFVIEWER=$_pdf
            return
        else
            print "$CMD: PDFVIEWER '$PDFVIEWER' not found."
        fi
        unset PDFVIEWER
    fi

    for _pdf in acroread xpdf gpdf
    do
        _pdf=$(rsf_find_on_path $_pdf)
        if [ -n "$_pdf" ]
        then
            PDFVIEWER=$_pdf
            unset _pdf
            return
        fi
    done

    # For backward compatibility, look here:
    if [ -n "$acrobat_ver" ]
    then
        base_cots_acrobat=base/cots/acrobat.$acrobat_ver/$ARCH
        for acrobat_dir in \
            $DIR/extras/acrobat.$acrobat_ver.$sys \
            $DIR/extras/acrobat/$sys/$acrobat_ver \
            $rsu_rational_dir/$base_cots_acrobat \
            $DIR_UP1/$base_cots_acrobat \
            $DIR_UP2/$base_cots_acrobat
        do
            test -d $acrobat_dir && break
            unset acrobat_dir
        done
    fi

    if [ -n "$acrobat_dir" ]
    then
        ACROREAD=$acrobat_dir/acroread
        PDFVIEWER=$ACROREAD
        ACROBAT=$acrobat_dir/Reader
        export ACROBAT
    fi
}

#------------------------------------------------------------------------
function rsf_launch_browser
{
    web_page=$1
    browser_cmd="$BROWSER_HOME/$browser"
    print "Launching $browser..."
    print "$browser_cmd file:$web_page"
    eval $browser_cmd file:$web_page >> $browser_log 2>&1 &
    sleep 5
    print "If $browser fails to come up, check the log file:"
    print "  $browser_log"
}

#------------------------------------------------------------------------
function rsf_locate_browser
{
    # Locate a browser.  User can specify a browser using BROWSER env. var.
    browser_log=/tmp/$CMD.$browser.$USER.log
    rm -f $browser_log
    unset BROWSER_HOME
    if [ -n "$BROWSER" ]
    then
        _name=${BROWSER##*/}
        browserList=$_name
        _exe=$(rsf_find_on_path $BROWSER)
        if [ -n "$_exe" ]
        then
            browser=${_exe##*/}
            BROWSER_HOME=${_exe:%/*}
            unset _exe _name
            return 0
        else
            print "$CMD: BROWSER '$BROWSER' not found."
        fi
        unset _name _exe
    else
        browserList=""
    fi

    # Look first for mozilla, then firefox, then netscape last.
    for browser in mozilla firefox netscape
    do
        _exe=$(rsf_find_on_path $browser)
        if [ -n "$_exe" ]
        then
            BROWSER_HOME=${_exe%/*}
            case $browser in
            mozilla|firefox|netscape)
                MOZILLA_HOME=$BROWSER_HOME
                export MOZILLA_HOME
                ;;
            esac
            unset _exe
            return
        fi
        browserList="$browserList $browser"
    done
    unset _exe browser

    # For backward compatibility, look here:
    if [ -n "$netscape_ver" ]
    then
        # These locations are for backward compatibility.
        base_cots_netscape=base/cots/netscape.$netscape_ver
        for BROWSER_HOME in \
            $DIR/extras/netscape/$sys/$netscape_ver \
            $DIR/extras/netscape.$netscape_ver.$sys \
            $rsu_rational_dir/$base_cots_netscape \
            $DIR_UP1/$base_cots_netscape \
            $DIR_UP2/$base_cots_netscape
        do
            test -d $BROWSER_HOME -a -x $BROWSER_HOME/netscape && break
            unset BROWSER_HOME
        done
        unset base_cots_netscape
    fi

    if [ -n "$BROWSER_HOME" ]
    then
        MOZILLA_HOME=$BROWSER_HOME
        export MOZILLA_HOME
        browser=netscape
    fi
}

#------------------------------------------------------------------------
function rsf_help
{
    if [ -z "$DISPLAY" ]
    then
        echo "$CMD: DISPLAY not set."
        exit 1
    fi
    unset NPX_PLUGIN_PATH

    Skip_OS_check=true
    rsf_set_arch_os
    rsf_set_defaults

    DIR_UP1=${DIR%/*}
    DIR_UP2=${DIR_UP1%/*}

    if [ -z "$rsu_rational_dir" ]
    then
        if [ -f "$RATL_LIST" ]
        then
            for _dir in $(grep " $rs_ID " $RATL_LIST | awk '{print $1}')
            do
                if [ -d $_dir/base ]
                then
                    rsu_rational_dir=$_dir
                    break
                fi
            done
        fi
    fi

    rsf_locate_pdf_reader
    rsf_locate_browser

    case $sys in
    sgi|sg32 )
        export XFILESEARCHPATH=$BROWSER_HOME
        ;;
    esac

    if rsf_select_doc
    then
        exit 0
    fi

    for web_page in \
        $DIR/$rs_Start_Page \
        $DIR/docs/README.html \
        $DIR/docs/index.html
    do
        test -f $web_page && break
        unset web_page
    done

    if [ -z "$web_page" ]
    then
        print "$CMD: There are no documents to view."
        exit 1
    fi

    if [ -z "$BROWSER_HOME" ]
    then
        print "
    Could not find on PATH: $browserList
    Set BROWSER to a program on your PATH and run $CMD again."
        exit 1
    fi

    rsf_launch_browser $web_page
    exit 0
}

#------------------------------------------------------------------------
function rsf_menu_title
{
    if [ "$1" = '-' ]
    then
        menu_title="$rs_Suite_Name $*"
    else
        menu_title="$*"
    fi

    if ${First_Menu:-true}
    then
        echo "$delim"
        echo "$banner"
        First_Menu=false
    fi
    echo "$delim"

    let "spaces = ( $WSize - ${#menu_title} ) / 2"
    if [ "$spaces" -gt 0 ]
    then
        indent=$(rsf_typst -L $spaces "$SPACES")
        print "\n${indent}${sul}${menu_title}${eul}"
        return
    fi

    case "$menu_title" in
    *\ -\ * )
        unset _mt
        set -- $menu_title
        while [ $# -gt 0 ]
        do
            case "$1" in
            - )
                let "spaces = ( $WSize - ${#_mt} ) / 2"
                indent=$(rsf_typst -L $spaces "$SPACES")
                print "${indent}${sul}${_mt}${eul}"
                unset _mt
                ;;
            * )
                _mt="${_mt}$1 "
                ;;
            esac
            shift
        done
        let "spaces = ( $WSize - ${#_mt} ) / 2"
        indent=$(rsf_typst -L $spaces "$SPACES")
        print "${indent}${sul}${_mt}${eul}"
        ;;
    * )
        print "${sul}${menu_title}${eul}"
        ;;
    esac
}

#------------------------------------------------------------------------
function rsf_get_var_menu
{
    if [ -z "$tracing" ]
    then
        tracing=$(set -o 2>&1 | grep xtrace | awk '{print $2}')
    fi

    if [ "$tracing" = on ]
    then
        X_opt="Tracing is on.  Turn $CMD tracing off."
    else
        X_opt="Tracing is off.  Turn $CMD tracing on."
    fi

    print "
    Unless you have been instructed by IBM to use this,
    please take the default to go back to the previous menu.

    You can enter a variable name to show its value, set it
    or change it.

    You can enter a function name (begin with rsf_) to run
    any function in $CMD.

    Or you can enter any one of these 6 options:

    b) Back to the previous menu.
    q) Quit $CMD now.  Do not save your inputs.
    t) Trace logging.  Display rsf_trace_log calls to the screen.
    x) $X_opt
 ?var) Display all variables beginning with the string 'var'.
       Enter ? to show all variables.
    g) Search all variables for expression.  You will be prompted for expr."

    unset X_opt

    while true
    do
        debug_prompt="    Enter $CMD variable name, function name,b,lf,q,x
    : [b] "
        unset do_function
        print_n "\n$debug_prompt"
        rsf_input option debug_prompt b
        rsf_log_input "$option" "$debug_prompt"
        cmd_var=$option
        case "$cmd_var" in
        rsf_* )
            do_function=$cmd_var
            ;;
        b )
            unset option
            break
            ;;
        g )
            debug_prompt="\nExpression: "
            print_n "\n$debug_prompt"
            rsf_input option debug_prompt ""
            set | egrep "$option"
            continue
            ;;
        q*|Q )
            echo "$delim"
            rsf_exit 0
            ;;
        t )
            Trace_log=true
            print "    Trace logging on."
            continue
            ;;
        x )
            if [ "$tracing" = on ]
            then
                rsf_turn_tracing off
                set +x
                print "    $CMD tracing is off."
            else
                print "    $CMD tracing is on."
                rsf_turn_tracing on
                set -x
            fi
            continue
            ;;
           
        \? )
            set
            continue
            ;;
        \?* )
            set | grep "${cmd_var#?}.*="
            continue
            ;;
        esac

        if [ -n "$do_function" ]
        then
            grep "^function $do_function" $FILE >/dev/null
            if [ $? -ne 0 ]
            then
                print "Function '$cmd_var' not defined in $FILE."
                continue
            fi

            funct_prompt="\n    Enter function args, X to not run\n    : "
            print_n "$funct_prompt"
            rsf_input option function_args
            rsf_log_input "$option" "$funct_prompt"
            case $option in
            x|X ) continue ;;
            esac
            args="$option"
            $do_function $args
            print $do_function return code: $?
            unset do_function
            continue
        fi

        eval val=\$$cmd_var
        if [ -n "$val" ]
        then
            print "\n$cmd_var=$val\n"
            debug_prompt="    Enter new '$cmd_var' value, or x to clear: "
        else
            print "\n$cmd_var not set.\n"
            debug_prompt="    Enter '$cmd_var' value: "
        fi

        print_n "$debug_prompt"
        rsf_input option debug_val
        rsf_log_input "$option" "$debug_prompt"
        cmd_val=$option
        case "$cmd_val" in
        "" )
            print "$cmd_var unchanged"
            ;;
        x )
            unset $cmd_var
            print "$cmd_var has been cleared"
            ;;
        * )
            if [ -n "$val" ]
            then
                if [ "$val" = "$cmd_val" ]
                then
                    print "$cmd_var unchanged"
                    continue
                fi
            fi
            eval export $cmd_var=\$cmd_val
            print "export $cmd_var=$cmd_val"
            ;;
        esac
    done
}

#------------------------------------------------------------------------
#START_OF_HELP_FILE
#
#START:cmpn_opt:
# This menu can be used to customize a product's installation.  Each item
# listed is a specific component of this product that can be installed
# separately.  In most cases, all of the components are installed by
# default.
#      ______________________________________________________________
#     |                       I M P O R T A N T                      |
#     |                                                              |
#     | Components can be de-selected, but in some cases a component |
#     | you install may depend on one that you de-select.            |
#     | If you are unsure, contact IBM technical support.            |
#     |______________________________________________________________|
#
# If the Inst column has a yes in it, the component will be installed.
# By entering the corresponding component number you can change this
# value to no and the component will not be installed.  Entering the
# same number again will reset the Inst value back to yes.
#
# You can enter a range of numbers.  For example to de-select components
# 4 through 8, you could enter each number separately, or you could enter
# them as a string (4 5 6 7 8), or you can enter them as a range (4-8).
# This will invert the Inst value for each component in the range.
#END:cmpn_opt:
#
#START:cust_opt:
# This menu can be used to customize your installation.  Each item
# listed is a specific product that can be installed separately.
# In most cases, all of the products are installed by default.
#
# If the Install column has a yes in it, the product will be installed.
# By selecting the corresponding product number you can change this value
# to no and the product will not be installed.  Selecting the same number
# again will reset the Install value back to yes.  If the product has
# already been installed, setting the Install column to no will not have
# any effect on the product.  In other words, rs_install will not
# uninstall it.
#
# You can enter a range of numbers.  For example, to de-select products 1
# through 4, you could enter each number separately, or you could enter
# them as a string (1 2 3 4), or you can enter them as a range (1-4).
# This will invert the Install value for each product in the range.
#
# The Size column provides the total amount of disk space required
# (expressed in kilobytes) to install the products that you have selected.
# Be sure you have enough disk space in the 'Rational' directory before
# proceeding. Note that if a product is already installed, you would need
# that much less space for the installation.  The rs_install command does
# not attempt to take that into consideration.
#END:cust_opt:
#
#START:doc_opt:
# This menu can be used to customize the on-line documentation
# installation.  Each item listed is a specific set of documents or
# supporting files or directories.  All of the documentation will be
# installed by default.  This program will keep track of any selections
# you make in this menu and retain that for future runs.
#
# If the Install column has a yes in it, the corresponding document item
# will be installed.  By entering the corresponding document item number
# you can change this value to no and the document item will not be
# installed.  Entering the same number again will reset the Install value
# back to yes.  If the document item has already been installed, setting
# the Install column to no will not have any effect on the document item.
# In other words, rs_install will not uninstall it.
#
# You can enter a range of numbers.  For example to de-select document
# items 1 through 4, you could enter each number separately, or you could
# enter them as a string (1 2 3 4), or you can enter them as a range
# (1-4).  The rs_install command will invert the Install value for each
# document item in the range.
#
# The Size column provides the total amount of disk space required
# (expressed in kilobytes) to install the documentation that you have
# selected.  Be sure you have enough disk space in the 'Rational'
# directory before proceeding.  Note that if a product is already
# installed, you would need that much less space for the installation.
# The rs_install command does not attempt to take that into consideration.
#END:doc_opt:
#
#START:flex_opt:
# You are in this menu because you have entered a license server
# who's architecture or operating system version do not match any of
# the ones that are included with this release.  Or there are no
# FLEXlm utilities installed for the architecture of this host.
#
# Enter option 1 to download the tar file that includes the FLEXlm
# utilities for this host.  Once that is done, you can continue.
#
# Enter option 2 check if you have access IBM's FTP server.
# To download a tar file you will need FTP/internet access from the
# machine you are on.
#
# Enter option 3 to find out how to get FLEXlm manually (not within
# this command).  It is important to follow these instructions exactly
# since this command expects FLEXlm to be installed in a specific place.
#END:flex_opt:
#
#START:hostid_opt:
# This command will determine the host ID of the license server
# machine.  If the license server machine is not the machine you
# are on, this command will use the rsh (or remsh) command
# to run the FLEXlm lmhostid command on the license server.
#
# The lmhostid command to be run is shown on the screen.
#
# You may not have your machines set up to allow you to use remote
# commands (rsh/remsh).  If that is the case, you need to login to the
# license server machine and run the license_setup command.  Then come
# back to this machine and run this command.  Specify option 1 in the
# Licensing Options Menu to use existing licensing.
#
# You can use option 2 in this menu to enter the host ID yourself.  This
# must be the same host ID that the lmhostid command would return if you
# run that command on the license server machine.  If it does not match,
# the licenses you get from IBM will not work.
#END:hostid_opt:
#
#START:import_opt:
# You have chosen to import license users from an existing purela license
# file.  The number of users in this license file do not match the number
# of licenses you specified.  This means one of two things; either there
# are too many users in the purela license file or not enough.  In either
# case, this command will not know which users skip or what
# additional user names to use.
#
# You can edit the purela license file and add or delete users so the
# number will match.  Then enter option 1 to try the import again.
#
# If you do not want to do that, select the f option (forward) and any
# additional users will be ignored or auto generated.  Later, you can
# edit the rational.opt file to and change the user names.  If you do
# that, you will need to restart the license server to have you changes
# take effect.  An options_setup command has been provided to make this
# easier.  The options_setup command must be run by the user who owns the
# running lmgrd process or you will not be able to shutdown and restart
# the server.
#END:import_opt:
#
#START:inst_mode_opt:
# If the product or suite you are installing includes products that are
# already installed by a previous release or by rerunning this command,
# you may want to skip installing those products.
#
# Choose option 1 if you want to be prompted whether or not to reinstall
# a product.  Generally this is not necessary unless you feel that the
# product was not installed properly.
#
# Choose option 2 to skip any products that are already installed.  In
# this mode, you will not be asked; the product will simply be skipped
# over.  This is the recommended option to take.
#
# Choose option 3 if you want all products that are installed, to be
# automatically uninstalled and reinstalled.  Generally, this is not
# necessary unless you want to reinstall all products.
#END:inst_mode_opt:
#
#START:lic_check_opt:
# This menu provides 4 options.   Depending on the type of license you
# are using, some options may not be required.
#
# Option 1 checks the rational vendor license keys in the license file
# (.dat file).  This option uses the exinstal/exinstrl commands to verify that the
# license keys in the license file match the other parameters on the
# INCREMENT or FEATURE line of the license file.  This option cannot be
# used if you specified port@host licensing because rs_install needs to
# run exinstal/exinstrl against a license file.  It cannot do this if it does not
# know the location of the license file.
#
# Option 2 starts the license server.  If it is already running, it will
# stop it and restart it.  It does this only if you are the current owner
# of the process or you are running rs_install as root.  If the license
# server is left in a unstable state, every attempt is made to detect and
# correct problems.  This includes checking for a dead rational vendor
# daemon, an orphaned vendor daemon, and abandoned lock files.
#
# Option 2 is not required if you are using port@host or you are using
# uncounted licenses.  The port@host value is used when a license server
# process is already running and the appropriate license is already being
# served. Uncounted licenses do not require a license server process to
# check in or check out licenses.
#
# Option 3 uses the lmstat command to check if the license server is
# running and has IBM Rational vendor licenses.  This option is  required if
# you are using counted licenses (Permanent or TLA) or if the licenses
# are being served by a license manager running on a license server machine.
#
# Option 4 can be used to update the product files that have license
# settings recorded in them.  This option only applies if you have already
# installed and post-installed products with a different license file or
# port@host.  For example, Rational Rose has a config.sh file that sets
# ROSE_LICENSE_FILE to whatever you configured the last time.  If you have
# switched license files (for example, Temporary.dat to server.dat) or the
# port@host, these files will need to be updated.  You can use this option
# to update these files, without having to rerun all of the post-install
# steps.
#END:lic_check_opt:
#
#START:lic_file_opt:
# In this menu, you need to enter the license file you are going to use.
# IBM recommends that you keep its products in a separate license file,
# but you can combine them with other vendor's FLEXlm licenses.
#
# Enter the full pathname to the license file.  If the file does not
# exist, this command will create the file.  If the file already exists,
# this command will update the file with any new license INCREMENT lines
# needed for the products you are installing.  Before updating,
# this command will make a backup copy of the existing license file.
#
# Any license files listed are gathered from one or more of the following
# sources.  The default is selected from this list in the precedence
# shown, if applicable:
#
#    1. From the previous run of this command.
#    2. From the system startup file for the license server on
#       this host (for example, /etc/rc2.d/S98Rational).
#    3. The license file in the 'Rational'/config directory that is
#       named <license_server>.dat, where <license_server> is the name
#       of the license server you have entered.  This is the default
#       license file IBM suggests.
#    4. The LM_LICENSE_FILE environment variable.
#    5. The ~/.flexlmrc file containing a RATIONAL_LICENSE_FILE setting.
#    6. The default FLEXlm license suggested is:
#       /usr/local/flexlm/licenses/license.dat
#END:lic_file_opt:
#
#START:lic_method:
# The licensing methods you are being asked to choose from must match
# the method shown in box 7 or 13 on your license key certificate.
#
# If you have a FLEXlm increment line, the license method is shown in the
# VENDOR_STRING as the 2nd parameter.  You must choose the one that
# matches or your license key will be invalid.
#END:lic_method:
#
#START:lic_prod_opt:
# Enter one or more numbers or a range of numbers to select products
# to license.  If the product is already selected, entering the
# corresponding number will deselect it.  You can enter a number
# like 1, a range such as 1-3, or a list like 2 3 4.
#
# Enter 'n' to display the next set of products.
#
# Enter 'p' to display the previous set of products.
#
# Enter 'u' to unselect every product, not just what is showing on the
# current screen.
#
# Enter 'f' to set up the licenses you have selected so far.
# This option is not valid if you have not selected any products.
#
# Enter 'q' to quit command.
#END:lic_prod_opt:
#
#START:one_key:
# You need to enter the license key as a 12-digit hexadecimal number.
# If you do not know the license key, or you were not given one
# for this product, you can skip the licensing of this product
# by entering a 0 (zero).  If later you install the product that
# requires this license, you will only be able to use it once the
# license for this product is configured.
#
# For temporary keys, the license key is in box 16 on your
# license key certificate.
#
# For permanent or TLA keys, it is the 6th parameter on the
# INCREMENT line.
#END:one_key:
#
#START:options_file:
# The options file is named rational.opt.  It exists in the same directory
# as the license file you are using for this product.
# You need to enter the full pathname of this file.
#END:options_file:
#
#START:pause:
# Press the Enter (or Return) key to continue with this command.
# You can enter a q to quit or q! to quit without saving defaults.
#END:pause:
#
#START:pcfg_opt:
# In this menu, you can select one and only one product configuration to
# install.  Enter the number corresponding to the product configuration
# you are going to use.
#END:pcfg_opt:
#
#START:prod_opt:
# You must enter an option for the product configuration you
# are installing.  In the rs_install program you will be given an
# opportunity to customize the install of the product configuration
# you select.
#
# You can enter option 'e' to view a list of licenses for each product.
# Products will have a primary license and in some cases one or more
# alternate licenses.  Use this option to see them.
#
# You can enter option 'd' to download the latest version of
# this command from ftp.software.ibm.com and run it.  If the version
# you are running now is newer than the one on the IBM FTP server,
# this command will not download it.
#END:prod_opt:
#
#START:prod_user:
# This product is licensed on a per user basis.
# The user login must match the UNIX login name of each user
# that will be using this product.
# Only the users entered here can use the product.
# You must enter the number of users that match the number of licenses
# you have purchased.
#
# At a later time you can use the options_setup command to change the
# users listed in the rational.opt options file.
#END:prod_user:
#
#START:Quantity:
# Enter the quantity of licenses for this license feature.  This is the
# number of users that are going to be licensed to use the product shown
# above.  The number of users must match what is in your license file.
# The quantity is the 5th parameter of the INCREMENT line.
#END:Quantity:
#
#START:rational_lic_file:
# Enter the full pathname to the license file of the current running
# license server that has rational vendor daemon licenses in it.  This is
# needed so that when the license server is restarted, it can read the
# existing license file and the temporary license file together.  The
# temporary license file contains counted licenses.  These licenses
# cannot co-mingle with permanent licenses due to the format of the
# temporary file.
#END:rational_lic_file:
#
#START:rd_opt:
# If this is the first time you are using this command, there will be no
# default location to install IBM Rational products.
#
# You must specify a root location where this command will create
# sub-directories to organize all IBM Rational UNIX products under.  The
# primary directory will be call 'releases' and this is where each
# individual product is installed.  Each product is installed in such a
# way that each unique version and UNIX platform are differentiated.
#
# A 'base' directory will be created to keep items that do not always
# change from release to release.  This is where the FLEXlm license
# utilities will be installed.  As an example, FLEXlm 6.0i for Solaris
# would get installed under base/cots/flexlm.6.0i/sun4_solaris2.
# If applicable, Netscape navigator, Adobe Acrobat, and compiler
# libraries would be installed under 'base'.
#
# A 'config' directory will be created as a place to keep license files,
# license logs, default files for this command and other configuration
# information.
#
# If you have used this command to install IBM Rational products before, you
# will have a default choice for the 'Rational' directory.  If you want
# to specify a new directory enter a 0 (zero) or just enter the new
# directory.  It must be a fully-qualified pathname (/var/rational for
# example).  Otherwise, just enter the number corresponding to the
# 'Rational' directory you want to use for this product.
#END:rd_opt:
#
#START:rsu_allow_rsh:
# Enter yes if you have permission to run remote shell commands to the
# license server machine using rsh or remsh.  If you do not, enter no.
# You will be asked if you have permission to use ssh instead. If not,
# read the instructions on how to proceed with running license_setup
# on the remote machine.
#END:rsu_allow_rsh:
#
#START:exp_date:
# The expiration date is in box 15 on your license key certificate.  If
# you have an INCREMENT line, it is the 4th parameter on the INCREMENT
# line.  The date must be in the FLEXlm format:  DD-MON-YEAR, where DD is
# the 1 or 2 digit day of the month, MON is the 3 character abbreviation
# of the month and YEAR is the 4 digit year.  The word permanent is used
# to express a license which does not expire.  You can enter a 'p' as an
# abbreviation to the word permanent.
#END:exp_date:
#
#START:rsu_import_lic_file:
# Enter the full pathname to the license file this command can use to
# import license information.  Normally, this file would be the
# licenses_for_server.upd file you received from IBM after visiting
# the web site: www.ibm.com/software/rational/support/licensing
#
# IBM recommends that you set up your permanent or TLA licenses
# using this method.
#
# You can enter none, but then you will be asked to enter 9 separate
# pieces of information to gather all of the necessary data to construct
# the FLEXlm INCREMENT lines.
#END:rsu_import_lic_file:
#
#START:issue_date:
# The ISSUE date is expressed on the INCREMENT line as a keyword
# parameter like ISSUED=DD-MON-YEAR.  You must enter the ISSUED
# date that is shown following the = sign.
#END:issue_date:
#
#START:rsu_lic_file:
# If you are trying to use existing licenses,
# enter the full pathname to the license file or enter port@host.
# If the licenses are being served by a license server, you can
# enter a port@host to specify the licenses.
#
# If you are setting up new licenses or updating an existing
# license file, you must enter a license file.  You cannot
# use port@host for this purpose.
#END:rsu_lic_file:
#
#START:rsu_lic_hostid:
# The license server host ID must match the one you specified
# when you visited www.ibm.com/software/rational/support/licensing.
# The host ID is shown as the 2nd parameter of the SERVER line.
#END:rsu_lic_hostid:
#
#START:rsu_lic_port:
# The license server port number is the TCP/IP port that FLEXlm uses to
# communicate license information.  By default, FLEXlm uses port number
# 27000.  It is recommended to use this number.
#
# If you already have a license manager daemon running on the server
# using port 27000 you need to use another one.  You should then use
# the next available one starting with 27001.
#      __________________________________________________________
#     |                       I M P O R T A N T                  |
#     |                                                          |
#     | You can use more than one FLEXlm lmgrd daemon running on |
#     | a server, but you can only have one rational vendor      |
#     | daemon running on a server.                              |
#     |__________________________________________________________|
#
#END:rsu_lic_port:
#
#START:rsu_lic_server:
# The license server name must match the license server you specified
# when you visited www.ibm.com/software/rational/support/licensing
# The server name is shown as the 1st parameter of the SERVER line.
#END:rsu_lic_server:
#
#START:notice:
# The NOTICE field is expressed on the INCREMENT line as a keyword
# parameter like NOTICE="Your Company Name".  You must enter the
# NOTICE exactly as it appears after the = sign.  Do not enter the
# quotes, just the company name.
#END:notice:
#
#START:rsu_acct_num:
# If you do not know your account number, enter 0 at this time.
#END:rsu_acct_num:
#
#START:rsu_purela_dir:
# If you know the directory name where purela licensing is kept, enter
# the full pathname of the directory.  This command will
# then convert the users.purela license file and try to import user
# information for FLEXlm licensing.
#
# If you do not know where the purela licensing is, you can enter none
# and you will be prompted for user names.  You will also be given an
# opportunity to auto-generate names as place holders until you decide
# which users to configure for this product.
#END:rsu_purela_dir:
#
#START:rsu_rational_dir:
# You must enter the full pathname to a directory where IBM Rational
# products can be installed.  If the directory does not exist, you wll be
# asked if it is okay to create it.  If this command fails to create it,
# you will be asked to enter a different directory.  If it already exists
# and you do not have write permissions, you will not be able to use that
# directory as the 'Rational' directory.
#
# Make sure the pathname you select is properly named.  If you plan on
# using this product from another machine, the product must be located
# from the same pathname or it will not function properly.  As an
# example, if you were to install products into /export/rational on host
# socrates but on host plato, the filesystem is mounted as
# /net/socrates/rational, you must then enter /net/socrates/rational as
# the 'Rational' directory, not the local filesystem /export/rational.
#END:rsu_rational_dir:
#
#START:rsu_show_lic_agree:
# If you answer yes (or y) you will be shown the IBM Rational products
# license agreement the next time you run this command.  If you answer
# no (or n) you will not be shown this agreement again for this version
# of this product.  This does not apply to other products or other
# versions of this product.
#END:rsu_show_lic_agree:
#
#START:rsu_show_legal_info:
# If you answer yes (or y) you will be shown the non-IBM-Rational products
# license agreement the next time you run this command.  If you answer
# no (or n) you will not be shown this agreement again for this version
# of this product.  This does not apply to other products or other
# versions of this product.
#END:rsu_show_legal_info:
#
#START:tc_mode_opt:
# Typical:
#    Installs the most commonly used features of the product.
#    Choose this option if you do not need to select specific
#    product features.
#
# Custom:
#    Installs specific features that may be excluded in the Typical
#    option.  Choose this option to use only specific features, or
#    because you have space constraints.
#END:tc_mode_opt:
#
#START:verify_opt:
# This menu allows you to re-enter information.
# Enter a number corresponding to the information you want to change.
# You will only be prompted for the data corresponding to the number you
# enter.  If you enter the last number, you will be prompted to re-enter
# all information.
#END:verify_opt:
#
#START:yn_use_this_license:
# If you answer yes, this command will configure this product
# Using the license configurations shown above.
#
# This allows you to skip the 'Licensing Options' menu, and all of
# the license configuration input screens.  You will next go to the
# 'Typical/Custom Install Preference' menu where you can start
# installing this product immediately.
#
# You can configure this product to use a subset
# of what is shown if there is more than one configuration.
#
# If you want to use a subset of what is shown, add more license
# configurations, configure a new license server, or enter a list of
# license configurations other than the one shown above, enter 'n'.  You
# will next go to the 'Licensing Options' menu.
#END:yn_use_this_license:
#
#START:yesno:
# Enter y for yes or n for no.
#END:yesno:
#
#START:yn_license_agreement:
# You must answer yes (or y) to accept the IBM Rational products license
# agreement.  If you answer no (or n), this command will exit.
#END:yn_license_agreement:
#
#START:yn_legal_agreement:
# You must answer yes (or y) to accept the non-IBM-Rational products license
# agreement.  If you answer no (or n), this command will exit.
#END:yn_legal_agreement:
#
#END_OF_HELP_FILE
#------------------------------------------------------------------------

#------------------------------------------------------------------------
function rsf_pause
{
    continue_opt=$1
    case "$continue_opt" in
    Q )
        yn_continue=no
        rsf_get_option yn_continue y_n "Do you want to continue $CMD?"
        test "$yn_continue" = yes && return
        rsf_cleanup Q
        ;;
    TO|TO_E )
        shift
        Pause_prompt="Press the Enter key to $*"
        ;;
    * )
        Pause_prompt="Press the Enter key to continue, q to quit $CMD"
        ;;
    esac

    $Doing_typical_install && return

    while true
    do
        print_n "\n    $Pause_prompt: "
        rsf_input option pause_prompt c
        rsf_log_input "$option" "$Pause_prompt"
        case $option in
        q! )
            rsf_exit 0
            ;;
        q )
            if [ "$continue_opt" = TO_E ]
            then
                rsf_exit 0
            else
                rsf_cleanup q
            fi
            ;;
        Q )
            rsf_cleanup Q
            ;;
        \! )
            rsf_get_var_menu
            rsf_pause
            ;;
        \!* )
            unix_cmd=${option#!}
            eval $unix_cmd
            rsf_pause
            ;;
        \? )
            option_name=pause
            rsf_show_help
            ;;
        * )
            return
            ;;
        esac
    done
}

#------------------------------------------------------------------------
function rsf_option_not_recognized
{
    case "$1" in
    -np )
        onr_pause=return
        shift
        ;;
    * )
        onr_pause=rsf_pause
        ;;
    esac
    case $2 in
    1 ) _a_num="1," ;;
    2 ) _a_num="a 1, 2," ;;
    * ) _a_num="a number from 1 to $2," ;;
    esac

    print "    Choice '$1' is not a recognized option."
    case "$3" in
    ""|mnu )
        print "    Enter $_a_num or q."
        ;;
    mnf )
        print "    Enter $_a_num f or q."
        ;;
    anf )
        print "    Enter $_a_num a, n, f or q."
        ;;
    anfb )
        print "    Enter $_a_num a, n, b, f or q."
        ;;
    mnfb )
        print "    Enter $_a_num b, f or q."
        ;;
    mnb )
        print "    Enter $_a_num b or q."
        ;;
    beq )
        print "    Enter $_a_num b, e, or q."
        ;;
    bed )
        print "    Enter a number $2, or b, e, d, or q."
        ;;
    * )
        print "    Enter $_a_num $3 or q."
        ;;
    esac
    rsf_explain_help
    $onr_pause
}

#------------------------------------------------------------------------
function rsf_display_important
{
    print "
    =================         =================         =================
    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
    =================         =================         ================="
}

#------------------------------------------------------------------------
function rsf_display_warning
{
    print "
    =============             =============             =============
    W A R N I N G             W A R N I N G             W A R N I N G
    =============             =============             ============="
}

#------------------------------------------------------------------------
function rsf_get_option
{
    option_name=$1
    option_type=$2
    option_prompt="$3"

    # The default option for a menu type can only be the def_option_name.
    # Otherwise, the default option can be option_name, if set.
    case $option_type in
    mnu | mnb | mnf | mnfb )
        eval def_option=\"\$def_$option_name\"
        ;;
    * )
        eval def_option=\"\$$option_name\"
        eval def_option2=\"\$def_$option_name\"
        def_option=${def_option:-$def_option2}
        ;;
    esac

    if [ "$option_type" = y_n ]
    then
        if [ -z "$def_option" ]
        then
            option_prompt="$option_prompt (y/n) "
        fi
    fi

    if [ -n "$def_option" ]
    then
        option_prompt="\n    $option_prompt [$def_option] "
    else
        option_prompt="\n    $option_prompt "
    fi

    # If we have started doing a typical install, try to
    # take the default and avoid prompting the user.
    # It's possible to get into a infinite loop.
    # To avoid this, check if we are asking for the same
    # option and default as the immediate prior prompt.
    # Also, there are places were the prompting goes back
    # and forth, such as "Enter directory" and "Not found, use anyway"
    # If the default for "use anyway" is no, we will thrash back and
    # forth.  To handle this, will keep track of the previous 2 prompts.
    if $Doing_typical_install
    then
        if [ -n "$def_option" -a \
            "$option_name $def_option" != "$prior_option_def" ]
        then
            if [ -z "$prior_option2_def" -o \
                "$option_name $def_option" != "$prior_option2_def" ]
            then
                print "    $option_prompt"
                eval $option_name=\$def_option
                prior_option2_def=$prior_option_def
                prior_option_def="$option_name $def_option"
                return
            fi
        fi
        prior_option2_def=$prior_option_def
        prior_option_def="$option_name $def_option"
    fi

    if ${rs_Auto_Help:-false}
    then
        rsf_show_help
    fi

    Go_back=false
    Repaint=false
    while true
    do
        $Repaint && echo "$Buffered_screen"
        print_n "$option_prompt"
        rsf_input option $option_name "$def_option"
        option=${option:-$def_option}
        rsf_log_input "$option" "$option_prompt"
        eval _option=\"$option\"
        if [ "'$_option'" != "'$option'" ]
        then
            option="$_option"
            rsf_log_input "$option (eval)" "$option_prompt"
        fi

        case "$option" in
        Q )
            rsf_cleanup Q
            ;;
        q )
            # If the default option is to quit, then quit, without asking.
            # It is odd to set the default to quit and then ask the user if
            # they are sure they want to.
            test "$def_option" = q && rsf_cleanup 0
            cont_prompt="\n    Are you sure you want to quit $CMD? [no] "
            print_n "$cont_prompt"
            rsf_input option quit_cmd no
            rsf_log_input "$option" "$cont_prompt"
            case $option in
            y*|Y*|q|Q )
                rsf_cleanup Q
                ;;
            q! )
                rsf_exit 0
                ;;
            esac
            continue
            ;;
        q!|Q! )
            rsf_exit 0
            ;;
        \~* )
            eval _option=$option
            if [ "$_option" != "$option" ]
            then
                option="$_option"
                rsf_log_input "$option (tilde eval)" "$option_prompt"
            fi
            ;;
        \! )
            rsf_buffer_screen
            rsf_get_var_menu
            continue
            ;;
        \!* )
            option=${option#!}
            rsf_buffer_screen
            eval $option
            continue
            ;;
        \? )
            if [ "$option_name" = license_opt ]
            then
                if [ "$HELP_FILE" = "$FILE" ]
                then
                    # Do this because this option is explained
                    # dynamically in this script, not statically.
                    eval license_opt=e
                    return
                fi
            elif [ "$option_type" = y_n ]
            then
                alternate_option_name=yesno
                rsf_show_help
                unset alternate_option_name
                continue
            fi
            rsf_buffer_screen
            rsf_show_help || Repaint=false
            continue
            ;;
        esac

        case "$option_type" in
        dir )
            if [ -n "$option" ]
            then
                if rsf_check_input_chars directory "$option"
                then
                    eval $option_name=\"$option\"
                    return
                else
                    rsf_explain_help
                fi
            else
                print "    You must enter a directory path."
                rsf_explain_help
            fi
            ;;
        fil )
            if [ -n "$option" ]
            then
                if rsf_check_input_chars file "$option"
                then
                    eval $option_name=\"$option\"
                    return
                else
                    rsf_explain_help
                fi
            else
                print "    You must enter a file name."
                rsf_explain_help
            fi
            ;;
        hex )
            alt_opt=$(rsf_is_hex_oops "$option")
            case "$alt_opt" in
            hex )
                eval $option_name=\"$option\"
                return
                ;;
            oops )
                # If someone enters an I or l for 1 (one) or an O for 0 (zero)
                # transform these characters and check again.
                _option=$(print "$option" |sed -e 's?[Iil]?1?g' -e 's?[Oo]?0?g')
                alt_opt=$(rsf_is_hex "$_option")
                case "$alt_opt" in
                hex )
                    if [ ${#_option} -eq 1 ]
                    then
                        eval $option_name=\"$_option\"
                        return
                    fi
                    _show=$(print "$option" |
                        sed -e 's?[IilOo]?^?g' -e 's?[0-9a-fA-F]? ?g')
                    print "
    You were expected to enter a hexadecimal number.
    The non-hexadecimal characters usually confused for letters
    have been converted as shown:
      You entered this: $option
       Changed to this: $_option
                        $_show"
                    eval $option_name=\"$_option\"
                    unset _option _show
                    return
                    ;;
                esac
                ;;
            esac
            print "    You must enter a hexadecimal number."
            rsf_explain_help
            ;;
        mnf )
            alt_opt=$(rsf_is_int "$option")
            case "$alt_opt" in
            int )
                eval $option_name=\"$option\"
                return
                ;;
            f|F )
                eval $option_name=f
                return
                ;;
            * )
                eval _last=\$last_$option_name
                print_n "    You must enter a menu option "
                if [ "${_last:-0}" -eq 1 ]
                then
                    print "1, f or q."
                else
                    print "from 1 to ${_last:-N}, f or q."
                fi
                rsf_explain_help
                ;;
            esac
            ;;
        mnfb )
            alt_opt=$(rsf_is_int "$option")
            case "$alt_opt" in
            int )
                eval $option_name=\"$option\"
                return
                ;;
            f|F )
                eval $option_name=f
                return
                ;;
            b|B )
                Go_back=true
                eval $option_name=b
                return
                ;;
            * )
                eval _last=\$last_$option_name
                print_n "    You must enter a menu option "
                if [ "${_last:-0}" -eq 1 ]
                then
                    print "1, b, f or q."
                else
                    print "from 1 to ${_last:-N}, b, f or q."
                fi
                rsf_explain_help
                ;;
            esac
            ;;
        mnu )
            alt_opt=$(rsf_is_int "$option")
            case "$alt_opt" in
            int )
                eval $option_name=\"$option\"
                return
                ;;
            * )
                print_n "    You must enter a menu option "
                eval _last=\$last_$option_name
                if [ "${_last:-0}" -eq 1 ]
                then
                    print "1 or q."
                else
                    print "from 1 to ${_last:-N}, or q."
                fi
                rsf_explain_help
                ;;
            esac
            ;;
        mnb )
            alt_opt=$(rsf_is_int "$option")
            case "$alt_opt" in
            int )
                if [ "$option_name" = prod_opt ]
                then
                    eval suite_install=\$rs_suite_install$option
                    if [ "$suite_install" = no ]
                    then
                        s=$option
                        rsf_check_prerequisite_installed verbose
                        print "
    Enter ${alt_rs_suites#, }, b, e, d, or q."
                        rsf_explain_help
                        Repaint=false
                        continue
                    fi
                fi
                eval $option_name=\"$option\"
                return
                ;;
            b|B )
                Go_back=true
                eval $option_name=b
                return
                ;;
            * )
                if [ "$option_name" = prod_opt ]
                then
                    case $option in
                    e|E )
                        prod_opt=e
                        return
                        ;;
                    d|D )
                        prod_opt=d
                        return
                        ;;
                    esac
                    print_n "    You must enter a menu option from"
                    print " 1 to $last_prod_opt, b, e, d, or q."
                    rsf_explain_help
                    continue

                elif [ "$option_name" = license_opt ]
                then
                    case $option in
                    e|E )
                        license_opt=e
                        return
                        ;;
                    esac
                    print_n "    You must enter a menu option from"
                    print " 1, 2, b, e, or q."
                    rsf_explain_help
                    continue
                fi

                print_n "    You must enter a menu option "
                eval _last=\$last_$option_name
                if [ "${_last:-0}" -eq 1 ]
                then
                    print "1, b or q."
                else
                    print "from 1 to ${_last:-N}, b or q."
                fi
                rsf_explain_help
                ;;
            esac
            ;;
        num )
            alt_opt=$(rsf_is_int "$option")
            case "$alt_opt" in
            int )
                eval $option_name=\"$option\"
                return
                ;;
            * )
                print "    You must enter a decimal value."
                rsf_explain_help
                ;;
            esac
            ;;
        rng )
            unset _opt_list
            # If there are any commas, change them to spaces.
            case "$option" in
            *,* ) option=$(echo "$option" | sed -e 's?,? ?g') ;;
            esac
            Continue_if_rng_err=':'

            for _opt in $option
            do
                alt_opt=$(rsf_is_int "$_opt")
                case "$alt_opt" in
                3121-* )
                    _opt_list="$_opt_list $_opt"
                    ;;
                *-* )
                    lower=${_opt%-*}
                    upper=${_opt#*-}
                    while [ "$lower" -le "$upper" ]
                    do
                        _opt_list="$_opt_list $lower"
                        let lower=lower+1
                    done
                    Continue_if_rng_err=continue
                    ;;
                int )
                    _opt_list="$_opt_list $_opt"
                    ;;
                c[0-9]* )
                    _opt_list="$_opt_list $_opt"
                    ;;
                a|A)
                    if [ "$option_name" = doc_opt ]
                    then
                        _opt_list="$_opt_list a"
                    fi
                    ;;
                b|B )
                    Go_back=true
                    _opt_list="$_opt_list b"
                    ;;
                f|F )
                    _opt_list="$_opt_list f"
                    ;;
                n|N)
                    if [ "$option_name" = doc_opt -o \
                         "$option_name" = lic_prod_opt ]
                    then
                        _opt_list="$_opt_list n"
                    fi
                    ;;
                p|P )
                    if [ "$option_name" = lic_prod_opt ]
                    then
                        _opt_list="$_opt_list p"
                    fi
                    ;;
                u|U )
                    if [ "$option_name" = lic_prod_opt ]
                    then
                        _opt_list="$_opt_list u"
                    fi
                    ;;
                esac
            done
            eval $option_name=\"$_opt_list\"
            return
            ;;
        str )
            if [ -n "$option" ]
            then
                case $option_name in
                rd_opt | rsu_lic_file )
                    if rsf_check_input_chars directory "$option"
                    then
                        eval $option_name=\"$option\"
                        return
                    else
                        rsf_explain_help
                    fi
                    ;;
                * )
                    eval $option_name=\"$option\"
                    return
                    ;;
                esac
            else
                print "    You must enter a string value."
                rsf_explain_help
            fi
            ;;
        y_n )
            case "$option" in
            y*|Y* )
               eval $option_name=yes
               return
               ;;
            n*|N* )
               eval $option_name=no
               return
               ;;
            * )
               print "    Please enter y for yes or n for no."
               rsf_explain_help
               ;;
            esac
            ;;
        * )
            if [ -n "$option" ]
            then
                eval $option_name=\"$option\"
                return
            fi
            print "    You must enter a value."
            rsf_explain_help
            ;;
        esac
    done
}

#------------------------------------------------------------------------
function rsf_check_input_chars
{
    # Check for special chars in input.   Ask if okay.
    inputTyp=$1
    inputVal=$2
    newInVal=`echo "$inputVal" | sed -e 's/[-~/:@,._+=0-9a-zA-Z]/ /g'`
    allBlank=`echo "$newInVal" | sed -e 's/ //g'`
    if [ -z "$allBlank" ]
    then
        return 0
    fi
    echo
    echo "    There are special characters in the $inputTyp you entered:"
    echo "    $inputVal" | cat -v
    echo "    $newInVal" | sed -e 's/[^ ]/\^/g'
    (
    yn_special_char=no
    rsf_get_option yn_special_char y_n "Are you sure this $inputTyp is okay?"
    test "$yn_special_char" = yes && exit 0
    exit 1
    )
    return $?
}

#------------------------------------------------------------------------
function rsf_save_defaults
{
    for opt_name in \
        rsu_allow_rsh      rsu_check_rational_dir \
        rsu_cq_web_url     rsu_install_mode \
        rsu_rp_web_url     rsu_start_lmgrd \
        rsu_purela_dir     rsu_cqdb_dir \
        rsu_typical_install rsu_allow_ssh
    do
        eval opt_val=\"\$$opt_name\"
        if [ -n "$opt_val" ]
        then
            print "$opt_name=\"$opt_val\""
        fi
    done > $PROD_DEFAULTS
    /bin/rm -f $USER_DEFAULTS

    if [ "$USER_DEFAULTS" != "$PROD_DEFAULTS" ]
    then
        (
        print "\n# rs_install defaults:"
        sort $PROD_DEFAULTS
        ) > $USER_DEFAULTS
    fi

    unset Other_Vars License_Vars
    for p in $rs_products
    do
        Other_Vars="$Other_Vars rsu_prod_ver_$p rsu_spn_$p"
    done

    for i in $License_Key_List
    do
        License_Vars="$License_Vars rsu_user_based_list$i"
    done

    for opt_name in \
        rsu_acct_num \
        rsu_fmhome \
        rsu_import_lic_file \
        rsu_install_docs \
        rsu_lic_file \
        rsu_lic_hostid \
        rsu_lic_port \
        rsu_lic_server \
        rsu_license_changed \
        rsu_license_file \
        rsu_options_updated \
        rsu_product_name \
        rsu_product_num \
        rsu_product_ver \
        rsu_rup_opt \
        rsu_show_lic_agree \
        rsu_show_legal_info \
        rsu_sp \
        $License_Vars \
        $Other_Vars
    do
        eval opt_val=\"\$$opt_name\"
        if [ -n "$opt_val" ]
        then
            print "$opt_name=\"$opt_val\""
        fi
    done >> $PROD_DEFAULTS

    if [ -n "$rs_Total_Lic" -a "${rsu_lic_picks:-0}" -gt 0 ]
    then
        print "rsu_lic_picks=\"$rsu_lic_picks\"" >> $PROD_DEFAULTS
        let i=Startup_index+1
        let last_lic_prod=Startup_index+rs_Total_Lic
        while [ $i -le $last_lic_prod ]
        do
            eval lic_pick=\$rsu_lic_pick$i
            if [ "$lic_pick" = yes ]
            then
                print "rsu_lic_pick$i=\"yes\""
            fi
            let i=i+1
        done >> $PROD_DEFAULTS
    fi

    (
    print "\n# rs_install defaults:"
    sort $PROD_DEFAULTS
    ) > $PROD_DEFAULTS.new
    /bin/cp $PROD_DEFAULTS.new $PROD_DEFAULTS
    /bin/rm -f $PROD_DEFAULTS.new
}

#------------------------------------------------------------------------
function rsf_cleanup
{
    for jre in $Releases/jre*
    do
        rsf_remove_dir $jre
    done

    Explain_technotes=false
    exit_status=0
    if ${Doing_download:-false}
    then
        print_n "    FTP transfer interrupted."
        if [ -f rs_install.$REV ]
        then
            print "  Restoring rs_install:"
            print /bin/rm -f rs_install
            /bin/rm -f rs_install
            print /bin/mv rs_install.$REV rs_install
            /bin/mv rs_install.$REV rs_install
        fi
        print
        rsf_exit $1
    fi

    case "$1" in
    q )
        yn_really_quit=no
        rsf_get_option yn_really_quit y_n "Are you sure you want to quit $CMD?"
        test "$yn_really_quit" = no && return
        exit_message="The $CMD command was quit by user."
        ;;
    Q )
        exit_message="The $CMD command was quit by user."
        ;;
    LAP )
        exit_message="The $CMD command quit; user declined license agreement."
        ;;
    0 )
        exit_status=$1
        ;;
    99 )
        exit_message="The $CMD command completed."
        ;;
    HUP|INT|QUIT|ILL|TRAP|ABRT|BUS|SEGV|SYS|ALRM|TERM|PWR)
        exit_message="$CMD received signal: $1"
        exit_status=$1
        ;;
    * )
        exit_message="Error in $CMD."
        exit_status=$1
        Explain_technotes=true
        ;;
    esac

    if [ -z "$exit_message" ]
    then
        if [ "$Install_errors-$Post_install_errors" = "0-0" ]
        then
            exit_message="The $CMD command completed successfully."
        fi
    fi

    case "$Install_errors" in
    0 )
        inst_message=""
        ;;
    1 )
        inst_message="\n    One error occurred during install."
        Explain_technotes=true
        ;;
    * )
        inst_message="\n    $Install_errors errors occurred during install."
        Explain_technotes=true
        ;;
    esac

    case "$Post_install_errors" in
    0 )
        post_message=""
        ;;
    1 )
        post_message="\n    One error occurred during post-install."
        Explain_technotes=true
        ;;
    * )
        post_message="
    $Post_install_errors errors occurred during post-install."
        Explain_technotes=true
        ;;
    esac
    set +x

    echo "$delim"
    print "    ${exit_message}${inst_message}$post_message"
    if $Explain_technotes
    then
        print "    For answers to frequently asked questions please visit our
    Technical Support pages at:
      $SUPPORT_URL"
        if [ -n "$rs_Update_Url" -a "$user_warned_of_platform" = yes ]
        then
            print "
    Check the following web address for the latest
    $rs_Suite_Name updates and platform support:

      $rs_Update_Url"
        fi
    fi

    # Cleanup files in RM list.
    if [ -f $RM_LIST ]
    then
        . $RM_LIST
        /bin/rm -f $RM_LIST
    fi

    if ${Save_defaults:-true}
    then
        if ${Save_lic_parms:-false}
        then
            if [ -n "$PROD_DEFAULTS" ]
            then
                rsf_save_defaults
                print "    Defaults saved in:\n    $PROD_DEFAULTS"
            fi
        fi
    fi

    rsf_exit $exit_status
}

#------------------------------------------------------------------------
function rsf_set_file_size
{
    # Check size against actual size.
    # On Linux use /usr/bin/perl (if available) and the -s file operator.
    # Why?  The 'ls -l' command is not reliable on Linux.
    # The position of the file size is depends on the way it formats the date.
    # This can make the ls -l operation below fail.
    case $sys in
    i386_linux2|s390x )
        if [ -x /usr/bin/perl ]
        then
            tmpSizFile=/tmp/$CMD.perl.size.$$
            (
            echo '$sizeOfFile = -s ' "\"$1\";"
            echo 'print "$sizeOfFile";'
            echo 'exit 0;'
            ) > $tmpSizFile
            /usr/bin/perl $tmpSizFile
            rm -f $tmpSizFile
            unset tmpSizFile
            return
        fi
        ;;
    esac

    set -- $(LANG= /bin/ls -l $1 2>/dev/null)
    if [ $# -gt 8 ]
    then
        print $5
    else
        print $4
    fi
}

#------------------------------------------------------------------------
function rsf_set_file_Ksize
{
    # Check size against actual size.
    _size=$(rsf_set_file_size $1)
    if [ $_size -lt 1000 ]
    then
        print 1
    else
        let _size=_size/1024
        let _rem=_size%1024
        if [ $_rem -gt 0 ]
        then
            let _size=_size+1
        fi
        print $_size
    fi
}

#------------------------------------------------------------------------
function rsf_set_ftp_cmd
{
    if [ -z "$FTP_CMD" ]
    then
        for dir in /usr/ucb /usr/bin /usr/bsd /bin
        do
            if [ -x $dir/ftp ]
            then
                FTP_CMD=$dir/ftp
                break
            fi
        done
        FTP_CMD=${FTP_CMD:-ftp}
        FTP_LOGIN="open $FTP_SERVER
user ftp ${USER}@"
    fi
}

#------------------------------------------------------------------------
function rsf_ftp_get
{
    ftp_src=$1
    ftp_dst=$2
    ftp_siz=$3

    rsf_set_ftp_cmd

    # First check if we already have the file.
    if [ -s $ftp_dst ]
    then
        # We have it. Check the size of the file if we can.
        if [ -z "$ftp_siz" ]
        then
            # Don't know the size of file so just return okay.
            print "    Already downloaded $ftp_dst."
            return 0
        fi

        actual_size=$(rsf_set_file_size $ftp_dst)
        if [ "$actual_size" -eq ${ftp_siz:-$actual_size} ]
        then
            print "    Already downloaded $ftp_dst."
            return 0
        fi
        Downloading="Re-downloading"
        from=" from"
        to="   to"
        Bytes="   Bytes:"
    else
        Downloading="Downloading"
        from="from"
        to="to"
        Bytes="Bytes:"
    fi

    print "\n    $Downloading ${ftp_src##*/}"
    print "           $from ftp://$FTP_SERVER${ftp_src%/*}"
    print "             $to $ftp_dst"
    if [ -n "$ftp_siz" ]
    then
        print "          $Bytes $ftp_siz"
    fi
    unset Downloading to

    ftpLog=/tmp/$CMD.ftp.$$
    ftpStatus=1
    print "$FTP_LOGIN\n bin \n get $ftp_src $ftp_dst" | $FTP_CMD -n > $ftpLog 2>&1
    if [ -s $ftp_dst ]
    then
        if [ -z "$ftp_siz" ]
        then
            # Don't know the size of file so assume it is okay.
            ftpStatus=0
            print "    Got it."
        else
            actual_size=$(rsf_set_file_size $ftp_dst)
            if [ "$actual_size" -eq "${ftp_siz:-$actual_size}" ]
            then
                ftpStatus=0
                print "    Got it."
                sleep 2
            else
                cat $ftpLog
                print "
    File size mismatch.
    Size of $ftp_dst: $actual_size
    Expected size: $ftp_siz bytes"
                rsf_pause
            fi
        fi
    else
        cat $ftpLog
        print "    Failed to download ${ftp_src##*/}."
        case $ftp_dst in
        */rs_install.info )
            ;;
        * )
            rsf_pause Q
            ;;
        esac
    fi
    rm -f $ftpLog
    return $ftpStatus
}

#------------------------------------------------------------------------
function rsf_download_me
{
    # So this function is only called once.
    test -n "$Download_status"  && return

    # Download rs_install.info file.
    /bin/rm -f /tmp/rs_install.info
    rsf_ftp_get $FTP_SCRIPTS/rs_install.info /tmp/rs_install.info
    if [ ! -s /tmp/rs_install.info ]
    then
        Download_status="    Cannot access $FTP_SERVER."
        return
    fi

    # Compare the version of this command with the one on the FTP server.
    . /tmp/rs_install.info
    /bin/rm -f /tmp/rs_install.info
    NEW_REV=${REV%.*}.$new_file_num
    if [ $RevN -ge $new_file_num ]
    then
        if [ $RevN -eq $new_file_num ]
        then
            Download_status="
    You are running $CMD version $REV which is the latest version.
    The version on the FTP server is also $NEW_REV.
    Download of $CMD not needed."

        else
            Download_status="
    You are running $CMD version $REV which is newer than the one
    on the FTP server (version $NEW_REV).
    Download of $CMD not needed."

        fi
        return
    fi

    print "
    You are running $CMD version $REV which is older than the one
    on the FTP server (version $NEW_REV)."

    if [ "$CMD" = rs_install ]
    then
        print "    Will download $CMD version $NEW_REV..."
    else
        print "    Will download $CMD version $NEW_REV (alias rs_install)..."
    fi

    # Download rs_install.  If rs_install is a wrapper, or it is not
    # writable or the directory is writable, put it in /tmp.
    TO_DIR=$(dirname $FILE)
    Doing_download=true
    if [ -w $FILE -a  -w $TO_DIR ]
    then
        /bin/mv $TO_DIR/rs_install $TO_DIR/rs_install.$REV 2>/dev/null &&
            print "    Saved backup of rs_install as rs_install.$REV."
        rsf_ftp_get $FTP_SCRIPTS/rs_install $TO_DIR/rs_install $new_file_size
        get_status=$?
        unset Doing_download
        if [ $get_status -ne 0 ]
        then
            /bin/rm -f $TO_DIR/rs_install
            /bin/mv $TO_DIR/rs_install.$REV $TO_DIR/rs_install
            Download_status="    Download of $CMD failed.  Version $REV of"
            Download_status="$Download_status rs_install restored."
            return
        fi
        NEW_CMD=./$CMD
    else
        /bin/rm -f /tmp/rs_install
        rsf_ftp_get $FTP_SCRIPTS/rs_install /tmp/rs_install $new_file_size
        unset Doing_download
        if [ $? -ne 0 ]
        then
            /bin/rm -f /tmp/rs_install
            Download_status="    Download of $CMD failed."
            return
        fi
        cd /tmp
        NEW_CMD=/tmp/$CMD
        /bin/rm -f rs_install.version
        echo NEW_REV=$new_file_num > rs_install.version
        chmod 666 rs_install.version 2>/dev/null
    fi

    chmod 775 rs_install 2>/dev/null

    # Create new links to command or copies for its aliases.
    for alias in $Cmd_Aliases
    do
        /bin/rm -f $alias
        /bin/ln -s rs_install $alias
    done

    cd $DIR
    rsf_pause
    Download_status="    Already downloaded the latest version of $CMD."
    export Download_status

    # Run new rs_install command.
    exec $BKSH $NEW_CMD $CMD_OPTS
    # Note: BKSH can be set to ksh or bash.
    exit $?  # Exec does not return. This command should not get run.
}

#------------------------------------------------------------------------
function rsf_show_owner
{
    _file_or_dir="$1"
    _fd_name=$2
    case $sys in
    sun )
        set -- $(/bin/ls -ldg $_fd_name)
        ;;
    * )
        set -- $(/bin/ls -ld $_fd_name)
        ;;
    esac
    _perms=$1
    _owner=$3
    _group=$4

    _aug_w="a+w"
    if [ "$_owner" = "$USER" ]
    then
        _aug_w="u+w"
    else
        for _g in $(groups 2>/dev/null)
        do
            if [ "$_g" = "$_group" ]
            then
                _aug_w="g+w"
            fi
        done
    fi

    Suggestion="Do this as $3:\n            chmod $_aug_w $_fd_name"

    print "\n    You do not have permissions to update $_file_or_dir:
      $_fd_name
        Owner:       $_owner
        Group:       $_group
        Permissions: $_perms

    Suggestion:
      Make sure $_file_or_dir is writable by $USER.
      $Suggestion"

    unset _file_or_dir _fd_name _perms _owner _group _aug_w
}

#------------------------------------------------------------------------
function rsf_file_dir_writable
{
    # Do not need permission to update if only using file.
    $Use_existing_licenses && return 0

    # Make sure we can update the file and the
    # enclosing directory.

    _name=$1
    if [ -d $_name ]
    then
        print "\n    You entered a directory:\n      $_name"
        return 1
    fi

    if touch $_name 2>/dev/null
    then
        # File is writable. Now check enclosing directory.
        if touch $_name.$USER.priorN 2>/dev/null
        then
            /bin/rm -f $_name.$USER.priorN
            unset _name
            return 0
        else
            rsf_show_owner "the enclosing directory" ${_name%/*}
        fi
    else
        # File is not writable. Check enclosing directory too.
        rsf_show_owner "this file" $_name
        if touch $_name.$USER.priorN 2>/dev/null
        then
            /bin/rm -f $_name.$USER.priorN
        else
            print "\n$delim\n    Also..."
            rsf_show_owner "the enclosing directory" ${_name%/*}
        fi
    fi
    rsf_pause
    unset _name
    return 1
}

#------------------------------------------------------------------------
function rsf_get_latest_pplus_ver
{
    # Determine the latest version of PurifyPlus product (arg1) and
    # platform (arg2..argN).  If not found, return 'not-installed'.
    _prod=$1
    shift
    unset _found
    for _plat in $*
    do
        for _pplus in $Releases/$_prod.$_plat.*
        do
            if [ -d $_pplus ]
            then
                _found=$_pplus
                _prodPlat=$_prod.$_plat
            fi
        done
    done
    if [ -n "$_found" ]
    then
        echo ${_found##*/$_prodPlat.}
    else
        echo not-installed
    fi
}

#------------------------------------------------------------------------
function rsf_sed_rsu_parms
{
  case $1 in
  */clearquest.sh )
      Use_Lic_File=${Actual_License_File:-$License_File}
      ;;
  */purifyplus_setup.* )
      purify_aix_ver=$(rsf_get_latest_pplus_ver purify aix)
      purify_hp_ver=$(rsf_get_latest_pplus_ver purify hp)
      purify_hpia_ver=$(rsf_get_latest_pplus_ver purify hpia)
      purify_i386_linux2_ver=$(rsf_get_latest_pplus_ver purify i386_linux2)
      purify_sol_ver=$(rsf_get_latest_pplus_ver purify sol)
      purify_solaris_x64_ver=$(rsf_get_latest_pplus_ver purify solaris_x64)
      quantify_aix_ver=$(rsf_get_latest_pplus_ver quantify aix)
      quantify_hp_ver=$(rsf_get_latest_pplus_ver quantify hp)
      quantify_hpia_ver=$(rsf_get_latest_pplus_ver quantify hpia)
      quantify_i386_linux2_ver=$(rsf_get_latest_pplus_ver quantify i386_linux2)
      quantify_sol_ver=$(rsf_get_latest_pplus_ver quantify sol)
      quantify_solaris_x64_ver=$(rsf_get_latest_pplus_ver quantify solaris_x64)
      purecov_aix_ver=$(rsf_get_latest_pplus_ver purecov aix)
      purecov_hp_ver=$(rsf_get_latest_pplus_ver purecov hp)
      purecov_hpia_ver=$(rsf_get_latest_pplus_ver purecov hpia)
      purecov_i386_linux2_ver=$(rsf_get_latest_pplus_ver purecov i386_linux2)
      purecov_sol_ver=$(rsf_get_latest_pplus_ver purecov sol)
      purecov_solaris_x64_ver=$(rsf_get_latest_pplus_ver purecov solaris_x64)
      purify_sg32_ver=$(rsf_get_latest_pplus_ver purify sg32)
      ;;
  * )
      Use_Lic_File=$License_File
      ;;
  esac

  sed \
  -e "s?%ACROBAT_VER%?$acrobat_ver?" \
  -e "s?%ARCH%?$ARCH?" \
  -e "s?%CONFIG%?$Config?" \
  -e "s?%CQWEBURL%?${rsu_cq_web_url:-none}?" \
  -e "s?%DIR_LOCATION%?$DIR_LOCATION?" \
  -e "s?%EXP_DATE%?$exp_date?" \
  -e "s?%FLEXLM_VER%?$flexlm_ver?" \
  -e "s?%HOST_ID%?$rsu_lic_hostid?" \
  -e "s?%HOST_NAME%?$HOSTNAME?" \
  -e "s?%INIT_FILE%?$init_file?" \
  -e "s?%ISSUED%?${issue_date:-$def_issue_date}?" \
  -e "s?%LICENSE_FILE%?$Use_Lic_File?" \
  -e "s?%LIC_ARCH%?$rs_Lic_Arch?" \
  -e "s?%LIC_DIR%?$Lic_Dir2?" \
  -e "s?%LIC_FILE%?$rsu_lic_file?" \
  -e "s?%LIC_HOSTID%?$rsu_lic_hostid?" \
  -e "s?%LIC_LOG%?${rsu_lic_file%.dat}.log?" \
  -e "s?%${lic_name:-LIC_NAME}%?$key?" \
  -e "s?%LIC_PORT%?$rsu_lic_port?" \
  -e "s?%LIC_SERVER%?$rsu_lic_server?" \
  -e "s?%LIC_USER%?$USER?" \
  -e "s?%LIC_VER%?$default_lic_ver?" \
  -e "s?%NETSCAPE_VER%?$netscape_ver?" \
  -e "s?%PLATFORM%?$THIS_OS?" \
  -e "s?%PQPC_VER%?$p_q_pc_ver?" \
  -e "s?%PQPC_HP_VER%?$p_q_pc_hp_ver?" \
  -e "s?%PQPC_HP_VER%?$p_q_pc_hp_ver?" \
  -e "s?%PQPC_SOL_VER%?$p_q_pc_sol_ver?" \
  -e "s?%PURIFY_VER%?$purify_ver?" \
  -e "s?%QUANTIFY_VER%?$quantify_ver?" \
  -e "s?%PURECOV_VER%?$purecov_ver?" \
  -e "s?%PURIFY_HP_VER%?$purify_hp_ver?" \
  -e "s?%PURIFY_HPIA_VER%?$purify_hpia_ver?" \
  -e "s?%PURIFY_SG32_VER%?$purify_sg32_ver?" \
  -e "s?%PURIFY_SOL_VER%?$purify_sol_ver?" \
  -e "s?%PURIFY_SOL_X86_VER%?$purify_solaris_x64_ver?" \
  -e "s?%PURIFY_SOLARIS_X64_VER%?$purify_solaris_x64_ver?" \
  -e "s?%PURIFY_LNX_VER%?$purify_i386_linux2_ver?" \
  -e "s?%PURIFY_AIX_VER%?$purify_aix_ver?" \
  -e "s?%QUANTIFY_HP_VER%?$quantify_hp_ver?" \
  -e "s?%QUANTIFY_HPIA_VER%?$quantify_hpia_ver?" \
  -e "s?%QUANTIFY_SOL_VER%?$quantify_sol_ver?" \
  -e "s?%QUANTIFY_SOL_X86_VER%?$quantify_solaris_x64_ver?" \
  -e "s?%QUANTIFY_SOLARIS_X64_VER%?$quantify_solaris_x64_ver?" \
  -e "s?%QUANTIFY_LNX_VER%?$quantify_i386_linux2_ver?" \
  -e "s?%QUANTIFY_AIX_VER%?$quantify_aix_ver?" \
  -e "s?%PURECOV_HP_VER%?$purecov_hp_ver?" \
  -e "s?%PURECOV_HPIA_VER%?$purecov_hpia_ver?" \
  -e "s?%PURECOV_SOL_VER%?$purecov_sol_ver?" \
  -e "s?%PURECOV_SOL_X86_VER%?$purecov_solaris_x64_ver?" \
  -e "s?%PURECOV_SOLARIS_X64_VER%?$purecov_solaris_x64_ver?" \
  -e "s?%PURECOV_LNX_VER%?$purecov_i386_linux2_ver?" \
  -e "s?%PURECOV_AIX_VER%?$purecov_aix_ver?" \
  -e "s?%PROD_HOME%?$Suite_Path?" \
  -e "s?%PRODUCT_DIR%?$rs_Suite_Dir?" \
  -e "s?%PRODUCT_NAME%?$rs_Suite_Name $rs_Suite_Ver?" \
  -e "s?%QUANTITY%?$Quantity?" \
  -e "s?%RATIONAL_DIR%?$rsu_rational_dir?" \
  -e "s?%ROSE_VER%?$rose_ver?" \
  -e "s?%ROSE_HP_VER%?$rose_hp_ver?" \
  -e "s?%ROSE_SOL_VER%?$rose_sol_ver?" \
  -e "s?%ROSERT_VER%?$rosert_ver?" \
  -e "s?%ROSERT_HP_VER%?$rosert_hp_ver?" \
  -e "s?%ROSERT_SOL_VER%?$rosert_sol_ver?" \
  -e "s?%RPWEBURL%?${rsu_rp_web_url:-none}?" \
  -e "s?%RSDSU_ROOT%?$rsu_rational_dir?" \
  -e "s?%CQ_VER%?$cq_ver?" \
  -e "s?%CQ_HP_VER%?$cq_hp_ver?" \
  -e "s?%CQ_SOL_VER%?$cq_sol_ver?" \
  -e "s?%RUP_VER%?$rup_ver?" \
  -e "s?%RUP_HP_VER%?$rup_hp_ver?" \
  -e "s?%RUP_SOL_VER%?$rup_sol_ver?" \
  -e "s?%SODA_VER%?$soda_ver?" \
  -e "s?%SODA_HP_VER%?$soda_hp_ver?" \
  -e "s?%SODA_SOL_VER%?$soda_sol_ver?" \
  -e "s?%SUITE_VER%?$rs_Suite_Ver?" \
  -e "s?%USER%?$USER?" \
  -e "s?%VDAEMON%?$vendor_daemon?" \
  -e "s?%VENDOR%?$rs_vendor?" \
  -e "s?%VERSION%?$rs_Suite_Ver?" \
  $1
}

#------------------------------------------------------------------------
function rsf_sort_num
{
    for _item in $*
    do
        echo "$_item"
    done | sort +n
}

#------------------------------------------------------------------------
function rsf_in_Working_List
{
    test -z "$Working_List" && return 1
    if print " $Working_List " | grep " $1 " >/dev/null
    then
        return 0
    else
        return 1
    fi
}

#------------------------------------------------------------------------
function rsf_is_a_link
{
    if [ -L $1 ]
    then
        # The last arg is the file arg 1 points to.
        set -- $(/bin/ls -l $1)
        let args=$#-1
        shift $args
        eval print $1
        return 0
    else
        return 1
    fi
}

#------------------------------------------------------------------------
function rsf_sntoint
{
    # Convert a number from scientific notation to integer.
    # Expected format is M.De+E
    case $1 in
    *.*e+* )
        _SN=$1
        ;;
    * )
        # No conversion needed.
        print $1
        return
        ;;
    esac

    (
    # Extract the components of the scientific number.
    _M=${_SN%%.*}
    _D=${_SN%e+*}
    _D=${_D#*.}
    _E=${_SN##*e+}

    _NUM=${_M}${_D}
    _LEN=${#_D}
    # Pad number with zeros until the length of the number matches
    # the exponent.
    while [ $_LEN -lt $_E ]
    do
        _NUM=${_NUM}0
        let _LEN=_LEN+1
    done
    print $_NUM
    )
    unset _SN
}

#------------------------------------------------------------------------
function rsf_remove_dir
{
    (
    for _d in $*
    do
        if [ -d $_d ]
        then
            if [ ! -w $_d ]
            then
                chmod -R u+w $_d
            fi
            /bin/rm -fr $_d
        elif [ -f $_d ]
        then
            /bin/rm -f $_d
        else
            continue
        fi

        if [ -d $_d ]
        then
            chmod -R u+w $_d
            /bin/rm -fr $_d
        elif [ -f $_d ]
        then
            chmod u+w $_d
            /bin/rm -f $_d
        fi
    done
    ) >/dev/null 2>&1
}

#------------------------------------------------------------------------
function rsf_create_dot_prod_name_ver
{
    print "prod_name_ver='$2 $3'" > $1/.prod_name_ver
    chmod 666 $1/.prod_name_ver >/dev/null 2>&1
}

#------------------------------------------------------------------------
function rsf_tarcp
{
    _check=$1
    tarcp_src=$2
    tarcp_dst=$3

    if [ "$4" != '-q' ]
    then
        print "    from: $tarcp_src"
        print "      to: $tarcp_dst"
    fi

    if [ $_check = check ]
    then
        if [ -d $prod_dst/. ]
        then
            totalN=1
            if rsf_reinstall_product product
            then
                rsf_remove_dir $prod_dst
            else
                return 1
            fi
        fi
        rsf_make_dir $tarcp_dst now
    fi

    # The K option is used on IRIX machines to ignore directories or
    # files larger than 2 gigabytes.  The directories rs_install is
    # copying are way less than this but there is an NFS problem
    # on IRIX 6.5.1 through 6.5.5 that incorrectly shows directories
    # being 4 gigabytes, so using the K option works around this problem.
    case $sys in
    sg32 ) K_opt=K ;;
       * ) K_opt=  ;;
    esac

    (cd $tarcp_src; tar -c${K_opt}f - . 2>/dev/null) |
        (cd $tarcp_dst; $tar_xf -; exit $?)
    if [ $? -ne 0 ]
    then
        let Install_errors=Install_errors+1
        return 1
    fi
    return 0
}

#------------------------------------------------------------------------
function rsf_install_prod_cmp
{
    # Return true if component description entry is in prod_cmp file.
    test -f $prod_cmp || return 1
    grep "^$cmp_desc ck " $prod_cmp >/dev/null && return 0
    grep "^$cmp_desc\$" $prod_cmp >/dev/null && return 0
    return 1
}

#------------------------------------------------------------------------
function rsf_update_prod_cmp
{
    if [ -z "$cksum" ]
    then
        if [ -f $prod_cmp ]
        then
            if grep "^$cmp_desc\$" $prod_cmp >/dev/null
            then
                return
            fi
        fi
        print "$cmp_desc" >> $prod_cmp
        return
    fi

    ckdesc="$cmp_desc ck $cksum"
    if [ -f $prod_cmp ]
    then
        if grep "^$ckdesc\$" $prod_cmp >/dev/null
        then
            return
        fi
        (
        grep -v "^$cmp_desc" $prod_cmp
        print "$ckdesc"
        ) >> $prod_cmp.new
        /bin/cp $prod_cmp.new $prod_cmp
        /bin/rm -f $prod_cmp.new
    else
        print "$ckdesc" >> $prod_cmp
    fi
}

#------------------------------------------------------------------------
function rsf_copy
{
    # Copy files from dir1 to dir2.
    _want_reinstall=false
    if [ "$1" = '-p' ]
    then
        _pre="    "
        _quiet='-q'
        shift
    elif [ "$1" = '-r' ]
    then
        _pre="    "
        _quiet='-q'
        _want_reinstall=true
        shift
    else
        _pre="\n    "
        unset _quiet
    fi
    test $# -eq 3 || return
    prod_name_ver="$1"
    dir1=$2
    dir2=$3
    test "$dir1" = "$dir2" && return
    Installing_what="${_pre}Installing: ${prod_name_ver}..."

    # Make dir2 if necessary.
    if [ -d "$dir2" ]
    then
        _dir2_already_exists=true
    else
        _dir2_already_exists=false
        print "$Installing_what"
        unset Installing_what
        rsf_make_dir $dir2 now
        if [ $? -ne 0 ]
        then
            print_e "
    Cannot continue until this directory can be created:
      $dir2"
            rsf_cleanup 2
        fi
    fi

    # Check if the directory is controlled by an update level file.
    # If it is, and dir2 already existed, and it is not up-to-date, reinstall.
    need_reinstall=false
    if $_want_reinstall
    then
        need_reinstall=true
    elif $_dir2_already_exists
    then
        if [ -f $dir1/.update_level ]
        then
            if [ -f $dir2/.update_level ]
            then
                if [ "$(cat $dir1/.update_level)" != \
                     "$(cat $dir2/.update_level)" ]
                then
                    need_reinstall=true
                fi
            else
                need_reinstall=true
            fi
        fi
    fi

    if $need_reinstall
    then
        print "${_pre}Reinstalling: ${prod_name_ver}..."
        rsf_remove_dir $dir2
        rsf_make_dir $dir2 now
        rsf_tarcp nocheck $dir1 $dir2 $_quiet
        return $?
    fi

    # If all files are already installed, return.
    if $_dir2_already_exists
    then
        _installed=true
        for _file in $dir1/*
        do
            if [ -f $_file -o -d $_file ]
            then
                _file_name=${_file##*/}
                if [ -f $dir2/$_file_name -o -d $dir2/$_file_name ]
                then
                    continue
                fi
                _installed=false
                break
            fi
        done
        if $_installed
        then
            print "${_pre}Installed: ${prod_name_ver}"
            return
        fi
    fi

    if $_dir2_already_exists
    then
        print "${_pre}Reinstalling: ${prod_name_ver}..."
        rsf_remove_dir $dir2
        rsf_make_dir $dir2 now
    elif [ -n "$Installing_what" ]
    then
        print "$Installing_what"
    fi
    rsf_tarcp nocheck $dir1 $dir2 $_quiet
}

#-----------------------------------------------------------------
function rsf_set_revision
{
    case $1 in
    *.ini )
        set -- 1 $(grep '^<version> ' $1)
        ;;
    * )
        set -- 1 $(egrep 'Version:|Revision:' $1)
        ;;
    esac

    shift
    while [ $# -gt 0 ]
    do
        case "$1" in
        \<version\> )
            print ${2#*.}
            return
            ;;
        *Version: )
            print ${2#*.}
            return
            ;;
        *Revision: )
            case $2 in
            /main/* )
                print ${2#/main/}
                ;;
            * )
                print ${2#*.}
                ;;
            esac
            return
            ;;
        esac
        shift
    done
    print 1
}

#-----------------------------------------------------------------
function rsf_update_config
{
    # Update same arg1 file in the config directory or file arg2 if specified.
    inst_file=$1
    test -f $inst_file || return

    if [ -n "$2" ]
    then
        config_file=$2
    else
        config_file=$Config/${inst_file##*/}
    fi
    new_file_num=$(rsf_set_revision $inst_file)

    if [ -f $config_file ]
    then
        # Config file exists -- update if necessary
        curr_file_num=$(rsf_set_revision $config_file)
        if [ $new_file_num -gt $curr_file_num ]
        then
            print "\n    Updating:   $config_file [rev $new_file_num]"
            /bin/rm -f $config_file
            /bin/cp $inst_file $config_file
        elif [ $new_file_num -eq $curr_file_num ]
        then
            diff $config_file $inst_file >/dev/null
            if [ $? -ne 0 ]
            then
                print "\n    Updating:   $config_file [rev $new_file_num]"
                /bin/rm -f $config_file
                /bin/cp $inst_file $config_file
            fi
        fi
    else
        print "\n    Installing: $config_file [rev $new_file_num]"
        /bin/cp $inst_file $config_file
    fi
}

#-----------------------------------------------------------------
function rsf_set_sys_arch
{
    # Set sys_arch to the arch name corresponding to sys name.
    case $1 in
    aix )
        sys_arch=rs6k_aix
        ;;
    axp )
        sys_arch=alpha_osf1
        ;;
    hpia )
        sys_arch=hpia
        ;;
    hp )
        sys_arch=hppa_hpux
        ;;
    *linux* )
        sys_arch=i386_linux2
        ;;
    sg32 )
        sys_arch=mips_irix_n32
        ;;
    sol )
        sys_arch=sun4_solaris2
        ;;
    solaris_x64|sol_x86 )
        sys_arch=solaris_x64
        ;;
    * )
        sys_arch=unknown
        ;;
    esac
}

#-----------------------------------------------------------------
function rsf_set_OS
{
    case $1 in
    aix|*/aix/* )
        OS="$os_name_aix"
        ;;
    axp|*/axp/* )
        OS="$os_name_axp"
        ;;
    hp|*/hp/* )
        OS="$os_name_hp"
        ;;
    hp64|*/hp64/* )
        OS="$os_name_hp64"
        ;;
    hp10|*/hp10/* )
        OS="$os_name_hp10"
        ;;
    hp11|*/hp11/* )
        OS="$os_name_hp11"
        ;;
    hpia|*/hpia/* )
        OS="$os_name_hpia"
        ;;
    *linux* )
        OS="$os_name_linux"
        ;;
    sgi|*/sgi/* )
        OS="$os_name_sgi"
        ;;
    sg32|*/sg32/* )
        OS="$os_name_sg32"
        ;;
    solaris_x64|*/solaris_x64/* )
        OS="$os_name_solaris_x64"
        ;;
    sol|*/sol/* )
        OS="$os_name_sol"
        ;;
    sun|*/sun/* )
        OS="$os_name_sun"
        ;;
    * )
        OS="$os_name_any"
        ;;
    esac
}

#-----------------------------------------------------------------
function rsf_set_other_OS
{
    case $1 in
    aix )
        other_OS="$os_name_aix"
        an_other_OS="an $other_OS"
        other_ARCH=rs6k_aix
        ;;
    axp )
        other_OS="$os_name_axp"
        an_other_OS="a $other_OS"
        other_ARCH=alpha_osf1
        ;;
    hp10 )
        other_OS="$os_name_hp10"
        an_other_OS="an $other_OS"
        other_ARCH=hppa_hpux
        ;;
    hp11 )
        other_OS="$os_name_hp11"
        an_other_OS="an $other_OS"
        other_ARCH=hppa_hpux
        ;;
    hp64 )
        # If on an HP-UX system, check if it has a 64 bit kernel.
        if [ "$sys" = hp ]
        then
            if getconf KERNEL_BITS 2>&1 | grep 64 >/dev/null
            then
                # This is a 64-bit kernel, so the other OS must
                # be set to the current OS.
                other_OS="$THIS_OS"
                an_other_OS="an $other_OS"
                other_ARCH=hppa_hpux
                return
            fi
        fi
        other_OS="$os_name_hp64"
        an_other_OS="an $other_OS"
        other_ARCH=hppa_hpux
        ;;
    hpia )
        other_OS="$os_name_hpia"
        an_other_OS="an $other_OS"
        other_ARCH=hpia
        ;;
    hp* )
        other_OS="$os_name_hp"
        an_other_OS="an $other_OS"
        other_ARCH=hppa_hpux
        ;;
    *linux* )
        other_OS="$os_name_linux"
        an_other_OS="a $other_OS"
        other_ARCH=i386_linux2
        ;;
    s390x )
        other_OS="$os_name_s390x"
        an_other_OS="a $other_OS"
        other_ARCH=s390x
        ;;
    sgi )
        other_OS="$os_name_sgi"
        an_other_OS="an $other_OS"
        other_ARCH=mips_irix5
        ;;
    sg32 )
        other_OS="$os_name_sg32"
        an_other_OS="an $other_OS"
        other_ARCH=mips_irix_n32
        ;;
    sol )
        other_OS="$os_name_sol"
        an_other_OS="a $other_OS"
        other_ARCH=sun4_solaris2
        ;;
    sol64 )
        other_OS="$os_name_sol (64 bit)"
        an_other_OS="a $other_OS"
        other_ARCH=sun4_solaris2
        ;;
    solaris_x86|sol_x86 )
        other_OS="$os_name_solaris_x86"
        an_other_OS="a $other_OS"
        other_ARCH=solaris_x86
        ;;
    solaris_x64|sol_x64 )
        other_OS="$os_name_solaris_x64"
        an_other_OS="a $other_OS"
        other_ARCH=solaris_x64
        ;;
    esac
}

#------------------------------------------------------------------------
function rsf_set_arch_os
{
    LS=/bin/ls
    LSL="$LS -l"
    LSN="$LS -nd"
    RSH=rsh
    RCP=/bin/rcp
    DF=/bin/df
    SUM=/bin/sum
    DF_CMD="$DF -k"
    if [ "$USER" = root ]
    then
        tar_xf='tar -xof'
    else
        tar_xf='tar -xf'
    fi
    UNCOMPRESS=uncompress
    sym_link='-L'
    os_name_ver=$(uname -sr)
    case $os_name_ver in
    OSF1* )
        THIS_OS="$os_name_axp"
        OS_NAME=OSF1
        ARCH=alpha_osf1
        sys=axp
        path_dirs=/bin:/usr/bin:/usr/ucb:/usr/ccs/bin:/usr/sbin:/etc
        init_file=/sbin/init.d/S98Rational
        link_to_init_file=/sbin/rc3.d/S89Rational
        obs_init_list="/sbin/init.d/SlmRational.sh /sbin/rc3.d/S89Rational.sh"
        du_opt='-sk'
        ;;
    HP-UX* )
        case `uname -m` in
        ia64 )
            THIS_OS="$os_name_hpia"
            OS_NAME="$os_name_hpia"
            os_name_ver="HP-UX IA64 $(uname -r)"
            sys=hpia
            ARCH=$sys
            ;;
        * )
            THIS_OS="$os_name_hp"
            OS_NAME="$os_name_hp"
            ARCH=hppa_hpux
            sys=hp
            ;;
        esac
        DF=/usr/bin/bdf
        DF_CMD=$DF
        RSH=remsh
        path_dirs=/bin:/usr/bin:/etc
        init_file=/sbin/init.d/S98Rational
        link_to_init_file=/sbin/rc2.d/S98Rational
        obs_init_list="/sbin/init.d/SlmRational.sh /sbin/rc2.d/SlmRational.sh"
        du_opt='-sk'
        ;;
    AIX* )
        THIS_OS="$os_name_aix"
        OS_NAME="$os_name_aix"
        ARCH=rs6k_aix
        sys=aix
        path_dirs=/bin:/usr/bin:/usr/ucb:/etc
        init_file=/etc/inittab
        os_name_ver="$os_name_aix $(oslevel)"
        ;;
    IRIX?5.* )
        THIS_OS="$os_name_sgi"
        OS_NAME=IRIX
        ARCH=mips_irix5
        RCP=/usr/bsd/rcp
        sys=sgi
        path_dirs=/usr/bin:/usr/bsd:/usr/ucb:/usr/etc:/usr/sbin:/etc
        init_file=/etc/init.d/S98Rational
        link_to_init_file=/etc/rc2.d/S98Rational
        obs_init_list="/etc/init.d/SlmRational.sh /etc/rc2.d/SlmRational.sh"
        du_opt='-sk'
        ;;
    IRIX64*|IRIX?[6-9].* )
        THIS_OS="$os_name_sg32"
        OS_NAME=IRIX
        ARCH=mips_irix_n32
        RCP=/usr/bsd/rcp
        sys=sg32
        path_dirs=/usr/bin:/usr/bsd:/usr/ucb:/usr/etc:/usr/sbin:/etc
        init_file=/etc/init.d/S98Rational
        link_to_init_file=/etc/rc2.d/S98Rational
        obs_init_list="/etc/init.d/SlmRational.sh /etc/rc2.d/SlmRational.sh"
        du_opt='-sk'
        ;;
    SunOS?5.* )
        case `uname -p` in
        sparc )
            THIS_OS="$os_name_sol"
            OS_NAME="$os_name_sol"
            ARCH=sun4_solaris2
            sys=sol
            ;;
        i?86|x86* )
            THIS_OS="$os_name_solaris_x86"
            OS_NAME="$os_name_solaris_x86"
            ARCH=solaris_x86
            sys=solaris_x86
            os_name_ver="Solaris x86"
            if [ -x /bin/isainfo ]
            then
                case `/bin/isainfo -b` in
                64 )
                    os_name_ver="Solaris x64"
                    THIS_OS="$os_name_solaris_x64"
                    OS_NAME="$os_name_solaris_x64"
                    ARCH=solaris_x64
                    sys=solaris_x64
                    ;;
                esac
            fi
            os_name_ver="$os_name_ver $(uname -r)"
            ;;
        * )
            os_bailout='exit 1'
            return
            ;;
        esac
        path_dirs=/usr/ucb:/bin:/usr/bin:/usr/5bin:/etc:/usr/ccs/bin
        init_file=/etc/rc2.d/S98Rational
        obs_init_list="/etc/rc2.d/SlmRational.sh"
        du_opt='-sk'
        # Check the hard limit for the number of file descriptors.
        # Needs to be 1024 to do FLEXlm commands.
        actual_fd_limit=`ulimit -H -n`

        case "$actual_fd_limit" in
        [0-9]* )
            if [ "$actual_fd_limit" -gt 1024 ]
            then
                ulimit -n 1024
                ulimit -H -n 1024
            fi
            ;;
        unlimited )
            ulimit -n 1024
            ulimit -H -n 1024
            ;;
        esac
        ;;
    Linux*2.* )
        THIS_OS="$os_name_linux"
        OS_NAME="$os_name_linux"
        case $(uname -m) in
        s390x )
            ARCH=s390x
            sys=s390x
            ;;
        * )
            ARCH=i386_linux2
            sys=i386_linux2
            ;;
        esac
        DF=df
        DF_CMD="$DF -k"
        LS=ls
        LSL="$LS -l"
        LSN="$LS -lnd"
        RCP=rcp
        SUM=sum
        UNCOMPRESS=gunzip
        tarOptO=''
        path_dirs=/bin:/usr/bin
        link_to_init_file="/etc/rc.d/rc3.d/S98Rational
          /etc/rc.d/rc4.d/S98Rational
          /etc/rc.d/rc5.d/S98Rational"
        if [ -d /etc/init.d -a -x /sbin/yast2 -a -x /sbin/chkconfig ]
        then
            init_file=/etc/init.d/ibmrational
            link_to_init_file="/sbin/chkconfig"
        elif [ -d /etc/rc.d/init.d ]
        then
            init_file=/etc/rc.d/init.d/S98Rational
        elif [ -d /etc/rc.d ]
        then
            init_file=/etc/rc.d/S98Rational
        else
            init_file=/etc/S98Rational
        fi
        obs_init_list="/etc/rc.d/rc2.d/SlmRational.sh
          /etc/rc.d/init.d/SlmRational.sh"
        RCP=/usr/bin/rcp
        du_opt='-sk'
        Do_underling=false
        if [ -f /etc/issue ]
        then
            linuxRel=`grep -i release /etc/issue`
        fi
        ;;
    * )
        os_bailout='exit 1'
        ;;
    esac

    test "$OS_NAME" = "$os_name_linux" || return

    # Check the following commands exist.
    # Report potential problems may occur if they do not.
    First_unix_warn="
    Potential install and licensing problems exist.

    The $CMD command uses the following commands and they do not exist:\n"
    unset do_pause
    for unix_cmd in \
        /bin/cat \
        /bin/chmod \
        /bin/cp \
        /bin/ln \
        /bin/ls \
        /bin/mv \
        /bin/ps \
        /bin/rm \
        /bin/rmdir \
        /bin/sh \
        /bin/stty
    do
        if [ ! -x $unix_cmd ]
        then
            if [ -n "$First_unix_warn" ]
            then
                rsf_display_warning
                print "$First_unix_warn"
                unset First_unix_warn
                do_pause="rsf_pause Q"
            fi
            print "      $unix_cmd"
        fi
    done
    $do_pause
}

#------------------------------------------------------------------------
function rsf_set_flexlm_OS_list
{
    # Set the list of supported O/S's for FLEXlm.
    # The suite_description.flexlm file will have a complete
    # list.  Only use the ones that have FLEXlm in the release.
    unset flexlm_OS_list
    if [ -f $SUITE_DESCRIPTION.flexlm ]
    then
        # This file overrides all those O/S lists in the else clause.
        . $SUITE_DESCRIPTION.flexlm
    else
        # If the product does not contain the flexlm OS lists set
        # some reasonable defaults (as of March 2002).
        flexlm_OS_aix="AIX 4.3.*
                       AIX 5.1.*
                       AIX 5.2.*
                       AIX 5.3.*"
        flexlm_OS_hp="HP-UX B.10.20
                      HP-UX B.11.*"
        flexlm_OS_hpia="HP-UX IA64 B.11.*"
        flexlm_OS_i386_linux2="Linux 2.*"
        flexlm_OS_sol="SunOS 5.7
                       SunOS 5.8
                       SunOS 5.9
                       SunOS 5.10"
    fi

    for _flexlm in \
        $DIR/extras/flexlm/* \
        $DIR/extras/flexlm.* \
        ../../base/cots/flexlm.$flexlm_ver/*
    do
        test -d "$_flexlm" || continue
        if [ -f "$_flexlm/versions" ]
        then
            _flex_sys=${_flexlm%/versions}
            _flex_sys=${_flex_sys##*/flexlm.}
            _flex_sys=${_flex_sys##*/}
        else
            _flex_sys=${_flexlm##*/}
            _flex_sys=${_flex_sys##*.}
        fi
        case $_flex_sys in
            alpha_osf1    ) _flex_sys=axp  ;;
            hppa_hpux     ) _flex_sys=hp   ;;
            mips_irix_n32 ) _flex_sys=sg32 ;;
            rs6k_aix      ) _flex_sys=aix  ;;
            sun4_solaris2 ) _flex_sys=sol  ;;
            solaris_x64   ) _flex_sys=solaris_x64 ;;
            sol_x86       ) _flex_sys=solaris_x64 ;;
        esac
        eval _flex_os=\$flexlm_OS_$_flex_sys
        flexlm_OS_list="$flexlm_OS_list
$_flex_os"
    done
    unset _flexlm _flex_sys _flex_os
}

#------------------------------------------------------------------------
function rsf_check_OS_list
{
    print "$OS_list" | while read supported
    do
        test -n "$supported" || continue
        case $supported in
        ISSUE* )
            if [ -f /etc/issue ]
            then
                set -f
                set -- $supported
                shift
                supported=$*
                set +f
                if grep "$supported" /etc/issue >/dev/null
                then
                    echo true
                    return
                fi
            fi
            continue
            ;;
        * )
            case "$os_name_ver" in
            $supported* )
                echo true
                return
                ;;
            esac
        ;;
        esac
    done
}

#------------------------------------------------------------------------
function rsf_get_linux_issue
{
    _info=""
    cat /etc/issue | while read line
    do
        if [ -n "$line" ]
        then
            set -f
            set -- $line
            set +f
            while [ $# -gt 0 ]
            do
                case $1 in
                Welcome ) shift ;;
                    \(* ) break ;;
                      * ) _info="$_info $1" ;;
                esac
                shift
            done
            echo "${_info# }"
            break
        fi
    done
}

#------------------------------------------------------------------------
function rsf_check_os_level
{
    ${Skip_OS_check:-false} && return
    os_check_opt=$1
    case $os_check_opt in
    flex|license_check|license_setup )
        # The O/S supported by these scripts is dependent on FLEXlm,
        # not on the products in the release.
        rsf_set_flexlm_OS_list
        OS_list=$flexlm_OS_list
        nr_OS_list="$flexlm_nr_OS_list"
        ;;
    rs_install )
        # The O/S supported by all the other scripts are dependent on
        # the products in the release.
        OS_list=$support_OS_list
        ;;
    * )
        return
        ;;
    esac

    os_okay=$(rsf_check_OS_list)
    ${os_okay:-false} && return

    case $sys in
    i386_linux2|x390s )
        sys_info=$(rsf_get_linux_issue)
        ;;
    * )
        sys_info=$os_name_ver
        ;;
    esac
    print_e "\n    ${sul}${sys_info}${eul} not supported in this release."
    case $os_check_opt in
    flex|license_check|license_setup )
        print "    The license utilities included in ${PWD##*/}"
        print "    are for these operating systems only:"
        ;;
    * )
        print "    $CMD must be run on one of these operating systems:"
        ;;
    esac

    print "$OS_list" | sed -e 's/ISSUE//' | while read supported
    do
        if [ -n "$supported" ]
        then
            print "        $supported"
        fi
    done

    print_e "
    IBM recommends you run $CMD on a machine running one of
    these operating systems.
    "
    case "$os_check_opt" in
    flex|license_check|license_setup )
        # The next message is applicable if not running from the CD-image dir.
        test "$os_check_opt" = flex && return
        ;;
    * )
        rsf_set_flexlm_OS_list
        OS_list=$flexlm_OS_list
        os_okay=$(CMD=license_check; rsf_check_OS_list)
        if ${os_okay:-false}
        then
            print_e "    If you want to do license setup or checking,
    run the license_setup or license_check command.  The list of supported
    operating systems for doing that includes $sys_info.
    "
        fi
        ;;
    esac

    if [ -f .date ]
    then
        # Check if the release is more than _M months old.
        _M=6
        cat .date | while read _entry
        do
            case "$_entry" in
            [0-9]*-[0-9]* ) _date1=${_entry%%-*} ;;
            * ) break ;;
            esac
            _y1=$(rsf_typst -L 4 $_date1)
            _m1=$(rsf_typst -R 4 $_date1)
            _m1=$(rsf_typst -L 2 $_m1)
            let _m1=$_m1+$_M
            if [ $_m1 -gt 12 ]
            then
                let _m1=$_m1-12
                let _y1=$_y1+1
            fi
            case $_m1 in
            [0-9]) _m1=0$_m1 ;;
            esac
            _date1=$_y1$_m1
            _date2=`date '+%Y%m'`
            if [ $_date2 -gt $_date1 ]
            then
                print "    Note: This release is more than $_M months old.\n"
            fi
        done
    fi

    if [ -n "$rs_Update_Url" ]
    then
        print_e "    Check the following web address for the latest
    $rs_Suite_Name updates and platform support:

      $rs_Update_Url
    "
    fi

    # If the OS matches one in the not-run list (nr_OS_list), bail out.
    if [ -n "$nr_OS_list" ]
    then
        os_not_okay=$(os_name_ver=$sys_info; OS_list=$nr_OS_list; rsf_check_OS_list)
        if ${os_not_okay:-false}
        then
            os_bailout="exit 1"
        fi
    fi


    if [ -z "$os_bailout" ]
    then
        os_bailout="rsf_pause Q"
        user_warned_of_platform=yes
    fi

    eval $os_bailout
}

#------------------------------------------------------------------------
function rsf_set_rsh_cmd
{
    test -n "$rsh_cmd" && return

    rsu_allow_rsh=${rsu_allow_rsh=yes}
    rsf_get_option rsu_allow_rsh y_n \
        "Is okay to run '$RSH $rsu_lic_server uname'?"

    if [ "$rsu_allow_rsh" = yes ]
    then
        rsh_cmd=$RSH
        return
    fi

    rsu_allow_ssh=${rsu_allow_ssh=yes}
    rsf_get_option rsu_allow_ssh y_n \
        "Is okay to run 'ssh $rsu_lic_server uname'?"
    if [ "$rsu_allow_ssh" = yes ]
    then
        rsh_cmd=ssh
        return
    fi
    rsh_cmd=Access-denied-by-user
}

#------------------------------------------------------------------------
function rsf_get_remote_os
{
    rhost=$1
    rsf_set_rsh_cmd
    print "\n    Checking remote host '$rhost' for architecture type...
$rsh_cmd $rhost uname -svrp"
remote_os=$($rsh_cmd $rhost uname -svrp | tail -1)
    case $remote_os in
    "" )
        unset remote_os remote_arch remote_sys
        ;;
    OSF1* )
        remote_os="$os_name_axp"
        remote_arch=alpha_osf1
        remote_sys=axp
        ;;
    HP-UX* )
        case `uname -m` in
        ia64 )
            remote_os="$os_name_hpia"
            remote_arch=hpia
            remote_sys=hpia
            ;;
        * )
            remote_os="$os_name_hp"
            remote_arch=hppa_hpux
            remote_sys=hp
            ;;
        esac
        ;;
    AIX* )
        remote_os="$os_name_aix"
        remote_arch=rs6k_aix
        remote_sys=aix
        ;;
    IRIX?5.* )
        remote_os="$os_name_sgi"
        remote_arch=mips_irix5
        remote_sys=sgi
        ;;
    IRIX64*|IRIX?[6-9].* )
        remote_os="$os_name_sg32"
        remote_arch=mips_irix_n32
        remote_sys=sg32
        ;;
    SunOS?5.*sparc )
        remote_os="$os_name_sol"
        remote_arch=sun4_solaris2
        remote_sys=sol
        ;;
    SunOS?5.*i386|SunOS?5.*x86* )
        remote_os="$os_name_solaris_x64"
        remote_arch=solaris_x64
        remote_sys=solaris_x64
        ;;
    Linux* )
        remote_os="$os_name_linux"
        remote_arch=i386_linux2
        remote_sys=i386_linux2
        ;;
    * )
        remote_os=unknown
        unset remote_arch remote_sys
        return
        ;;
    esac
    print "    Remote host $rhost running $remote_os [$remote_arch]"
}

#------------------------------------------------------------------------
function rsf_set_extra_dir
{
    #arg1: tool name
    #arg2: version
    #arg3: sys (short arch name)
    #arg4: arch
    #arg5: 'install'  (when installing flexlm, optional)

    if [ "$1" = flexlm -a -f $EXTRAS/$1.$3/versions ]
    then
        eval ${1}_dir=$EXTRAS/$1.$3
        .  $EXTRAS/$1.$3/versions
        return 0
    fi

    if [ -d $EXTRAS/$1.$2.$3 ]
    then
        eval ${1}_dir=$EXTRAS/$1.$2.$3
        return 0
    fi

    if [ -d $EXTRAS/$1/$3/$2 ]
    then
        eval ${1}_dir=$EXTRAS/$1/$3/$2
        return 0
    fi

    if [ -d $EXTRAS/$1.$2/$3 ]
    then
        eval ${1}_dir=$EXTRAS/$1.$2/$3
        return 0
    fi

    if [ -z "$2" ]
    then
        for _dir in $EXTRAS/$1.*.$3 $EXTRAS/$1/$3/* $EXTRAS/$1.*/$3
        do
            if [ -d $_dir ]
            then
                eval ${1}_dir=$_dir
                return 0
            fi
        done
    fi

    test -n "$rsu_rational_dir" || return 1

    # If installing, do not return the base location or an alternate version.
    test "$5" = install && return 1

    e_arch=${4:-$ARCH}

    if [ -d $rsu_rational_dir/base/cots/$1.$2/$e_arch ]
    then
        eval ${1}_dir=$rsu_rational_dir/base/cots/$1.$2/$e_arch
        return 0
    fi

    if [ "$1" = flexlm ]
    then
        # Check for other versions of FLEXlm.
        for flexlm_dir in $rsu_rational_dir/base/cots/flexlm.*/$e_arch
        do
            test -d $flexlm_dir && return 0
        done
        unset flexlm_dir
    fi
    return 1
}

#------------------------------------------------------------------------
function rsf_find_on_path
{
    # Return the path name of arg1 command.
    # First check if command (arg1) is an executable in the current context.
    # If arg1 is on the path, return the first match.
    # If not on path, return null string.
    if [ -x "$1" ]
    then
        echo "$1"
        return
    fi

    # Look for command on search PATH.
    for _dir in $(IFS=: ; echo $PATH)
    do
        if [ -x "$_dir/$1" -a ! -d "$_dir/$1" ]
        then
            echo "$_dir/$1"
            return
        fi
    done
    echo ""
}

#------------------------------------------------------------------------
function rsf_not_on_path
{
    _exe=$(rsf_find_on_path $1)
    if [ -z "$_exe" ]
    then
        # Not on path, return true
        unset _exe
        return 0
    else
        # On path, return false
        unset _exe
        return 1
    fi
}

#------------------------------------------------------------------------
function rsf_set_path
{
    PATH=$path_dirs:$PATH
    if rsf_set_extra_dir netscape $netscape_ver $sys
    then
        netscape_command=$netscape_dir/netscape
        PATH=$netscape_dir:$PATH
    fi

    rsf_set_extra_dir gzip $gzip_ver $sys && PATH=$gzip_dir:$PATH
    if rsf_set_extra_dir flexlm "$flexlm_ver" $sys
    then
        PATH=$flexlm_dir:$PATH
    else
        Enable_flexlm=false
    fi
    rsf_set_extra_dir gtar "$gtar_ver" $sys && PATH=$gtar_dir:$PATH
    test -d $EXTRAS/bin && PATH=$EXTRAS/bin:$PATH
    export PATH

    if ${Okay_to_install:-true}
    then
        # Check for FLEXlm in the CD image directory.
        set -- 1 $(/bin/ls -d $EXTRAS/flexlm.* $EXTRAS/flexlm/* 2>/dev/null)
    else
        # Check for FLEXlm installed in the cots area.
        set -- 1 $(/bin/ls -d $Cots/flexlm.*/* 2>/dev/null)
    fi

    if [ $# -le 2 ]
    then
        rs_multi_flex=no
        return
    fi
    shift
    rs_multi_flex=yes

    for _flexdir in $*
    do
        test -d $_flexdir || continue
        case ${_flexdir##*/} in
        axp|*.axp.*|alpha_osf1 )
            rs_flex_list="$rs_flex_list \n      $os_name_axp"
            ;;
        hp|*.hp.*|hppa_hpux )
            rs_flex_list="$rs_flex_list \n      $os_name_hp"
            ;;
        hpia|*.hpia.* )
            rs_flex_list="$rs_flex_list \n      $os_name_hpia"
            ;;
        aix|*.aix.*|rs6k* )
            rs_flex_list="$rs_flex_list \n      $os_name_aix"
            ;;
        sgi|*.sgi.*|mips_irix5 )
            rs_flex_list="$rs_flex_list \n      $os_name_sgi"
            ;;
        sg32|*.sg32.*|mips_irix* )
            rs_flex_list="$rs_flex_list \n      $os_name_sg32"
            ;;
        sol|*.sol.*|sun4_solaris2 )
            rs_flex_list="$rs_flex_list \n      $os_name_sol"
            ;;
        solaris_x86|*.solaris_x86.* )
            rs_flex_list="$rs_flex_list \n      $os_name_solaris_x86"
            ;;
        solaris_x64|*.solaris_x64.* )
            rs_flex_list="$rs_flex_list \n      $os_name_solaris_x64"
            ;;
        *linux* )
            rs_flex_list="$rs_flex_list \n      $os_name_i386_linux2"
            ;;
        esac
    done
    unset _flexdir
}

#------------------------------------------------------------------------
function rsf_mkdir_p
{
    test -d $1 && return 0
    _dir_path=/
    for _pdir in $(IFS=/; echo /$1)
    do
        if [ "$_pdir" != "/"  -a \
             "$_pdir" != "."  -a \
             "$_pdir" != ".."    ]
        then
            _dir_path=${_dir_path}$_pdir
            if [ ! -d $_dir_path ]
            then
                mkdir $_dir_path
                if [ $? -ne 0 ]
                then
                    return 1
                fi
            fi
            _dir_path=${_dir_path}/
        fi
    done
    return 0
}

#------------------------------------------------------------------------
function rsf_make_dir
{
    _dir=$1
    _now=${2:-ask}
    if [ -d $_dir/. ]
    then
        if [ -w $_dir/. ]
        then
            return 0
        else
            print
            print "    $_dir exists."
            print "    However, $USER does not have write permissions."
            rsf_pause
            return 1
        fi
    fi

    if [ "$_now" = ask ]
    then
        print
        print "    $_dir not found."
        def_make_dir=yes
        rsf_get_option yn_make_dir y_n "Create it?"
    else
        yn_make_dir=yes
    fi

    if [ "$yn_make_dir" = yes ]
    then
        if rsf_mkdir_p $_dir
        then
            return 0
        fi
    fi
    return 1
}

#------------------------------------------------------------------------
function rsf_print_menu
{
    # Will highlight the default item on the menu.
    if [ -z "$1" ]
    then
        print "$2"
        return
    fi

    print "$2" |
    sed -e "s?^      $1) ?----> $1) ?" \
        -e "s?^     $1) ?---> $1) ?" \
        -e "s?^    $1) ?--> $1) ?"
}

#------------------------------------------------------------------------
function rsf_installed_other_arch
{
    # If the rs_Allow_Multiple_Archs is set to false then
    # check if some other arch other than this $ARCH is installed for the
    # product in the Rational directory.  If it is return true.

    ${rs_Allow_Multiple_Archs:-true} && return 1
    test -d $1 || return 1

    _rel_dir=$1/releases/$rs_Suite_Dir.$rs_Suite_Ver
    for other_arch in $ARCH_LIST
    do
        test "$other_arch" = "$ARCH" && continue
        if [ -d $_rel_dir/$other_arch  -o  -d $_rel_dir/install/$other_arch ]
        then
            unset _rel_dir
            return 0
        fi
    done
    return 1
}

#------------------------------------------------------------------------
function rsf_find_prior_rd_dirs
{
    # Any entries matching rs_ID take precedence.
    if $Doc_install_only
    then
        if [ -f $RATL_LIST ]
        then
            for _dir in $(grep " $rs_ID " $RATL_LIST | awk '{print $1}')
            do
                test -d $_dir/releases && print $_dir
            done
            unset _dir
        fi
        return
    fi

    test -f $RATL_LIST && grep " $rs_ID " $RATL_LIST | awk '{print $1}'

    # These files would be second in line as the most likely place.
    for _def_file in $HOME/.rs_install.rd /tmp/rs_install.rd.$USER
    do
        test -s "$_def_file" || continue
        (
        unset rsu_rational_dir
        . $_def_file 2>/dev/null
        test -n "$rsu_rational_dir" && print "$rsu_rational_dir"
        )
    done

    # Any remaining entries in this file not match rs_ID will go next.
    test -f $RATL_LIST && grep -v " $rs_ID " $RATL_LIST | awk '{print $1}'

    # Get other Rational directory settings from these fine Rational
    # install tools:
    for _cmd in cdinstall rinstall network_install
    do
        for _def_file in \
            $HOME/.Rational/$_cmd.$USER \
            $HOME/.$_cmd \
            /tmp/$_cmd.$USER
        do
            test -s $_def_file || continue
            unset rational_dir
            . $_def_file 2>/dev/null
            test -n "$rational_dir" && print "$rational_dir"
        done
    done
}

#------------------------------------------------------------------------
function rsf_rd_on_list
{
    for _n in $rd_n_list
    do
        eval _rd_n=\$rational_dir$_n
        test "$_rd_n" = "$_rd" && return 0
    done
    return 1
}

#------------------------------------------------------------------------
function rsf_set_rational_dir_list
{
    n=0
    last_rd_opt=0
    unset rational_dir_list def_rsu_rational_dir rd_opt_list
    unset def_rd_opt rd_n_list
    print_n "    Checking for 'Rational' directories."
    for _rd in $(rsf_find_prior_rd_dirs)
    do
        test -d $_rd || continue
        # Check if already on the list and skip it if it is.
        rsf_rd_on_list && continue
        rsf_installed_other_arch $_rd && continue
        rsf_check_user_is_owner quiet $_rd || continue

        let n=n+1
        rd_n_list="$rd_n_list $n"
        eval rational_dir$n=$_rd
        if [ "$_rd" = "$rsu_rational_dir" ]
        then
            def_rd_opt=$n
        else
            def_rsu_rational_dir=${def_rsu_rational_dir:-$_rd}
        fi
        N=$(rsf_typst -R 3 $n)
        rational_dir_list="$rational_dir_list
   $N)  $_rd "
        rd_opt_list="${rd_opt_list}$n,"
        print_n .
        #Keep the list to a manageable number so it wont scroll off the screen.
        test $n -ge $Max_rd_list_entries && break
    done
    last_rd_opt=$n

    case $n in
    0 )
        print ".  None found."
        if $Doc_install_only
        then
            set -- 1 $(grep " $rs_ID " $RATL_LIST 2>/dev/null|awk '{print $1}')
            shift 1
            case $# in
            0 )
                ;;
            1 )
                print "
    There appears to have been 1 product install but this 'Rational'
    directory does not exist or is not accessible from $HOST:

      $1 not found"
                ;;
            * )
                print "
    There appears to have been $# product installs but none of these
    'Rational' directories exist or they are not accessible from $HOST:
"
                for _rd in $*
                do
                    print "      $_rd not found"
                done
                ;;
            esac

            # Do not allow installer to select a different Rational dir
            # when installing the documentation.
            print "
    You must install from the product CD before running $CMD
    for the documentation distribution."
            rsf_cleanup 99
        fi
        ;;
    1 )
        print "  One found."
        ;;
    * )
        print " $n found."
        ;;
    esac
    unset _rd_n _rd _n
}

#------------------------------------------------------------------------
function rsf_rational_dir_menu
{
    rdm_exit=$1
    if [ "$rs_Install_Point_Products" = yes ]
    then
        rsf_menu_title Enter Install Location
    else
        rsf_menu_title $rs_Suite_Name - Enter Install Location
    fi
    prior_rational_dir=$rsu_rational_dir

    print "
    Enter the location to install $rs_vendor_products.
    This will be referred to as the 'Rational' directory.
    In 'Rational' directory, $CMD will create a releases
    directory to keep all of the products by name and version."

    print "
    For example, in 'Rational'/releases, this install will
    create a '${ftp_dir_name:-$rs_Suite_Dir.$rs_Suite_Ver}' directory to install
    $rs_Suite_Name $rs_Suite_Ver.

    The 'Rational' directory must be accessible from
    every machine where you plan to run these $rs_vendor_products.
    The 'Rational' directory path must be identical on each machine.
    Thus, an automount path like /tmp_mnt/rational should not be used
    because you cannot access this directory from every machine.\n"

    if ${rs_Allow_Multiple_Archs:-true}
    then
        :
    else
        print "    NOTE: You cannot install $rs_Suite_Name $rs_Suite_Ver in
          the 'Rational' directory for more than one architecture."
        print
    fi

    rsf_set_rational_dir_list
    case $last_rd_opt in
    1 )
        if $Doc_install_only
        then
            rsu_rational_dir=$rational_dir1
            print "
    Automatically selected this installation location from the previous
    product install:

      $rsu_rational_dir

    It is necessary to install the product documentation in the same
    'Rational' directory for the on-line documentation to function correctly."
            rsf_set_rational_dir_vars
            return
        fi
        ;;
    * )
        rsf_pause $rdm_exit
        ;;
    esac

    if $Doc_install_only
    then
        rd_opt_list="$rd_opt_list or q"
        RDM_Mesg="    You must enter a number from 1 to $last_rd_opt or q.\n"
    else
        rd_opt_list="0,${rd_opt_list}directory or q"
        rational_dir_list="
     0)  A new 'Rational' directory.$rational_dir_list"
        RDM_Mesg="
    You must enter a number from 0 to $last_rd_opt, a new 'Rational'
    directory using a full pathname or q to quit $CMD."
    fi

    while true
    do
        rsu_rational_dir=$prior_rational_dir
        if [ $last_rd_opt -gt 1 ]
        then
            while true
            do
                def_rd_opt=${def_rd_opt:-1}
                rsf_print_menu "$def_rd_opt" \
"    Enter a 'Rational' directory from the list below.
$rational_dir_list

     q)  Quit $CMD.$Help_Option5"
                unset rd_opt
                rsf_get_option rd_opt str "Enter $rd_opt_list:"
                case $rd_opt in
                0 )
                    if $Doc_install_only
                    then
                        print "$RDM_Mesg"
                        continue 2
                    fi
                    rsf_get_option rsu_rational_dir dir \
                        "Enter 'Rational' directory:"
                    break
                    ;;
                /* )
                    if $Doc_install_only
                    then
                        if [ -f $RATL_LIST ]
                        then
                            grep "$rd_opt $rs_ID " $RATL_LIST >/dev/null
                            if [ $? -ne 0 ]
                            then
                                print "$RDM_Mesg"
                                continue 2
                            fi
                        fi
                    fi
                    rsu_rational_dir=$rd_opt
                    break
                    ;;
                [1-9]|[1-9][0-9] )
                    eval rsu_rational_dir=\$rational_dir$rd_opt
                    test -n "$rsu_rational_dir" && break
                    ;;
                esac
                print "$RDM_Mesg"
            done
        else
            rsf_get_option rsu_rational_dir dir "Enter 'Rational' directory:"
        fi

        if [ -d $rsu_rational_dir ]
        then
            rsf_check_user_is_owner ask $rsu_rational_dir
            if [ $? -ne 0 ]
            then
                rsu_rational_dir=$prior_rational_dir
                continue
            fi

            if rsf_installed_other_arch $rsu_rational_dir
            then
                print "
    You cannot use $rsu_rational_dir
    as the 'Rational' directory.  The product has already
    been installed there for $other_arch."
                rsu_rational_dir=$prior_rational_dir
                continue
            fi
            break
        fi

        rsf_make_dir $rsu_rational_dir && break
        rsu_rational_dir=$prior_rational_dir
    done

    if [ "$prior_rational_dir" != "$rsu_rational_dir" ]
    then
        # Whenever the installer changes the rational directory check
        # the license server still has access to this directory.
        rsu_check_rational_dir=true
    fi
    rsf_set_rational_dir_vars
}

#------------------------------------------------------------------------
function rsf_set_rational_dir_vars
{
    Config=$rsu_rational_dir/config
    if rsf_make_dir $Config now
    then
        Releases=$rsu_rational_dir/releases
        rsf_make_dir $Releases now
        Backups=$Config/Backups
        rsf_make_dir $Backups now || unset Backups
    else
        print "
    No write permission in $rsu_rational_dir from $HOST."
        rsf_cleanup 2
    fi

    # Create a defaults directory to put these files.
    Defaults_Dir=$Config/defaults
    if rsf_mkdir_p $Defaults_Dir
    then
        # Set the defaults file to the product and user.
        PROD_DEFAULTS=$Defaults_Dir/rs_install.$rs_ID.$USER
    else
        print "
    No write permission in $Config from $HOST."
        rsf_cleanup 2
    fi

    Base=$rsu_rational_dir/base
    Cots=$Base/cots
    Temporary_Dat_Name=Temporary.dat
    Temporary_Dat=$Config/$Temporary_Dat_Name
    purela_user_file=$Config/purela_users.list
    Lic_Dir=$rsu_rational_dir/base/cots/flexlm.$flexlm_ver/$ARCH
    rsf_set_suite_path_vars

    ${Running_remote:-false} && return

    # Update Rational directory list.
    (
    print "$rsu_rational_dir $rs_ID "
    if [ -s $RATL_LIST ]
    then
        egrep -v "^$rsu_rational_dir\$|^$rsu_rational_dir $rs_ID " $RATL_LIST |
            head -$Max_rd_list_entries
    fi
    ) > $RATL_LIST.2
    /bin/cp $RATL_LIST.2 $RATL_LIST
    /bin/rm -f $RATL_LIST.2
}

#------------------------------------------------------------------------
function rsf_set_suite_path_vars
{
    Suite_Path=$Releases/$rs_Suite_Dir.$rs_Suite_Ver
    Suite_Install=$Suite_Path/$INSTALL
    Suite_List=$Suite_Install/suite_list
}

#------------------------------------------------------------------------
function rsf_set_free_disk_space
{
    _dir=$1
    if [ ! -d $_dir/. ]
    then
        free_disk_space=0
        return 1
    fi

    if [ -z "$df_block_size" ]
    then
        if $DF_CMD $_dir | grep "512-blocks" >/dev/null
        then
            df_block_size=512
        else
            df_block_size=1K
        fi
    fi

    # Determine the disk space available from the DF command.
    set -- `(cd $_dir; $DF_CMD .) | tail -1`
    case $sys in
    aix ) free_disk_space=$3 ;;
      * ) shift `expr $# - 3` ; free_disk_space=$1 ;;
    esac

    if [ ${#free_disk_space} -gt 8 ]
    then
        # Cut down the size to 8 chars.
        free_disk_space=$(rsf_typst -R 8 $free_disk_space)
    fi

    # If the DF command returns 512-byte blocks divide free_disk_space by 2.
    if [ "$df_block_size" = 512 ]
    then
        let free_disk_space=free_disk_space/2
    fi
    return 0
}

#------------------------------------------------------------------------
function rsf_check_disk_space
{
    if rsf_set_free_disk_space $rsu_rational_dir
    then
        if [ $suite_size -lt $free_disk_space ]
        then
            return
        else
            rsf_display_warning
            print "
    $This_sp requires $suite_size K-bytes of disk space to install.
    There are only $free_disk_space K-bytes of disk space available on:
      $rsu_rational_dir

    This is okay if you have already installed $the_sp.
    If you have not installed $the_sp, make sure there is
    enough room to install it before you continue.

    Here is the output of the '$DF_CMD' command:"

        fi
    else
        rsf_display_warning
        print "
    Cannot determine the disk space available on:
      $rsu_rational_dir

    This install requires $suite_size K-bytes of disk space.
    Here is the output of the '$DF_CMD' command:"

    fi

    print
    print "$DF_CMD $rsu_rational_dir/."
    $DF_CMD $rsu_rational_dir/.

    # If doing a typical install, we need to suspend it for this prompt.
    if $Doing_typical_install
    then
        Doing_typical_install=false
        prior_typical=true
    else
        prior_typical=false
    fi

    yn_okay_to_install=no
    rsf_get_option yn_okay_to_install y_n "Do you want to continue anyway?"
    test "$yn_okay_to_install" = no && rsf_cleanup Q

    # Restore typical install mode flag.
    Doing_typical_install=$prior_typical
    unset prior_typical
}

#------------------------------------------------------------------------
function rsf_extract_lic_components
{
    if [ -n "$lic_desc" ]
    then
        if $IniB_Format
        then
            grep "|${lic_desc%,*}|" $INI_FILE |
            awk -F\| '{print $9,$12}' | sort -u
            return
        fi
    fi

    grep "^$lic_name|" $INI_FILE | awk -F\| '{print $9,$12}'
    return
}

#------------------------------------------------------------------------
function rsf_extract_ini_description
{
    if $IniB_Format
    then
        case "$lic_name" in
        RoseRealTime )
            # Must use what is set in rs_startup_desc since trying to
            # extract using the license feature name will produce 2
            # different descriptions.
            eval print \"\$rs_startup_desc$2\"
            ;;
        * )
            grep "^$1|" $INI_FILE | awk -F\| '{print $6}' | head -1
            ;;
        esac
        return
    fi

    grep "^$1|" $INI_FILE | awk -F\| '{print $6}'
}

#------------------------------------------------------------------------
function rsf_license_is_in_file
{
    lic_search="INCREMENT $lic_name "
    if grep "$lic_search" $rsu_lic_file >/dev/null 2>&1
    then
        if [ -n "$1" ]
        then
            if grep "$1" $rsu_lic_file >/dev/null 2>&1
            then
                return 0
            else
                return 1
            fi
        else
            return 0
        fi
    else
        return 1
    fi
}

#------------------------------------------------------------------------
function rsf_split_desc
{
    # Split the line (arg3) at a word boundary if the length exceeds arg2.
    # Arg 1 is a boolean if splitting the line at a dash.
    # Return line 1 in desc1 and line2 in desc2.

    _dash=$1
    _col=$2
    shift 2
    set -- $*
    desc1=$1
    desc2=$1
    shift
    while [ $# -gt 0 ]
    do
        desc2="$desc2 $1"
        if $_dash && test "$1" = '-'
        then
            break
        elif [ ${#desc2} -gt $_col ]
        then
            break
        fi
        desc1="$desc2"
        shift
    done

    if [ $# -gt 0 ]
    then
        desc2="$*"
    else
        unset desc2
    fi
    unset _col _dash
}

#------------------------------------------------------------------------
function rsf_define_other_suite
{
    rsu_product_num=$s
    rs_Suite_Dir=RationalLicenseServer
    rsu_product_name="IBM Rational License Server"
    if [ -z "$rs_Suite_Ver" ]
    then
        rs_Suite_Ver=$rs_suite_ver1
    fi
    rsu_product_ver="$rs_Suite_Ver"
    Prod_Name_Ver="$rsu_product_name $rsu_product_ver"
    rs_Suite_Name="$rsu_product_name"

    eval suite_full_name=\$rs_suite_full_name$s
    if [ -z "$suite_full_name" ]
    then
        suite_full_name=$rsu_product_name
        eval rs_suite_full_name$s=\$rsu_product_name
        eval rs_suite_name$s=\$rsu_product_name
        eval rs_suite_ver$s=\$rs_Suite_Ver
        eval rs_suite_dir$s=$rs_Suite_Dir
        eval rs_suite_fl$s=yes
        eval rs_suite_nl$s=yes
        eval rs_suite_ub$s=yes
    fi
    rsf_set_suite_path_vars
    rsf_mkdir_p $Suite_Path
    unset New_lic_list
}

#------------------------------------------------------------------------
function rsf_explain_product_licenses
{
    case "$CMD" in
    rs_install|license_setup )
        print "
    The $CMD command will do the license setup or if you plan on
    using existing licenses, it will check that you have the necessary
    licenses configured."
        ;;
    esac

    print "
    For the corresponding products, you need one or more of the
    primary licenses (P) or one of the alternate licenses (A):"

    if ${Gen_prod_lic_list:-true}
    then
        # Generate the list of product licenses once.
        # If the user displays it again, it will be cached.
        _indent="         "

        for s in $rs_suites
        do
            eval _name=\$rs_suite_full_name$s
            eval _list=\$rs_suite_key_list$s
            spt_tag=$(rsf_typst -R 3 $s)
            Prod_lic_list="$Prod_lic_list\n\n  $spt_tag)  ${sul}$_name${eul}"

            _p=0  # number of primary licenses
            _a=0  # number of alternate licenses

            # Define a list of primary licenses
            for i in $_list
            do
                eval _feat=\$rs_startup_key$i
                let _p=_p+1
                eval _primary$_p=\$_feat
                _primary_list="$_primary_list $_feat"
                _reset="$_reset _primary$_p"
            done

            # Define a list of alternate licenses
            _altr_list=$(for _feat in $_primary_list
                do
                    rsf_list_alternate_licenses $_feat
                done | sort -u)

            for _feat in $_altr_list
            do
                let _a=_a+1
                eval _altr$_a=\$_feat
                _reset="$_reset _altr$_a"
            done

            _indent="         "
            i=0
            while true
            do
                let i=i+1
                eval _feat=\$_primary$i
                eval _altr=\$_altr$i
                if [ -n "$_feat"  -a  -n "$_altr" ]
                then
                    _Feat=$(rsf_typst -L 33 "P) $_feat")
                    _Altr="A) $_altr"
                    Prod_lic_list="$Prod_lic_list\n$_indent $_Feat  $_Altr"
                    Have_altr=true
                elif [ -n "$_feat" ]
                then
                    _Feat=$(rsf_typst -L 33 "P) $_feat")
                    _Altr=""
                    if [ $i -eq 1 ]
                    then
                        # There are no alternate licenses.
                        _Altr="A) none"
                    fi
                    Prod_lic_list="$Prod_lic_list\n$_indent $_Feat  $_Altr"
                elif [ -n "$_altr" ]
                then
                    _Feat=$(rsf_typst -L 33 "$SPACES")
                    _Altr="A) $_altr"
                    Prod_lic_list="$Prod_lic_list\n$_indent $_Feat  $_Altr"
                    Have_altr=true
                else
                    break
                fi
            done

            unset $_reset
            unset _primary_list _altr_list _reset
        done
        Gen_prod_lic_list=false
    fi

    rsf_pause TO view the list of licenses
    print "\n    Licenses needed for...$Prod_lic_list"

    if ${Have_altr:-false}
    then
        rsf_pause
        print "
    Alternate licenses can be used with some products.  Alternate
    licenses are suitable for use with the product shown above it.
    This program will search for any licenses that are already
    configured and suggest using them.  It will check for the
    alternates in addition to the primary licenses."

    fi

    rsf_pause TO return to the "\n    $rs_Product_Selection Menu"
    unset s i _name _list _feat _altr_feat _p _a _indent
}

#------------------------------------------------------------------------
function rsf_product_selection_menu
{
    License_setup_other=false
    unset Allow_other
    case $CMD in
    rs_install|license_setup )
        if [ "$Enable_flexlm" = true ]
        then
            if [ "$rs_Req_Lic" != true ]
            then
                Allow_other=OTHER
            fi
        fi
        ;;
    esac

    spt_spc="   "
    Pre_Req_Failed=true
    suite_list="
        ${sul}$rs_Product_Selection_Title:${eul}"
    no_go_list="\n"
    unset Cannot_upgrade

    unset alt_rs_suites
    last_prod_opt=0
    for s in $rs_suites $Allow_other
    do
        if [ "$s" = OTHER ]
        then
            let s=last_prod_opt+1
            if [ $s -eq 1 -a -z "$rs_suites" ]
            then
                License_setup_other=true
                rsf_define_other_suite
                unset rs_NL_Quantity rs_Eval_Quantity
                rsf_install_flexlm
                return
            else
                suite_full_name="License setup only - $rs_vendor_products"
                unset suite_ver
                suite_name=OTHER
                eval rs_suite_name$s=$suite_name
            fi
        else
            eval suite_name=\$rs_suite_name$s
            eval suite_full_name=\$rs_suite_full_name$s
            if [ "$rs_Show_Vers" = yes ]
            then
                eval suite_ver=\$rs_suite_ver$s
            else
                unset suite_ver
            fi
        fi
        rsf_set_suite_var_list
        if rsf_check_prerequisite_installed quiet
        then
            test "$suite_name" = OTHER || Pre_Req_Failed=false
            spt_tag=$(rsf_typst -R 3 $s)
            suite_list="$suite_list
  $spt_tag)  $suite_full_name $suite_ver"
            if [ -z "$ps_range" ]
            then
                ps_range="$s"
            else
                ps_range="$ps_range, $s"
            fi
            alt_rs_suites="$alt_rs_suites, $s"
            eval rs_suite_install$s=yes
        else
            eval suite_name=\$rs_suite_name$s
            eval suite_ver=\$rs_suite_ver$s
            spt_tag=$(rsf_typst -R 3 "[$s")
            suite_list="$suite_list
  $spt_tag]  $suite_full_name $suite_ver
  $spt_spc   (Cannot upgrade; prerequisite version $rs_Pre_Req_Version is not installed.)"
            spt_tag=$(rsf_typst -R 3 $s)
            no_go_list="$no_go_list
  $spt_tag)  $suite_full_name $suite_ver
  $spt_spc   Cannot upgrade; prerequisite version $rs_Pre_Req_Version
  $spt_spc    has not been installed."

            Cannot_upgrade="

    Items marked with [] cannot be installed.\n"
            test "$rs_product_num"  = "$s" && unset rs_product_num
            test "$rsu_product_num" = "$s" && unset rsu_product_num
            eval rs_suite_install$s=no
        fi
        last_prod_opt=$s
    done

    def_prod_opt=${rs_product_num:-${rsu_product_num:-e}}
    if $Pre_Req_Failed
    then
        print "$no_go_list

    There are no products in this release that meet the
    installation requirements.
"
        rsf_exit 1
    fi

    if [ $rs_suite -eq 1 -a -z "$Allow_other" ]
    then
        s=1
    else
        while true
        do
            if [ "$rs_Install_Point_Products" = yes ]
            then
                rsf_menu_title $rs_Product_Selection Menu
                rsf_print_menu "$def_prod_opt" "    $rs_Product_Selection_Desc
    You can only select one item from the list.  These products require FLEXlm
    licensing.  Enter option 'e' to see the specific FLEXlm licenses for each
    product.
$suite_list"

            else
                rsf_menu_title $rs_Suite_Name - $rs_Product_Selection Menu
                rsf_print_menu "$def_prod_opt" "    $rs_Product_Selection_Desc
    You can only select one item from the list.
    These products require FLEXlm licensing.  Enter option 'e' to see the
    specific FLEXlm licenses for each product.
$suite_list"

            fi

            print "
    e)  Explain what licenses are needed for each product.
    d)  Download the latest version of the $CMD command from
        $FTP_SERVER and run it.
    b)  Back to the previous menu.
    q)  ${Quit_CMD}${Help_Option4}$Cannot_upgrade"

            unset prod_opt
            rsf_get_option prod_opt mnb "Enter option:"
            alt_opt=$(rsf_is_int "$prod_opt")
            case $alt_opt in
            int )
                s=$prod_opt
                eval rsu_product_name=\$rs_suite_name$s
                if [ -n "$rsu_product_name" ]
                then
                    if [ "$rsu_product_name" = OTHER ]
                    then
                        License_setup_other=true
                        rsf_define_other_suite
                        unset rs_NL_Quantity rs_Eval_Quantity
                        unset License_Key_List Alternate_Key_List
                        rsf_install_flexlm
                        return
                    else
                        eval suite_install=\$rs_suite_install$s
                        test "$suite_install" = no || break
                    fi
                fi
                ;;
            b )
                return
                ;;
            e )
                rsf_explain_product_licenses
                test "$def_prod_opt" = e && unset def_prod_opt
                continue
                ;;
            d )
                rsf_download_me
                print "$Download_status"
                rsf_pause
                continue
                ;;
            esac

            rsf_option_not_recognized -np "$prod_opt" "${alt_rs_suites#, }" bed
        done
    fi
    rsf_set_product_parameters
    rsf_install_flexlm
}

#------------------------------------------------------------------------
function rsf_set_product_parameters
{
    if [ -n "$product_num_lic_chk" -a \
            "$product_num_lic_chk" != "$s" ]
    then
        # We checked licenses for a product already.
        # The user has now picked a different product.
        # Restore licensing to a pre-check state to check again.
        rsu_lic_file=$orig_lic_file
        rsu_license_file=$orig_license_file
        unset New_lic_list
    fi

    eval suite_full_name=\$rs_suite_full_name$s
    eval rsu_product_ver=\$rs_suite_ver$s
    eval default_lic_ver=\$rs_suite_lic_ver$s
    eval rs_allow_floating=\$rs_suite_fl$s
    eval rs_allow_node_locked=\$rs_suite_nl$s
    eval rs_allow_user_based=\$rs_suite_ub$s
    eval product_dir=\$rs_suite_dir$s
    Prod_Name_Ver="$rsu_product_name $rsu_product_ver"
    rsu_product_num=$s
    rsf_set_sp_vars suite

    if [ "$rs_Install_Point_Products" = yes ]
    then
        # At this point do not reload product definitions.
        Enable_product_defs=false
        unset rs_Map_Name rs_Map_Licenses rs_Map_Order

        if [ -f $SUITE_DESCRIPTION.$product_dir ]
        then
            . $SUITE_DESCRIPTION.$product_dir
            rsf_set_rational_dir_vars
            rsf_set_sp_vars
        else
            # Reload the suite description file.
            . $SUITE_DESCRIPTION
        fi
    else
        if [ -f $SUITE_DESCRIPTION.$product_dir ]
        then
            . $SUITE_DESCRIPTION.$product_dir
        fi
    fi

    rs_Suite_Name="$rsu_product_name"
    rs_Suite_Ver=$rsu_product_ver
    rs_Suite_Dir=$product_dir

    rsf_set_suite_var_list
    rsf_check_prerequisite_installed verbose || rsf_exit 1

    if [ -z "$rs_Suite_Dir" ]
    then
        rsf_define_other_suite
    else
        rsf_set_suite_path_vars
        rsf_mkdir_p $Suite_Path
    fi

    eval suite_key_list=\$rs_suite_key_list$s
    if [ -n "$suite_key_list" ]
    then
        rsf_set_License_Key_List -n "$suite_key_list"
    else
        rsf_set_License_Key_List -a
    fi
}

#------------------------------------------------------------------------
function rsf_total_components
{
    size=0
    unset spcmps
    for cn in $(rsf_sort_num $*)
    do
       if [ -f $DIR/products/$prod_dir/$prod_sys/$Ver/file$cn ]
       then
           eval inst=\$cmp_${cn}_inst
           if [ "${inst:-yes}" = yes ]
           then
               eval let size=size+\$cmp_${cn}_size
           fi
           spcmps="$spcmps $cn"
       fi
    done
    eval subprod_comp_size_$spn=$size
    eval subprod_comp_$spn=\"$spcmps\"
}

#------------------------------------------------------------------------
function rsf_add_license_components
{
    set -- 1 $(rsf_extract_lic_components)
    shift
    while [ $# -gt 0 ]
    do
        sub_lic=${1%:*}
        if [ "$sub_lic" = Rose98_Unix ]
        then
            if [ "$lic_name" = Rose98_Unix ]
            then
                sub_lic="rose_unix"
            fi
        fi
        if [ "$sub_lic" != "$lic_name" ]
        then
            Whats_licensed="$Whats_licensed $sub_lic"
        fi
        shift
    done
    unset sub_lic
}

#------------------------------------------------------------------------
function rsf_filter_users_of
{
    _first=true
    grep "Users of $1:" $2 |
    while read _x1 _x2 _lic _x3 _x4 _n _x5
    do
        case $_n in
        1 ) _license=license ;;
        * ) _license=licenses ;;
        esac
        if $_first
        then
            print "$1 ($_n $_license available)"
            _first=false
        else
            print "             $1 (plus $_n more $_license available)"
        fi
    done
    unset _first _lic _n _license _x1 _x2 _x3 _x4 _x5
}

#------------------------------------------------------------------------
function rsf_format_Licenses_found
{
    # Column-align the license feature names.
    _len=1
    print "$Licenses_found" | while read _x1 _lic _x2
    do
        if [ ${#_lic} -gt $_len ]
        then
            _len=${#_lic}
        fi
    done

    Licenses_found=`
        print "$Licenses_found" | while read line
        do
            if [ -z "$line" ]
            then
                print
                continue
            fi
            set -- $line
            if [ "$1" = "License:" ]
            then
                _lic=$(rsf_typst -L $_len $2)
                shift 2
                print "    License: $_lic  $*"
            else
                print "             $line"
            fi
        done`
}

#------------------------------------------------------------------------
function rsf_list_alternate_licenses
{
    (
    _lic=$1
    case "$_lic" in
    PurifyPlusUNIX )
        print "$ALT_PPLUS_LICENSES"
        ;;
    esac


    for other in $(awk -F\| '{print $1,$9,$12}' $INI_FILE |
           grep " $_lic:" | awk '{print $1}')
    do
        test "$other" = "$_lic" && continue
        print "$other"
    done
    ) | sort -u
}


#------------------------------------------------------------------------
function rsf_check_temp_key
{
    # First check the key has not expired.  Return 2 if it has.
    # Next, check the license key is valid.  Return 1 if it is not.
    # Return 0 if the key is okay.

    # The rsf_exp_date_format_okay returns 2 if the expiration date has past.
    _mesg=$(rsf_exp_date_format_okay false)
    test $? = 2 && return 2

    (
    SKN=1
    Feat_List=$lic_name
    key_status=""
    if rsf_extract_incr_lines $vendor_daemon > $TEMP 2>/dev/null
    then
        if exinstal $TEMP > /dev/null 2>&1
        then
            key_status=0
        else
            key_status=1
        fi
    fi
    if rsf_extract_incr_lines $trl_daemon > $TEMP 2>/dev/null
    then
        if exinstrl $TEMP > /dev/null 2>&1
        then
            key_status=${key_status:-0}
        else
            key_status=1
        fi
    fi
    exit ${key_status:-1}
    )
    return $?
}

#------------------------------------------------------------------------
function rsf_trace_log
{
    # Input: arg1: log to file (true/false)
    #        arg2: trace information
    # If Trace_log is true, show trace information (arg2) on the screen.
    # The Trace_log flag can only be set in the debug menu.  Enter ! to get
    # into the debug menu.
    # If arg1 is true and we are logging to a file, then put trace info there.

    if $Trace_log
    then
        print "$2"
    elif [ "$1" = true -a -n "$LOG_FILE" ]
    then
        print "$2" >> $LOG_FILE
    fi
}

#------------------------------------------------------------------------
function rsf_set_lmstat_cmd
{
    # Find lmstat in $Lic_Dir or on PATH.
    # If not found, display error.
    test -n "$lmstat_cmd" && return
    if [ -n "$Lic_Dir"  -a  -x "$Lic_Dir/lmstat" ]
    then
        lmstat_cmd="$Lic_Dir/lmstat"
        return
    fi

    if [ -n "$flexlm_dir"  -a  -x "$flexlm_dir/lmstat" ]
    then
        lmstat_cmd="$flexlm_dir/lmstat"
        return
    fi

    _exe=$(rsf_find_on_path lmstat)
    if [ -n "$_exe" ]
    then
        lmstat_cmd="$_exe"
        return
    fi

    print_e "    Cannot check licenses--lmstat command not found on PATH"
    print_e "    or here: $Lic_Dir/lmstat"
    test "$Lic_Dir" = "$flexlm_dir" ||
       print_e "    or here: $flexlm_dir/lmstat"

    lmstat_cmd=lmstat
}

#------------------------------------------------------------------------
function rsf_set_Whats_licensed
{
    # Mark any licensed products 'not licensed' if its license
    # feature name is not in the 'Whats_licensed' list.

    test -n "$Whats_licensed" && return
    test -n "$rsu_lic_file" || return

    # Arg 1 is the Need_server flag.  Set it if it is not.
    _arg1="$1"

    unset Licenses_found
    _contains_alt_lic=false

    prior_lic_file=$rsu_lic_file
    for rsu_lic_file in $(IFS=: ; echo $prior_lic_file)
    do
      test -z "$_arg1" && rsf_check_if_server_needed "$rsu_lic_file"
      if $Need_server
      then
        if [ ! -d $Lic_Dir ]
        then
            rsf_is_flexlm_installed lmstat local flexlm_dir Lic_Dir
            if [ $? -ne 0 ]
            then
                rsu_lic_file=$prior_lic_file
                return 1
            fi
        fi

        rsf_set_lmstat_cmd
        $lmstat_cmd -a -c $rsu_lic_file >$TEMP 2>&1
        set -- 1 $(grep "$vendor_daemon: UP" $TEMP)
        if [ "$3" = UP ]
        then
            _vd_version=$4
        fi
        for i in $License_Key_List
        do
            _do_complain=true
            eval lic_name=\$rs_startup_key$i
            eval lic_desc=\$rs_startup_desc$i
            if grep "Users of $lic_name:" $TEMP >/dev/null
            then
                rsf_trace_log false "P) $lic_name being served in $rsu_lic_file"
                Whats_licensed="$Whats_licensed $lic_name"
                rsf_add_license_components
                Licenses_found="$Licenses_found
    License: $(rsf_filter_users_of $lic_name $TEMP)"
                rsf_add_to_list Flex_Servers "SERVER $rsu_lic_file $_vd_version"
                continue
            else
                rsf_trace_log false "P) $lic_name not served in $rsu_lic_file"
            fi

            # This checks the inverse condition. A point product
            # such as purify might be licensed by a suite license
            # such as DevelopmentStudioUNIX, so check the INI file too.
            this_lic=$lic_name
            show_lic=$lic_name
            for lic_name in $(rsf_list_alternate_licenses $this_lic)
            do
                if grep "Users of $lic_name:" $TEMP >/dev/null
                then
                    rsf_trace_log false "A) $lic_name served in $rsu_lic_file"
                    Whats_licensed="$Whats_licensed $lic_name"
                    unset lic_desc
                    rsf_add_license_components
                    _contains_alt_lic=true
                    case $lic_name in
                    PurifyPlusUNIX|DevelopmentStudioUNIX* )
                        if [ "$this_lic" = purify ]
                        then
                            show_lic="purify, quantify, and purecov"
                        elif [ "$this_lic" = quantify -o \
                               "$this_lic" = purecov ]
                        then
                            continue 2
                        fi
                        ;;
                    esac
                    Licenses_found="$Licenses_found
    License: $(rsf_filter_users_of $lic_name $TEMP)
             (Alternate license for $show_lic)"
                    _do_complain=false
                    rsf_add_to_list Flex_Servers "SERVER $rsu_lic_file $_vd_version"
                else
                    rsf_trace_log false "A) $lic_name not served in $rsu_lic_file"
                fi
            done
            if $_do_complain
            then
                Licenses_found="$Licenses_found
    License: $this_lic  Not Licensed."
            fi
        done

      else  # Do not need server
        for i in $License_Key_List
        do
            _do_complain=true
            eval lic_name=\$rs_startup_key$i
            eval lic_desc=\$rs_startup_desc$i
            unset lic_feat
            eval $(rsf_read_increment $rsu_lic_file)
            not_licensed="Not Licensed"
            if [ "$lic_feat" = "$lic_name" ]
            then
                rsf_check_temp_key
                case $? in
                0 )
                    Whats_licensed="$Whats_licensed $lic_name"
                    case $Quantity in
                    0|uncounted )
                        _qty="Evaluation key"
                        ;;
                    * )
                        _qty="Quantity: $Quantity"
                        ;;
                    esac
                    rsf_trace_log false "P) $lic_name eval in $rsu_lic_file"
                    rsf_add_license_components
                    Licenses_found="$Licenses_found
    License: $lic_name  $_qty expires: $exp_date"
                    rsf_add_to_list Flex_No_Server $rsu_lic_file
                    continue
                    ;;
                1 )
                    rsf_trace_log false "P) $lic_name eval key not valid in $rsu_lic_file"
                    not_licensed="Evaluation key not valid"
                    ;;
                2 )
                    rsf_trace_log false "P) $lic_name eval key expired on $exp_date in $rsu_lic_file"
                    not_licensed="Evaluation key expired on $exp_date"
                    ;;
                esac
            fi

            this_lic=$lic_name
            show_lic=$lic_name
            for lic_name in $(rsf_list_alternate_licenses $lic_name)
            do
                unset lic_feat
                eval $(rsf_read_increment $rsu_lic_file)
                if [ "$lic_feat" = "$lic_name" ]
                then
                    if rsf_check_temp_key
                    then
                        Whats_licensed="$Whats_licensed $lic_name"
                        case $Quantity in
                        0|uncounted )
                            _qty="Evaluation key"
                            ;;
                        * )
                            _qty="Quantity: $Quantity"
                            ;;
                        esac
                        rsf_trace_log false "A) $lic_name eval in $rsu_lic_file"
                        unset lic_desc
                        rsf_add_license_components
                        _contains_alt_lic=true
                        case $lic_name in
                        PurifyPlusUNIX|DevelopmentStudioUNIX* )
                            if [ "$this_lic" = purify ]
                            then
                                show_lic="purify, quantify, and purecov"
                            elif [ "$this_lic" = quantify -o \
                                   "$this_lic" = purecov ]
                            then
                                continue 2
                            fi
                            ;;
                        esac
                        Licenses_found="$Licenses_found
    License: $lic_name  $_qty expires: $exp_date
             (Alternate license for $show_lic)"
                        _do_complain=false
                        rsf_add_to_list Flex_No_Server $rsu_lic_file
                        continue
                    fi
                fi
                rsf_trace_log false "A) $lic_name eval not in $rsu_lic_file"
            done

            if $_do_complain
            then
            Licenses_found="$Licenses_found
    License: $this_lic  $not_licensed."
            fi

        done
      fi
    done
    rsu_lic_file=$prior_lic_file

    eval suite_prod=\"\$rs_suite_prod$rsu_product_num\"
    unset PIL PNL LNN
    _have_lic=false
    _part_lic=false
    for p in $suite_prod
    do
        eval prod_lic_name=\$rs_prod_lic_name$p
        if [ "$prod_lic_name" = none ]
        then
            eval rs_prod_licensed$p=none
            LNN="
                               * License not needed."
            continue
        fi

        for lic_name in $Whats_licensed
        do
            if [ "$prod_lic_name" = "$lic_name" ]
            then
                # This product is licensed.
                eval rs_prod_licensed$p=yes
                PIL="
                               + This product is licensed."
                # If one or more parts are licensed, this may be okay.
                # User can confirm later.
                _have_lic=true
                continue 2
            fi
        done

        # This product is not licensed.
        eval rs_prod_licensed$p=no
        PNL="
                               - This product is not licensed."
        _part_lic=true
    done

    # Set a license score.
    # (A)  All licenses for the product are configured.
    # (B)  All licenses for the product are configured,
    #      however some are alternates.
    # (C)  Some licenses are configured, but not all.
    # (N)  No licenses are configured.

    if $_have_lic
    then
        # There are one or more licenses.
        if $_part_lic
        then
            License_score=C
        elif $_contains_alt_lic
        then
            License_score=B
        else
            License_score=A
        fi
        rsf_format_Licenses_found
    else
        License_score=N
    fi
    rsf_trace_log true "Whats_licensed: $Whats_licensed ($License_score)"
    unset _arg1 _qty _have_lic _part_lic _contains_alt_lic
    return 0
}

#------------------------------------------------------------------------
function rsf_add_to_list
{
    eval _val=\$$1
    if [ -z "$_val" ]
    then
        eval $1=\"$2\"
    else
        echo " $_val " | grep " $2 " >/dev/null && return
        eval $1=\"$_val $2\"
    fi
    unset _val
}

#------------------------------------------------------------------------
function rsf_typical_or_custom_menu
{
    # Typical will be the default mode.
    rsu_typical_install=${rsu_typical_install:-true}
    last_tc_mode_opt=2
    unset tc_mode_opt
    if $rsu_typical_install
    then
        def_tc_mode_opt=1
    else
        def_tc_mode_opt=2
    fi
    unset TC_IP

    while true
    do
        if $rsu_typical_install
        then
           TCF="Forward to install and post-install $rsu_product_name now."
        else
           TCF="Forward to the next menu to customize the install..."
        fi

        rsf_menu_title $rsu_product_name - Typical/Custom Install Preference
        rsf_print_menu "$def_tc_mode_opt" "
    Choose the install option you prefer:

     1)  Typical      Install recommended product components.

     2)  Custom       Select specific product components to install.
$TC_IP
     b)  Back to the previous menu.
     f)  $TCF
     q)  ${Quit_CMD}$Help_Option5"

        rsf_get_option tc_mode_opt mnfb "Enter install preference:"
        case $tc_mode_opt in
        1 )
            TC_IP="\n    You have chosen to do a typical install.\n"
            rsu_typical_install=true
            def_tc_mode_opt=f
            ;;
        2 )
            TC_IP="\n    You have chosen to do a custom install.\n"
            rsu_typical_install=false
            def_tc_mode_opt=f
            ;;
        b )
            return
            ;;
        f )
            break
            ;;
        * )
            rsf_option_not_recognized "$tc_mode_opt" "$last_tc_mode_opt" mnfb
            ;;
        esac
    done

    if $rsu_typical_install
    then
        Doing_typical_install=true
        rsu_install_mode=skip
        rsu_install_docs=all
    fi
}

#------------------------------------------------------------------------
function rsf_select_product_config_menu
{
    pcsm_first=true

    # If doing a Soda install from the suite,
    # Set the product configuration default to the first configuration,
    # which is crafted for the Suite install.
    if [ "$prod_dir" = soda ]
    then
        case "$rsu_product_name" in
        *DevelopmentStudio*RealTime* )
            eval rsu_spn_$p=2
            ;;
        *DevelopmentStudio* )
            eval rsu_spn_$p=1
            ;;
        esac
    fi

    while true
    do
        rsf_menu_title $Prod $Ver - Product Configuration Menu
        unset PCSM
        spn=1
        eval pcfg_opt=\$rsu_spn_$p
        while [ $spn -le $subprods ]
        do
            N=$(rsf_typst -R 2 $spn)
            eval spdesc=\"\$subprod_desc_$spn\"
            eval spcmps=\"\$subprod_comp_$spn\"
            if $pcsm_first
            then
                rsf_total_components $spcmps
            else
                eval size=\$subprod_comp_size_$spn
            fi
            if [ ${#spdesc} -gt 60 ]
            then
                rsf_split_desc false 60 "$spdesc"
                spdesc="$desc1"
                spdesc2="$desc2"
            else
                unset spdesc2
            fi
            Size=$(rsf_typst -R 9 $size)
            if [ "$pcfg_opt" = "$spn" ]
            then
                def_pcfg_opt=$spn
                PCSM="$PCSM
--->$N) $Size  $spdesc"
            else
                PCSM="$PCSM
    $N) $Size  $spdesc"
            fi

            if [ -n "$spdesc2" ]
            then
                PCSM="$PCSM
                     $spdesc2"
            fi
            eval spdesc_b=\"\$subprod_desc_${spn}b\"
            if [ -n "$spdesc_b" ]
            then
                PCSM="$PCSM
                   $spdesc_b"
            fi
            let spn=spn+1
        done
        pcsm_first=false
        last_pcfg_opt=$subprods

        print "
    Select ONE product configuration to install.

        Size (KB)  Product Configuration
        ---------  -----------------------------------------------------------  $PCSM

     f)  Forward to the next menu to continue...
     q)  ${Quit_CMD}$Help_Option5

    Enter one product configuration to install (1-$last_pcfg_opt)"

        unset PCSM
        if $Doing_typical_install
        then
            pcfg_opt=${def_pcfg_opt:-1}
        else
            rsf_get_option pcfg_opt mnf "Enter menu option:"
        fi

        alt_opt=$(rsf_is_int "$pcfg_opt")
        case $alt_opt in
        int )
            eval spcmps=\"\$subprod_comp_$pcfg_opt\"
            if [ -n "$spcmps" ]
            then
                eval rsu_spn_$p=\"$pcfg_opt\"
                eval rsu_cmps_$p=\"$spcmps\"
                eval rsu_prod_ver_$p=\"$Prod $Ver\"
                break
            else
                rsf_option_not_recognized "$pcfg_opt" "$last_pcfg_opt" mnf
            fi
            ;;
        f )
            break
            ;;
        * )
            rsf_option_not_recognized "$pcfg_opt" "$last_pcfg_opt" mnf
            ;;
        esac
    done
}

#------------------------------------------------------------------------
function rsf_customize_groups_menu
{
    print "\n    Customizing groups not implemented yet."
    rsf_pause
}

#------------------------------------------------------------------------
function rsf_customize_components_menu
{
    while true
    do
        rsf_menu_title $Prod $Ver - Product Component Customization Menu
        if [ "$Doing_typical_install" = false -a \
             "${Do_component_warn:-true}" = true ]
        then
            rsf_display_important
            print "
    Components can be de-selected, but in some cases a component
    you install may depend on one that you de-select.
    If you are unsure, contact $rs_vendor technical support."
            rsf_pause
            Do_component_warn=false
        fi

        print "
  No. Inst?   Kbytes  Component Description
  --- -----   ------  --------------------------------------------------------"

        total=0
        unset spcmps
        eval spn=\$rsu_spn_$p
        if [ -n "$spn" ]
        then
            eval spnprod=\$rsu_prod_ver_$p
            # Make sure the saved product component numbers are for
            # the current product.
            if [ "$spnprod" = "$Prod $Ver" ]
            then
                # Get component list from the product configuration.
                eval spcmps=\"\$subprod_comp_$spn\"
            else
                unset spn rsu_prod_ver_$p rsu_spn_$p rsu_cmps_$p
            fi
        fi

        if [ -z "$spcmps" ]
        then
            # Compute component list based on existence of files in the
            # product directory.
            eval spcmps=\$rsu_cmps_$p
            if [ -z "$spcmps" ]
            then
                cn=1
                while [ $cn -le $cmps ]
                do
                    if [ -f $DIR/products/$prod_dir/$prod_sys/$Ver/file$cn ]
                    then
                        spcmps="$spcmps $cn"
                    fi
                    let cn=cn+1
                done
                eval rsu_cmps_$p=\"$spcmps\"
            fi
        fi
        c=0
        for cn in $spcmps
        do
            let c=c+1
            N=$(rsf_typst -R 3 $c)
            eval cn_$c=$cn
            eval cmp_desc=\"\$cmp_${cn}_desc\"
            eval size=\$cmp_${cn}_size
            Cmp_Size=$(rsf_typst -R 7 $size)
            eval prod_cfg_size_$spn=$size
            eval inst=\$cmp_${cn}_inst_$p
            if [ -z "$inst" ]
            then
                eval inst=\$cmp_${cn}_inst
            fi
            if [ "${inst:-yes}" = yes ]
            then
                let total=total+size
                eval cmp_${cn}_inst_$p=yes
            else
                eval cmp_${cn}_inst_$p=no
            fi
            Inst=$(rsf_typst -R 5 $inst)
            print " $N) $Inst  $Cmp_Size  $cmp_desc"
        done
        last_cmpn_opt=$c
        def_cmpn_opt=f

        Cmp_Size=$(rsf_typst -R 7 $total)

        print_n "  --- -----   ------  "
        echo "--------------------------------------------------------"
        print "             $Cmp_Size  Total Kbytes (installed)

   f) Forward to the next menu to continue...
   q) ${Quit_CMD}$Help_Option3

    Enter a component number (1-$last_cmpn_opt) or range to (de)select."

        unset cmpn_opt
        $Doing_typical_install && break

        rsf_get_option cmpn_opt rng "Enter menu option:"
        for c in $cmpn_opt
        do
            alt_opt=$(rsf_is_int "$c")
            case $alt_opt in
            int )
                eval cn=\$cn_$c
                if [ -n "$cn" ]
                then
                    eval inst=\$cmp_${cn}_inst_$p
                    if [ "${inst:-yes}" = yes ]
                    then
                        eval cmp_${cn}_inst_$p=no
                    else
                        eval cmp_${cn}_inst_$p=yes
                    fi
                    continue
                fi
                $Continue_if_rng_err
                rsf_option_not_recognized "$c" "$last_cmpn_opt" mnfb
                ;;
            b )
                : ignore
                ;;
            f )
                break 2
                ;;
            * )
                rsf_option_not_recognized "$c" "$last_cmpn_opt" mnfb
                ;;
            esac
        done
    done
    eval rs_prod_size$p=$total
}

#------------------------------------------------------------------------
function rsf_do_custom_install
{
    eval Prod=\"\$rs_prod_name$p\"
    eval prod_dir=\$rs_prod_dir$p
    eval prod_sys=\"\$rs_prod_sys$p\"
    prod_sys=${prod_sys:-$sys}
    eval Ver=\"\$rs_prod_ver$p\"
    prod_desc=$DIR/products/$prod_dir/$prod_sys/$Ver/prod_desc
    if [ ! -f $prod_desc ]
    then
        $Doing_typical_install && return
        print "
    You cannot customize the install of $Prod $Ver."
        rsf_pause
        return
    fi

    # Read the prod_desc file.
    unset subprods groups
    . $prod_desc

    # Check if doing product configurations. If so, select a product config.
    if [ -n "$subprods" ]
    then
        rsf_select_product_config_menu
    fi

    # Not implemented yet.
    # Check if doing product groupings. If so, configure groups.
    #if [ -n "$groups" ]
    #then
    #    rsf_customize_groups_menu
    #fi

    # Customize at the component (file1..fileN) level.
    rsf_customize_components_menu
}

#------------------------------------------------------------------------
function rsf_customize_product_menu
{
    if $Doc_install_only
    then
        Product=Tool
        # If doing a doc-only install, make sure there is source
        # for any extras products (e.g. netscape, acrobat) in extras.
        unset suite_prod
        for p in $rs_products
        do
            eval prod_dir=\$rs_prod_dir$p
            eval prod_sys=\"\$rs_prod_sys$p\"
            prod_sys=${prod_sys:-$sys}
            eval Ver=\"\$rs_prod_ver$p\"
            if rsf_set_extra_src $DIR/extras/$prod_dir $prod_sys $Ver
            then
                suite_prod="$suite_prod $p"
                eval rs_prod_licensed$p=none
            fi
        done
        LNN="
                               * License not needed."
    else
        Product=Product
        eval suite_prod=\"\$rs_suite_prod$rsu_product_num\"
        rsf_update_license_map
        unset Whats_licensed
        rsf_set_Whats_licensed
    fi

    unset custom_list clist def_list
    have_ppm=false
    first_time=true
    while true
    do
        if $Doing_typical_install
        then
            rsf_menu_title $rsu_product_name - $Product Table
            print "
    Use the custom install preference if you want to override the
    default install shown in this table."

        else
            rsf_menu_title $rsu_product_name - $Product Customization Menu
        fi

         UL=$(rsf_typst -L ${#rsu_product_name} "$delim")
           UL="         --------   ---------  $UL"
        CMM="\n         Install?   Size (KB)  $rsu_product_name\n$UL"

        suite_size=0
        unset suite_yes suite_no
        pN=0
        for p in $suite_prod
        do
            let pN=pN+1
            N=$(rsf_typst -R 3 $pN)
            eval pN$pN=$p
            eval Prod=\"\$rs_prod_name$p\"
            eval prod_dir=\$rs_prod_dir$p
            eval prod_sys=\"\$rs_prod_sys$p\"
            prod_sys=${prod_sys:-$sys}
            eval Ver=\"\$rs_prod_ver$p\"
            eval size=\"\$rs_prod_size$p\"
            eval licensed=\$rs_prod_licensed$p
            eval inst=\"\$rs_prod_inst$p\"
            if [ -z "$inst" ]
            then
                # The product has not been selected by the user to install.
                # Install if this product matches the architecture we are
                # installing on and it is licensed.
                case $prod_sys in
                $sys )
                    if [ "$licensed" = no ]
                    then
                        inst=no
                    else
                        inst=yes
                    fi
                    ;;
                * )
                    inst=no
                    ;;
                esac

                # If the directory is listed in rs_Install_No, do not install.
                for exclude_dir in $rs_Install_No
                do
                    if [ "$exclude_dir" = "$prod_dir" ]
                    then
                        inst=no
                        break
                    fi
                done
            fi

            case $inst-$licensed-$prod_sys in
            yes-yes-*      ) Prod="+ $Prod" ;;
             no-yes-$sys   ) Prod="- $Prod" ;;
             no-yes-*      ) Prod="~ $Prod" ; have_ppm=true ;;
            yes-no-*       ) Prod="- $Prod" ;;
             no-no-*       ) Prod="- $Prod" ;;
            yes-none-*     ) Prod="* $Prod" ;;
             no-none-$sys  ) Prod="- $Prod" ;;
             no-none-*     ) Prod="~ $Prod" ; have_ppm=true ;;
            esac
            eval rs_prod_inst$p=$inst

            Inst=$(rsf_typst -R 8 $inst)
            if [ "$inst" = yes ]
            then
                Size=$(rsf_typst -R 10 $size)
                suite_size="$suite_size + $Size"
                suite_yes=yes
            else
                suite_no=no
                Size="        --"
            fi


            pcdesc="$Prod $Ver"
            if [ ${#pcdesc} -gt 48 ]
            then
                rsf_split_desc false 48 "$pcdesc"
                CMM="$CMM
   $N)  $Inst  $Size  $desc1
                                   $desc2"
            else
                CMM="$CMM
   $N)  $Inst  $Size  $pcdesc"
            fi

            $first_time || continue

            if [ -f $DIR/products/$prod_dir/$prod_sys/$Ver/prod_desc ]
            then
                clist="$clist $p"
            else
                unset spn rsu_prod_ver_$p rsu_spn_$p rsu_cmps_$p
                continue
            fi
        done

        last_cust_opt=$pN
        first_time=false

        case "${suite_yes}${suite_no}" in
        yes )
            suite_inst=full
            ;;
        no )
            suite_inst=none
            ;;
        yesno )
            suite_inst=custom
            ;;
        esac

        if [ -n "$def_list" ]
        then
            set -- $def_list
            def_cust_opt=$1
        else
            def_cust_opt=f
        fi

        if $have_ppm
        then
            PPM="
                               ~ Product platform mismatch."
        else
            unset PPM
        fi

        CMM="$CMM\n$UL"
        let suite_size=suite_size
        eval rs_suite_size$rsu_product_num=$suite_size
        Size=$(rsf_typst -R 10 $suite_size)
        Inst=$(rsf_typst -R 8 $suite_inst)
        if $Doing_typical_install
        then
            print "$CMM
         $Inst  $Size    Total $PIL $PPM $PNL $LNN"
            break
        fi
        rsf_print_menu "$def_cust_opt" "
$CMM
         $Inst  $Size    Total $PIL $PPM $PNL $LNN

     b)  Back to the previous menu.
     f)  Forward to the next menu to continue...
     q)  ${Quit_CMD}$Help_Option5

    Enter a product number (1-$last_cust_opt) or range to (de)select."

        unset cust_opt
        rsf_get_option cust_opt rng "Enter menu option:"
        for pN in $cust_opt
        do
            alt_opt=$(rsf_is_int $pN)
            case $alt_opt in
            int )
                eval p=\$pN$pN
                eval Prod=\"\$rs_prod_name$p\"
                if [ -n "$Prod" ]
                then
                    eval inst=\"\$rs_prod_inst$p\"
                    if [ "${inst:-yes}" = yes ]
                    then
                        eval rs_prod_inst$p=no
                    else
                        eval rs_prod_inst$p=yes
                    fi
                    continue
                fi
                $Continue_if_rng_err
                rsf_option_not_recognized "$pN" "$last_cust_opt" mnfb
                ;;
            b )
                return
                ;;
            f )
                for p in $clist
                do
                    eval inst=\"\$rs_prod_inst$p\"
                    if [ "${inst:-yes}" = yes ]
                    then
                        rsf_do_custom_install
                    fi
                done
                break 2
                ;;
            * )
                rsf_option_not_recognized "$pN" "$last_cust_opt" mnfb
                ;;
            esac
        done
    done

    if $Doing_typical_install
    then
        for p in $clist
        do
            eval inst=\"\$rs_prod_inst$p\"
            if [ "${inst:-yes}" = yes ]
            then
                rsf_do_custom_install
            fi
        done
    fi

    unset PIL PPM PNL LNN CMM
}

#------------------------------------------------------------------------
function rsf_set_install_mode
{
    case $1 in
    1|ask )
        def_inst_mode_opt=1
        rsu_install_mode=ask
        ;;
    2|skip )
        yn_reinstall=no
        def_inst_mode_opt=2
        rsu_install_mode=skip
        ;;
    3|reinstall )
        yn_reinstall=yes
        def_inst_mode_opt=3
        rsu_install_mode=reinstall
        ;;
    esac
}

#------------------------------------------------------------------------
function rsf_install_mode_menu
{
    if $Doing_typical_install
    then
        rsf_set_suite_size
        rsf_check_disk_space
        rsf_save_defaults
        return
    fi

    rsf_set_install_mode ${rsu_install_mode:-skip}
    last_inst_mode_opt=3
    unset inst_mode_opt

    if $Doc_install_only
    then
        product=document
        to_install="to install the documents"
    else
        product=product
        to_install="to install and post_install $rsu_product_name"
    fi

    if [ "$rsu_sp" = product ]
    then
        If_product="If the $product appears to be installed,"
    else
        If_product="If a $product in the list of ${product}s appears to be installed,"
    fi

    unset IMC
    while true
    do
        rsf_menu_title $rsu_product_name - Enter Install Mode
        rsf_print_menu "$def_inst_mode_opt" "
    $If_product
    $CMD will...

     1)  ask          Will ask you if you want to reinstall it.

     2)  skip         Automatically skip it.
                      Do this if you know the $product has already been
                      installed.

     3)  reinstall    Automatically uninstall and reinstall it.
                      Do this if you know the $product has not been
                      installed properly. $IMC

     b)  Back to the previous menu.
     f)  Forward $to_install...
     q)  ${Quit_CMD}$Help_Option5"

        rsf_get_option inst_mode_opt mnfb "Enter install mode option:"
        case $inst_mode_opt in
        1|2|3 )
            rsf_set_install_mode $inst_mode_opt
            IMC="

    You have chosen ${sul}$rsu_install_mode${eul} mode."
            def_inst_mode_opt=f
            ;;
        b )
            return
            ;;
        f )
            break
            ;;
        * )
            rsf_option_not_recognized "$inst_mode_opt" "$last_inst_mode_opt" mnfb
            ;;
        esac
    done
    rsf_set_suite_size
    rsf_check_disk_space
    rsf_save_defaults
}

#------------------------------------------------------------------------
function rsf_get_doc_size_list
{
    (
    cd $DIR/docs
    n_docs=0
    if [ -s .control ]
    then
        grep -v "^#" .control | awk -F\| '{print $1, $3}' |
        while read doc_type doc_list
        do
            _total_size=0
            _warn=false
            unset _miss
            for doc_file in $doc_list
            do
                if [ -d $doc_file ]
                then
                    set -- $(du $du_opt $doc_file)
                    let _total_size=_total_size+$1
                elif [ -f $doc_file ]
                then
                    _size=$(rsf_set_file_Ksize $doc_file)
                    let _total_size=_total_size+_size
                else
                    _warn=true
                    _miss="$_miss\n         $doc_file"
                fi
            done
            test $_total_size -gt 0 && print $_total_size $doc_type
            if $_warn
            then
                print_e "Warning: Missing doc elements for $doc_type: $_miss"
            fi
        done
        return
    fi

    for doc_file in *
    do
         let n_docs=n_docs+1
         _doc_list="$_doc_list $doc_file"
    done

    # If there is only one item in the docs directory, then
    # present the doc list in one more level of detail during install.
    if [ $n_docs -eq 1 ]
    then
        unset _doc_list
        for doc_file in */*
        do
            _doc_list="$_doc_list $doc_file"
        done
    fi

    for doc_file in $_doc_list
    do
        if [ -d $doc_file ]
        then
            du $du_opt $doc_file
        else
            _size=$(rsf_set_file_Ksize $doc_file)
            print $_size $doc_file
        fi
    done
    )
}

#------------------------------------------------------------------------
function rsf_set_doc_desc
{
    # Set the document description from the .control file or the
    # .description file.
    # If that does not exist, base the description on the document
    # file name and type.
    unset doc_desc
    if [ -s $DIR/docs/.control ]
    then
        IFS='|'
        set -- $(grep "^$doc_file|" $DIR/docs/.control)
        doc_type=$1
        doc_desc=$2
        doc_file=$3
        IFS=$oldIFS
        return
    fi

    if [ -s $DIR/docs/.description ]
    then
        doc_desc=$(grep "^$doc_file:" $DIR/docs/.description |
                   awk -F: '{print $2}')
        test -n "$doc_desc" && return
    fi

    case "$doc_file" in
    pdf/* )
        doc_subdir=pdf
        doc_type="PDF Docs"
        ;;
    ps/* )
        doc_subdir=ps
        doc_type="Postscript Docs"
        ;;
    */* )
        doc_subdir=html
        doc_type="HTML Docs"
        ;;
    * )
        doc_type="Documentation"
        ;;
    esac

    for manual in $(IFS=_ ; echo ${doc_file#*/})
    do
        case "$manual" in
        api         ) manual="API" ;;
        cq          ) manual="ClearQuest" ;;
        FLEXlm      ) manual="$manual" ;;
        html        ) manual="Documents in HTML." ;;
        index.html  ) manual="Document HTML index file." ;;
        pdf         ) manual="Documents for Adobe Acrobat reader." ;;
        pqc         ) manual="PurifyPlus" ;;
        ps          ) manual="Documents for postscript printing." ;;
        purecov     ) manual="PureCoverage" ;;
        README.html ) manual="Document HTML readme file." ;;
        ref         ) manual="Reference" ;;
        relnote     ) manual="Release Notes" ;;
        rup         ) manual="RUP" ;;
        soda        ) manual="SoDA" ;;
        *           ) _C=$(rsf_typst -L 1 "$manual")
                      _C=$(rsf_uc "$_C")
                      manual="${_C}${manual#?}"
                      ;;
        esac

        if [ -n "$doc_desc" ]
        then
            doc_desc="$doc_desc $manual"
        else
            doc_desc=$manual
        fi
    done
    test -n "$doc_type" && doc_desc="$doc_desc ($doc_type)"
    unset manual
}

#------------------------------------------------------------------------
function rsf_install_docs_menu
{
    if [ ! -d $DIR/docs ]
    then
        rsu_install_docs=none
        return
    fi

    rsu_install_docs=${rsu_install_docs:-all}

    n=0
    if [ -f $DOC_SIZES ]
    then
        # Get sizes from file created from running rs_install -size.
        set -- $(cat $DOC_SIZES)
    else
        # Compute sizes.
        set -- $(rsf_get_doc_size_list)
    fi

    unset Doc_N_List
    while [ $# -gt 0 ]
    do
        let n=n+1
        Doc_N_List="$Doc_N_List $n"
        eval doc_size_$n=$1
        doc_file=$2
        eval doc_file_$n=$doc_file
        shift 2
        rsf_set_doc_desc
        eval doc_desc_$n=\"$doc_desc\"
        eval suite_doc=\$rs_suite_doc$rsu_product_num
        if [ -n "$suite_doc" ]
        then
            eval doc_inst_$n=no
            for doc in $suite_doc
            do
                test "$doc" = DOCS: && continue
                if [ "$doc" = "$doc_type" ]
                then
                    eval doc_inst_$n=yes
                    break
                fi
            done
            continue
        fi

        case "$rsu_install_docs" in
        all|*$doc_file* )
            eval doc_inst_$n=yes
            ;;
        * )
            eval doc_inst_$n=no
            ;;
        esac
    done

    while true
    do
        size=0 Doc_size=0 n=0
        if $Doing_typical_install
        then
            rsf_menu_title Documentation Table
        else
            rsf_menu_title Install Documentation Menu
        fi
        print "
    The docs/ directory on the release media contains the on-line
    documentation for $the_sp.  This may include the installation
    guide, release note, getting started docs or on-line help."

        print
        print "         Install?   Size (KB)  Product Documentation"
        echo  "         --------   ---------  ---------------------"
        unset doc_type_list
        inst_any=no
        not_inst_any=no
        for n in $Doc_N_List
        do
            N=$(rsf_typst -R 3 $n)
            eval doc_file=\"\$doc_file_$n\"
            eval doc_desc=\"\$doc_desc_$n\"
            eval doc_size=\$doc_size_$n
            eval doc_inst=\$doc_inst_$n
            Inst=$(rsf_typst -R 8 $doc_inst)
            if [ "$doc_inst" = yes ]
            then
                Size=$(rsf_typst -R 10 $doc_size)
                let Doc_size=Doc_size+doc_size
                if [ -n "$doc_type_list" ]
                then
                    doc_type_list="${doc_type_list}+$doc_file"
                else
                    doc_type_list=$doc_file
                fi
                inst_any=yes
            else
                Size="        --"
                doc_size="--"
                not_inst_any=yes
            fi
            print "   $N)  $Inst  $Size  $doc_desc"
        done

        case "${inst_any}-$not_inst_any" in
        yes-yes )
            rsu_install_docs=custom
            ;;
        yes-no )
            rsu_install_docs=all
            ;;
        no-yes )
            rsu_install_docs=none
            ;;
        esac

        last_doc_opt=$n
        def_doc_opt=f

        if ${Option_b_okay:-true}
        then
            Chk_anfb=anfb
            Allow_Backward="
     b)  Back to the previous menu."
        else
            Chk_anfb=anf
            unset Allow_Backward
        fi

        echo  "         --------   ---------  ---------------------"
        Inst=$(rsf_typst -R 8 $rsu_install_docs)
        Size=$(rsf_typst -R 10 $Doc_size)
        print "         $Inst  $Size  Total (does not account for documents
                                      already installed.)"

        $Doing_typical_install && break

        print "
     a)  All of the above.
     n)  None of the above. $Allow_Backward
     f)  Forward to the next menu to continue...
     q)  ${Quit_CMD}$Help_Option5

    Enter a number (1-$last_doc_opt) or range to select or de-select which
    documents to install."

        unset doc_opt
        rsf_get_option doc_opt rng "Enter menu option:"
        for d in $doc_opt
        do
            alt_opt=$(rsf_is_int "$d")
            case $alt_opt in
            int )
                eval doc_file=\$doc_file_$d
                if [ -n "$doc_file" ]
                then
                    eval inst=\$doc_inst_$d
                    if [ "${inst:-yes}" = yes ]
                    then
                        eval doc_inst_$d=no
                    else
                        eval doc_inst_$d=yes
                    fi
                    continue
                fi
                $Continue_if_rng_err
                rsf_option_not_recognized "$d" "$last_doc_opt" $Chk_anfb
                ;;
            a|n )
                if  [ "$d" = a ]
                then
                    inst=yes
                else
                    inst=no
                fi
                i=1
                while [ $i -le $last_doc_opt ]
                do
                    eval doc_inst_$i=$inst
                    let i=i+1
                done
                continue
                ;;
            b )
                ${Option_b_okay:-true} && return
                rsf_option_not_recognized "$d" "$last_doc_opt" $Chk_anfb
                ;;
            f )
                break 2
                ;;
            * )
                rsf_option_not_recognized "$d" "$last_doc_opt" $Chk_anfb
                ;;
            esac
        done
    done

    if [ "$rsu_install_docs" = custom ]
    then
        rsu_install_docs=${doc_type_list:-none}
    fi
}

#------------------------------------------------------------------------
function rsf_set_suite_size
{
    eval suite_size=\"\$rs_suite_size$rsu_product_num\"
    if [ "$rsu_install_docs" = none ]
    then
        Size_Desc=" (Total size of $the_sp)"
    elif [ ${Doc_size:-0} -gt 0 ]
    then
        let suite_size=${suite_size:-0}+Doc_size
        if [ "$rsu_install_docs" = all ]
        then
            Size_Desc=" ($rsu_sp with documentation)"
        else
            Size_Desc=" ($rsu_sp with selected documentation)"
        fi
    else
        Size_Desc=" ($rsu_sp without docs)"
    fi
}

#-----------------------------------------------------------------
function rsf_install_patches
{
    num_patches=0
    for patch_dir in $prod_src/????????-?? $prod_src/?????????-?
    do
        test -d $patch_dir || continue
        for ip_file in $patch_dir/install_*
        do
            if [ -f $ip_file ]
            then
                let num_patches=num_patches+1
                patch_list="$patch_list $patch_dir"
                break
            fi
        done
    done

    case $num_patches in
    0 )
        return
        ;;
    1 )
        print "\n    There is 1 patch to install."
        ;;
    * )
        print "\n    There are $num_patches patches to install."
        ;;
    esac

    prod_install=$prod_dst/install
    test -d $prod_install || mkdir $prod_install
    patch_num=0
    for patch_dir in $patch_list
    do
        let patch_num=patch_num+1
        patch_id=${patch_dir##*/}
        if [ -d $prod_install/$patch_id ]
        then
            print "    Patch $patch_id has already been copied to the install area."
            continue
        fi

        if [ $num_patches -gt 1 ]
        then
            print "    Copying patch $patch_num of $num_patches: $patch_id"
        else
            print "    Copying patch: $patch_id"
        fi
        print "      from: $patch_dir"
        mkdir $prod_install/$patch_id
        for patch_file in \
            $patch_dir/install_* \
            $patch_dir/description* \
            $patch_dir/*.inventory \
            $patch_dir/*.tar*
        do
            patch_name=${patch_file##*/}
            /bin/cp $patch_file $prod_install/$patch_id/$patch_name
        done
    done
    print "    NOTE: Patches will be applied during post-install."
}

#------------------------------------------------------------------------
function rsf_update_suite_list
{
    if grep "^$1\$" $Suite_List >/dev/null 2>/dev/null
    then
        return
    fi
    rsf_mkdir_p $Suite_Install
    print $1 >> $Suite_List
}

#------------------------------------------------------------------------
function rsf_reinstall_product
{
    _comp=$1
    if [ $totalN -gt 1 ]
    then
        CofN=" $C of $totalN:"
    else
        CofN=":"
    fi

    case $rsu_install_mode in
    ask )
        rsf_set_OS $prod_sys
        if [ "$_comp" = product ]
        then
            Reinstall_it="This product appears to be installed for $OS.\n"
        else
            Reinstall_it="Installed$CofN $cmp_desc ($fileN)\n"
        fi
        Reinstall_it="$Reinstall_it    Reinstall it"
        yn_reinstall=${yn_reinstall:-no}
        rsf_get_option yn_reinstall y_n "$Reinstall_it?"
        if [ "$yn_reinstall" = yes ]
        then
            if [ "$_comp" = product ]
            then
                print "    Reinstalling: $prod_name_ver"
            else
                print "    Reinstalling$CofN $cmp_desc ($fileN)"
            fi
            return 0
        else
            return 1
        fi
        ;;
    skip )
        if [ "$_comp" = product ]
        then
            print "    This $_comp appears to be installed--skipping."
        else
            print "    Installed$CofN $cmp_desc ($fileN)"
        fi
        unset _comp
        yn_reinstall=no
        return 1
        ;;
    reinstall )
        if [ "$_comp" = product ]
        then
            print "    This $_comp appears to be installed--reinstalling..."
        else
            print "    Reinstalling$CofN: $cmp_desc ($fileN)"
        fi
        unset _comp
        yn_reinstall=yes
        return 0
        ;;
    esac
}

#------------------------------------------------------------------------
function rsf_list_fileN
{
    eval rsu_cmps=\$rsu_cmps_$p
    if [ -n "$rsu_cmps" ]
    then
        for cn in $rsu_cmps
        do
            eval inst=\$cmp_${cn}_inst_$p
            test "${inst:-yes}" = yes && print file$cn
        done
        return
    fi

    (
    cd $prod_src
    /bin/ls file[1-9]
    if [ -f file10 ]
    then
        /bin/ls file??
    fi
    )
}

#------------------------------------------------------------------------
function rsf_cksum_does_not_match
{
    # If the tar file has a checksum, use it to validate that it
    # has not changed since the last install.
    if [ -n "$cksum" ]
    then
        if grep "^$cmp_desc ck $cksum\$" $prod_cmp >/dev/null
        then
            return 1
        else
            return 0
        fi
    fi
    return 1
}

#------------------------------------------------------------------------
function rsf_do_reinstall_tar
{
    # If the checksum on the tar file has changed, will need reinstall.
    unset Explain_reinstall need_reinstall
    if rsf_cksum_does_not_match
    then
        # The tar file has changed since the last install.
        need_reinstall=need
    fi

    case ${need_reinstall:-$rsu_install_mode} in
    need )
        Explain_reinstall="
      (Product tar file was updated since the last install.)"
        ;;
    ask )
        Reinstall_it="Installed$CofN  $cmp_desc\n    Reinstall it"
        yn_reinstall=${yn_reinstall:-no}
        rsf_get_option yn_reinstall y_n "$Reinstall_it?"
        test "$yn_reinstall" = no && return 1
        ;;
    skip )
        print "    Installed$CofN  $cmp_desc"
        return 1
        ;;
    esac

    print "    Reinstalling$CofN ${cmp_desc}$Explain_reinstall"

    # Remove files that were installed from this tar file.

    case $tar_name in
    *.tar.Z )
        tar_tf="$UNCOMPRESS -c $tar_file | tar -tf -"
        ;;
    *.gtar.gz )
        tar_tf="gzip -dc $tar_file | gtar -tf -"
        ;;
    *.tar.gz|*.cbt )
        tar_tf="gzip -dc $tar_file | tar -tf -"
        ;;
    *.gtar )
        tar_tf="gtar -tf $tar_file"
        ;;
    * )
        tar_tf="tar -tf $tar_file"
        ;;
    esac
    tar_tf="$tar_tf | sed -e 's? .*link.* to.*??' -e 's? -> .*??' | sort -r"

    test -n "$Prod_Dir_Ver" && cd $Releases
    eval $tar_tf | while read lfile
    do
        if [ -f "$lfile" -o -L "$lfile" ]
        then
            /bin/rm -f "$lfile"
        else
            /bin/rmdir "$lfile" 2>/dev/null
        fi
    done
    /bin/rm -f $prod_dst/.tests.passed*
    test -n "$Prod_Dir_Ver" && cd $OLDPWD
    return 0
}

#------------------------------------------------------------------------
function rsf_do_reinstall_cmp
{
    # Initially, assume not installed.
    inst=no
    eval cmp_name=\$cmp_${N}_name
    list_file=$prod_dst/install/share/$cmp_name.list

    # If the checksum on the tar file has changed, will need reinstall.
    if rsf_cksum_does_not_match
    then
        # The tar file has changed since the last install.
        inst=need
        return 0
    fi

    # Get and check the component file list.
    if [ ! -s $list_file ]
    then
        # Cannot check files.
        return 1
    fi

    # Check first and last files in list exists.
    # If the first file is installed, may be a partial install.
    # If the last file is installed, we have a complete install.
    first_file=$(head -1 $list_file)
    if [ -f "$first_file" -o -d "$first_file/." ]
    then
        inst=partial
        last_file=$(tail -1 $list_file)
        if [ -f "$last_file" -o -d "$last_file/." ]
        then
            # Component is already installed.
            inst=yes
            return 0
        fi
    fi
    return 0
}

#------------------------------------------------------------------------
function rsf_uninstall_component
{
    # inst is partial.
    # To reinstall a component, first remove the existing files
    # listed in the component file list.
    # If there is any white space in the file names, must rm each one.
    # Otherwise, can use xargs to remove them.
    if grep "[$WS]" $list_file > /dev/null
    then
        cat $list_file | while read lfile
        do
            /bin/rm -fr "$lfile"
        done
    else
        cat $list_file | xargs /bin/rm -fr
    fi
    return 0
}

#------------------------------------------------------------------------
function rsf_install_file0
{
    prod_cmp=$prod_dst/install/$ARCH/prod_cmp
    rsf_set_OS $prod_sys
    cmp_desc="Data, Install and Post-Install Tools for $OS"

    print "    Installing $cmp_desc"
    if [ -d $prod_dst/install  -a  ! -d $prod_dst/install/$ARCH ]
    then
        # This is an install of a new ARCH on top of another ARCH
        # Before installing, try to make the files writable by the installer.
        chmod -R u+w $prod_dst 2>/dev/null
    fi

    cd $rsu_rational_dir
    $tar_xf $prod_src/file0
    if [ $? -ne 0 ]
    then
        let Install_errors=Install_errors+1
    fi
    cd $prod_dst
    if [ -d install/$ARCH ]
    then
        (
        cd install
        if [ -f share.tar.Z ]
        then
            $UNCOMPRESS share.tar.Z
            $tar_xf share.tar
            /bin/rm -f share.tar
        elif [ -f share.tar.gz ]
        then
            gtar -xzf share.tar.gz
            /bin/rm -f share.tar.gz
        elif [ -f share.tar ]
        then
            $tar_xf share.tar
            /bin/rm -f share.tar
        fi
        )
    else
        print "    FAIL: Could not install file0:"
        print "          $prod_src/file0"
        print "          Not created: $prod_dst/install/$ARCH"
        let Install_errors=Install_errors+1
        return 1
    fi

    rsf_update_prod_cmp
    return 0
}

#------------------------------------------------------------------------
function rsf_install_fileN
{
    print "    from: $prod_src"
    print "      to: $prod_dst"

    file_list=$(rsf_list_fileN)
    set -- $file_list
    totalN=$#

    rsf_install_file0 || return

    # Read the description file for this product.
    if [ -f $prod_src/prod_desc ]
    then
        prod_desc=$prod_src/prod_desc
    elif [ -f $prod_dst/install/$ARCH/prod_desc ]
    then
        prod_desc=$prod_dst/install/$ARCH/prod_desc
    else
        set -- $(/bin/ls $prod_dst/install/*/prod_desc 2>/dev/null)
        prod_desc=$1
    fi
    . $prod_desc

    arch_defaults=$prod_dst/install/$ARCH/install_defaults

    No_install_problems=true
    C=0
    for fileN in $file_list
    do
        let C=C+1
        N=${fileN#file}
        file=$prod_src/$fileN
        eval cmp_desc=\"\$cmp_${N}_desc\"
        eval cmp_arch=\$cmp_${N}_arch
        prod_cmp=$prod_dst/install/$cmp_arch/prod_cmp
        eval cmp_root=\$cmp_${N}_root
        if [ "$cmp_root" = base ]
        then
            cd $Base
        else
            cd $prod_dst
        fi

        rsf_extract_checksum $prod_src $fileN

        if rsf_install_prod_cmp
        then
            # Installed, check if need reinstalling.
            if rsf_do_reinstall_cmp $prod_src $fileN
            then
                case "$inst" in
                no )
                    print "    Installing$CofN $cmp_desc ($fileN)"
                    ;;
                yes )
                    if rsf_reinstall_product component
                    then
                        rsf_uninstall_component
                    else
                        continue
                    fi
                    ;;
                partial )
                    print "    Reinstalling$CofN $cmp_desc ($fileN)"
                    print "      Required since this component was" \
                        left partially installed.
                    rsf_uninstall_component
                    ;;
                need )
                    print "    Reinstalling$CofN $cmp_desc ($fileN)"
                    print "      (Product" tar file was updated since the \
                                  last "install.)"
                    rsf_uninstall_component
                    ;;
                esac
            else
                print "    Installed$CofN $cmp_desc ($fileN)"
                continue
            fi
        else
            print "    Installing$CofN $cmp_desc ($fileN)"
        fi

        case $compress in
        compress )
            $UNCOMPRESS -c $file | $tar_xf -
            status=$?
            ;;
        gzip )
            gzip -dc $file | $tar_xf -
            status=$?
            ;;
        * )
            $tar_xf $file
            status=$?
            ;;
        esac
        if [ $status -eq 0 ]
        then
            rsf_update_prod_cmp
        else
            let Install_errors=Install_errors+1
            No_install_problems=false
        fi
    done

    if $No_install_problems
    then
        # Set product install status.
        (
        grep -v "INST_STATUS=" $arch_defaults 2>/dev/null
        print "INST_STATUS=COMPLETED"
        ) >> $arch_defaults.new
        /bin/cp $arch_defaults.new $arch_defaults
        /bin/rm -f $arch_defaults.new
    fi
}


#------------------------------------------------------------------------
function rsf_set_tar_list
{
    tar_list=$(/bin/ls $prod_src/*tar* $prod_src/*.cbt 2>/dev/null)
    if [ -n "$prod_share_src" ]
    then
        _s=$(/bin/ls $prod_share_src/*tar* $prod_share_src/*.cbt 2>/dev/null)
        if [ -n "$_s" ]
        then
            tar_list="$tar_list $_s"
        fi
        unset _s
    fi
}

#------------------------------------------------------------------------
function rsf_install_type
{
    if [ -f $prod_src/file0 ]
    then
        rsf_install_fileN
        return
    fi

    cd $prod_dst

    rsf_set_tar_list
    set -- $tar_list
    totalN=$#
    if [ "$totalN" -eq 0 ]
    then
        print "    FAIL: Could not find a file to install from here:"
        print "          $prod_src"
        print "          or from:"
        print "          $prod_src2"
        return
    fi

    print "    from: $prod_src"
    print "      to: $prod_dst"
    rsf_mkdir_p $prod_dst/install
    prod_cmp=$prod_dst/install/prod_cmp

    C=0
    for tar_file in $tar_list
    do
        let C=C+1
        if [ -n "$ftp_plat" ]
        then
            OS=$ftp_plat
        else
            rsf_set_OS $tar_file
        fi
        tar_name=${tar_file##*/}
        unset cmp_desc
        case $tar_name in
        *.tar.Z )
            # Compressed, standard tar file
            tar_cmd="$UNCOMPRESS -c $tar_file | $tar_xf -"
            ;;
        *.gtar.gz )
            # GNU zip, GNU tar file
            tar_cmd="gzip -dc $tar_file | gtar -xf -"
            ;;
        *.tar.gz )
            # GNU zip, standard tar file
            tar_cmd="gzip -dc $tar_file | $tar_xf -"
            ;;
        *.cbt )
            # GNU zip, standard tar file
            tar_cmd="gzip -dc $tar_file | $tar_xf -"
            pkg_file=${tar_file%cbt}pkg
            cmp_desc=$(grep "^Description:" $pkg_file 2>/dev/null)
            cmp_desc="$cmp_desc (${tar_file##*/})"
            ;;
        *.gtar )
            # GNU tar file
            tar_cmd="gtar -xf $tar_file"
            ;;
        * )
            # Plain tar file
            tar_cmd="$tar_xf $tar_file"
            ;;
        esac

        if [ -n "$cmp_desc" ]
        then
            cmp_desc=${cmp_desc#Description:}
            cmp_desc=${cmp_desc#\ }
        else
            cmp_desc="$tar_name file for $OS"
        fi

        if [ $totalN -gt 1 ]
        then
           CofN=" $C of $totalN:"
        else
           CofN=":"
        fi

        rsf_extract_checksum ${tar_file%/*} $tar_name

        if rsf_install_prod_cmp
        then
            # Installed, check if need reinstalling.
            rsf_do_reinstall_tar || continue
            test -n "$Prod_Dir_Ver" && rsf_set_prod_dir_ver true
        else
            print "    Installing$CofN $cmp_desc"
        fi

        test -n "$Prod_Dir_Ver" && cd $Releases
        eval $tar_cmd
        if [ $? -eq 0 ]
        then
            rsf_update_prod_cmp
        else
            let Install_errors=Install_errors+1
        fi
        test -n "$Prod_Dir_Ver" && cd $OLDPWD
    done
}

#------------------------------------------------------------------------
function rsf_set_prod_src
{
    if [ -d $1/$2/$3 ]
    then
        prod_src=$1/$2/$3
        prod_src2=$1/$3
    else
        prod_src=$1/$3
        prod_src2=$1/$2/$3
    fi

    if [ -d $1/share/$3 ]
    then
        prod_share_src=$1/share/$3
    else
        unset prod_share_src
    fi
}

#------------------------------------------------------------------------
function rsf_set_extra_src
{
    if [ -d $1/$2/$3 ]
    then
        prod_src=$1/$2/$3
        prod_src2=$1/$3
        return 0
    elif [ -d $1.$3.$2 ]
    then
        prod_src=$1.$3.$2
        prod_src2=$1.$3
        return 0
    elif [ -d $1.$3/$2 ]
    then
        prod_src=$1.$3/$2
        prod_src2=$1.$3
        return 0
    elif [ -d $1/$3 ]
    then
        prod_src=$1/$3
        prod_src2=$1/$2/$3
    else
        return 1
    fi
}

#------------------------------------------------------------------------
function rsf_set_INI_FILE
{
    # Need to determine which INI file to use
    test -z "$DIR" && DIR=$(rsf_normalize_dir $(pwd))
    INI_FILE=$DIR/$INI_FILE
    INI2_FILE=$DIR/$INI2_FILE
    IniB_Format=false
    Ini_Eval_Format=false

    if [ -f $INI2_FILE ]
    then
        # The eval format of this file was:
        #   lic_name eval_qty
        # If not this format, it is the new INI file.
        set -- 1 $(grep "^DevelopmentStudioUNIX " $INI2_FILE)
        if [ -n "$3" -a "$2" = DevelopmentStudioUNIX ]
        then
            # This is the eval format.
            Ini_Eval_Format=true
        else
            # This is the new ini file.
            INI_FILE=$INI2_FILE
            unset INI2_FILE
        fi
    fi

    if [ -f $INI_FILE ]
    then
        grep "|Floating|" $INI_FILE >/dev/null && IniB_Format=true
    else
        print_e "\n    Could not find file:\n    $INI_FILE\n"
        rsf_usage 1
    fi
}

#------------------------------------------------------------------------
function rsf_set_misc
{
    do_stty=$1
    EXTRAS=$DIR/extras

    # Set year, month and day parameters
    year=$(date +%Y 2>/dev/null)
    case $year in
    [1-9][0-9][0-9][0-9] )
        ;;
    * )
        unset year
        set -- $(date)
        ;;
    esac

    while [ -z "$year" -a  $# -gt 0 ]
    do
        case $1 in
        [1-9][0-9][0-9][0-9] )
            year=$1
            break
            ;;
        esac
        shift
    done

    month=$(date +%m)
    day=$(date +%d)
    today=${year}${month}$day
    case $month in
    1|01 ) This_Month=Jan ;;
    2|02 ) This_Month=Feb ;;
    3|03 ) This_Month=Mar ;;
    4|04 ) This_Month=Apr ;;
    5|05 ) This_Month=May ;;
    6|06 ) This_Month=Jun ;;
    7|07 ) This_Month=Jul ;;
    8|08 ) This_Month=Aug ;;
    9|09 ) This_Month=Sep ;;
      10 ) This_Month=Oct ;;
      11 ) This_Month=Nov ;;
      12 ) This_Month=Dec ;;
    esac
    def_issue_date=${day}-${This_Month}-${year}

    # Note: BKSH can be set to ksh or bash.
    if [ -z "$BKSH" ]
    then
        if $inBash
        then
            BKSH="/bin/bash -norc"
        else
            BKSH="/bin/ksh -p"
        fi
    fi

    if [ -x $EXTRAS/bin/lic_merge ]
    then
        LIC_MERGE="$BKSH $EXTRAS/bin/lic_merge"
    fi

    unset sul eul
    ${Running_remote:-false} && return

    if ${Do_underling:-true}
    then
        sul=$(tput smul 2>/dev/null)
        eul=$(tput rmul 2>/dev/null)
    fi

    test "$do_stty" = "no-stty" && return
    # If the kill-line-input character is the @ symbol,
    # change it to ctrl-U.
    if /bin/stty -a | grep 'kill = @' >/dev/null 2>&1
    then
        /bin/stty kill ^U
        # Restore setting upon exit.
        Restore_stty="/bin/stty kill @"
    fi
}

#------------------------------------------------------------------------
function rsf_list_all_alt_licenses
{
    # No alternate licenses when doing setup for other.
    $License_setup_other && return

    for i in $License_Key_List
    do
        eval lic_name=\$rs_startup_key$i
        case "$lic_name" in
        PurifyPlusUNIX )
            print "$ALT_PPLUS_LICENSES"
            ;;
        esac

        # Check for alternate license names using the .ini file.
        egrep "[|$WS]$lic_name:[1-9]" $INI_FILE |
            awk -F\| '{print $1}' |
            grep -v "^$lic_name\$"
    done | sort -u
}

#------------------------------------------------------------------------
function rsf_set_License_Key_List
{
    unset License_Key_List Feature_List Alternate_Key_List Feat_List
    feat_column=30
    Lic_Nam2=$(rsf_typst -L $feat_column "$SPACES")
    case $1 in
    -a )
        n=0
        SKN=0
        while true
        do
            let n=n+1
            eval lic_name=\$rs_startup_key$n
            test -n "$lic_name" || break
            Feat_List="$Feat_List $lic_name"
            License_Key_List="$License_Key_List $n"
            let SKN=SKN+1
        done
        let rs_startup_key_n=n-1
        ;;
    -i )
        # Set list from import file.
        search="INCREMENT[$WS].*[$WS]$vendor_daemon[$WS]|INCREMENT[$WS].*[$WS]$trl_daemon[$WS]"
        set -- 1 $(egrep "^$search"  $rsu_import_lic_file 2>/dev/null |
                   awk '{print $2}')
        shift
        test $# -eq 0 && return 1
        Feat_List="$*"
        Feature_List="
${sul}License Feature${eul}                  ${sul}Description${eul}"

        let i=${Startup_index}0+1
        for lic_name in $Feat_List
        do
            eval rs_startup_key$i=\$lic_name
            rsf_extract_lic_desc_method_from_import
            eval rs_startup_desc$i=\$lic_desc
            eval rs_startup_method$i=\$lic_method
            License_Key_List="$License_Key_List $i"
            Lic_Name=$(rsf_typst -L $feat_column $lic_name)
            Feature_List="$Feature_List\n$Lic_Name   $lic_desc"
            let i=i+1
        done
        return 0
        ;;
    -n )
        License_Key_List="$2"
        set -- $2
        SKN=$#
        while [ $# -gt 0 ]
        do
            eval lic_name=\$rs_startup_key$1
            Feat_List="$Feat_List $lic_name"
            shift
        done
        ;;
    esac

    # Using the .ini file, add any "suite" licenses to the the alternate
    # key list if they contain any of the licenses in the license key
    # list.  For example, if purify is in the license key list, the code
    # below will add DevelopmentStudioUNIX license to the alternate list
    # because purify is a member of that suite license.
    # These alternate keys cannot be on the license key list since it is
    # used for setting up temp keys.  Cannot use alternates for this
    # purpose, only for checking license import files, existing license
    # files and lmstat output for keys.
    set -- $(rsf_list_all_alt_licenses)
    if [ $# -gt 0 ]
    then
        if [ -z "$rs_startup_key_n" ]
        then
            # Walk the list of defined startup keys and
            # set rs_startup_key_n to the last one.
            n=0
            while true
            do
                let n=n+1
                eval lic_name=\$rs_startup_key$n
                test -n "$lic_name" || break
            done
            let rs_startup_key_n=n-1
        fi

        n=$rs_startup_key_n
        for alt_name in $(rsf_list_all_alt_licenses)
        do
            let SKN=SKN+1
            let n=n+1
            lic_desc=$(rsf_extract_ini_description $alt_name $n)
            eval rs_startup_key$n=\$alt_name
            eval rs_startup_desc$n=\$lic_desc
            Alternate_Key_List="$Alternate_Key_List $n"
            Feat_List="$Feat_List $alt_name"
        done
    fi

    Feature_List="
${sul}License Feature${eul}                  ${sul}Description${eul}"

    for n in $License_Key_List $Alternate_Key_List
    do
        eval lic_name=\$rs_startup_key$n
        Lic_Name=$(rsf_typst -L $feat_column $lic_name)

        if $License_setup_other
        then
            eval lic_desc=\$rs_startup_desc$n
        else
            lic_desc=$(rsf_extract_ini_description $lic_name $n)
            if [ -n "$lic_desc" ]
            then
                eval rs_startup_desc$n=\$lic_desc
            else
                eval lic_desc=\$rs_startup_desc$n
            fi
        fi

        if [ ${#lic_desc} -gt 46 ]
        then
            rsf_split_desc true 46 "$lic_desc"
            lic_desc="$desc1\n$Lic_Nam2     $desc2"
        fi
        Feature_List="$Feature_List\n$Lic_Name   $lic_desc"
    done
}

#------------------------------------------------------------------------
function rsf_set_prod_dir_ver
{
    # Arg1: Boolean: True if doing install, False if not.

    # Check if this product is shipped with a tar file containing a top-level
    # directory.  If it does and the containing directory does not match the
    # expected default, create a link to install through.
    # Since some products need to be installed in a separate directory
    # for each platform, include the prod_sys value to the product
    # directory path: <product>.<prod_sys>.<version>

    Doing_install=$1
    eval prod_dir=\$rs_prod_dir$p
    eval prod_ver=\"\$rs_prod_ver$p\"
    prod_dir_ver=$prod_dir.$prod_ver
    eval Prod_Sys=\"\$rs_prod_sys$p\"
    prod_sys=${Prod_Sys:-$sys}
    eval prod_lic_name=\$rs_prod_lic_name$p
    if [ "$prod_lic_name" != none  -a  "$rs_Install_In_Suite_Dir" = true ]
    then
        prod_dir_ver=$rs_Suite_Dir.$rs_Suite_Ver
        return
    fi

    eval Prod_Dir_Ver=\$rs_prod_dir_ver$p
    test -z "$Prod_Dir_Ver" && return

    if [ -n "$Prod_Sys" ]
    then
        case "$prod_dir" in
        *.$Prod_Sys* )
            prod_dir_ver=$prod_dir.$prod_ver
            ;;
        * )
            ${rs_Allow_Sys_Release_Dir:-true} &&
                prod_dir_ver=$prod_dir.$Prod_Sys.$prod_ver
            ;;
        esac
    else
        prod_dir_ver=$prod_dir.$prod_ver
    fi

    $Doing_install || return

    test "$Prod_Dir_Ver" = "$prod_dir_ver" && return

    # It contains a top-level directory and it does not match.

    if [ "$prod_lic_name" = none ]
    then
        Root=$Cots
    else
        Root=$Releases
    fi

    # Link to standard name.
    # During post-install (rsf_do_post_install) remove link and rename.
    cd $Root
    if [ -d $prod_dir_ver -a ! -L $prod_dir_ver ]
    then
        # Temporarily move it back during the install.
        /bin/mv $prod_dir_ver $Prod_Dir_Ver
    else
        rsf_make_dir $Root/$Prod_Dir_Ver now
    fi

    _marker="# $Prod_Dir_Ver = $prod_dir_ver"
    grep "^$_marker" $RM_LIST >/dev/null 2>&1
    if [ $? -ne 0 ]
    then
        if [ ! -L $prod_dir_ver ]
        then
             /bin/ln -s $Prod_Dir_Ver $prod_dir_ver
        fi
        print "
$_marker
/bin/rm -f $Root/$prod_dir_ver
/bin/mv    $Root/$Prod_Dir_Ver $Root/$prod_dir_ver" >> $RM_LIST

    fi
    cd $OLDPWD
}

#------------------------------------------------------------------------
function rsf_check_if_server_needed
{
    # Look at all of the quantity fields in the license file.
    # If any licenses are counted, will need to start a server.
    case "$1" in
    *@* )
        Need_server=true
        return
        ;;
    esac

    Need_server=false
    for _lf in $(IFS=: ; echo $1)
    do
        test -s "$_lf" || continue
        for _qty in $(egrep "^INCREMENT|^FEATURE" $_lf | awk '{print $6}')
        do
            case $_qty in
            0|uncounted )
                ;;
            [0-9]* )
                Need_server=true
                return
                ;;
            esac
        done
    done
}

#------------------------------------------------------------------------
function rsf_set_rs_License_Map
{
    if [ -n "$rs_Map_Name" ]
    then
        rs_License_Map=$rs_Map_Name
        return
    fi

    case $rs_Suite_Dir in
    DevelopmentStudioUNIX )
        rs_License_Map=License_Map
        return
        ;;
    DeveloperKitHP )
        rs_License_Map=RDK_License_Map
        return
        ;;
    DeveloperTools|PurifyPlus* )
        rs_License_Map=PurifyPlus_License_Map
        return
        ;;
    esac
    unset rs_License_Map
}

#------------------------------------------------------------------------
function rsf_set_RSU_LICENSE_MAP
{
    rsf_set_rs_License_Map
    if [ -n "$rs_License_Map" ]
    then
        if [ -f $Config/$rs_License_Map ]
        then
            export RSU_LICENSE_MAP=$Config/$rs_License_Map
        fi
    fi
}

#------------------------------------------------------------------------
function rsf_update_license_map
{
    # This function will set it if it is appropriate for the product.
    rsf_set_rs_License_Map

    # return if there is no map file for this product.
    test -z "$rs_License_Map" && return

    savLicFile=$rsu_lic_file
    case $rs_Suite_Dir in
    PurifyPlus* )
        # Before updating the P+ map file, make a list of all the licenses
        # being used by it in the release area.
        unset rsu_lic_file
        for _lf in $(rsf_get_unique_lic $Releases/*/.lm_license_file)
        do
            rsu_lic_file="$rsu_lic_file:$_lf"
        done
        rsu_lic_file=${rsu_lic_file#:}
        rsu_lic_file=${rsu_lic_file:-$savLicFile}
        ;;
    esac
    # Do the work
    rsf_do_license_map_update

    # Restore the license file info.
    rsu_lic_file=$savLicFile
}

#------------------------------------------------------------------------
function rsf_get_unique_lic
{
    for _lics in `(sort -u $* 2>/dev/null)`
    do
        for _lic in `(IFS=':' ; echo $_lics)`
        do
            echo $_lic
        done
    done | sort -u
}

#------------------------------------------------------------------------
function rsf_do_license_map_update
{
    test "$map_updated" = "$rsu_lic_file:$rs_License_Map" && return

    if [ -z "$rs_Map_Licenses" -o -z "$rs_Map_Order" -o -z "$rsu_lic_file" ]
    then
        # Do not create the map file, just copy it.
        rsf_update_config $DIR/$INSTALL/$rs_License_Map
        return
    fi

    # Generate the map that is optimized based on the licenses the
    # in the rs_Map_Order variable, but only include the ones that
    # are actually licensed.

    rsf_set_Actual_licenses
    rsf_trace_log true "Actual_licenses: $Actual_licenses"

    MAP_DIR=/tmp/$CMD.$USER.map
    test -d $MAP_DIR || mkdir $MAP_DIR
    print /bin/rm -fr $MAP_DIR >> $RM_LIST

    (
    echo "# Version: $RevN"
    echo "#$delim"
    echo "# This is the license map file for $rs_Suite_Name."
    echo "# Generated by $USER running $CMD on $(date +%D)."
    echo "# License: $rsu_lic_file"
    echo "#$delim"
    ) > $MAP_DIR/$rs_License_Map

    Have_map_licenses=false
    for lic_name in $rs_Map_Licenses
    do
        unset map_entry
        for this_lic in $rs_Map_Order
        do
            if [ "$this_lic" = standalone ]
            then
                # Add standalone if lic_name is licensed.
                eval have_lic=\$have_lic_$lic_name
                if ${have_lic:-false}
                then
                    map_entry="$map_entry, standalone"
                fi
            else
                # Add this_lic if it is licensed.
                eval have_lic=\$have_lic_$this_lic
                if ${have_lic:-false}
                then
                    # Get the this_lic license's version.
                    set -- $(grep "^$this_lic|" $INI_FILE |
                             awk -F\| '{print $2}')
                    map_entry="$map_entry, $this_lic:$1"
                fi
            fi
        done

        test -z "$map_entry" && continue

        # Removing the leading comma.
        map_entry=${map_entry#,}

        # Get the lic_name license's version.
        set -- $(grep "^$lic_name|" $INI_FILE | awk -F\| '{print $2}')
        print "$lic_name:$1 $map_entry" >>  $MAP_DIR/$rs_License_Map
        Have_map_licenses=true
    done

    if $Have_map_licenses
    then
        # Install the generated file.
        rsf_update_config $MAP_DIR/$rs_License_Map
        test -n "$LOG_FILE" && cat $Config/$rs_License_Map >> $LOG_FILE
        map_updated="$rsu_lic_file:$rs_License_Map"
    elif [ -f $DIR/$INSTALL/$rs_License_Map ]
    then
        # Install the default file.
        rsf_update_config $DIR/$INSTALL/$rs_License_Map
        test -n "$LOG_FILE" && cat $Config/$rs_License_Map >> $LOG_FILE
        map_updated="$rsu_lic_file:$rs_License_Map"
    fi
}

#------------------------------------------------------------------------
function rsf_set_Actual_licenses
{
    # Create a list of actual licenses.
    unset Actual_licenses
    prior_lic_file=$rsu_lic_file
    for lic_name in $rs_Map_Licenses $rs_Map_Order
    do
        test "$lic_name" = standalone && continue
        eval have_lic_$lic_name=false
    done

    if [ "$rs_Map_Name" = PurifyPlus_License_Map ]
    then
        # The map generation must also include all current .lm_license_file
        # settings from any existing PQC products installed in this area.
        for _olf in $(rsf_list_pqc_licenses | sort -u)
        do
            case ":$prior_lic_file:" in
            *:$_olf:* )
                ;;
            * )
                _other_lf="$_other_lf:$_olf"
                ;;
            esac
        done
    fi

    for rsu_lic_file in $(IFS=: ; echo ${prior_lic_file}$_other_lf)
    do
        rsf_check_if_server_needed $rsu_lic_file
        if $Need_server
        then
            rsf_set_lmstat_cmd
            $lmstat_cmd -a -c $rsu_lic_file >$TEMP 2>&1
            for lic_name in $rs_Map_Licenses $rs_Map_Order
            do
                test "$lic_name" = standalone && continue
                eval have_lic=\$have_lic_$lic_name
                $have_lic && continue
                if grep "Users of $lic_name:" $TEMP >/dev/null 2>&1
                then
                    eval have_lic_$lic_name=true
                    Actual_licenses="$Actual_licenses $lic_name"
                fi
            done
            continue
        fi

        for lic_name in $rs_Map_Licenses $rs_Map_Order
        do
            test "$lic_name" = standalone && continue
            eval have_lic=\$have_lic_$lic_name
            $have_lic && continue
            eval have_lic_$lic_name=false
            unset lic_feat
            eval $(rsf_read_increment $rsu_lic_file)
            if [ "$lic_feat" = "$lic_name" ]
            then
                if rsf_check_temp_key
                then
                    eval have_lic_$lic_name=true
                    Actual_licenses="$Actual_licenses $lic_name"
                fi
            fi
        done
    done
    rsu_lic_file=$prior_lic_file
    unset _olf _other_lf
}

#------------------------------------------------------------------------
function rsf_list_pqc_licenses
{
    for _pd in $Releases/purify* $Releases/quantify* $Releases/purecov*
    do
        if [ -s $_pd/.lm_license_file ]
        then
            _llf=$(cat $_pd/.lm_license_file)
            for _lf in $(IFS=: ; echo $_llf)
            do
                echo "$_lf"
            done
        fi
    done
    unset _pd _llf _lf
}

#------------------------------------------------------------------------
function rsf_set_License_File
{
    # Use the actual license file for each product for
    # startup or evaluation licensing, if no server is involved.
    # Otherwise, use port@host.

    unset Actual_License_File
    rsf_check_if_server_needed "$rsu_lic_file"
    if [ "$Lic_Key_Type" = temporary ]
    then
        if $Need_server
        then
            License_File=$rsu_lic_file
            return
        fi
        # Set this when using Startup or Eval keys.
        # This can be used instead of License_File
        # to eliminate going through the license server.
        Actual_License_File=$rsu_lic_file
    fi

    if $Need_server
    then
        # Need a license server, use port@host.
        if [ -n "$rsu_lic_port" -a "$rsu_lic_server" ]
        then
            case "$rsu_lic_file" in
            *:*|*@* )
                License_File=$rsu_lic_file
                ;;
            * )
                License_File=$rsu_lic_port@$rsu_lic_server
                ;;
            esac
        else
            License_File=$rsu_lic_file
        fi
    else
        # For uncounted licenses without a server,
        # must use license file name.
        License_File=$rsu_lic_file
        return
    fi
}

#------------------------------------------------------------------------
function rsf_set_setup_filenames
{
    # Set then name of the source files used to construct the
    # setup file for DevelopmentStudioUNIX Suite, ClearQuest,
    #  DeveloperKitHP, PurifyPlus, and RoseRT.
    # Return false if there are no setup files.

    unset SETUP_CSH SETUP_SH

    case $rs_Suite_Dir in
    DevelopmentStudioUNIX )
        SETUP_CSH=$DIR/extras/install_data/rs_setup.csh
         SETUP_SH=$DIR/extras/install_data/rs_setup.ksh
        ;;
    ClearQuest )
        SETUP_CSH=$DIR/extras/install_data/cq_setup.csh
         SETUP_SH=$DIR/extras/install_data/cq_setup.sh
        ;;
    DeveloperKitHP )
        SETUP_CSH=$DIR/extras/install_data/rdk_setup.csh
         SETUP_SH=$DIR/extras/install_data/rdk_setup.ksh
        ;;
    DeveloperTools|PurifyPlus* )
        SETUP_CSH=$DIR/extras/install_data/purifyplus_setup.csh
         SETUP_SH=$DIR/extras/install_data/purifyplus_setup.sh
        ;;
    RoseRT )
        SETUP_CSH=$DIR/extras/install_data/rosert_setup.csh
         SETUP_SH=$DIR/extras/install_data/rosert_setup.sh
        ;;
    * )
        return 1
        ;;
    esac

    if [ ! -f $SETUP_CSH  ]
    then
        unset SETUP_CSH
    fi

    if [ ! -f $SETUP_SH  ]
    then
        unset SETUP_SH
    fi

    test -n "${SETUP_CSH}${SETUP_SH}"  || return 1
}

#------------------------------------------------------------------------
function rsf_create_setup_files
{
    rsf_set_setup_filenames || return

    print "
    Creating/updating setup files
    in $Suite_Path..."

    rsf_set_License_File
    unset yn_update_cfg

    Suite_Name=${Suite_Path##*/}
    Rational_Dir_Name=${rsu_rational_dir##*/}
    for setup_src in $SETUP_CSH $SETUP_SH
    do
        setup_name=${setup_src##*/}
        setup_dst=$Suite_Path/$setup_name
        rsf_sed_rsu_parms $setup_src > $TEMP
        if [ -f $setup_dst ]
        then
            if diff $TEMP $setup_dst >/dev/null
            then
                print "      Up-to-date: $setup_name in $Suite_Name"
            else
                /bin/cp $TEMP $setup_dst
                print "         Updated: $setup_name in $Suite_Name"
            fi
        else
            /bin/cp $TEMP $setup_dst
            print "         Created: $setup_name in $Suite_Name"
        fi

        if [ ! -f $rsu_rational_dir/$setup_name ]
        then
            /bin/cp $TEMP $rsu_rational_dir/$setup_name
            yn_update_cfg=yes
            continue
        fi

        rd_setup_dst=$rsu_rational_dir/$setup_name
        if diff $rsu_rational_dir/$setup_name $TEMP >/dev/null
        then
            yn_update_cfg=yes
            continue
        fi

        if [ -z "$yn_update_cfg" ]
        then
            eval $(grep "SETUP_USE=" $rd_setup_dst | sed -e 's?^#??')
            print "
    A copy of $setup_name exists in the
    $rsu_rational_dir directory.
    $SETUP_USE"

            def_yn_update_cfg=yes
            rsf_get_option yn_update_cfg y_n \
                "Would you like to update the copy of $setup_name
    in $rsu_rational_dir?"
        fi

        if [ "$yn_update_cfg" = no ]
        then
            print "     Not Updated: $setup_name in $Rational_Dir_Name."
            continue
        fi

        if /bin/cp $TEMP $rsu_rational_dir/$setup_name
        then
            print "         Updated: $setup_name in $Rational_Dir_Name."
            continue
        fi

        print "          Update: $setup_name in $Rational_Dir_Name failed."
        print "                  You are not the owner of this file."
    done
    /bin/rm $TEMP

    if [ "$yn_update_cfg" = yes ]
    then
        setup_root=$rsu_rational_dir
    else
        setup_root=$Suite_Path
    fi

    print "
    You can source the setup file to help you start the programs in this
    install.  If you are installing this for users in addition to yourself
    you will want to have them add one of these commands to their login
    environment."

    if [ -n "$SETUP_CSH" ]
    then
        print "
    Users of csh, tcsh and other csh-compatible shells do this:

source $setup_root/${SETUP_CSH##*/}"
    fi

    if [ -n "$SETUP_SH" ]
    then
        print "
    Users of sh, ksh, bash and other bourne-compatible shells do this:

. $setup_root/${SETUP_SH##*/}"
    fi

    print
}

#------------------------------------------------------------------------
function rsf_list_doc_dir
{
    cd $DIR/docs
    if [ -s .sizes ]
    then
        awk '{print $2}' .sizes
        return
    fi

    for doc_file in */*
    do
        test -f $doc_file -o -d $doc_file && print $doc_file
    done

    for doc_file in *
    do
        test -f $doc_file && print $doc_file
    done
}

#------------------------------------------------------------------------
function rsf_install_doc_file
{
    doc_src=$DIR/docs/$doc_file
    doc_dst=$Suite_Path/docs/$doc_file
    Doc_reinstall=false
    Doc_installed=false

    if [ -f $doc_src ]
    then
        # Source doc is a file.  Check destination file.
        if [ -f $doc_dst ]
        then
            Doc_installed=true
        fi
        doc_fname_file="$doc_fname file"
    elif [ -d $doc_src/. ]
    then
        # Source doc is a directory.  Check destination directory.
        if [ -d $doc_dst/. ]
        then
            Doc_installed=true
        else
            # Make sure destination does not exist as a file.
            test -f $doc_dst && /bin/rm -f $doc_dst
        fi
        doc_fname_file="$doc_fname directory"
    fi

    if $Doc_installed
    then
        case $rsu_install_mode in
        ask )
            Reinstall_it="The $doc_fname_file is already installed."
            Reinstall_it="$Reinstall_it\n    Reinstall it"
            yn_reinstall=${yn_reinstall:-no}
            rsf_get_option yn_reinstall y_n "$Reinstall_it?"
            test "$yn_reinstall" = no && return
            Doc_reinstall=true
            ;;
        reinstall )
            Doc_reinstall=true
            ;;
        skip )
            print "    Already installed: $doc_fname"
            return
            ;;
        esac
    fi

    if [ -d $doc_src ]
    then
        if $Doc_reinstall
        then
            rsf_copy -r "$doc_fname" $doc_src $doc_dst
        else
            rsf_copy -p "$doc_fname" $doc_src $doc_dst
        fi
    elif [ -f $doc_src ]
    then
        if $Doc_reinstall
        then
            print "    Reinstalling: $doc_fname..."
            /bin/rm -f $doc_dst
            /bin/cp $doc_src $doc_dst
        else
            print "    Installing: $doc_fname..."
            rsf_mkdir_p ${doc_dst%/*}
            /bin/cp $doc_src $doc_dst
        fi
    fi
}

#------------------------------------------------------------------------
function rsf_do_doc_install
{
    test "$rsu_install_docs" = none && return
    test -d $DIR/docs || return

    # The docs directory should be that, not a file.
    # Remove it if it is a file, just in case.
    test -f $Suite_Path/docs && /bin/rm -f $Suite_Path/docs

    if [ "$rsu_install_docs" = all ]
    then
        doc_list=$(rsf_list_doc_dir)
    else
        doc_list=$(IFS='+'; echo $rsu_install_docs)
    fi

    prior_doc_type=none
    for doc_file in $doc_list
    do
        rsf_set_doc_desc
        doc_files=$doc_file
        if [ "$doc_type" != "$prior_doc_type" ]
        then
            print "\n    Installing: ${sul}$doc_desc${eul}
    from: $DIR/docs
      to: $Suite_Path/docs"
            prior_doc_type=$doc_type
        fi

        for doc_file in $doc_files
        do
            doc_fname=$doc_file
            desc="$doc_fname: $doc_desc"
            rsf_install_doc_file
        done
    done
}

#------------------------------------------------------------------------
function rsf_install_flexlm
{
    $Enable_flexlm || return
    (
    for flex_sys in $SYS_LIST
    do
        unset flexlm_dir
        rsf_set_sys_arch $flex_sys
        rsf_set_extra_dir flexlm "$flexlm_ver" $flex_sys $sys_arch install
        test -n "$flexlm_dir" || continue
        flex_dst=$rsu_rational_dir/base/cots/flexlm.$flexlm_ver/$sys_arch
        test -f "$flex_dst/lmgrd" -a -f "$flex_dst/rational" && continue
        rsf_set_other_OS $flex_sys
        rsf_copy "FLEXlm $flexlm_ver for $other_OS" $flexlm_dir $flex_dst
    done
    exit $Install_errors
    )
    Install_errors=$?
}

#------------------------------------------------------------------------
function rsf_is_flexlm_installed
{
    # Check that the FLEXlm utilities are installed.
    _cmd=$1
    _local_remote=$2
    _src_var=$3
    _dst_var=$4
    eval _src_dir=\$$_src_var
    eval _dst_dir=\$$_dst_var
    if [ -n "$_src_dir" -a -n "$_dst_dir" ]
    then
        if [ -d "$_dst_dir" ]
        then
            return 0
        fi
    fi

    # FLEXlm source and destination command not installed.
    # Try to find it on the user's command search path.
    for _dir in $(IFS=: ; echo $PATH)
    do
        if [ -x $_dir/$_cmd ]
        then
            # Found it.  Use this one.
            eval $_src_var=\$_dir
            eval $_dst_var=\$_dir
            return 0
        fi
    done

    Flexlm_install_problem=true

    if [ -z "$Explain_flex_install_prob" ]
    then
        # Explain this only once.
        Explain_flex_install_prob=true
        case "$_cmd-$_local_remote" in
        lmstat-local|exinst_l-local )
            _err_mesg="Cannot check licenses."
            _this_os="$THIS_OS"
            ;;
        lmstat-remote )
            _err_mesg="Cannot check licenses on remote server."
            _this_os="$remote_os"
            ;;
        lmhostid-remote )
            _err_mesg="Cannot determine host ID of the remote server."
            _this_os="$remote_os"
            ;;
        esac
        print "    $_err_mesg  $_cmd not found."
        print "    FLEXlm is not installed for $_this_os."
    fi
    return 1
}

#------------------------------------------------------------------------
function rsf_misc_suite_install
{
    if [ $Okay_to_install = false ]
    then
        return
    fi

    rsf_install_flexlm

    for cpThis in rs_install $Cmd_Aliases
    do
        if [ -f $DIR/$cpThis ]
        then
            break
        else
            unset cpThis
        fi
    done

    if [ -n "$cpThis" -a -n "$Suite_Path" ]
    then
        /bin/rm -f $Suite_Path/$cpThis
        /bin/cp -f $DIR/$cpThis $Suite_Path/$cpThis
        (
         cd $Suite_Path
         for alias in $Cmd_Aliases
         do
             test "$alias" = "$cpThis" && continue
             /bin/rm -f $alias
             /bin/ln -s $cpThis $alias
         done

         # Create conditional aliases (need to exist in the distribution dir)
         for alias in $Cond_Aliases
         do
             test -f $DIR/$alias || continue
             /bin/rm -f $alias
             /bin/ln -s $cpThis $alias
         done
        )
    fi

    print "
    Setting release area to be user and group writable:"
    print chmod -R u+w,g+w $Suite_Path
    /bin/chmod -R u+w,g+w $Suite_Path 2>/dev/null

    if [ ! -d $Suite_Path/$INSTALL ]
    then
        rsf_copy "$rs_Suite_Name_Ver Install Data" \
            $DIR/$INSTALL $Suite_Path/$INSTALL
    fi

    if [ -d extras/LAP/LA_files ]
    then
        set --
    else
        set -- extras/shrink*.html
    fi
    for other in $Cond_Copies $*
    do
        test -f $other || continue
        /bin/rm -f $Suite_Path/$other
        /bin/cp $other $Suite_Path/$other
    done

    rsf_update_config $DIR/$INSTALL/uninstall
    rsf_update_config $INI_FILE
    if [ -d $DIR/$INSTALL/config ]
    then
        for cfg in $DIR/$INSTALL/config/*
        do
            rsf_update_config $cfg
        done
    fi

    if [ ! -d $Suite_Path/extras/bin ]
    then
        rsf_copy "$rs_Suite_Name_Ver Tools" \
            $DIR/extras/bin $Suite_Path/extras/bin
    fi

    if [ -d $DIR/extras/ksh -a ! -d $Suite_Path/extras/ksh ]
    then
        rsf_copy "$rs_Suite_Name_Ver K-Shell" \
            $DIR/extras/ksh $Suite_Path/extras/ksh
    fi
}

#------------------------------------------------------------------------
function rsf_create_lm_license_file
{
    # Only set this file for licensed products.
    eval licensed=\$rs_prod_licensed$p
    test "$licensed" = yes || return

    case $prod_dir in
    *ClearQuestClient* )
        Use_Lic_File=${Actual_License_File:-$License_File}
        ;;
    * )
        Use_Lic_File=$License_File
        ;;
    esac
    print "$Use_Lic_File" > $prod_home/.lm_license_file
}

#------------------------------------------------------------------------
function rsf_do_extras_install
{
    # Install all products that are not licensed.
    # (utilities such as netscape and acrobat, e.g. lic_name = none)
    for p in $suite_prod
    do
        eval prod=\"\$rs_prod_name$p\"
        eval prod_ver=\"\$rs_prod_ver$p\"
        prod_name_ver="$prod $prod_ver"
        rsf_set_prod_dir_ver true
        eval inst=\"\$rs_prod_inst$p\"
        if [ "${inst:-yes}" = no ]
        then
            print "\n      Not installing ${sul}${prod_name_ver}${eul}."
            continue
        fi

        eval size=\"\$rs_prod_size$p\"
        if rsf_set_extra_src $DIR/extras/$prod_dir $prod_sys $prod_ver
        then
            print "\n    Installing ${sul}${prod_name_ver}${eul} ($size KB)..."
            rsf_set_other_OS $prod_sys
            prod_dst=$Cots/$prod_dir_ver/$other_ARCH
            rsf_update_suite_list $prod_dst
            if rsf_tarcp check $prod_src $prod_dst
            then
                rsf_install_patches
            fi
        fi
    done

    # Run rsf_link_docs for each installed product under releases.
    for p in $rs_products
    do
        eval prod_name=\"\$rs_prod_name$p\"
        rsf_set_prod_dir_ver false
        prod_name_ver="$prod_name $prod_ver"
        test "$prod_lic_name" = none && continue
        prod_home=$Releases/$prod_dir_ver
        test -d $prod_home || continue
        rsf_link_docs
    done

    # Need to rerun the bin_setup command after the doc links get created.
    for bin_setup in $DIR/$INSTALL/*bin_setup.pi
    do
        if [ -f $bin_setup ]
        then
            . $bin_setup
            break
        fi
    done
}

#------------------------------------------------------------------------
function rsf_do_install
{
    $Okay_to_install || return
    rsf_set_suite_size
    print
    print "    Installing: ${sul}$Prod_Name_Ver${eul}..."
    print "    into: $rsu_rational_dir"
    print "    size: $suite_size KB $Size_Desc"

    rsf_create_dot_prod_name_ver "$Suite_Path" \
        "${suite_full_name:-${rsu_product_name:-$rs_Suite_Name}}" \
        "${rsu_product_ver:-$rs_Suite_Ver}"

    rsf_misc_suite_install
    rsf_update_license_map
    rsf_do_doc_install

    eval suite_prod=\"\$rs_suite_prod$rsu_product_num\"
    for p in $suite_prod
    do
        eval prod=\"\$rs_prod_name$p\"
        test "$prod" = FLEXlm && continue

        eval inst=\"\$rs_prod_inst$p\"
        inst=${inst:-yes}
        eval prod_ver=\"\$rs_prod_ver$p\"
        prod_name_ver="$prod $prod_ver"
        if [ "$inst" = no ]
        then
            print "\n      Not installing ${sul}${prod_name_ver}${eul}."
            continue
        fi

        eval size=\"\$rs_prod_size$p\"
        rsf_set_prod_dir_ver true
        if [ "$prod_lic_name" = none ]
        then
            if rsf_set_extra_src $DIR/extras/$prod_dir $prod_sys $prod_ver
            then
                print "\n    Installing ${sul}${prod_name_ver}${eul} ($size KB)..."
                rsf_set_other_OS $prod_sys
                prod_dst=$Cots/$prod_dir_ver/$other_ARCH
                rsf_update_suite_list $prod_dst
                if rsf_tarcp check $prod_src $prod_dst
                then
                    rsf_install_patches
                fi
            fi
            continue
        fi

        print "\n    Installing ${sul}${prod_name_ver}${eul} ($size KB)..."
        rsf_set_prod_src $DIR/products/$prod_dir $prod_sys $prod_ver
        prod_dst=$Releases/$prod_dir_ver
        rsf_update_suite_list $prod_dst
        rsf_make_dir $prod_dst now
        rsf_install_type
        rsf_install_patches
        if [ "$prod_dir" = rose ]
        then
            rsf_create_dot_prod_name_ver "$prod_dst" "$prod" "$prod_ver"
        fi
    done
    cd $DIR
    rsf_pause
}

#------------------------------------------------------------------------
function rsf_check_ini_file
{
    # First check license specs and then check package specs.
    INI_NAME=${INI_FILE##*/}
    ini_error=0

    # Will check the following items for each license spec.
    # 1. There are at least 11 parameters for each entry.
    # 2. Parm 2 is a valid license version: nnn.mmm
    # 3. Parm 5 is a valid DUP_GROUP: U, H, D, UH, UD, HD, UHD or NONE
    # 4. Parm 7 is a valid license method.: Floating, Node-Locked or NamedUser
    # 5. Parm 8 is a valid license part number: 3121-<5-digits>
    # 6. Parm 11 is a valid evaluation license quantity: 0, 1 or 9999.
    # 7. There are no duplicate entries for a specific product (parm 6), and
    #      license method (parm 7).

    grep -v "^<" $INI_FILE | while read entry
    do
        IFS='|'
        set -- $entry
        IFS=$oldIFS

        case "$2" in
        [0-9]*.[0-9]|[0-9]*.[0-9][0-9]|[0-9]*.[0-9][0-9][0-9] )
           ;;
        * )
           let ini_error=ini_error+1
           print_e "*** $CMD: Error $ini_error: license '$1' format error"
           print_e "    in $INI_NAME.  Invalid license version '$2'."
           ;;
        esac

        case "$5" in
        U|H|D|UH|UD|HD|UHD|NONE )
           ;;
        * )
           let ini_error=ini_error+1
           print_e "*** $CMD: Error $ini_error: license '$1' format error"
           print_e "    in $INI_NAME.  Invalid DUP_GROUP '$5'."
           ;;
        esac

        case "$7" in
        Floating|Node-Locked|NamedUser )
           ;;
        * )
           let ini_error=ini_error+1
           print_e "*** $CMD: Error $ini_error: license '$1' format error"
           print_e "    in $INI_NAME.  Invalid license method '$7'."
           ;;
        esac

        case "$8" in
        3121-[0-9][0-9][0-9][0-9][0-9] )
           ;;
        * )
           let ini_error=ini_error+1
           print_e "*** $CMD: Error $ini_error: license '$1' format error"
           print_e "    in $INI_NAME.  Invalid license part number '$8'."
           ;;
        esac

        lic=$1
        shift 9
        case "$2" in
        0|1|9999 )
           ;;
        * )
           let ini_error=ini_error+1
           print_e "*** $CMD: Error $ini_error: license '$lic' format error"
           print_e "    in $INI_NAME.  Invalid eval license quantity '$2'."
           ;;
        esac
    done

    # Check for duplicate entries.
    grep -v "^<" $INI_FILE | awk -F\| '{printf("%s|%s\n",$6,$7)}' |
        sort > $TEMP.1
    sort -u $TEMP.1 > $TEMP.2
    diff $TEMP.1 $TEMP.2 >/dev/null
    if [ $? -ne 0 ]
    then
        let ini_error=ini_error+1
        print_e "*** $CMD: Error $ini_error: Duplicate license entry found"
        print_e "    in $INI_NAME:"
        diff $TEMP.2 $TEMP.1 |
            sed -e '/^[0-9]/d' -e 's?>?      check:?'
    fi
    /bin/rm -f $TEMP.1 $TEMP.2

    # Now check package specs.
    # First, make sure the sequence number (arg2) is sequenced properly.
    n=0
    for seq in $(grep "^<package>" $INI_FILE | awk -F\| '{print $2}')
    do
        let n=n+1
        if [ $n -ne $seq ]
        then
            let ini_error=ini_error+1
            print_e "*** $CMD: Error $ini_error: <package> sequence error."
            print_e "    <package> $n is marked as $seq in $INI_NAME."
            break
        fi
    done

    # Second, check the package specification field (arg9) is valid.
    # The package specification is composed of the parameters:
    # Parm 1: PACKAGE
    # Parm 2: package name
    # Parm 3: vendor daemon
    # Parm 4: package version
    # Parm 5: package license key
    # Will check parms 1, 3, 4 and 5 only.
    set -- $(grep  "^<package>" $INI_FILE |
             awk -F\| '{print $9}' |
             awk '{print $1, $2, $3, $4, $5}')
    while true
    do
        if [ "$1" != PACKAGE ]
        then
           let ini_error=ini_error+1
           print_e "*** $CMD: Error $ini_error: <package> '$2' format error"
           print_e "    in $INI_NAME.  Missing 'PACKAGE' tag."
        fi

        if [ "$3" = "$vendor_daemon" -o  "$3" = "$trl_daemon" ]
        then
           :
        else
           let ini_error=ini_error+1
           print_e "*** $CMD: Error $ini_error: <package> '$2' format error"
           print_e "    in $INI_NAME.  Invalid vendor daemon: $3"
        fi

        case "$4" in
        [0-9]*.[0-9]|[0-9]*.[0-9][0-9]|[0-9]*.[0-9][0-9][0-9] )
           ;;
        * )
           let ini_error=ini_error+1
           print_e "*** $CMD: Error $ini_error: <package> '$2' format error"
           print_e "    in $INI_NAME.  Invalid PACKAGE version '$4'."
           ;;
        esac

        alt_opt=$(rsf_is_hex "$5")
        case "$alt_opt" in
        hex )
           if [ ${#5} -ne 12 ]
           then
           let ini_error=ini_error+1
           print_e "*** $CMD: Error $ini_error: <package> '$2' format error"
           print_e "    in $INI_NAME.  PACKAGE key '$5' is not 12 digits."
           fi
           ;;
        * )
           let ini_error=ini_error+1
           print_e "*** $CMD: Error $ini_error: <package> '$2' format error"
           print_e "    in $INI_NAME.  Invalid PACKAGE key '$5'."
           ;;
        esac

        # Shift to the next PACKAGE
        shift
        while [ "$1" != PACKAGE ]
        do
            shift
            test $# -eq 0 && break 2
        done
    done

    case $ini_error in
    0 )
        print "\n+++ $CMD: All license entries okay"
        print "    in $INI_FILE."
        ;;
    1 )
        print "\n*** $CMD: One error with license entry"
        print "    in $INI_FILE."
        ;;
    * )
        print "\n*** $CMD: $ini_error errors with license entries"
        print "    in $INI_FILE."
        ;;
    esac
}

#------------------------------------------------------------------------
function rsf_set_checksum_file_name
{
    checksum_name=.checksum
    checksum_file=$1/$checksum_name
}

#------------------------------------------------------------------------
function rsf_extract_checksum
{
    rsf_set_checksum_file_name $1 $2
    if [ -f $checksum_file ]
    then
        set -- $(grep " $2 ck" $checksum_file 2>/dev/null)
        if [ $# -eq 3 ]
        then
            cksum="$1"
            return
        fi
    fi
    unset cksum
}

#------------------------------------------------------------------------
function rsf_create_checksum_file
{
    test "$prod_dir" = rose -o "$prod_dir" = soda && return
    # Create a checksum file and use it to determine if a component#
    # (tar file) needs to be reinstalled.
    _loc=$1
    _file=$2
    rsf_set_checksum_file_name $_loc $_file
    if [ -f $checksum_file ]
    then
        grep " $_file ck" $checksum_file >/dev/null && return
    fi
    set -- $($SUM -r $_loc/$_file)
    echo $1 $_file ck >> $checksum_file
    print $checksum_file >> $TEMP
}

#------------------------------------------------------------------------
function rsf_compute_product_size
{
    if [ ! -w . ]
    then
        print_e "
    The -size option is not valid.  You do not have
    write permissions on the current directory:
       $DIR
        "
        return 1
    fi

    PRODUCT_SIZES=$BASE_PRODUCT_SIZES.$sys
    test -f $PRODUCT_SIZES || touch $PRODUCT_SIZES

    if [ ! -w $PRODUCT_SIZES ]
    then
        print_e "
    The -size option is not valid.  You do not have
    write permissions on the file:
       $PRODUCT_SIZES
        "
        return 1
    fi

    if [ -f $PRODUCT_SIZES ]
    then
        . $PRODUCT_SIZES
        NEW_PRODUCT_SIZES=$PRODUCT_SIZES.new
        print /bin/rm -f $NEW_PRODUCT_SIZES >> $RM_LIST
        size_file=${PRODUCT_SIZES##*/}
    else
        NEW_PRODUCT_SIZES=$PRODUCT_SIZES
        size_file=${SUITE_DESCRIPTION##*/}
    fi
    (
    print "# Sizes in this file override the sizes listed in the"
    print "# ${SUITE_DESCRIPTION##*/} file for $other_OS."
    ) > $NEW_PRODUCT_SIZES

    print "\nComputing the size of $rs_Suite_Name $rs_Suite_Ver"
    print "for $other_OS.\n"

    grand_total=0
    for p in $rs_products
    do
        eval prod_name=\"\$rs_prod_name$p\"
        eval prod_dir=\$rs_prod_dir$p
        eval prod_ver=\$rs_prod_ver$p
        eval prod_sys=\$rs_prod_sys$p
        prod_sys=${prod_sys:-$sys}
        eval prod_size=\"\$rs_prod_size$p\"
        eval prod_lic_name=\$rs_prod_lic_name$p
        prod_name_ver="$prod_name $prod_ver"

        # Set product source. First look for a version directory
        # under a sys dir, then look for a version directory under
        # the prod_dir directory, then look under extras.
        unset prod_src_list
        for prod_src in \
            $DIR/products/$prod_dir/$prod_sys/* \
            $DIR/products/$prod_dir/$prod_ver \
            $DIR/extras/$prod_dir/$prod_sys/$prod_ver \
            $DIR/extras/$prod_dir.$prod_ver.$prod_sys \
            $DIR/extras/$prod_dir.$prod_ver/$prod_sys \
            END
        do
            if [ "$prod_src"  = END ]
            then
                # Ignore netscape and acrobat if missing from Unix suite.
                case "$rs_Suite_Dir-$prod_dir" in
                DevelopmentStudioUNIX-netscape )
                    continue 2
                    ;;
                DevelopmentStudioUNIX-acrobat )
                    continue 2
                    ;;
                esac

                # Ignore product errors on Doc-only CD.
                $Doc_install_only && continue 2

                let size_error=size_error+1
                rsf_set_other_OS $prod_sys
                print_e "*** $CMD: Error $size_error:"
                print_e "    $prod_name_ver/$other_OS source not found."
                print_e "    Checked these locations: $prod_src_list"
                continue 2
            fi

            if [ -d $prod_src ]
            then
                 break
            fi
            prod_src_list="$prod_src_list\n      $prod_src"
        done

        if [ -f $prod_src/file0 ]
        then
            if [ $prod_src/prod_desc -nt $prod_src/file0 ]
            then
                . $prod_src/prod_desc
            else
                # The prod_desc file does not exist or it is older than file0.
                # Extract prod_desc from file0.
                print "Updating $prod_src/prod_desc (file0 is newer)"
                set -- $(tar tf $prod_src/file0 | grep /prod_desc)
                prod_desc=$1
                mkdir $prod_dir.tmp.$$
                cd $prod_dir.tmp.$$
                tar xf $prod_src/file0 $prod_desc
                /bin/rm -f $prod_src/prod_desc
                cp $prod_desc $prod_src/prod_desc
                cd $OLDPWD
                rsf_remove_dir $prod_dir.tmp.$$
                . $prod_src/prod_desc
            fi
            print $prod_src/prod_desc >> $TEMP

            # Compute size of file0 (Install tools)
            set -- size $(gtar -tvf $prod_src/file0 |
                          awk 'BEGIN {sum=0} {sum+=$3} END {print sum}')

            size=$(rsf_sntoint ${2:-0})
            # Add 10% by multiplying by 11/10ths.
            let "size=$size/10*11"

            # Convert bytes to Kbytes and round off size to nearest 1K.
            if [ $size -lt 1000 ]
            then
                size=1
            else
                size3=$(rsf_typst -R 3 $size)
                if [ $size3 -lt 500 ]
                then
                    let size=size/1000
                else
                    let size=$size/1000+1
                fi
            fi
            rsf_create_checksum_file $prod_src file0
            print $prod_src/file0 >> $TEMP

            c=1
            while [ $c -le $cmps ]
            do
                if [ -f $prod_src/file$c ]
                then
                    print $prod_src/file$c >> $TEMP
                    eval cmp_size=\$cmp_${c}_size
                    let size=size+cmp_size
                    rsf_create_checksum_file $prod_src file$c
                fi
                let c=c+1
            done
            Total=$(rsf_typst -R 8 $size)
            let grand_total=grand_total+size
            if [ $size -eq $prod_size ]
            then
                sd_status="(Okay in $size_file)"
            else
                sd_status="(Was $prod_size in $size_file)"
            fi
            print "${Total} KB  $prod_name_ver"
            print "             $sd_status"
            print "rs_prod_size$p='$size' # $prod_name_ver" \
               >> $NEW_PRODUCT_SIZES
            continue
        fi

        case $prod_dir in
        purify|quantify|purecov|RoseRT)
            Get_prod_dir_from_tar=true
            ;;
        * )
            Get_prod_dir_from_tar=false
            ;;
        esac

        total_size=0
        prod_share_src=$(dirname $prod_src)
        prod_share_src=$(dirname $prod_share_src)/share/$prod_ver
        if [ ! -d $prod_share_src ]
        then
            unset prod_share_src
        fi
        rsf_set_tar_list
        for tar_file in $tar_list
        do
            print $tar_file >> $TEMP
            case $tar_file in
            *.Z )
                if $Get_prod_dir_from_tar
                then
                    set -- prod_dir $(gtar -tZf $tar_file \
                           2>/dev/null |head -1)
                    prod_dir_ver=$2
                fi
                set -- size $(gtar -tZvf $tar_file 2>/dev/null |
                              awk 'BEGIN {sum=0} {sum+=$3} END {print sum}')
                ;;
            *.gz|*.cbt )
                print ${tar_file%cbt}pkg >> $TEMP
                if $Get_prod_dir_from_tar
                then
                    set -- prod_dir $(gtar -tzf $tar_file \
                           2>/dev/null | head -1)
                    prod_dir_ver=$2
                fi
                set -- size $(gtar -tzvf $tar_file 2>/dev/null |
                              awk 'BEGIN {sum=0} {sum+=$3} END {print sum}')
                ;;
            * )
                if $Get_prod_dir_from_tar
                then
                    set -- prod_dir $(gtar -tf $tar_file 2>/dev/null |head -1)
                    prod_dir_ver=$2
                fi
                set -- size $(gtar -tvf $tar_file |
                              awk 'BEGIN {sum=0} {sum+=$3} END {print sum}')
                ;;
            esac
            test $# -eq 2 || continue

            # Add 10% by multiplying by 11/10ths.
            size=$(rsf_sntoint $2)
            let "size=size/10*11"

            # Convert bytes to Kbytes and round off size to nearest 1K.
            case $size in
            ?|??|???) size=1 ;;
            *[01234]??) let size=size/1000 ;;
            *) let size=$size/1000+1 ;;
            esac
            let total_size=total_size+size
            if [ "$prod_lic_name" != none ]
            then
                rsf_create_checksum_file ${tar_file%/*} ${tar_file##*/}
            fi
        done
        if [ $total_size -eq 0  -a  "$prod_lic_name" = none ]
        then
            set -- $(cd $prod_src; du $du_opt .)
            total_size=$1
        fi
        Total=$(rsf_typst -R 8 $total_size)
        let grand_total=grand_total+total_size
        if [ $total_size -eq $prod_size ]
        then
            sd_status="(Okay in $size_file)"
        else
            sd_status="(Was $prod_size in $size_file)"
        fi
        print "${Total} KB  $prod_name_ver"
        print "             $sd_status"
        print "rs_prod_size$p='$total_size' # $prod_name_ver" \
           >> $NEW_PRODUCT_SIZES

        # Check if the tar file contains the directory name other than .
        # If so, record the dirname in the product sizes file.
        if $Get_prod_dir_from_tar
        then
            if [ "${prod_dir_ver%%/*}" = . ]
            then
                continue
            fi
            case $prod_dir in
            purify|quantify|purecov|RoseRT )
                # Extract the top directory name.
                prod_dir_ver=${prod_dir_ver%%/*}
                ;;
            TopTwo )
                # Extract the top 2 directory names.
                _p=${prod_dir_ver%%/*}
                _v=${prod_dir_ver#*/}
                _v=${_v%%/*}
                prod_dir_ver=$_p/$_v
                ;;
            esac
            print "             Directory: $prod_dir_ver"
            print "rs_prod_dir_ver$p='$prod_dir_ver'" >> $NEW_PRODUCT_SIZES
        fi
    done

    Total=$(rsf_typst -R 8 $grand_total)
    GT="${Total} KB  Grand Total for $other_OS"
    GTL=$(rsf_typst -L ${#GT} "$delim")
    echo "$GTL"
    echo "$GT"
    echo
    if [ $NEW_PRODUCT_SIZES = $PRODUCT_SIZES ]
    then
        print "\nProduct sizes have been saved in $PRODUCT_SIZES."
    else
        if diff $PRODUCT_SIZES $NEW_PRODUCT_SIZES
        then
            print "\nProduct sizes are up-to-date in $PRODUCT_SIZES."
        else
            /bin/cp $NEW_PRODUCT_SIZES $PRODUCT_SIZES
            print "\nProduct sizes have been updated in $PRODUCT_SIZES."
        fi
        /bin/rm -f $NEW_PRODUCT_SIZES
    fi
    sd=${SUITE_DESCRIPTION##*/}
    echo "These values will override the size values in the $sd file."
    echo
    return $size_error
}

#------------------------------------------------------------------------
function rsf_create_doc_sizes
{
    test -d docs  || return

    print "\nComputing the size of the objects in the docs/directory..."
    NEW_SIZES=$DOC_SIZES.new
    rsf_get_doc_size_list > $NEW_SIZES

    if [ -f $DOC_SIZES ]
    then
        if diff $DOC_SIZES $NEW_SIZES
        then
            /bin/rm -f $NEW_SIZES
            print "\nOn-line document sizes are up-to-date in:\n  $DOC_SIZES"
        else
            /bin/rm -f $DOC_SIZES
            /bin/mv $NEW_SIZES $DOC_SIZES
            print "\nOn-line document sizes have been updated in:\n  $DOC_SIZES"
        fi
    else
        /bin/mv $NEW_SIZES $DOC_SIZES
        print "\nOn-line document sizes have been saved in:\n  $DOC_SIZES"
    fi
}

#------------------------------------------------------------------------
function rsf_build_product_sizes
{
    # Build size file for each platform.
    DIR=$(pwd)
    DOC_SIZES=$DIR/docs/.sizes
    Skip_OS_check=true
    Do_prod_sys_check=true
    function oslevel {
    return
    }

    rsf_set_misc "no-stty"
    rsf_set_arch_os
    rsf_set_path
    rsf_create_doc_sizes

    # Cleanup any checksum files.
    rsf_set_checksum_file_name
    find products -type f -name $checksum_name -exec /bin/rm -f {} \; \
        2>/dev/null
    /bin/rm -f $TEMP

    size_error=0
    if [ -f docs/.control ]
    then
        if grep '"DOCS:' $SUITE_DESCRIPTION >/dev/null
        then
            Check_doc_entries=true
            . $SUITE_DESCRIPTION
            for doc in $(grep -v "^#" docs/.control | awk -F\| '{print $1}')
            do
                if print " $Complete_doc_list " | grep " $doc " >/dev/null
                then
                    continue
                fi
                let size_error=size_error+1
                print_e "*** $CMD: Error $size_error: doc type '$doc' in"
                print_e "    docs/.control not used in $SUITE_DESCRIPTION."
            done
            rs_suite=0
        fi
    fi

    for sys in $SYS_LIST
    do
        (
        # If there is at least one product for this sys then
        # compute the size.
        sys_found=false
        for _dir in products/*/$sys* extras/*/$sys* extras/*.$sys*
        do
            case $_dir in
            extras/flexlm* ) continue ;;
            esac

            if [ -d $_dir ]
            then
                sys_found=true
                break
            fi
        done

        $sys_found || exit $size_error
        rsf_set_other_OS $sys
        rs_suite=0 rs_product=0
        unset rs_products rs_suites

        let size1_error=size_error+1
        . $SUITE_DESCRIPTION || exit $size1_error
        if [ -f $SUITE_DESCRIPTION.$sys ]
        then
            . $SUITE_DESCRIPTION.$sys
        fi

        rsf_compute_product_size
        exit $size_error
        )
        size_error=$?
    done

    Size_mesg="\n    The following products/ files are not being used:\n"
    find products -type f -print 2>/dev/null | while read file
    do
        grep "$file\$" $TEMP >/dev/null
        if [ $? -ne 0 ]
        then
            let size_error=size_error+1
            print "$Size_mesg***   error $size_error: $file"
            unset Size_mesg
        fi
    done

    rsf_check_ini_file
    let size_error=size_error+ini_error

    case "$size_error" in
    0 )
        print "\n+++ The '$CMD -size' command completed successfully."
        ;;
    1 )
        print "\n*** The '$CMD -size' command detected one error."
        ;;
    * )
        print "\n*** The '$CMD -size' command detected $size_error errors."
        ;;
    esac
}

#------------------------------------------------------------------------
function rsf_is_a_lic_file
{
    # It is a license file if it has INCREMENT or FEATURE lines.
    egrep "^INCREMENT|^FEATURE" $1 >/dev/null 2>&1
    return $?
}

#------------------------------------------------------------------------
function rsf_is_a_rational_lic_file
{
    # It is a Rational license file if it has any INCREMENT or FEATURE
    # line for the Rational/IBM vendor daemons.
    for _daemon in $vendor_daemon $trl_daemon
    do
        if egrep "^INCREMENT.*[$WS]$_daemon[$WS]" $1 >/dev/null 2>&1
        then
            return 0
        fi
        if egrep   "^FEATURE.*[$WS]$_daemon[$WS]" $1 >/dev/null 2>&1
        then
            return 0
        fi
    done
    return 1
}

#------------------------------------------------------------------------
function rsf_license_check_menu
{
    rsf_check_flexlm_ver
    last_lic_check_opt=4
    end_lic_check_opt=q
    unset def_lic_check_opt
    rsf_update_license_map

    # Set flag Using_port_at_host if strictly using port@host.
    # If there are port@hosts within a colon-separated list,
    # but there are also license files, we are not strictly
    # using port@host.  In this case we can still run exinstal.
    case "$rsu_lic_file" in
    *:* )
        Using_port_at_host=true
        The_license_file="The license configuration list"
        using_port_host_or_list="using a license configuration list"
        ;;
    *@* )
        Using_port_at_host=true
        The_license_file="The port@host"
        using_port_host_or_list="using port@host"
        ;;
    * )
        Using_port_at_host=false
        The_license_file="The license file"
        if [ -z "$Lic_Key_Type" ]
        then
            for i in $License_Key_List $Alternate_Key_List
            do
                eval lic_name=\$rs_startup_key$i
                eval $(rsf_read_increment $rsu_lic_file)
            done
        fi
        ;;
    esac

    if $Using_port_at_host
    then
        # Cannot perform exinstal check if using port@host.
        LCM1="1)  Cannot use exinstal to check keys--$using_port_host_or_list:
         $rsu_lic_file"
    else
        if [ "$CMD" = options_setup ]
        then
            def_lic_check_opt=2
        else
            def_lic_check_opt=1
        fi
        LCM1="1)  Check license keys in:
         $rsu_lic_file"
    fi

    rsf_check_if_server_needed "$rsu_lic_file"

    if $Using_port_at_host
    then
        def_lic_check_opt=${def_lic_check_opt:-3}
        LCM23="

     2)  Cannot start/restart the license server $using_port_host_or_list.

     3)  Check license server using lmstat."

    elif $Need_server
    then
        if $Use_existing_licenses
        then
            def_lic_check_opt=${def_lic_check_opt:-3}
        else
            def_lic_check_opt=${def_lic_check_opt:-2}
        fi
        LCM23="

     2)  Start or restart the license server.
         Will check if a license server is running.  If not, will start it.
         If it is running, will restart it.

     3)  Check license server using lmstat."

    else
        LCM23="

     The license server is not needed for uncounted licenses:

     2)  No need to start or restart the license server.

     3)  No need to check license server using lmstat--licenses are uncounted."
    fi

    rsf_check_license_changed "this menu (step 4)."
    if $License_setup_other
    then
        unset LCM4
        last_lic_check_opt=3
    elif $rsu_license_changed
    then
        def_lic_check_opt=${def_lic_check_opt:-4}
        LCM4="
     4)  Update license settings for $rs_Suite_Name."
    else
        LCM4="
     4)  License settings for $rs_Suite_Name up-to-date."
    fi

    case $CMD in
    rs_install )
        end_lic_check_opt=f
        Option_f_okay=true
        Allow_Forward="
     f)  Forward to the next menu to continue..."
        ;;
    * )
        Option_f_okay=false
        unset Allow_Forward
        ;;
    esac

    case $CMD in
    rs_install|license_setup|options_setup )
        Option_b_okay=true
        Allow_Backward="
     b)  Back to the previous menu."
        ;;
    * )
        Option_b_okay=false
        unset Allow_Backward
        ;;
    esac

    case "${Option_f_okay}-$Option_b_okay" in
    true-true )
        Lic_chk_mnu=mnfb
        ;;
    true-false )
        Lic_chk_mnu=mnf
        ;;
    false-true )
        Lic_chk_mnu=mnb
        ;;
    false-false )
        Lic_chk_mnu=mnu
        ;;
    esac

    def_lic_check_opt=${def_lic_check_opt:-$end_lic_check_opt}

    while true
    do
        rsf_menu_title $rs_Suite_Name - License Check Menu
        case "$def_lic_check_opt" in
        1 )
            LCM="$LCM1
         Will check for these licenses:
         $Feature_List $LCM23"
            ;;
        3 )
            LCM="$LCM1 $LCM23  Will check for these licenses:
         $Feature_List"
            ;;
        * )
            LCM="$LCM1 $LCM23"
            ;;
        esac

        rsf_print_menu "$def_lic_check_opt" "$Explain_fix_license
     $LCM
     $LCM4
     $Allow_Forward $Allow_Backward
     q)  ${Quit_CMD}$Help_Option5"

        unset lic_check_opt
        rsf_get_option lic_check_opt $Lic_chk_mnu "Enter menu option:"

        case $lic_check_opt in
        1 )
            if $Using_port_at_host
            then
                print "
    Option 1 is not a valid choice.  The license keys cannot be checked when
    you are $using_port_host_or_list."
                rsf_pause
            else
                if rsf_do_license_check_exinst_l
                then
                    if $Need_server
                    then
                        if $Use_existing_licenses
                        then
                            def_lic_check_opt=3
                        else
                            def_lic_check_opt=2
                        fi
                    elif $rsu_license_changed
                    then
                        def_lic_check_opt=4
                    else
                        def_lic_check_opt=$end_lic_check_opt
                    fi
                elif $Option_b_okay
                then
                    def_lic_check_opt=b
                fi
            fi
            ;;
        2 )
            if $Use_existing_licenses
            then
                if $Using_port_at_host
                then
                    print "
    You selected to use existing licenses.  You cannot use this option
    when using port@host ($rsu_lic_file)."
                    rsf_pause
                elif $Need_server
                then
                    rsf_startlm_local_or_remote
                    unset rsu_options_updated
                    def_lic_check_opt=3
                else
                    print "
    You selected to use existing licenses.  Since the license file
    contains temporary licenses, a license server is not needed.
    Therefore, you do not need to start a license server."
                    rsf_pause
                fi

            elif $Need_server
            then
                rsf_startlm_local_or_remote
                unset rsu_options_updated
                def_lic_check_opt=3
            else
                print "
    Option 2 is not a valid choice.  It is not necessary to have a license
    server with uncounted licenses."
                rsf_pause
            fi
            ;;
        3 )
            if $Need_server
            then
                if rsf_do_license_check_lmstat
                then
                    if $rsu_license_changed
                    then
                        def_lic_check_opt=4
                    else
                        def_lic_check_opt=$end_lic_check_opt
                    fi
                elif $Option_b_okay
                then
                    def_lic_check_opt=b
                else
                    if $Use_existing_licenses
                    then
                        def_lic_check_opt=3
                    else
                        def_lic_check_opt=2
                    fi
                fi
            elif $Using_port_at_host
            then
                if rsf_do_license_check_lmstat
                then
                    if $rsu_license_changed
                    then
                        def_lic_check_opt=4
                    else
                        def_lic_check_opt=$end_lic_check_opt
                    fi
                elif $Option_b_okay
                then
                    def_lic_check_opt=b
                else
                    def_lic_check_opt=q
                fi
            else
                print "
    It is not necessary to have a license server with temporary/uncounted
    licenses.  Therefore you do not need to run the lmstat command."
                rsf_pause
            fi
            ;;
        4 )
            if $rsu_license_changed
            then
                rsf_update_lic_setting
                def_lic_check_opt=$end_lic_check_opt
            else
                print "
    It is not necessary to update the license settings.
    $The_license_file is unchanged since the last time post_install
    was run."
                yn_fix_lic=no
                rsf_get_option yn_fix_lic y_n "Update license settings anyway?"
                test "$yn_fix_lic" = yes && rsf_update_lic_setting
            fi
            ;;
        * )
            test "$lic_check_opt" = b  -a  "$Option_b_okay" = true && return
            test "$lic_check_opt" = f  -a  "$Option_f_okay" = true && break
            rsf_option_not_recognized "$lic_check_opt" "$last_lic_check_opt" \
                $Lic_chk_mnu
            ;;
        esac

        if $License_setup_other
        then
            unset LCM4
            if [ $def_lic_check_opt = 4 ]
            then
                def_lic_check_opt=$end_lic_check_opt
            fi
        elif $rsu_license_changed
        then
            LCM4="
     4)  Update license settings for $rs_Suite_Name."
        else
            LCM4="
     4)  License settings for $rs_Suite_Name up-to-date."
        fi

    done
    unset Option_f_okay Option_b_okay Lic_chk_mnu LCM LCM1 LCM23 LCM4
}

#------------------------------------------------------------------------
function rsf_do_license_check_exinst_l
{
    case $rsu_lic_file in
    *@*|*:*)
        return 0
        ;;
    esac

    print "\n$delim\n"

    rsf_is_flexlm_installed exinstal local flexlm_dir Lic_Dir || return 1

    # The exinstal and exinstrl commands return a count of the number of licenses
    # that have some sort of problem.
    EX_TMP=/tmp/exinst_l.tmp.$$
    EX_DAT=/tmp/exinst_l.dat.$$
    print /bin/rm -f $EX_TMP $EX_DAT >> $RM_LIST

    print "
    Will check for these specific licenses:\n$Feature_List"

    exinst_run=false
    ex_vars="EX_TMP EX_DAT lic_file exinst_run e_num
             exp_num license_keys lic_list num_lic lic_remain
             Server_line Vendor_line lic_found in_incr ex_vars"

    ex_status=0
    lic_remain=0
    if [ -f $rsu_lic_file ]
    then
        print "\n    Searching for '$vendor_daemon' specific license keys in:
      $rsu_lic_file"

        if rsf_extract_incr_lines $vendor_daemon > $EX_DAT
        then
            exinst_run=true
            rsf_run_exinst_cmd exinstal $vendor_daemon
            let ex_status=ex_status+$?
        fi
        print "\n    Searching for '$trl_daemon' specific license keys..."
        if rsf_extract_incr_lines $trl_daemon > $EX_DAT
        then
            exinst_run=true
            rsf_run_exinst_cmd exinstrl $trl_daemon
            let ex_status=ex_status+$?
        fi

    fi

    if $exinst_run
    then
        if [ $ex_status -eq 0 ]
        then
            unset $ex_vars
            rsf_pause
            return 0
        fi
    else
        print "
    No $vendor_daemon or $trl_daemon specific licenses found in:
      $rsu_lic_file"
        ex_status=1
    fi

    if [ $lic_remain -gt 0 ]
    then
        def_yn_use_dat_anyway=no
        rsf_get_option yn_use_dat_anyway y_n "Use this license anyway?"
        if [ "$yn_use_dat_anyway" = yes ]
        then
            ex_status=0
        else
            ex_status=1
        fi
    else
        test $ex_status -gt 0 && rsf_pause Q
    fi
    unset $ex_vars
    return $ex_status
}

#------------------------------------------------------------------------
function rsf_run_exinst_cmd
{
    # Before running exinstal or exinstrl on the licenses in the EX_DAT file,
    # check if any are expired.  If so, report on these and remove
    # them from the file.
    ex_prog=$1
    _daemon=$2
    set -- $(egrep "^INCREMENT|^FEATURE" $EX_DAT | awk '{print $2}')
    lic_list=$*
    num_lic=$#
    (
    exp_err=0
    for lic_name in $lic_list
    do
        set -- $(egrep "[$WS]$lic_name[$WS]" $EX_DAT)
        exp_date=$5
        mesg=$(rsf_exp_date_format_okay false)
        if [ $? = 2 ]
        then
            lic_line="$1 $2 $3 $4 $5 $6 $7"
            print "
Checking: $lic_line
    The expiration date appears to have already past.
    The date on this license is $exp_date
    A valid expiration date would have to be $def_issue_date or later."

            let exp_err=exp_err+1
            # Remove this from the file
            egrep -v "[$WS]$lic_name[$WS]" $EX_DAT > $EX_DAT.new
            /bin/mv $EX_DAT.new $EX_DAT
        fi
    done
    exit $exp_err
    )
    exp_num=$?

    if [ $exp_num -eq $num_lic ]
    then
        # All licenses expired.
        lic_remain=0
    elif [ $exp_num -gt 0 ]
    then
        # Some licenses expired.
        let lic_remain=num_lic-exp_num
        if [ $lic_remain -eq 1 ]
        then
            license_keys="the one remaining '$_daemon' license key"
        else
            license_keys="the $lic_remain '$_daemon' remaining license keys"
        fi
    else
        # No licenses expired.
        lic_remain=$num_lic
        if [ $num_lic -eq 1 ]
        then
            license_keys="the one '$_daemon' license key"
        else
            license_keys="the $num_lic '$_daemon' license keys"
        fi
    fi

    if [ $lic_remain -gt 0 ]
    then
        print "
    Running '$ex_prog' command to check $license_keys:
$Lic_Dir/$ex_prog \\
    $EX_DAT
"
        $Lic_Dir/$ex_prog $EX_DAT > $EX_TMP
        e_num=$?
        let e_num=e_num+exp_num

        # Show the installer what ex_prog emitted, excluding some lines.
        egrep -v "^Feature:|^License path:|^FLEXlm error:|^\$" $EX_TMP |
            sed -e "s?do no match?do not match?"
    else
        e_num=$exp_num
    fi

    print
    case $e_num in
    0 )
        print "    All '$_daemon' license keys are okay in:
      $rsu_lic_file"
        return 0
        ;;
    1 )
        print "    There is a problem with one '$_daemon' license key in:
      $rsu_lic_file"
        return 1
        ;;
    * )
        print "    There are problems with $e_num '$_daemon' license keys in:
      $rsu_lic_file"
        return 1
        ;;
    esac
}

#------------------------------------------------------------------------
function rsf_extract_incr_lines
{
    unset Server_line Vendor_line
    _daemon=$1
    if [ ${SKN:-0} -eq 0 ]
    then
        Feat_List=$(egrep "INCREMENT|FEATURE" $rsu_lic_file |
                    grep " $_daemon " |
                    awk '{print $2}')
    fi
    lic_found=0
    in_incr=false
    (cat $rsu_lic_file; print "\nEND") | while read arg1 arg2 arg3 other
    do
        case "$arg1" in
        END )
            case $lic_found in
            0 )
                print_e "    No $_daemon specific licenses found."
                return 1
                ;;
            1 )
                print_e "    One $_daemon specific license found."
                return 0
                ;;
            * )
                print_e "    $lic_found $_daemon specific licenses found."
                return 0
                ;;
            esac
            ;;
        SERVER )
            print "$arg1 $arg2 $arg3 $other"
            ;;
        VENDOR )
            if [ "$arg2" = "$_daemon" ]
            then
                print "$arg1 $arg2 $arg3 $other"
            fi
            ;;
        DAEMON )
            if [ "$arg2" = "$_daemon" ]
            then
                print "$arg1 $arg2 $arg3 $other"
            fi
            ;;
        INCREMENT|FEATURE )
            for feat in $Feat_List
            do
                if [ "$arg2:$arg3" = "$feat:$_daemon" ]
                then
                    print "\n$arg1 $arg2 $arg3 $other \\"
                    in_incr=true
                    let lic_found=lic_found+1
                    break
                fi
            done
            ;;
        "" |^\# )
            if $in_incr
            then
                print
                in_incr=false
            fi
            ;;
        * )
            if $in_incr
            then
                print "$arg1 $arg2 $arg3 $other \\"
            fi
            ;;
        esac
    done
}

#------------------------------------------------------------------------
function rsf_list_package_comps
{
    if _pkg_spec=$(grep "PACKAGE $lic_name " $INI_FILE)
    then
         print_e -n "\nPACKAGE $lic_name contains:"
         _comps=${_pkg_spec##*COMPONENTS=\"}
         _comps=${_comps%%\"*}
         _comps=$(print "$_comps" | sed -e 's?\\n??g')
         for _alt in $_comps
         do
             _alt=${_alt%%:*}
             print_e -n " $_alt"
             print "$_alt"
         done
         print_e ""
    else
        print $lic_name
    fi
}

#------------------------------------------------------------------------
function rsf_lmstat
{
    rsf_set_lmstat_cmd
    print "
    Checking license server for $rs_Suite_Name licenses:

    Running the FLEXlm 'lmstat' command...

$lmstat_cmd -a \\
    -c $rsu_lic_file
    "
    test -d $Lic_Dir ||
        rsf_is_flexlm_installed lmstat local flexlm_dir Lic_Dir ||
            return 1

    $lmstat_cmd -a -c $rsu_lic_file |
        sed -e 's?, node-locked??' -e 's? 1 licenses? 1 license?' \
        >$TEMP 2>&1

    nf=0
    nm=0
    if [ -z "$License_Key_List" ]
    then
        # Normally this would be defined except when running license_check.
        i=0
        for lic_name in $(egrep "INCREMENT|FEATURE" $rsu_lic_file |
            egrep "[$WS]$vendor_daemon[$WS]|[$WS]$trl_daemon[$WS]" |
            awk '{print $2}')
        do
            let i=i+1
            eval rs_startup_key$i=\$lic_name
            License_Key_List="$License_Key_List $i"
        done
    fi

    for i in $License_Key_List $Alternate_Key_List
    do
        eval lic_name=\$rs_startup_key$i
        for lic_name in $(rsf_list_package_comps)
        do
            let nf=nf+1
            # Check for each license in the lmstat output (TEMP).
            # Use sort -u to get around a bug in FLEXlm 10.8.0.1.
            _is_licensed=$(grep "Users of $lic_name:" $TEMP | sort -u)
            if [ -n "$_is_licensed" ]
            then
                print "$_is_licensed"
            else
                print "Users of $lic_name: NOT LICENSED"
                let nm=nm+1
            fi
        done
    done

    print
    if [ $nf -eq 1 ]
    then
        if [ $nm -eq 0 ]
        then
            print "    The license component ($lic_name) appears to be okay."
            return 0
        else
            print "    The license component ($lic_name) is not being served."
            rsf_pause TO see complete lmstat command output
            echo "$delim"
            cat $TEMP
            echo "$delim"
            return 1
        fi
    fi

    # There are 2 or more licenses. It is okay if some of the licenses
    # are being served.  Do not necessarily need all of them.
    if [ $nm -eq 0 ]
    then
        # This is a case where all of the licenses are being served.
        print "    The $nf license components appear to be okay."
        return 0
    fi

    if [ $nm -eq $nf ]
    then
        # This is a case where none of the licenses are being served.
        print "    The $nf license components are not being served."
        rsf_pause TO see complete lmstat command output
        echo "$delim"
        cat $TEMP
        echo "$delim"
        return 1
    fi

    # This is a case were some, but not all of the licenses are being served.
    if [ $nm -eq 1 ]
    then
        print "    1 of the $nf license components is not being served."
    else
        print "    $nm of the $nf license components are not being served."
    fi

    let ns=nf-nm
    if [ $ns -eq 1 ]
    then
        print "    This may be okay, since 1 license is being served."
    else
        print "    This may be okay, since $ns licenses are being served."
    fi
    return 0
}

#------------------------------------------------------------------------
function rsf_do_license_check_lmstat
{
    print "\n$delim\n"

    case "${Lic_Key_Type}-$Need_server" in
    temporary-false )
        print "
    It is not necessary to check $Lic_Key_Type licenses with lmstat.
    You do not need a license server running to use these licenses.
    The lmstat command is for counted licenses only."
        rsf_pause
        return 0
        ;;
    esac

    rsf_is_flexlm_installed lmstat local flexlm_dir Lic_Dir || return 1

    if rsf_lmstat
    then
        /bin/rm -f $TEMP
        rsf_pause
        return 0
    fi

    # Check log file.
    license_log=${rsu_lic_file%.dat}.log
    if [ -s $license_log ]
    then
        print "
    The lmgrd license server log file:"
        tail -100 "$license_log"
    fi

    rsf_pause Q
    return 1
}

#------------------------------------------------------------------------
function rsf_explain_license_setup
{
    rhost="$1"

    if [ -w $DIR/. ]
    then
        print "
    Run the license_setup command on $rhost.  To do this,
    use the mount command on $rhost to mount this directory,
    if it is not already mounted as an NFS filesystem."

    else
        print "
    Run the license_setup command on $rhost.  To do this,
    load the CD on $rhost or use the mount command on
    $rhost to mount this directory if it is not already
    mounted as an NFS filesystem."

    fi

    test "$rhost" = "the remote machine" && return

    print "
    For example, to mount this directory login to $rhost and ...

    # As root:   (if not already mounted)
    mkdir $DIR
    mount $HOST:$DIR \\
          $DIR

    If you are unable to mount $DIR,
    try copying it to $rhost.  It does not need to be put
    in the exact same location."

    if [ "$USER" = root ]
    then
        print "    cd $DIR"
        print "    ./license_setup"
    else
        print
        print "    # As $USER run the license_setup command:"
        print "    cd $DIR"
        print "    ./license_setup"
    fi
    print
}

#------------------------------------------------------------------------
function rsf_check_lic_server
{
    if [ "${rsu_lic_server%%.*}" = "$HOST" ]
    then
        return 0
    fi

    if [ -n "$rsu_lic_server" -a "$rsu_lic_server" = "$prior_lic_server" ]
    then
        $rsu_check_rational_dir || return 0
    fi

    if [ "${rs_multi_flex:-no}" = no ]
    then
        a_os_mach="a $THIS_OS machine"
    else
        a_os_mach="one of the supported architectures"
    fi

    remote_check=pass
    if $Imported_licenses
    then
        rsf_menu_title $rs_Suite_Name - Check Remote License Server
        print "
    Since the license file you are importing uses a license server other
    than $HOST, will check if..."
    else
        print "
    Since you have selected a license server other than $HOST,
    will check if..."
    fi

    print "
    1. You have remote access to $rsu_lic_server using rsh/remsh or ssh.
    2. The machine is $a_os_mach to run the
       FLEXlm software.
    3. It has access to $rsu_rational_dir."

    rsf_set_rsh_cmd
    if [ -z "$rsh_cmd" ]
    then
        rsf_display_important
        print "    Cannot check if $rsu_lic_server has access to"
        print "      $rsu_rational_dir."
        print "    You will need to set up the license server manually."
        return 1
    fi

    rsf_get_remote_os $rsu_lic_server

    if [ "$remote_os" = unknown ]
    then
        print "\n    You have remote access to $rsu_lic_server"
        print "    from $HOST but it is not a supported architecture,"
        print "    so it cannot be used as a license server."
        print "    Please select a host for your license server that matches"
        print "    one of these host types:"
        print "$rs_flex_list"
        return 1
    fi

    if [ "$remote_os" = other ]
    then
        print "\n    You do not have remote access to $rsu_lic_server"
        print "    from $HOST and it is not a supported architecture,"
        print "    so it cannot be used as a license server.  Please select"
        print "    another host for your license server."
        return 1
    fi

    if [ -z "$remote_os" ]
    then
        print "\n    You do not have remote access to $rsu_lic_server"
        print "    from $HOST, so it cannot be set up as a license server"
        print "    using $CMD."
        rsf_explain_license_setup $rsu_lic_server
        return 1
    fi

    if [ "$remote_os" != "$THIS_OS" -a "${rs_multi_flex:-no}" = no ]
    then
        print "\n    Host ${sul}$rsu_lic_server${eul} is running $remote_os."
        print "    The FLEXlm software can only be used on $THIS_OS."
        print "    They do not match so $rsu_lic_server cannot be"
        print "    used as a license server."
        return 1
    fi

    print "\n    Okay, $rsu_lic_server is running $remote_os."
    print "    Will check that $rsu_lic_server has access to"
    print "      $rsu_rational_dir."
    print "$rsh_cmd $rsu_lic_server /bin/ls -d $rsu_rational_dir"
    _rd=$($rsh_cmd $rsu_lic_server /bin/ls -d $rsu_rational_dir |tail -1)
    if [ "$_rd" = "$rsu_rational_dir" ]
    then
        print "\n    Okay, $rsu_lic_server has access."
        return 0
    else
        rsu_allow_rsh=no
        print "\n    Host, $rsu_lic_server does not have access."
        return 1
    fi
}

#------------------------------------------------------------------------
function rsf_check_for_remote_server
{
    if [ "${rsu_lic_server%%.*}" != "$HOST" ]
    then
        if rsf_check_lic_server
        then
            rsf_set_license_dirs
            if rsf_is_flexlm_installed lmstat remote flexlm_dir2 Lic_Dir2
            then
                return
            else
                rsf_cleanup 2
            fi
        fi

        rsf_pause TO "see instructions on running
    the license_setup command on $rsu_lic_server"
        rsf_explain_license_setup $rsu_lic_server

        if [ "$CMD" = rs_install ]
        then
            rsf_pause TO see final notes
            print "
    After you run license_setup on $rsu_lic_server, then run
    $CMD on $HOST.  During the Licensing Options Selections,
    select option 1 to use existing licensing that you just configured
    on $rsu_lic_server."

        fi
        rsf_cleanup 2
    fi
}

#------------------------------------------------------------------------
function rsf_set_license_dirs
{
    # This function sets Lic_Dir2 to the path of the installed
    # FLEXlm code base on the architecture of the server machine.
    # For eval keys, rsu_lic_server is not set.
    test "$LD_set_from" = "$rsu_lic_server" && return
    LD_set_from=$rsu_lic_server

    if [ "$Lic_Key_Type" = temporary  -o \
         "${rsu_lic_server%%.*}" = "$HOST" ]
    then
        flexlm_dir2=$flexlm_dir
        Lic_Dir2=$Lic_Dir
        Lic_Arch=$ARCH
        return 0
    fi

    if [ -z "$remote_arch" ]
    then
        rsf_get_remote_os $rsu_lic_server
        test "$remote_os" = other -o -z "$remote_os" && return 1
    fi
    local_flexlm_dir=$flexlm_dir
    unset flexlm_dir
    rsf_set_extra_dir flexlm "$flexlm_ver" $remote_sys $remote_arch
    Lic_Arch=$remote_arch
    if [ -n "$flexlm_dir" ]
    then
        flexlm_dir2=$flexlm_dir
        flexlm_dir=$local_flexlm_dir
        unset local_flexlm_dir
        Lic_Dir2=$rsu_rational_dir/base/cots/flexlm.$flexlm_ver/$remote_arch
        return 0
    fi

    unset LD_set_from Lic_Dir2
    flexlm_dir=$local_flexlm_dir
    unset local_flexlm_dir
    return 1
}

#------------------------------------------------------------------------
function rsf_enter_lic_file_name
{
    # Prompt installer for license file.
    # Call rsf_check_lic_file to check licensing.

    # Check if the existing license file has a SERVER line.
    # Cannot use an existing license file that does not match
    # the license type we are configuring.

    ex_port_host=${rsu_lic_port:-$def_lic_port}
    ex_port_host="$ex_port_host@${rsu_lic_server:-$HOSTNAME}"

    if [ "$Use_existing_licenses" = false ]
    then
        # If we are not using existing licenses and the license file
        # is set to the temporary license file, reset it.
        test "${rsu_lic_file##*/}" = Temporary.dat && unset rsu_lic_file
    fi

    prior_lic_file=$rsu_lic_file
    while true
    do
        if $Use_existing_licenses
        then
            path_name="pathname or port@host:"
            print "
    Enter the full pathname to the license file or enter port@host.

    If the licenses are being served by a license server, you can
    enter a port@host to specify the licenses.  An example of a
    port@host would be: $ex_port_host

    Otherwise, you must specify the full pathname to the license file.

    You may enter a list of files or port@host license configurations,
    with each one separated by a : (colon) character.  For example:
      1706@host1:1707@host2:1708@host3"

        else
            path_name="pathname:"
            print "
    Enter a full pathname for the license file.

    This can be an existing license file that $CMD will update
    or it can be a new file that $CMD will create."

        fi

        rsf_get_option rsu_lic_file str "License file $path_name"
        case $rsu_lic_file in
        *:* )
            save_lic_file=$rsu_lic_file
            if rsf_check_lic_path $save_lic_file
            then
                rsu_lic_file=$save_lic_file
                return 0
            fi
            rsu_lic_file=$prior_lic_file
            ;;
        * )
            if rsf_check_lic_file
            then
                rsf_set_options_file
                return 0
            fi
            rsu_lic_file=$prior_lic_file
            ;;
        esac
    done
}

#------------------------------------------------------------------------
function rsf_set_server_hostid_port
{
    if [ $1 = target ]
    then
        rsu_lic_server=$target_lic_server
        rsu_lic_hostid=$target_lic_hostid
        rsu_lic_port=$target_lic_port

    elif ${2:-$Imported_licenses}
    then
        rsu_lic_server=$import_lic_server
        rsu_lic_hostid=$import_lic_hostid
        rsu_lic_port=$import_lic_port
    fi
}

#------------------------------------------------------------------------
function rsf_check_lic_path
{
    if $Use_existing_licenses
    then
        :
    else
        print "
    Cannot use a colon-separated list when doing license setup.
    This can only be used when using existing license configurations."
        rsf_pause
        return 1
    fi

    # Walk the list of license configurations backwards so that the first
    # port@host on the list is the last on processed.
    IFS=:
    set -- $1
    IFS=$oldIFS
    n=$#
    path_error=0
    while [ $n -gt 0 ]
    do
        eval rsu_lic_file=\$$n
        rsf_check_lic_file
        test $? -ne 0 && path_error=1
        let n=n-1
    done
    return $path_error
}

#------------------------------------------------------------------------
function rsf_check_lic_file
{
    case $rsu_lic_file in
    /* )
        if [ ! -f $rsu_lic_file ]
        then
            if $Use_existing_licenses
            then
                print "
    You selected the option to use existing licenses.
    However, the license file you have selected does not exist:
      $rsu_lic_file
    Please enter the full pathname to a license file or enter the port@host."
                rsf_pause
            else
                if rsf_file_dir_writable $rsu_lic_file
                then
                    rsf_set_server_hostid_port import
                    return 0
                fi
            fi
            rsu_lic_file=$prior_lic_file
            return 1
        fi

        if $Imported_licenses
        then
            if [ "$rsu_lic_file" = "$rsu_import_lic_file" ]
            then
                print "
    The IBM Rational license file is a text file that is automatically
    created when you run the $CMD command.
    The default file for permanent or TLA licenses is:
      $rsu_rational_dir/config/${rsu_lic_server:-license-server-name}.dat

    You specified the file you used to import licenses from.
    What is needed is the name of the license file $CMD will
    either update or create from these imported licenses.

    Note: For best results, use the IBM Rational license file only for
          IBM Rational Software product licenses."
                rsf_pause
                rsu_lic_file=$prior_lic_file
                return 1
            fi
        fi

        rsf_extract_server_info target $rsu_lic_file
        if [ -z "$target_lic_hostid" ]
        then
            if $Use_existing_licenses
            then
                if rsf_is_a_lic_file $rsu_lic_file
                then
                    rsf_set_server_hostid_port import
                    return 0
                else
                    print "
    There is no SERVER line in this file.  It does not appear to be a
    FLEXlm license file.  This product requires FLEXlm licensing."
                    rsf_pause
                    rsu_lic_file=$prior_lic_file
                    return 1
                fi
            else
                rsf_set_server_hostid_port import
                return 0
            fi
        fi

        if $Use_existing_licenses
        then
            rsf_set_server_hostid_port target
            return 0
        fi

        # Have license file with server, doing license setup.
        if $Imported_licenses
        then
            # The license file being set up must have a matching host ID.
            if [ "$target_lic_hostid" = "$import_lic_hostid" ]
            then
                rsf_set_server_hostid_port import
                return 0
            else
                print "
    The SERVER line in this license file:
      $rsu_lic_file
    contains the host ID '$target_lic_hostid'.  This does not match the
    host ID '$import_lic_hostid' in the import file.  You cannot update
    this license file with the keys in the import file since the server
    information is incompatible.

    Please select a different license file."
                rsf_pause
                rsu_lic_file=$prior_lic_file
                return 1
            fi
        else
            rsf_set_server_hostid_port target
            return 0
        fi
        ;;

    *@* )
        if $Use_existing_licenses
        then
            set -- $(IFS='@'; echo $rsu_lic_file)
            if [ $# -eq 1 ]
            then
                rsu_lic_port=${def_lic_port:-27000}
                rsu_lic_server=$1
                rsu_lic_file=$rsu_lic_port@$rsu_lic_server
                License_File=$rsu_lic_file
                return 0
            elif [ $# -eq 2 ]
            then
                rsu_lic_port=$1
                rsu_lic_server=$2
                License_File=$rsu_lic_file
                return 0
            else
                print "
    The license you enter does not match the port@host format:
      $rsu_lic_file"
                rsf_pause
                rsu_lic_file=$prior_lic_file
                return 1
            fi
        else
            print "
    You cannot use '$rsu_lic_file' as the license file
    when you are doing license setup."
            rsu_lic_file=$prior_lic_file
            rsf_pause
            return 1
        fi
        ;;

    * )
        print "\n    $rsu_lic_file is not a full pathname."
        rsu_lic_file=$prior_lic_file
        rsf_pause
        return 1
        ;;
    esac
}

#------------------------------------------------------------------------
function rsf_find_pqc_licenses
{
    unset pqpc_licenses
    for _dir in $(IFS=':'; echo $PATH)
    do
        test -x $_dir/purify || continue

        if [ -L $_dir/purify ]
        then
            set -- $(/bin/ls -l $_dir/purify)
            if [ $# -gt 1 ]
            then
                let _n=$#-1
                shift $_n
                _dir2=${1%/*}
                case $_dir2 in
                /*   ) _dir=$_dir2 ;;
                ../* ) _dir=$_dir/$_dir2
                esac
            fi
        fi

        if [ -f "$_dir/.lm_license_file" ]
        then
            _lm_lic_file=$(cat $_dir/.lm_license_file)
            for _lf in $(IFS=':'; echo $_lm_lic_file)
            do
                rsf_add_to_lic_file_list $_dir/.lm_license_file "$_lf"
            done
        fi
    done
    unset _n _dir _dir2 _lm_lic_file _lf
}

#------------------------------------------------------------------------
function rsf_add_to_lic_file_list
{
    # This function adds license files and port@host specifications to a
    # variable called lic_file_list.  It does so conditionally.
    #
    # If we are using existing licenses, port@host is okay to use and
    # license files must exist.  The Temporary.dat file is okay in this case.
    #
    # If we are not using existing licensing, the list must be files only
    # because this will be used to select a license file to create or
    # update. Therefore, port@host licenses are not okay and license
    # files must exist, except for the default license file,
    # "server-name".dat.  This way, the user is steared to create the
    # default license file.
    #
    # For perm or TLA license setup, check license files have SERVER line
    # that matches the imported or specified host ID.
    #
    # Arg 1: Trace message.
    # Arg 2: the license file, port@host, or license list.

    _trace_lic="$1"
    _lic="$2"
    _check_file_vendor=false
    if $Use_existing_licenses
    then
        case "$_lic" in
        *:* )
            _trace_lic="$_trace_lic (:)"
            ;;
        *@* )
            _trace_lic="$_trace_lic (@)"
            ;;
        /* )
            _check_file_vendor=true
            ;;
        * )
            return 1
            ;;
        esac
    else
        # Doing permanent or TLA license setup.
        case "$_lic" in
        *:*|*@* )
            # Cannot use port@host or a license list.
            return 1
            ;;
        */Temporary.dat )
            # Do not let this file be used to set up permanent licenses.
            return 1
            ;;
        /* )
            # If the file is the default, it does not need to exist.
            # Otherwise, use only if this license is one of ours.
            if [ "$_trace_lic" != default ]
            then
                _check_file_vendor=true
            fi
            ;;
        * )
            return 1
            ;;
        esac
    fi

    if $_check_file_vendor
    then
        # Skip this license if the file does not exist or
        # if one of our vendor daemons is not in this file.
        test -f "$_lic" || return 1
        # It would be on an INCREMENT/FEATURE line or the VENDOR/DAEMON line.
        egrep "[$WS]$vendor_daemon|[$WS]$trl_daemon" $_lic >/dev/null 2>&1 || return 1

        # Check the server host ID in the file matches if we are doing
        # permanent or TLA license setup (license_opt=2).
        if [ ${license_opt:-0} -eq 2 ]
        then
            grep "^SERVER.*$rsu_lic_hostid" $_lic >/dev/null 2>&1 || return 1
        fi
        _trace_lic="$_trace_lic ($rsu_lic_hostid)"
    fi

    # Add to list if not in list.
    if print " $lic_file_list " | grep " $_lic " >/dev/null
    then
        # Already on the list.
        rsf_trace_log true "$_trace_lic (dup) ==> $_lic"
    else
        # Add it.
        rsf_trace_log true "$_trace_lic ==> $_lic"
        lic_file_list="$lic_file_list $_lic"
    fi
    unset _trace_lic _lic _check_file_vendor
    return 0
}

#------------------------------------------------------------------------
function rsf_create_lic_file_list
{
    # Only use port@host, licenses lists or Temporary.dat licenses
    # if the installer wants to use an existing license.  Otherwise,
    # do not present these as an option for setting up permanent licenses.
    if $Use_existing_licenses
    then
        # This is a list of licenses already checked.
        if [ -n "$New_lic_list" ]
        then
            # Use it.
            lic_file_list=$New_lic_list
            rsf_set_lic_file_opt_list $lic_file_list
            return
        fi
    fi

    rsf_trace_log true "\nLicense checking in rsf_create_lic_file_list:"
    unset def_lic_file lic_file_list

    # First check for the previously specified license file.
    # rsu_license_file is the one specified during post_install.
    # All products would be set with this.  The rsu_lic_file
    # is the primary file used to configure licenses in this command.
    # The difference is rsu_license_file might be the port@host.
    for _var in rsu_license_file rsu_lic_file
    do
        eval lic_file=\$$_var
        test -n "$lic_file" || continue
        rsf_add_to_lic_file_list "$_var" "$lic_file"
    done

    # Check for the license file in the system startup files.
    for ifile in $init_file $obs_init_list
    do
        if [ -r "$ifile" ]
        then
            eval $(grep "^LICENSE_DAT=" $ifile)
            if [ -n "$LICENSE_DAT" ]
            then
                for lic_file in $(IFS=: ; echo $LICENSE_DAT)
                do
                    rsf_add_to_lic_file_list "$ifile" "$lic_file" && break
                done
            fi
        fi
    done

    # This is the default name when configuring a license file
    # for the first time.  If we are using exising licensing, this
    # file must exist.  If not using existing, the file does not have
    # to exist.  This program will create it.
    if [ "$importedAny" = yes ]
    then
        rsf_add_to_lic_file_list default "$Config/$HOST.any.dat"
    elif [ -n "$rsu_lic_server" ]
    then
        rsf_add_to_lic_file_list default "$Config/$rsu_lic_server.dat"
    fi

    # Check any and all rational/config directories for dat files.
    # Start with the default one.
    rd_list=$rsu_rational_dir
    for _n in $rd_n_list
    do
        eval _rd=\$rational_dir$_n
        test "$_rd" = "$rsu_rational_dir" && continue
        rd_list="$rd_list $_rd"
    done

    # With the list of rational dirs, check all dat files.
    # Do no reuse rsu_lic_file.  Only use temp if doing existing.
    for _rd in $rd_list
    do
        for lic_file in $_rd/config/*.dat
        do
            # Skip it if it does not exist.
            test -f $lic_file || continue
            rsf_add_to_lic_file_list "rational_dir*/config/*.dat" "$lic_file"
        done

        # Check defaults files.  Extract the rsu_lic_file setting from each.
        for lic_file in \
            $(grep "^rsu_lic_file=" $_rd/config/defaults/* 2>/dev/null |
              sed -e 's?.*rsu_lic_file="??' -e 's?"$??' |
              sort -u)
        do
            rsf_add_to_lic_file_list "*defaults/rsu_lic_file=" "$lic_file"
        done
    done

    if [ -n "$LM_LICENSE_FILE" ]
    then
        unset _list
        for lic_file in $(IFS=: ; echo $LM_LICENSE_FILE)
        do
            test -z "$lic_file" && continue
            rsf_add_to_lic_file_list LM_LICENSE_FILE "$lic_file"
            _list="${_list}:$lic_file"
        done
        if [ -n "$_list" ]
        then
            _list=${_list#:}
            rsf_add_to_lic_file_list "LM_LICENSE_FILE all" "$_list"
        fi
        unset _list
    fi

    case $rsu_product_name in
    *Purify* ) rsf_find_pqc_licenses ;;
    esac

    rsf_add_to_lic_file_list "FLEXlm Default" \
        /usr/local/flexlm/licenses/license.dat

    if [ -r ~/.flexlmrc ]
    then
        eval $(grep RATIONAL_LICENSE_FILE= ~/.flexlmrc)
        test -n "$RATIONAL_LICENSE_FILE" &&
            rsf_add_to_lic_file_list .flexlmrc "$RATIONAL_LICENSE_FILE"
    fi

    # Set the default to the first one found.
    for lic_file in $lic_file_list
    do
        rsf_trace_log true "Default (first found) ==> $lic_file"
        def_lic_file=$lic_file
        break
    done

    if [ -n "$lic_file_list" ]
    then
        rsf_set_lic_file_opt_list $lic_file_list
    else
        rsf_set_lic_file_opt_list
    fi
    rsf_trace_log true "End of license checking.\n"
}

#------------------------------------------------------------------------
function rsf_set_lic_file_opt_list
{
    l=0
    unset lic_file_list lic_file_opt_list
    last_lic_file_opt=0
    if [ $# -eq 0 ]
    then
        def_lic_file_opt=1
    fi

    while [ $# -gt 0 ]
    do
        case $1 in
        *@*|*:* )
            ;;
        * )
            if [ ! -f "$1" ]
            then
                if [ "$1" != "$def_lic_file" ]
                then
                    shift
                    continue
                fi
            fi
            if $Imported_licenses
            then
                if grep ^SERVER $1 >/dev/null 2>&1 |
                   grep ${import_lic_hostid:-x} >/dev/null
                then
                    # This license file has a server line that
                    # matches the import file hostid.
                    # Make it the default selection.
                    def_lic_file=$1
                fi
            fi
            ;;
        esac
        let l=l+1
        let last_lic_file_opt=last_lic_file_opt+1
        L=$(rsf_typst -R 2 $l)
        eval lic_file_$l=$1
        lic_file_opt_list="$lic_file_opt_list
    $L)  $1"
        lic_file_list="$lic_file_list $1"
        if [ "$1" = "$def_lic_file" ]
        then
            def_lic_file_opt=$l
        fi
        shift
    done

    let last_lic_file_opt=last_lic_file_opt+1
    L=$(rsf_typst -R 2 $last_lic_file_opt)
    if [ $last_lic_file_opt -eq 1 ]
    then
        lic_file_opt_list="$lic_file_opt_list
    $L)  Enter a full pathname to a license file."
    else
        lic_file_opt_list="$lic_file_opt_list
    $L)  Enter a full pathname to a license file other than one listed above."
    fi
}

#------------------------------------------------------------------------
function rsf_set_options_file
{
    case $rsu_lic_file in
    /* ) options_file=${rsu_lic_file%/*}/$vendor_daemon.opt ;;
    esac
}

#------------------------------------------------------------------------
function rsf_lic_file_menu
{
    if [ "$license_opt" = 1 -a "$prod_licensed" = yes ]
    then
        rsf_set_License_File
        unset Lic_Key_Type
        return
    fi

    unset def_lic_file_opt Explain_port_host
    rsf_create_lic_file_list
    ex_port_host=${rsu_lic_port:-$def_lic_port}
    ex_port_host="$ex_port_host@${rsu_lic_server:-$HOSTNAME}"

    while true
    do
        rsf_menu_title $rs_Suite_Name - Enter License File
        if $Use_existing_licenses
        then
            rsf_print_menu "$def_lic_file_opt" "
    Select a license file to use for $rs_Suite_Name.

    This must be an existing license file or a port@host.
    It can be a port@host specification since you have selected
    to use existing licenses.

    A license file needs to be entered as a full pathname.
$lic_file_opt_list
         Or enter a port@host.  Example: $ex_port_host

     b)  Back to the previous menu.
     q)  ${Quit_CMD}$Help_Option5"

        else
            rsf_print_menu "$def_lic_file_opt" "
    Select a license file to use for $rs_vendor_products.

    This can be an existing license file or a new file that $CMD
    will create.

    A license file needs to be entered as a full pathname.
$lic_file_opt_list

     b)  Back to the previous menu.
     q)  ${Quit_CMD}$Help_Option5"

        fi

        unset lic_file_opt
        rsf_get_option lic_file_opt str "Enter menu option:"
        case $lic_file_opt in
        [1-9]|[1-9][0-9] )
            if [ "$lic_file_opt" = "$last_lic_file_opt" ]
            then
                rsf_enter_lic_file_name && break
            else
                eval lic_file=\$lic_file_$lic_file_opt
                if [ -n "$lic_file" ]
                then
                    lic_file_opt=$lic_file
                else
                    print "\n    Option $lic_file_opt is not in the list."
                    rsf_pause
                fi
            fi
            ;;
        b )
            Go_back=true
            return
            ;;
        esac

        case $lic_file_opt in
        *:* )
            prior_lic_file=$rsu_lic_file
            if rsf_check_lic_path $lic_file_opt
            then
                rsu_lic_file=$lic_file_opt
                break
            fi
            rsu_lic_file=$prior_lic_file
            ;;
        *@* )
            if $Use_existing_licenses
            then
                rsu_lic_file=$lic_file_opt
                break
            else
                print "
    Cannot use port@host '$lic_file_opt' license configuration
    when doing license setup."
                rsf_pause
            fi
            ;;
        /* )
            prior_lic_file=$rsu_lic_file
            rsu_lic_file=$lic_file_opt
            if rsf_check_lic_file
            then
                if rsf_file_dir_writable $rsu_lic_file
                then
                    rsf_set_options_file
                    break
                fi
            fi
            rsu_lic_file=$prior_lic_file
            ;;
        * )
            rsf_option_not_recognized "$lic_file_opt" "$last_lic_file_opt" mnb
            ;;
        esac
    done

    case "$license_opt" in
    1 )
        unset Lic_Key_Type Need_server
        ;;
    2 )
        rsf_check_and_set_user_based
        rsf_get_lic_port
        rsf_do_license_setup
        ;;
    esac
}

#------------------------------------------------------------------------
function rsf_get_lic_port
{
    if $Imported_licenses
    then
        rsf_check_if_server_needed "$rsu_import_lic_file"
    fi

    if [ "$Need_server" != true  -a -f "$rsu_lic_file" ]
    then
        rsf_check_if_server_needed "$rsu_lic_file"
    fi

    ${Need_server:-false} || return

    rsu_lic_port=${target_lic_port:-${import_lic_port:-$rsu_lic_port}}
    rsf_menu_title $rs_Suite_Name - Enter License Server Port Number
    print "
    Port numbers are used by the license server daemons to communicate
    using TCP/IP networking.  For each server machine, the port number
    must be unique.  Globetrotter's FLEXlm licensing uses port number
    $def_lic_port as the default.  If you already have a license server
    running, and you are planning on using the same license file, you
    must use the port number in the license file on the SERVER line.
    If you are unsure, stay with the default recommended here.

    Any unused number from $Min_port_num to $Max_port_num would be okay.
    This number can be changed at any time.  It is not tied to the
    license keys.

    The port number should not conflict with one in the /etc/services file
    or under NIS services.  The $CMD program will check for any
    possible conflicts automatically to see if the port number is in use."

    def_rsu_lic_port=${rsu_lic_port:-$def_lic_port}
    while true
    do
        rsf_get_option rsu_lic_port num "License server port number:"
        case $rsu_lic_port in
        2700?|27010 ) return ;;
        esac

        if [ $rsu_lic_port -lt $Min_port_num ]
        then
            print "
    You must enter a port number that is greater than or equal to the
    minimum port number ($Min_port_num)."
            unset rsu_lic_port
            continue

        elif [ $rsu_lic_port -gt $Max_port_num ]
        then
            print "
    You must enter a port number that is less than or equal to the
    maximum port number ($Max_port_num)."
            unset rsu_lic_port
            continue
        fi

        print "
    Checking for port number $rsu_lic_port in /etc/services...
grep ' $rsu_lic_port/' /etc/services"
        unset _services
        if grep "[$WS]$rsu_lic_port/" /etc/services 2>/dev/null
        then
            _services="in /etc/services"
        else
            print "
    No conflicts in /etc/services file.  Now checking for
    port number $rsu_lic_port under NIS services...
ypcat services | grep ' $rsu_lic_port/'"
            if ypcat services 2>/dev/null | grep "[$WS]$rsu_lic_port/"
            then
                _services="under NIS services"
            fi
        fi

        if [ -n "$_services" ]
        then
            print "\n    Port number $rsu_lic_port is in use $_services."
            yn_use_lic_port=no
            rsf_get_option yn_use_lic_port y_n \
                "Use port number $rsu_lic_port anyway?"
            test "$yn_use_lic_port" = yes && break
            unset rsu_lic_port
        else
            print "\n    Port number $rsu_lic_port appears to be okay."
            rsf_pause
            break
        fi
    done
}

#------------------------------------------------------------------------
function rsf_extract_purela_users
{
    if [ ! -f $purela_users ]
    then
        print "     $purela_users not found."
        print "     Cannot import user names from purela licensing."
        return 1
    fi

    print "
    Attempting conversion of purela users to FLEXlm users:
      from: $purela_users
      to:   $purela_user_file"

    /bin/rm -f $purela_user_file

    cat $purela_users | while read key value
    do
        case $key in
        product: )
            prod=$value
            ;;
        OS: )
            case $value in
            IRIX* )
                plat=IRIX
                ;;
            SunOS )
                plat=Solaris
                ;;
            HP-UX )
                plat=HP-UX
                ;;
            * )
                plat=$value
                ;;
            esac
            ;;
        user: )
            uid=$value
            unset prod plat
            ;;
        * )
            continue
            ;;
        esac

        if [ -n "$prod"  -a -n "$uid" -a -n "$plat" ]
        then
            _DT_PROD=$(rsf_typst -L 14 $prod)
            _DT_PLAT=$(rsf_typst -L 14 $plat)
            print "$_DT_PROD $_DT_PLAT $uid" >> $purela_user_file
            print "PurifyPlusUNIX $_DT_PLAT $uid" >> $purela_user_file
            unset prod plat uid
        fi
    done

    if [ ! -s $purela_user_file ]
    then
        print "    No user logins were found in purela licensing."
        unset _DT_PROD _DT_PLAT
        return 1
    fi

    (
    print "# This file can be used by rs_install/license_setup to import
# user logins from purela licensing to FLEXlm licensing.
# Edit this file so that the number of users matches the
# number of licenses you have for each product.

#Product       Platform       User-Login
#-------       --------       ----------"

    _prior_prod_plat=none
    sort -u $purela_user_file | while read prod plat uid
    do
        _DT_PROD=$(rsf_typst -L 14 $prod)
        _DT_PLAT=$(rsf_typst -L 14 $plat)
        if [ "$_DT_PROD $_DT_PLAT" = "$_prior_prod_plat" ]
        then
            print "$_DT_PROD $_DT_PLAT $uid"
        else
            print "\n$_DT_PROD $_DT_PLAT $uid"
            _prior_prod_plat="$_DT_PROD $_DT_PLAT"
        fi
    done
    ) > $purela_user_file.tmp
    /bin/mv $purela_user_file.tmp $purela_user_file
    unset _DT_PROD _DT_PLAT
    return 0
}

#------------------------------------------------------------------------
function rsf_create_purela_user_file
{
    Have_purela_import=false
    if [ -f $purela_user_file ]
    then
        if [ "$lic_name" = PurifyPlusUNIX ]
        then
            if grep PurifyPlusUNIX $purela_user_file >/dev/null
            then
                Have_purela_import=true
            fi
        else
            Have_purela_import=true
        fi
    fi

    if $Have_purela_import
    then
        print "
    You have imported user information from purela licensing already.
    There is a converted purela user file that $CMD will use:
      $purela_user_file
    You do not need to convert purela user info again unless you want
    to convert a different users.purela file."
        yn_purela_import=no
        rsf_get_option yn_purela_import y_n \
            "Convert another users.purela file?"
    else
        print "
    If you know the location of the purela users you can enter
    the full pathname of the directory and $CMD will import
    users listed for $desc.
    The directory must contain the users.purela file."
        rsf_get_option yn_purela_import y_n "Import from purela?"
    fi

    test "$yn_purela_import" = no && return 1

    while [ "$yn_purela_import" = yes ]
    do
        if [ -z "$rsu_purela_dir" ]
        then
            rsu_purela_dir=none
        else
            test -d "$rsu_purela_dir"|| rsu_purela_dir=none
        fi
        rsf_get_option rsu_purela_dir dir "Enter the purela directory:"
        case $rsu_purela_dir in
        none )
            unset rsu_purela_dir
            return 1
            ;;
        */users.purela )
            purela_users=$rsu_purela_dir
            ;;
        * )
            purela_users=$rsu_purela_dir/users.purela
            ;;
        esac
        if rsf_extract_purela_users $purela_users
        then
            return 0
        fi
        rsf_get_option yn_purela_import y_n "Try to import again?"
    done
    return 1
}

#------------------------------------------------------------------------
function rsf_combine_ubl_pul
{

    # Combine the user_based_list from a previous run (what is saved in
    # the defaults file) with the purela_user_list extracted from the
    # purela user file.

    if [ -z "$user_based_list" ]
    then
        user_based_list=$purela_user_list
        return
    fi

    if [ -z "$purela_user_list" ]
    then
        set -- $user_based_list
        user_count=$#
        return
    fi

    # Weed out duplicates.  Cannot use sort -u.
    set -- $user_based_list $purela_user_list
    user_count=1
    user_based_list=$1
    shift
    while [ $# -gt 0 ]
    do
        print " $user_based_list " | grep " $1 " >/dev/null
        if [ $? -ne 0 ]
        then
            user_based_list="$user_based_list $1"
            let user_count=user_count+1
        fi
        shift
    done
}

#------------------------------------------------------------------------
function rsf_set_user_based_from_purela
{
    case $lic_name in
    purify )
        User_based_product=Purify
        ;;
    purecov )
        User_based_product=PureCoverage
        ;;
    quantify )
        User_based_product=Quantify
        ;;
    PurifyPlusUNIX )
        User_based_product=PurifyPlusUNIX
        ;;
    esac

    search_for="^$User_based_product .*$OS_NAME "
    while true
    do
        set -- $(grep "$search_for" $purela_user_file | sort -u |
                 awk '{print $3}')
        user_count=$#
        purela_user_list="$*"

        test $user_count -lt $Quantity && rsf_combine_ubl_pul

        if [ $user_count -eq $Quantity ]
        then
            user_based_list=$purela_user_list
            print "
    Import of $user_count unique purela users completed successfully
    for $desc."
            unset purela_user_list
            rsf_pause
            return 0
        fi

        if [ $user_count -gt $Quantity ]
        then
            let i=user_count-Quantity
            case $i in
            1 )
                Add_Remove_mesg="Remove the one extra user"
                are_i_too_many_users="is one user too many"
                ;;
            * )
                Add_Remove_mesg="Remove the $i extra users"
                are_i_too_many_users="are $i users too many"
                ;;
            esac
            Order_mesg=".
    Or at least edit the file so that the first $Quantity users match the
    first $Quantity in this file."
            no_import=0
            Remaining_users_mesg="in import file will be ignored."
        else
            let i=Quantity-user_count
            case $i in
            1 )
                Add_Remove_mesg="Add one more user"
                are_i_too_many_users="needs to be one more user"
                ;;
            * )
                Add_Remove_mesg="Add $i more users"
                are_i_too_many_users="needs to be $i more users"
                ;;
            esac
            Order_mesg=":"
            no_import=1
            Remaining_users_mesg="can be entered by you or auto-generated."
        fi

        def_import_opt=f
        last_import_opt=1
        if $Using_vi
        then
            vi_opt=$(grep -n "$search_for" $purela_user_file |
                     head -1 | awk -F: '{print $1}')
            test -n "$vi_opt" && vi_opt="+$vi_opt"
        else
            unset vi_opt
        fi

        if [ "$user_count" = 0 ]
        then
            print "
    No purela users were imported."
        else
            print "
    Import of $user_count purela users completed.
    However, there $are_i_too_many_users."
        fi

        print "    In another window, edit the converted purela user file.
    $Add_Remove_mesg for $desc/${OS_NAME}$Order_mesg

$EDIT $vi_opt $purela_user_file

    When you are done editing enter one of these options:

     1)  Retry import of license users from the purela license file.
         (After editing purela users file.)

     f)  Forward to the next step.
         Do not attempt another import.
         Take the $user_count purela user imports you have so far.
         The remaining users $Remaining_users_mesg

     q)  ${Quit_CMD}$Help_Option5"

        rsf_get_option import_opt mnf "Enter option:"
        unset Add_Rem_mesg are_i_too_many_users
        case $import_opt in
        1 )
            continue
            ;;
        f )
            if [ $user_count -gt $Quantity ]
            then
                set -- $purela_user_list
                unset purela_user_list
                while [ $# -gt $i ]
                do
                    purela_user_list="$purela_user_list $1"
                    shift
                done
            fi
            user_based_list=$purela_user_list
            unset purela_user_list
            return $no_import
            ;;
        * )
            rsf_option_not_recognized "$import_opt" "$last_import_opt" mnf
            ;;
        esac
    done
}

#------------------------------------------------------------------------
function rsf_enter_user_based_list
{
    rsf_menu_title $rs_Suite_Name - Enter License Users for $desc
    if [ "$Quantity" = 1 ]
    then
        def_prod_user=$USER
        set -- 1 ${user_based_list:-$prior_ubl}
        shift
        prod_user=$1
        print "
    A FLEXlm options file will be created or updated with one user listed
    in it.  Enter the user login of the person who will be using
    ${sul}$desc${eul}."
        rsf_get_option prod_user str "Enter user login:"
        user_based_list="$prod_user"
        return
    fi

    print "
    A FLEXlm options file will be created or updated with $Quantity users
    listed in it for ${sul}${desc}${eul}."

    i=0
    unset new_ub_list
    if ${rs_Allow_purela_importing:-false}
    then
        user_count=0
        rsf_create_purela_user_file
        if [ -f $purela_user_file ]
        then
            unset user_based_list
            rsf_set_user_based_from_purela && return

            print "\n    You can fill in the remainder of the $desc"
            print "    users below."

            if [ -n "$user_based_list" ]
            then
                new_ub_list=$user_based_list
                let i=${user_count:-0}+1
            else
                i=0
            fi
        fi
    fi

    if [ $i -eq 0 ]
    then
        print "
    If you know the user logins of all the people that will be
    using this product, enter them here."
        set -- ${user_based_list:-${prior_ubl:-$USER}}
        i=1
    fi

    let j=i+1
    print "
    Enter -n if you want to stop entering users.  If you enter -n
    the remainder of the users will be generated as user$i, user$j, etc.
    You can later edit the options file and change these user names."
    if [ -x $DIR/options_setup ]
    then
        print "    The command called options_setup will help you do this."
    fi

    while [ $i -le $Quantity ]
    do
        case "$1" in
        "" )
            unset prod_user
            ;;
        * )
            prod_user=$1
            shift
            ;;
        esac

        rsf_get_option prod_user str "Enter user login #$i of $Quantity:"
        case "$prod_user" in
        -*|-* ) break ;;
        esac

        if print " $new_ub_list " | grep " $prod_user " >/dev/null
        then
            print "    User '$prod_user' has already been specified."
            unset prod_user
        else
            new_ub_list="$new_ub_list $prod_user"
            let i=i+1
        fi
    done
    user_based_list=$new_ub_list
    unset new_ub_list
}

#------------------------------------------------------------------------
function rsf_check_and_set_user_based
{
    while true
    do
        for k in $License_Key_List $Alternate_Key_List
        do
            eval Quantity=\$rsu_lic_qty$k
            case "$Quantity" in
            ""|0|uncounted ) continue ;;
            esac
            eval key=\$rsu_lic_key$k
            test -n "$key" || continue
            eval lic_method=\$rsu_lic_method$k
            test "$lic_method" = "$USER_BASED" || continue
            Using_UB_license=true
            eval lic_name=\$rs_startup_key$k
            eval desc=\$rs_startup_desc$k
            eval user_based_list=\$rsu_user_based_list$k
            rsf_enter_user_based_list
            eval rsu_user_based_list$k=\$user_based_list
            prior_ubl=$user_based_list
        done

        $Using_UB_license || break

        yn_repeat_ub=no
        rsf_get_option yn_repeat_ub y_n \
            "Do you want to go through the user specifications again?"
        test "$yn_repeat_ub" = no && break
    done
}

#------------------------------------------------------------------------
function rsf_exp_date_format_okay
{
    case $exp_date in
    p*|P*)
        exp_date=permanent
        return 0
        ;;
    *-*-*)
        ;;
    * )
        print "
    The expiration date must be in the format DD-MMM-YYYY such as 31-Dec-$year."
        if $1
        then
            echo "    You can enter ${sul}p${eul} to specify a permanent expiration date."
        fi
        return 1
        ;;
    esac

    exp_date_format=0
    case $exp_date in
    *-[2-9][0-9][0-9][0-9] )
        exp_year=${exp_date##*-}
        ;;
    * )
        let year1=year+1
        let year2=year+2
        exp_year=${exp_date##*-}
        print "
    The year, $exp_year, in $exp_date should be one of
    $year, $year1, $year2, ... etc."
        unset exp_year
        exp_date_format=1
        ;;
    esac

    case $exp_date in
    *-jan-*|*-Jan-*|*-JAN-* )
        exp_month=01
        Month=January
        max_days=31
        ;;
    *-feb-*|*-Feb-*|*-FEB-* )
        exp_month=02
        Month="February $exp_year"
        if [ "$(expr $exp_year % 4)" -eq 0 ]
        then
            max_days=29
        else
            max_days=28
        fi
        ;;
    *-mar-*|*-Mar-*|*-MAR-* )
        exp_month=03
        Month=March
        max_days=31
        ;;
    *-apr-*|*-Apr-*|*-APR-* )
        exp_month=04
        Month=April
        max_days=30
        ;;
    *-may-*|*-May-*|*-MAY-* )
        exp_month=05
        Month=May
        max_days=31
        ;;
    *-jun-*|*-Jun-*|*-JUN-* )
        exp_month=06
        Month=June
        max_days=30
        ;;
    *-jul-*|*-Jul-*|*-JUL-* )
        exp_month=07
        Month=July
        max_days=31
        ;;
    *-aug-*|*-Aug-*|*-AUG-* )
        exp_month=08
        Month=August
        max_days=31
        ;;
    *-sep-*|*-Sep-*|*-SEP-* )
        exp_month=09
        Month=September
        max_days=30
        ;;
    *-oct-*|*-Oct-*|*-OCT-* )
        exp_month=10
        Month=October
        max_days=31
        ;;
    *-nov-*|*-Nov-*|*-NOV-* )
        exp_month=11
        Month=November
        max_days=30
        ;;
    *-dec-*|*-Dec-*|*-DEC-* )
        exp_month=12
        Month=December
        max_days=31
        ;;
    * )
        exp_month=${exp_date#*-}
        exp_month=${exp_month%-*}
        this_month=$(rsf_lc "$This_Month")
        THIS_MONTH=$(rsf_uc "$This_Month")
        print "
    The month, $exp_month, in $exp_date is not recognized.
    should be one of: Jan, Feb, Mar, Apr, May, Jun, Jul, Aug,
                      Sep, Oct, Nov, or Dec.
    Remember, you can enter the month in lower case ($this_month), all
    upper case ($THIS_MONTH) or with initial capitalization ($This_Month)."
        unset exp_month max_days
        exp_date_format=1
        ;;
    esac

    case $exp_date in
    0-* )
        exp_day=0
        ;;
    [0-9][0-9]-* )
        exp_day=${exp_date%%-*}
        ;;
    [1-9]-* )
        exp_day=0${exp_date%%-*}
        ;;
    * )
        exp_day=${exp_date%%-*}
        print "
    The day, $exp_day, in $exp_date should be a one
    or two digit number."
        unset exp_day
        exp_date_format=1
        ;;
    esac

    if [ -n "$exp_day" -a "$exp_day" -eq 0 ]
    then
        print "
    The day, $exp_day, in $exp_date must be greater than 0 and less than
    or equal to $max_days (the maximum number of days in $Month)."
        unset exp_day
        exp_date_format=1
    fi

    if [ -n "$exp_day" -a -n "$max_days" ]
    then
        if [ "$exp_day" -gt "$max_days" ]
        then
            print "
    There are only $max_days days in $Month, not $exp_day days."
            exp_date_format=1
        fi
    fi

    test $exp_date_format -eq 1 && return 1

    exp_date_n=${exp_year}${exp_month}$exp_day
    if [ "${#exp_date_n}" -eq 8 ]
    then
        test "$exp_date_n" -ge "$today" && return 0

        print "
    The expiration date appears to have already past.
    According to the date command on $HOST,
    today is $today (YYYYMMDD format) and you entered an expiration
    date  of $exp_date_n (converted from $exp_date).

    A valid expiration date would have to be $day-$This_Month-$year or later."
        if [ "$exp_date" = "$prior_exp_date" ]
        then
            unset exp_date prior_exp_date
        else
            unset exp_date
        fi
    fi
    return 2
}

#------------------------------------------------------------------------
function rsf_remove_comments_blanks
{
    inblank=false
    CTRL_M=$(print "\0015")
    (grep -v "^#" $1; echo) |
    sed -e "s?$CTRL_M??g" -e "s?^[$WS]*\$?%B%?" -e 's?^?%%?' -e 's?\\?%C%?g' |
    while read line
    do
        case "$line" in
        %%%B% )
            if $inblank
            then
                continue
            fi
            inblank=true
            ;;
        * )
            inblank=false
            ;;
        esac
        print "$line"
    done | sed -e 's?^%%??' -e 's?%C%?\\?g' -e 's?^%B%??'
    unset inblank
}

#------------------------------------------------------------------------
function rsf_INCREMENT
{
    test "$1" = "$lic_name" || return

    while [ $# -gt 0 ]
    do
        case "$1" in
        VENDOR_STRING=* )
            lic_method=$(print $1 | awk -F\| '{print $2}')
            case "$lic_method" in
            Node* ) lic_method=Node-Locked ;;
            esac
            ;;
        vendor_info=* )
            lic_desc=$(print $1 | awk -F\| '{print $2}')
            ;;
        esac
        shift
    done
}

#------------------------------------------------------------------------
function rsf_extract_lic_desc_method_from_import
{
    if grep "Last Issued:" $rsu_import_lic_file >/dev/null
    then
        _e_del_last_issued="-e 1,/Last.Issued:/d"
    else
        unset _e_del_last_issued
    fi

    CTRL_M=$(print "\0015")
    sed -e 's?^?#?' $_e_del_last_issued \
        -e 's?^#INCREMENT?rsf_INCREMENT?' \
        -e "s?#$TAB? ?" \
        -e "s?$CTRL_M??g" \
        $rsu_import_lic_file > $TEMP

    . $TEMP
    /bin/rm -f $TEMP
}

#------------------------------------------------------------------------
function rsf_extract_request_id
{
    # Use sed to extract the licenses file.
    EXTDIR=/tmp/licupd.$$
    print /bin/rm -fr $EXTDIR >> $RM_LIST
    test -d $EXTDIR || mkdir $EXTDIR
    if [ $start1 -gt 1 ]
    then
        # This will remove lines 1 to start1-1:
        let start0=start1-1
        sed_e1="-e '1,${start0}d'"
    else
        unset sed_e1
    fi
    eval sed $sed_e1 -e \"${end1}q\" $rsu_import_lic_file > $EXTDIR/lic.upd

    if grep "^INCREMENT" $EXTDIR/lic.upd >/dev/null 2>&1
    then
        if rsf_extract_server_info import $EXTDIR/lic.upd
        then
            rsf_set_server_hostid_port import true
            UPD=license_for_$rsu_lic_server.upd
        fi
        print "    The $UPD file has been extracted from"
        print "    $rsu_import_lic_file."
        rsf_remove_comments_blanks $EXTDIR/lic.upd > $Config/$UPD
        return 0
    fi
    return 1
}

#------------------------------------------------------------------------
function rsf_extract_server_info
{
    test -s $2 || return 1
    Eprefix=$1
    Efile=$2
    Extracted=false
    set -- 1 $(grep "^SERVER[$WS]" $Efile 2>/dev/null)
    if [ $# -ge 4 ]
    then
        Extracted=true
    else
        set -- 1 2 $(grep "Host .* for this machine:" $Efile |
                     awk -F: '{print $2}') $def_lic_port
        if [ $# -gt 4 ]
        then
            CTRL_M=$(print "\0015")
            set - $(print "$*" | sed -e "s?$CTRL_M??g")
            Extracted=true
        fi
    fi

    if $Extracted
    then
        case $3 in
        any|ANY )
            eval ${Eprefix}_lic_server=$HOST
            eval ${Eprefix}_lic_hostid=ANY
            eval ${Eprefix}_lic_port=${def_lic_port:-27000}
            ;;
        * )
            eval ${Eprefix}_lic_server=\$3
            eval ${Eprefix}_lic_hostid=\$4
            alt_opt=$(rsf_is_int "$5")
            case "$alt_opt" in
            int )
               eval ${Eprefix}_lic_port=\$5
               ;;
            esac
            ;;
        esac
    else
        eval ${Eprefix}_lic_server=$HOST
        eval ${Eprefix}_lic_hostid=ANY
        eval ${Eprefix}_lic_port=${def_lic_port:-27000}
    fi
    unset Efile Eprefix Extracted
    return 0
}

#------------------------------------------------------------------------
function rsf_check_import_file
{
    found_problems=no
    set -- 1 $(grep "Content-Type:" $rsu_import_lic_file)
    shift
    if [ $# -gt 0 ]
    then
        found_problems=yes
        Explain_extraneous="
    There are lines like this in the file that should be removed:
      $*"
    else
        unset Explain_extraneous
    fi

    set -- $(wc -l $rsu_import_lic_file)
    import_file_length=$1
    if [ $import_file_length -ge 200 ]
    then
        found_problems=yes
        Explain_too_big="
    The license file may be too big--expected 200 or less lines:
      $rsu_import_lic_file ($1 lines).\n"
    else
        unset Explain_too_big
    fi

    if [ $found_problems = yes ]
    then
        rsf_display_important
        print "$Explain_too_big
    You should edit this file and remove any extraneous lines.
    Leave the '#' and '#-#' comments, the INCREMENT, SERVER, VENDOR,
    and FEATURE lines.  $Explain_extraneous

    If you feel this is not a problem you can choose to use this file
    as your license file anyway.

    You can edit this file in another window and use the file
    or save it as another file and select the new file to import."

        yn_use_import_anyway=no
        rsf_get_option yn_use_import_anyway y_n \
            "Use ${rsu_import_lic_file##*/} anyway?"
        test "$yn_use_import_anyway" = no && return 1
    fi

    if rsf_extract_server_info import $rsu_import_lic_file
    then
        rsf_set_server_hostid_port import true
        UPD=license_for_$rsu_lic_server.upd
    fi

    if [ "$Config/$UPD" != "$rsu_import_lic_file" ]
    then
        rsf_save_prior_file $Config/$UPD
        rsf_remove_comments_blanks $rsu_import_lic_file > $Config/$UPD
    fi
    return 0
}

#------------------------------------------------------------------------
function rsf_parse_increment
{
    print "lic_feat='$2'"
    print "vdaemon='$3'"
    print "exp_date='$5'"
    $Set_rsu_lic_vars && print "rsu_lic_exp_date$i='$5'"
    print "Quantity='$6'"

    if [ "$5" = permanent ]
    then
        # Any license with the word permanent in the expiration date
        # is a permanent license.
        Key_expires=false
        print "rsu_lic_qty$i='$6'"
        print "Lic_Key_Type=permanent"
        print "lic_key_type=permanent"
        print "rsu_lic_key='$7'"
        print "rsu_lic_key$i='$7'"
    else
        # The license is either a TLA license or an temporary
        # license.  Later, will determine if license is node-locked
        # and if it is, will need to treat it like a counted license
        # even if it is uncounted.
        Key_expires=true
        print "Lic_Key_Type=temporary"
        print "rsu_startup_key$i='$7'"
        qty=$6
        key=$7
    fi

    shift 7
    Node_locked=false
    while [ $# -gt 0 ]
    do
        case "$1" in
        VENDOR_STRING )
            case "$2" in
            *Floating* )
                print "lic_method=Floating"
                $Set_rsu_lic_vars && print "rsu_lic_method$i=Floating"
                ;;
            *NodeLocked* )
                print "lic_method='Node-Locked'"
                $Set_rsu_lic_vars && print "rsu_lic_method$i=Node-Locked"
                Node_locked=true
                ;;
            esac
            shift
            ;;
        HOSTID )
            if [ "$2" != ANY ]
            then
                $Set_rsu_lic_vars && print "rsu_lic_hostid='$2'"
            fi
            shift
            ;;
        ISSUED )
            $Set_rsu_lic_vars && print "rsu_lic_issue_date$i='$2'"
            shift
            ;;
        NOTICE )
            $Set_rsu_lic_vars && print "rsu_lic_notice$i=\"$2\""
            shift
            ;;
        USER_BASED )
            print "lic_method='$USER_BASED'"
            $Set_rsu_lic_vars && print "rsu_lic_method$i=$USER_BASED"
            ;;
        esac
        shift
    done

    if $Key_expires
    then
        # Treat NL as TLA (counted) even if not counted.
        if $Node_locked
        then
            print "Lic_Key_Type=permanent"
            print "lic_key_type=TLA"
        else
            case $qty in
            0|uncounted )
                print "Lic_Key_Type=temporary"
                print "lic_key_type=Evaluation"
                ;;
            * )
                print "Lic_Key_Type=permanent"
                print "lic_key_type=TLA"
                ;;
            esac
        fi
        if $Set_rsu_lic_vars
        then
            print "rsu_lic_key$i='$key'"
            print "rsu_lic_qty$i='$qty'"
        fi
        print "Quantity='$qty'"
    fi
}

#------------------------------------------------------------------------
function rsf_read_increment
{
    test -s $1 || return 1
    (cat $1; echo) | while read line
    do
        case "$line" in
        INCREMENT* )
            set -- $line
            if [ "$2" = "$lic_name" ]
            then
                eval rsf_parse_increment $(print "$line" | sed -e 's?=? ?g')
                break
            fi
            ;;
        esac
    done
}

#------------------------------------------------------------------------
function rsf_import_lic_data
{
    def_rsu_import_lic_file=none

    rsf_menu_title $rs_Suite_Name - Import Licenses
    print "
    The import file you specify should be from a file you saved from an
    e-mail message you received from $rs_vendor.  This is not the
    license file $CMD will set up.  It is the license information this
    program will import to make decisions about what product(s) you
    have licensed and how the licenses should be set up with as a FLEXlm
    license server.

    The file is called something like ${sul}license_for_server.upd${eul}.
    The file must contain FLEXlm SERVER and INCREMENT lines for
    $rs_Suite_Name.

    Currently, $CMD cannot import a redundant server license file."

    if $License_setup_other
    then
        unset def_rsu_import_lic_file
    else
        print "
    If you do not have a .upd file to import licenses from, enter none."
        def_rsu_import_lic_file=none
    fi

    importedAny=no
    prior_import_lic_file=$rsu_import_lic_file
    while true
    do
        rsu_import_lic_file=$prior_import_lic_file
        rsf_get_option rsu_import_lic_file fil "File to import from:"
        case $rsu_import_lic_file in
        none )
            if $License_setup_other
            then
                print "
    The $CMD command requires a .upd license to import."
                rsf_cleanup 2
            fi
            print "
    You selected the option to set up a license server.  To do this,
    you need a .upd license file to import.  If you already have a license
    server you should select option 1 to use and existing license."
            rsf_pause
            def_license_opt=1
            Go_back=true
            unset rsu_import_lic_file
            return 1
            ;;
        esac

        if [ ! -f "$rsu_import_lic_file" ]
        then
            print "\n    $rsu_import_lic_file not found."
            continue
        fi

        if [ !  -r "$rsu_import_lic_file" ]
        then
            print "\n    $rsu_import_lic_file not readable."
            continue
        fi

        # Check that there is one and only one SERVER line. for counted
        # licenses.  If there is no SERVER line, check if there are any
        # INCREMENT lines.
        set -- $(grep "^SERVER" $rsu_import_lic_file | wc -l)
        case $1 in
        0 )
            if [ $(grep "^INCREMENT" $rsu_import_lic_file | wc -l) -eq 0 ]
            then
                print "\n    Cannot import this file:
      $rsu_import_lic_file\n
    There are no SERVER or INCREMENT lines in this file."
                continue
            fi
            # No server line but have INCREMENTs.
            # The server line is assumed to be for ANY host and hostid.
            importedAny=yes
            ;;
        1 )
            # One SERVER is okay.
            set -- $(grep "^SERVER" $rsu_import_lic_file)
            case $2 in
            any|ANY ) importedAny=yes ;;
            esac
            ;;
        3 )
            print "\n    Cannot import this file:\n      $rsu_import_lic_file\n
    It contains 3 SERVER lines.  Currently, $CMD cannot import a
    redundant server license file.  What you need to do is manually
    start a license server on these 3 servers and then rerun
    $CMD to use an existing license server:"

            grep "^SERVER" $rsu_import_lic_file |
                awk '{printf("      %s\n",$2)}'
            print "
    Refer to the installation guide for instructions on setting up
    redundant license servers."
            unset rsu_import_lic_file
            rsf_pause Q
            print "    You will need to enter a different import file."
            continue
            ;;
        * )
            print "\n    Cannot import this file:\n      $rsu_import_lic_file\n
    It contains $1 SERVER lines.  This is an invalid license file.
    License files must contain one or three SERVER lines.
    Currently, $CMD can only import a single server license file."
            continue
            ;;
        esac

        # Check INCREMENT lines.
        set -- $(egrep "^INCREMENT.*$vendor_daemon|^INCREMENT.*$trl_daemon" \
                 $rsu_import_lic_file | awk '{print $2, $5}')
        need_continue=':'
        while [ $# -ge 2 ]
        do
            _feat=$1
            exp_date=$2
            _date=$2
            shift 2
            _mesg=$(rsf_exp_date_format_okay false)
            _status=$?
            case $_status in
            0 ) continue ;;
            1 ) ;;
            2 ) _mesg="    This license has expired." ;;
            esac
            _inc=$(grep "^INCREMENT[$WS]*$_feat[$WS].*$_date" \
                   $rsu_import_lic_file|head -1|awk '{print $1,$2,$3,$4}')
            _pre=$(rsf_typst -L ${#_inc} "$SPACES")
            _mark=$(rsf_typst -L ${#_date} "^^^^^^^^^^^")
            print "
    The '$_feat' license has an invalid expiration date:
$_inc $_date $6
$_pre $_mark
$_mesg
    You need to remove this license before importing this file."
            need_continue=continue
        done
        unset _feat _date _status _mesg _inc _pre _mar
        eval $need_continue

        if $License_setup_other
        then
            rsf_set_License_Key_List -i && break
        else
            for i in $License_Key_List $Alternate_Key_List
            do
                eval lic_name=\$rs_startup_key$i
                search="INCREMENT $lic_name $vendor_daemon"
                grep "^$search"  $rsu_import_lic_file >/dev/null && break 2
                search="INCREMENT $lic_name $trl_daemon"
                grep "^$search"  $rsu_import_lic_file >/dev/null && break 2
            done
        fi

        print "
    Checked the import file and could not find an INCREMENT line for:
      $Feature_List\n
    There does not appear to be any license information to import
    for $rs_Suite_Name."

        if rsf_is_a_lic_file $rsu_import_lic_file
        then
            yn_use_lic_file=no
            rsf_get_option yn_use_lic_file y_n "Use this import file anyway?"
            test "$yn_use_lic_file" = yes && break
        else
            print "
    There are no INCREMENT or FEATURE lines in the import file."
        fi
    done

    set -- 1 $(grep -n "^#-#    End Request: " $rsu_import_lic_file |
        tail -1)
    if [ $# -eq 6  -a  "$3 $4" = "End Request:" ]
    then
        end1=${2%:*}
        Request_id="$5 $6"
        start1="#-#    Last Issued: $Request_id"
        set -- 1 $(grep -n "^$start1" $rsu_import_lic_file)
        if [ $# -eq 6  -a "$3 $4" = "Last Issued:" ]
        then
            let start1=${2%:*}-2
            extract_request=yes
        fi
    fi

    print "
    Importing licenses from:
      $rsu_import_lic_file"

    if [ "$extract_request" = yes ]
    then
        # First attempt to extract using request ID.
        # If it fails.  Do it with the rsf_check_import_file function.
        rsf_extract_request_id || rsf_check_import_file || return 1
    else
        # Just do it with this function.
        rsf_check_import_file || return 1
    fi

    for i in $License_Key_List $Alternate_Key_List
    do
        eval lic_name=\$rs_startup_key$i
        unset lic_feat
        eval $(rsf_read_increment $Config/$UPD)
        if [ -n "$lic_feat" ]
        then
            eval lic_desc=\"Imported \$rs_startup_desc$i license:\"
            if [ ${#lic_desc} -gt 74 ]
            then
                rsf_split_desc false 74 "$lic_desc"
                print "\n    $desc1\n    $desc2"
            else
                print "\n    $lic_desc"
            fi
            print "      Name:     $lic_feat ($vdaemon)"
            print "      Quantity: $Quantity"
            if [ "$exp_date" != permanent ]
            then
            print "      Expires:  $exp_date"
            fi
            print "      Type:     $lic_key_type"
            if [ -n "$lic_method" ]
            then
            print "      Method:   $lic_method"
            fi
        else
            unset rsu_lic_qty$i
        fi
    done
    rsf_pause
    return 0
}

#------------------------------------------------------------------------
function rsf_add_group_opt
{
    if [ $tot_group -eq 1 ]
    then
        print "    Adding/checking INCLUDE $lic_name GROUP $group_name"
    else
        print "    $group_N of $tot_group: Adding/checking INCLUDE $lic_name GROUP $group_name"
    fi
    (
    egrep -v "[$WS]$group_name[$WS]| $lic_name:KEY=$key " \
        $options_file 2>/dev/null
    print "GROUP $group_name $user_based_list"
    print "INCLUDE $lic_name:KEY=$key GROUP $group_name"
    ) > $TEMP
    /bin/cp $TEMP $options_file
    /bin/rm -f $TEMP
}

#------------------------------------------------------------------------
function rsf_set_user_based_list
{
    # Set users in groups of rs_Max_users_per_group size.
    # Start by using the rsu_user_based_list or the remainder_ub_list
    # specified in ubl_source.  Auto-generate the remainder users
    # up to Quantity.
    unset user_based_list

    # Load command line args with any user login ids.
    set -- 1 $ubl_source
    shift

    # Set a limit for the number of users to set in this group.
    # This must be whatever is less:
    #    Quantity or
    #    rs_Max_users_per_group (including the previous user count).
    let ub_limit=rs_Max_users_per_group+user_count
    if [ $ub_limit -gt $Quantity ]
    then
        ub_limit=$Quantity
    fi

    # Check the existing list (if any) up through ub_limit.
    # The next set of users need to be auto-generated up through ub_limit.
    while [ $user_count -lt $ub_limit ]
    do
        let user_count=user_count+1
        if [ $# -gt 0 ]
        then
            user_based_list="$user_based_list $1"
            shift
        else
            user_based_list="$user_based_list user$user_count"
        fi
    done

    if [ $# -gt 0 ]
    then
        # Put the remainder of the users back on this list
        # for the next time through this function.
        ubl_source="$*"
    fi

    unset ub_limit

    if [ $user_count -ge $Quantity ]
    then
        return 0
    else
        return 1
    fi
}

#------------------------------------------------------------------------
function rsf_create_options_file
{
    # If using user-based permanent licenses, must have an options file
    # for user includes.  Create or update as needed.
    $Using_UB_license || return
    test "$Lic_Key_Type" = permanent || return
    test -n "$options_file" || return

    rs_Max_users_per_group=${rs_Max_users_per_group:-100}
    if [ -f $options_file ]
    then
        opt_exist=yes
        unset prior_file
        rsf_save_prior_file $options_file >/dev/null
        prior_options=$prior_file
    else
        opt_exist=no
    fi
    rsu_options_updated=true

    (
    print "##
## Some licenses are restricted to run only by certain users.
## You specify which users will be authorized to run the applications.
## You can edit this file to change the users you want to be authorized.
## Do not remove any users, just change the user login.  The number of users
## must match the license quantity.
## NOTE: For changes to take effect,
##       you must restart the license server using this options file.
##"
    grep -v "^##" $options_file 2>/dev/null
    ) > $TEMP
    /bin/cp $TEMP $options_file

    gn=0
    group_N="000"
    for i in $License_Key_List $Alternate_Key_List
    do
        eval lic_method=\$rsu_lic_method$i
        test "$lic_method" = "$USER_BASED" || continue

        eval Quantity=\$rsu_lic_qty$i
        test -n "$Quantity" || continue

        eval key=\$rsu_lic_key$i
        case "$key" in
        ???????????? )
            eval Quantity=\$rsu_lic_qty$i
            case "$Quantity" in
            0|uncounted )
                continue
                ;;
            esac
            eval lic_name=\$rs_startup_key$i
            ;;
        * )
            continue
            ;;
        esac

        # Set the base GROUP name for the options file.
        eval base_group_name=\$rs_group_name$i
        base_group_name=${base_group_name:-$rs_Suite_Abbr}

        # Each new set of max gets a count from 1 up.
        user_count=0
        let tot_group=Quantity/rs_Max_users_per_group+1

        # Set the initial list.
        eval ubl_source=\"\$rsu_user_based_list$i\"

        # Make an entry for each rs_Max_users_per_group set of users.
        while true
        do
            rsf_set_user_based_list
            ubl_status=$?
            # Check if there is an entry for group_name.  If there is and
            # it is not for this license, set an new group name.
            while true
            do
                group_name=${base_group_name}_$group_N
                grep " $group_name\$" \
                    $options_file >/dev/null 2>&1 || break
                grep " $lic_name:KEY=.* $group_name\$" \
                    $options_file >/dev/null 2>&1 && break
                let gn=gn+1
                group_N=$(printf "%03d" $gn)
            done
            rsf_add_group_opt
            let gn=gn+1
            group_N=$(printf "%03d" $gn)
            # Check the status to see if the list is complete.
            test $ubl_status -eq 0 && break
        done
        unset ubl_status ubl_source user_based_list user_count
        unset group_name base_group_name tot_group
    done

    if [ -n "$prior_options" ]
    then
        if [ -f $prior_options ]
        then
            if diff $options_file $prior_options >/dev/null 2>&1
            then
                unset rsu_options_updated
                /bin/rm -f $prior_options
            fi
        fi
    fi

    unset prod_user
    /bin/rm -f $TEMP

    case ${opt_exist}$rsu_options_updated in
    yestrue )
        print "\n    Options file has been updated:\n      $options_file"
        rsu_license_changed=true
        test -n "$LOG_FILE" && cat $options_file >> $LOG_FILE
        ;;
    yes* )
        print "\n    Options file is up-to-date:\n      $options_file"
        test -n "$LOG_FILE" && cat $options_file >> $LOG_FILE
        ;;
    notrue )
        print "\n    Options file has been created:\n      $options_file"
        test -n "$LOG_FILE" && cat $options_file >> $LOG_FILE
        rsu_license_changed=true
        ;;
    no* )
        print "\n    Options file was NOT created:\n      $options_file"
        ;;
    esac
    unset opt_exist
}

#------------------------------------------------------------------------
function rsf_save_prior_file
{
    test $# -eq 0 && return
    _file=$1
    test -s  $_file || return

    _file_name=${_file##*/}

    set -- 1 $(/bin/ls -1r $Backups/$_file_name.prior* 2>/dev/null)
    if [ $# -ge 2 ]
    then
        if diff $_file $2 >/dev/null
        then
            prior_file=$2
            return
        fi
        pindex=${2##*prior}
        let pindex=${pindex:-0}+1
        prior_file=$Backups/$_file_name.prior$pindex
    else
        prior_file=$Backups/$_file_name.prior1
    fi

    if touch $prior_file 2>/dev/null
    then
        /bin/rm -f $prior_file
        /bin/cp -p $_file $prior_file
        print "\n    Pre-existing '$_file_name' file saved as:"
        print "      $prior_file"
    else
        unset prior_file
    fi
}

#------------------------------------------------------------------------
function rsf_set_lic_port
{
    rsu_lic_port=${rsu_lic_port:-$target_lic_port}
    test -n "$rsu_lic_port" && return
    if [ -f $rsu_lic_file ]
    then
        rsf_extract_server_info prior $rsu_lic_file
        rsu_lic_port=${prior_lic_port:-$def_lic_port}
    else
        rsu_lic_port=$def_lic_port
    fi
}

#------------------------------------------------------------------------
function rsf_compare_lic_versions
{
    # Usage: rsf_compare_lic_versions X1.M1 {-gt|-lt|-eq} X2.M2
    # Break license version into two parts:
    #   exponent (X1,X2) and mantissa (M1,M2).
    # Then compare each separately.  If the exponents (number to left of .)
    # are equal, compare the mantissas (number to the right of .).
    # This is done since ksh does not have a floating point comparison
    # operator.  Return true if the operator (arg2) is true for the comparison.
    (
    _Op=$2
    _X1=${1%.*}
    _X2=${3%.*}
    unset _M1 _M2
    if [ $_X1 -ne $_X2 ]
    then
        # Need to compare exponent part only.
        test $_X1 $_Op $_X2 && exit 0
        exit 1
    fi

    # Need to compare mantissas.
    # Extract right side of . and normalize to 3 digits.
    case $1 in
    *.* ) _M1=${1#*.} ;;
    esac

    case $3 in
    *.* ) _M2=${3#*.} ;;
    esac

    case $_M1 in
    "" ) _M1=0 ;;
     ? ) _M1=${_M1}00 ;;
    ?? ) _M1=${_M1}0 ;;
    esac

    case $_M2 in
    "" ) _M2=0 ;;
     ? ) _M2=${_M2}00 ;;
    ?? ) _M2=${_M2}0 ;;
    esac

    test $_M1 $_Op $_M2 && exit 0
    exit 1
    )
    return $?
}

#------------------------------------------------------------------------
function rsf_check_flexlm_ver
{
    if [ -z "$Flex_Servers" -o -n "$flexlm_ver_checked" ]
    then
        # No license servers or already ran this check
        return
    fi
    
    if [ -z "$rs_Flex_Ver_Rec" -a -z "$rs_Flex_Ver_Min" ]
    then
        flexlm_ver_checked=n/a
        return
    fi
    if [ -z "$rs_Flex_Ver_Feats" ]
    then
        flexlm_ver_checked=n/a
        return
    fi
    flexlm_ver_checked=yes
    _server_versions=""
    _prior_vd_ver=""
    _this_port_host=""
    _n_lic_srvrs=0
    print_n "\n    Checking license server version..."
    set -- $Flex_Servers
    while [ $# -ge 3 ]
    do
        case $1 in
        SERVER )
            _this_port_host="$2"
            _actual_vd_ver=${3#v} # remove leading v char.
            shift 2
            rsf_check_actual_vs_prior
            ;;
        esac
        shift
    done
    if [ $_n_lic_srvrs = 0 ]
    then
        # Cannot check vendor daemon version.  Just return.
        print "No $vendor_daemon vendor daemon licenses found."
        return
    elif [ $_n_lic_srvrs = 1 ]
    then
        _server_versions="The FLEXlm license server version is: $_server_versions"
    else
        _server_versions="The FLEXlm license server versions are: $_server_versions"
    fi
    print
    if [ -n "$rs_Flex_Ver_Min" ]
    then
        if rsf_compare_lic_versions $_actual_vd_ver -lt $rs_Flex_Ver_Min
        then
            print "
    ERROR: $_server_versions
        This does not meet the required minimum version of $rs_Flex_Ver_Min.
        This install cannot proceed.  The minumum required version is $rs_Flex_Ver_Min.
        IBM Rational requires that you upgrade your license server to $flexlm_ver,
            which is provided in this release."
            yn_flex_ver_min=no
            rsf_get_option yn_flex_ver_min y_n "Do you want to continue anyway?"
            test "$yn_flex_ver_min" = no && rsf_cleanup Q
            let Install_errors=Install_errors+1
            return
        fi
    fi
    if [ -n "$rs_Flex_Ver_Rec" ]
    then
        if rsf_compare_lic_versions $_actual_vd_ver -lt $rs_Flex_Ver_Rec
        then
            print "
    WARNING: $_server_versions
        This does not meet the recommended minimum version of $rs_Flex_Ver_Rec.
        This is sufficient for the product version you are installing and
            the install can proceed and complete normally.
        However, the next release of this product will require a minimum
            license server version, $rs_Flex_Ver_Rec.
        IBM Rational recommends you upgrade your license server to $flexlm_ver,
            which is provided in this release."
           rsf_pause
        else
            print "
    OKAY: $_server_versions
          This meets the recommended minimum version of $rs_Flex_Ver_Rec."
        fi
    fi
}

#------------------------------------------------------------------------
function rsf_check_actual_vs_prior
{
    # Check if this server has one or more of the license features needed for
    # this product install.
    _this_port_host=$(rsf_typst -L 30 "$_this_port_host")
    _server_versions="$_server_versions
    $_this_port_host  [Version $_actual_vd_ver]"
    let _n_lic_srvrs=_n_lic_srvrs+1
    if [ -n "$_prior_vd_ver" ]
    then
        if rsf_compare_lic_versions $_prior_vd_ver -gt $_actual_vd_ver
        then
            _actual_vd_ver=$_prior_vd_ver
        fi
    fi
    _prior_vd_ver=$_actual_vd_ver
}

#------------------------------------------------------------------------
function rsf_append_package_spec
{
    # This will extract FLEXlm packages from the ini file that may be
    # defined for specific licenses.  If there is one, it will append it
    # to the license file.

    package_spec="PACKAGE $lic_name "
    grep "$package_spec" $INI_FILE >/dev/null || return

    if grep "$package_spec" $rsu_lic_file >/dev/null 2>&1
    then
        print "\n    $package_spec $added_mesg"
        return
    fi

    print "\n    Adding $package_spec $to_mesg"
    print "      $rsu_lic_file"

    grep "$package_spec" $INI_FILE |
    sed -e 's?\\?%BS%?g' |
    while read pkg_entry
    do
        IFS='|'
        set -- $pkg_entry
        shift 8
        print
        print "$1" | sed -e 's?%BS%n?\
?g' -e "s?%BS%t?$TAB?g" -e 's?%BS%?\\?g'
    done >> $rsu_lic_file
    IFS=$oldIFS
}

#------------------------------------------------------------------------
function rsf_do_license_setup
{
    rsf_menu_title $rs_Suite_Name - License Creation/Update

    added_mesg="has already been added to\n    the license file."
    imprt_mesg="has been imported into\n    the license file."
    noimprt_mesg="was not imported into\n    the license file."
    to_mesg="to license file:"
    in_mesg="in license file:"

    rsf_misc_suite_install

    if [ -f $rsu_lic_file ]
    then
        Updating=Updating
        updated=updated
        update=update
    else
        Updating=Creating
        updated=created
        update=creation
    fi

    unset prior_file
    rsf_save_prior_file $rsu_lic_file
    rsf_set_lic_port

    # For permanent licenses add the SERVER and VENDOR lines
    # to the license file, if needed.
    Add_vendor_lines=true
    _server="SERVER    $rsu_lic_server   $rsu_lic_hostid   $rsu_lic_port"
    if [ "$Imported_licenses" = true  -a  -f "$Config/$UPD" ]
    then
        (
        grep "^SERVER" $Config/$UPD >/dev/null || echo "$_server"
        egrep "^VENDOR[$WS]|DAEMON[$WS]" $Config/$UPD >/dev/null
        if [ $? -ne 0 ]
        then
            for _vendor in $(egrep "^INCREMENT|^FEATURE" $Config/$UPD | awk '{print $3}' |sort -u)
            do
                echo "VENDOR    $_vendor"
            done
        fi
        cat $Config/$UPD
        ) > $rsu_lic_file
        Add_vendor_lines=false
        print "\n    License file has been $updated from the ${rsu_import_lic_file##*/} file."
        added_mesg="has been imported from\n    the import file."
        print "\n    The SERVER line for $rsu_lic_server $added_mesg"

        # Change the port number if the user specified one that is
        # different from the imported license file.  If there is no
        # port number in the file, add the one the user specified.
        if [ -z "$import_lic_port" -o \
             "$import_lic_port" != "$rsu_lic_port" ]
        then
            print "
    Adding TCP/IP port number $rsu_lic_port to the SERVER line
    $in_mesg\n      $rsu_lic_file"
            (
            print "$_server"
            grep -v "^SERVER" $rsu_lic_file
            ) > $TEMP
            /bin/cp $TEMP $rsu_lic_file
            /bin/rm -f $TEMP
        fi

    else
        /bin/rm -f $rsu_lic_file
        print "\n    Adding SERVER line for $rsu_lic_server $to_mesg"
        print "      $rsu_lic_file"
        print "$_server" > $rsu_lic_file
    fi
    unset _server

    if $Add_vendor_lines
    then
        for _daemon in $vendor_daemon $trl_daemon
        do
            if grep "^VENDOR[$WS]*$_daemon" $rsu_lic_file >/dev/null 2>&1
            then
                print "\n    VENDOR $_daemon $added_mesg"
            else
                if egrep "^INCREMENT.*[$WS]$_daemon[$WS]" $rsu_lic_file >/dev/null 2>&1
                then
                    print "\n    Adding VENDOR $_daemon $to_mesg"
                    print "      $rsu_lic_file"
                    print "VENDOR    $_daemon" >> $rsu_lic_file
                fi
            fi
        done
    fi

    # If licensing a suite, add the license package to the license
    # file if needed.
    if [ -f $LICENSE_PACKAGE ]
    then
        # Extract the package name and check if this package is in the
        # license file and up to date.
        set -- 1 $(grep "^PACKAGE" $LICENSE_PACKAGE)
        pkg_name=$3
        pkg_ver1=$5
        pkg_search="PACKAGE $pkg_name "
        set -- 1 $(grep "^$pkg_search" $rsu_lic_file 2>/dev/null)
        if [ $# -gt 1 ]
        then
            # Package in license file.
            # Check the version and if older, remove it.
            pkg_ver2=$5
            if rsf_compare_lic_versions $pkg_ver1 -gt $pkg_ver2
            then
                # Package needs updating.
                print "\n    Updating license PACKAGE $pkg_name $in_mesg
"
                print "      $rsu_lic_file"
                # Remove the old PACKAGE and append the new one.
                if [ -n "$LIC_MERGE" ]
                then
                    $LIC_MERGE -r "$pkg_search" $rsu_lic_file $TEMP 2>/dev/null
                    /bin/cp $TEMP $rsu_lic_file
                    /bin/rm -f $TEMP
                fi
                cat $LICENSE_PACKAGE >> $rsu_lic_file
            else
                # Package is up to date.
                print "\n    License PACKAGE $pkg_name $added_mesg"
            fi
        else
            # Package not in file.  Append it.
            print "\n    Adding license PACKAGE $pkg_name $to_mesg"
            print "      $rsu_lic_file"
            cat $LICENSE_PACKAGE >> $rsu_lic_file
        fi
    fi

    if [ -f $EXTRA_LICENSE ]
    then
        # If the first license key in the extra file is not in
        # the license file, add the entire contents of extra file.
        set -- $(grep "^INCREMENT " $EXTRA_LICENSE)
        lic_name=$2
        rsf_license_is_in_file ||
            cat $EXTRA_LICENSE >> $rsu_lic_file
    fi

    # Add INCREMENT license to the license file if needed.
    # Create a startup or evaluation license file from the template file.
    rsf_set_license_dirs
    for i in $License_Key_List
    do
        eval lic_desc=\$rs_startup_desc$i
        eval lic_name=\$rs_startup_key$i
        if [ "$Lic_Key_Type" = temporary ]
        then
            eval key=\$rsu_startup_key$i
            eval Quantity=\$rsu_startup_qty$i
            eval exp_date=\$rsu_startup_exp_date$i
            eval lic_method=\$rsu_startup_method$i
            issue_date=$def_issue_date
            notice=$Temp_notice
        else
            eval key=\$rsu_lic_key$i
            eval Quantity=\$rsu_lic_qty$i
            eval exp_date=\$rsu_lic_exp_date$i
            eval lic_method=\$rsu_lic_method$i
            eval issue_date=\$rsu_lic_issue_date$i
            eval notice=\$rsu_lic_notice$i
        fi
        test -z "$Quantity" && continue
        test "$lic_method" = "$USER_BASED" && Using_UB_license=true
        if rsf_license_is_in_file $key
        then
            if $Imported_licenses
            then
                print "\n    License INCREMENT $lic_name $imprt_mesg"
            else
                print "\n    License INCREMENT $lic_name $added_mesg"
            fi
            rsf_append_package_spec
            continue
        else
            if $Imported_licenses
            then
                print "\n    License INCREMENT $lic_name $noimprt_mesg"
                continue
            fi
        fi
        rsf_append_package_spec
    done

    if [ -n "$LOG_FILE" ]
    then
        print "\n    $Updated $rsu_lic_file:" >> $LOG_FILE
        cat $rsu_lic_file >> $LOG_FILE
    fi

    if [ -n "$prior_file" -a  -n "$LIC_MERGE" ]
    then
        $LIC_MERGE $rsu_lic_file $prior_file $TEMP 2>/dev/null
        diff $rsu_lic_file $TEMP >/dev/null
        if [ $? -ne 0 ]
        then
            print "\n    Licenses in $prior_file have been merged"
            print "    With licenses in $rsu_lic_file."
            /bin/cp $TEMP $rsu_lic_file
        fi
        /bin/rm -f $TEMP
    fi

    rsf_create_options_file
    rsf_update_license_map

    unset added_mesg imprt_mesg noimprt_mesg to_mesg in_mesg

    # For uncounted licenses we do not need the server so we are done.
    if [ "$Lic_Key_Type" = temporary -o ${Need_server:-false} = false ]
    then
        print "\n    License file $update completed."
        rsf_pause TO continue to the License Check Menu
        return
    fi

    rsf_create_start_lmgrd_file
    rsf_pause TO continue to the License Check Menu
}

#------------------------------------------------------------------------
function rsf_create_start_lmgrd_file
{
    # This function contains an embedded bourne shell script for
    # starting and stopping the license server.  The script also
    # runs other FLEXlm utilities.

    # Create the license server startup file.
    LICENSE_PATH=$rsu_lic_file
    if [ "$Lic_Key_Type" = permanent ]
    then
        rsu_start_lmgrd=$Config/start_lmgrd_on_$rsu_lic_server
    else
        rsu_start_lmgrd=$Config/start_temp_lmgrd_on_$rsu_lic_server
        if [ -n "$rational_lic_file" ]
        then
            # Will need to start server with 2 files.
            LICENSE_PATH="$rational_lic_file:$rsu_lic_file"
        fi
    fi

    rsf_set_license_dirs
    /bin/rm -f $rsu_start_lmgrd
    test -f $rsu_start_lmgrd && return
    flexver=${Lic_Dir2##*/flexlm.}
    flexver=${flexver%%/*}
    max_fd_limit=1024
    case $Lic_Arch in
    *_solaris2|hppa_hpux|hpia|mips_irix_n32|alpha_osf1 )
        Start_Shell='#!/sbin/sh'
        ;;
    * )
        Start_Shell='#!/bin/sh'
        ;;
    esac

    # Beginning of embedded start script. (About 140 lines long)
    print "$Start_Shell
# Run the license manager for $rs_vendor
# FLEXlm version: $flexver
# (for entry in $init_file)
# The next 8 lines are for insserv on Linux SUSE
### BEGIN INIT INFO
# Provides:       ibmrational
# Required-Start: \$network
# Required-Stop:
# Default-Start:  3 5
# Default-Stop:
# Description:    Start the IBM Rational license server
### END INIT INFO
#------------------------------------------------------------------------
# This script can be called with the following command line options:
#
#   start      This will start the lmgrd license server processes.
#              This is the default action if no command line argument
#              is specified.  The rational vendor daemon will start
#              if there are any rational licenses in the license file.
#              The ibmratl vendor daemon will start if there are any
#              ibmratl licenses in the license file.
#
#   stop       Stop the license server processes.
#
#   lmstat     Run the lmstat command. You can do specify other options
#              to lmstat.  For example, 'lmstat -a' or 'lmstat -f feature'.
#
#   lmreread   Tell the license server to reread the license file.
#
#   exinstal   Run the exinstal command on the license file to check the
#              validity of the $vendor_daemon license codes.
#
#   exinstrl   Run the exinstrl command on the license file to check the
#              validity of the $trl_daemon license codes.
#
#   lmdiag     Run the lmdiag command on the license file.
#
#   start_msg  These actions are for the system rc scripts use.
#   and        They display a message.
#   stop_msg
#
#------------------------------------------------------------------------

FLEXlm_action() {

LICENSE_DIR=$Lic_Dir2
LICENSE_DAT=$rsu_lic_file
LICENSE_PATH='$LICENSE_PATH'
LICENSE_EXE=\$LICENSE_DIR/lmgrd
LICENSE_LOG=${rsu_lic_file%.dat}.log
LICENSE_USER=$USER

case \"\$1\" in
stop_msg )
    echo \"Stop lmgrd/$vendor_daemon license server\"
    return 0
    ;;
stop )
    # Stop license manager.
    echo \"Shutting down lmgrd/$vendor_daemon license servers...\"
    \$LICENSE_DIR/lmdown -q -c \$LICENSE_DAT
    return \$?
    ;;
lmreread|reread )
    # Tell license manager to reread the license file.
    echo \$LICENSE_DIR/lmreread -c \$LICENSE_DAT
    \$LICENSE_DIR/lmreread -c \$LICENSE_DAT
    return \$?
    ;;
lmdiag|diag )
    # Do lmdiag command. Pass any other parameters to the command.
    shift
    echo \$LICENSE_DIR/lmdiag -c \$LICENSE_DAT -n \$*
    \$LICENSE_DIR/lmdiag -c \$LICENSE_DAT -n \$*
    return \$?
    ;;
lmstat|stat )
    # Do lmstat command. Pass any other parameters to the command.
    shift
    echo \$LICENSE_DIR/lmstat -c \$LICENSE_DAT \$*
    \$LICENSE_DIR/lmstat -c \$LICENSE_DAT \$*
    return \$?
    ;;
exinstal|ex )
    # Check the 'rational' licenses using exinstal.
    echo \$LICENSE_DIR/exinstal \$LICENSE_DAT
    \$LICENSE_DIR/exinstal \$LICENSE_DAT
    return \$?
    ;;
exinstrl|trl )
    # Check the 'ibmratl' licenses using exinstrl.
    echo \$LICENSE_DIR/exinstrl \$LICENSE_DAT
    \$LICENSE_DIR/exinstrl \$LICENSE_DAT
    return \$?
    ;;
start_msg )
    echo \"Start lmgrd license server.\"
    return 0
    ;;
\"\"|start|Start|START )
    ;;
* )
    echo \"\$0: command option '\$1' not recognized.\"
    return 1
    ;;
esac

if [ -x \$LICENSE_EXE ]
then
    if [ -f \$LICENSE_DAT ]
    then
        # Need to 'su LICENSE_USER' if LICENSE_USER is not root
        # and this script is run as root.
        if id | grep \"uid=0\" >/dev/null 2>&1
        then
            if [ \"\$LICENSE_USER\" = root ]
            then
                Use_su_command=false
            else
                Use_su_command=true
            fi
        else
            Use_su_command=false
        fi

        if [ -s \$LICENSE_LOG ]
        then
            RM_LOG=\"/bin/rm -f \$LICENSE_LOG.prior\"
            MV_LOG=\"/bin/mv \$LICENSE_LOG  \$LICENSE_LOG.prior\"
            if \$Use_su_command
            then
                su \$LICENSE_USER -c \"\$RM_LOG ; \$MV_LOG\"
            else
                eval \$RM_LOG
                eval \$MV_LOG
            fi
        fi

        lower_fd_limit=false
        case \`uname -s\` in
        SunOS )
            # Check the hard limit for the number of file descriptors.
            # Needs to be $max_fd_limit according to Globetrotter.
            actual_fd_limit=\`ulimit -H -n\`
            case \"\$actual_fd_limit\" in
            [0-9]* )
                if [ \"\$actual_fd_limit\" -gt $max_fd_limit ]
                then
                    lower_fd_limit=true
                fi
                ;;
            unlimited )
                lower_fd_limit=true
                ;;
            esac
            ;;
        esac

        if \$lower_fd_limit
        then
            # Lower the file descriptor limits.
            ulimit -n $max_fd_limit
            ulimit -H -n $max_fd_limit
        fi

        if \$Use_su_command
        then
            # Start license manager.
            echo \"Starting FLEXlm lmgrd license server\" \\
                 \"as \$LICENSE_USER.\"
            START_LMGRD=\"\$LICENSE_EXE -c \$LICENSE_PATH -l \$LICENSE_LOG\"
            su \$LICENSE_USER -c \"\$START_LMGRD &\" >/dev/null 2>&1
        else
            echo \"Starting FLEXlm lmgrd license server.\"
            \$LICENSE_EXE -c \$LICENSE_PATH >\$LICENSE_LOG 2>&1 &
        fi
    else
        echo \"License data file not found:\"
        echo \"  \$LICENSE_DAT\"
        return 1
    fi
else
    echo \"License manager not found: \$LICENSE_EXE\"
    return 1
fi
}

(
# If this script is sourced (which it is by some rc scripts), running it
# in a subshell prevents any setting of variables in the calling script.
FLEXlm_action \${1+\"\$@\"}
exit \$?
)" > $rsu_start_lmgrd
    # End of embedded start script.

    chmod a+x $rsu_start_lmgrd 2>/dev/null

}

#------------------------------------------------------------------------
function rsf_startlm_local_or_remote
{
    if [ "${rsu_lic_server%%.*}" = "$HOST" ]
    then
        # Start it local (on this host).
        rsf_start_license_server
        rsf_pause
        return
    fi

    # Need to attempt to start it remotely.
    rsf_save_defaults
    print "Lic_Key_Type='$Lic_Key_Type'" >> $PROD_DEFAULTS
    Remote_id=$tmp_product_def.${USER}-on-${HOST}

    # Make sure the latest commands are in the installed area.
    if $Okay_to_install
    then
        /bin/rm -f $Suite_Path/rs_install
        /bin/cp -p $FILE $Suite_Path/rs_install >/dev/null 2>&1
        if [ -f $INSTALL/rs_install ]
        then
            /bin/rm -f $Suite_Path/$INSTALL/rs_install
            /bin/cp -p $FILE $Suite_Path/$INSTALL/rs_install \
                >/dev/null 2>&1
        fi
    fi

    rsf_set_rsh_cmd

    print "rsu_rational_dir='$rsu_rational_dir'" >> $PROD_DEFAULTS

    print "
    Running license_setup command on remote server: $rsu_lic_server

    In case your home directory is different or does not have access
    on $HOST, will copy default files to
    $rsu_lic_server:/tmp.

$RCP $PROD_DEFAULTS \\
   ${rsu_lic_server}:$Remote_id
"
    $RCP $PROD_DEFAULTS ${rsu_lic_server}:$Remote_id
    if [ $? -ne 0 ]
    then
        print "
    The rcp command appears to have failed.
    Checking if the defaults file was actually copied:
$rsh_cmd $rsu_lic_server /bin/ls $Remote_id"
        _rdef=$($rsh_cmd $rsu_lic_server /bin/ls $Remote_id |
                tail -1)
        if [ "$_rdef" = "$Remote_id" ]
        then
            print "    It appears that the remote copy worked."
        else
            print "    *** Cannot rcp to $rsu_lic_server."
            print "    *** Cannot run remote setup."
            rsf_pause Q
            return
        fi
    fi

    if [ "$remote_os" = "$os_name_linux" ]
    then
        RBKSH="/bin/bash -norc"
    else
        RBKSH="/bin/ksh -p"
    fi

    print "
    Will check if the license server is running on $rsu_lic_server...

$rsh_cmd $rsu_lic_server $RBKSH $Suite_Path/license_setup -remote $Remote_id"
    $rsh_cmd $rsu_lic_server $RBKSH $Suite_Path/license_setup -remote $Remote_id
    rsf_pause
}

#------------------------------------------------------------------------
function rsf_check_license_changed
{
    # If the license file is changed since post-install ran
    # installer needs to update licensing.
    def_menu="the ${sul}License Check Menu${eul}."
    which_menu="${1:-$def_menu}"
    unset def_menu
    rsf_set_License_File
    unset Explain_fix_license
    rsu_license_changed=false
    if [ "$CMD" = options_setup ]
    then
        rsu_license_changed=true
        return
    fi

    if [ "${rsu_options_updated:-false}" = true -a \
         "$Lic_Key_Type" = permanent ]
    then
        rsu_license_changed=true
        return
    fi

    # No need to explain license change when setting up licenses
    # for a product not in this release.
    $License_setup_other && return

    if [ -n "$rsu_license_file" -a -n "$rsu_lic_file"  -a  \
         "$rsu_license_file" != "$rsu_lic_file" ]
    then
        case "$rsu_lic_file" in
        *:* ) The_license_file="The license configuration list" ;;
        *@* ) The_license_file="The port@host" ;;
        * ) The_license_file="The license file" ;;
        esac
        case "$rsu_license_file" in
        *:* ) this_file="this license configuration list:\n$rsu_license_file" ;;
        *@* ) this_file="this port@host: $rsu_license_file" ;;
        * ) this_file="this license file:\n      $rsu_license_file" ;;
        esac
        Explain_fix_license="                               --- NOTE ---
    $The_license_file you selected is different than the license
    currently in use by $this_sp.  $The_sp has already been installed
    and is using $this_file
    To get $the_sp to use the new license settings, you will need to
    update the license settings in $which_menu
    "
        rsu_license_changed=true
        return
    fi
}

#------------------------------------------------------------------------
function rsf_explain_temp_perm_license_combo
{
    rsf_display_important
    print "
    For the temporary licenses to work, you will need to start a license
    server on $HOST with this file:

      $rsu_lic_file

    Since a license server is already running, the way you need to do
    this is to start the lmgrd process with both license files
    in a manner like this:

      lmgrd -c \"license_file_1_pathname:license_file_2_pathname\"

    By specifying 2 or more files in a colon-separated list you
    effectively combine all of the licenses into one server without
    combining the files themselves.  This is necessary since the
    temporary licenses cannot be combined with the permanent licenses
    in the same file because the SERVER lines are slightly different.

    The $CMD command knows how to do this.  You need to enter
    the full pathname of the \"other\" license file and this one:

      $rsu_lic_file
    "
}

#------------------------------------------------------------------------
function rsf_find_rational_lic_file
{
    # Look at the BSD version of ps since it tends not to truncate.
    # Otherwise, use System V /bin/ps which might truncate the filename.
    _v_list=" $vendor_daemon -T | $trl_daemon -T "
    if [ -x /usr/ucb/ps ]
    then
        set -- 1 $(/usr/ucb/ps axww |grep -v grep |egrep "$_v_list")
    elif [ -x /usr/bsd/ps ]
    then
        set -- 1 $(/usr/bsd/ps axww |grep -v grep |egrep "$_v_list")
    else
        set -- 1 $(/bin/ps -ef |grep -v grep |egrep "$_v_list")
    fi
    shift

    unset rational_lic_file maybe_lic_file _v_list
    while [ $# -gt 0 ]
    do
        case "$1" in
        -c )
            if [ -n "$2" ]
            then
                if [ -f "$2" ]
                then
                    rational_lic_file=$2
                    break
                else
                    maybe_lic_file=$2
                fi
            fi
            ;;
        /* )
            if [ -f "$1" ]
            then
                rational_lic_file=$1
                break
            else
                set -- $1*
                for _f in $*
                do
                    if [ -f $_f ]
                    then
                        if rsf_is_a_rational_lic_file $_f
                        then
                            rational_lic_file=$_f
                            break 2
                        fi
                    fi
                done
                maybe_lic_file=${maybe_lic_file:-$1}
            fi
            ;;
        esac
        shift
    done

    if [ -n "$rational_lic_file" ]
    then
        return 0
    fi

    if [ -z "$maybe_lic_file" ]
    then
        return 2
    fi

    case "$maybe_lic_file" in
    *:* )
        unset new_maybe
        ;;
    * )
        return 1
        ;;
    esac

    # It may be a colon-separated list of files.
    # Check if any exist and check if any are the temp file.
    for _lic in $(IFS=: ; echo $maybe_lic_file)
    do
        if [ -f "$_lic" ]
        then
            if [ "$_lic" != "$rsu_lic_file" ]
            then
                if rsf_is_a_rational_lic_file $_lic
                then
                    unset maybe_lic_file
                    rational_lic_file=$_lic
                    return 0
                fi
            fi
            new_maybe="$new_maybe\n      $_lic"
        else
            new_maybe="$new_maybe\n      $_lic (truncated?)"
        fi
    done
    prior_maybe_lic_file=$maybe_lic_file
    maybe_lic_file="$new_maybe"
    unset new_maybe
    return 1
}

#------------------------------------------------------------------------
function rsf_dont_restart_server
{
    # Check if server is already running.
    # If it is, will need to restart with both files.
    # If not running, return false.
    # If the user does not want to restart the server, return true.
    # Otherwise, return false.

    # Return status of rsf_find_rational_lic_file:
    #   0=running, 1=maybe, 2=not running.
    rsf_find_rational_lic_file
    case $? in
    0 )
        print "\n    A $rs_vendor license server is already running."
        ;;
    1 )
        print "\n    A $rs_vendor license server may be running."
        ;;
    2 )
        return 1
        ;;
    esac

    # Ask if user wants to restart the server.

    rsf_get_option yn_restart_server y_n \
        "Would you like $CMD to restart the $rs_vendor server now?"
    if [ "$yn_restart_server" = no ]
    then
        rsf_explain_temp_perm_license_combo
        return 0
    fi

    if [ -n "$maybe_lic_file" ]
    then
        print "
    The $CMD command could not determine the complete pathname to the
    existing license file.  From the UNIX ps command, a $vendor_daemon
    or $trl_daemon vendor daemon appears to be running.  The pathname shown
    here was extracted from the ps command.  Unfortunately, the information
    was either truncated or there was more than one file to choose from:

      $maybe_lic_file

    Please enter the full pathname so $CMD can restart the server
    with this file and the temporary license file together.

    You can enter a list of files as long as they are fully-qualified
    and separated by a colon.

    Please ${sul}do not${eul} enter the name of the temporary license file
    ($rsu_lic_file)."

        while true
        do
            rsf_get_option rational_lic_file fil "License file:"
            if [ -s "$rational_lic_file" ]
            then
                rsf_is_a_lic_file $rational_lic_file && break
                print "
    $rational_lic_file
    does not contain any INCREMENT lines.
    This is not a valid license file"
            else
                case $rational_lic_file in
                *:* )
                    unset valid_lic_path
                    for _lic in $(IFS=: ; echo $rational_lic_file)
                    do
                        if [ -s "$_lic" ]
                        then
                            if rsf_is_a_lic_file "$_lic"
                            then
                                valid_lic_path=${valid_lic_path:-true}
                                continue
                            else
                                print "    $_lic is not a FLEXlm license file."
                                valid_lic_path=false
                            fi
                        else
                            print "    $_lic not found."
                            valid_lic_path=false
                        fi
                    done
                    ${valid_lic_path:-false} && break
                    print "
    One or more of the files in the license path are missing or
    are not valid FLEXlm license files."
                    ;;
                * )
                    print "
    $rational_lic_file
    not found or empty."
                    ;;
                esac
            fi
            unset rational_lic_file
            rsf_get_option yn_restart_server y_n \
                "Would you like $CMD to restart server now?"
            if [ "$yn_restart_server" = no ]
            then
                rsf_explain_temp_perm_license_combo
                return 0
            fi
        done
    fi
    unset maybe_lic_file

    if ${valid_lic_path:-false}
    then
        rsf_extract_server_info running $(IFS=: ; echo $rational_lic_file)
    else
        rsf_extract_server_info running $rational_lic_file
    fi

    if [ "$running_lic_port" != "$rsu_lic_port" ]
    then
        # Need to fix the server line to match the running license server.
        (
        print "SERVER    $rsu_lic_server   ANY   $running_lic_port"
        grep -v "^SERVER" $rsu_lic_file
        ) > $rsu_lic_file.new
        /bin/cp $rsu_lic_file.new $rsu_lic_file
        /bin/rm -f $rsu_lic_file.new
    fi
    return 1
}

#------------------------------------------------------------------------
function rsf_stop_lmgrd
{
    print "
    Stopping license server:
$Lic_Dir/lmdown \\
    -q -c $rsu_lic_file"

    if $Lic_Dir/lmdown -q -c $rsu_lic_file
    then
        print
        sleep 5
    else
        kill $lmgr_pid $vendor_pid
    fi
}

#------------------------------------------------------------------------
function rsf_start_lmgrd
{
    print
    print /bin/sh $rsu_start_lmgrd
    cd $Config
    /bin/sh $rsu_start_lmgrd
    cd $OLDPWD
    sleep 4
}

#------------------------------------------------------------------------
function rsf_license_server_check
{
    # This function will check the status of the license server
    # processes and lock files.  The following return codes are used:
    # 0 - No license server is running or the person running
    #     this command owns the license server.
    # 1 - A problem was detected and repaired.  This function
    #     should be called again to recheck the status.
    #     If it fails the next time, then the problem cannot be
    #     repaired so there is only one retry.
    # 2 - The license server is no owned by the person running
    #     this command or a a problem was detected but could not
    #     be repaired.
    #
    # If an lmgrd daemon is running, the function will set lmgr_pid.
    # If a vendor daemon is running, the function will set vendor_pid.

    unset lmgr_pid vendor_pid owner_status lock_status orphan_status

    # First, check for the existence of any lock files.  If there is a lock
    # file for the vendor daemon, then one may be running or this could
    # be left over from that crashed or was killed one.  Check
    # below for a running lmgrd and vendor daemon.  If not running, remove
    # the lock file.  If a server is running, check who owns it.
    lock_file_list=""
    for _daemon in $vendor_daemon $trl_daemon
    do
        for lock_file in /usr/tmp/lock$_daemon /tmp/lock$_daemon
        do
            if [ -f $lock_file ]
            then
                lock_file_list="$lock_file_list $lock_file"
            fi
        done
    done

    # Second, check for any running lmgrd processes.
    case $sys in
    aix )
        PSEF=/tmp/bin_ps_ef.$$
        /bin/ps -ef > $PSEF
        PS_TMP_FILES="$PSEF"
        set -- $(grep lmgrd $PSEF | awk '{print $2}')
        ;;
    * )
        PSE=/tmp/bin_ps_e.$$
        PSEF=/tmp/bin_ps_ef.$$
        /bin/ps -e > $PSE
        /bin/ps -ef > $PSEF
        PS_TMP_FILES="$PSE $PSEF"
        set -- $(grep lmgrd $PSE | awk '{print $1}')
        ;;
    esac

    # Third, for any running lmgrd, check for a vendor daemon
    # that is the child process of each lmgrd.  Also check for any
    # orphaned vendor daemons.
    server_running=false
    lmgrd_not_running=true
    if [ $# -gt 0 ]
    then
        for lmgr_pid in $*
        do
            set -- 1 $(grep " $lmgr_pid " $PSEF  | egrep " $vendor_daemon | $trl_daemon ")
            shift
            if [ $# -gt 0 ]
            then
                print "    An lmgrd and an IBM Rational vendor process are running."
                owner=$1
                server_running=true
                lmgrd_not_running=false
                break
            fi
            unset lmgr_pid
        done
    fi

    # Look for any vendor daemon processes.  The second parm is the process id.
    for _daemon in $vendor_daemon $trl_daemon
    do
        set -- 1 $(grep " $_daemon " $PSEF | awk '{print $1,$2}')
        shift
        if [ $# -gt 0 ]
        then
            owner=$1
            server_running=true
            vendor_pid="$vendor_pid $2"
        fi
    done

    # Fourth, check for ownership and status.
    if $server_running
    then
        # If the person running this command is not the owner
        # then we cannot restart, modify or repair the license server.
        if [ "$USER" = "$owner" ]
        then
            print "    You are the owner of process:\n$delim"
        else
            print "    You are not the owner of process:\n$delim"
            if [ "$USER" != root ]
            then
                owner_status=2
            fi
        fi
        head -1 $PSEF
        if [ -n "$lmgr_pid" ]
        then
            grep " $lmgr_pid " $PSEF
            for _pid in $vendor_pid
            do
                grep " $_pid " $PSEF | grep -v " $lmgr_pid "
            done
        else
            for _pid in $vendor_pid
            do
                grep " $_pid " $PSEF
            done
        fi
        echo "$delim"
        echo
        if $lmgrd_not_running
        then
            print "    The FLEXlm license manager daemon process (lmgrd) is not running."
            print "    It died or someone did a 'kill -9' on the process id."
            if [ "$USER" = "$owner" ]
            then
                print "    The $CMD command will attempt to repair this situation."
                orphan_status=1
                kill $vendor_pid 2>/dev/null
                sleep 5
                # If the first kill does not get it, use kill -9
                # and check the lock file below.
                kill -9 $vendor_pid 2>/dev/null
                server_running=false
            else
                print "    The $CMD command cannot repair this situation."
            fi
        fi

        if [ "$USER" != root -a "$USER" != "$owner" ]
        then
            print "
    Since you are not the owner of the license server process, you do not have
    permissions to stop, restart or update the license server on this machine.
    FLEXlm does not allow more that one unique vendor daemon per machine.

    You need to set up the product licenses on this machine as $owner.
    Combine all of the IBM Rational licenses into a single license file."
        fi
    else
        print "    No lmgrd/$vendor_daemon/$trl_daemon process combo running on $HOST."
    fi

    if $server_running
    then
        :
    elif [ -n "$lock_file_list" ]
    then
        lock_status=1
        print_n "    Attempting to remove abandoned lock file..."
        for lock_file in $lock_file_list
        do
            /bin/rm -f $lock_file
            if [ -f $lock_file ]
            then
                print
                /bin/rm $lock_file
            fi
            if [ -f $lock_file ]
            then
                case $lock_file in
                *$vendor_daemon ) _daemon=$vendor_daemon ;;
                *$trl_daemon ) _daemon=$trl_daemon ;;
                esac
                print "
    This lock file will prevent the starting of lmgrd and $_daemon.
    The $CMD command attempted to do this and could not.
    This file must be removed:"
                /bin/ls -l $lock_file
                lock_status=2
            else
                print removed.
            fi
        done
    fi
    /bin/rm -f $PS_TMP_FILES
    return ${owner_status:-${lock_status:-${orphan_status:-0}}}
}

#------------------------------------------------------------------------
function rsf_check_for_license_servers
{
    # This function will check the status of the license server
    for i in 1 2
    do
        print "
    Checking if any IBM Rational license servers are running..."
        rsf_license_server_check
        case $? in
        0 )
            return 0
            ;;
        1 )
            if [ $i -eq 2 ]
            then
                print "
    Cannot start license server on $HOST."
                return 1
            else
                print "\n    Checking again..."
                sleep 2
            fi
            ;;
        2 )
            print "
    Cannot start license server on $HOST."
            rsf_cleanup 2
            ;;
        esac
    done
}

#------------------------------------------------------------------------
function rsf_start_license_server
{
    if [ "$Lic_Key_Type" = temporary ]
    then
        if rsf_dont_restart_server
        then
            return
        fi
    fi

    rsf_create_start_lmgrd_file
    if rsf_check_for_license_servers
    then
        if [ -n "$vendor_pid" ]
        then
            started=restarted
            print "    Okay to restart license server on $HOST."
            rsf_stop_lmgrd
            rsf_check_for_license_servers
            if [ -n "$vendor_pid" ]
            then
                print "\n    Failed to stop the license server."
                print "    Cannot restart license server."
                return
            fi
        else
            started=started
            print "    Okay to start license server on $HOST."
        fi
    else
        print "    Cannot start or restart license server."
        return
    fi

    rsf_start_lmgrd
    rsf_check_for_license_servers
    if [ "$Lic_Key_Type" = permanent ]
    then
        if [ -z "$vendor_pid" ]
        then
            print "\n    Failed to start vendor daemon."
            return
        fi
    else
        if [ -z "$lmgr_pid" ]
        then
            print "\n    Failed to start the license server."
            return
        fi
    fi
    print "\n    Successfully $started the license server"

    # If the user has a start file tell them to update the
    # license server startup file.
    # They need to be root to do this part.

    if [ -f $init_file ]
    then
        if [ "$init_file" = /etc/inittab ]
        then
            if [ -r /etc/inittab ]
            then
                if grep $rsu_start_lmgrd /etc/inittab
                then
                    echo "    The system startup file for the license server is up-to-date."
                    return
                fi
                installed=updated
            else
                installed=checked
            fi
        else
            if diff $init_file $rsu_start_lmgrd >/dev/null
            then
                echo "    The system startup file for the license server is up-to-date."
                return
            fi
            installed=updated
        fi
    else
        installed=installed
    fi

    rsf_display_important

    echo "
    The system startup file for the license server needs to be $installed.
    The startup file has been created."
    if [ "$init_file" = /etc/inittab ]
    then
        echo "    As root, you can edit the startup file using a text editor."
    else
        echo "    As root, you can copy the startup file to the ${init_file%/*} directory."
    fi

    echo "    The commands to do this are:"
    echo

    if ${Running_remote:-false}
    then
        echo "      rlogin $rsu_lic_server"
    fi

    print "      su"
    if [ "$init_file" = /etc/inittab ]
    then
        print "      $EDIT /etc/inittab"
        print "      # Add this line to /etc/inittab:"
        print "      lmgr:234:once:/bin/sh $rsu_start_lmgrd"
    else
        print "      cp $rsu_start_lmgrd \\"
        print "         $init_file"
    fi

    if [ -n "$link_to_init_file" ]
    then
        for ifile in $link_to_init_file
        do
            if [ "$ifile" = /sbin/chkconfig ]
            then
                iServ=${init_file##*/}
                print "      # Run these admin commands to configure license server:"
                print "        $ifile --add $iServ"
                print "        $ifile --level 35 $iServ on"
                print "        /sbin/insserv $init_file"
            else
                print "      ln -s $init_file $ifile"
            fi
        done
    fi

    # Check for obsolete startup scripts and tell user to remove them.
    if [ -n "$obs_init_list" ]
    then
        n_ifiles=0
        unset rm_ifiles
        for ifile in $obs_init_list
        do
            if [ -L $ifile -o -s $ifile ]
            then
                let n_ifiles=n_ifiles+1
                rm_ifiles="$rm_ifiles      /bin/rm $ifile\n"
            fi
        done
        case $n_ifiles in
        0 )
            ;;
        1 )
            print "      # Remove this file since it is no longer used:"
            print "$rm_ifiles"
            ;;
        * )
            print "      # Remove these files since they are no longer used:"
            print "$rm_ifiles"
            ;;
        esac
        unset n_ifiles rm_ifiles ifile
    fi

    print "
    If you do not do this, the license server will not restart
    when $rsu_lic_server reboots.
    ====================================================================="
}

#------------------------------------------------------------------------
function rsf_options_setup_menu
{
    rsf_menu_title $rs_Suite_Name - License Options Setup

    if [ -n "$rsu_lic_file" ]
    then
        case "$rsu_lic_file" in
        */Temporary.dat )
            print "
    There is no 'rational.opt' options file when using temporary licenses."
            rsf_exit 1
            ;;
        *:* )
            ;;
        *@* )
            print "
    Cannot change the 'rational.opt' options file when using
    port@host licensing:
      $rsu_lic_file"
            rsf_exit 1
            ;;
        esac
    else
        print "
    Cannot change the 'rational.opt' options file.
    The license file has not been specified."
        rsf_exit 1
    fi

    if [ -z "$rsu_start_lmgrd" ]
    then
        if [ -n "$rsu_lic_server" ]
        then
            for rsu_start_lmgrd in \
                $Config/start_lmgrd_on_$rsu_lic_server \
                $Config/start_temp_lmgrd_on_$rsu_lic_server \
                CREATE
            do
                if [ "$rsu_start_lmgrd" = CREATE ]
                then
                    rsf_create_start_lmgrd_file
                    Cannot_find="Cannot create"
                    break
                elif [ -f $rsu_start_lmgrd ]
                then
                    Cannot_find="Cannot find"
                    break
                fi
            done
        fi
    fi

    if [ ! -f $rsu_start_lmgrd ]
    then
        print "    $Cannot_find the license server startup script:
      $rsu_start_lmgrd

    This script is needed to restart the license server."
        rsf_exit 1
    fi

    print "
    Select the $vendor_daemon options file for editing.
    For the changes to take effect, the license server must be
    restarted.  Once you have modified the file, confirm that
    you want to restart the license server."

    prior_options_file=$options_file
    while true
    do
        rsf_get_option options_file fil "Options file:"
        test -s "$options_file" && break
        print "    $options_file not found."
        options_file=$prior_options_file
    done
    rsf_save_prior_file $options_file
    print "\n    Will start $EDIT on the options file."
    rsf_pause
    $EDIT $options_file

    if [ -n "$prior_file" ]
    then
        if [ -f $prior_file ]
        then
            if diff $prior_file $options_file > /dev/null
            then
                print "
    No changes were made to the options file.  The backup file:
      $prior_file
    is identical to the options file.

    No need to restart the license server.
    "
                rsf_exit 0
            fi
        fi
    fi
}

#------------------------------------------------------------------------
function rsf_make_one_prod_link
{
    if [ "${rs_Make_Prod_Links:-true}" = true -o "$prod_dir" = RoseRT ]
    then
        file_link=$(rsf_is_a_link $rsu_rational_dir/$prod_dir)
        link_to=releases/$prod_dir_ver
        test "$file_link" = "$link_to" && return
        test -d $rsu_rational_dir/$link_to || return
    else
        if [ -L $rsu_rational_dir/$prod_dir ]
        then
            /bin/rm -f $rsu_rational_dir/$prod_dir
        fi
        return
    fi

    Show_cmds=':'
    if [ -n "$file_link" ]
    then
        if [ -d $rsu_rational_dir/$prod_dir/. ]
        then
            # Ask, only if link is still valid.
            print "
    You have an existing link '$prod_dir -> $file_link' in
    in $rsu_rational_dir.
    You can replace this link with a link to $link_to:

       % rm -f $rsu_rational_dir/$prod_dir
       % ln -s $link_to $rsu_rational_dir/$prod_dir
"
            yn_make_sym_link=${yn_make_sym_link:-yes}
            rsf_get_option yn_make_sym_link y_n \
                "Would you like $CMD to do this now?"
            test "$yn_make_sym_link" = no && return
            Show_cmds=print
        else
            # Link no longer points to a valid directory.  Remove it.
            /bin/rm -f $rsu_rational_dir/$prod_dir
        fi
    fi

    $Show_cmds /bin/rm -f $rsu_rational_dir/$prod_dir
               /bin/rm -f $rsu_rational_dir/$prod_dir
    $Show_cmds /bin/ln -s $link_to $rsu_rational_dir/$prod_dir
               /bin/ln -s $link_to $rsu_rational_dir/$prod_dir
}

#------------------------------------------------------------------------
function rsf_make_prod_links
{
    prod_dir=$rs_Suite_Dir
    prod_ver=$rs_Suite_Ver
    test -d $Releases/$prod_dir.$prod_ver && rsf_make_one_prod_link

    for p in $suite_prod
    do
        eval prod_lic_name=\$rs_prod_lic_name$p
        test "$prod_lic_name" = none && continue
        rsf_set_prod_dir_ver false
        rsf_make_one_prod_link
    done
}

#------------------------------------------------------------------------
function rsf_fix_acroread
{
    test -f $prod_home/acroread || return
    chmod u+w $prod_home/acroread 2>/dev/null
    test -w $prod_home/acroread || return
    sed -e "s?^install_dir=/.*?install_dir=\${ACROBAT:-$prod_home/Reader}?" \
        -e "s?^install_dir=\$.*?install_dir=\${ACROBAT:-$prod_home/Reader}?" \
        $prod_home/acroread > $TEMP

    diff $prod_home/acroread $TEMP >/dev/null ||
        /bin/cp $TEMP $prod_home/acroread
    /bin/rm -f $TEMP
}

#------------------------------------------------------------------------
function rsf_write_version_files
{
    prod_arch=$prod_home/$ARCH
    if [ -d $prod_arch -a -w $prod_arch ]
    then
        test -n "$netscape_ver" &&
            print "$netscape_ver" > $prod_arch/.netscape_version
        test -n "$acrobat_ver" &&
            print "$acrobat_ver" > $prod_arch/.acrobat_version
    fi
}

#-----------------------------------------------------------------
function rsf_redefine_get_input
{
    # This new get_input function is added the point-product install
    # library so that its post_install input function will recognize
    # installing in typical mode.
    test -w share/install_lib || return

    # Make sure we have not already added this.
    get_input_comment='New get_input function for typical-mode installs.'
    grep "get_input_comment" share/install_lib >/dev/null && return

    # Okay, now add the new get_input.
    (
    _d1="------------------------------------"
    print
    print "#${_d1}${_d1}"
    print 'get_input() {'
    print "#${_d1}${_d1}"
    print "# $get_input_comment"
    print
    print '    if ${TYPICAL_INSTALL:-false}'
    print '    then'
    print '        if [ -n "$2" ]'
    print '        then'
    print '            result=$2'
    print '            echo "$1 [$2]"'
    print '            return'
    print '        fi'
    print '    fi'
    print
    print '    while true'
    print '    do'
    print '        echo'
    print '        $ECHON "$1 [$2]  $NOCR"'
    print '        read result'
    print '        if [ -n "$result" ]'
    print '        then'
    print '            log_result'
    print '            eval result=\"$result\"'
    print '            case $result in'
    print '            *\~* )'
    print '                result=`expand_tilde $result`'
    print '            esac'
    print '            return'
    print '        elif [ -n "$2" ]'
    print '        then'
    print '            result=$2'
    print '            log_result'
    print '            return'
    print '        else'
    print '            echo "You must enter a value."'
    print '        fi'
    print '    done'
    print
    print '}'
    print
    )  >> share/install_lib
}

#-----------------------------------------------------------------
function rsf_redefine_log_result
{
    # This new log_result function is added the point-product install
    # library so that its post_install read input function will log
    # user input to this commands log file.
    test -w share/install_lib || return

    log_result_comment='New log_result function:'
    grep "log_result_comment" share/install_lib >/dev/null && return

    (
    _d1="------------------------------------"
    print
    print "#${_d1}${_d1}"
    print 'log_result() {'
    print "#${_d1}${_d1}"
    print "# $log_result_comment" 'log to $LOG_FILE.'
    print
    print '    if [ -n "$LOG_FILE" ]'
    print '    then'
    print '        if [ -w $LOG_FILE ]'
    print '        then'
    print '            echo "${1:-$result}" >> $LOG_FILE'
    print '            return'
    print '        fi'
    print '    elif [ -n "$log"  -a  -w $install_dir/$log ]'
    print '    then'
    print '        echo "${1:-$result}" >> $install_dir/$log'
    print '    fi'
    print '}'
    print
    )  >> share/install_lib
}

#-----------------------------------------------------------------
function rsf_redefine_forbid_root
{
    # If installer wants to run as root, update the forbid_root function.
    # Otherwise, post_install will not run.

    test "$USER" = root || return

    test -w share/install_lib || return

    # Now check if this has already been done.
    forbid_comment="New forbid_root function: Allows root."
    grep "$forbid_comment" share/install_lib >/dev/null && return

    (
    _d1="------------------------------------"
    print
    print "#${_d1}${_d1}"
    print 'forbid_root() {'
    print "#${_d1}${_d1}"
    print "# $forbid_comment"
    print
    print '    return'
    print '}'
    print
    )  >> share/install_lib
}

#-----------------------------------------------------------------
function rsf_explain_run_on_other
{
    # This is so we only explain rlogin to complete post_install once
    # for each unique sys.
    eval Explained_rlogin=\$Explained_rlogin_$test_sys
    ${Explained_rlogin:-false} && return

    print "
    $prod_name_ver has been installed for $other_OS.
    Since you are on $HOST running $Test_OS, you will
    need to login to $an_other_OS machine and run post_install there.
    For example:
      rlogin ${test_sys}_host"

    if [ "$prod_pi_functions" = no-op ]
    then
        print "      cd $prod_home"
        set -- *.post_install ${prod_dir}_test
        while [ $# -gt 0 ]
        do
            test -x ./$1 && print "      ./$1"
            shift
        done
        return
    else
        print "      cd $Suite_Path"
        print "      ./post_install"
    fi
    eval Explained_rlogin_$test_sys=true
    rsf_pause
}

#------------------------------------------------------------------------
function rsf_do_ppi_functions
{
    for ppi_file in $DIR/$INSTALL/*.ppi
    do
        if [ -f $ppi_file ]
        then
            . $ppi_file
        fi
    done
}

#------------------------------------------------------------------------
function rsf_do_pi_functions
{
    if [ -z "$1" ]
    then
        eval prod_pi_functions=\"\$rs_prod_pi_functions$p\"
    else
        prod_pi_functions=$1
    fi

    if [ -n "$prod_pi_functions" ]
    then
        for pi_function in $prod_pi_functions
        do
            if [ -f $DIR/$INSTALL/$pi_function ]
            then
                # No longer run cache_setup for purify, purecov, quantify
                # if there is a configure script.
                case "${prod_dir}-$pi_function" in
                purify-cache_setup*|purecov-cache_setup*|quantify-cache_setup* )
                    if [ -x $prod_home/$prod_dir.configure ]
                    then
                        continue
                    fi
                    ;;
                esac
                . $DIR/$INSTALL/$pi_function
            else
                case $pi_function in
                rsf_* )
                    eval $pi_function
                    ;;
                esac
            fi
        done
    fi

    # The rest of this function was developed for Purify, Quantify and
    # PureCoverage.  Qualify if the product release matches one of these.
    # These products will have one of these 3 exe's:
    case "$prod_dir" in
    purify|purecov|quantify )
        if [ -x $prod_home/$prod_dir.configure ]
        then
            unset _lic_opt _doc_dir
            test -n "${Use_Lic_File:-$rsu_lic_file}" &&
                 _lic_opt="-license ${Use_Lic_File:-$rsu_lic_file}"
            test -d $Suite_Path/docs &&
                 _doc_opt="-doc_dir $Suite_Path/docs"

            # Reset these or typical install will incorrectly think
            # we are in an infinite loop and stop on the "Run again" prompt.
            unset prior_option_def prior_option2_def
            cd $prod_home
            RS_INSTALL_SUBSHELL_FILE=./$prod_dir.configure
            . $RS_INSTALL_SUBSHELL_FILE $prod_home $_lic_opt $_doc_opt

            if  [ "$ppc_errors" -gt 0 ]
            then
                let Post_install_errors=Post_install_errors+ppc_errors
                rsf_pause
            fi
            cd $OLDPWD
            return
        fi
        ;;
    * )
        return
        ;;
    esac

    eval licensed=\$rs_prod_licensed$p
    if [ "$licensed" != yes ]
    then
        rsf_display_warning
        print "    $prod_name_ver does not appear to be licensed with:"
        print "      $rsu_lic_file"
        print "    Will not run self-test for this product."
        rsf_pause
        return
    fi

    eval prod_sys=\$rs_prod_sys$p
    test_sys=${prod_sys:-$sys}
    eval Explained_rlogin=\$Explained_rlogin_$test_sys
    pass_file=$prod_home/.tests.passed.on.$test_sys
    On_64=false
    Test_OS="$THIS_OS"

    if [ "$prod_sys" = sol ]
    then
        Test_OS="$THIS_OS (32-bit)"
        if [ -x /bin/isainfo ]
        then
            if [ "$(/bin/isainfo -b)" = 64 ]
            then
                On_64=true
                test_sys=sol64
                pass_file=${pass_file}64
                Test_OS="$THIS_OS (64-bit)"
            fi
        fi

        if [ "$On_64" = false  -a  ! -f ${pass_file}64 ]
        then
            rsf_set_other_OS sol64
            rsf_explain_run_on_other
        fi
    fi

    if [ "$prod_sys" != "$sys" ]
    then
        rsf_set_other_OS $prod_sys
        if [ "$other_OS" != "$Test_OS" ]
        then
            # Don't say anything if we have already run post_install for this
            # product.
            test -f $pass_file  && return
            rsf_explain_run_on_other
            return
        fi
    fi

    if [ -f $pass_file ]
    then
        print "
    ${sul}$prod_name_ver${eul}
    The post_install and test_install have already been run successfully
    on $Test_OS."
        run_pi=yn_run_${prod_dir}_pi
        eval def_$run_pi=no
        rsf_get_option $run_pi y_n "Run again?"
        eval yn_run_pi=\$$run_pi
        test "$yn_run_pi" = no && return
    fi

    unset do_pause
    cd $prod_home
    for pi_file in *.post_install
    do
        test -x ./$pi_file || continue

        print
        print ./$pi_file
        if ./$pi_file
        then
            print "+++ $prod_name post installation passed."
            do_pause=${do_pause:-sleep}
        else
            do_pause=rsf_pause
            print "
*** $prod_name post installation failed.
*** To rerun $prod_name post installation type:
***   cd $prod_home
***   ./$pi_file
"
            let Post_install_errors=Post_install_errors+1
        fi
    done

    self_test=${prod_dir}_test
    test -x ./$self_test || return
    print "\n+++ Running the $prod_name self-test..."

    # Check if the installer is listed in the options file.
    # This check can only be done if the options_file is set.
    # If using port@host, it may not be.  If the licensing being
    # used is temporary, the options file does not come into play.
    Cannot_run_test=false
    if [ -n "$options_file" ]
    then
        if [ -f $options_file ]
        then
            if [ -f $prod_home/.lm_license_file ]
            then
                case $(cat $prod_home/.lm_license_file) in
                */Temporary.dat )
                    Check_options=false
                    ;;
                * )
                    case "$rsu_product_name" in
                    *PurifyPlus* )
                        if [ "$lic_method" = "$USER_BASED" ]
                        then
                            Check_options=true
                        else
                            Check_options=false
                        fi
                        ;;
                    * )
                        Check_options=true
                        ;;
                    esac
                    ;;
                esac
            fi
        else
            Check_options=false
        fi

        if $Check_options
        then
            # Extract the GROUP name.
            Cannot_run_test=true
            for group in $(egrep "${prod_lic_name}:KEY=|PurifyPlusUNIX:KEY=" \
                $options_file | awk '{print $4}')
            do
                if grep " $group " $options_file |
                   egrep " $USER | $USER\$" >/dev/null
                then
                    Cannot_run_test=false
                    break
                fi
            done
        fi
    fi

    if $Cannot_run_test
    then
        do_pause=rsf_pause
        if egrep "${prod_lic_name}:KEY=|PurifyPlusUNIX:KEY=" $options_file \
           >/dev/null 2>&1
        then
            print "
*** $prod_name installation self-test cannot be run.
*** You have not configured yourself ($USER) as an authorized
*** licensed user.  To use $prod_name or run this self-test,
*** you would need to edit this file and include $USER for the
*** $prod_lic_name license:
***   $options_file
"
        else
            print "
*** It appears that $prod_name is not licensed.
*** The installation self-test cannot be run.
*** To use $prod_name or run this self-test,
*** you need to license this product.
"
        fi
        yn_run_test=${yn_run_test:-no}
        rsf_get_option yn_run_test y_n "Try to run the self-test anyway?"
        test "$yn_run_test" = no && return
    fi

    print ./$self_test
    if ./$self_test
    then
        print "+++ $prod_name $prod_ver self-test passed."
        # Let support know that the self-test passed
        touch $pass_file
        chmod 777 $pass_file
        if $On_64
        then
            # Mark the 32 bit tests passed too.
            touch ${pass_file%64}
            chmod 777 ${pass_file%64}
        fi
        do_pause=${do_pause:-sleep}
    else
        do_pause=rsf_pause
        /bin/rm -f $pass_file
        print "
*** $prod_name self-test failed.
*** To rerun $prod_name self-test type:
***   cd $prod_home
***   ./$self_test
"
        let Post_install_errors=Post_install_errors+1
    fi

    cd $OLDPWD
    ${do_pause:-true} 2
}

#------------------------------------------------------------------------
function rsf_update_lic_setting
{
    n_files=0
    eval suite_prod=\"\$rs_suite_prod$rsu_product_num\"
    rsf_set_Whats_licensed || return

    print "\n    Checking files that contain license information..."
    set -- 1 $(
    for p in $suite_prod
    do
        eval licensed=\$rs_prod_licensed$p
        test "$licensed" = yes || continue
        rsf_set_prod_dir_ver false
        prod_home=$Releases/$prod_dir_ver
        test -d $prod_home || continue
        print $prod_dir $prod_home
    done | sort -u)
    shift

    Use_Lic_File=$License_File

    while [ $# -gt 0 ]
    do
        prod_dir=$1
        prod_home=$2
        shift 2
        case $prod_dir in
        apex )
            _ftu=$prod_home/bin/apexinit
            ltag=APEX_LICENSE_FILE
            ;;
        ClearQuestClient )
            _ftu=$prod_home/bin/clearquest
            ltag=cq_license
            # We want to use the license file for CQ in this release.
            # Not port@host, if it is an startup or eval license.
            Use_Lic_File=${Actual_License_File:-$License_File}
            ;;
        rose )
            _ftu=$prod_home/config.sh
            ltag=ROSE_LICENSE_FILE
            ;;
        soda )
            _ftu=$prod_home/bin/soda
            ltag=SODA_LICENSE_FILE
            ;;
        PurifyPlusRealTime|TestRealTime )
            for _ftu in pplusrtinit.csh pplusrtinit.sh \
                        testrtinit.csh  testrtinit.sh
            do
                _ftu=$prod_home/$_ftu
                test -f $_ftu || continue
                print
                case $_ftu in
                *.csh )
                    _n1="setenv LM_LICENSE_FILE"
                    _n2="\"$Use_Lic_File:\${LM_LICENSE_FILE}\""
                    sed -e "s?[$WS]$_n1 \".*\"?${TAB}$_n1 $_n2?" \
                        -e "s?[$WS]$_n1 [^\"].*?${TAB}$_n1 $Use_Lic_File?" \
                        $_ftu > $TEMP
                    ;;
                *.sh )
                    _n1="LM_LICENSE_FILE="
                    _n2="$Use_Lic_File:\${LM_LICENSE_FILE:-}"
                    sed -e "s?^$_n1.*?${_n1}$_n2?" $_ftu > $TEMP
                    ;;
                * )
                    continue
                    ;;
                esac

                if diff $_ftu $TEMP >/dev/null
                then
                    print "    Up-to-date: $_ftu"
                else
                    /bin/cp $TEMP $_ftu
                    let n_files=n_files+1
                    print "    Updated: $_ftu"
                    egrep "^$_n1|[$WS]$_n1" $_ftu
                fi
                /bin/rm -f $TEMP
            done
            continue
            ;;
        * )
            print
            if [ -s $prod_home/.lm_license_file ]
            then
                if [ "$(cat $prod_home/.lm_license_file)" = "$Use_Lic_File" ]
                then
                    print "    Up-to-date: $prod_home/.lm_license_file"
                else
                    print "$Use_Lic_File" > $prod_home/.lm_license_file
                    let n_files=n_files+1
                    print "    Updated: $prod_home/.lm_license_file"
                    cat $prod_home/.lm_license_file
                fi
            else
                print "$Use_Lic_File" > $prod_home/.lm_license_file
                let n_files=n_files+1
                print "    Created: $prod_home/.lm_license_file"
                cat $prod_home/.lm_license_file
            fi
            continue
            ;;
        esac

        test -f $_ftu || continue
        print
        sed -e "s?$ltag=.*?$ltag=\${$ltag:-$Use_Lic_File}?" $_ftu > $TEMP
        if diff $_ftu $TEMP >/dev/null
        then
            print "    Up-to-date: $_ftu"
        else
            /bin/cp $TEMP $_ftu
            let n_files=n_files+1
            print "    Updated: $_ftu"
            grep "$ltag=" $_ftu
        fi
        /bin/rm -f $TEMP
    done

    rsf_set_setup_filenames
    for setup in SETUP_CSH SETUP_SH
    do
        eval setup=\$$setup
        test -z "$setup" && continue
        test -f "$setup" || continue
        for setup_root in $rsu_rational_dir $Suite_Path
        do
            setup_name=${setup##*/}
            setup_file=$setup_root/$setup_name
            test -f $setup_file || continue

            case $setup_name in
            purifyplus_setup.csh )
               _license="set _LmLicense       = "
               ;;
            purifyplus_setup.sh )
               _license="_LmLicense="
               ;;
            * )
               _license="license="
               ;;
            esac

            grep "$_license" $setup_file >/dev/null || continue
            print
            sed -e "s?$_license.*?$_license$License_File?" $setup_file \
                > $TEMP
            if diff $setup_file $TEMP >/dev/null
            then
                print "    Up-to-date: $setup_file"
            else
                /bin/cp $TEMP $setup_file
                let n_files=n_files+1
                print "    Updated: $setup_file"
                grep "$_license" $setup_file
            fi
            /bin/rm -f $TEMP
        done
    done

    case $n_files in
    0 )
        print "\n    No files needed their license settings updated."
        ;;
    1 )
        print "\n    One file needed its license setting updated."
        ;;
    * )
        print "
    $n_files files needed their license settings updated."
        ;;
    esac

    rsf_update_license_map
    rsu_license_file="$License_File"
    rsf_check_license_changed
    rsf_pause
}

#------------------------------------------------------------------------
function rsf_do_prod_post_install
{
    install=$prod_home/install
    print "\n    Running $prod_name_ver post_install"
    print "         in $install"

    cd $install

    # Here is where SoDA and Rose get tied together for RSDSU:
    case $prod_dir in
    rose )
        # First ROSE gets set.
        RSDSU_ROSE=$prod_home
        ;;
    soda )
        # If RSDSU_ROSE is set record ROSE prod home for SoDA.
        # Then SoDA does not need to ask about Rose in its post_install.
        if [ -n "$RSDSU_ROSE" ]
        then
            /bin/rm -f $ARCH/rose_home_dir
            print ROSE_HOME=$RSDSU_ROSE > $ARCH/rose_home_dir
        fi

        # Try to set FMHOME from saved value or global_defaults file.
        if [ -n "$rsu_fmhome" ]
        then
            FMHOME=$rsu_fmhome
        elif [ -f $Config/global_defaults ]
        then
            eval $(grep "^FMHOME=" $Config/global_defaults)
        fi
        if [ -n "$FMHOME" ]
        then
            rsu_fmhome=$FMHOME
            export FMHOME
        fi
        ;;
    esac

    install_defaults=$install/.install_defaults
    arch_defaults=$install/$ARCH/install_defaults
    (
    print product=$prod_dir
    print prod_home=$prod_home
    print prod_base=$Base
    print rational_dir=$rsu_rational_dir
    print release_dir=$Releases
    print apex_layered_product=$apex_layered_product
    print check_license=no
    ) > $install_defaults

    (
    egrep -v "INST_HOMEDIR=|INST_STATUS=" $arch_defaults 2>/dev/null
    print "INST_HOMEDIR=$prod_home"
    print "INST_STATUS=COMPLETED"
    ) >> $arch_defaults.new
    /bin/cp $arch_defaults.new $arch_defaults
    /bin/rm -f $arch_defaults.new

    (
    print SV_LIC_FILE_NAME=$License_File
    print LM_LICENSE_FILE=$License_File
    print export SV_LIC_FILE_NAME LM_LICENSE_FILE
    ) > .license_data

    (
    print "SV_LIC_FILE_NAME=$License_File"
    print "SV_VERIFY_WITH_RSH=yes"
    print "SV_LICENSE_ARCH=$ARCH"
    for i in $License_Key_List
    do
        eval notice=\$rsu_lic_notice$i
        if [ -n "$notice" ]
        then
            print "SV_COMPANY_NAME=\"$notice\""
            break
        fi
    done
    ) > $Config/global_defaults

    case $prod_dir in
    rose* )
        if [ -x ./check_reqs  -a  ! -x ../bin/check_rose_reqs ]
        then
            /bin/cp check_reqs ../bin/check_rose_reqs
        fi
        if $Doing_typical_install
        then
            # The read command in the rose check_reqs script causes
            # rs_install to pause, even in typical mode.  Fix it so
            # it does not pause in this mode.
            if grep " read any_key" check_reqs >/dev/null
            then
                sed -e 's?read any_key?${TYPICAL_INSTALL:-false} || read AK?' \
                    check_reqs > check_reqs.new
                /bin/cp check_reqs.new check_reqs
                /bin/rm -f check_reqs.new
            fi
        fi
        ;;
    * )
        if [ -x ./check_reqs  -a  ! -x ../bin/check_reqs ]
        then
            /bin/cp check_reqs ../bin
        fi
        ;;
    esac

    for inst_file in share/run_order share/version_map*
    do
        rsf_update_config $inst_file
    done

    rsf_redefine_forbid_root
    if [ -n "$LOG_FILE" ]
    then
        rsf_redefine_log_result
        export LOG_FILE
    fi

    if $Doing_typical_install
    then
        export TYPICAL_INSTALL=true
        rsf_redefine_get_input
    fi

    export Running_rs_install=true
    if grep "args.*remote" post_install >/dev/null
    then
        # This command supports the remote option so that the
        # local install.log file does not get created.
        if [ -n "$Play_back" ]
        then
            ./post_install remote </dev/null
        else
            ./post_install remote
        fi
    else
        if [ -n "$Play_back" ]
        then
            ./post_install </dev/null
        else
            ./post_install
        fi
    fi
    cd $OLDPWD
}

#------------------------------------------------------------------------
function rsf_link_docs
{
    # Do not link docs to the suite to this product if they are the same thing.
    test "$Suite_Path" = "$prod_home" && return

    # Do not link docs to non-licensed products (acrobat, netscape, etc.)
    test "$prod_lic_name" = none && return

    # Do not link docs if there aren't any.
    test -d $Suite_Path/docs || return

    # Do not link docs if it already exists as a directory.
    test -d $prod_home/docs && return

    cd $prod_home
    SRC_DOCS=../$rs_Suite_Dir.$rs_Suite_Ver/docs
    SRC_HTML=$SRC_DOCS/html

    if [ -n "$rs_Link_List_These_Docs" ]
    then
        set -- $rs_Link_List_These_Docs
        _sd=$1
        shift
        _docs="$*"
        for _dir in $_sd $_sd.*
        do
            case "$_dir" in
            *\.\* ) continue ;;
            esac

            test -d $_dir || mkdir $_dir
            for _doc in $_docs
            do
                if [ -d $SRC_HTML/$_doc ]
                then
                    /bin/rm -f $_dir/$_doc
                    test -d $_dir/$_doc ||
                        /bin/ln -s ../$SRC_HTML/$_doc $_dir/$_doc
                fi
            done
        done
    fi

    if ${rs_Link_Docs:-false}
    then
        for _dir in UI UI.*
        do
            if [ -d $_dir/. ]
            then
                for HTML in \
                    $SRC_HTML/purifyplus/$prod_dir* \
                    $SRC_HTML/dev_tools/$prod_dir* \
                    $SRC_HTML/$prod_dir*
                do
                    if [ -d $HTML ]
                    then
                        /bin/rm -f $_dir/html
                        /bin/ln -s ../$HTML $_dir/html
                        break
                    fi
                done

                for HTML in \
                    $SRC_HTML/purifyplus/installing_and_gettingstarted \
                    $SRC_HTML/dev_tools/installing_and_gettingstarted \
                    $SRC_HTML/pqc_install
                do
                    if [ -d $HTML ]
                    then
                       /bin/rm -f $_dir/installing_and_gettingstarted
                       /bin/ln -s ../$HTML $_dir/installing_and_gettingstarted
                       break
                    fi
                done
            else
                /bin/rm -f docs
                /bin/ln -s $SRC_DOCS docs
            fi
        done
    fi
    cd $OLDPWD
    unset SRC_DOCS SRC_HTML _dir _ui _doc _docs _sd
}

#------------------------------------------------------------------------
function rsf_make_dirs_writable
{
    find $1 -type d -exec chmod u+w {} \;
}

#------------------------------------------------------------------------
function rsf_do_post_install
{
    if [ -s $RM_LIST ]
    then
        . $RM_LIST
        /bin/rm -f $RM_LIST
    fi

    eval suite_prod=\"\$rs_suite_prod$rsu_product_num\"
    rsf_set_Whats_licensed

    # Check for Apex releases.  If any, have products that are used
    # with Apex be optional layered products.
    if [ -z "$apex_layered_product" ]
    then
        for apex_home in $APEX_HOME $Releases/apex.*
        do
            if [ -f $apex_home/.apex_version ]
            then
                apex_layered_product=optional
            else
                apex_layered_product=no
            fi
            break
        done
    fi

    unset Working_List
    rsf_check_license_changed
    if [ -n "$LM_LICENSE_FILE" ]
    then
        export LM_LICENSE_FILE="$rsu_license_file:$LM_LICENSE_FILE"
    else
        export LM_LICENSE_FILE=$rsu_license_file
    fi
    rsf_make_dirs_writable $Suite_Path

    rsf_set_RSU_LICENSE_MAP
    rsf_do_ppi_functions

    for p in $suite_prod
    do
        eval prod_name=\"\$rs_prod_name$p\"
        rsf_set_prod_dir_ver false
        prod_name_ver="$prod_name $prod_ver"
        if [ "$prod_lic_name" = none ]
        then
            prod_home=$Cots/$prod_dir_ver/$ARCH
        else
            prod_home=$Releases/$prod_dir_ver
            rsf_write_version_files
        fi

        test -d $prod_home || continue
        if [ "$prod_dir" = rose ]
        then
            if [ -s $prod_home/.prod_name_ver ]
            then
                . $prod_home/.prod_name_ver
            elif [ -s $prod_home/.rs_prod_ver ]
            then
                . $prod_home/.rs_prod_ver
            fi
        fi

        rsf_make_dirs_writable $prod_home
        rsf_link_docs

        if [ ! -f $prod_home/install/$ARCH/prod_desc ]
        then
            # Record license file or port@host in any release
            # that does not use post_install.
            rsf_create_lm_license_file
            test "$prod_dir" = acrobat && rsf_fix_acroread
            rsf_do_pi_functions
            if [ -x $prod_home/bin/postinstall ]
            then
                # SiteLoad has a postinstall script it needs to run.
                export prod_home
                rsf_menu_title $prod_name - Post-Install
                $prod_home/bin/postinstall
            fi
            continue
        fi

        rsf_do_pi_functions

        if rsf_in_Working_List $prod_dir_ver
        then
            # This means we just ran post_install for this product
            # So we do not need to run it more than once back-to-back.
            continue
        elif $rsu_license_changed
        then
            rsf_do_prod_post_install
            Working_List="$Working_List $prod_dir_ver"
            continue
        fi

        unset POST_INSTALL
        if [ -f $prod_home/install/$ARCH/install_defaults ]
        then
           eval $(grep POST_INSTALL= $prod_home/install/$ARCH/install_defaults)
        fi

        prod_sys_completed=$prod_home/install/.$prod_sys.completed
        if [ "$POST_INSTALL" = COMPLETED ]
        then
            if [ "$prod_dir" = rose -a  ! -f $prod_sys_completed ]
            then
                POST_INSTALL=NEEDED
            fi
        fi

        if [ "$POST_INSTALL" = COMPLETED ]
        then
            print "
    ${sul}$prod_name_ver${eul}
    Post-install has already been run on $THIS_OS"
            run_pi=yn_run_${prod_dir}_pi
            eval def_$run_pi=no
            rsf_get_option $run_pi y_n "Run again?"
            eval yn_run_pi=\$$run_pi
            test "$yn_run_pi" = yes && rsf_do_prod_post_install
        else
            rsf_do_prod_post_install
        fi

        if [ "$prod_dir" = rose  ]
        then
            touch $prod_sys_completed
        fi
        unset prod_sys_completed

        Working_List="$Working_List $prod_dir_ver"
    done
    unset prod_dir prod_ver prod_sys prod_home prod_name
    unset prod_dir_ver prod_lic_name
    for _pi in $DIR/$INSTALL/*.pi
    do
        test -f $_pi && rsf_do_pi_functions ${_pi##*/}
    done
    unset rsu_license_changed
    rsu_license_file="$License_File"
}

#------------------------------------------------------------------------
function rsf_welcome_menu
{
    if [ -n "$WELCOME_FILE" ]
    then
        sed -e "s?%COMMAND%?$CMD?g" -e "s?%USER_NAME%?$USER?g" $WELCOME_FILE
        rsf_pause
        return
    fi

    rsf_menu_title Using $Command

    if [ -n "$Play_back" ]
    then
        print "
    You are running the $CMD command as $USER in playback mode.
    All of the inputs will be extracted from this file:
      $Play_back"
    else
        print "\n    You are running the $CMD command as $USER."
    fi

    if [ -n "$Record_in" ]
    then
        print "
    All of your inputs will be recorded in this file:
      $Record_in"
    fi

    if [ -n "$LOG_FILE" ]
    then
        print "
    Output from $CMD will be copied to a log file.  When you exit
    $CMD or $CMD completes, the location of the log file
    is displayed."
    fi

    print "
    The -help option can be used to display $CMD command line options.
    All of your inputs will be saved for future runs of $CMD."

    if [ "$LINES" -lt "$Min_lines" ]
    then
        print "
    Your window size is $LINES lines long.  $rs_vendor recommends running
    $CMD in a terminal window that has at least $Min_lines lines."
    fi

    print "
    You can enter a q, q! or ? ${sul}at any prompt${eul}:
    q    Will save your inputs and quit $CMD.
    q!   Quit $CMD without saving your inputs.
         Note that the 'Rational' directory is always saved.
    ?    Get help on the current prompt."

    rsf_pause
}

#------------------------------------------------------------------------
function rsf_license_agreement_menu
{
    # Check if we are using LAP Tool.  There are 2 scripts that
    # could be run.  The runlaptool.pi script is sourced.  The runlaptool
    # script without the .pi suffix is run as a command.
    # Check for variables set (.pi version) or exit codes (command version).
    if [ -f $EXTRAS/LAP/bin/runlaptool.pi ]
    then
        # This is the IBM way to do the license agreement with LAP Tool.
        . $EXTRAS/LAP/bin/runlaptool.pi
        case "$userAccepts" in
        yes )
            yn_license_agreement=yes
            unset rsu_show_lic_agree rsu_show_legal_info
            if [ -f $Suite_Path/license/.who ]
            then
                acceptLicMesg=`cat $Suite_Path/license/.who`
            fi
            return
            ;;
        no|no_display )
            rsf_cleanup LAP
            ;;
        * )
            rsf_cleanup no_LA
            ;;
        esac
    elif [ -x $EXTRAS/LAP/bin/runlaptool ]
    then
        $EXTRAS/LAP/bin/runlaptool
        lapStatus=$?
        case $lapStatus in
        9 )
            yn_license_agreement=yes
            unset rsu_show_lic_agree rsu_show_legal_info
            acceptLicMesg="$USER accepts the license agreement on $(date)."
            echo "    $acceptLicMesg"
            return
            ;;
        3 )
            echo "    User declines the license agreement."
            rsf_cleanup 0
            ;;
        * ) echo "    $EXTRAS/LAP/bin/runlaptool returned status=$lapStatus."
            rsf_cleanup 0
            ;;
        esac
    fi

    # This is for backward compatibility.
    # Not using LAP Tool.  This is the older method.
    rsf_show_license_agreement \
        "$DIR/$LICENSE_AGREEMENT_FILE" \
        "IBM" \
        "IBM Corporation" \
        "yn_license_agreement" \
        "rsu_show_lic_agree" \
        "$DIR/$ALT_LICENSE_AGREE_FILE"

    rsf_show_license_agreement \
        "$DIR/$LEGAL_INFORMATION" \
        "third party software" \
        "Third Party Software" \
        "yn_legal_agreement" \
        "rsu_show_legal_info" \
        "$DIR/$ALT_LEGAL_INFO"

    acceptLicMesg="$USER accepted the license agreement on $(date)."
}

#------------------------------------------------------------------------
function rsf_show_license_agreement
{
    lic_agree_file=$1
    lic_agree_type=$2
    Lic_Agree_Type=$3
    yn_lic_agree_var=$4
    show_lic_agree_var=$5
    alt_agree_file=$6

    eval show_lic_agree=\$$show_lic_agree_var
    test "$show_lic_agree" = no  && return

    localized_agree_file=$I18N/${lic_agree_file##*/}.$LC2
    if [ -f $localized_agree_file ]
    then
        lic_agree_file=$localized_agree_file
    elif [ ! -f "$lic_agree_file" ]
    then
        # Check the alternate naming of this file.
        if [ -f "$alt_agree_file" ]
        then
            lic_agree_file=$alt_agree_file
        else
            return
        fi
    fi

    menu_title="$Lic_Agree_Type License Agreement"

    (
    case "$PAGER" in
    *less ) H=h ;;
    * ) H='?' ;;
    esac

    unset sul eul
    print "\n$delim
    Displaying the $lic_agree_type license agreement with program: $PAGER
      q  Press q to stop showing the license agreement.
         Press the space bar to show the next page.
      $H  Press $H to get help on $PAGER."

    rsf_menu_title $menu_title
    cat $lic_agree_file
    ) | $PAGER

    if [ -d $EXTRAS/LAP/LA_files ]
    then
        set -- $EXTRAS/LAP/LA_files/*.html
        print "\n$delim
    The license agreements can be found in this directory in
    $# languages:
      $EXTRAS/LAP/LA_files

    You can view one of these $# files using a language enabled browser
    if you prefer:"
        (
        cd $EXTRAS/LAP/LA_files
        n=0
        set -- *.html
        while [ $# -gt 0 ]
        do
            case $n in
            4 ) print    "      $1"; n=0 ;;
            * ) print_n "      $1"; let n=n+1 ;;
            esac
            shift
        done
        print
        )
    fi

    rsf_get_option $yn_lic_agree_var y_n \
        "Do you agree to the terms of the $Lic_Agree_Type
    license agreement?"
    eval yn_lic_agree=\$$yn_lic_agree_var
    if [ "$yn_lic_agree" = no ]
    then
        print "    User declines the license agreement."
        rsf_exit 0
    fi

    rsf_get_option $show_lic_agree_var y_n \
        "Show this license agreement next time?"
    rsf_save_defaults
}

#------------------------------------------------------------------------
function rsf_no_license_exit
{
    print "
    You cannot install $Prod_Name_Ver
    without an existing license.  If you have a license server and you
    know the server name and the port number set LM_LICENSE_FILE and
    run $CMD again.

    # Users of csh, tcsh and other csh-compatible shells do this:
      setenv LM_LICENSE_FILE port@host
      (eg: setenv LM_LICENSE_FILE $def_lic_port@$HOST)

    # Users of sh, ksh, bash and other bourne-compatible shells do this:
      LM_LICENSE_FILE=port@host; export LM_LICENSE_FILE
      (eg: LM_LICENSE_FILE=$def_lic_port@$HOST; export LM_LICENSE_FILE)

    # Then rerun the command:
      $0 $CMD_OPTS"

    rsf_cleanup 2
}

#------------------------------------------------------------------------
function rsf_license_configured
{
    rsf_install_flexlm
    rsf_is_flexlm_installed lmstat local flexlm_dir Lic_Dir
    if [ $? -ne 0 ]
    then
        if ${rs_Req_Lic:-false}
        then
            rsf_no_license_exit
        else
            return 1
        fi
    fi
    print "\n    Checking if $rsu_product_name license is configured:"
    product_num_lic_chk=$rsu_product_num

    Use_existing_licenses=true
    rsf_create_lic_file_list

    # Make sure all of the items in the list are unique.
    unset New_lic_list
    for lic_file in $lic_file_list
    do
        print " $New_lic_list " | grep " $lic_file " >/dev/null && continue
        New_lic_list="$New_lic_list $lic_file"
    done
    lic_file_list=$New_lic_list
    unset New_lic_list lic_check_list all_licensed

    License_configured=0
    for rsu_lic_file in $(IFS=: ; echo $lic_file_list)
    do
        unset orig_lic_name
        # Use the port@host if this license needs a server.
        rsf_check_if_server_needed $rsu_lic_file
        if $Need_server
        then
            # If not a file, will leave rsu_lic_file as is.
            if rsf_extract_server_info this $rsu_lic_file
            then
                # This is a file and we have the port@host info.
                orig_lic_name=$rsu_lic_file
                rsu_lic_file=$this_lic_port@$this_lic_server
                unset this_lic_port this_lic_server
            fi
        fi

        # Do not check this again if already on the list.
        if [ -n "$lic_check_list" ]
        then
            case ":$lic_check_list:" in
            *:$rsu_lic_file:* ) continue ;;
            esac
        fi
        lic_check_list="$lic_check_list:$rsu_lic_file"

        unset Whats_licensed
        rsf_set_Whats_licensed "$Need_server" || break

        case $rsu_lic_file in
        *@* ) lic_type="Server" ;;
        *   ) lic_type="File" ;;
        esac

        # Check license score.  If it scored an A, use it now.
        # If it scored a B or C, remember it and use it if
        # we do not come across a license with a score of A.
        # The second list (A2, etc) might also contain the license file name.
        case "$License_score" in
        A )
            A_lic_list="$A_lic_list $rsu_lic_file"
            A2_lic_list="$A2_lic_list $rsu_lic_file $orig_lic_name"
            A_all_found="$A_all_found

    ${sul}$rsu_lic_file${eul} contains:$Licenses_found"
            ;;
        B )
            B_lic_list="$B_lic_list $rsu_lic_file"
            B2_lic_list="$B2_lic_list $rsu_lic_file $orig_lic_name"
            B_all_found="$B_all_found

    ${sul}$rsu_lic_file${eul} contains:$Licenses_found"
            ;;
        C )
            C_lic_list="$C_lic_list $rsu_lic_file"
            C2_lic_list="$C2_lic_list $rsu_lic_file $orig_lic_name"
            C_all_found="$C_all_found

    ${sul}$rsu_lic_file${eul} contains:$Licenses_found"
            ;;
        N )
            print "       no: $rsu_lic_file"
            continue
            ;;
        esac

        print "      yes: $rsu_lic_file"
        let License_configured=License_configured+1
        all_licensed="$all_licensed $Whats_licensed"
    done

    if [ $License_configured -gt 0 ]
    then
        # If there are multiple licenses, combine them into one list
        # and make that the default.  Use licenses with a better score (A)
        # before license with a lesser score (B,C).
        set -- $A_lic_list $B_lic_list $C_lic_list
        New_lic_list=$*
        Licenses_found="$A_all_found $B_all_found $C_all_found"
        Whats_licensed="$all_licensed"

        if [ $License_configured -eq 1 ]
        then
            rsu_lic_file=$New_lic_list
            case $rsu_lic_file in
            *@* )
                print "\n    Found one license server:$Licenses_found"
                _lic="this license server"
                ;;
              * )
                print "\n    Found one license file:$Licenses_found"
                 _lic="this license file"
                ;;
            esac
        else
            rsu_lic_file=$(print "$New_lic_list" | sed -e 's? ?:?g')
            print "
    Found $License_configured license configurations:$Licenses_found"
            if [ $License_configured -eq 2 ]
            then
                _lic="both sets of these licenses"
            else
                _lic="all $License_configured sets of these licenses"
            fi
        fi

        # Reset the new list to also include any license file names.
        set -- $A2_lic_list $B2_lic_list $C2_lic_list
        New_lic_list=$*

        unset A_lic_list A2_lic_list A_all_found
        unset B_lic_list B2_lic_list B_all_found
        unset C_lic_list C2_lic_list C_all_found
        unset lic_check_list all_licensed lic_file orig_lic_name

        yn_use_this_license=yes
        ${rs_Req_Lic:-false} && return 0
        rsf_get_option yn_use_this_license y_n \
            "Would you like to configure $rsu_product_name
    to use $_lic?"
        if [ "$yn_use_this_license" = yes ]
        then
            return 0
        fi

    elif ${Flexlm_install_problem:-false}
    then
        rsf_check_os_level flex
        rsf_cleanup 2

    else
        print "\n    No license found."
    fi

    if ${rs_Req_Lic:-false}
    then
        rsf_no_license_exit
    fi

    unset Whats_licensed Licenses_found Need_server
    return 1
}

#------------------------------------------------------------------------
function rsf_explain_lic_opt1
{
    print "\n${delim}
Option 1) USE AN EXISTING RATIONAL LICENSE

    Select this option if you already have licenses set up for this product.
    For example, you may have run rs_install or the license_setup command
    on another machine or set up the licenses manually.

    With a license server running, the preferred way to specify the
    licenses is by 'port@host'.  A port is the TCP/IP port number used
    by the license server on the license host.  You can also specify
    the licenses by entering the license file pathname.  If the
    licenses are temporary (uncounted, expire) you must specify the
    license file pathname."

    if [ -z "$SKN" ]
    then
        rsf_set_License_Key_List -a
    fi

    case $SKN in
    1 )
        print "
    This release requires that the following IBM Rational license feature is
    provided in the license file or is already being served from
    a license server:
         $Feature_List"
        ;;
    * )
        print "
    This release requires that one or more of the following IBM Rational license
    features is provided in the license file or is already being served from
    a license server:
         $Feature_List"
        ;;
    esac
}

#------------------------------------------------------------------------
function rsf_explain_lic_opt2
{
    print "\n${delim}
Option 2) SET UP A PERMANENT OR TERM-LICENSE-AGREEMENT (TLA) LICENSE

    Select this option if

       * You have received your permanent license key from IBM.
OR
       * You have received a TLA license from IBM.

    Note: You will only receive a .upd file if you have requested a
    license key from the Rational License Key Center (RLKC) web page.  If you do
    not have a license, visit the RLKC web page now.

    RLKC Web Address: $ACCT_LINK_URL

    You must have an IBM account number to get licenses from this
    web site.  Your account number can be found in the upper left box
    of the license key certificate that was included with the product.
    If you do not have a license key certificate, contact IBM at:

      $CONTACT_URL"

    if [ -f $DIR/$rs_Fax_License_Request ]
    then
        print "
    If you do not have web access, open this file in a web browser, fill
    it out, and fax it in.  The fax numbers are listed on the form:

    $DIR/$rs_Fax_License_Request"

    fi
}

#------------------------------------------------------------------------
function rsf_license_setup_options_menu
{
    if $License_setup_other
    then
        license_opt=2
        Set_rsu_lic_vars=true
        return 0
    fi

    if [ "$CMD" = rs_install -a "$Do_license_search" = true ]
    then
        $Go_back && return
        Use_existing_licenses=true
        prior_lic_file=$rsu_lic_file
        if rsf_license_configured
        then
            license_opt=1
            Use_existing_licenses=true
            Set_rsu_lic_vars=false
            rsf_check_flexlm_ver
            return 0
        fi
        rsu_lic_file=$prior_lic_file
        Use_existing_licenses=false
    fi

    def_license_opt=${def_license_opt:-e}
    while true
    do
        if [ "$rs_Install_Point_Products" = yes ]
        then
            rsf_menu_title $rsu_product_name - Licensing Options Menu
        else
            rsf_menu_title $rs_Suite_Name - Licensing Options Menu
        fi
        rsf_print_menu "" "
    Select one of the following 2 licensing options.

     1)  Use an existing IBM Rational license file (FLEXlm) or server for
         $rs_Suite_Name $rs_Suite_Ver.
     2)  Set up a permanent, term-license-agreement (TLA) license, or
         temporary file and server.  You need a .upd license file to import
         into $CMD.

     b)  Back to the previous menu.
     e)  Explain the licensing options in more detail.
     q)  $Quit_CMD"

        unset license_opt
        rsf_get_option license_opt mnb "Enter license option:"
        case $license_opt in
        1 )
            Use_existing_licenses=true
            Set_rsu_lic_vars=false
            return 0
            ;;
        2 )
            Set_rsu_lic_vars=true
            return 0
            ;;
        b )
            unset license_opt
            return
            ;;
        e|\? )
            unset def_license_opt
            if [ "$License_setup_other" = false ]
            then
                rsf_explain_lic_opt1
                rsf_pause TO see an explanation of option 2
            fi
            rsf_explain_lic_opt2
            rsf_pause TO return to the Licensing Options Menu
            ;;
        * )
            rsf_option_not_recognized "$license_opt" 2 beq
            ;;
        esac
    done
}

#------------------------------------------------------------------------
function rsf_do_uninstall
{
    rsf_menu_title Uninstalling Products
    if [ -n "$rsu_rational_dir" ]
    then
        if [ "$Okay_to_install" = false ]
        then
            print "
    You cannot completely uninstall $rs_Suite_Name
    while you are in this directory.

    To uninstall this product, do this:

      cd $rsu_rational_dir
      config/uninstall $rs_Suite_Dir $rs_Suite_Ver

    To list all products and select one for uninstall, do this:

      cd $rsu_rational_dir
      config/uninstall
"
            rsf_cleanup 99
        fi

        if [ -d $rsu_rational_dir -a -x $rsu_rational_dir/config/uninstall ]
        then
            cd $rsu_rational_dir
            print In $rsu_rational_dir

            if [ -d releases/$rs_Suite_Dir.$rs_Suite_Ver ]
            then
                print Running: config/uninstall $uninstall_opt \
                    $rs_Suite_Dir $rs_Suite_Ver
                config/uninstall $uninstall_opt $rs_Suite_Dir $rs_Suite_Ver &&
                    return 0
                rsf_cleanup 2
            fi

            # Check if there are any product directories in the releases dir.
            # If so, run the uninstall script without any options.
            for _pdir in releases/*.*
            do
                if [ -d $_pdir ]
                then
                    print Running: config/uninstall
                    config/uninstall
                    print "    uninstall returned status=$?"
                    return 0
                fi
            done
        fi
    fi

    print "\n    Uninstalling $rs_Suite_Name_Ver
    is not necessary when you have not yet done an install."
    rsf_cleanup 99
}

#------------------------------------------------------------------------
function rsf_perm_key_setup_menu
{
    if rsf_import_lic_data
    then
        # No need to ask for server name, license type, quantity, etc.
        # Can get this information from the imported file.
        Imported_licenses=true
        rsf_check_for_remote_server
        return
    fi
    Go_back=true
}

#------------------------------------------------------------------------
function rsf_set_remainder_steps
{
    if [ "$CMD" = license_setup ]
    then
        if [ "$prior_CMD" = rs_install ]
        then
            if $License_setup_other
            then
                StepLast=5
                return
            fi
            # Return to rs_install command since the licensing mode
            # has been changed.
            CMD=rs_install
        else
            StepLast=5
            return
        fi
    fi

    if $License_setup_other
    then
        # Switch to license_setup command, but remember
        # that we came from rs_install.
        prior_CMD=rs_install
        CMD=license_setup
        StepLast=5
        return
    fi

    if $Okay_to_install
    then
        Step6=rsf_typical_or_custom_menu
        if [ -d $DIR/docs ]
        then
            Step7=rsf_install_docs_menu
        else
            Step7=:
            rsu_install_docs=none
        fi
        Step8=rsf_customize_product_menu
        Step9=rsf_install_mode_menu
        Step10=rsf_do_install
        Step11=rsf_do_post_install
        Step12=rsf_create_setup_files
        StepLast=12
    else
        Step6=rsf_do_post_install
        Step7=rsf_create_setup_files
        StepLast=7
    fi
}

#------------------------------------------------------------------------
function rsf_Main
{
    Save_lic_parms=true
    case $CMD in
    rs_install )
        # Fall through
        ;;
    license_setup )
        if ${Running_remote:-false}
        then
            print "\n    Successfully logged into $HOST."
            rsf_start_license_server
            if [ -f $RM_LIST ]
            then
                . $RM_LIST
                /bin/rm -f $RM_LIST
            fi
            exit 0
        fi
        # Fall through
        ;;
    license_check )
        if [ -z "$rsu_product_num" ]
        then
            rsf_product_selection_menu
        else
            rsf_install_flexlm
            s=$rsu_product_num
            rsf_set_product_parameters
        fi
        rsf_license_check_menu
        rsf_cleanup $?
        ;;
    post_install )
        if [ -z "$rsu_product_num" ]
        then
            rsf_product_selection_menu
        else
            s=$rsu_product_num
            rsf_set_product_parameters
        fi
        rsf_do_post_install
        rsf_make_prod_links
        rsf_create_setup_files
        rsf_cleanup 0
        ;;
    uninstall )
        rsf_do_uninstall
        rsf_cleanup 0
        ;;
    * )
        if [ -f $DIR/$INSTALL/$CMD ]
        then
            . $DIR/$INSTALL/$CMD
        elif [ -f $DIR/$INSTALL/$CMD.pi ]
        then
            . $DIR/$INSTALL/$CMD.pi
        elif [ -f $DIR/$INSTALL/$CMD.ppi ]
        then
            . $DIR/$INSTALL/$CMD.ppi
        elif [ -f $DIR/$INSTALL/z$CMD.pi ]
        then
            . $DIR/$INSTALL/z$CMD.pi
        fi
        rsf_cleanup 0
        ;;
    esac

    Step0=rsf_welcome_menu
    if $Doc_install_only
    then
        if [ -z "$rsu_product_num" ]
        then
            print "
    You must first install a product from product CD before installing
    the documentation."
            rsf_cleanup 2
        fi

        s=$rsu_product_num
        rsf_set_product_parameters

        if [ ! -d "$Suite_Path" ]
        then
            print "
    $Suite_Path not found.

    You must first install a product from product CD before installing
    the documentation."
            rsf_cleanup 2
        fi
        test -f $Suite_Path/rs_help ||
             /bin/ln -s rs_install $Suite_Path/rs_help

        Step1=rsf_typical_or_custom_menu
        Step2=rsf_install_docs_menu
        Step3=rsf_customize_product_menu
        Step4=rsf_install_mode_menu
        Step5=rsf_misc_suite_install
        Step6=rsf_do_doc_install
        Step7=rsf_do_extras_install
        StepLast=7
        license_opt=9
    else
        Step1=rsf_product_selection_menu
        if $Enable_flexlm
        then
            Step2=rsf_license_setup_options_menu
        else
            Step2=:
        fi
    fi

    StepN=1
    Do_step=$Step1
    while [ -n "$Do_step" ]
    do
        : Do step $StepN: $Do_step
        eval $Do_step

        # Step 3, 4 and 5 depend on the licensing option chosen in step 2.
        # Need to define these steps after running step 2 which can
        # happen more than once if the installer backs up far enough.
        # That is why this logic has to be inside this loop.
        case "$yn_use_this_license-$StepN-$license_opt" in
        yes-* )
            # Using existing licensing in auto mode--license found and checked.
            # Therefore, will not do any license checking either.
            Step3=:
            Step4=:
            Step5=:
            rsf_set_remainder_steps
            ;;
        *-2-1 )
            # Using existing licensing.  Do not need to do permanent or
            # evaluation license setup (step 3).
            Imported_licenses=false
            Step3=:
            Step4=rsf_lic_file_menu
            Step5=rsf_license_check_menu
            rsf_set_remainder_steps
            ;;
        *-2-2 )
            # Set up permanent licenses.
            Step3=rsf_perm_key_setup_menu
            Step4=rsf_lic_file_menu
            Step5=rsf_license_check_menu
            rsf_set_remainder_steps
            ;;
        *-2-9 )
            ;;
        *-2-* )
            Imported_licenses=false
            Step3=:
            Step4=:
            Step5=:
            rsf_set_remainder_steps
            ;;
        esac

        if $Go_back
        then
            let StepN=$StepN-1
            test $StepN -lt 0 && StepN=0
            eval Do_step=\$Step$StepN
            while [ "$Do_step" = : ]
            do
                let StepN=$StepN-1
                eval Do_step=\$Step$StepN
            done
            if [ "$Do_step" = rsf_perm_key_setup_menu ]
            then
                # Since this step cannot be backed up from,
                # backup one more step.
                let StepN=$StepN-1
                eval Do_step=\$Step$StepN
            fi
        else
            let StepN=$StepN+1
            eval Do_step=\$Step$StepN
        fi
    done

    rsf_cleanup 0
}

#========================================================================
# MAIN: rs_install starts here.
#
# The rs_install command can download itself from the FTP server.  If it
# cannot update the copy of itself in the CDROM image directory it will
# put it in the /tmp directory.  The next time this script is run, it
# checks for this condition.  If there is a copy of rs_install in the
# /tmp directory, check if it is newer than the version of this script.
if [ "$FILE" != /tmp/rs_install -a \
     -f /tmp/rs_install -a \
     -f /tmp/rs_install.version ]
then
    . /tmp/rs_install.version
    if [ -n "$NEW_REV" ]
    then
        if [ "$NEW_REV" -gt "$RevN" ]
        then
            NEW_CMD=/tmp/rs_install
            # Run new rs_install command.
            print "Running newer version of $CMD (version 2.$NEW_REV):"
            set -x
            exec $BKSH $NEW_CMD -CMD $CMD ${1+"$@"}
            # Note: BKSH can be set to ksh or bash.
            exit $?  # Exec does not return. This command should not get run.
        fi
    fi
fi

# For all of these signals, run the cleanup routine and exit.
# Cannot trap on the KILL signal so do not bother listing it.
trap 'rsf_cleanup HUP'   HUP
trap 'rsf_cleanup INT'   INT
trap 'rsf_cleanup QUIT'  QUIT
trap 'rsf_cleanup ILL'   ILL
trap 'rsf_cleanup TRAP'  TRAP
trap 'rsf_cleanup ABRT'  ABRT
trap 'rsf_cleanup BUS'   BUS
trap 'rsf_cleanup SEGV'  SEGV
trap 'rsf_cleanup ALRM'  ALRM
trap 'rsf_cleanup TERM'  15
trap 'rsf_cleanup PWR'   PWR

# Need to ignore the following signals:
# WINCH: WINdow CHange (resizing a window)
trap WINCH

if [ "$PAGER" != more ]
then
    if rsf_not_on_path $PAGER
    then
        PAGER=more
    fi
fi

usage_error=0
while [ $# -gt 0 ]
do
    case $1 in
    -accept )
        accept_option=yes
        if [ "$m_option" = yes ]
        then
            print_e "$CMD: option '$1' cannot be used with the -m option."
            let usage_error=usage_error+1
        fi
        if [ -z "$2" ]
        then
            print_e "$CMD: You must specify the LA_PATH directory with the $1 option."
            let usage_error=usage_error+1
        else
            if [ ! -d "$2" ]
            then
                print_e "$CMD: $2 not found."
                let usage_error=usage_error+1
            else
                LA_PATH=$2
            fi
            shift
        fi
        ;;
    -agree )
        if [ -d extras/LAP ]
        then
            print_e "$CMD: You cannot use the '$1' option with extras/LAP."
            let usage_error=usage_error+1
        else
            rsu_show_lic_agree=no
            rsu_show_legal_info=no
        fi
        ;;
    -cdrom|-c|-dir|-d )
        DIR=$2
        if [ -z "$DIR" ]
        then
            print_e "$CMD: $1 option specified."
            print_e "$CMD: You must specify the CDROM directory with this option."
            rsf_usage 1
        elif [ ! -d $DIR ]
        then
            print_e "$CMD: $1 $2 option specified."
            print_e "$CMD: Cannot find $2."
            rsf_usage 1
        fi
        cd $DIR
        shift
        ;;
    -CMD )
        CMD=$2
        Quit_CMD="Quit $CMD.  Enter q! to quit without saving your inputs."
        shift
        ;;
    -force|-f )
        case $CMD in
        uninstall )
            uninstall_opt="$1"
            ;;
        * )
            print_e "$CMD: option '$1' not recognized."
            let usage_error=usage_error+1
            ;;
        esac
        ;;
    -help|-h )
        rsf_usage 0
        ;;
    -internal_help|-ih )
        rsf_internal_usage
        exit 0
        ;;
    -in_xterm )
        print "$CMD: Option '$1' is no longer supported."
        ;;
    -locale|-lo )
        case $2 in
        [a-z][a-z] )
            LC2=$2
            HELP_FILE=$I18N/help_file.$LC2
            if [ -f $HELP_FILE ]
            then
                if [ -f $I18N/welcome_file.$LC2 ]
                then
                    WELCOME_FILE=$I18N/welcome_file.$LC2
                fi
            else
                # Show there is no help file.  This ls will produce an error.
                /bin/ls $HELP_FILE
                print
                print "$CMD: There is no help file that matches the"
                print "            2-character locale extension '$LC2'."
                rsf_show_locales
                rsf_usage 1
            fi
            ;;
        * )
            print
            print "$CMD: Option $1 requires a 2-character locale extension"
            print "            to match the help_file in $INSTALL."
            rsf_show_locales
            rsf_usage 1
            ;;
        esac
        ;;
    -log )
        case $2 in
        -*|"" )
            print "$CMD: Option $1 requires a log file name."
            rsf_usage 1
            ;;
        esac
        LOG_FILE=$2
        if [ -d $LOG_FILE ]
        then
            if [ -w $LOG_FILE ]
            then
                # The user specified a directory.
                # Set the log file to be the log name in this directory.
                LOG_FILE=$LOG_FILE/$LOG_NAME
            else
                print "$CMD: You specified a directory as the log file name."
                print "$CMD: The directory is not writable by you."
                rsf_usage 1
            fi
        fi
        LOG_NAME=${LOG_FILE##*/}
        shift
        ;;

    -netscape|-ns )
        print "$CMD: Option '$1' is no longer supported."
        ;;
    -no_clear|-nc )
        print "$CMD: Option '$1' is no longer supported."
        ;;
    -no_help|-nh )
        print "$CMD: Option '$1' is no longer supported."
        ;;
    -no_underlining|-nu )
        Do_underling=false
        ;;
    -no_log|-nl )
        unset LOG_FILE
        ;;
    -no_save|-nos )
        Save_defaults=false
        ;;
    -no_xterm|-nx )
        print "$CMD: Option '$1' is no longer supported."
        ;;
    -pdf )
        print "$CMD: Option '$1' is no longer supported."
        ;;
    -playback|-play|-p )
        case $2 in
        -*|"" )
            print_e "$CMD: option '$1' requires a playback file."
            let usage_error=usage_error+1
            ;;
        /* )
            if [ ! -f $2 ]
            then
                print_e "$CMD: Playback file '$2' not found."
                let usage_error=usage_error+1
            else
                Play_back=$2
            fi
            shift
            ;;
        * )
            if [ ! -f $2 ]
            then
                print_e "$CMD: Playback file '$2' not found."
                let usage_error=usage_error+1
            else
                Play_back=$(pwd)/$2
            fi
            shift
            ;;
        esac
        Load_defaults=false
        Save_defaults=false
        rsu_show_lic_agree=no
        rsu_show_legal_info=no
        RSI_PLAY_BACK=$Play_back
        export RSI_PLAY_BACK
        ;;
    -record|-rec )
        case $2 in
        -*|"" )
            DATE_TIME=$(date '+%Y.%m.%d-%H:%M')
            if [ -n "$HOME" ]
            then
                if [ -w $HOME ]
                then
                    Record_in=$HOME/$CMD.record.$DATE_TIME
                else
                    Record_in=/tmp/$CMD.record.$USER.$DATE_TIME
                fi
            else
                Record_in=/tmp/$CMD.record.$USER.$DATE_TIME
            fi
            ;;
        /* )
            Record_in=$2
            shift
            ;;
        * )
            Record_in=$(pwd)/$2
            shift
            ;;
        esac
        /bin/rm -f $Record_in
        touch $Record_in
        if [ $? -ne 0 -o ! -f $Record_in ]
        then
            print_e "$CMD: Cannot create or update record file:"
            print_e "$CMD:   $Record_in"
            let usage_error=usage_error+1
        fi
        Load_defaults=false
        Save_defaults=false
        rsu_show_lic_agree=no
        rsu_show_legal_info=no
        RSI_RECORD_IN=$Record_in
        export RSI_RECORD_IN
        ;;
    -remote )
        Running_remote=true
        Skip_OS_check=true
        Remote_id="$2"
        batch_mode=yes
        unset LOG_FILE
        Do_underling=false
        shift
        ;;
    -reset|-re )
        Load_defaults=false
        ;;
    -rsf_* )
        # IBM Rational internal-use-only option.
        func=${1#-}
        shift
        $func ${1+"$@"}
        exit
        ;;
    -save )
        save_option=yes
        if [ "$accept_option" = yes ]
        then
            print_e "$CMD: option '$1' cannot be used with the -accept option."
            let usage_error=usage_error+1
        fi
        case $2 in
        -*|"" )
            print_e "$CMD: option '$1' requires a LA_PATH directory."
            let usage_error=usage_error+1
            ;;
        /* )
            if [ ! -d "$2" ]
            then
                print_e "$CMD: LA_PATH directory '$2' not found."
                let usage_error=usage_error+1
            elif [ ! -w "$2" ]
            then
                print_e "$CMD: LA_PATH directory '$2' is not writable."
                let usage_error=usage_error+1
            else
                LA_PATH=$2
            fi
            shift
            ;;
        * )
            print_e "$CMD: LA_PATH '$2' must be a fully-qualified directory."
            let usage_error=usage_error+1
            shift
            ;;
        esac
        ;;
    -setvar )
        Setvars=yes
        varlist="$varlist $2"
        eval $2
        shift
        ;;
    -size )
        unset LOG_FILE
        rsf_set_INI_FILE
        rsf_build_product_sizes
        rsf_exit 0
        ;;
    -skip_license|-sl )
        Do_license_search=false
        ;;
    -trace|-x )
        rsf_turn_tracing on
        set -x
        ;;
    -v* ) # -version
        echo $FILE:
        grep "^#@.#." $FILE | sed -e "s?#@.#.?$TAB?"
        exit 0
        ;;
    -xterm|-xt  )
        print "$CMD: Option '$1' is no longer supported."
        ;;
    +xterm|+xt  )
        print "$CMD: Option '$1' is no longer supported."
        ;;
    -* )
        if [ "$batch_mode" = yes ]
        then
            opt_var=${1#-}
            eval $opt_var=\"$2\"
            shift
        else
            print_e "$CMD: option '$1' not recognized."
            let usage_error=usage_error+1
        fi
        ;;
    * )
        break
        ;;
    esac
    shift
done
test $usage_error -gt 0 && rsf_usage 1

if [ -z "$HELP_FILE" ]
then
    # This function sets the help file if the -locale option was not used.
    rsf_set_help_file
fi

if [ "${rs_Auto_Help:-false}" = false ]
then
    Help_Option3="\n   ?)  Help."
    Help_Option4="\n    ?)  Help."
    Help_Option5="\n     ?)  Help."
    Help_Option6="\n      ?)  Help."
    Help_Option10="\n          ?)  Help."
fi

if [ -n "$LOG_FILE" ]
then
    function rsf_log_input
    {
        test -s "$LOG_FILE" || return
        eval _log_option=\$log_$Option_Name
        if ${_log_option:-true}
        then
            if ${Logging_started:-false}
            then
                echo "$1" >> $LOG_FILE
            else
                echo "$2 $1" >> $LOG_FILE
            fi
        fi
        unset log_$Option_Name _log_option
    }

    function rsf_buffer_screen
    {
        ${Logging_started:-false} || return
        $Repaint && return
        Repaint=true
        _sl=$(grep -n "^------" $LOG_FILE | tail -1)
        if [ -n "$_sl" ]
        then
            _sl=${_sl%%:*}
        else
            _sl=1
        fi
        Buffered_screen=$(sed -e "1,${_sl}d"  -e '$d' $LOG_FILE)
        unset _sl
    }
else
    function rsf_log_input
    {
        return
    }
    function rsf_buffer_screen
    {
        return
    }
fi

rsf_set_arch_os

# Load default values.
if [ -f $SUITE_DESCRIPTION ]
then
    . $SUITE_DESCRIPTION
    DIR=$(rsf_normalize_dir $(pwd))
    if [ -f $SUITE_DESCRIPTION.$sys ]
    then
        . $SUITE_DESCRIPTION.$sys
    elif [ -z "$support_OS_list" ]
    then
        for _sys in $SYS_LIST
        do
            if [ -f $SUITE_DESCRIPTION.$_sys ]
            then
                . $SUITE_DESCRIPTION.$_sys
                if [ -n "$support_OS_list" ]
                then
                    new_support_OS_list="$new_support_OS_list
                    $support_OS_list"
                    unset support_OS_list
                fi
            fi
        done
        support_OS_list="$new_support_OS_list"
    fi
else
    DIR=$(rsf_normalize_dir "$(cd $(dirname $FILE); pwd)")
    cd $DIR
    if [ -f $SUITE_DESCRIPTION ]
    then
        . $SUITE_DESCRIPTION
        if [ -f $SUITE_DESCRIPTION.$sys ]
        then
            . $SUITE_DESCRIPTION.$sys
        fi
    else
        print_e "
    Could not find $CMD data.
    Looked in $DIR/$SUITE_DESCRIPTION
     and  in  $SUITE_DESCRIPTION\n"
        rsf_usage 1
    fi
fi
rs_vendor_name="IBM Corporation"
rs_vendor="IBM"

rsf_set_install_flags
rsf_check_os_level $CMD

DOC_SIZES=$DIR/docs/.sizes
NODE_LOCK_AGREEMENT=$DIR/$INSTALL/node_lock_agreement
LICENSE_PACKAGE=$DIR/$LICENSE_PACKAGE
EXTRA_LICENSE=$DIR/$EXTRA_LICENSE

rsf_set_INI_FILE

rsf_set_banner

if [ "$batch_mode" = no ]
then
    if [ "$USER" = root ]
    then
        print "
    You are logged into $HOST as root.
    Are you sure you want to run $CMD as root?"

        rsf_pause TO_E continue $CMD as root, q to quit
    fi
fi

rsf_set_misc ""
rsf_set_LINES

if [ "$batch_mode" = no ]
then
    rsf_welcome_menu
    if [ -f README.relnote ]
    then
        $PAGER README.relnote
        rsf_pause
    fi
fi
rsf_set_defaults
rsf_select_rational_dir
rsf_read_defaults
rsf_set_path
rsf_set_options_file

if [ "$CMD" = options_setup ]
then
    while true
    do
        rsf_options_setup_menu
        Go_back=false
        rsf_license_check_menu
        $Go_back || rsf_exit 0
    done
fi

if [ "$batch_mode" = no  -a  -z "$Play_back" ]
then
    case $CMD in
    rs_install|license_setup )
        rsf_license_agreement_menu
        ;;
    esac
fi

if [ -n "$LOG_FILE" ]
then
    Logging_started=true
    # Start with a clean log file (if it is the default one in /tmp)
    /bin/rm -f $DEF_LOG_FILE
    (
    print "User: $USER"
    print "Date: $(date)"
    print "Host: $(uname -a)"
    if [ -n "$linuxRel" ]
    then
        print "Rel:  $linuxRel"
    fi
    print "Dir:  $DIR"
    print "Cmnd: $CMD $CMD_OPTS"
    print "Vers: $REV"
    print "Ratl: $rsu_rational_dir"
    if [ -n "$acceptLicMesg" ]
    then
        print LicA: $acceptLicMesg
    fi
    echo "${delim}"
    ) >> $LOG_FILE
    rsf_Main 2>&1 | tee -a $LOG_FILE
    # Remove the log file if it is empty.  It has been moved.
    test -s $LOG_FILE || /bin/rm -f $LOG_FILE
else
    rsf_Main
fi

# End of rs_install.
