#!/bin/sh
# +--------------------------------------------------------------------------+
# | Copyright 1992 - 2002 Rational Software Corporation. All Rights Reserved.|
# | This software contains proprietary and confidential information of       |
# | Rational and its suppliers. Use, disclosure or reproduction is           |
# | prohibited without the prior express written consent of Rational.        |
# +--------------------------------------------------------------------------+
#
#@(#)$Revision: 1.94 $  $Date: 03/12/2002 10:37:17 $

# When adding other tape command aliases to this script, add to this list:
alias_list="readtape writetape verifytape duptape stattape pl"

#**************************************************************************
#SOHT
#
#SYNOPSIS
#    readtape    [-help] [-i] [-f] [-r] [-e] [-v] [-obs <OTHERBS>] <N>
#    writetape   [-help] [-i] [-f] [-r] [-e] [-v] [-obs <OTHERBS>]
#    verifytape  [-help] [-i] [-f] [-r] [+e] [-obs <OTHERBS>]
#    duptape     [-help] [-i] [-f] [-r] [+e] [-obs <OTHERBS>]
#    stattape    [-help] [-i] [-g|-l|-p]
#    pl          [-help] [-i] [<args>]
#
#DESCRIPTION
#    These scripts are used to duplicate Rational installation
#    tapes.  The tape device can be 8mm, 4mm or QIC.
#
#    The various aliases that you can invoke this script are listed
#    in the synopsis above.  They will be automatically installed
#    when you run any of the commands.  You can install them and do nothing
#    else by running any of the commands with the -i option.
#
#    To duplicate a tape do readtape, writetape and verifytape:
#
#    % readtape    # creates files file0 .. fileN.
#
#    Change tapes or specify a different tape device.
#    This is a way to copy from 8mm to 4mm or QIC, etc.
#
#    % writetape   # writes file0 .. fileN to tape device.
#    % verifytape  # Verify the tape you created can be read.
#
#    The duptape script does a writetape followed by a verifytape.
#    This is the same as running writetape with the -v option.
#
#    The stattape script displays info about the product and the
#    components on the tape.  You must run readtape first.  It
#    extracts product description information from file0.
#
#OPTIONS
#    -e     Will eject the tape. This is the default for
#           the verifytape and duptape commands.
#
#    +e     Do not eject the tape.
#
#    -f     Will not ask about tape device--uses default.
#
#    -help  Displays this text to the screen.
#
#    -g     For stattape, display group information.
#    -l     For stattape, display license information.
#    -p     For stattape, display product configuration information.
#
#    -r     Will run the dd command in "raw" mode--No tar file,
#           compression or block factors will be used.
#
#    -v     Will verify the tape after a read or write.
#
#    -obs   Allows you to set the other block size to
#           somthing other than 126b.
#
#    <N>    Will make readtape only read fileN.  <N> must be a number that
#           represents one of the components on the tape.
#
#DEPENDENCIES
#    This script depends on having a tape in a tape drive:
#    default: /dev/nrst0 (SunOS) or /dev/rmt0.5 (AIX), etc.
#    IMPORTANT: These defaults specify the NO-REWIND tape device.
#    Special commands used: mt, tar
#
#AUTHOR
#    Tom Arnold, Software Engineer, Rational Software Corporation
#      E-mail: arnold@rational.com, http://www.rational.com/
#
#    $Revision: 1.94 $
#
#EOHT
#**************************************************************************

#------------------------------------------------------------------------
# Set defaults

SCRIPT=$0
CMD=`basename $SCRIPT`
NSR=/ned/storage/releases
GOPL=$NSR/.gopl
ALOHA_HOST=power
PROD_LIST=$NSR/.prod_list
LIST_FUNCTIONS=$NSR/bin/list_functions
STORAGE=/people/arnold/misc/storage
dirname=`dirname $SCRIPT`
DIR=`(cd $dirname; pwd)`
ELAPSE=$DIR/elapse
STAT_DIR=/tmp/$CMD.dir.$$
TMP=/tmp/$CMD.$$
GET_DEV=/tmp/$CMD.get_dev.$$
HOST=`hostname`
FIRSTBS=20b
OTHERBS=126b
NEED_REWIND=yes
TAPE_TYPE=8mm    # Assume 8mm tape. Only QIC is treated differently.
Log_aux="Log aux"
Revision=version
status=0
ask=yes
install_only=no
group_info=no
license_info=no
product_info=no
eject=no
never_eject=no
raw_mode=no
verify=no
fileN_only=no
do_sleep=':'
do_trace=':'
tell_conv=':'

if [ "$USER" != arnold ]
then
    unset DISPLAY
fi

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


#------------------------------------------------------------------------
Usage() {
#------------------------------------------------------------------------

    # Extract the text between #SOHT and #EOHT in this script
    if [ "`uname -s`" = OSF1 ]
    then
        sed -e '1,/^#SOHT/d' -e '/^#EOHT/,$d' -e 's/^#//' $SCRIPT
    else
        sed -e '1,/^#SOHT/d' -e '/^#EOHT/,$d' -e 's/^#//' $SCRIPT | more
    fi
    cleanup0 Quit
    exit $1
}

#-----------------------------------------------------------------
get_result() {
#-----------------------------------------------------------------
# Get input from the user, providing a prompt value.

    while true
    do
        echo
        $ECHON "$1 [$2]  $NOCR"
        read result
        if [ -n "$result" ]
        then
            return
        elif [ -n "$2" ]
        then
            result=$2
            return
        else
            echo "You must enter a value."
        fi
    done
}

