DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400 Tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400 Tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T d

⟦7ca04e961⟧ TextFile

    Length: 47507 (0xb993)
    Types: TextFile
    Names: »do_install«

Derivation

└─⟦1e97d88e5⟧ Bits:30000533 8mm tape, Rational 1000, RATIONAL ASIS (AIX) 110.2.4.15
    └─⟦this⟧ »./releases/asis.110.2.4.15/install/do_install« 

TextFile

#! /bin/sh
# @(#)do_install  $Revision: 1.39 $  $Date: 1994/01/24 16:45:47 $
# @(#)Copyright(c) 1993,1994 by Rational.
#
#  MODULE SPECIFICATION
#  Name:
#    do_install
#
#  Subsystem:
#    install
#
#  Description:
#    Load from the product from tape or disk.
#
#-----------------------------------------------------------------

umask 002

#=================================================================
# query shell functions:
#=================================================================

#-----------------------------------------------------------------
user_group_ok_query() {
#-----------------------------------------------------------------
#
# Ask if the current user and group are ok
#
# takes no arguments
#
# set globals: user_group_ok (yes,no), this_user, this_group

    user_group_test=user_group_test.$$
    add_cleanup_file $user_group_test
    /bin/rm -fr $user_group_test
    touch $user_group_test
    this_user=`ls -ld $user_group_test|awk '{print $3}'`

    if [ `ls -ldg $user_group_test|wc -w` -eq 8 ]
    then
        this_group=`ls -ldg $user_group_test|awk '{print $3}'`
    else
        this_group=`ls -ldg $user_group_test|awk '{print $4}'`
    fi

    fmt_mesg "When files are created they will be owned by '$this_user'
              with group set to '$this_group'."
    get_yn "Is this ok?" yes

    user_group_ok="$result"
    if [ "$user_group_ok" = no ]
    then
        fmt_mesg "Please log on as a user that has the user name and
                  group that you want the files created by this script to
                  have, then restart the installation process."
        exit 1
    fi
}

#-----------------------------------------------------------------
check_block_factor() {
#-----------------------------------------------------------------
#
# Check block factor for tape drives on AIX machines.  Must be 0.
#

    if [ "$device_arch" = rs6k ]
    then
        tape_name=`basename $device | awk -F. '{print $1}'`
        # set arg 2 = block size
        set -- `$remote /etc/lsattr -l $tape_name -E | grep block_size`
        if [ $? -eq 0 ]
        then
            # Check block factor (arg 2)
            if [ "$2" != 0 ]
            then
                echo "The blocking factor for $device_host's $tape_name is $2, should be 0."
                echo "Use smit on $device_host to set the blocking factor."
                return 1
            else
                # Block factor okay.
                return 0
            fi
        else
            # tape_name not found in the device configuration database
            return 1
        fi
    else
        # No need to check block factor on systems other than AIX.
        return 0
    fi
}

#-----------------------------------------------------------------
check_dir_name() {
#-----------------------------------------------------------------
# Check that directory name ends in required_part
#
# arg1:   dir_name
# arg2:   required_part
#
# return: 0 = okay
#         1 = dir_name does not end with required_part
#

    dir_name=$1
    required_part="$2"
    if echo $dir_name | grep "$required_part\$" >/dev/null
    then :
    else
        echo "The directory needs to end in '$required_part'"
        return 1
    fi
    return 0
}


#-----------------------------------------------------------------
check_group_id() {
#-----------------------------------------------------------------
# Check that a directory and its sub-directories has the set-group-ID
# set on it.
#
# arg1: Directory to check.
#

    if [ ! -g $1 ]
    then
        if chmod g+s $1
        then
            return
        else
            fmt_mesg "The directory $1 must have the group-id bit set.
                      $command tried to set them using 'chmod g+s' and failed.
                      You must be the owner of the directories.  Refer to the
                      Installation Steps in the Installation Guide."
            exit 1
        fi
    fi
}


#-----------------------------------------------------------------
check_prerequisites() {
#-----------------------------------------------------------------

    case $feature in
        apex|rose|soda )
            ;;
        * )
            # Determine if a prerequisite version of Apex is installed for
            # this version of feature.
            apex_list=`grep "^$feature.$product_version" \
                       $install_dir/version_map |
                       sed -e "s/$feature.$product_version//"`
            for apex_version in $apex_list
            do
                # Determine if this version of Apex is installed.
                if [ -d $rational_dir/releases/$apex_version ]
                then
                    return $TRUE
                fi
            done

            fmt_mesg "Before installing $product_name version
                $product_version you need to have one of
                these versions of Rational Apex installed: $apex_list"
            exit 1
            ;;
    esac

}


#-----------------------------------------------------------------
tape_disk_query() {
#-----------------------------------------------------------------
# Ask which device to use.  Assume the device is a tape unless the
# device name contains the string '/rfd' or '/fd'.
#
# Sets global variable dev, ndevice
#

    device=${device:-$device_default}
    ndevice=${ndevice:-$ndevice_default}
    device_restore=$device

    while true
    do
        get_input "Enter $device_kind device:" $device
        device="$result"
        if echo $device | egrep "/rfd|/fd" >/dev/null
        then
            device_kind=disk
            Device_Kind=Disk
            ndevice=$device
            break
        else
            device_kind=tape
            Device_Kind=Tape
            if check_block_factor
            then
                get_input "Enter no-rewind tape device:" $ndevice
                ndevice="$result"
                break
            else
                get_yn "Do you want to re-enter a tape device?" no
                if [ "$result" = no ]
                then
                    exit 1
                fi
                device=$device_restore
            fi
        fi
    done

    save_defaults device
    save_defaults ndevice
}

