#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# bos720 src/bos/usr/bin/mksysb/listvgbackup.sh 1.25.11.6 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 1999,2015 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)23        1.25.11.6  src/bos/usr/bin/mksysb/listvgbackup.sh, cmdbsys, bos720, 1508A_720 2/11/15 16:58:39
############################
# COMPONENT NAME: cmdbsys
# FILE NAME: listvgbackup.sh
# ORIGINS: 27
#
# FILE DESCRIPTION: This shell script allows listing and restoring of individual
#                   files from a system (rootvg) backup, volume group backup,
#                   or workload partition backup
#                   created with the mksysb, savevg, or savewpar commands.
#                   The source of the backup may be file, tape, cdrom, or dvd.
#
#                   There are several commands linked to this script:
#                      lsmksysb, lssavevg, lssavewpar, restorevgfiles, and
#                      restwparfiles.
#                   Behavior is different based upon the basename of the 
#                   invoked command.
#
# RETURN VALUE DESCRIPTION:
#
# EXTERNAL PROCEDURES CALLED:
#
###########################
#
# Input flags:
#-----------------------------------------------------------------------
# -b blocks   ## Number of 512-byte blocks to read in a single
#             ## input operation 
#             ## Defaults to the default of the restore command
#-----------------------------------------------------------------------
# -f device   ## Device (file, tape, cdrom) containing the backup
#             ## Default: /dev/rmt0
#-----------------------------------------------------------------------
# -r          ## Indicates files are to be restored from the backup
#             ## List the files to be restored in the filelist
#             ## Not required for "restorevgfiles" or "restwparfiles"
#             ## Default: list files only
#-----------------------------------------------------------------------
# -a          ## Verify tape physical block size 
#             ## (only applicable if tape device)
#-----------------------------------------------------------------------
# -m          ## Restores informational and control files (restwparfiles)
#-----------------------------------------------------------------------
# -s          ## Specify if backup is of a user volume group (not rootvg)
#             ## (not allowed with lssavewpar or restwparfiles)
#-----------------------------------------------------------------------
# -d path     ## Directory to restore files to
#             ## (only used with "-r", restorevgfiles, or restwparfiles
#-----------------------------------------------------------------------
# -D          ## Produces debug output
#-----------------------------------------------------------------------
# -B          ## List contents of /var/adm/ras/vgbackuplog
#             ## which is the system's volume group backup log.
#-----------------------------------------------------------------------
# file_list   ## List of files to be restored if -r flag specified
#             ## Default: restore all files. Note - if file_list is
#             ## not specified, users should restore to a temporary
#             ## directory (not /).
#-----------------------------------------------------------------------
# -l          ## List logical volume, filesystem, and general information
#             ## about a backup image.
#-----------------------------------------------------------------------
# -L          ## List fileset information (such as lslpp -l)
#             ## about a rootvg or wpar backup image.
#-----------------------------------------------------------------------
# -c          ## List the output from -l, or -L flags using colon 
#             ## separation.
#-----------------------------------------------------------------------
# -V          ## Verify the readability of a backup image or tape
#             ## by reading the header information of each file in the 
#             ## backup.
#-----------------------------------------------------------------------
#
#
# Functions
#    altertape
#    compare_options
#    cleanup
#    create_tmp_dir 
#    debug_switch
#    determine_conflicting_options
#    getoptions
#    get_stanza_data
#    get_vgdata
#    get_lvmaps
#    determine_backup_type
#    ls_backup_lpp
#    ls_backup_properties
#    relative_to_absolute
#    restore_multivolumeCD
# 
# Return Codes
# 0    Successful return
# 1    Usage message returned
# 2    Error encountered
# 3    Trap

export PATH="/usr/bin:/usr/sbin:$PATH"  #adding AIX Path followed by user's Path

function altertape
{
# sets tape block size to the value used for creating the backup
typeset adevice=$DEVICE

TAPEBLKSZ=tapeblksz                    # name of file with tape info
TMPDIR=/tmp/_mksysb.$$                 # tmp dir for restoring tapeblksz

create_tmp_dir $TMPDIR                 # create tmp dir for tapeblksz file
olddir=`pwd`
cd $TMPDIR

/usr/bin/dspmsg -s $MSGSET $MSGCAT 38 \
'0512-048 Verifying block size for tape device.\n'

# Determine and save old block size
OLDBLOCKSZ=`LC_MESSAGES=C /usr/sbin/lsattr -E -O -a block_size -l $BASE_DEV | /usr/bin/grep -v block_size`

if [ "$BACKUPTYPE" = "rvg" ]
then
    # Set blocksize to 512 if System Backup
    [ $OLDBLOCKSZ -ne 512 ] && /usr/sbin/chdev -l $BASE_DEV -a block_size=512 >/dev/null 2>&1
    # Restore the tapeblksz file
    TAPEFILE='-s 2'                    # location of file on tape
    [[ $adevice = /dev/rmt+([0-9])\.[$NRWFLAGS] ]] || adevice=$adevice.1
    /usr/sbin/restore $TAPEFILE -xqf $adevice ./$TAPEBLKSZ > /dev/null

    # Rewind the tape and set block size to value in tapeblksz file
    tctl -f $DEVICE rewind
    set -- `cat $TAPEBLKSZ`
    TBLOCKSZ=$1
    if [ $TBLOCKSZ -ne 512 ]
    then
        /usr/sbin/chdev -l $BASE_DEV -a block_size=$TBLOCKSZ >/dev/null 2>&1
    fi
    cd $olddir
    /bin/rm -rf $TMPDIR 2>/dev/null
    TMPDIR=

    # setup for next restore/list from tape
    TAPEFILE='-s 4'
elif [ "$BACKUPTYPE" = "wpar" ]
then
    TAPEBLKSZ=${DATA_ROOT_DIR}/tapeblksz         # name of file with tape info
    # Using a wpar backup - set blocksize to zero if needed
    [[ $OLDBLOCKSZ -ne $ZEROBLKSZ ]] && /usr/sbin/chdev -l $BASE_DEV -a block_size=0 > /dev/null 2>&1

    /usr/sbin/restore -xqf $DEVICE $TAPEBLKSZ > /dev/null

    # Rewind the tape and set block size to value in tapeblksz file
    tctl -f $DEVICE rewind
    if [ -s "$TAPEBLKSZ" ]
    then
         set -- `cat $TAPEBLKSZ`
         TBLOCKSZ=$1
         if [ $TBLOCKSZ -ne $ZEROBLKSZ ] 
         then
             /usr/sbin/chdev -l $BASE_DEV -a block_size=$TBLOCKSZ >/dev/null 2>&1
         fi
    fi
    cd $olddir
    /bin/rm -rf $TMPDIR 2>/dev/null
    TMPDIR=
else 
    # Using a user vg backup - set blocksize to zero if needed
    [[ $OLDBLOCKSZ -ne $ZEROBLKSZ ]] && /usr/sbin/chdev -l $BASE_DEV -a block_size=0 > /dev/null 2>&1

    # restore files looking for file list should be first
    # this will give you the location of the tapeblksz file
    TMPDIR_LIST=`ls $TMPDIR`
    /usr/sbin/restore -xqf $DEVICE $BFLAG > /dev/null 2>&1 &
    PID=$!
    while [[ -n $PID ]]
    do
        DATA_LIST=`find $TMPDIR -print | grep vgdata.files`
        if [[ -n "$DATA_LIST" ]]
        then
            # Found vgdata.files
            sleep 5
            kill $PID >/dev/null 2>&1
            PID=
        elif [ "$TMPDIR_LIST" != "`ls $TMPDIR`" ]
        then
            # Backup possibly not a volume group backup
            DATA_LIST=`find $TMPDIR -print | grep vgdata.files`
            sleep 5
            kill $PID >/dev/null 2>&1
            PID=
        else
            # Still getting file list from backup, is restore done?
            PID=`ps $PID | grep $PID | awk '{print$1}'`
        fi
    done
    # resync the tape, if the device is no rewind
    [[ $DEVICE = /dev/rmt+([0-9]).[$NRWFLAGS] ]] && /usr/bin/mt -f /dev/$BASE_DEV.1 bsf 1

    # set VGDATA_FILE to unique file if found
    VGDATA_FILE=`ls ./tmp/vgdata 2>/dev/null | grep "vgdata.files*[0-9]"`
    if [[ -z $VGDATA_FILE ]]
    then
    # Look for non-unique DATA_LIST file and set if found.
        VGDATA_FILE=`ls ./tmp/vgdata 2>/dev/null | grep "vgdata.files"`
    fi
    if [[ -z $DATA_LIST ]]
    then
        cleanup "$EXIT_EC" \
        "`/usr/bin/dspmsg -s $MSGSET $MSGCAT 39 '
0512-049 Restore of /tmp/vgdata/vgdata.files failed.\n\
Unable to restore information regarding the tape block size.\n'`"
    fi

    # Has tapeblksz file already been restored?
    TAPEBLKSZ=`find $TMPDIR -print | grep tapeblksz`
    if [[ -z $TAPEBLKSZ ]]
    then
        # Look for tapeblksz file on tape
        TAPEBLKSZ=`/usr/bin/cat ./tmp/vgdata/$VGDATA_FILE | /usr/bin/grep tapeblksz`
        # vgdata.files might not be complete, so restore entire file
        if [[ ! -s $TAPEBLKSZ ]]
        then
            /usr/sbin/restore -xqf $DEVICE $BFLAG ./tmp/vgdata/$VGDATA_FILE >/dev/null 2>&1
            TAPEBLKSZ=`/usr/bin/cat ./tmp/vgdata/$VGDATA_FILE | /usr/bin/grep tapeblksz`
            if [[ -z $TAPEBLKSZ ]]
            then
                cleanup "$EXIT_EC" \
                "`/usr/bin/dspmsg -s $MSGSET $MSGCAT 39 '
0512-049 Restore of /tmp/vgdata/vgdata.files failed.\n\
Unable to restore information regarding the tape block size.\n'`"
            fi
            [[ $DEVICE = /dev/rmt+([0-9]).[$NRWFLAGS] ]] && /usr/bin/mt -f /dev/$BASE_DEV.1 bsf 1
            /usr/sbin/restore -xqf $DEVICE $BFLAG $TAPEBLKSZ > /dev/null
        fi
    fi
    if [ -s "$TAPEBLKSZ" ]
    then
         set -- `cat $TAPEBLKSZ`
         TBLOCKSZ=$1
         if [ $TBLOCKSZ -ne $ZEROBLKSZ ] 
         then
             /usr/sbin/chdev -l $BASE_DEV -a block_size=$TBLOCKSZ >/dev/null 2>&1
         fi
    fi
fi

cd $olddir
olddir=
}

function compare_options
{

########################################################################
## If the first option is set, the second option must also be set
########################################################################

        if [ $1 = "IN_CONJUNCTION" ]; then
                if [ $3 = "yes" -a $5 = "no" ]; then
                        MESG=`/usr/bin/dspmsg -s 5  mksysb.cat 89 \
                                "0512-308 $NAME: option -$2 must be used in conjunction \n\
with the -$4 option.\n" $2 $4 $NAME`
                        print "$MESG"
                        cleanup "$USAGE_EC"
                fi

########################################################################
## The options are mutually exclusive and cannot be called together
########################################################################

        elif [ $1 = "MUTUALLY_EXCLUSIVE" ]; then
                if [ $3 = "yes" -a $5 = "yes" ]; then
                        MESG=`/usr/bin/dspmsg -s 5  mksysb.cat 90 \
                                "0512-309 $NAME: option -$2 and -$4 are mutually exclusive.\n" \
                                $2 $4 $NAME`
                        print "$MESG"
                        cleanup "$USAGE_EC"
                fi
        fi

} ## end of compare_options