#------------------------------------------------------------------------
cleanup0() {
#------------------------------------------------------------------------

    $do_trace
    if [ -n "$cmd_status" ]
    then
        return
    fi

    if [ -n "$1" ]
    then
        cmd_status=$1
        Log_aux=':'
        if  [ "$cmd_status" = Quit ]
        then
            unset DISPLAY
        else
            Log neg "$CMD - $cmd_status"
        fi
    elif [ $status -eq 0 ]
    then
        cmd_status="Completed successfully"
    else
        cmd_status=Failed
    fi

    if [ -d $STAT_DIR ]
    then
        /bin/rm -fr $STAT_DIR
    fi

    for file in $TMP $GET_DEV
    do
        if [ -f $file ]
        then
            /bin/rm -f $file
        fi
    done


    if [ -x $HOME/bin/xremind -a  -n "$DISPLAY" ]
    then
        $HOME/bin/xremind -cm "$CMD - $cmd_status"
    fi

    if [ -n "$start"  -a  "$cmd_status" != Quit ]
    then
        Log aux Elapsed time for $CMD: `$ELAPSE -l $start`
        $ELAPSE -c $start
        unset start
    fi
    eval $Log_aux $CMD - $cmd_status.
    exit $status
}

#------------------------------------------------------------------------
Log() {
#------------------------------------------------------------------------

    Date=`date '+%T'`
    case $1 in
          aux ) shift; echo "$Date ::: [$*]" >&2 ;;
          pos ) shift; echo "$Date +++ $*" >&2 ;;
          neg ) shift; echo "$Date ++* $*" >&2 ;;
         warn ) shift; echo "$Date !!! $*" >&2 ;;
          err ) shift; echo "$Date *** $*" >&2 ;;
         note ) shift; echo "$Date --- $*" >&2 ;;
         cont ) shift; echo "$Cont ... $*" >&2 ;;
    esac
    Cont="$Date"
}

#------------------------------------------------------------------------
Log2() {
#------------------------------------------------------------------------

    log_type=$1
    shift
    echo
    Log $log_type "$*"
}

#------------------------------------------------------------------------
Log_TMP() {
#------------------------------------------------------------------------

    if [ -s $TMP ]
    then
        # If this file is not empty, errors may have occured.
        if [ `grep -v "records " $TMP | wc -l` -gt 0 ]
        then
            Log err `cat $TMP`
            return 1
        else
            # Only the records in/out from dd.  Okay.
            Log note `cat $TMP`
        fi
    fi
    return 0
}

#------------------------------------------------------------------------
Log_desc() {
#------------------------------------------------------------------------

    note="$1"

    if [ $f -eq 0 ]
    then
        desc="Installation tools"
    else
        eval desc=\"\$cmp_${f}_desc\"
    fi

    Log2 note "$note"
    Log  note "\"$desc\""
}

#------------------------------------------------------------------------
rewind_tape() {
#------------------------------------------------------------------------

    $do_trace
    if [ $NEED_REWIND = yes ]
    then
        Log2 note Rewinding tape: $TAPE_DEV
        Log aux $MT $TAPE_DEV rewind
        $MT $TAPE_DEV rewind > $TMP 2>&1
        if Log_TMP
        then
            NEED_REWIND=no
        else
            exit 1
        fi
    fi
}

#------------------------------------------------------------------------
eject_tape() {
#------------------------------------------------------------------------

    $do_trace
    rewind_tape
    if [ $never_eject = yes ]
    then
        return
    fi

    if [ $eject = yes ]
    then
        Log2 note Ejecting tape: $TAPE_DEV
        Log aux $MT $TAPE_DEV $offline
        $MT $TAPE_DEV $offline > $TMP 2>&1
        if Log_TMP
        then
            return
        else
            exit 1
        fi
    fi
}

#------------------------------------------------------------------------
sound_alarm() {
#------------------------------------------------------------------------

    $do_trace
    status=1
    Log err $1 FAILED
    eject_tape
    exit 1
}

#------------------------------------------------------------------------
check_dir() {
#------------------------------------------------------------------------

    $do_trace
    if [ $ask = no ]
    then
        return
    fi

    if [ `ls | wc -l` -gt 0 ]
    then
        Log2 warn The directory you are in does not appear to be empty.
        Log  cont When reading Rational product tapes, it is best to do
        Log  cont so in an empty directory.
        get_result "Do you wish to continue?" no
        case $result in
            Y*|y* ) return ;;
        esac
        cleanup0 Quit
        exit 0
    fi
}

#------------------------------------------------------------------------
make_prod_list() {
#------------------------------------------------------------------------

    if [ -z "$MAKE_GOPL" ]
    then
        return
    fi

    if [ "$READ_ONLY" = yes ]
    then
        CHMOD=chmod
    else
        CHMOD=':'
    fi

    Log2 note "Making $PROD_LIST"
    Log  note "   and $GOPL"

    if [ ! -r $STORAGE ]
    then
        Log err  "$STORAGE missing."
        Log cont "Cannot run $CMD."
        exit 1
    fi

    Log2 note "Creating the product list from $STORAGE list..."

    for dir in `cat $STORAGE`
    do
        if [ ! -d $dir ]
        then
            echo $dir >> $STORAGE.miss
            grep -v "^$dir\$" $STORAGE > $TMP.2
            /bin/cp $TMP.2 $STORAGE
            /bin/rm -f $TMP.2
            continue
        fi
        echo $dir/$subdir
    done|sort|awk 'BEGIN {N=0} {N+=1} {printf("pl%s - %s\n",N,$1)}' > $TMP

    echo
    if diff $GOPL $TMP >/dev/null
    then
        Log pos $GOPL up-to-date
    else
        if cp $TMP $GOPL
        then
            Log pos $GOPL updated
            /bin/ls -l $GOPL
        else
            Log err $GOPL not updated
        fi
    fi

    awk '{print $3}' $GOPL | sed -e "s?/? ?g" |
    while read entry
    do
        set -- $entry
        shift `expr $# - 4`
        case $3 in
        i386 ) echo "$1 $2/$3 $4" ;;
        m68k ) echo "$1 $2/$3 $4" ;;
        mips ) echo "$1 $2/$3 $4" ;;
        power ) echo "$1 $2/$3 $4" ;;
        rh32 ) echo "$1 $2/$3 $4" ;;
        x86 ) echo "$1 $2/$3 $4" ;;
        * )
            case $1 in
            apexlx ) echo "$1 $2/$3 $4" ;;
            apexrt ) echo "$1 $2/$3 $4" ;;
            apexvw ) echo "$1 $2/$3 $4" ;;
                 * ) echo "$2 $3 $4" ;;
            esac
        esac
    done > $TMP

    if diff $PROD_LIST $TMP >/dev/null
    then
        Log pos $PROD_LIST up-to-date
    else
        if cp $TMP $PROD_LIST
        then
            Log pos $PROD_LIST updated
            /bin/ls -l $PROD_LIST
        else
            Log err $PROD_LIST not updated
        fi

        if rcp $GOPL $PROD_LIST ${ALOHA_HOST}:$NSR
        then
            Log pos $GOPL and $PROD_LIST
            Log cont updated in Aloha
        else
            Log err $GOPL and $PROD_LIST
            Log cont not updated in Aloha
        fi
    fi
    exit 0
}

