#!/bin/sh
#******************************************************************************
#                              ISTP LZP SOFTWARE
#                      Property of the U.S. Government
#                              NASA/GSFC/Code 500
#******************************************************************************
#
#    UNIT NAME:  loadtape 
#
#    PURPOSE:  To load ISTP standard block/product files from tape
#
#    INVOCATION METHOD:  loadtape [-hi]
#
#    ARGUMENT LIST:
#    Name            Type            Use  Description
#    --------------  --------------  ---  -----------
#    flags           string           I   option flags
#
#    EXTERNAL VARIABLES:
#    Source          Name            Type       Use  Description
#    --------------  --------------  ---------  ---  -----------
#    Bourn-Shell     $status         string     I/O  success = 0, else failure
#
#    EXTERNAL UNIT/MACRO/PROCEDURE/FUNCTION REFERENCES:
#    Name            Purpose
#    --------------  ----------------
#    dd              copy data from tape device to disk
#    mt              rewind tape device
#
#    ABNORMAL TERMINATION CONDITIONS, ERROR MESSAGES:
#    $status <> 0 when any stage of processing fails
#
#    ASSUMPTIONS, CONSTRAINTS, RESTRICTIONS:
#    none
#
#    DEVELOPMENT HISTORY:
#    Author           Change-ID        Release  Date      Description of Change
#    ---------------  ---------------  -------  --------  ---------------------
#    T. Le            WIND970001       R1.0     11/10/97  Initial version
#    R. Wiechert      ISTP             R1.1     12/01/97  Add CDHF format files
#                                                          and choice of devices.
#    R. Wiechert      ISTP             R1.0C    02/04/98  Add ISAS format files,
#                                                          delimiter types, and
#                                                          tape serial numbers.
#    R. Wiechert      ISTP             R1.0C    03/11/98  Add choice of formats,
#                                                          modify ISAS process.
#
#    NOTES:
#    none
#
#******************************************************************************
tmp_file=label.$$
default_device=/dev/rmt/2bn
default_format=NASA
default_block_size=6250
maximum_block_size=65535
maximum_null_count=3
isas_block_size=23040
isas_file_prefix="GE_SD_ISAS_"
raw_file_prefix="RAW_"
start_block="TAPE INVENTORY NUMBER:  "
end_block="CREATION DATE:  "
start_product=" @ISTP_COM:RG_BUILD_TRANSFER_LIST"
end_product="END"
start_vaxheader=".*HDR1.*DECFILE.*HDR2.*HDR3.*HDR4.*"
start_vaxfilename=".*HDR1"
start_vaxextension=".*HDR1.*DECFILE.*HDR2.*HDR3.*HDR4 "
return=0

if [ $# -gt 0 ]
then
more << END_USAGE_TEXT
 
USAGE:     loadtape [help]

PURPOSE:   Loads ISTP standard data files from tape device.

SYNOPSIS:  After prompting for the tape format and device,
           loadtape will load files from the specified tape
           device into the current working directory.  All
           known data formats are automatically recognized,
           except for ISAS contingency formats which do not
           always have tape labels:

                NASA ISTP GBRS NASCOM block files
                NASA ISTP LZP IBM product files
                NASA ISTP CDHF VAX product files
                ISAS ISTP GEOTAIL contingency files

           In the event that a format is not recognized,
           a file called "label.unknown" is generated for
           inspection and debugging.  Otherwise, all other
           temporary files generated during the load will
           be removed automatically.  Unknown formats can
           be loaded using the RAW format specification.

NOTES:     When loading ISAS contingency data, several
           zero length read operations are expected near
           the end of the loading process.  This is not
           an error condition.  If the load does not result
           in the expected volume of data, try again using
           an alternate tape format specification.

END_USAGE_TEXT
exit 1
fi

printf "\nFormat   Description\n"
printf "------   -------------------------------------\n"
printf "NASA     load using automatic format detection\n"
printf "ISAS-8   load ISAS RAW format, usually 8mm\n"
printf "ISAS-9   load ISAS IBM format, usually 9track\n"
printf "RAW      load all files including markers\n"
printf "\nEnter tape format ($default_format): "
read tape_format
if [ ! "$tape_format" ]
then
   tape_format="$default_format"
fi

tape_format=`echo $tape_format | tr '[a-z]' '[A-Z]'`
case $tape_format in
   NASA)    label_type=unknown ;;
   ISAS-8)  label_type=isas ;;
   ISAS-9)  label_type=isas ;;
   RAW)     label_type=raw ;;
   *) printf "Unknown tape format\nABORTED\n"; exit 1 ;;