function cleanup
{
ec=$1
error=$2

    case "$ec" in
	"$USAGE_EC" )   
# -----------------------------------------------------------------------
#  Use this message if function was "listvgbackup"
# -----------------------------------------------------------------------
if [ $NAME = listvgbackup -o $NAME = lsmksysb \
     -o $NAME = lssavevg ]
then
	error="`/usr/bin/dspmsg -s $MSGSET $MSGCAT 64 '
Usage:  %s [-b blocks] [-f device] [-l] [-a] [-c] [-s] [-r] [-d path] [-B] [-D] [-L] [-V] [-n] [file_list]\n
-b blocks\tNumber of 512-byte blocks to read in a single
\t\tinput operation
-f device\tName of device to restore the information from.
\t\tDefault is /dev/rmt0
-l\t\tList backup information only.
-a\t\tAlter the tape block size if necessary to read the backup
\t\t(used only if tape device)
-c\t\tColon separate the information listed about a backup
-s\t\tIndicates the backup is of a user volume group.
\t\t(if not specified, the default is a root volume group)
-r\t\tRestore files from the backup
\t\tDefault is to list contents of backup
-d path\t\tDirectory to have files restored into
\t\t(Used only with -r flag, default is current directory)
-B\t\tDisplays past volume group and system backups from log 
-D\t\tProduces debug output
-L\t\tList fileset information (rootvg backup only).
-V\t\tVerify backup readability (tape only).
-n\t\tDo not restore ACLs, PCLs, or extended attributes.
file_list\tList of files to restore. (Used only with -r flag)\n' "$NAME" `"

elif [ $NAME = lssavewpar ]
then
	error="`/usr/bin/dspmsg -s $MSGSET $MSGCAT 82 '
Usage:  %s [-b blocks] [-f device] [-a] [-l | -L | -M | -N] [-c] [-D] [-V]\n
-b blocks\tNumber of 512-byte blocks to read in a single
\t\tinput operation
-f device\tName of device to restore the information from.
\t\tDefault is /dev/rmt0
-a\t\tAlter the tape block size if necessary to read the backup
\t\t(used only if tape device)
-l\t\tList backup information only.
-L\t\tList fileset information
-M\t\tLists information regarding writable namefs-mounted file systems
-N\t\tLists information regarding any writable NFS-mounted file systems
\t\tincluded in the backup. 
-c\t\tColon separate the information listed about a backup
-D\t\tProduces debug output
-V\t\tVerify backup readability (tape only).\n' "$NAME" `"

elif [ $NAME = restorevgfiles ]
then
# -----------------------------------------------------------------------
#  Otherwise, use this message, if function was a restore function
# -----------------------------------------------------------------------
	error="`/usr/bin/dspmsg -s $MSGSET $MSGCAT 88 '
Usage:  %s [-b blocks] [-f device] [-a] [-s] [-d path] [-D] [-m] [-n] [file_list]\n
-b blocks\tNumber of 512-byte blocks to read in a single
\t\tinput operation
-f device\tName of device to restore the information from.
\t\tDefault is /dev/rmt0
-a\t\tAlter the tape block size if necessary to read the backup
\t\t(used only if tape device)
-s\t\tIndicates the backup is of a user volume group.
\t\t(if not specified, the default is a root volume group)
-d path\t\tDirectory to have files restored into
\t\t(default is current directory)
-D\t\tProduces debug output
-m\t\tRestores only backup information and control files
-n\t\tDo not restore ACLs, PCLs, or extended attributes.
file_list\tList of files to restore.\n' "$NAME" `"
elif [ $NAME = restwparfiles ]
then
# -----------------------------------------------------------------------
#  Otherwise, use this message, if function was a restore function
# -----------------------------------------------------------------------
	error="`/usr/bin/dspmsg -s $MSGSET $MSGCAT 74 '
Usage:  %s [-b blocks] [-f device] [-a] [-m] [-d path] [-D] [-n] [file_list]\n
-b blocks\tNumber of 512-byte blocks to read in a single
\t\tinput operation
-f device\tName of device to restore the information from.
\t\tDefault is /dev/rmt0
-a\t\tAlter the tape block size if necessary to read the backup
\t\t(used only if tape device)
-m\t\tRestores only workload partition information and control 
\t\tfiles from the backup image.
-d path\t\tDirectory to have files restored into
\t\t(default is current directory)
-D\t\tProduces debug output
-n\t\tDo not restore ACLs, PCLs, or extended attributes.
file_list\tList of files to restore.\n' "$NAME" `"

else
# EXIT OUT - script was somehow run without using "listvgbackup" or "restorevgfiles"
print Bad script name - \"$NAME\"
print Should be either \"listvgbackup\" or \"restorevgfiles\"
fi ;;
        "$TRAP_EC" )
            error="`/usr/bin/dspmsg -s $MSGSET $MSGCAT 4 '0512-007 %s: Abnormal program termination.' "$NAME" `" ;;

	"$EXIT_EC" )
            ;; 

	*)      ;;
    esac

if [ $unmountcd -eq 1 ]
then
    sleep 10
    /usr/sbin/umount $TMPCDDIR 2>/dev/null
    if [ $? -ne 0 ]
    then
        sleep 10
        /usr/sbin/umount $TMPCDDIR 2>/dev/null
    fi
fi
if [ "$AUTORESUME" = "yes" ];then
    if [ -z "$OLDCDDEVICE" ];then
        OLDCDDEVICE=$DEVICE
    fi
    /usr/sbin/cdutil -r $OLDCDDEVICE > /dev/null 2>&1
fi
[ $REWIND -eq 1 ] && /usr/bin/tctl -f $DEVICE rewind

if [[ $ALTERTAPE = yes ]]
then
    if [[ -n $TBLOCKSZ && $OLDBLOCKSZ -ne $TBLOCKSZ ]]
    then
        /usr/sbin/chdev  -l $BASE_DEV -a block_size=$OLDBLOCKSZ >/dev/null 2>&1
    fi
fi

[ -d "$TMPCDDIR" ] && /bin/rm -rf $TMPCDDIR 2>/dev/null
[ -d "$TMPDIR" ] && /bin/rm -rf $TMPDIR 2>/dev/null


[ -n "$error" ] && echo "\n${error}\n"
trap '' 1 2 15
exit "$ec"
}

function create_tmp_dir 
{
dirname=$1

    umask 077
    /usr/bin/mkdir $dirname
    RC=$?
    if [[ $RC -ne 0 ]]
    then
        cleanup "$EXIT_EC" \
        "`/usr/bin/dspmsg -s $MSGSET $MSGCAT 40 '
0512-050 Could not create temporary directory %s\n' $dirname`"

    fi
return 0
}

function debug_switch
{
    if [ "$LISTVGBACKUP_DEBUG" ] || [ "$DEBUGFLAG" = "yes" ]
    then
        set -x                                    ## turn on cmd/function tracing
        for i in $(typeset +f)
        do
            typeset -ft $i
        done
    else
        set +x                                    ## turn off cmd/function tracing
    fi
}

function determine_conflicting_options
{
     if [[ "$METAFILESFLAG" = "yes" ]] && [[ -n "$RESTFILES" ]]
     then
            cleanup $USAGE_EC
     fi
     if [[ "$NAME" = "restorevgfiles" || "$NAME" = "restwparfiles" ]]; then

        if [ "$LSFLAG" = "yes" ] || \
                [ "$LPPFLAG" = "yes" ] || \
                [ "$SHOWBACKUPLOG" = "yes" ] || \
                [ "$VERIFYFLAG" = "yes" ] || \
                [ "$COLONFLAG" = "yes" ]
        then
            cleanup $USAGE_EC
        fi
     else

##########################################################
## Flags that cannot be used together
##########################################################

        compare_options "MUTUALLY_EXCLUSIVE" \
                        L $LPPFLAG             l $LSFLAG
        compare_options "MUTUALLY_EXCLUSIVE" \
                        L $LPPFLAG             d $DIRFLAG
        compare_options "MUTUALLY_EXCLUSIVE" \
                        L $LPPFLAG             r $RESTOREFLAG 
        compare_options "MUTUALLY_EXCLUSIVE" \
                        L $LPPFLAG             s $SAVEVGFLAG
        compare_options "MUTUALLY_EXCLUSIVE" \
                        l $LSFLAG              d $DIRFLAG
        compare_options "MUTUALLY_EXCLUSIVE" \
                        l $LSFLAG              r $RESTOREFLAG 
        compare_options "MUTUALLY_EXCLUSIVE" \
                        B $SHOWBACKUPLOG       l $LSFLAG
        compare_options "MUTUALLY_EXCLUSIVE" \
                        B $SHOWBACKUPLOG       c $COLONFLAG
        compare_options "MUTUALLY_EXCLUSIVE" \
                        B $SHOWBACKUPLOG       r $RESTOREFLAG
        compare_options "MUTUALLY_EXCLUSIVE" \
                        B $SHOWBACKUPLOG       f $DEVICEFLAG
        compare_options "MUTUALLY_EXCLUSIVE" \
                        B $SHOWBACKUPLOG       s $SAVEVGFLAG
        compare_options "MUTUALLY_EXCLUSIVE" \
                        B $SHOWBACKUPLOG       L $LPPFLAG
        compare_options "MUTUALLY_EXCLUSIVE" \
                        B $SHOWBACKUPLOG       d $DIRFLAG
        compare_options "MUTUALLY_EXCLUSIVE" \
                        B $SHOWBACKUPLOG       b $BLOCKFLAG
        compare_options "MUTUALLY_EXCLUSIVE" \
                        B $SHOWBACKUPLOG       a $ALTERTAPE
        compare_options "MUTUALLY_EXCLUSIVE" \
                        V $VERIFYFLAG       l $LSFLAG
        compare_options "MUTUALLY_EXCLUSIVE" \
                        V $VERIFYFLAG       c $COLONFLAG
        compare_options "MUTUALLY_EXCLUSIVE" \
                        V $VERIFYFLAG       r $RESTOREFLAG
        compare_options "MUTUALLY_EXCLUSIVE" \
                        V $VERIFYFLAG       s $SAVEVGFLAG
        compare_options "MUTUALLY_EXCLUSIVE" \
                        V $VERIFYFLAG       L $LPPFLAG
        compare_options "MUTUALLY_EXCLUSIVE" \
                        V $VERIFYFLAG       d $DIRFLAG

        compare_options "IN_CONJUNCTION" \
                        l $LSFLAG              f $DEVICEFLAG
        compare_options "IN_CONJUNCTION" \
                        L $LPPFLAG             f $DEVICEFLAG 
        compare_options "IN_CONJUNCTION" \
                        V $VERIFYFLAG          f $DEVICEFLAG 

        if [[ $NAME = "restwparfiles" ]] || [[ $NAME = "restorevgfiles" ]]
	then
            compare_options "IN_CONJUNCTION" \
                        M $METAFILESFLAG       f $DEVICEFLAG 
        elif [[ $NAME = "lssavewpar" ]]
        then
            compare_options "MUTUALLY_EXCLUSIVE" \
                        l $LSFLAG              M $LSNAMEFSFLAG
            compare_options "MUTUALLY_EXCLUSIVE" \
                        L $LPPFLAG             M $LSNAMEFSFLAG
            compare_options "MUTUALLY_EXCLUSIVE" \
                        l $LSFLAG              N $LSNFSFLAG
            compare_options "MUTUALLY_EXCLUSIVE" \
                        L $LPPFLAG             N $LSNFSFLAG
            compare_options "MUTUALLY_EXCLUSIVE" \
                        M $LSNAMEFSFLAG        N $LSNFSFLAG
        fi
     fi

} ## end of determine_conflicting_options