#-----------------------------------------------------------------
host_query() {
#-----------------------------------------------------------------
#
# Ask about the device host.
#
# Sets global (at the moment):
# device_host, remote, device_arch, device_default, ndevice_default
#

    fmt_mesg "If your $device_kind drive is attached to some other machine,
              then enter the name of the remote host.
              If you enter the name of this machine (the default), then install
              will use the $device_kind drive mounted on this machine."

    get_input "$device_kind host name:" $device_host
    device_host="$result"


    if [ "$device_host" = "$HOSTNAME" ]
    then
        device_sys_name=$SYS_NAME
        remote=
    else
        echo "Checking remote host architecture."
        remote="rsh $device_host -n"
        device_sys_name=`$remote /bin/uname -s`
    fi


    if [ $device_kind = disk ]
    then
        device_default=/dev/rfd0
        ndevice_default=/dev/rfd0
        case $device_sys_name in
            SunOS)
                device_arch=sun4
                ;;
            AIX)
                device_arch=rs6k
                ;;
            *)
                device_arch=UNKNOWN
                warn "$device_host $device_sys_name architecture unknown"
                ;;
        esac
    else
        case $device_sys_name in
            SunOS)
                device_arch=sun4
                device_default=/dev/rst0
                ndevice_default=/dev/nrst0
                ;;
            AIX)
                device_arch=rs6k
                device_default=/dev/rmt0.4
                ndevice_default=/dev/rmt0.5
                ;;
            *)
                device_arch=UNKNOWN
                device_default=/dev/tape0
                ndevice_default=/dev/ntape0
                warn "$device_host $device_sys_name architecture unknown"
                ;;
        esac
    fi

    save_defaults device_host
    save_defaults device_arch
}

#-----------------------------------------------------------------
verbose_query() {
#-----------------------------------------------------------------
#
# Ask if we should print file names as they are loaded.
#
# takes no arguments
#
# set globals: verbose (yes,no), vop (v,"")
#

    fmt_mesg "By default, install displays the path name of each file that
              is read off of the $device_kind. If you like, you can suppress the
              verbose output."

    get_yn "Display file names during load?" $verbose
    verbose="$result"
    if [ "$verbose" = yes ]
    then
        vop=v
    else
        vop=
    fi
    save_defaults verbose
}

#-----------------------------------------------------------------
prod_home_query() {
#-----------------------------------------------------------------
#
#  Ask about the product home hierarchy parent directory and make it.
#
# takes no arguments
#
# sets global more, prod_home
#

    if [ -n "$feature_base" ]
    then
        fmt_mesg "There are two locations of interest to this $command
            program.  The first is the parent directory of the install
            directory, which is referred to as the 'Release Directory'.
            The second location is called the 'Rational Base Library
            Directory'."
    
        fmt_mesg "You get new files in the 'Release Directory' with each
            new release from Rational. If you want to keep more than one
            version of this product around at a time, you can put
            different releases in different directories. On the other
            hand, the 'Rational Base Library Directory' will be the same
            for all releases of this product."
    
        fmt_mesg "It is important that the answer you provide for the
            'Release Directory' and especially the 'Rational Base Library
            Directory' are 'permanent name' paths. A 'permanent name'
            path is one that will work from any machine. Thus, an
            automount path like '/tmp_mnt/rational/base' is NOT a
            'permanent name' path because you cannot change directory to
            that path on any machine."
    
        fmt_mesg "The default answers for the following questions are
            computed from the result of 'pwd' (print working directory),
            which generally does NOT produce the 'permanent name' of a
            directory."
    else
        prod_base=N/A

        fmt_mesg "You will be asked to input the name of the 'Release
            Directory' to use for restoring $product_name files. This is
            typically the parent directory of the install directory."

        fmt_mesg "You get new files in the 'Release Directory' with each
            new release from Rational. If you want to keep more than one
            version of this product around at a time, you can put
            different releases in different directories."

        fmt_mesg "It is important that the answer you provide for the
            'Release Directory' is a 'permanent name' path. A 'permanent
            name' path is one that will work from any machine. Thus, an
            automount path like '/tmp_mnt/rational/releases' is NOT a
            'permanent name' path because you cannot change directory to
            that path on any machine."
    fi

    while true
    do
        get_input "Release Directory:" "$prod_home"
        prod_home="$result"
        if check_dir_name $prod_home releases/$feature.$product_version
        then
            if mk_prod_dir $NO $prod_home
            then
                break
            else
                continue
            fi
        else
            continue
        fi
    done

    if [ -z "$release_dir"  ]
    then
        release_dir=`dirname $prod_home`
    fi

    if [ -z "$rational_dir" ]
    then
        case $feature in
            apex|rose )
                rational_dir=`dirname $release_dir`
                ;;
            * )
                # For layered products, set rational dir based on APEX_HOME
                if [ -z "$APEX_HOME" ]
                then
                    get_input "Enter APEX_HOME:"
                    APEX_HOME=$result
                    export APEX_HOME
                fi

                rational_dir=`dirname $APEX_HOME`
                if [ "`basename $rational_dir`" = releases ]
                then
                    rational_dir=`dirname $rational_dir`
                fi
                ;;
        esac
    fi

    if [ -z "$prod_base"    ]
    then
        prod_base=$rational_dir/base
    fi

    check_group_id $rational_dir

    if [ "$prod_base" != N/A ]
    then
        while true
        do
            get_input "Rational Base Library Directory:" "$prod_base"
            prod_base="$result"
            if check_dir_name $prod_base base
            then
                if mk_prod_dir $NO $prod_base
                then
                    get_free_kbytes $prod_base
                    if [ $base_size -gt $free_kbytes ]
                    then
                        echo "Not enough space on $prod_base:"
                        echo "    need $base_size"
                        echo "    have $free_kbytes"
                    else
                        update_fs_size $base_size
                        break
                    fi
                fi
            fi
        done
    fi

    check_prerequisites

    # Set .Rational_location on each dir_name
    # Save new defaults.
    cpath_status=0
    cpath_err_msg="Cannot set Rational location on:"

    for dir_name in prod_home prod_base release_dir rational_dir
    do
        eval dir=\$$dir_name
        if [ $dir = N/A ]
        then
            continue
        fi

        if set_cpath -f $dir $dir
        then
            save_defaults $dir_name
        else
            cpath_status=$?
            if [ -n "$cpath_err_msg" ]
            then
                echo "$cpath_err_msg"
            fi
            echo "  $dir"
            cpath_err_msg=
        fi
    done

    if [ $cpath_status -ne 0 ]
    then
        fatal "Check that these directories exists and that user and
            group write permissions are set."
    fi
}