#------------------------------------------------------------------------
prod_sed() {
#------------------------------------------------------------------------

    (
    echo "pn Product Platform Version"
    echo "-- ------- -------- -------"
    awk '{print $1,$3}' $GOPL
    ) | Sed
}

#------------------------------------------------------------------------
Sed() {
#------------------------------------------------------------------------
# Underscores (_) become slashes (/)
# Equals (=) become spaces ( )

sed -e "s?^pl??" -e "s? /.*/mkprod-storage/? ?" -e "s? /.*/releases/? ?" \
    -e "s?rose/rose_apex?Rose_C++=for=Apex?" \
    -e "s?rose_apex?Rose_C++=for=Apex?" \
    -e "s?ada_analyzer?Ada=Analyzer?" \
    -e "s?apex_clearcase?Apex_ClearCase?" \
    -e "s?apexlx?Apex=for=LynxOS?" \
    -e "s?apexrt?Apex=for=Rational=Exec?" \
    -e "s?apexvw?Apex=for=VxWorks?" \
    -e "s?apex_ada?Apex=Ada?" \
    -e "s?apex_cpp?Apex=C_C++?" \
    -e "s?apex_duo?Apex=Duo?" \
    -e "s?apex?Rational=Apex?" \
    -e "s?\.Rational Apex\.?.apex.?" \
    -e "s?axi?AXI=(Ada_X=Interface)?" \
    -e "s?puretools?Purify=Apex,=PureCoverage=Apex=and=Quantify=Apex?" \
    -e "s?rci?The=RCI?" \
    -e "s?rose/rose_dev?Rose=Developer=(Rose_C++=for=Apex)?" \
    -e "s?rose/rose_cpp?Rose_C++?" \
    -e "s?rose/rose_ada?Rose_Ada?" \
    -e "s?rose/rose_comb?Rose=Modeler=\&=C++?" \
    -e "s?rose/rose?Rose?" \
    -e "s?rose_cpp?Rose_C++?" \
    -e "s?rose_dev?Rose=Developer?" \
    -e "s?rose_ada?Rose_Ada?" \
    -e "s?rose_comb?Rose=Modeler=\&=C++?" \
    -e "s?rose98unix?Rose=98=for=Unix?" \
    -e "s?rose?Rose?" \
    -e "s?soda?SoDA?" \
    -e "s?summit?Rational=Summit?" \
    -e "s?testmate?TestMate?" \
    -e "s?/alpha?->Alpha=AXP?" \
    -e "s?/cpu32?->cpu32=68332_340_360?" \
    -e "s?/hppa?->HP-PA?" \
    -e "s?/hprt?->HP-RT?" \
    -e "s?/i386?->Intel=i386_Pentium?" \
    -e "s?/x86?->Intel=i386_Pentium?" \
    -e "s?/68k?->Motorola=68k?" \
    -e "s?/mips1?->MIPS=I?" \
    -e "s?/mips2?->MIPS=II?" \
    -e "s?/mips3?->MIPS=III?" \
    -e "s?/mips4?->MIPS=IV?" \
    -e "s?/mips?->MIPS?" \
    -e "s?/power?->PowerPC?" \
    -e "s?/rh32?->rh32?" \
    -e "s?/rad6000?->rad=6000?" \
    -e "s?/sparc?->SPARC?" \
    -e "s?aix?AIX?" \
    -e "s?axp?Compaq=Tru64?" \
    -e "s?hp?HP-UX?" \
    -e "s?ia64_linux2?Linux/Intel ia64?" \
    -e "s?sgi?IRIX?" \
    -e "s?sg32?IRIX_N32?" \
    -e "s?sunsol?SunOS=\&=Solaris?" \
    -e "s?sol?Solaris?" \
    -e "s?sun?SunOS?" \
    -e "s?win95?MS=Win95_WinNT?" \
    -e "s?win?MS=Windows=3.1?" \
    -e "s?i386_linux2?Linux/Intel x86?" \
    -e "s?GA_?GA=?" \
    -e '/^$/d' \
    -e "s?/? ?g"

}