function getoptions
{
    if [[ $NAME = restorevgfiles ]] || [[ $NAME = restwparfiles ]]
    then
	RESTOREFLAG=yes		## equivalent to "-r" flag
    fi

    # If invoked as restwparfiles, image could be mksysb or savewpar
    # so will have to recheck later on
    if [ "$NAME" = "lssavewpar" ] || [ "$NAME" = "restwparfiles" ]
    then
	WPAR_IMAGE=yes		
	BACKUPTYPE=wpar
    fi


    if [[ $NAME = lssavewpar ]] 
    then
        CMDOPTIONS=":b:f:aclDLMNV"
    elif [[ $NAME = restwparfiles ]] 
    then
        CMDOPTIONS=":b:f:amnDd:"
    else
        CMDOPTIONS=":b:f:aclmnsrDBLVd:"
    fi

    while getopts $CMDOPTIONS OPTION               ## Parse command line flags
    do
	case $OPTION in
	    b) BFLAG="-b $OPTARG" 
               BLOCKFLAG=yes;;  ## get number of blocks
	    f) DEVICE="$OPTARG"  
               DEVICEFLAG=yes;;  ## get backup device
	    a) ALTERTAPE=yes ;; ## Set tape block size to match value in backup
            m) METAFILESFLAG=yes;;  ## Restore control files
	    s) BACKUPTYPE=uvg 
               SAVEVGFLAG=yes ;; ## If specified, using a user vg backup
	    r) RESTOREFLAG=yes ;; ## If specified, do a listing of the backup
            D) DEBUGFLAG=yes ;;   ## If specified, turns on debug
            B) SHOWBACKUPLOG=yes;; ## If specified, lists contents of backup log
            L) LPPFLAG=yes;;  ## List the properties of a backup
            V) VERIFYFLAG=yes;;  ## List the properties of a backup
            l) LSFLAG=yes;;  ## List the properties of a backup
            n) DISABLEACLS="-n";;  ## ACLs, PCLs, and EAs should not be restored
            M) LSNAMEFSFLAG=yes;;  ## Show writable namefs mount info (lssavewpar)
            N) LSNFSFLAG=yes;;  ## Show writable NFS mount info (lssavewpar)
            c) COLONFLAG=yes;;  ## List using colon separated 
                               ## output (-l and -L only)
	    d) RESTOREDIR="$OPTARG" 
               DIRFLAG=yes;; ## Directory to restore files into
	    \?) cleanup "$USAGE_EC" "" ;;  ## Display usage message
	esac
    done

    shift $(( $OPTIND - 1 ))
    RESTFILES=$*
}

function get_stanza_data
{
    STANZA=$1    ## Stanza Name
    ATTR="$2"    ## Field Name=
    DSK=$3       ##      Unique Field Name Value (may be null)
    RECORD=$4    ## Field Name for stanza line you seek the data from.

    if [ "$DSK" = "" ]
    then
        DSK1="$DSK"
        /usr/bin/sed '/:$/i\
' $IMAGE_DATA | /usr/bin/grep -p "^"$STANZA: | \
        /usr/bin/egrep -p "^[ 	]+$ATTR[ 	]*=[ 	]*$DSK1" |  \
        /usr/bin/egrep "^[ 	]+$RECORD[ 	]*" | \
            /usr/bin/sed -e "s/[ 	]*=/ =/" -e "s/ =[ 	]*/ = /" | \
            /usr/bin/awk '{ for (i = 3; i <= NF; i++)
                        { print $i } }'
    else
        DSK1=$DSK"$"
        ## fgrep added to handle . and _ characters in user data search
	## fields (DSK).
	## First grep searches for stanza types.
	## fgrep eliminates problems with . and _ characters.
	## First egrep ensures that only the specific search criteria is
	## met (eliminates preceding and trailing characters).
        /usr/bin/sed '/:$/i\
' $IMAGE_DATA | /usr/bin/grep -p "^"$STANZA: | /usr/bin/fgrep -p -w $DSK | \
        /usr/bin/egrep -p "^[ 	]+$ATTR[ 	]*=[ 	]*$DSK1" |  \
        /usr/bin/egrep "^[ 	]+$RECORD[ 	]*" | \
            /usr/bin/sed -e "s/[ 	]*=/ =/" -e "s/ =[ 	]*/ = /" | \
            /usr/bin/awk '{ for (i = 3; i <= NF; i++)
                        { print $i } }'
    fi
    return 0
}

function get_vgdata
{
    # set VGDATA_FILE to unique file if found
    VGDATA_FILE=`ls $LSBACKUPDIR/tmp/vgdata | /usr/bin/grep "vgdata.files*[0-9]"`

    if [[ -z $VGDATA_FILE ]]
    then
    # Look for non-unique DATA_LIST file and set if found.
        VGDATA_FILE=`/usr/bin/ls $LSBACKUPDIR/tmp/vgdata | /usr/bin/grep "vgdata.files"`
    fi

    # Backup is not a volume group backup
    if [[ -z $VGDATA_FILE ]]
    then
        cd /  2>&1 >/dev/null
        exit
    fi

    # restore vgdata.files again to be sure entire file is restored
    [[ $DEVICE = /dev/rmt+([0-9])\.[$NRWFLAGS] ]] \
                           && /usr/bin/mt -f $DEVICE bsf 1

    VGDATA_FILES=/tmp/vgdata/$VGDATA_FILE
    /usr/sbin/restore -xqf $DEVICE $BFLAG .$VGDATA_FILES > /dev/null 2>&1
    
    [[ $DEVICE = /dev/rmt+([0-9])\.[$NRWFLAGS] ]] \
                           && /usr/bin/mt -f $DEVICE bsf 1 > /dev/null

    /usr/sbin/restore -xqf $DEVICE $BFLAG \
                           `/usr/bin/cat $LSBACKUPDIR$VGDATA_FILES` > /dev/null 2>&1
    /usr/bin/cat $LSBACKUPDIR$VGDATA_FILES | /usr/bin/grep tapeblksz >/dev/null 2>&1
    [[ $? -eq 0 ]] && tapeblksz_exists=yes

    # Get Volume group name
    VG=`/usr/bin/cat $LSBACKUPDIR$VGDATA_FILES | /usr/bin/grep -v "backup\.data" | /usr/bin/grep "\.data" | /usr/bin/awk -F/ '{print$4}'`
    if [ "$VG" = "" ]
    then
        VG=`/usr/bin/cat $LSBACKUPDIR$VGDATA_FILES | /usr/bin/grep "filesystems" | /usr/bin/awk -F/ '{print$4}'`
    fi  
    DATA_DIR="$DATA_BASEDIR/$VG"         # vg data Directory
    IMAGE_DATA="$DATA_DIR/$VG.data"      # vg Image.data file
    if [ "$VG" = "backup" ]
    then
        BACKUP_DATA="$DATA_DIR/vgdata/backup.data"
    else
        BACKUP_DATA="$DATA_DIR/backup.data"
    fi
}

## This function determines if backup 
## is a savevg/mksysb/or other kind of backup.
## (only called for -l, -L flags, where -s
## doesn't matter or with restwparfiles, which
## could be using a wpar backup or a mksysb image)
function determine_backup_type
{
typeset LSBACKUPDIR_LIST
typeset VGDATA_FILES
typeset IMAGE_DATA_TEMP
typeset IS_MKSYSB="yes"
typeset WHAT_IS_IT=""

IS_ZEROBLKSZ="no"
BLKSZ=""
    cd $LSBACKUPDIR
######################################
## First we get a listing of the backup
## directory.
######################################
    LSBACKUPDIR_LIST=`ls $LSBACKUPDIR` > /dev/null 2>&1

######################################
## If we are working with tape...
######################################
    if [[ $TAPEBACKUP = "yes" ]]; then

       ##############################################
       ## Let's get the current block size
       ##############################################
       BASE_DEV=`/usr/bin/basename $DEVICE | /usr/bin/cut -d . -f1`
       BASE_DEV1=`/usr/bin/basename $DEVICE`
       BLKSZ=`LANG=C lsattr -EOa block_size -l $BASE_DEV | grep -v block_size`
       if [[ "$BLKSZ" != "0" ]]; then
           ###########################################
           ## If current block size isn't 0 (variable)
           ## then maybe the backup was made at that size!
           ## This will generally be faster if this is 
           ## the case, let try to dd now.
           ###########################################
           /usr/bin/dd if=$DEVICE bs=$BLKSZ count=1 \
                       of=$FIRST_BLK conv=noerror > /dev/null 2>&1

           #################################
           ## Well if that last dd didn't work:
           ## try using a large (2048k) size and 
           ## conv=noerror
           #################################
           if [[ "$?" -ne 0 ]]; then 
               /usr/bin/mt -f $DEVICE bsf 1 > /dev/null 2>&1
               /usr/sbin/chdev -l $BASE_DEV1 -a block_size=0 >/dev/null 2>&1
               /usr/bin/dd if=$DEVICE bs=2048k count=1 \
                           of=$FIRST_BLK conv=noerror > /dev/null 2>&1

               #################################
               ## Well if that last dd didn't work:
               ## try using 512 since boot image is
               ## done using 512 block size
               #################################
               if [[ "$?" -ne 0 ]]; then 
                   /usr/bin/mt -f $DEVICE bsf 1 > /dev/null 2>&1
                   /usr/bin/dd if=$DEVICE bs=512 count=1 \
                               of=$FIRST_BLK conv=noerror > /dev/null 2>&1
               fi
               /usr/sbin/chdev -l $BASE_DEV1 -a block_size=$BLKSZ >/dev/null 2>&1
           fi
       else
           IS_ZEROBLKSZ="yes"
           /usr/bin/dd if=$DEVICE bs=512 count=4 \
                       of=$FIRST_BLK conv=noerror > /dev/null 2>&1
       fi
       ###############################
       ## Now, we have a block, so let's
       ## see what it is.
       ###############################
       WHAT_IS_IT=`LANG=C /usr/bin/file ${FIRST_BLK} | awk '{print $2}'`
       case "$WHAT_IS_IT"
       in
                  # looks like a fake mksysb boot image
          "ELF"|"commands")             # looks like a mksysb boot image
              IS_MKSYSB="yes"
              [[ "$ALTERTAPE" = "yes" ]] && altertape
              /usr/bin/rm -fr $FIRST_BLK

              ##############################################
              ## If we made it to the 4th image (the mksysb)
              ## then let's dd it! Either dd large or small
              ## whatever we determined earlier.
              ##############################################
              if [[ "$?" -eq 0 ]]; then
                 if [[ "$IS_ZEROBLKSZ" = "yes" ]]; then
                     /usr/bin/mt -f $DEVICE bsf 1  > /dev/null 2>&1
                     if [[ $DEVICE = /dev/rmt+([0-9])\.[$NRWFLAGS] ]]; then
                        /usr/bin/tctl -f $DEVICE fsf 3 > /dev/null 2>&1
                     else
                        /usr/bin/tctl -f $DEVICE.1 fsf 3 > /dev/null 2>&1
                     fi
                     /usr/bin/dd if=$DEVICE bs=512 count=4 \
                                 of=$FIRST_BLK conv=noerror > /dev/null 2>&1
                 else
                     if [[ $DEVICE = /dev/rmt+([0-9])\.[$NRWFLAGS] ]]; then
                        /usr/bin/tctl -f $DEVICE fsf 3 > /dev/null 2>&1
                     else
                        /usr/bin/tctl -f $DEVICE.1 fsf 3 > /dev/null 2>&1
                     fi
                     /usr/bin/dd if=$DEVICE bs=$BLKSZ count=1 \
                                 of=$FIRST_BLK conv=noerror > /dev/null 2>&1
                 fi
              fi
          ;;
          "backup/restore")  # looks like a savevg or wpar backup
              if [ "$NAME" = "lssavewpar" ] || [ "$NAME" = "restwparfiles" ]
              then
                 BACKUPTYPE="wpar"
              else
                 BACKUPTYPE="uvg_or_wpar"
              fi
              [[ "$ALTERTAPE" = "yes" ]] && altertape
              IS_MKSYSB="no"
          ;;
          *)                 # not a volume group backup
              /usr/bin/mt -f $DEVICE bsf 1  > /dev/null 2>&1
              DEV_BNAME=`/usr/bin/basename $DEVICE 2> /dev/null`
              if [ "$NAME" != "lssavewpar" ] && [ "$NAME" != "restwparfiles" ]
              then
                 /usr/bin/dspmsg -s 3 $MSGCAT 28 \