#-----------------------------------------------------------------
cmp_home_query() {
#-----------------------------------------------------------------
#
# Ask about the component storage directory and make it - may be
# different than product home directory.
#
# arg1: comp_dir
# arg2: component size in kbytes
#
# set globals: more, cmp_home
#

    comp_dir=$1
    kbytes_size=$2
    more=1
    while [ $more -eq 1 ]
    do
        if [ $component_root = "$feature_base" ]
        then
            # Cannot put base subsystems/views in a directory other than
            # comp_dir for now.
            cmp_home=$comp_dir
            return
        else
            get_input "Component storage directory:" "$comp_dir"
            cmp_home="$result"
        fi

        if [ ! -d "$cmp_home" ]
        then
            fmt_mesg "The $cmp_home directory does not exist."
            get_yn "Do you want to make the directory now?" no
            if [ $result = yes ]
            then
                if mkdir_p $cmp_home
                then :
                else
                    continue
                fi
            else
                continue
            fi
        fi

        get_free_kbytes $cmp_home

        if [ $kbytes_size -gt $free_kbytes ]
        then
            echo "Not enough space on $cmp_home:"
            echo "    need $kbytes_size"
            echo "    have $free_kbytes"
            more=1
        elif [ "$cmp_home" != "$comp_dir" ]
        then
            mk_prod_dir $YES $cmp_home
            more=$?
        else
            more=0
        fi
    done
    update_fs_size $kbytes_size
}

#-----------------------------------------------------------------
update_fs_size() {
#-----------------------------------------------------------------
#
# Update the remaining Kbytes free for the Filesystem the component
# is installed on
#
# arg1: component size
#
# Note: get_free_bytes sets Filesystem, free_kbytes
#

    # Set free_after: Kbytes free, after doing the component install.
    free_after=`expr $free_kbytes - $1`

    # Update fs_sizes Filesystem entry
    if grep "$Filesystem" $fs_sizes >/dev/null
    then
        # Save the free_after value for next component.
        sed -e "s?.* $Filesystem?$free_after $Filesystem?" $fs_sizes \
            > /tmp/free_kbytes.$$
        mv /tmp/free_kbytes.$$ $fs_sizes
        return
    fi

    # Create fs_sizes entry for Filesystem
    # Save the after value for next component.
    echo $free_after $Filesystem >> $fs_sizes
}

#-----------------------------------------------------------------
get_free_kbytes() {
#-----------------------------------------------------------------
#
# Set free_kbytes: Kbytes free, before doing the component install.
#
# arg1: filesystem's directory
#

    fs_dir=$1
    set -- `df $fs_dir | tail -1`
    eval Filesystem=\$$#

    if grep "$Filesystem" $fs_sizes >/dev/null
    then
        set -- `grep "$Filesystem" $fs_sizes`
        free_kbytes=$1
        return
    fi

    case $ARCH in
        sun4) shift `expr $# - 3`; free_kbytes=$1 ;;
        rs6k) free_kbytes=$3 ;;
    esac
}