#------------------------------------------------------------------------
select_prod() {
#------------------------------------------------------------------------

    if [ "$CMD" = stattape ]
    then
        # Set product description from comp0 or install dir.
        for prod_desc in comp0/releases/*/install/*/prod_desc \
            $ARCH/prod_desc */prod_desc
        do
            if [ -f $prod_desc ]
            then
                return
            fi
        done
        unset prod_desc
    fi

    if [ -f file0  -a  "$CMD" != pl ]
    then
        return
    fi

    if [ ! -s $PROD_LIST ]
    then
        if [ "$CMD" = pl ]
        then
            if [ ! -d $NSR ]
            then
               Log err "$PROD_LIST missing."
               Log cont "Cannot run $CMD."
               exit 1
            fi
        else
            Log err "Could not find the first file: file0"
            Log cont "You need to run readtape first"
            Log cont "Aborting $CMD"
            exit 1
        fi
    fi

    echo
    if [ "$CMD" = pl ]
    then
        make_prod_list
        if [ -n "$args" ]
        then
            set -- $args
            do_greps="fgrep -i -- '$1' $TMP"
            shift
            while [ $# -gt 0 ]
            do
                do_greps="$do_greps | grep -i '$1'"
                shift
            done
            prod_sed |
            awk '{printf("  %4s.  %-20s  %-16s  %s\n", $1,$2,$3,$4)}' |
            sed -e 's?_?/?g' -e 's?=? ?g' > $TMP
            head -2 $TMP
            eval $do_greps
        else
            prod_sed |
            awk '{printf("  %4s.  %-20s  %-16s  %s\n", $1,$2,$3,$4)}' |
            sed -e 's?_?/?g' -e 's?=? ?g'
        fi
        echo
        exit 0
    fi

    if [ ! -s $LIST_FUNCTIONS ]
    then
        Log err "Could not find the first file: file0"
        Log cont "You need to run readtape first"
        Log cont "Aborting $CMD"
        exit 1
    fi

    . $LIST_FUNCTIONS

    pl_get_prod_location

    if [ -z "$prod_location" ]
    then
        Log err "Could not find product directory."
        Log cont "Aborting $CMD"
        exit 1
    fi

    echo
    echo "Product duplication directory:"
    echo "  $prod_location"
    cd $prod_location
    return $?
}

#------------------------------------------------------------------------
show_license_info() {
#------------------------------------------------------------------------

    lic_desc=`dirname $prod_desc`/lic_desc
    if [ ! -f $lic_desc ]
    then
        echo
        echo Sorry, no license information is available with this release.
        echo
        echo "This product release was created  on $product_date"
        echo "before the -l option was invented on 07/03/97."
        return
    fi

    . $lic_desc

    if [ -n "$subprod_lic_1"  -a  -n "$subprods" ]
    then
        # Licensing done by product configurations.
        item_desc="Product Configuration"
        Items=$subprods
    else
        # Licensing done by components.
        item_desc=Component
        Items=$cmps
    fi

    echo "
 No.  $item_desc Description
        Feature - License Description (lic ver)
 ---  ------------------------------------------------------------------------"

    item=1
    while [ $item -le $Items ]
    do
        if [ -n "$subprod_lic_1" ]
        then
            eval lic_list=\"\$subprod_lic_${item}\"
            eval item_desc=\"\$subprod_desc_${item}\"
        else
            eval lic_list=\"\$cmp_${item}_lic\"
            eval item_desc=\"\$cmp_${item}_desc\"
        fi

        if [ -n "$lic_list" ]
        then
            if [ $item -lt 10 ]
            then
                echo "  $item.  $item_desc"
            else
                echo " $item.  $item_desc"
            fi

            for fn in $lic_list
            do
                eval lic_feat=\"\$license_feature$fn\"
                eval lic_desc=\"\$license_desc$fn\"
                eval lic_ver=\"\$license_version$fn\"
                if [ -n "$lic_feat" ]
                then
                    echo "        $lic_feat - $lic_desc ($lic_ver)"
                fi
            done
            echo
        fi
        item=`expr $item + 1`
    done
echo "------------------------------------------------------------------------------"
}

#------------------------------------------------------------------------
show_product_info() {
#------------------------------------------------------------------------

    $do_trace
    if [ "$product_info" = no ]
    then
        return
    fi

    if [ ${subprods:-0} -eq 0 ]
    then
        echo
        echo "There is no product configuration information for this release."
        return
    fi

    echo
    echo " No  Kbytes  Product Configuration Description / Component Numbers"
    echo " --  ------  -----------------------------------------------------"
    blnk="            "
    spn=1
    while [ $spn -le $subprods ]
    do
        eval _desc=\"\$subprod_desc_$spn\"
        spn_total=0
        eval _list=\"\$subprod_comp_$spn\"
        for _cn in $_list
        do
            eval _size=\$cmp_${_cn}_size
            spn_total="$spn_total + $_size"
        done
        spn_total=`expr $spn_total`

        echo $spn $spn_total |
             awk '{printf(" %2s  %6s  ", $1, $2)}'
             echo $_desc

        # Display component numbers.  Sort them and put up to 22 on each line.
        set -- `(for _cn in $_list; do echo $_cn; done | sort +n)`
        (
        while [ $# -gt 22 ]
        do
            _list="$1 $2 $3 $4 $5 $6 $7 $8 $9"
            shift 9
            _list="$_list $1 $2 $3 $4 $5 $6 $7 $8 $9"
            shift 9
            _list="$_list $1 $2 $3 $4"
            shift 4
            echo "$blnk $_list"
        done
        if [ $# -gt 0 ]
        then
            echo "$blnk $*"
        fi
        ) | sed -e 's? 1 ? 1  ?' \
                -e 's? 2 ? 2  ?' \
                -e 's? 3 ? 3  ?' \
                -e 's? 4 ? 4  ?' \
                -e 's? 5 ? 5  ?' \
                -e 's? 6 ? 6  ?' \
                -e 's? 7 ? 7  ?' \
                -e 's? 8 ? 8  ?' \
                -e 's? 9 ? 9  ?'

        spn=`expr $spn + 1`
    done
    echo
}

#------------------------------------------------------------------------
do_archivetape() {
#------------------------------------------------------------------------

    $do_trace
    Log warn $CMD is obsolete.
    cleanup0 Quit
    exit 1
}

#------------------------------------------------------------------------
do_stattape() {
#------------------------------------------------------------------------

    $do_trace

    if [ -z "$prod_desc" ]
    then
        this_dir=`pwd`
        toc=$STAT_DIR/table_of_contents
        mkdir $STAT_DIR

        # Extract product and license description files from file0.
        tar -tf file0 > $toc 2>&1
        prod_desc=`egrep "prod_desc|product_desc" $toc`
        if [ -z "$prod_desc" ]
        then
            Log err "No product description found in file0."
            return
        fi

        lic_desc=`grep "/lic_desc\$" $toc`

        (cd $STAT_DIR; tar -xf $this_dir/file0 $prod_desc $lic_desc)
        prod_desc=$STAT_DIR/`echo "$prod_desc" | head -1`
    fi

    . $prod_desc

    if [ -n "$cmps" ]
    then
        LAST=${cmps:-0}
    else
        LAST=`expr ${required_cmps:-0} + \
                   ${recommend_cmps:-0} + \
                   ${optional_cmps:-0} + \
                   ${auxiliary_cmps:-0}`
    fi
    TOTAL=`expr $LAST + 1`
    Of=" of $LAST"

    if [ -n "$release_type" ]
    then
        banner_version="$product_version$patch_level ($release_type)"
    else
        banner_version="$product_version$patch_level"
    fi

    if [ $CMD != stattape ]
    then
        if [ -n "$arches" ]
        then
            tape=`echo $arches | Sed | sed -e 's?_?/?g' -e 's?=? ?g'`
            tape="for $tape tape."
        else
            tape=tape.
        fi
        echo
        echo "$Doing $product_name $banner_version $tape"

        if [ -z "$cmps" ]
        then
            # Translate component descriptions
            t=1
            for comp_type in required recommend optional auxiliary
            do
                eval N=\${${comp_type}_cmps:-0}
                n=1
                while [ $n -le $N ]
                do
                    eval cmp_${t}_desc=\$${comp_type}_cmp_${n}_desc
                    n=`expr $n + 1`
                    t=`expr $t + 1`
                done
            done
        fi
        return
    fi

    if [ -z "$compress" ]
    then
        compress=no
        if [ -n "$toc" ]
        then
            if grep /.compress $toc >/dev/null
            then
                compress=yes
            fi
        fi
    fi

    tar_format="standard tar"
    if [ -n "$toc" ]
    then
        if grep /gtar.Z $toc >/dev/null
        then
            tar_format="GNU tar"
        fi
    else
        for gtarZ in comp0/releases/*/install/*/gtar.Z */gtar.Z
        do
            if [ -f $gtarZ ]
            then
                tar_format="GNU tar"
            fi
        done
    fi

    if [ -z "$product_date" ]
    then
        product_date=`$LS $STAT_DIR/$prod_desc |
                      awk '{printf ("%s %s %s",$5,$6,$7)}'`
    fi

    product_date=${product_date:-???}

    echo
    echo "      Product:  $product_name $banner_version"
    if [ -n "$arches" ]
    then
        echo "     Platform: $arches"
    fi
    echo "         Date:  $product_date"
    echo " Media format:  $tar_format, compression=${compress:-???}"
    if [ -z "$patch_level" ]
    then
        tape_version=${device_version:-$tape_version}
        tape_version=${tape_version:-???}
        echo "Media version:  $tape_version"
    fi

    if [ "$license_info" = yes ]
    then
        show_license_info
        return
    fi

    if [ "$product_info" = yes ]
    then
        show_product_info
        return
    fi

    t=1
    echo
    echo " No      Size  Description"
    echo " --  --------  ----------------------------------------------------------------"
    SIZE=`$DU  file0 | awk '{print $1}'`
    SIZE=`expr $SIZE / 2`
    echo 0 $SIZE | awk '{printf(" %2d  %5s KB", $1, $2, $3)}'
    echo "  Installation Component"
    echo
    if [ "$group_info" = yes ]
    then
        if [ ${groups:-0}} -eq 0 ]
        then
            echo
            echo "There is no group information for this release."
            groups=0
        fi
    else
        groups=0
    fi

    if [ $groups -gt 0 ]
    then
        unset COMP_TYPES
        g=1
        while [ $g -le $groups ]
        do
            eval glist=\$group_comp_$g
            eval group_desc=\$group_desc_${g}
            echo
            echo "               GROUP $g: $group_desc"
            if [ -z "$glist" ]
            then
                echo "         0 KB  None"
            else
                for n in $glist
                do
                    eval desc=\$cmp_${n}_desc
                    eval size=\$cmp_${n}_size
                    echo $n $size | awk '{printf(" %2d %6s KB", $1, $2)}'
                    echo "  $desc"
                    SIZE="$SIZE + $size"
                done
            fi
            g=`expr $g + 1`
        done
        echo
    elif [ -n "$subprods" ]
    then
        COMP_TYPES=subprod
    elif [ -z "$required_cmps" ]
    then
        COMP_TYPES=comp
    else
        COMP_TYPES="required recommend optional auxiliary"
        comp_separator="yes"
    fi

    for comp_type in $COMP_TYPES
    do
        if [ $comp_type = subprod  -o \
             $comp_type = comp ]
        then
            N=${cmps:-0}
            comp_type_=""
        else
            eval N=\${${comp_type}_cmps:-0}
            comp_type_=${comp_type}_
        fi

        if [ $N -eq 0 ]
        then
            continue
        fi

        if [ "$comp_separator" = yes ]
        then
            echo
            case $comp_type in
                required ) echo "               Required Components" ;;
               recommend ) echo "               Recommended Components" ;;
                optional ) echo "               Optional Components" ;;
               auxiliary ) echo "               Auxiliary Components" ;;
            esac
        fi

        n=1
        while [ $n -le $N ]
        do
            eval desc=\$${comp_type_}cmp_${n}_desc
            eval size=\$${comp_type_}cmp_${n}_size
            echo $t $size | awk '{printf(" %2d %6s KB", $1, $2)}'
            echo "  $desc"
            t=`expr $t + 1`
            n=`expr $n + 1`
            SIZE="$SIZE + $size"
        done
    done
    echo

    SIZE=`expr $SIZE`
    echo $SIZE | awk '{printf("%10s KB  ", $1)}'
    echo "Total size for $TOTAL components (installed)"

    if [ $compress != no ]
    then
        # Display compression value and ratio.
        CSIZE=`$DU file[0-9] file[1-9][0-9] 2>/dev/null |
               awk 'BEGIN {sum=0} {sum += $1 / 2} END {print sum}'`
        COMPRESSION=`expr ${CSIZE}0000 / $SIZE | sed -e 's/..\$/.&/'`
        case "$COMPRESSION" in
        -* )
            # The numbers are too big. Compute in M-bytes, not K-bytes.
            CSIZE=`expr $CSIZE / 1000 + 1`
            SIZE=`expr $SIZE / 1000 + 1`
            COMPRESSION=`expr ${CSIZE}0000 / $SIZE | sed -e 's/..\$/.&/'`
            UNIT=MB
            ;;
        * )
            UNIT=KB
        esac
        RATIO=`expr ${SIZE}00 / $CSIZE | sed -e 's/..\$/.&/'`
        echo $CSIZE $UNIT | awk '{printf("%10s %s  ", $1, $2)}'
        echo "Size on $device_kind (${COMPRESSION}% of its original size)"
        echo "               Compression ratio: ${RATIO} to 1"
    fi
    echo
}