"0512-060 %s: The backup %s is not a volume group \
backup.\nPreview of Volume Group attributes canceled.\n" \
$NAME $DEV_BNAME ""
              else
                 /usr/bin/dspmsg -s 3 $MSGCAT 30 \
"0512-067 %s: The backup %s is not a workload partition \
backup.\nPreview of Workload Partition attributes canceled.\n" \
$NAME $DEV_BNAME
              fi
              cd / > /dev/null 2>&1
              /usr/bin/rm -fr $FIRST_BLK > /dev/null 2>&1
              /usr/bin/rm -fr $LSBACKUPDIR > /dev/null 2>&1
              cleanup $EXIT_EC
          ;;
       esac
    else
       ## Not a tape, just get the first block.
       /usr/bin/dd if=$DEVICE bs=1k count=1 of=$FIRST_BLK > /dev/null 2>&1
    fi

###################################
## Now...
## We restore that "first_blk" file
## we dd'ed off the tape/file and
## check and see what files we get.
## This way we can see if it's a
## mksysb, savevg, or wpar image.
###################################
    /usr/sbin/restore -xqf $FIRST_BLK > /dev/null 2>&1 &
    PID=$!
    while [[ -n $PID ]]
    do
        IMAGE_INFO_FILE=`/usr/bin/find $LSBACKUPDIR -print | /usr/bin/grep image.info` > /dev/null 2>&1 
        VGDATA_FILES=`/usr/bin/find $LSBACKUPDIR -print | /usr/bin/grep vgdata.files` > /dev/null 2>&1 
        BOSINST_TEMP=`/usr/bin/find $LSBACKUPDIR -print | /usr/bin/grep bosinst.data` > /dev/null 2>&1

	if [[ -n "$IMAGE_INFO_FILE" ]]
	then
            # Found image info file
	    BACKUPTYPE=`/usr/bin/awk '{print $1}' $IMAGE_INFO_FILE`
	    BACKUPSOURCE=`/usr/bin/awk '{print $2}' $IMAGE_INFO_FILE`
            /usr/bin/kill $PID > /dev/null 2>&1
            PID=
        elif [[ -n "$VGDATA_FILES" ]]
        then
            # Found vgdata.files
            /usr/bin/kill $PID > /dev/null 2>&1
            PID=
            BACKUPTYPE=uvg
        elif [[ -n "$BOSINST_TEMP" ]]
        then 
            # Found bosinst.data file
            /usr/bin/kill $PID > /dev/null 2>&1
            PID=
            BACKUPTYPE=rvg
        else
            # Still getting file list from backup, is restore done?
            /usr/bin/ps $PID > /dev/null 2>&1
            PID=`ps $PID | grep $PID | awk '{ print $1 }'`
            if [ \( -z "$PID" \) -a \( -z "$IMAGE_DATA_TEMP" \) \
                    -a \( -z "$IMAGE_INFO_FILE" \) \
                    -a \( -z "$VGDATA_FILES" \) ]; then
                # Unknown backup type
                BACKUPTYPE=
            fi
        fi
    done
}

###########################################
## get_lvmaps: Checks to see whether lv map
## files need to be restored from the
## backup
##
###########################################
function get_lvmaps
{
    if [[ $NAME = "restorevgfiles" ]]
	then
		RESTFILES=`grep "^[ 	]*MAPFILE=" "$IMAGE_DATA" | awk '{if( -n $2 ) {print "."$2}}'`
	else
		RESTFILES=`grep "^[ 	]*MAPFILE=" "$IMAGE_DATA" | awk '{if( -n $2 ) {print $2}}'`
	fi
    if [[ -n "$RESTFILES" ]]
    then 
       return 0
    else 
       return 1
    fi
}

function ls_backup_lpp
{
    /usr/bin/mkdir $LSBACKUPDIR 
    cd $LSBACKUPDIR
    [[ "$BACKUPTYPE" != "wpar" ]] && determine_backup_type

###########################################
## Check and see if backup is ROOTVG or WPAR
## If it is, then restore backup.data
## and print out the lpp -l information
###########################################

    DEV_BNAME=`/usr/bin/basename $DEVICE 2> /dev/null`
    if [[ $BACKUPTYPE = rvg  ]]
    then
	VG="rootvg"
        SEEK="-s 4"
        DATA_ROOT_DIR=.
        DATA_DIR=/tmp/vgdata/rootvg
        WPARSPECFILE=
        if [ "$NAME" = "lssavewpar" ] || [ "$NAME" = "restwparfiles" ]
        then
           /usr/bin/dspmsg -s 3 $MSGCAT 30 \
"0512-067 %s: The backup %s is not a workload partition \
backup.\nPreview of Workload Partition attributes canceled.\n" \
$NAME $DEV_BNAME
            cleanup $EXIT_EC
        fi
    else
	VG=""
        DATA_ROOT_DIR=./.savewpar_dir
        DATA_DIR=/.savewpar_dir
        WPARSPECFILE=${DATA_ROOT_DIR}/wpar.spec
        if [ "$NAME" != "lssavewpar" ] && [ "$NAME" != "restwparfiles" ]
        then
           /usr/bin/dspmsg -s 3 $MSGCAT 28 \
"0512-060 %s: The backup %s is not a rootvg volume group \
backup.\nPreview of Volume Group attributes canceled.\n" \
$NAME $DEV_BNAME rootvg
            cleanup $EXIT_EC
        fi
    fi
    if [[ $BACKUPTYPE = rvg  || $BACKUPTYPE = wpar ]]
    then
        if [[ $DEVICE = /dev/rmt+([0-9])\.[$NRWFLAGS] ]]; then
            /usr/sbin/restore -xqf $DEVICE $SEEK $BFLAG \
               ${DATA_ROOT_DIR}/image.data .${DATA_DIR}/backup.data \
               ${WPARSPECFILE} > /dev/null 2>&1
        elif [[ $DEVICE = "/dev/rmt"* ]]; then
            /usr/sbin/restore -xqf $DEVICE.1 $SEEK $BFLAG \
               ${DATA_ROOT_DIR}/image.data .${DATA_DIR}/backup.data \
               ${WPARSPECFILE} > /dev/null 2>&1
        else
            /usr/sbin/restore -xqf $DEVICE $BFLAG \
               ${DATA_ROOT_DIR}/image.data .${DATA_DIR}/backup.data \
               ${WPARSPECFILE} > /dev/null 2>&1
        fi

	# Check for alternate data files on a CD or DVD backup
	if [[ $BACKUPTYPE = wpar ]] && [[ $unmountcd = 1 ]]
	then
	    restore_alt_data || cleanup $EXIT_EC
	fi

        if [[ $BACKUPTYPE = rvg  ]]
        then
            IMAGE_DATA=$LSBACKUPDIR/image.data
        else
            IMAGE_DATA=$LSBACKUPDIR${DATA_DIR}/image.data
        fi
        BACKUP_DATA=$LSBACKUPDIR${DATA_DIR}/backup.data

        if [ -s $BACKUP_DATA ]; then
            OLDIFS=$IFS;IFS="_#_"
            while read line
            do
               if [[ $line = *"==================="* ]]; then
                   (( numBreaks = $numBreaks + 1 ))
               fi
               if [[ $COLONFLAG = yes ]]; then
                   if [[ $numBreaks -eq 3 ]]; then
                       read line
                       while [[ $line != *"================"* ]]
                       do
                           print "$line"
                           read line
                       done
                       (( numBreaks = $numBreaks + 1 ))
                   fi
               else
                   if [[ $numBreaks -eq 2 ]]; then
                      read line
                      while [[ $line != *"================"* ]]
                      do
                          if [[ $line = *"----"* ]]; then
                              echo $line
                          else
                              print "$line" 2> /dev/null
                          fi
                          read line
                      done
                      (( numBreaks = $numBreaks + 1 ))
                   fi
               fi
               done < $BACKUP_DATA
           fi
           IFS=$OLDIFS
    else
        DEV_BNAME=`/usr/bin/basename $DEVICE 2> /dev/null`
        if [ "$NAME" != "lssavewpar" ] && [ "$NAME" != "restwparfiles" ]
        then
           /usr/bin/dspmsg -s 3 $MSGCAT 28 \
"0512-060 %s: The backup %s is not a volume group \
backup.\nPreview of Volume Group attributes canceled.\n" \
$NAME $DEV_BNAME ""
        else
           /usr/bin/dspmsg -s 3 $MSGCAT 30 \
"0512-067 %s: The backup %s is not a workload partition \
backup.\nPreview of Workload Partition attributes canceled.\n" \
$NAME $DEV_BNAME
        fi
        /usr/bin/mt -f $DEVICE bsf 1 > /dev/null 2>&1
        cd / > /dev/null 2>&1
        /usr/bin/rm -fr $FIRST_BLK > /dev/null 2>&1
        /usr/bin/rm -fr $LSBACKUPDIR > /dev/null 2>&1
        cleanup $EXIT_EC
    fi
    [[ $TAPEBACKUP = "yes" ]] && /usr/bin/mt -f $DEVICE bsf 1 > /dev/null 2>&1
    cd / > /dev/null 2>&1
    /usr/bin/rm -fr $FIRST_BLK > /dev/null 2>&1
    /usr/bin/rm -fr $LSBACKUPDIR > /dev/null 2>&1
}