esac

printf "Enter tape device ($default_device): "
read tape_device
if [ ! "$tape_device" ]
then
   tape_device="$default_device"
fi

printf "\nPlease load, rewind, and bring tape online.\n"
printf "Begin reading tape now (Yes/No)? "
read answer
answer=`echo $answer | tr '[a-z]' '[A-Z]' | tr -cd 'YN'`
if [ "$answer" != "Y" ]
then
   printf "User cancelled job\nABORTED\n"; exit 1
fi

printf "\nRewinding...\n"
mt -f $tape_device rewind 1>/dev/null 2>/dev/null
trap "echo ABORTED; rm -f $tmp_file 2>/dev/null; mt -f $tape_device rewind; exit 1" 1 2 3 15

if [ "$label_type" = "unknown" ]
then
   printf "Reading label...\n"
   dd if=$tape_device of=$tmp_file bs=$default_block_size
   if [ $? != 0 ]
   then
      printf "READ ERROR\n"
      exit 1
   fi

   OLDIFS=$IFS
   IFS="!\$"
   read label <$tmp_file
   for line in $label
   do
      if [ "$label_type" = "product" ]
      then
         file_list=$line
         break
      fi

      word=`expr "$line" : "$start_block\(.*\)$end_block.*"`
      if [ "$word" ]
      then
         label_type="block"
         extension=.$word
         dayofyear=`expr "$line" : ".*DATA START:  \(...\) ........ ...DATA STOP:.*"`
         millisecs=`expr "$line" : ".*DATA START:  ... \(........\) ...DATA STOP:.*"`
         microsecs=`expr "$line" : ".*DATA START:  ... ........ \(...\)DATA STOP:.*"`
         filename=$dayofyear"_"$millisecs"_"$microsecs
         blocksize=$default_block_size
         break
      fi

      word=`expr "$line" : "\($start_product\).*"`
      if [ "$word" ]
      then
         label_type="product"
         continue
      fi

      word=`expr "$line" : "\($start_vaxheader\)"`
      if [ "$word" ]
      then
         label_type="vaxfile"
         file_list=$line
         blocksize=$maximum_block_size
         break
      fi
   done
   IFS=$OLDIFS
fi

if [ "$label_type" = "block" ]
then
   printf "\nReading $filename$extension\n"
   printf "??? bytes, ??? per record\n"
   dd if=$tape_device of=$filename$extension bs=$blocksize
   if [ $? != 0 ]
   then
      printf "READ ERROR\n"
      return=1
   fi
fi