#------------------------------------------------------------------------
do_readtape() {
#------------------------------------------------------------------------

    $do_trace
    if [ ! -w . ]
    then
        Log err "You must have write capability in this directory to run $CMD."
        status=1
        exit $status
    fi

    echo
    if [ "$fileN_only" = yes ]
    then
        SKIP="Skipping file0"
        echo "Will ONLY read file$NN from $TAPE_DEV into directory:"
    else
        echo About to read files from tape $TAPE_DEV into directory:
    fi
    echo ${prod_location:-`pwd`}

    if [ $verify = yes ]
    then
        echo Will verify the tape after reading it.
    fi

    rewind_tape

    f=0
    sizet=0
    TOTAL=1  # Reset by calling do_stattape below
    bs=$FIRSTBS
    while [ $f -lt $TOTAL ]
    do
        NEED_REWIND=yes
        if [ "$fileN_only" = yes ]
        then
            TOTAL=9999
            if [ $f -lt $NN ]
            then
                $ECHON "$SKIP"
                $MT $TAPE_DEV fsf 1
                bs=$OTHERBS
                p=$f
                f=`expr $f + 1`
                SKIP=" $f"
                continue
            elif [ $f -gt $NN ]
            then
                rewind_tape
                return
            fi
        fi

        Log_desc "Reading file${f}$Of"
        if [ $raw_mode = yes ]
        then
            Log aux "dd if=$TAPE_DEV of=file$f $DD_OPTS"
            dd if=$TAPE_DEV of=file$f $DD_OPTS 2>$TMP
            dd_status=$?
        else
            Log aux "dd if=$TAPE_DEV of=file$f ibs=$bs $DD_OPTS"
            dd if=$TAPE_DEV of=file$f ibs=$bs $DD_OPTS 2>$TMP
            dd_status=$?
        fi
        Log_TMP

        if [ $dd_status -eq 0 ]
        then
            sizef=`$DU  file$f | awk '{print $1}'`
            sizef=`expr $sizef / 2`
            sizet="$sizet + $sizef"
            Log note "file$f read (size: $sizef KB)"
        else
            Log err "Read error on file$f.  Are you sure you"
            Log cont "have a Rational product tape in $TAPE_DEV?"
            sound_alarm Read
        fi

        if [ "$fileN_only" = no  -a  $f -eq 0 ]
        then
            # After reading first file, extract number of components (TOTAL)
            do_stattape
            Log note "Will read in file1 .. file$LAST from $TAPE_DEV."
        fi

        bs=$OTHERBS  # subsequent block size
        p=$f
        f=`expr $f + 1`
    done
    sizet=`expr $sizet`
    Log note There are $f components on the tape.
    Log note They have been saved as file0 .. file$p.
    Log note "Total size: $sizet KB"
    eject_tape
    Log aux "Tape read completed for $product_name $banner_version"
}