function ls_backup_properties
{
typeset numBreaks
typeset colon_line
typeset line

    /usr/bin/mkdir $LSBACKUPDIR
    cd $LSBACKUPDIR
    [[ "$BACKUPTYPE" != "wpar" ]] && determine_backup_type

#######################
## Backup is ROOTVG?
#######################

    DEV_BNAME=`/usr/bin/basename $DEVICE 2> /dev/null`
    if [[ $BACKUPTYPE = rvg ]]
    then
        if [ "$NAME" = "lssavewpar" ] || [ "$NAME" = "restwparfiles" ]
        then
	    /usr/bin/dspmsg -s 3 $MSGCAT 30 \
"0512-067 %s: The backup %s is not a workload partition \
backup.\nPreview of Workload Partition attributes canceled.\n" \
$NAME $DEV_BNAME
            cleanup $EXIT_EC
        fi
	VG="rootvg"
        if [[ $DEVICE = /dev/rmt+([0-9])\.[$NRWFLAGS] ]]; then
            /usr/sbin/restore -xqf $DEVICE -s 4 $BFLAG \
               ./image.data ./tmp/vgdata/rootvg/backup.data > /dev/null 2>&1
        elif [[ $DEVICE = "/dev/rmt"* ]]; then
            /usr/sbin/restore -xqf $DEVICE.1 -s 4 $BFLAG \
               ./image.data ./tmp/vgdata/rootvg/backup.data > /dev/null 2>&1
        else
            /usr/sbin/restore -xqf $DEVICE $BFLAG \
               ./image.data ./tmp/vgdata/rootvg/backup.data > /dev/null 2>&1
        fi
        IMAGE_DATA=$LSBACKUPDIR/image.data
        BACKUP_DATA=$LSBACKUPDIR/tmp/vgdata/rootvg/backup.data
        
##################################################
## Get and set backup size variables and set 
## general info variables.
## Check flags for "colon delimited" output.
## Parse backup.data for correct report section.
## Print report to stdout.
##################################################
     

	if [ "$BACKUPTYPE" = "rvg" ] 
	then
	   shrinkinfo=`/usr/bin/tail -1 $BACKUP_DATA 2> /dev/null`
	else
	   # shrinkinfo is in the third section of the wpar backup.data
	   shrinklno=`/usr/bin/grep -n "^================================" ${BACKUP_DATA} | \
	   /usr/bin/tail +3l | /usr/bin/head -1 | cut -d: -f1`

	   # skip heading
	   (( shrinklno = shrinklno + 2 ))

	   shrinkinfo=`/usr/bin/tail +${shrinklno} $BACKUP_DATA 2> /dev/null | /usr/bin/head -1`
		     
	fi

        BACKUP_SHRINK_SIZE=`echo $shrinkinfo \
                             | awk -F : '{print $1}'`
        BACKUP_SIZE=`echo $shrinkinfo \
                      | awk -F : '{print $2}'`
        IS_METADATA=`echo $shrinkinfo \
                      | awk -F : '{print $3}'`
	[[ "$IS_METADATA" = "" ]] && IS_METADATA="no"
        DATE_TIME=$( /usr/bin/awk '$1=="DATE_TIME="{ print $2, $3, $4, $5, $6, $7 }' $IMAGE_DATA 2> /dev/null )
        UNAME_INFO=$( /usr/bin/awk '$1=="UNAME_INFO="{ print $2, $3, $4, $5, $6 }' $IMAGE_DATA 2> /dev/null )
        OSLEVEL=$( /usr/bin/awk '$1=="OSLEVEL="{ print $2 }' $IMAGE_DATA 2> /dev/null )
        OSLEVEL_R=$( /usr/bin/awk '$1=="OSLEVEL_R="{ print $2 }' $IMAGE_DATA 2> /dev/null )
        OSLEVEL_S=$( /usr/bin/awk '$1=="OSLEVEL_S="{ print $2 }' $IMAGE_DATA 2> /dev/null )

#######################################
## Check and see if we are to colon 
## separate the data.
#######################################

        if [ $COLONFLAG = no ]; then
	    if [ "$BACKUPTYPE" = "rvg" ] 
	    then
                echo "VOLUME GROUP:\t\t$VG"
	    else
                echo "WORKLOAD PARTITION:\t$WPAR"
	    fi
            echo "BACKUP DATE/TIME:\t$DATE_TIME"
            echo "UNAME INFO:\t\t$UNAME_INFO"
            echo "BACKUP OSLEVEL:\t\t$OSLEVEL"
            echo "MAINTENANCE LEVEL:\t$OSLEVEL_R"
            [[ -n ${OSLEVEL_S} ]] && \
				echo "SERVICEPACK LEVEL:\t$OSLEVEL_S"
            echo "BACKUP SIZE (MB):\t$BACKUP_SIZE"
            echo "SHRINK SIZE (MB):\t$BACKUP_SHRINK_SIZE"
            echo "VG DATA ONLY:\t\t$IS_METADATA"
            echo ""
            numBreaks=0
            if [ -s $BACKUP_DATA ]; then
                while read line
                do
                    if [[ $line = *"==================="* ]]; then
                        (( numBreaks = $numBreaks + 1 ))
                    fi
                
                    if [[ $numBreaks -eq 1 ]]; then
                        read line
                        while [[ $line != *"================"* ]]
                        do
                            print "$line"
                            read line
                        done
                        (( numBreaks = $numBreaks + 1 ))
                    fi
                done < $BACKUP_DATA 
            fi
        else

#######################################
## Else, colon separate the data. (rootvg)
#######################################

            DATE_TIME=`echo $DATE_TIME | /usr/bin/sed -e "s/\:/\./g"`
			if [[ -n ${OSLEVEL_S} ]]; then
				print "#VG Name:Date:Uname Info:OS Level:Maintenance Level:Size:Shrink Size:LV Name:LV Type:LPs:PPs:PVs:LV State:Mount Point:VG Data Only:ServicePack Level"
			else
				print "#VG Name:Date:Uname Info:OS Level:Maintenance Level:Size:Shrink Size:LV Name:LV Type:LPs:PPs:PVs:LV State:Mount Point:VG Data Only"
			fi
            numBreaks=0
            if [ -s $BACKUP_DATA ]; then
                while read line
                do
                    if [[ $line = *"==================="* ]]; then
                        (( numBreaks = $numBreaks + 1 ))
                    fi
        
                    if [[ $numBreaks -eq 1 ]]; then
                        read line
                        while [[ $line != *"================"* ]]
                        do
                            if [[ "$line" != *":"* && "$line" != *"LV"* ]]; then
                                colon_line=`echo $line | /usr/bin/sed -e "s/\ /\:/g"`
                                echo "$VG:$DATE_TIME:$UNAME_INFO:$OSLEVEL:$OSLEVEL_R:$BACKUP_SIZE:$BACKUP_SHRINK_SIZE:$colon_line:${IS_METADATA}${OSLEVEL_S:+:$OSLEVEL_S}"
                            fi
                            read line
                        done
                        (( numBreaks = $numBreaks + 1 ))
                    fi
                done < $BACKUP_DATA
            fi
        fi

################################
## Else, if backup is USERVG
################################

   elif [ "$BACKUPTYPE" = "uvg" ]; then
        get_vgdata

##################################################
## Now after restoring from tape into temp 
## directory, we set the variables to the newly 
## restored data file paths.
##################################################

        IMAGE_DATA=$LSBACKUPDIR$IMAGE_DATA
        BACKUP_DATA=$LSBACKUPDIR$BACKUP_DATA

##################################################
## Check flags for "colon delimited" output.
## Parse backup.data for correct report section.
## Print report to stdout.
##################################################

        BACKUP_SHRINK_SIZE=`/usr/bin/tail -1 $BACKUP_DATA 2> /dev/null \
                             | awk -F : '{print $1}'`
        BACKUP_SIZE=`/usr/bin/tail -1 $BACKUP_DATA 2> /dev/null \
                     | awk -F : '{print $2}'`
        IS_METADATA=`/usr/bin/tail -1 $BACKUP_DATA 2> /dev/null \
                      | awk -F : '{print $3}'`
	[[ "$IS_METADATA" = "" ]] && IS_METADATA="no"
        DATE_TIME=$( /usr/bin/awk '$1=="DATE_TIME="{ print $2, $3, $4, $5, $6, $7 }' $IMAGE_DATA 2> /dev/null )
        UNAME_INFO=$( /usr/bin/awk '$1=="UNAME_INFO="{ print $2, $3, $4, $5, $6 }' $IMAGE_DATA 2> /dev/null )
        OSLEVEL=$( /usr/bin/awk '$1=="OSLEVEL="{ print $2 }' $IMAGE_DATA 2> /dev/null )
        OSLEVEL_R=$( /usr/bin/awk '$1=="OSLEVEL_R="{ print $2 }' $IMAGE_DATA 2> /dev/null )
        OSLEVEL_S=$( /usr/bin/awk '$1=="OSLEVEL_S="{ print $2 }' $IMAGE_DATA 2> /dev/null )

#######################################
## Check and see if we are to colon 
## separate the data.
#######################################

        if [ $COLONFLAG = no ]; then
            echo "VOLUME GROUP:\t\t$VG"
            echo "BACKUP DATE/TIME:\t$DATE_TIME"
            echo "UNAME INFO:\t\t$UNAME_INFO"
            echo "BACKUP OSLEVEL:\t\t$OSLEVEL"
            echo "MAINTENANCE LEVEL:\t$OSLEVEL_R"
            [[ -n ${OSLEVEL_S} ]] && \
				echo "SERVICEPACK LEVEL:\t$OSLEVEL_S"
            echo "BACKUP SIZE (MB):\t$BACKUP_SIZE"
            echo "SHRINK SIZE (MB):\t$BACKUP_SHRINK_SIZE"
            echo "VG DATA ONLY:\t\t$IS_METADATA"
            echo ""
            numBreaks=0
            if [ -s $BACKUP_DATA ]; then 
                while read line
                do
                    if [[ $line = *"==================="* ]]; then
                        (( numBreaks = $numBreaks + 1 ))
                    fi
                
                    if [[ $numBreaks -eq 1 ]]; then
                        read line
                        while [[ $line != *"================"* ]]
                        do
                            print "$line"
                            read line
                        done
                        (( numBreaks = $numBreaks + 1 ))
                    fi
                done < $BACKUP_DATA 
            fi
    
#######################################
## Else, colon separate the data.
#######################################

        else
            DATE_TIME=`echo $DATE_TIME | /usr/bin/sed -e "s/\:/\./g"`
			if [[ -n ${OSLEVEL_S} ]]; then
				print "#VG Name:Date:Uname Info:OS Level:Maintenance Level:Size:Shrink Size:LV Name:LV Type:LPs:PPs:PVs:LV State:Mount Point:VG Data Only:ServicePack Level"
			else
				print "#VG Name:Date:Uname Info:OS Level:Maintenance Level:Size:Shrink Size:LV Name:LV Type:LPs:PPs:PVs:LV State:Mount Point:VG Data Only"
			fi
            numBreaks=0
            while read line
            do
                if [[ $line = *"==================="* ]]; then
                    (( numBreaks = $numBreaks + 1 ))
                fi
    
                if [[ $numBreaks -eq 1 ]]; then
                    read line
                    while [[ $line != *"================"* ]]
                    do
                        if [[ "$line" != *":"* && "$line" != *"LV"* ]]; then
                            colon_line=`echo $line | \
                                   /usr/bin/sed -e "s/\ /\:/g"`
                            echo "$VG:$DATE_TIME:$UNAME_INFO:$OSLEVEL:$OSLEVEL_R:$BACKUP_SIZE:$BACKUP_SHRINK_SIZE:$colon_line:${IS_METADATA}${OSLEVEL_S:+:$OSLEVEL_S}"
                        fi
                        read line
                    done
                    (( numBreaks = $numBreaks + 1 ))
                fi
            done < $BACKUP_DATA
        fi
#######################
## Backup is WPAR?
#######################

    elif [[ $BACKUPTYPE = wpar ]]
    then
        DATA_ROOT_DIR=./.savewpar_dir
        DATA_DIR=/.savewpar_dir
        if [ "$NAME" != "lssavewpar" ] && [ "$NAME" != "restwparfiles" ]
        then
           /usr/bin/dspmsg -s 3 $MSGCAT 28 \
"0512-060 %s: The backup %s is not a volume group \
backup.\nPreview of Volume Group attributes canceled.\n" \
$NAME $DEV_BNAME ""
            cleanup $EXIT_EC
        fi
        if [[ $DEVICE = /dev/rmt+([0-9])\.[$NRWFLAGS] ]]; then
            /usr/bin/mt -f $DEVICE bsf 1 > /dev/null 2>&1
            /usr/sbin/restore -xqf $DEVICE $BFLAG \
               ${DATA_ROOT_DIR}/image.data ${DATA_ROOT_DIR}/backup.data > /dev/null 2>&1
        elif [[ $DEVICE = "/dev/rmt"* ]]; then
            /usr/sbin/restore -xqf $DEVICE.1 $BFLAG \
               ${DATA_ROOT_DIR}/image.data ${DATA_ROOT_DIR}/backup.data > /dev/null 2>&1
        else
            /usr/sbin/restore -xqf $DEVICE $BFLAG \
               ${DATA_ROOT_DIR}/image.data ${DATA_ROOT_DIR}/backup.data > /dev/null 2>&1
        fi
        IMAGE_DATA=$LSBACKUPDIR${DATA_DIR}/image.data
        BACKUP_DATA=$LSBACKUPDIR${DATA_DIR}/backup.data

	# Check for alternate data files on a CD or DVD backup
	if [[ $unmountcd = 1 ]]
	then
	    restore_alt_data || cleanup $EXIT_EC
	fi

        
##################################################
## Get and set backup size variables and set 
## general info variables.
## Check flags for "colon delimited" output.
## Parse backup.data for correct report section.
## Print report to stdout.
##################################################
     

	# Check to see if the file is not there.  If the information
	# file is missing, we cannot proceed.
	if [ ! -f ${BACKUP_DATA} ]
	then
            /usr/bin/dspmsg -s 3 $MSGCAT 30 \
"0512-067 %s: The backup %s is not a workload partition \
backup.\nPreview of Workload Partition attributes canceled.\n" \
$NAME $DEVICE
            cleanup $EXIT_EC
	fi

	   # shrinkinfo is in the fourth section of the wpar backup.data
	   shrinklno=`/usr/bin/grep -n "^================================" ${BACKUP_DATA} | \
	   /usr/bin/tail +4l | /usr/bin/head -1 | cut -d: -f1`

	   # skip heading
	   (( shrinklno = shrinklno + 2 ))

	   shrinkinfo=`/usr/bin/tail +${shrinklno} $BACKUP_DATA 2> /dev/null | /usr/bin/head -1`

        BACKUP_SHRINK_SIZE=`echo $shrinkinfo \
                             | awk -F : '{print $1}'`
        BACKUP_SIZE=`echo $shrinkinfo \
                      | awk -F : '{print $2}'`
        IS_METADATA=`echo $shrinkinfo \
                      | awk -F : '{print $3}'`
	[[ "$IS_METADATA" = "" ]] && IS_METADATA="no"
        DATE_TIME=$( /usr/bin/awk '$1=="DATE_TIME="{ print $2, $3, $4, $5, $6, $7 }' $IMAGE_DATA 2> /dev/null )
        UNAME_INFO=$( /usr/bin/awk '$1=="UNAME_INFO="{ print $2, $3, $4, $5, $6 }' $IMAGE_DATA 2> /dev/null )
        OSLEVEL=$( /usr/bin/awk '$1=="OSLEVEL="{ print $2 }' $IMAGE_DATA 2> /dev/null )
        OSLEVEL_R=$( /usr/bin/awk '$1=="OSLEVEL_R="{ print $2 }' $IMAGE_DATA 2> /dev/null )
        OSLEVEL_S=$( /usr/bin/awk '$1=="OSLEVEL_S="{ print $2 }' $IMAGE_DATA 2> /dev/null )
        WPAR_NAME=$( /usr/bin/awk '$1=="WPAR_NAME="{ print $2 }' $IMAGE_DATA 2> /dev/null )

#######################################
## Check and see if we are to colon 
## separate the data.
#######################################

        if [ $COLONFLAG = no ]; then
            echo "WORKLOAD PARTITION:\t$WPAR_NAME"
            echo "BACKUP DATE/TIME:\t$DATE_TIME"
            echo "UNAME INFO:\t\t$UNAME_INFO"
            echo "BACKUP OSLEVEL:\t\t$OSLEVEL"
            echo "MAINTENANCE LEVEL:\t$OSLEVEL_R"
            [[ -n ${OSLEVEL_S} ]] && \
				echo "SERVICEPACK LEVEL:\t$OSLEVEL_S"
            echo "BACKUP SIZE (MB):\t$BACKUP_SIZE"
            echo "SHRINK SIZE (MB):\t$BACKUP_SHRINK_SIZE"
            echo ""
            numBreaks=0
            if [ -s $BACKUP_DATA ]; then
                while read line
                do
                    if [[ $line = *"==================="* ]]; then
                        (( numBreaks = $numBreaks + 1 ))
                    fi
                
                    if [[ $numBreaks -eq 1 ]]; then
                        read line
                        while [[ $line != *"================"* ]]
                        do
                            print "$line"
                            read line
                        done
                        (( numBreaks = $numBreaks + 1 ))
                    fi
                done < $BACKUP_DATA 
            fi
        else

#######################################
## Else, colon separate the data. (rootvg)
#######################################

            DATE_TIME=`echo $DATE_TIME | /usr/bin/sed -e "s/\:/\./g"`
			if [[ -n ${OSLEVEL_S} ]]; then
				print "#VG Name:Date:Uname Info:OS Level:Maintenance Level:Size:Shrink Size:LV Name:LV Type:LPs:PPs:PVs:LV State:Mount Point:WPAR:ServicePack Level"
			else
				print "#VG Name:Date:Uname Info:OS Level:Maintenance Level:Size:Shrink Size:LV Name:LV Type:LPs:PPs:PVs:LV State:Mount Point:WPAR"
			fi
            numBreaks=0
            if [ -s $BACKUP_DATA ]; then
                while read line
                do
                    if [[ $line = *"==================="* ]]; then
                        (( numBreaks = $numBreaks + 1 ))
                    fi
        
                    if [[ $numBreaks -eq 1 ]]; then
                        read line
                        while [[ $line != *"================"* ]]
                        do
                            if [[ "$line" != *":"* && "$line" != *"LV"* ]]; then
                                colon_line=`echo $line | /usr/bin/sed -e "s/\ /\:/g"`
                                echo "$VG:$DATE_TIME:$UNAME_INFO:$OSLEVEL:$OSLEVEL_R:$BACKUP_SIZE:$BACKUP_SHRINK_SIZE:$colon_line:${WPAR_NAME}${OSLEVEL_S:+:$OSLEVEL_S}"
                            elif [[ "$line" = *":"* ]]; then
				# VG=`echo $line | sed 's/$line/:$'`
				VG=${line%:}
                            fi
                            read line
                        done
                        (( numBreaks = $numBreaks + 1 ))
                    fi
                done < $BACKUP_DATA
            fi
        fi

    else
##################################
## Else Backup is an unknown type
##################################
        if [ "$NAME" != "lssavewpar" ] && [ "$NAME" != "restwparfiles" ]
        then
           /usr/bin/dspmsg -s 3 $MSGCAT 28 \
"0512-060 %s: The backup %s is not a volume group \
backup.\nPreview of Volume Group attributes canceled.\n" \
$NAME $DEV_BNAME ""
        else
           /usr/bin/dspmsg -s 3 $MSGCAT 30 \
"0512-067 %s: The backup %s is not a workload partition \
backup.\nPreview of Workload Partition attributes canceled.\n" \
$NAME $DEV_BNAME
        fi
        /usr/bin/mt -f $DEVICE bsf 1 > /dev/null 2>&1
        cd / > /dev/null 2>&1
        /usr/bin/rm -fr $FIRST_BLK > /dev/null 2>&1
        /usr/bin/rm -fr $LSBACKUPDIR > /dev/null 2>&1
        cleanup $EXIT_EC

    fi
    [[ $TAPEBACKUP = "yes" ]] && /usr/bin/mt -f $DEVICE bsf 1 > /dev/null 2>&1
    cd / > /dev/null 2>&1
    /usr/bin/rm -fr $FIRST_BLK > /dev/null 2>&1
    /usr/bin/rm -fr $LSBACKUPDIR > /dev/null 2>&1
    cleanup 0
}	