#-----------------------------------------------------------------
queries() {
#-----------------------------------------------------------------
#
# Ask about the tape/disk load parameters. (answers saved in defaults file
# by various *_query functions)
#
# takes no arguments
#
# set global: more
#

    # Save old defaults file until new one is complete
    if [ -s $install_defaults ]
    then
        mv $install_defaults $install_defaults.sav
        add_cleanup_func restore_defaults
    fi
    user_group_ok_query

    more=1
    while [ $more -eq 1 ]
    do
        separator
        echo
        if [ $device_kind = tape ]
        then
            echo "                              Tape Load Dialog"
            echo "                              ----------------"
        elif [ $device_kind = disk ]
        then
            echo "                              Disk Load Dialog"
            echo "                              ----------------"
        else
            echo "                              Network Load Dialog"
            echo "                              -------------------"
        fi

        cp /dev/null $install_defaults
        host_query

        if [ $device_kind = net ]
        then
            device_kind=net
            Device_Kind=Net
            save_defaults device
            save_defaults ndevice
        else
            tape_disk_query
        fi

        verbose_query
        prod_home_query

        separator
        echo "Your answers were:"
        echo "    $Device_Kind Host:          $device_host"
        echo "    $Device_Kind Device:        $device"
        if [ $device_kind = tape ]
        then
            echo "      (no rewind)       $ndevice"
        fi
        echo "    Verbose:            $verbose"
        echo
        echo "    Release Directory:"
        echo "        $prod_home"

        if [ $prod_base != N/A ]
        then
            echo
            echo "    Base Directory:"
            echo "        $prod_base"
        fi

        ask_ok
    done
    /bin/rm -f $install_defaults.sav
}


#=================================================================
# Tape operation functions.
#=================================================================

#-----------------------------------------------------------------
set_tape() {
#-----------------------------------------------------------------
#
# Figure out the name of the "no rewind" tape. Move tape to second
# tar file on the tape. (The one after the one that contains this
# installation script.)
#
# takes no arguments
#
# sets globals: tape_position, vop, tape, ntape,
#

    tape_position=999

    #  Determine the tape devices for auto-rewind and no-rewind modes.

    separator
    if [ "$device_host" != "$HOSTNAME" ]
    then
        echo "Reading from $device on $device_host."
    else
        echo "Reading from $device."
    fi

    #  Skip the first tape file. (The file that contained this script.)

    rew_tape
    fsf_tape 1
}

#-----------------------------------------------------------------
rew_tape() {
#-----------------------------------------------------------------
#
# Rewind the tape.
#
# takes no arguments
#
# sets global: tape_position
#

    echo "$remote mt -f $device rewind"
    sleep 10
    $remote mt -f $device rewind

    #  Make sure this worked.

    if [ $? -ne 0 ]
    then
        fmt_mesg "Tape rewind failure.  Is $device a valid device name?
                  Is the tape loaded?  If $device_host is a machine other
                  than $HOSTNAME, is it a valid machine name?
                  Do you have rsh permission?
                  Product tape load cancelled."
        exit 1
    fi
    tape_position=0
}

#-----------------------------------------------------------------
fsf_tape() {
#-----------------------------------------------------------------
#
# Skip forward over tape files
#
# argument 1: number of tape files to skip forward
#
# sets global: tape_position
#

    echo "$remote mt -f $ndevice fsf $1"
    sleep 10
    $remote mt -f $ndevice fsf $1
    if [ $? -ne 0 ]
    then
        fmt_mesg "Tape forward failure.
                  Is $device still on line?
                  Is the product tape still loaded?
                  Product tape load cancelled."
        exit 1
    fi
    tape_position=`expr $tape_position + $1`

}

#-----------------------------------------------------------------
read_tape() {
#-----------------------------------------------------------------
#
# Move the tape to the correct position.
# Extract contents of tape.  Contents are [un]compressed tar files.
#
# arg1: tape position of component
# arg2: location to extract into (cd $2)
# arg3: files to extract (all files if arg3 is null)
#
# sets globals: need_rewind, tape_position
#

    # Check if component location is in a list of components to skip.
    for cmp_to_skip in $skip_components
    do
        if [ "$1" = "$cmp_to_skip" ]
        then
            return
        fi
    done

    #  Read Product.

    if [ $tape_position -gt $1 ]
    then
        set_tape
    fi

    while [ $tape_position -lt $1 ]
    do
        fsf_tape 1
    done

    need_rewind=yes

    sleep 10
    (cd $2
    if [ $compress = no ]
    then
        $remote dd if=$ndevice ibs=126b obs=2520b | \
            tar x${vop}pBf - $3
    else
        $remote dd if=$ndevice ibs=126b obs=2520b | \
            uncompress | tar x${vop}pBf - $3
    fi
    )

    if [ $? -ne 0 ]
    then

        fmt_mesg "Load failure. Product may have been partially loaded,
                  or not loaded at all. You should delete the files just
                  installed and attempt the install again. The problem may
                  have been due to:"

        echo "
    * Insufficient disk space.
    * Incorrect permissions on the product directory.
    * If you are using links to distribute the Product components,
      the link may be wrong or the directory to which the link
      points may not exist.
    * Tape read error.
    * If the tape drive is remote, a failure on the remote machine."

        get_yn "Do you want to try again?" yes
        if [ "$result" = yes ]
        then
            rew_tape
            read_tape $1 $2 $3
        else
            exit 1
        fi

    fi
    need_rewind=no
    tape_position=`expr $tape_position + 1`

}