#------------------------------------------------------------------------
do_writetape() {
#------------------------------------------------------------------------

    $do_trace
    echo
    if [ $verify = yes  -o  $CMD = duptape ]
    then
        echo Tape duplication procedure: first write, then verify.
    fi

    echo About to write the files in directory:
    echo
    echo ${prod_location:-`pwd`}
    ls -Ctr file[0-9]* 2>/dev/null
    echo
    echo onto the tape in drive $TAPE_DEV on host $HOST

    if [ $ask = yes ]
    then
        echo Make sure you have a clean tape loaded and ready to write
        get_result " " "Return to proceed ..."
    fi

    rewind_tape

    f=0
    sizet=0
    bs=$OTHERBS
    while [ -s file$f ]
    do
        NEED_REWIND=yes
        set -- `$DU  file$f`
        sizef=`expr $1 / 2`
        sizet="$sizet + $sizef"

        if [ $f = 0 ]
        then
            Log_desc "Writing file0 ($sizef KB)"
            Log aux "dd if=file0 of=$TAPE_DEV $DD_OPTS"
            dd if=file0 of=$TAPE_DEV $DD_OPTS 2>$TMP
            dd_status=$?
        else
            Log_desc "Writing file${f}$Of ($sizef KB)"
            if [ $raw_mode = yes ]
            then
                Log aux "dd if=file$f of=$TAPE_DEV $DD_OPTS"
                dd if=file$f of=$TAPE_DEV $DD_OPTS 2>$TMP
                dd_status=$?
            else
                Log aux "dd if=file$f obs=$bs of=$TAPE_DEV $DD_OPTS"
                dd if=file$f obs=$bs of=$TAPE_DEV $DD_OPTS 2>$TMP
                dd_status=$?
            fi
        fi
        Log_TMP

        if [ $dd_status -ne 0 ]
        then
            sound_alarm Write
        fi

        f=`expr $f + 1`
    done
    sizet=`expr $sizet`
    Log note "Total size: $sizet KB"
    eject_tape
    Log aux "Tape written for $product_name $banner_version"
}

