#!/bin/sh
#
# media_cntrl	uniqNum open  -[rwe] [host:]media tapenum
#		uniqNum read  fileset
#		uniqNum write fileset
#		uniqNum close
#
#	open
#		-r:  Do initializations	to enable subsequent reads
#		-w:  Do initializations	to enable subsequent writes
#		-e:  Confirms that the specified media is accessible
#               tapenum: Hariraj- Added this to support multiple
#               CDROM mount points /cdrom/CDROM1 etc..
#
#	read
#		Reads the specified fileset from media.
#		The start of the tape is fileset 0.
#
#	write	
#		Write data to the current media position (fileset)
#
#	close
#		Close rewinds the specified media (if it is a tape device).
#
#
#############################################################################
#
#	Copyright (C) Cadence Design Systems, Inc. All rights
#	reserved.  Unpublished -- rights reserved under the
#	copyright laws of the United States of America.
#
#			RESTRICTED RIGHTS LEGEND
#	Use, duplication, or disclosure by the Government is subject
#	to restrictions as set forth in subparagraph (c)(l)(ii) of 
#	the Rights in Technical Data and Computer Software clause 
#	at DFARS 52.227-7013.
#
#			Cadence Design Systems, Inc.
#			555 River Oaks Parkway
#			San Jose, CA 95134	USA
#
#############################################################################
BOURNE=/bin/sh
XTERMPATH=/usr/bin/X11
XTERMBIN=xterm
XTERMOPTS="-T 'SoftLoad 6.0 Console' -fn 9x15  -sl 200 -g 80x40+0+0 -bg \#e0e0e0 -fg \#800000 -sb -e ${BOURNE} softload_GUI"
sysPATH=/bin:/usr/bin:/usr/ucb:$XTERMPATH

jsr=''

IsRTapeDev() {		#return success if arg 'could be' a rewind tape dev
    case $1 in
        /dev/rmt/0?*bn) return 1;;
        /dev/rmt/0?*b)  return 0;;
	/dev/rmt/?*n) 	return 1;;
	/dev/rmt/?*) 	return 0;;
        /dev/nrtape)    return 1;;
        /dev/rmt[0123456789])      return 0;;
        /dev/?*.[246])  return 0;;
        /dev/?*.?)      return 1;;
        /dev/r[sm]t?*)  return 0;;
        /dev/n?*)       return 1;;
        /dev/?*)        return 0;;
	*)		return 1;;
    esac
}

IsNTapeDev() {		#return success if arg 'could be' a Nrewind tape dev
    case $1 in
        /dev/rmt/0?*bn) return 0;;
	/dev/rmt/?*n) 	return 0;;
	/dev/nrtape)	return 0;;
        /dev/?*.[1357]) return 0;;
        /dev/nr?*)      return 0;;
        /dev/n?*)       return 0;;
	*)		return 1;;
    esac
}


IsTapeDev() {		#return success if arg 'could be' local/remote tape dev
    devName=`echo $1 | sed 's@.*:@@'`
    $jsr IsRTapeDev "$devName" || $jsr IsNTapeDev "$devName"
    return $?
}