#-----------------------------------------------------------------
do_tape_loads() {
#-----------------------------------------------------------------

    # Ready the installation tape
    set_tape

    cmps_loaded=$check_limit
    this_extract=1
    while [ $this_extract -le $cur_extract_count ]
    do
        eval component_loc=\$component_loc_$this_extract
        eval cmp_home=\$component_home_$this_extract
        eval prod_root=\$prod_root_$this_extract
        eval component_desc=\$component_desc_$this_extract
        eval component_indx=\$component_indx_$this_extract
        eval DO=\$component_do_$this_extract

        if [ "$verbose" = yes ]
        then
            separator
        fi
    
        fmt_mesg "${DO}ing $component_desc on $cmp_home"
        read_tape $component_loc $cmp_home ""

        if [ "$cmp_home" != "$prod_root" ]
        then
            mk_links $prod_root $cmp_home
        fi

        # update install database that component has been loaded
        cmps_loaded=`expr $cmps_loaded + 1`
        put_var "${component_indx}_${cmps_loaded}" "$component_desc"
        put_var "${component_indx}_LOADED" "$cmps_loaded"

        this_extract=`expr $this_extract + 1`
    done
}


#=================================================================
# Various other shell functions
#=================================================================

#-----------------------------------------------------------------
mk_prod_dir() {
#-----------------------------------------------------------------
#
# Check and create a product installation directory. If dir exists,
# ask user if they want to remove contents.
#
# arg 1: flag to verify if directory already exists and is not empty.
# arg 2: directory to create (or clean)
#
# sets global: ret_status
#
# returns non-zero for failure
#

    ret_status=0
    check_dir=$1
    prod_dir=$2
    base_dir=`basename $prod_dir`

    if [ -n "$installing_specific_files" ]
    then
        installation_status=`get_var INST_STATUS`
        if [ "$installation_status" -ne COMPLETED ]
        then
            fmt_mesg "Installation of specific files is only allowed after
                      the product installation has been completed."
            ret_status=1
        fi
        return $ret_status
    fi

    rmdir $prod_dir 2>/dev/null
    if [ -d $prod_dir  -a  $check_dir -eq $YES ]
    then
        # Ignore 'install' and '.Rational_Location' dirs
        file_dir_list=`/bin/ls -A $prod_dir 2>/dev/null | grep -v install |
                       grep -v '\.Rational_Location'`
        if [ -n "$file_dir_list" ]
        then
            fmt_mesg "The directory $prod_dir exists and is not empty:"
            echo "$file_dir_list" | sed -e "s/^/    /g" | more

            get_yn "Do you want to DELETE contents" no
            if [ "$result" = yes ]
            then
                fmt_mesg "Cleaning up files and directories.  This may take
                          a while."
                for rm_file in $file_dir_list
                do
                    if [ -d $prod_dir/$rm_file ]
                    then
                        chmod -R +w $prod_dir/$rm_file
                        /bin/rm  -r $prod_dir/$rm_file
                    else
                        chmod +w $prod_dir/$rm_file
                        /bin/rm  $prod_dir/$rm_file
                    fi

                    if [ $? -ne 0 ]
                    then
                        touch /tmp/mk_prod_dir.$$
                        add_cleanup_file /tmp/mk_prod_dir.$$
                    fi
                done
            else
                echo "Then you must select another directory which is empty."
                ret_status=1
            fi
        fi
    fi

    if [ -f /tmp/mk_prod_dir.$$ ]
    then
        /bin/rm -f /tmp/mk_prod_dir.$$
        fmt_mesg "Unable to clean up directory contents"
    fi

    if [ ! -d $prod_dir ]
    then
        mkdir_p $prod_dir
        if [ $? -ne 0 ]
        then
            echo "Directory create failure.  Do you have write permission?"
            ret_status=1
        fi
    fi

    if [ $ret_status -ne 0 ]
    then
        echo "You can either ABORT the install or re-enter another directory name."
        get_yn "Do you want to ABORT the install" no
        if [ "$result" = yes ]
        then
            exit 1
        fi
    fi
    return $ret_status
}

#-----------------------------------------------------------------
check_loaded() {
#-----------------------------------------------------------------
#
#  Check if component has already been loaded by a previous install.
#  If so, display message and set yn_def to no.  If component
#  has not been loaded and is not an optional component, set yn_def=yes.
#
#  input:  check_limit, var_indx, component_desc, COMPONENT_DIR
#  output: yn_def, DO
#

    DO=Load
    case $type in
        optional )
            yn_def=no
            ;;
        * )
            yn_def=yes
            ;;
    esac

    # If the component description has been saved in the install database
    # or the component exists in the base or releases directory
    # we can assume that the component has already been loaded.
    if grep "$component_desc" $inst_db >/dev/null
    then
        DO="Re-load"
        yn_def=no
        fmt_mesg "The $component_desc has already been loaded by a
                  previous install."
        return
    elif [ -d $COMPONENT_DIR  -o  -f $COMPONENT_DIR ]
    then
        DO="Re-load"
        yn_def=no
        fmt_mesg "The $component_desc has already been loaded by a
                  previous install."
        return
    fi
}