#------------------------------------------------------------------------
do_verifytape() {
#------------------------------------------------------------------------

    $do_trace

    if [ "$TAPE_TYPE" = QIC ]
    then
        Log2 warn "Cannot verify QIC tapes.  Skipping verifytape."
        return
    fi

    echo
    echo About to verify the tape in drive $TAPE_DEV against files
    echo in directory:
    echo
    echo ${prod_location:-`pwd`}
    /bin/ls -Ctr file[0-9] file[1-9][0-9] 2>/dev/null

    rewind_tape

    if [ -z "$LAST" ]
    then
        do_stattape
    fi

    f=0
    bs=$FIRSTBS
    while [ -s file$f ]
    do
        NEED_REWIND=yes
        if [ $f = 0 ]
        then
            Log_desc "Comparing file0"
        else
            Log_desc "Comparing file${f}$Of"
        fi

        $do_sleep

        if [ $raw_mode = yes ]
        then
            Log aux "dd if=$TAPE_DEV $DD_OPTS | cmp - file$f"
            dd if=$TAPE_DEV $DD_OPTS 2>$TMP | cmp - file$f
            cmp_status=$?
        else
            Log aux "dd if=$TAPE_DEV ibs=$bs obs=1k $DD_OPTS | cmp - file$f"
            dd if=$TAPE_DEV ibs=$bs obs=1k $DD_OPTS 2>$TMP | cmp - file$f
            cmp_status=$?
        fi
        Log_TMP

        if [ $cmp_status -eq 0 ]
        then
            Log pos file$f verified okay
        else
            sound_alarm Compare
        fi
        bs=$OTHERBS  # subsequent block size
        f=`expr $f + 1`
    done
    eject=yes
    eject_tape
    Log aux "Tape verified for $product_name $banner_version"
}

#------------------------------------------------------------------------
do_duptape() {
#------------------------------------------------------------------------

    $do_trace
    do_writetape
    do_verifytape
    Log aux "Tape duplicated for $product_name $banner_version"
}

#------------------------------------------------------------------------
get_tape_type() {
#------------------------------------------------------------------------

    if [ -n "$TAPE_TYPE" ]
    then
        return
    elif [ "$ask" = no ]
    then
        TAPE_TYPE=8mm
        return
    fi

    echo
    if [ "$verify" = yes ]
    then
        echo "Cannot verify QIC tapes."
        echo "Will skip the verifytape step if the tape type is QIC."
        tell_reset="echo Resetting verify flag=no."
    else
        tell_reset=':'
    fi

    eval $tell_conv Will use conv=sync for dd command when writing QIC tapes.

    get_result "Input tape type (8mm, 4mm or QIC):" 8mm
    case $result in
        q*|Q* )
            TAPE_TYPE=QIC
            eval $tell_reset
            verify=no
            echo Setting dd command conv=sync.
            DD_OPTS='conv=sync'
            ;;
        * )
            TAPE_TYPE=$result
            DD_OPTS=
            ;;
    esac
}