#######################
## Dump information from wpar section - colon formatted output just
## replaces blanks with colons.  Section number is passed in from
## caller.
#######################
function ls_wpar_rwinfo
{
section=$1
typeset numBreaks
typeset line

    /usr/bin/mkdir $LSBACKUPDIR
    cd $LSBACKUPDIR
    determine_backup_type

#######################
## Check that backup is from a wpar
#######################

    if [[ $BACKUPTYPE != wpar ]]
    then
           DEV_BNAME=`/usr/bin/basename $DEVICE 2> /dev/null`
           /usr/bin/dspmsg -s 3 $MSGCAT 30 \
"0512-067 %s: The backup %s is not a workload partition \
backup.\nPreview of Workload Partition attributes canceled.\n" \
$NAME $DEV_BNAME
            cleanup $EXIT_EC
        
    fi

    # Restore the backup data from the media
    BACKUP_DATA=$LSBACKUPDIR${DATA_DIR}/backup.data
    if [[ $DEVICE = /dev/rmt+([0-9])\.[$NRWFLAGS] ]]; then
        /usr/bin/mt -f $DEVICE bsf 1 > /dev/null 2>&1
        /usr/sbin/restore -xqf $DEVICE $BFLAG \
            ${DATA_ROOT_DIR}/backup.data > /dev/null 2>&1
    elif [[ $DEVICE = "/dev/rmt"* ]]; then
        /usr/sbin/restore -xqf $DEVICE.1 $BFLAG \
           ${DATA_ROOT_DIR}/backup.data > /dev/null 2>&1
    else
        /usr/sbin/restore -xqf $DEVICE $BFLAG \
           ${DATA_ROOT_DIR}/backup.data > /dev/null 2>&1
    fi

#######################################
## Skip ahead to the specified section
## NFS is the fifth section
## namefs is the sixth section
#######################################

    numBreaks=0
    if [ -s $BACKUP_DATA ]; then
       while read line
       do
           if [[ $line = *"==================="* ]]; then
              (( numBreaks = $numBreaks + 1 ))
           fi
             
           if [[ $numBreaks -eq $section ]]; then
              read line
              while [[ $line != *"================"* ]]
              do
                 if [ $COLONFLAG = no ]; then
                    print "$line"
                 else
                    echo $line | /usr/bin/sed 's/ /:/g'
                 fi
                 read line || break
              done
              break
           fi
       done < $BACKUP_DATA
    else
           DEV_BNAME=`/usr/bin/basename $DEVICE 2> /dev/null`
           /usr/bin/dspmsg -s 3 $MSGCAT 30 \
"0512-067 %s: The backup %s is not a workload partition \
backup.\nPreview of Workload Partition attributes canceled.\n" \
$NAME $DEV_BNAME
    fi

    [[ $TAPEBACKUP = "yes" ]] && /usr/bin/mt -f $DEVICE bsf 1 > /dev/null 2>&1
    cd / > /dev/null 2>&1
    /usr/bin/rm -fr $FIRST_BLK > /dev/null 2>&1
    /usr/bin/rm -fr $LSBACKUPDIR > /dev/null 2>&1
    cleanup 0
}	

function relative_to_absolute
{
typeset given_path=$1
typeset absolute

   if [[ $given_path = [/~.]* ]] ; then
      print $given_path
   else
      absolute=$(pwd)/${given_path}
      print $absolute
   fi
}