#-----------------------------------------------------------------
ask_about_component_type() {
#-----------------------------------------------------------------
#
#  Ask about the products from the given component type
#
# arg 1: type (required, recommend, optional, auxiliary)
# arg 2: minimum number of components that must be loaded
#
# sets globals: type, var_indx, req_load_total,
#               load_cmp, cmps_loaded, check_limit
#               cmps_to_load, component_desc, component_loc
#

    type=$1
    req_load_total=$2
    eval var_indx=INST_`echo "$type" | tr "[a-z]" "[A-Z]"`
    load_cmp=1
    cmps_loaded=`get_var ${var_indx}_LOADED`
    cmps_loaded=${cmps_loaded:-0}
    check_limit=$cmps_loaded
    eval cmps_to_load=\$${type}_cmps
    put_var "${var_indx}_REQUIRED" "$req_load_total"
    while [ $cmps_to_load -ne 0 ]
    do
        eval component_desc=\$${type}_cmp_${load_cmp}_desc
        eval component_loc=\$${type}_cmp_${load_cmp}_loc
        eval component_root=\$${type}_cmp_${load_cmp}_root
        eval component_size=\$${type}_cmp_${load_cmp}_size
        eval component_dir=\$${type}_cmp_${load_cmp}_dir

        # Set default root directory location.
        case $component_root in
            $feature_base )
                prod_root=$prod_base
                ;;
            * )
                prod_root=$prod_home
                ;;
        esac
        COMPONENT_DIR=$prod_root/$component_dir

        # If component is not already loaded,
        # will set DO=Load & yn_def=yes otherwise DO=Re-load & yn_def=no
        # The default answer for optional components is always no.
        check_loaded

        get_yn "$DO $component_desc (size = ${component_size}KB)?" $yn_def
        if [ "$result" = yes ]
        then
            cmp_home_query $prod_root $component_size

            # save answers for later extract
            cur_extract_count=`expr $cur_extract_count + 1`
            eval component_loc_$cur_extract_count=\"$component_loc\"
            eval component_home_$cur_extract_count=\"$cmp_home\"
            eval prod_root_$cur_extract_count=\"$prod_root\"
            eval component_desc_$cur_extract_count=\"$component_desc\"
            eval component_indx_$cur_extract_count=\"$var_indx\"
            eval component_do_$cur_extract_count=\"$DO\"
            cmps_loaded=`expr $cmps_loaded + 1`
        fi

        cmps_to_load=`expr $cmps_to_load - 1`
        load_cmp=`expr $load_cmp + 1`

    done

    if [ $cmps_loaded -lt $req_load_total ]
    then
        if [ $req_load_total -eq 1 ]
        then
            req_needed="one $type component was"
        else
            req_needed="$req_load_total $type components were"
        fi
        fmt_mesg "$abort_msg If $req_needed not
                  loaded by a previous run of this $command program,
                  $product_name may not work properly."
    fi

}


#-----------------------------------------------------------------
save_defaults() {
#-----------------------------------------------------------------
#
# Function that saves installation defaults.
# Writes <name>=<value> to $install_defaults file
#
# arg 1: the variable name to save
#
# sets no global variables (!)
#

    if [ -w $install_defaults ]
    then
        eval echo "$1=\$$1" >> $install_defaults
    fi
}


#-----------------------------------------------------------------
sig_cleanup() {
#-----------------------------------------------------------------
#
#  Function called when interrupts or signals occur.
#

    echo >&2
    echo "Product load interrupted." >&2
    echo >&2

    if [ "$need_rewind" = yes ]
    then
        echo "Rewinding tape." >&2
        $remote mt -f $device rewind
    fi

    if [ "$need_eject" = yes ]
    then
        $remote eject $device
    fi
    exit 1
}


#-----------------------------------------------------------------
ask_about_components() {
#-----------------------------------------------------------------

    # Ask about Required Components
    if [ $required_cmps -gt 0 ]
    then
        separator
        echo "Required Product Components:"
        abort_msg="One or more required components were not selected."
        ask_about_component_type required $min_required_cmps
    fi

    # Ask About Recommended Components
    if [ $recommend_cmps -gt 0 ]
    then
        separator
        fmt_mesg "Recommended Product Components:"
        abort_msg="Failed to select enough of the recommended components."
        ask_about_component_type recommend 0
    fi

    # Ask about Optional Components
    if [ $optional_cmps -gt 0  -a $optional = yes ]
    then
        separator
        fmt_mesg "Optional Product Components:"
        abort_msg="Optional component load error."
        ask_about_component_type optional 0
    fi
}

#-----------------------------------------------------------------
print_component_extract_answers() {
#-----------------------------------------------------------------

    echo "
Your answers were:
    "
    this_extract=1
    while [ $this_extract -le $cur_extract_count ]
    do
        eval cmp_home=\$component_home_$this_extract
        eval component_desc=\$component_desc_$this_extract
        eval DO=\$component_do_$this_extract
        fmt_mesg "$DO $component_desc on $cmp_home"
        this_extract=`expr $this_extract + 1`
    done
}

#-----------------------------------------------------------------
usage() {
#-----------------------------------------------------------------

    echo  "
Usage: install [-p component_name [-f simple_file_name]... ]

    -p component_name           component name from which files
                                should be extracted (e.g. rs6k_bin)
    -f simple_file_name         simple file name of file to be extracted
                                (e.g. rada).  Multiple -f arguments may be used
                                to extract multiple files.
    -x                          Debug tracing.

NOTE: The normal invocation of install is without parameters.
    " >&2
    exit 1
}