#------------------------------------------------------------------------
get_tape_dev() {
#------------------------------------------------------------------------

    if [ $ask = no ]
    then
        TAPE_DEV=$def_tape_dev
        return
    fi

    echo
    echo "You need to specify a NO-REWIND tape device."
    echo
    echo "Here is a list of possible choices:"

    if [ -x /bin/ksh ]
    then
        # Use ksh select to pick the tape device.
        devices=`/bin/ls $show_tape_devs`
        if [ -n "$devices" ]
        then
            echo "typeset -L N
            N=\`/bin/ls $show_tape_devs | wc -l\`
            PS3=\"Enter NO-REWIND tape device (1-\$N) #: \"
            echo
            select dn in \`/bin/ls $show_tape_devs\`
            do
                if [ -n \"\$dn\" ]
                then
                    echo TAPE_DEV=\$dn > $TMP
                    break
                fi
            done" > $GET_DEV

            /bin/ksh -p $GET_DEV
            if [ -s $TMP ]
            then
                . $TMP
            fi

            if [ -n "$TAPE_DEV" ]
            then
                return
            fi
        fi
    fi

    eval /bin/ls -C $show_tape_devs 2>/dev/null
    echo
    echo "For $SYS_NAME you need to specify something like '$def_tape_dev'."
    echo "$explain"
    get_result "Input tape device:" $def_tape_dev
    TAPE_DEV=$result
}

#==============================================================================
# Main

while [ $# -gt 0 ]
do
    case $1 in
        -c* ) ;;
        -e* ) eject=yes ;;
        +e* ) never_eject=yes ;;
        -f  ) ask=no ;;
        -h* ) Usage 0 ;;
        -i  ) install_only=yes ;;
        -g* ) group_info=yes ;;
        -l* ) license_info=yes ;;
        -p* ) product_info=yes ;;
        -m  ) MAKE_GOPL=yes; READ_ONLY=no  ;;
        -mr ) MAKE_GOPL=yes; READ_ONLY=yes ;;
        -obs) OTHERBS=$2; shift ;;
        -r* ) raw_mode=yes ;;
        -s  ) echo "$CMD: Option '$1' obsolete--ignoring" ;;
        -v  ) verify=yes ; unset TAPE_TYPE ;;
        -x  ) do_trace='set -x'; set -x ;;
        -0  ) fileN_only=yes; NN=0 ;;
    [0-9]*  ) if [ $CMD = pl ]
              then
                  break
              else
                  fileN_only=yes; NN=$1
              fi
              ;;
        -*  ) echo "$CMD: Option '$1' not recognized."; Usage 0 ;;
         *  ) break ;;
    esac
    shift
done
args="$*"

#------------------------------------------------------------------------
# Install the rest of the tape scripts.
do_install=no
for tape_cmnd in $alias_list
do
    if [ ! -x $DIR/$tape_cmnd ]
    then
        if [ "$tape_cmnd" = pl  -a  ! -f $GOPL ]
        then
            continue
        fi
        install_list="$install_list $tape_cmnd"
        do_install=yes
    fi
done

install_mesg="Nothing to install."
if [ $do_install = yes ]
then
    Log note "Installing other 'tape' commands in $DIR:"
    for tape_cmnd in $install_list
    do
        if [ ! -w $DIR ]
        then
            Log err "Installation of tape command aliases cannot be done."
            Log cont "$DIR not writeable"
            unset install_mesg
            break
        fi

        (cd $DIR
         ln -s $CMD $tape_cmnd && Log pos "  installed: $tape_cmnd"
        )
        install_mesg="Installation of tape command aliases completed."
    done
fi

if [ $install_only = yes ]
then
    Log aux "$install_mesg"
    cleanup0 Quit
    exit
elif [ $do_install = yes ]
then
    Log aux "$install_mesg"
    echo
fi

#------------------------------------------------------------------------
# Set the tape device and some architecture specific messages.

echo "Rational Product Release Media Utility: $CMD  $Revision: 1.94 $xx"
if [ -x /bin/uname ]
then
    UNAME=/bin/uname
elif [ -x /usr/5bin/uname ]
then
    UNAME=/usr/5bin/uname
else
    echo "Cannot determine system architecture. The 'uname' command not found."
    exit 1
fi
SYS_NAME=`$UNAME -s`

DU="/usr/bin/du -s"
LS='ls -l'
MT="mt -f"

offline=rewoffl
def_tape_dev=N/A
show_tape_devs="/dev/nr[ms]t* /dev/r[ms]t*n /dev/rmt/*"

case "$SYS_NAME" in
    AIX )
        ARCH=rs6k
        LS='ls -lg'
        def_tape_dev=/dev/rmt0.5
        show_tape_devs="/dev/rmt*.5"
        explain="              (the '.5' -----vv  specifies no-rewind)"
        ;;
    OSF1 )
        ARCH=alpha_osf1
        SYS_NAME="Compaq Tru64"
        do_sleep='sleep 10'
        def_tape_dev=/dev/nrmt0l
        show_tape_devs="/dev/nrmt*"
        explain="            (the 'n' ----v  specifies no-rewind)"
        ;;
    IRIX* )
        ARCH=mips_irix5
        SYS_NAME=IRIX
        LS='ls -g'
        do_sleep='sleep 10'
        offline=offline
        def_tape_dev=/dev/nrtape
        show_tape_devs="/dev/rmt/tps*nr* /dev/nrtape* /dev/nrst*"
        explain="            (the 'nr' specifies no-rewind)"
        ;;
    HP-UX )
        ARCH=hppa_hpux
        DU="/bin/du -s"
        LS='ls -g'
        MT="mt -t"
        do_sleep='sleep 10'
        offline=offl
        def_tape_dev=/dev/rmt/0mn
        show_tape_devs="/dev/rmt/*n /dev/rmt/*nb"
        explain="                  (the 'n' ----v  specifies no-rewind)"
        ;;
    SunOS )
        DU="/usr/5bin/du -s"
        SYS_REL=`$UNAME -r`
        case $SYS_REL in
          5.* )
            ARCH=sun4_solaris2
            SYS_NAME=Solaris
            def_tape_dev=/dev/rmt/0lbn
            show_tape_devs="/dev/rmt/* /dev/nr[ms]t*"
            explain="            (the 'n' ---------v  specifies no-rewind)"
            ;;
          * )
            ARCH=sun4
            def_tape_dev=/dev/nrst0
            show_tape_devs="/dev/nr[ms]t*"
            explain="            (the 'n' ----v  specifies no-rewind)"
            ;;
        esac
        ;;
    Linux )
        case `$UNAME -rm` in
        2.*i?86 )
            ARCH=i386_linux2
            ;;
        2.*ia64 )
            ARCH=ia64_linux2
            ;;
        esac
        ;;
esac

trap 'cleanup0 Quit' 0
trap 'cleanup0 Hangup' 1
trap 'cleanup0 Interrupted' 2
trap 'cleanup0 Quit' 3
trap 'cleanup0 Terminated' 15

case $CMD in
    stattape )
        Log_aux=':'
        unset DISPLAY
        select_prod
        do_stattape
        exit $status
        ;;
    readtape )
        Doing=Reading
        check_dir
        ;;
    writetape )
        Doing=Writing
        select_prod
        do_stattape
        TAPE_TYPE=
        tell_conv="Log cont"
        ;;
    duptape )
        Doing=Duplicating
        select_prod
        do_stattape
        TAPE_TYPE=
        tell_conv="Log cont"
        verify=yes
        ;;
    archivetape )
        Log_aux=':'
        unset DISPLAY
        do_archivetape
        ;;
    verifytape )
        Doing=Verifying
        select_prod
        do_stattape
        TAPE_TYPE=
        verify=yes
        ;;
    pl )
        Log_aux=':'
        unset DISPLAY
        select_prod
        ;;
    * )
        echo "readtape: unknown command alias: $CMD."
        cleanup0 Quit
        exit 1
        ;;
esac

get_tape_dev
get_tape_type

echo
echo "No-rewind tape device: $TAPE_DEV"
echo "            Tape type: $TAPE_TYPE"

#------------------------------------------------------------------------
# Start timer if it exists.
#------------------------------------------------------------------------
if [ -x $ELAPSE ]
then
    start=`$ELAPSE`
fi

#------------------------------------------------------------------------
# Do command: readtape, writetape, verifytape, or duptape
#------------------------------------------------------------------------

do_$CMD

if [ $verify = yes ]
then
    if [ $CMD = readtape  -o  $CMD = writetape ]
    then
        do_verifytape
    fi
fi

cleanup0