function restore_multivolumeCD
{
NEXTVOL=0
VOLID=$(/usr/bin/grep "^DATE=" $TMPCDDIR/mkcd.data | cut -d= -f2)

    ## Create a subshell to prompt for the CDs and dd the image
    ## from each CD, which is piped to restbyname
    (
    while [ "$CDLASTVOLUME" = "no" ]; do
        (( NEXTVOL = CDVOLUME + 1 ))
        if [ $CDVOLUME -gt 1 ]; then

            ## If we are past the first volume, we need to unmount the 
            ## previous volume.
            ## Unmount in a loop, since the dd could cause the CD to busy
            umount_return=1
            while [ $umount_return -ne 0 ]
            do
                sleep 10 1>&2
                /usr/sbin/umount $TMPCDDIR 1>&2
                umount_return=$?
                if [ $umount_return -ne 0 ]; then
                    /usr/bin/dspmsg $MSGCAT $MSGSET 46 \
"Warning:  Failed unmounting device %s on mount point %s.  Retrying ...\n" \
                    "$OLDCDDEVICE" "$TMPCDDIR" 1>&2
                fi
            done

            volrc=255
            /usr/bin/dspmsg $MSGCAT -s $MSGSET 52 \
"\n\nPlease remove volume %s, insert volume %s, and press the ENTER key.\n" \
            "$OLDCDVOLUME" "$CDVOLUME" 1>&2
            read -u0 answer
            while [ $volrc -ne 0 ]; do
                >/dev/null 2>&1 <$OLDCDDEVICE
                if [ $? -eq 0 ]
                then
                    /usr/sbin/mount -rv $MEDIA_FILESYSTEM $OLDCDDEVICE $TMPCDDIR 1>&2
                    if [ -s $TMPCDDIR/mkcd.data ]
                    then
                        NEWVOLID=$(/usr/bin/grep "^DATE=" $TMPCDDIR/mkcd.data | cut -d= -f2)
                        if [ $NEWVOLID -eq $VOLID ]
                        then
                            NEWCDVOL=$(/usr/bin/grep "^VOLUME=" $TMPCDDIR/mkcd.data | cut -d= -f2)
                            if [ $NEWCDVOL -eq $CDVOLUME ]
                            then
                                volrc=0
                            else
                                sleep 5
                                /usr/sbin/umount $TMPCDDIR 1>&2
                                /usr/bin/dspmsg $MSGCAT -s $MSGSET 52 \
"\n\nPlease remove volume %s, insert volume %s, and press the ENTER key.\n" \
                                "$NEWCDVOL" "$CDVOLUME" 1>&2
                                read -u0 answer
                            fi
                        else
                            sleep 5
                            /usr/sbin/umount $TMPCDDIR 1>&2
                            /usr/bin/dspmsg $MSGCAT -s $MSGSET 84 \
"Warning: The current volume is not part of the original volume's set.\nPlease remove the current volume, insert the next volume matching the original,\nand then press the ENTER key.\n" 1>&2
                            read -u0 answer
                        fi
                    fi
                fi
            done

            CDVOLUME=$(grep "^VOLUME=" $TMPCDDIR/mkcd.data | cut -d= -f2)
            grep -q LASTVOLUME $TMPCDDIR/mkcd.data > /dev/null 2>&1
            if [ $? -eq 0 ]; then
                CDLASTVOLUME=yes
            fi
        fi
        OLDCDVOLUME=$CDVOLUME
        (( CDVOLUME = CDVOLUME + 1 ))
        /usr/bin/dd bs=2048 if=$DEVICE 2>/dev/null
	## > 2GB of data on media DVD?
	if [ -s $DEVICE"2" ]
	then
		/usr/bin/dd bs=2048 if=$DEVICE"2" 2>/dev/null ## Part two of > 2GB>
	fi
    done
    ) | /usr/sbin/restore $TXFLAG $TAPEFILE -f - $DISABLEACLS $RESTFILES 1>&2
    return $?
}

#######################
## Restore alternate metadata files from a CD backup
#######################
function restore_alt_data
{
    [[ -z "$DATA_ROOT_DIR" ]] && DATA_ROOT_DIR=.
    if [ -f $TMPCDDIR/image.data ]
    then
        cp $TMPCDDIR/image.data ${DATA_ROOT_DIR}/image.data || return 1
    fi
    if [ "$BACKUPTYPE" = wpar ] && [ -f $TMPCDDIR/wpar.spec ]
    then
        cp $TMPCDDIR/wpar.spec ${DATA_ROOT_DIR}/wpar.spec || return 1 
    fi
    return 0
}

#### Main main MAIN listvgbackup.sh
ALTERTAPE=no                                     ## Flag for altering tape
AUTOMOUNTCD=                                     ## cdromd running
AUTORESUME=no                                    ## restart cdromd
BACKUPLOG=/var/adm/ras/vgbackuplog               ## Backup log location
BACKUPTYPE=rvg                                   ## Using rootvg backup
BLOCKFLAG=no                                     ## Tape blocksize flag
CDLASTVOLUME=no                                  ## Indicator of last volume
CDVOLUME=0                                       ## Volume number of CD
COLONFLAG=no                                     ## Colon separated output
DEBUGFLAG=no                                     ## Controls debug output
DEVICE=/dev/rmt0                                 ## Default device /dev/rmt0
DEVICEFLAG=no                                    ## Backup device flag
DIRFLAG=no                                       ## Restore directory flag
DISABLEACLS=                                     ## Disable ACLs, PCLs, EAs
FIRST_BLK=/tmp/first_blk.$$                      ## Block containing vg.data
LPPFLAG=no                                       ## List mksysb lpp info flag
LSBACKUPDIR=/tmp/$$lsbackup                      ## Temp directory for listing
LSFLAG=no                                        ## List vgbackup properties
LSNAMEFSFLAG=no                                  ## List writable NAMEFS info
LSNFSFLAG=no                                     ## List writable NFS info
MSGCAT=mksysb.cat                                ## Message catalog filename
MSGSET=1
NAME=`/usr/bin/basename $0`
NEWVOLID=                                        ## CD timestamp
NAMEFSSECTION=6                                  ## Writable namefs info is in 6th section
NFSSECTION=5                                     ## Writable NFS info is in 5th section
NRWFLAGS=1357
RESTFILES=                                       ## List of files to restore
RESTORE=/usr/sbin/restore
RESTOREDIR=                                      ## Directory to restore files
RESTOREFLAG=no                                   ## Just list files, do not
                                                 ## restore files.
REWIND=0 
SAVEVGFLAG=no                                    ## User volume group flag
SAVEWPARIMAGE=no                                 ## WPAR rather than VG image
SHOWBACKUPLOG=no                                 ## Backuplog display flag
olddir=
TBLOCKSZ=
TMPCDDIR=
TMPDIR=
DATA_BASEDIR=/tmp/vgdata                         ## For user vg backups
DATA_LIST=$DATA_BASEDIR/vgdata.files             ## For user vg backups
VERIFYFLAG=no                                    ## Verify flag for backups
VOLID=                                           ## CD timestamp
unmountcd=0                                      ## If set to 1, unmount cd on exit
ZEROBLKSZ=0

## Backup media type
TAPEBACKUP=no
ONECDBACKUP=no
FILEBACKUP=no
MEDIA_FILESYSTEM=cdrfs

## Flags for restore command
BFLAG=                                           ## b flag for restore
TAPEFILE=                                        ## -s flag for tape devices
TXFLAG=xd                                        ## T or xd flag for restore

USAGE_EC=1                                       ## exit codes
EXIT_EC=2
TRAP_EC=3

# Trap on exit/interrupt/break to clean up
trap 'cleanup $TRAP_EC "" '  1 2 15

[ "$LISTVGBACKUP_DEBUG" ] && set -x && debug_switch

# Parse command line options
getoptions $*
determine_conflicting_options $*

# Set debug, based on the environmental variable, LISTVGBACKUP_DEBUG
[ "$DEBUGFLAG" = "yes" ] && set -x
debug_switch

# Check for backuplog display only
if [[ $SHOWBACKUPLOG = yes ]]
then
    /usr/bin/alog -f $BACKUPLOG -o
    cleanup 0
fi