if [ "$label_type" = "product" ]
then
   set -- $file_list
   while [ $# -gt 0 ]
   do
      word=`expr "$1" : "\(.._.._..._........_V..\)"`
      if [ "$word" ]
      then
         filename=$1
         totalsize=$2
         extension=$6
         blocksize=$7
         printf "\nReading $filename$extension\n"
         printf "$totalsize bytes, $blocksize per record\n"
         dd if=$tape_device of=$filename$extension bs=$blocksize
         if [ $? != 0 ]
         then
            printf "READ ERROR\n"
            return=1
         fi
         shift 7
      else
         if [ "$word" = "$end_product" ]
         then
            break
         fi
         shift 1
      fi
   done
fi

if [ "$label_type" = "vaxfile" ]
then
   while [ "$file_list" ]
   do
      filename=`expr "$file_list" : "$start_vaxfilename\(.................\).*"`
      extension=`expr "$file_list" : "$start_vaxextension\(.........\).*"`
      printf "\nReading $filename$extension\n"
      printf "??? bytes, ??? per record\n"
      dd if=$tape_device of=$filename$extension bs=$blocksize
      if [ $? != 0 ]
      then
         printf "READ ERROR\n"
         return=1
      fi
      dd if=$tape_device of=$tmp_file bs=$blocksize
      dd if=$tape_device of=$tmp_file bs=$blocksize
      if [ $? != 0 ]
      then
         printf "READ ERROR\n"
         return=1
         break
      fi
      OLDIFS=$IFS
      IFS="!\$"
      file_list=""
      read label <$tmp_file
      for line in $label
      do
         word=`expr "$line" : "\($start_vaxheader\)"`
         if [ "$word" ]
         then
            file_list=$line
         fi
      done
      IFS=$OLDIFS
   done
fi

if [ "$label_type" = "isas" -o "$label_type" = "raw" ]
then
   date=`date "+%Y%m%d:%T"` # YYYYMMDD:HH:MM:SS
   day=`expr "$date" : '\(.*\):.*:.*:.*'`"_"
   hrs=`expr "$date" : '.*:\(.*\):.*:.*'`
   min=`expr "$date" : '.*:.*:\(.*\):.*'`
   sec=`expr "$date" : '.*:.*:.*:\(.*\)'`
   time=`expr $sec + 60 \* $min + 3600 \* $hrs`
   time=`expr $time / 2`

   serialnum=`printf "%04X" $time`
   printf "\nTape ID must be unique for a particular day.\n"
   printf "Enter unique tape identifier ($serialnum): \n"
   read answer
   if [ "$answer" ]
   then
      serialnum="$answer"
   fi

   case $label_type in
      isas) file_prefix="$isas_file_prefix"; current_block_size="$isas_block_size" ;;
      raw)  file_prefix="$raw_file_prefix";  current_block_size="$maximum_block_size" ;;
      *)    file_prefix="ERROR_"; current_block_size="0" ;;
   esac
 
   sleep 2 # ensures that suggested serial numbers are unique
   file_list=`ls -d $file_prefix$day$serialnum*.S* 2>/dev/null`
   if [ "$file_list" ]
   then
      printf "FILE EXISTS\n"
      exit 1
   fi

   segment=1
   logical_count=1
   physical_count=0
   null_count=0

   shift $#
   set -- A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
   while [ $# -gt 0 ]
   do
      group=$1
      filename=$file_prefix$day$serialnum$group
      extension=`printf ".S%02d" $segment`
      if [ "$tape_format" = "ISAS-9" ]
      then
         # skip header, read data, skip tail
         skipflag=`expr $physical_count % 3`
      else
         # always read data
         skipflag=1
      fi

      if [ "$skipflag" = 1 ]
      then
         redirect=""
         blocksize=$current_block_size
         printf "\nReading $filename$extension\n"
         printf "??? bytes, $current_block_size per record\n"
      else
         redirect="1>/dev/null 2>/dev/null"
         blocksize=$default_block_size
         filename=/dev/null
         extension=""
      fi

      eval dd if=$tape_device of=$filename$extension bs=$blocksize $redirect
      if [ $? != 0 ]
      then
         printf "READ ERROR\n"
         return=1
         break
      fi

      if [ "$skipflag" = "1" ]
      then
         logical_count=`expr $logical_count + 1`
         filesize=`ls -ld $filename$extension 2>/dev/null | awk '{ print $5 }'`
         if [ "$filesize" = 0 ]
         then
            rm -f $filename$extension 2>/dev/null
            null_count=`expr $null_count + 1`
            if [ "$null_count" -ge "$maximum_null_count" ]
            then
               printf "GIVING UP\n"
               break
            else
               printf "NULL FILE\n"
            fi
         else
            null_count=0
         fi
         while [ forever ]
         do
            if [ "$label_type" = "raw" ]
            then
               answer=no
            else
               printf "\nFiles should be grouped by day of year.\n"
               printf "Start new file groups when in doubt.\n"
               printf "Next file is number $logical_count on tape.\n"
               printf "\nStart new file group (Yes/No/Quit)? "
               read answer
            fi
            answer=`echo $answer | tr '[a-z]' '[A-Z]' | tr -cd 'YNQ'`
            case $answer in
               Y) segment=1; shift 1; break ;;
               N) segment=`expr $segment + 1`; break ;;
               Q) shift $#; break ;;
            esac
         done
      fi

      physical_count=`expr $physical_count + 1`
   done
fi

if [ "$label_type" = "unknown" ]
then
   printf "\nPlease examine label.unknown\nUNKNOWN LABEL\n"
   mv -f $tmp_file label.unknown
   return=1
fi

printf "\nRewinding...\n"
rm -f $tmp_file 2>/dev/null
mt -f $tape_device rewind 1>/dev/null 2>/dev/null
printf "DONE\n"
exit $return