#-----------------------------------------------------------------
get_opts() {
#-----------------------------------------------------------------

    cmp_desc_name=
    simple_file_names=
    optional=no

    while [ $# -gt 0 ]
    do
        case $1 in
        -p)
            if [ $# -eq 0 ]
            then
                echo "bad -p" >&2
                usage
            fi
            installing_specific_files=TRUE
            shift
            cmp_desc_name="$1"
            ;;
        -f)
            if [ $# -eq 0 ]
            then
                echo "bad -f" >&2
                usage
            fi
            shift
            if [ -z "$simple_file_names" ]
            then
                simple_file_names="$1"
            else
                simple_file_names="$simple_file_names|$1"
            fi
            ;;
        -o|-optional)
            optional=yes
            ;;
        -x)
            set -x
            ;;
        *)
            echo "bad option $1" >&2
            usage
            ;;
        esac
        shift
    done
}

#-----------------------------------------------------------------
read_specific_files() {
#-----------------------------------------------------------------
#
# Read named files from a named component on the tape
#

    grep $cmp_desc_name $install_dir/prod_desc.$ARCH >/tmp/read_grep.$$
    add_cleanup_file /tmp/read_grep.$$
    if [ ! -s /tmp/read_grep.$$ ]
    then
        fatal "There is no such component "$cmp_desc_name" on the tape.
               Installation ABORTED."
    fi


    cmp_id=`sed -e 's/_desc_name.*$//' /tmp/read_grep.$$`

    eval cmp_loc=\$${cmp_id}_loc
    eval cmp_id_root=\$${cmp_id}_root
    if [ $cmp_id_root -eq "$feature_home" ]
    then
        cmp_id_root_path=`get_var INST_HOMEDIR`
    else
        cmp_id_root_path=`get_var INST_BASE_LOC`
    fi

    # get tar path names out of .list file containing list of all files
    # in this component.
    egrep "$simple_file_names" $install_dir/$cmp_desc_name.list \
        >/tmp/tar_file_names.$$
    add_cleanup_file /tmp/tar_file_names.$$

    set_tape
    read_tape $cmp_loc $cmp_id_root_path "`cat /tmp/tar_file_names.$$`"
}


#-----------------------------------------------------------------
do_disk_loads() {
#-----------------------------------------------------------------
#
#  Load product from floppy disk.
#

    echo
    echo "Ejecting first Disk"
    $remote eject $device
    if [ $device_host != $HOSTNAME ]
    then
        echo "Reading $product_name from $device on $device_host."
    else
        echo "Reading $product_name from $device."
    fi

    /bin/rm -f $install_dir/disk_load.err
    numdisks=`cat dkinfo`
    DiskNum=2

    while [ $DiskNum -le $numdisks ]
    do
        while true
        do
            echo "Insert disk number $DiskNum in $device."
            press_cr
            break
        done

        need_eject=yes

        if [ -n "$remote" ]
        then
            $remote dd if=$device bs=9k conv=sync count=1 > dinfo.$DiskNum \
                2>> $install_dir/disk_load.err
        else
            dd if=$device of=dinfo.$DiskNum bs=9k conv=sync count=1 \
                2>> $install_dir/disk_load.err
        fi

        idstring=`echo $DiskNum | awk '{printf("Disk %2d of", $1)}'`

        echo "Reading $idstring $numdisks"
        if fgrep "$idstring" dinfo.$DiskNum > /dev/null 2>&1
        then
            blocks=`grep blocks dinfo.${DiskNum} | sed 's% blocks%%'`
            if [ -n "$remote" ]
            then
                $remote dd if=$device bs=9k conv=sync skip=1 count=$blocks \
                    >> $feature.tar.Z 2>> $install_dir/disk_load.err
            else
                dd if=$device bs=9k conv=sync skip=1 count=$blocks \
                    >> $feature.tar.Z 2>> $install_dir/disk_load.err
            fi

            $remote eject $device
            need_eject=no
            DiskNum=`expr $DiskNum + 1`
        else
            echo "Wrong disk..."
            $remote eject $device
            need_eject=no
        fi
    done

    chk_disk_num=2
    while [ $chk_disk_num -le $numdisks ]
    do
        if [ -f dinfo.$chk_disk_num ]
        then
            # Cleanup
            /bin/rm -f dinfo.$chk_disk_num
        else
            # Problem?
            fmt_mesg "Load failure.  $product_name may have been partially
                loaded, or not loaded at all.  You should delete the files
                just installed and attempt the install again.  The problem
                may have been due to:"
            echo "
    * Insufficient disk space.
    * Incorrect permissions on the product directory.
    * Floppy disk read error.
    * If the floppy disk drive is remote, a failure on the remote machine."

            echo "disk_load.err:"
            cat $install_dir/disk_load.err
            /bin/rm -f dinfo.[1-9] dinfo.?[0-9]
            exit 1
        fi
        chk_disk_num=`expr $chk_disk_num + 1`
    done
}


#-----------------------------------------------------------------
uncompress_tar() {
#-----------------------------------------------------------------

    echo
    echo "Extracting files from $feature.tar.Z"
    uncompress < $install_dir/$feature.tar.Z |( cd $cmp_home; tar x${vop}pf -)
    if [ $? -eq 0 ]
    then 
        put_var $FEATURE "$cmp_home"
        #/bin/rm -f $install_dir/$feature.tar.Z
    else
        fatal "The installation has failed.
            Review the error messages produced by the extraction commands
            to determine the reason for the problem.  If you cannot determine
            the problem contact Rational support."
    fi

    if [ $device_kind = tape \
         -a -n "$cmp_home"   \
         -a "$cmp_home" != "$prod_root" ]
    then
        mk_links $prod_root $cmp_home
    fi
}