# Determine if device type is tape.  Necessary to set before
# determining backup type when invoked by restwparfiles which
# could be used for a wpar or mksysb backup (in the case of.
# a system backup image used to populate a versioned WPAR). 
# Determine the device type
if [[ $DEVICE = /dev/*[0-9] ]]                 ## tape or cd device
then
    BASE_DEV=`/usr/bin/basename $DEVICE | /usr/bin/cut -d . -f1`
    USBMS_DEV=`/usr/sbin/lsdev -C -c usbms -l $BASE_DEV -S available | /usr/bin/wc -l`
    MS_DEV=`/usr/sbin/lsdev -C -c disk -t mstor -l $BASE_DEV -S available | /usr/bin/wc -l`
    if [ `/usr/sbin/lsdev -C -c tape -l $BASE_DEV -S available | /usr/bin/wc -l` -eq 1 ]
    then 
        TAPEBACKUP=yes
    fi
fi

# restwparfiles could be used with either a mksysb image 
# (for populating from a system backup) or from a wpar backup
# image, so check the device to figure it out.
if [[ $NAME = restwparfiles ]]
then
   if [[ $TAPEBACKUP = "yes" ]]
   then
       /usr/bin/mkdir $LSBACKUPDIR 
       OPWD=$PWD
       determine_backup_type
       cd $OPWD
       /usr/bin/rm -fr $LSBACKUPDIR > /dev/null 2>&1
   else
       backup_type=wpar
   fi
fi
     

if [[ $BACKUPTYPE = wpar  ]]
then
        DATA_ROOT_DIR=./.savewpar_dir
        DATA_DIR=/.savewpar_dir
        WPARSPECFILE=${DATA_ROOT_DIR}/wpar.spec
else
        DATA_ROOT_DIR=.
fi

if [[ "$METAFILESFLAG" = "yes" ]]
then
    IMAGE_DATA=${DATA_ROOT_DIR}/image.data
fi
    
# Determine the device type
if [[ $DEVICE = /dev/*[0-9] ]]                 ## tape or cd device
then
    if [[ $TAPEBACKUP = "yes" ]]
    then                                          ## tape device
	# Check for "listing" a backup's properties
	if [[ $LSFLAG = yes ]]
	then
	    DEVICE=$(relative_to_absolute $DEVICE) 
	    ls_backup_properties
	    cleanup 0
	fi

	# Check for listing lpp information about a backup
	if [[ $LPPFLAG = yes ]]
	then
	    DEVICE=$(relative_to_absolute $DEVICE) 
	    ls_backup_lpp
	    cleanup 0
	fi

	# Check for listing writable NFS mount information 
	if [[ $LSNFSFLAG = yes ]]
	then
	    DEVICE=$(relative_to_absolute $DEVICE) 
	    ls_wpar_rwinfo $NFSSECTION
	    cleanup 0
	fi
      
	# Check for listing writable NFS mount information 
	if [[ $LSNAMEFSFLAG = yes ]]
	then
	    DEVICE=$(relative_to_absolute $DEVICE) 
	    ls_wpar_rwinfo $NAMEFSSECTION
	    cleanup 0
	fi
      
        if [ "$BACKUPTYPE" = "rvg" ]              ## mksysb tape
        then
            tctl -f $DEVICE rewind                ## rewind tape
            # Set device to be no rewind
            [[ $DEVICE = /dev/rmt+([0-9])\.[$NRWFLAGS] ]] || DEVICE=$DEVICE.1
            REWIND=1                              ## Flag to rewind in cleanup
            TAPEFILE="-s 4"                       ## initialize for tape media
        fi
             
        if [ "$ALTERTAPE" = "yes" ]
        then                                      ## determine and set block size
            altertape
        fi
    elif [ `/usr/sbin/lsdev -C -c cdrom -l $BASE_DEV -S available | /usr/bin/wc -l` -eq 1 ] || \
         [ $USBMS_DEV -eq 1 ] || \
	 [ $MS_DEV -eq 1 ]
    then                                          ## cd device
        BFLAG=                                    ## clear, not applicable for cd
	if [[ $VERIFYFLAG = yes ]]; then
	    cleanup $USAGE_EC
	fi

	case "$BACKUPTYPE" in
	   "rvg")  backup_image=mksysb_image;;
	   "uvg")  backup_image=savevg_image;;
	   "wpar") backup_image=savewpar_image;;
	esac

        TMPCDDIR=/tmp/_cdrom.$$
        create_tmp_dir $TMPCDDIR                  ## create tmp dir for cd mount

        if [ -s "/usr/sbin/cdcheck" ] && [ $USBMS_DEV -ne 1 ] && [ $MS_DEV -ne 1 ]; then
            AUTOMOUNTCD="`/usr/sbin/cdcheck -a $DEVICE 2>/dev/null`"
        fi
        if [ -n "$AUTOMOUNTCD" ]; then
            /usr/sbin/cdutil -s -k $DEVICE > /dev/null 2>&1
            if [ $? -eq 0 ]; then   ## cdutil command return code
                AUTORESUME=yes 
            fi
        fi
        
        # mount cd
        >/dev/null 2>&1 <$DEVICE
        if [ $? -eq 0 ]; then
            /usr/sbin/mount -v'cdrfs' -r $DEVICE $TMPCDDIR 2>/dev/null
            RC=$?
        else
            sleep 10
            /usr/sbin/mount -v'cdrfs' -r $DEVICE $TMPCDDIR 2>/dev/null
            RC=$?
        fi 
        if [[ $RC -ne 0 ]]
        then
            MEDIA_FILESYSTEM=udfs
            /usr/sbin/mount -v'udfs' -r $DEVICE $TMPCDDIR 2>/dev/null
            RC=$?
        fi
        if [[ $RC -ne 0 ]]
        then
            cleanup "$EXIT_EC" \
            "`/usr/bin/dspmsg -s $MSGSET $MSGCAT 43 '
0512-055 %s: Failed mounting %s to mount point %s.\n' \
"$NAME" "$DEVICE" "$TMPCDDIR"`"
	fi
        CDVOLUME=$(/usr/bin/grep "^VOLUME=" $TMPCDDIR/mkcd.data 2> /dev/null | cut -d= -f2)
        while [[ $CDVOLUME -ne 1 ]]; do
            sleep 5
            /usr/sbin/umount $TMPCDDIR
            /usr/bin/dspmsg $MSGCAT -s $MSGSET 52 \
"\n\nPlease remove volume %s, insert volume %s, and press the ENTER key.\n" \
            "$CDVOLUME" "1" 
            read -u0 answer
# Loop waiting for CD to be ready
            cdready=0
            while [[ $cdready -eq 0 ]]; do
                >/dev/null 2>&1 <$DEVICE
                if [ $? -eq 0 ]; then
                    cdready=1
                fi
            done
            /usr/sbin/mount -v $MEDIA_FILESYSTEM -r $DEVICE $TMPCDDIR
            NEWCDVOL=$(/usr/bin/grep "^VOLUME=" $TMPCDDIR/mkcd.data 2> /dev/null | cut -d= -f2)
            if [[ $NEWCDVOL -eq 1 ]]
            then
                CDVOLUME=$NEWCDVOL
            fi
        done

	# Check for multivolume CD unless this is a WPAR metafile
	# backup, since all the metafiles will be at the beginning
	# of the image.
        /usr/bin/grep -q LASTVOLUME $TMPCDDIR/mkcd.data 2> /dev/null
        if [ $? -eq 0 ] || [ "$METAFILESFLAG" = "yes" ] 
        then
            CDLASTVOLUME=yes
            ONECDBACKUP=yes
        fi
        unmountcd=1

	# restwparfiles might need to process a mksysb or savewpar image.
	# check the media to see which one is there.
        if [[ $NAME = restwparfiles ]]
	then
	   if [[ -f $TMPCDDIR/usr/sys/inst.images/mksysb_image ]]
	   then
              backup_image=mksysb_image
	      BACKUPTYPE=rvg
              DATA_ROOT_DIR=.
              IMAGE_DATA=${DATA_ROOT_DIR}/image.data
	   else
              backup_image=savewpar_image
	      BACKUPTYPE=wpar
	   fi
	fi

        # Save old cd device name, and make device point to the backup image.
        OLDCDDEVICE=$DEVICE
        DEVICE=$TMPCDDIR/usr/sys/inst.images/$backup_image
	
        if [[ ! -r "$DEVICE" ]] && [[ ! -s "$DEVICE" ]]
        then
            cleanup "$EXIT_EC" \
            "`/usr/bin/dspmsg -s $MSGSET $MSGCAT 42 '
0512-054 %s: File %s does not exist or is empty.\n' \
"$NAME" "$DEVICE"`"
        fi
    else
        cleanup "$EXIT_EC" \
        "`/usr/bin/dspmsg -s $MSGSET $MSGCAT 37 '
0512-046 %s: Device %s is not in the available state.\n' \
"$NAME" "$DEVICE"`"
    fi
else
    if [[ ! -s "$DEVICE" ]]
    then
        cleanup "$EXIT_EC" \
        "`/usr/bin/dspmsg -s $MSGSET $MSGCAT 42 '
0512-054 %s: File %s does not exist or is empty.\n' \
"$NAME" "$DEVICE"`"
    fi
    FILEBACKUP=yes
fi

# Check for "listing" a backup's properties
if [[ $LSFLAG = yes ]]
then
    DEVICE=$(relative_to_absolute $DEVICE) 
    ls_backup_properties
    cleanup 0
fi

# Check for listing lpp information about a backup
if [[ $LPPFLAG = yes ]]
then
    DEVICE=$(relative_to_absolute $DEVICE) 
    ls_backup_lpp
    cleanup 0
fi

# Check for listing writable NFS mount information 
if [[ $LSNFSFLAG = yes ]]
then
    DEVICE=$(relative_to_absolute $DEVICE) 
    ls_wpar_rwinfo $NFSSECTION
    cleanup 0
fi
      
# Check for listing writable namefs mount information 
if [[ $LSNAMEFSFLAG = yes ]]
then
    DEVICE=$(relative_to_absolute $DEVICE) 
    ls_wpar_rwinfo $NAMEFSSECTION
    cleanup 0
fi
      
if [[ "$METAFILESFLAG" = "yes" ]]
then
    if [[ $BACKUPTYPE = wpar  ]]
    then
        RESTFILES="${DATA_ROOT_DIR}/image.data ${WPARSPECFILE} ${DATA_ROOT_DIR}/backup.data"
    else
        DATA_ROOT_DIR=.
        RESTFILES="${DATA_ROOT_DIR}/image.data"
    fi
fi
      
if [[ $RESTOREFLAG = no ]] 
then
    TXFLAG="-Tvq"
    RESTFILES= 
else
    TXFLAG="-xvdq"
    olddir=`pwd`
    [[ -n $RESTOREDIR ]] && cd $RESTOREDIR
    
    # Prevent restwparfiles from restoring from the global /
    if [ "$NAME" = "restwparfiles" ]
    then
       cwd=`/usr/bin/pwd -P`
       if [[ "$cwd" = "/" ]]
       then
	  typeset -i unamew=0
	  unamew=`/usr/bin/uname -W`

	  if [ $unamew -eq 0 ]
	  then
              cleanup "$EXIT_EC" \
          "`/usr/bin/dspmsg -s $MSGSET $MSGCAT 78 '
0512-069 %s: Cannot restore files into /.\n' $NAME`"
	  fi
       fi
    fi
fi

# If this is a restwparfiles -m operation and if there are logical volume
# map files, then we will need to make two passes, one to read the image.data
# and the other to read in the map files
if [[ "$METAFILESFLAG" = "yes" ]] 
then
   PASSES_LEFT=2
else
   PASSES_LEFT=1
fi

while [[ $PASSES_LEFT -gt 0 ]]
do
 if [[ $FILEBACKUP = yes ]] || [[ $TAPEBACKUP = yes ]]
 then
    if [[ $VERIFYFLAG = no ]]; then
       ${RESTORE} $TXFLAG $BFLAG -f $DEVICE $TAPEFILE $DISABLEACLS $RESTFILES 
       RC=$?
    else
       # Check for verify a backup (just list without output)
       if [[ $TAPEBACKUP = "yes" ]]
       then
           /usr/bin/dspmsg -s $MSGSET $MSGCAT 56 \
           "\nVerifying readability..."
           print "\n"
       else
           cleanup $USAGE_EC
       fi
       ${RESTORE} $TXFLAG $BFLAG -f $DEVICE $TAPEFILE $DISABLEACLS $RESTFILES > /dev/null
       RC=$?
       [ "$RC" -ne 0 ] && cleanup $EXIT_EC "`/usr/bin/dspmsg -s $MSGSET $MSGCAT 59 \
'\n0512-062 Attention: The media on %s is corrupt! \n' $DEVICE`"
    fi
 elif [[ $ONECDBACKUP = yes ]]
 then
    if [[ -s $DEVICE"2" ]]     ## Is the backup greater than 2GB DVD
    then
    (
        READ_LARGE_DVD=yes
        IMAGE1=yes
        while [[ $READ_LARGE_DVD = yes ]]; do
            if [[ $IMAGE1 = yes ]]
            then
                ## Part 1 of greater than 2GB
                /usr/bin/dd bs=2048 if=$DEVICE 2>/dev/null
                IMAGE1=no
            else
                ## Part 2 of greater than 2GB
                /usr/bin/dd bs=2048 if=$DEVICE"2" 2>/dev/null
                READ_LARGE_DVD=no
            fi
        done
    ) | ${RESTORE} $TXFLAG -f - $DISABLEACLS $RESTFILES

    else
        if [[ "$METAFILESFLAG" = "yes" ]]
		then
			${RESTORE} -xvq $BFLAG -f $DEVICE $TAPEFILE $DISABLEACLS $RESTFILES
		else
			${RESTORE} $TXFLAG $BFLAG -f $DEVICE $TAPEFILE $DISABLEACLS $RESTFILES
		fi
    fi
    RC=$?

    # Check for alternate image.data and wpar.spec files in a WPAR backup
    if [[ "$METAFILESFLAG" = "yes" ]] && [[ $unmountcd = 1 ]]
    then
        restore_alt_data || cleanup $EXIT_EC
    fi
 else                                             ## Multivolume CD
    restore_multivolumeCD
    RC=$?
 fi
 [ $RC -ne 0 ] && cleanup $EXIT_EC
 
 (( PASSES_LEFT = PASSES_LEFT - 1 ))

 # Check for lvmaps - if there aren't any, then we're done
 if [[ "$METAFILESFLAG" = "yes" ]] && [[ $PASSES_LEFT -gt 0 ]]
 then
    get_lvmaps
    if [ $? -eq 0 ]
    then 
       # resync the tape device for the second pass if the device is no rewind
       [[ $DEVICE = /dev/rmt+([0-9]).[$NRWFLAGS] ]] && /usr/bin/mt -f /dev/$BASE_DEV.1 bsf 1
    else
       [ $RC -ne 0 ] && cleanup $EXIT_EC || cleanup 0
    fi 
 fi
done

[ $RC -ne 0 ] && cleanup $EXIT_EC || cleanup 0