NTapeDevName() {	#print name of Nrewind tapedev corresponding to argument
       case $1 in
          /dev/rmt/0?*bn) echo $1 
                          return 0;;  #Can get rid of first 2 lines
          /dev/rmt/0?*b)  echo $1 | sed 's@b@bn@'
                          return 0 ;;
	  /dev/rmt/?*) 	  echo $1 | sed 's@[^n]$@&n@'
                          return 0 ;;
          /dev/*.2)       echo $1 | sed 's@2$@3@' 
                          return 0 ;;
          /dev/*.4)       echo $1 | sed 's@4$@5@' 
                          return 0 ;;
          /dev/*.6)       echo $1 | sed 's@6$@7@' 
                          return 0 ;;
          /dev/*.[1357])  echo $1
                          return 0 ;;
          /dev/rmt[0123456789]*)      echo "$1.1"
                          return 0 ;;
          /dev/n?*)       echo $1 
                          return 0;;
          /dev/r[sm]t?*)  echo $1 | sed 's@^/dev/@/dev/n@'
                          return 0 ;;
          * )             echo $1
                          return 1;;
       esac

}

RTapeDevName() {	#print name of rewind tapedev corresponding to argument
    case $1 in
       /dev/rmt/0?*b)  echo $1
                          return 0 ;;
       /dev/rmt/0?*bn) echo $1 | sed 's@bn@b@'
                          return 0 ;;
       /dev/rmt/*)     echo $1 | sed 's@n@@'
                          return 0 ;;
       /dev/*.1)       echo $1 | sed 's@.1$@@'
                          return 0 ;;
       /dev/*.3)       echo $1 | sed 's@3$@2@'
                          return 0  ;;
       /dev/*.5)       echo $1 | sed 's@5$@4@'
                          return 0  ;;
       /dev/*.7)       echo $1 | sed 's@7$@6@' 
                          return 0 ;;
       /dev/*.[246])   echo $1
                          return 0 ;;
       /dev/rmt[0123456789]*)      echo $1
                          return 0 ;;
       /dev/r[sm]t?*)  echo $1
                          return 0 ;;
       /dev/n?*)       echo $1 | sed 's@^/dev/n@/dev/@'
                          return 0 ;;
       * )              echo $1 
                          return 1 ;;
   esac

}

MAXTARBSZ=20

HostAddress() {			# if error, no address printed
    /etc/arp $1 |\
        sed -n 's#.*(\(.*\)).*#\1#p'
}

HostAlive() {			# successful if supplied host responds to ping
    /etc/ping      $1 64 2	2>/dev/null \
       | sed -n '$p' | grep '^round-trip ' 1>/dev/null
    return $?
}

Rsh() {
    read=false
    write=false
    hostPlat=false
    case $1 in
	-r) read=true
	    shift;;
	-w) write=true
	    shift;;
	-rw|-wr)
	    read=true
	    write=true
	    shift;;
        -p)
	    hostPlat=true
            shift
            ;;
    esac
    rshHost=$1;	shift

    rsh=rsh

    if $hostPlat ; then
      host_plat=`eval $rsh $rshHost uname -s`
      case $host_plat in
        SunOS ) echo sun    #Do not bother about sun4v or sun4
            return 0;;
        AIX) echo ibmrs
            return 0;;
        HP-UX) echo hppa
            return 0;;
        IRIX) echo sgi
            return 0 ;;
        Linux) echo lnx86
            return 0 ;;
        *) echo UNKNOWN
           return 1;;
      esac
    fi
    
    if $read ; then
	stdin=""
    else
	stdin="</dev/null"
    fi

    if $write ; then
	cmnd="$BOURNE -c '$*; echo \$? > /tmp/rsh$$'"
	eval $rsh $rshHost '$cmnd' $stdin
	rshStatus=\
`$rsh $rshHost "$BOURNE -c 'cat /tmp/rsh$$; rm -f /tmp/rsh$$'" </dev/null` 
    else
	cmnd="$BOURNE -c '$* >/dev/null; echo \$?'"
	rshStatus=`eval $rsh $rshHost '$cmnd' $stdin`
    fi
    test "X$rshStatus" = 'X' && rshStatus=1	#return failure
    return $rshStatus
}



test -z "$loadLog" && loadLog=/dev/null;	export loadLog

dataID=$1; shift
infoFile=/tmp/media_cntrl$dataID
option=$1; shift

NL="
"

if [ $option = open ]; then  #{
  openStatus=$1;  shift
  dataLoc=$1;  shift

  if [ ! -z "$1" ]; then  #{
    tapenum=$1; shift
  fi  #}

  if [ ! -z "$1" -a "X$1" = "Xprodinfo" ]; then  #{
    prod_flag=$1; shift
  fi  #}

  mediaHost=`echo $dataLoc | sed -n 's@:.*@@p'`
  if [ "X$mediaHost" != "X" ]; then  #{
    remote_plat=`$jsr Rsh -p $mediaHost`
  else
    remote_plat=""
  fi  #}
else
  ################################
  # read info file
  ################################
  if [ ! -f $infoFile ]; then  #{
    test $option = close ||
      echo "Error: Could not locate $infoFile" | tee -a $loadLog  1>&2
    exit 1
  fi  #}
  . $infoFile  #source $infoFile
fi   #}
rm -f $infoFile   #remove old info

if [ "X$mediaHost" = "X" ]; then  #{
  remote=""
  remoteSource=""
  remoteSink=""
MT='mt -f'
else
  if [ "X$remote_plat" = "XUNKNOWN" ]; then  #{
    echo "${NL}Could not determine platform of host $mediaHost${NL}"
    exit 1
  else
    remote="$jsr Rsh $mediaHost"
    remoteSource="$jsr Rsh -w $mediaHost"	#remote process writes, we read
    remoteSink="$jsr Rsh -r $mediaHost"		#we write, remote process reads
    case $remote_plat in
      sun | ibmrs | sgi ) 
         MT='mt -f'
         ;;
      hppa )
        MT='mt -t'
         ;;
      *)
        MT=''
    esac
  fi  #}
fi #}

if [ -z "$MT" ]; then #{
  echo "${NL}Could not determine platform of host $mediaHost${NL}"
  exit 1
fi  #}


case $option in  #{
  open)
    if [ "X$mediaHost" != 'X' ]; then  #{
      mediaLoc=`echo $dataLoc | sed -n 's@.*:@@p'` # remove hostname:
    else
      mediaLoc=$dataLoc   # media is local
    fi   #}

    if $jsr IsRTapeDev "$mediaLoc" ; then  #{
      mediaType=special			# tape device
      mediaLoc=`$jsr NTapeDevName $mediaLoc`
      if [ $? -ne 0 ]; then
        echo "Not a conventional tape device: $mediaLoc" 1>&2
        exit 1
      fi
      dataLoc=$mediaLoc
      test "X$mediaHost" != 'X' && dataLoc="${mediaHost}:${dataLoc}"
    elif $jsr IsNTapeDev "$mediaLoc"; then 
	    mediaType=special			# tape device
    else
	    mediaType=disk
    fi  #}

    $remote test -r $mediaLoc || {
       echo "Error: $dataLoc not readable" | tee -a $loadLog	1>&2
        exit 1
    }
    test "X$openStatus" = 'X-e' && exit 0  # just check for existence

    if [ $mediaType = special ]; then #{
      mediaAccess=sequential   # no-rewind tape device
      echo "$remote $MT $mediaLoc rewind"	   >> $loadLog
      $remote $MT $mediaLoc rewind		|| exit 1
    else
      mediaAccess=direct			# disk
    fi  #}
	
    if [ "X$openStatus" = 'X-r' ]; then  #{
      if [ $mediaType = disk ]; then	#{make sure image exists
        $remote test -r $mediaLoc/FS.0 || { 
          tmp_media=`echo $mediaLoc | sed 's@/[^/]*.$@@'`
          if $remote test -r $tmp_media/CDROM${tapenum}/IMAGES.DIR/FS.0 ; then  #{
            mediaLoc=$tmp_media/CDROM${tapenum}/IMAGES.DIR
          else
            if $remote test -r $mediaLoc/IMAGES.DIR/FS.0 ; then  #{
              mediaLoc=$mediaLoc/IMAGES.DIR
            else
              if $remote test -r $mediaLoc/CDROM${tapenum}/IMAGES.DIR/FS.0 ; then  #{
                 mediaLoc=$mediaLoc/CDROM${tapenum}/IMAGES.DIR
              else
                 echo "$dataLoc image not found" | tee -a $loadLog 1>&2
                 exit 1
              fi  #}
            fi  #}
          fi  #}
        }
        if [ "X$prod_flag" = "Xprodinfo" ]; then #{
          tmp_media=`echo $mediaLoc | sed 's@/[^/]*.$@@'`
          if $remote test -r $tmp_media/PRODINFO.TRZ ; then #{
            mediaLoc=$tmp_media
          else
            prod_flag=""
          fi #}
        fi #}
      fi  #} media=disk
      elif [ "X$openStatus" = 'X-w' ]; then
      $remote test -w $mediaLoc || {
        echo "$dataLoc not writable" 	| tee -a $loadLog 	1>&2
        exit 1
      }
    fi  #}
    mediaPos=0
    ;;
  read)
    fsNum=$1; shift
    if [ $mediaPos != $fsNum -a $mediaAccess = sequential ] ; then  #{
      ################################
      # position media
      ################################
      mtOpts=
      mtDiff=`expr $fsNum - $mediaPos`
      if [ $mtDiff -gt 0 ]; then  #{
        mtOpts="fsf $mtDiff"
      else				# not supported by all devices
        mtOpts="bsf `expr 0 - $mtDiff`"
      fi  #}
      if [ ! -z "$mtOpts" ]; then  #{
        mtlog=/tmp/mt$$; rm -f $mtlog
        echo "$remote $MT $mediaLoc $mtOpts"		>> $loadLog
        $remote $MT $mediaLoc $mtOpts 2>$mtlog
	cmndStat=$?
        cat $mtlog | tee -a $loadLog 1>&2
        rm -f $mtlog
        test $cmndStat -ne 0 && exit 2
      fi  #}
      mediaPos=`expr $mediaPos + $mtDiff`
    fi  #}
    ################################
    # transfer data
    ################################
    if [ $mediaType = disk ]; then  #{
      if [  "X$prod_flag" = "Xprodinfo" ]; then
        fsName=PRODINFO.TRZ
      else
        fsName="FS.$fsNum"
      fi
      $remote test -r $mediaLoc/${fsName} || {
        # ONLY DO THIS IF USING NAMED FILES
        t_suffix=".t"
        Z_suffix=".Z"
        fsName=$fsNum$t_suffix
        $remote test -r $mediaLoc/$fsName || {
          if $remote test -r $mediaLoc/$fsName$Z_suffix ; then  #{
            fsName=$fsNum$t_suffix$Z_suffix
          else
            echo "$fsNum image not found" | tee -a $loadLog 1>&2
            exit 1
          fi  #}
        }
      }
      readCmnd="\
      $remoteSource dd if=$mediaLoc/${fsName} bs=${mediaBlocking}b"
    else
      readCmnd="$remoteSource dd if=$mediaLoc bs=${mediaBlocking}b"
    fi  #}
    echo "$readCmnd" >> $loadLog
    ddlog=/tmp/dd$$
    $readCmnd 2>$ddlog
    cmndStat=$?
    cat $ddlog >> $loadLog
    if [ $cmndStat -ne 0 ]; then  #{
      cat $ddlog 	1>&2
      echo "dd: I/O error" 	| tee -a $loadLog 	1>&2
      rm -f $ddlog
      exit 3
    fi  #}
    rm -f $ddlog
    test $mediaAccess = sequential && mediaPos=`expr $mediaPos + 1`
    ;;
  write)
    fsNum=$1; shift
    if [ $mediaPos != $fsNum -a $mediaAccess = sequential ] ; then  #{
      echo "Error: tape not positioned for requested write" | \
         tee -a $loadLog 1>&2
       exit 1
    fi  #}
    if [ $mediaType = disk ]; then  #{
      writeCmnd="\
      $remoteSink dd of=$mediaLoc/FS.${fsNum} obs=${mediaBlocking}b"
    else
      writeCmnd="$remoteSink dd of=$mediaLoc obs=${mediaBlocking}b"
    fi  #}
    echo "$writeCmnd" 				>> $loadLog
    ddlog=/tmp/dd$$
    $writeCmnd 2>$ddlog
    cmndStat=$?
    cat $ddlog >> $loadLog
    if [ $cmndStat -ne 0 ]; then  #{
      cat $ddlog 	1>&2
      echo "dd: write error" 	| tee -a $loadLog 	1>&2
      rm -f $ddlog
      exit 3
    fi  #}
    rm -f $ddlog
    test $mediaAccess = sequential && mediaPos=`expr $mediaPos + 1`
    ;;
  close)
    if [ $mediaAccess = sequential ]; then  #{
      echo "$remote $MT $mediaLoc rewind"		>> $loadLog
      $remote $MT $mediaLoc rewind	|| exit 1
      mediaPos=0
    fi  #}
    exit 0
    ;;
esac

################################
# write info file
################################
cat - >$infoFile <<EOF_DATAFILE
mediaLoc=$mediaLoc
mediaHost=$mediaHost			#{hostname,""}
mediaAccess=$mediaAccess		#{sequential,direct}
mediaType=$mediaType			#{disk,special}
mediaPos=$mediaPos
mediaBlocking=$MAXTARBSZ
prod_flag=$prod_flag
remote_plat=$remote_plat
EOF_DATAFILE