#-----------------------------------------------------------------
update_config() {
#-----------------------------------------------------------------

    # Log what was installed in the database:
    #    <feature> <version> <location> <user> <date>
    config=$rational_dir/config
    if [ ! -d $config ]
    then
        mkdir_p $config
    fi

    (cd $rational_dir/releases
    if [ $sym_link config ]
    then
        rm -f config
        ln -s $rational_dir/config config
    elif [ ! -d config ]
    then
        ln -s $rational_dir/config config
    fi
    )

    install_db=$config/install_db
    db_entry="$feature.$product_version $prod_home  $USER  `date`"
    if [ -f $install_db ]
    then
        if grep "^$feature.$product_version " $install_db >/dev/null
        then
            # replace entry
            sed -e "s?^$feature.$product_version .*?$db_entry?" \
                $install_db > /tmp/install_db.$$
            mv /tmp/install_db.$$ $install_db
        else
            # add entry
            echo "$db_entry" >> $install_db
        fi
    else
        # Create install_db
        echo "$db_entry" > $install_db
    fi

    # Update these files in the config directory:
    for file in uninstall version_map run_order
    do
        if [ ! -f $install_dir/$file ]
        then
            continue
        fi

        if [ -f $config/$file ]
        then
            # config file exists -- update if necessary
            set -- 1 `grep "Revision:" $config/$file`
            if [ -n "$3" ]
            then
                curr_file_num=`echo $3 | awk -F. '{print $2}'`
                set -- 1 `grep "Revision:" $install_dir/$file`
                new_file_num=`echo $3 | awk -F. '{print $2}'`
                if [ $new_file_num -gt $curr_file_num ]
                then
                    echo Updating $config/$file
                    cp $install_dir/$file $config/$file
                fi
            else
                echo Updating $config/$file
                cp $install_dir/$file $config/$file
            fi
        else
            echo Installing $config/$file
            cp $install_dir/$file $config/$file
        fi
    done
}


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

check_and_set_arch

read_prod_desc

PATH=$install_dir:$PATH

# Used for keeping track of filesystem size calculations.
fs_sizes=$install_dir/.fs_sizes
/bin/rm -f $fs_sizes
touch $fs_sizes
add_cleanup_file $fs_sizes

#  Set Defaults
device_host=$HOSTNAME
prod_home=`dirname $install_dir`
FEATURE=`echo $feature | tr '[a-z]' '[A-Z]'`
cmp_home=$prod_home
verbose=yes

# load any saved defaults from a previous run of this script
if [ -s $install_defaults.sav ]
then
    mv $install_defaults.sav $install_defaults
fi
if [ -s $install_defaults ]
then
    . $install_defaults
fi
need_rewind=no

#  Get program options

get_opts $*

banner Installing: "$product_name" "$product_version" "$copyright_year"

#  Root cannot run this script.

forbid_root

#  Get input.

queries

if [ ! -w $prod_home ]
then
    fmt_mesg "Directory $prod_home does not exist, or you do not have
              write permission.  $Device_Kind load aborted."
    exit 1
fi

if [ -n "$cmp_desc_name" ]
then
   if [ $device_kind = tape ]
   then
       read_specific_files
       exit 0
   else
       fatal "The -c option can only be used for tapes."
   fi
fi

put_var INST_PRODUCT "$product_name"
put_var INST_VERSION "$product_version"
put_var INST_HOMEDIR "$prod_home"
put_var INST_STATUS FAILED

if [ $device_kind = tape ]
then
    notify=no
    while true
    do
        if [ $notify = no ]
        then
            notify=yes
            separator
            echo "                       Component Extract Dialog"
            echo "                       ------------------------"
            fmt_mesg "You will be asked if you want to load each
                product component.  This is done so you can restart
                this installation after some kind of failure without
                having to re-do steps that have already run
                successfully. Failure to load any required component
                will prevent the software from running properly."

            if [ "$prod_base" != N/A ]
            then
                except_base="not in the 'Rational Base Library Directory'"
            fi

            fmt_mesg "Components $except_base can be loaded in a directory
                other than the parent directory.  This capability is provided
                so that if you don't have enough free disk space on one disk
                partition, you will still be able to load this software by
                distributing the different components onto different disk
                partitions. It is generally more convenient to load all the
                data in one place if you have enough disk space in one disk
                partition. If you choose to install this component some place
                other than the default, the appropriate logical links will be
                established in the product parent directory."
        fi

        cur_extract_count=0
        ask_about_components

        print_component_extract_answers

        fmt_mesg "If you made any mistakes, answer 'no' and all the
                  prompts in this dialog will repeat."

        get_yn "Are these entries OK?" yes
        if [ "$result" = yes ]
        then
            break
        else
            # Start over
            /bin/rm -f $fs_sizes
            touch $fs_sizes
        fi
    done

    do_tape_loads

elif [ $device_kind = disk ]
then
    do_disk_loads
    uncompress_tar
else
    uncompress_tar
fi


# Set link for share/bin/check_reqs -> install/check_reqs
if [ -d $prod_home/share/bin ]
then
    /bin/rm -f $prod_home/share/bin/check_reqs
    ln -s $install_dir/check_reqs $prod_home/share/bin/check_reqs
fi

update_config

#  Tape is loaded.
put_var INST_STATUS COMPLETED
put_var INST_BASE_LOC $prod_base

#  End of script.