#!/bin/ksh
#**********************************************************************#
#*                                                                    *#
#* Copyright (c) 2001 by Sun Microsystems, Inc.                       *#
#* All rights reserved.                                               *#
#*                                                                    *#
#**********************************************************************#


########################################################################
#                                                                      #
# BATCH Utility       :     IEBCOPY                                    #
# Purpose             :     Dataset copy utility                       #
#                                                                      #
#                                                                      #
#                                                                      #
########################################################################


# function: iebcopy_abort
iebcopy_abort ()
{
   echo 16 > status.${JON}
   exit 16
}

# function: exec_iebcopy_command     execute command and test for error
exec_iebcopy_command ()
{
   $iebcopy_command
   if [ $? -ne 0 ]
   then
      echo "IEBCOPY  (S) command unsuccessful"
      echo "             $iebcopy_command"
      iebcopy_abort
   fi
}
# function: locate_function
locate_function ()    
{
   if [ "a$IDEBUG" = ayes ]
   then
      set -x
   fi
   field=1
   while [ $field -lt 3 ]
   do
      word=`echo $tmpline | cut -f$field -d' '`
      case $word in
         COPY)
            new_function=$word ; export new_function
            break
         ;;
         ALTERMOD|COPYGRP|CG|COPYMOD|CM)
            new_function=$word ; export new_function
            echo "IEBCOPY (S) function not supported: $word"
            echo "            $line"
            iebcopy_abort
            break
         ;;
         LIST=*|MAXBLK=*|MEMBER=*|M=*|MINBLK=*|EXCLUDE|SELECT|S)
            new_keyword=$word; export new_keyword
            echo "IEBCOPY (S) function not supported: $word"
            echo "            $line"
            iebcopy_abort
            break
         ;;
         INDD=*|I=*)
            new_keyword=INDD; export new_keyword
            #if INDD is first on line, we have concatenation
            indd_concat=true; export indd_concat
            break
         ;;
         *)
            if [ $field -eq 2 ]
            then
               # function statement must be first or second word on line
               echo "IEBCOPY (S) function not supported: $word"
               echo "            $line"
               echo 255 > status.${JON}
               exit 255
            else
               # first position may be the optional label 
               # check if second position is a recognizable function
               field=`expr $field + 1`; export field
            fi
         ;;
      esac
   done
}

# function: process_current_copy
process_current_copy ()    
{
   if [ "a$IDEBUG" = ayes ]
   then
      set -x
   fi
   if [ $current_function = COPY ]
   then
     #-------------------------------------------------------------------------
     #  Have COPY to process -  Must have INDD and OUTDD
     #-------------------------------------------------------------------------
     if [ "a$outfile" = a  -o  "a$inddlist" = a ]
     then
        # COPY does not have OUTDD defined - error
        echo " "
        echo "IEBCOPY  (S) command unsuccessful: COPY function  requires INDD and OUTDD"
        echo " "
        echo "IEBCOPY  (S) command unsuccessful"
        echo "             $iebcopy_command"
        echo " "
        echo 16 > status.${JON}
        exit 16
     fi
     if [ "a$VERBOSE" = ayes ]
     then
        echo "IEBCOPY  (I) outfile  : $outfile"
        echo "             infile(s): $inddlist"
     fi

     #-------------------------------------------------------------------------
     # Determine status of outfile
     #-------------------------------------------------------------------------
     if [ ! -f $outfile ]
     then
        # outfile does not exist as a file
        if [ -d $outfile ]
        then
          # outfile exists as a directory - a PDS,
          # in this environment as a directory containing 'member' files
          outfile_type=pds; export outfile_type
          outdir=$outfile; export outdir
        else
           #-------------------------------------------------------------------
           # Outfile does not exist as a file nor a directory 
           # Make the directory path (if necessary) and initialize the file
           #-------------------------------------------------------------------
           # First, retrieve path
           #-------------------------------------------------------------------
           iebcopy_command="outdirname=\`dirname $outfile\`"
           exec_iebcopy_command
           #-------------------------------------------------------------------
           # Create output file directory if necessary
           #-------------------------------------------------------------------
           if [ ! -d $outdirname ]
           then
              iebcopy_command="mkdir -p $outdirname"; export iebcopy_command
              exec_iebcopy_command
              cat $DEVNULL > $outfile
           fi
           outfile_type=file; export outfile_type
        fi
     else
        #-------------------------------------------------------------------
        # outfile already exists as a file - reinitialize before copy
        #-------------------------------------------------------------------
        cat  $DEVNULL > $outfile
        outfile_type=file; export outfile_type
     fi
     #-------------------------------------------------------------------------
     # Now process infile(s)
     #-------------------------------------------------------------------------
     entry=2
     last_infile=false; export last_infile
     until [ $last_infile = true ]
     do 
        infile_name=`echo $inddlist | cut -f$entry  -d':'`
        if [ -z $infile_name ]
        then
           # no more to process
           last_infile=true; export last_infile
           break
        fi 

        if [ -d $infile_name ]
        then
           #-----------------------------------------------------------------
           # The INDD points to an existing directory, not a file
           # INDD is a PDS 
           # In this environment, a directory containing "member" files
           #-----------------------------------------------------------------
           infile_type=pds; export infile_type
           indir=$infile_name; export indir
        else
           if [ ! -f $infile_name ]
           then
              echo "IEBCOPY  (S) Error: input file does not exist:"
              echo "             $infile_name"
              iebcopy_abort
           else
              # infile_name exists as a file
              infile_type=file
           fi
        fi

        case $infile_type in 
           file)
              case $outfile_type in
                 file)
                    # sequential in file to out sequential file
                    iebcopy_command="cp $infile_name $outfile"; export iebcopy_command
                 ;;
                 pds)
                    # sequential in file to out pds directory 
                    iebcopy_command="cp $infile_name  $outdir"; export iebcopy_command
                 ;;
              esac
           ;;
           pds)
           case $outfile_type in
              file)
                    #pds input sequential file output - not supported
                    echo "IEBCOPY  (S) Copy of a PDS to a sequential file is not supported in the current version"
                    iebcopy_abort
                 ;;
                 pds)
                    #pds input pds output
                    #iebcopy_command="cp $indir/* $outdir" ; export iebcopy_command
                    indirlist=`ls -1 $indir` ; export indirlist
                    outdirlist=`ls -1 $outdir` ; export outdirlist
                    for name in $indirlist
                    do
                       echo $outdirlist | grep $name  > $DEVNULL 2>&1
                       if [ $? -eq 0 ]
                       then
                          echo "IEBCOPY (W) ${outdir}/${name} exists, copy not performed"
                       else
                          iebcopy_command="cp ${indir}/${name} $outdir"
                          if [ "a$VERBOSE" = aYES ]
                          then
                             echo "IEBCOPY command: $iebcopy_command"
                          fi
                          exec_iebcopy_command
                          iebcopy_command=''; export iebcopy_command
                       fi
                    done
                 ;;
              esac
           ;;
        esac
        if [ "a$VERBOSE" = aYES -a "a$iebcopy_command" != a ]
        then
           echo " "
           echo "IEBCOPY  (I) command is:"
           echo "             $iebcopy_command"
           echo " "
        fi
        exec_iebcopy_command
        entry=`expr $entry + 1`
     done
  #else
      # No copy to process - just return   
   fi
   current_function=null; export current_function
}


#function: build_copy 
build_copy ()
{
   #---------------------------------------------------------------------------
   # The current function is a COPY  
   #---------------------------------------------------------------------------
   # may have single ddname 
   # INDD=ddname
   # or multiple 
   # OUTDD=OUT1,INDD=DD1,DD2,DD3
   # INDD=DD1,DD2,DD3,OUTDD=OUT1
   # also may have:
   # OUTDD=OUT1,INDD=((DD1,R),DD2,DD3) 
   # OUTDD=OUT1,INDD=((DD1_R),DD2,DD3) change ,R to _R
   # OUTDD=OUT1,INDD=((DD1_R) DD2,DD3) change ',' to space
   # OUTDD=OUT1,INDD=DD1_R DD2 DD3  change '(' and ')' to space
   #---------------------------------------------------------------------------
   if [ "a$IDEBUG" = ayes ]
   then
      set -x
   fi
   
   echo $tmpline|grep "INDD=("
   if [ $? = 0 ]
   then
      echo " "   
      echo "IEBCOPY  (S) INDD syntax not supported in the current version:"
      echo " "   
      echo $line
      echo " "   
      iebcopy_abort
   fi

   while [ $# -ne 0 ]
   do
      arg=${1}; export arg
      parse_string $arg ; export parse_string
      # walk through strings
      case $string_type in
         function)
         ;;
         keyword)
            case $keyword_name in
               INDD)
                  current_keyword=INDD; export current_keyword
                  envdd=$`eval echo DD_${keyword_value}`
                  envdd=`eval echo $envdd`
                  inddlist=$inddlist:$envdd; export inddlist
               ;;
               OUTDD)
                  current_keyword=OUTDD; export current_keyword
                  envdd=$`eval echo DD_${keyword_value}`
                  outfile=`eval echo $envdd`; export outfile
               ;; 
               EXCLUDE)
                  # EXCLUDE=(MEM1,MEM2,...)
                  # EXCLUDE=MEM1
                  echo "IEBCOPY  (S) Keyword: $keyword_name not supported in the current version "
                  echo "             $line"
                  iebcopy_abort
               ;;
               SELECT|S)
                  # SELECT=MEM1
                  # SELECT=((MEM1,NEWNAME,R),MEM2)
                  # SELECT=((MEM1,,R),MEM2)
                  # SELECT=(MEM2,(MEM1,NEWNAME))
                  echo "IEBCOPY  (S) Keyword: $keyword_name not supported in the current version "
                  echo "             $line"
                  iebcopy_abort
               ;;
               *)
                  echo "IEBCOPY  (S) Keyword: $keyword_name not supported in the current version "
                  echo "             $line"
                  iebcopy_abort
               ;;
            esac    
         ;;
         keyword_value)
            if [ "a$current_keyword" = "aINDD" ]
            then
               envdd=$`eval echo DD_${string_value}`
               envdd=`eval echo $envdd`
               inddlist=$inddlist:$envdd; export inddlist
                     
            fi
         ;;
         *)
         ;;
      esac
      shift
   done
}

# function: parse_string
parse_string () {
   if [ "a$IDEBUG" = ayes ]
   then
      set -x
   fi
   string_type=null; export string_type
   function_name=null; export function_name
   keyword_name=null; export keyword_name
   keyword_value=null; export keyword_value
   string_value=null; export string_value
   parse_string=${1}
   case $parse_string in
      ALTERMOD|COPYGRP|CG|COPYMOD|CM)
         string_type=function; export string_type
         function_name=$parse_string; export function_name
      ;;
      LIST=*|MAXBLK=*|MEMBER=*|MINBLK=*)
         string_type=keyword; export string_type
         keyword_name=`echo $parse_string | cut -f1 -d'='`
         export keyword_name
         keyword_value=`echo $parse_string | cut -f2 -d'='`
         export keyword_value
      ;;
      EXCLUDE)
         string_type=keyword; export string_type
         keyword_name=EXCLUDE; export keyword_name
         echo "IEBCOPY (S) Keyword: $keyword_name is not supported in the current version"
         iebcopy_abort
      ;;
      SELECT|S)
         string_type=keyword; export string_type
         keyword_name=SELECT; export keyword_name
         echo "IEBCOPY (S) Keyword: $keyword_name is not supported in the current version"
         iebcopy_abort
         
      ;;
      COPY|C)
         string_type=function; export string_type
         function_name=COPY; export function_name
      ;;
      INDD=*|I=*)
         string_type=keyword; export string_type
         keyword_name=INDD; export keyword_name
         keyword_value=`echo $parse_string|cut -f2 -d'='`; export keyword_value
      ;;
      OUTDD=*|O=*)
         string_type=keyword; export string_type
         keyword_name=OUTDD; export keyword_name
         keyword_value=`echo $parse_string|cut -f2 -d'='`; export keyword_value
      ;;
      *)
         string_type="keyword_value"; export string_type
         string_value=$parse_string; export string_value
         
      ;;
   esac
}

#------------------------------------------------------------------------------
#  Start IEBCOPY
#------------------------------------------------------------------------------
echo " "
echo "Start:  IEBCOPY"
if [ "a$VERBOSE" = aYES -o "a$VALIDATE" = "ay" ]
then
  if [ "a$IDEBUG" = ayes ]
  then
     set -x
  fi
  echo " "
  echo "---------------------------------------------------------------------- "
  echo "IEBCOPY (W) Utility is not fully supported"
  echo "   Supported:"
  echo "        . COPY of SYSUT1 to SYSUT2"
  echo "        . COPY INDD=.. OUTDD=.. control statements defined in SYSIN"
  echo "   Copy of an input PDS to an output sequential file is not supported."
  echo "   EXCLUDE and SELECT options of COPY function are not supported."
  echo "   All other IEBCOPY functions are not supported in the current version."
  echo "---------------------------------------------------------------------- "
  echo " "
fi

iebcopy_action=null
echo 0 > status.${JON}

if [ "a$VALIDATE" = "ay" ]
then
   echo "IEBCOPY (I) submitted in validation mode, not executed"
fi
if [ "a$VALIDATE" = "ay" ]
then
   exit 0
fi


#----------------------------------------------------------------------------#
# SUPPORTED:   simple copy syntax: 
# //STEP1  EXEC PGM=IEBCOPY
# //SYSUT1 DD DSN=dataset     can be sequential file or PDS
# //SYSUT2 DD DSN=dataset     can be sequential file or PDS
#
# SYSIN is not required, if present is ignored
#----------------------------------------------------------------------------#


#----------------------------------------------------------------------------#
#  SYSIN data syntax is:
#  <optlabel> <control_statement_name> <parms>
#
#  where optlabel is :           a 1-8 character optional label name 
#
#  control_statement_name can be: 
#                                ALTERMOD 
#                                COPY       ***** only COPY is supported ****
#                                COPYGRP CG
#                                COPYMOD CM 
#                                EXCLUDE 
#                                SELECT   S
#                                INDD= (indicates begin of next copy sequence)  
#
# COPYMOD,COPYGRP, SELECT, EXCLUDE, ALTERMOD are not supported.
#----------------------------------------------------------------------------#

#----------------------------------------------------------------------------#
# check for valid COPY syntax: 
# //STEP1  EXEC PGM=IEBCOPY
# //DDIN1  DD  ...
# //DDOUT1 DD  ...
# //SYSIN  DD   * or DSN=
# <optlabelname> COPY INDD=DDIN1,OUTDD=DDOUT1
# <optlabelname> COPY INDD=DDINn,OUTDD=DDOUTn
# <optlabelname> COPY INDD=DDINn,OUTDD=DDOUTn
#----------------------------------------------------------------------------#

#----------------------------------------------------------------------------#
# also may have concatenation:
# //STEP1  EXEC PGM=IEBCOPY
# //DDIN1  DD  ...
# //DDOUT1 DD  ...
# //SYSIN  DD   * or DSN=
# <optlabelname> COPY OUTDD=DDOUT1
#                DDIN=DDINn 
#                DDIN=DDINn
#----------------------------------------------------------------------------#

#----------------------------------------------------------------------------#
# IEBCOPY can also be used to copy PDS's and PDSE's 
#
# This is not supported in this version and will fail with:
#  cp: xyzdirname: is a directory 
#----------------------------------------------------------------------------#

#----------------------------------------------------------------------------#
# Check if copy of SYSUT1 to SYSUT2
#----------------------------------------------------------------------------#
if [ "a$DD_SYSUT1" != a ]
then
   if [ "a$DD_SYSUT2" != a ]
   then
      iebcopy_action=sysut1_to_sysut2
   fi
fi

#----------------------------------------------------------------------------#
# Check for SYSIN control statements
#----------------------------------------------------------------------------#
if [ $iebcopy_action = null ]
then
   if [ "a$DD_SYSIN" = a ]
   then
      echo "IEBCOPY (S) ERROR: SYSUT1 or SYSUT2 not defined, SYSIN is required"
      echo 16 > status.${JON}
      exit 16
   else
      iebcopy_action=sysin
   fi
fi

case $iebcopy_action in
   sysut1_to_sysut2)
      if [ "a$VERBOSE" = aYES -o "a$VALIDATE" = "ay" ]
      then
         if [ "a$DD_SYSUT1" != a ]
         then
            echo " "
            echo "DD_SYSUT1=$DD_SYSUT1"
         fi
         if [ "a$DD_SYSUT2" != a ]
         then
            echo "DD_SYSUT2=$DD_SYSUT2"
         fi
         if [ "a$DD_SYSIN" != a ]
         then
            echo " "
            echo "DD_SYSIN:"
            cat $DD_SYSIN
            echo " "
         fi
         echo " "
      fi
      #--------------------------------------------
      #  SYSUT2 must be FS
      #--------------------------------------------
      if [ -d "$DD_SYSUT2" ]
      then
         # SYSUT2 exists as a directory and is a PDS - directory with  
         # "member" files 
         sysut2_type=pds; export sysut2_type
      else
         sysut2_type=file; export sysut2_type
      fi

      if [ $sysut2_type = file ]
      then
         if [ "a$SYSUT2_FILETYPE" = a ]
         then
           #Do not  have file type
           if [ "a$SYSUT2_FILENAME" != a ]
           then
              #Have filename, determine if file type is SYSOUT
              echo $SYSUT2_FILENAME | grep sysoutdir >$DEVNULL 2>&1
              if [ $? -eq 0 ]
              then
                 SYSUT2_FILETYPE=FS #SYSOUT - same as FS
              fi
           else
              #Do not have file type or file name
              if [ "a$DSN_SYSUT2" = a ]
              then
                 #Do not have filetype, file name or datasetname to search File_Map
                 echo "IEBCOPY  (S) ERROR: SYSUT2 - Unable to determine filename or type"
                 echo 16 > status.${JON}
                 exit 16
              else
                 iebcopy_command="sysut2_filemap_filetype=`ftval $DSN_SYSUT2 $JOB_CAT 3`"
                 exec_iebcopy_command
                 if [ "a$sysut2_filemap_filetype" != FS ]
                 then
                    echo "IEBCOPY  (S) ERROR: SYSUT2 file type must be FS"
                    echo 16 > status.${JON}
                    exit 16
                 fi
              fi
           fi
         fi
      fi
      #--------------------------------------------
      #  SYSUT1 can be sequential or PDS
      #--------------------------------------------
      if [ -d "$DD_SYSUT1" ]
      then
         # SYSUT1 exists as a directory and is a PDS -  a directory with  
         # "member" files 
         sysut1_type=pds; export sysut1_type
      else
         sysut1_type=file; export sysut1_type
      fi

      if [ $sysut1_type = file ]
      then
         if [ "a$SYSUT1_FILETYPE" = a ]
         then
           #Do not  have file type
           if [ "a$SYSUT1_FILENAME" = a ]
           then
              #Do not have file type or file name
              if [ "a$DSN_SYSUT1" = a ]
              then
                 #Do not have filetype, file name or datasetname to search File_Map
                 echo "IEBCOPY  (S) ERROR: SYSUT1 - Unable to determine filename or type"
                 echo 16 > status.${JON}
                 exit 16
              else
                 iebcopy_command="sysut1_filemap_filetype=`sysut1_filemap_filetype=ftval $DSN_SYSUT1 $JOB_CAT 3`"
                 exec_iebcopy_command
                 if [ "a$sysut1_filemap_filetype" != FS ]
                 then
                    echo "IEBCOPY  (S) ERROR: SYSUT1 file type must be FS"
                    echo 16 > status.${JON}
                    exit 16
                 else
                    SYSUT1_FILETYPE=FS
                 fi
              fi
           fi
         fi
      fi
      #--------------------------------------------
      #  Perform the SYSUT1 to SYSUT2 copy 
      #--------------------------------------------

      #
      # Determine processing here based on seq vs. PDS
      #
      if [ $sysut1_type = file ]
      then
         iebcopy_command="cp $DD_SYSUT1 $DD_SYSUT2"
         exec_iebcopy_command
         if [ $? -eq 0 ]
         then
            echo "IEBCOPY  (I) Command executed successfully:" 
            echo "             $iebcopy_command"
            echo " "
            echo 0 > status.${JON}
         fi
      else
         # pds
         iebcopy_command="cp $DD_SYSUT1/* $DD_SYSUT2"
         exec_iebcopy_command
         if [ $? -eq 0 ]
         then
            echo "IEBCOPY  (I) Command executed successfully:" 
            echo "             $iebcopy_command"
            echo 0 > status.${JON}
         fi
      fi
   ;;


   sysin)
   #--------------------------------------------------------------------------#
   #  case where copy functions are defined by sysin utility control statements
   # 
   #  <optional label> function <optional OUTDD=...,INDD=...>
   #  function can be: 
   #                ALTERMOD 
   #                COPY       ***** only COPY is supported ****
   #                COPYGRP  CG
   #                COPYMOD  CM
   #                EXCLUDE 
   #                SELECT   
   # 
   #                INDD=   indicates continuation of previous function 
   #                        statement  - supported for COPY=
   #--------------------------------------------------------------------------#
      new_function=null ; export new_function
      current_function=null ; export current_function
      indd_concat=null export indd_concat
      keyword_name=null
      #-----------------------------------
      # read a SYSIN line
      #-----------------------------------
      cat $LN_SYSIN | while read line
      do
         #--------------------------------------------
         # Check if new function statement
         #--------------------------------------------
         tmpline=`echo $line| sed -e 's/,/ /g'`; export tmpline
         locate_function $tmpline
         #----------------------------------------------------
         # May have a current COPY to process
         #----------------------------------------------------
         case $new_function in
            COPY|C)
               process_current_copy 
               #----------------------------------------------------
               # have a new COPY function statement
               #----------------------------------------------------
               current_function=COPY; export current_function
               new_function=null; export new_function 
               inddlist=""; export inddlist
               command=cp ; export command
               tmpline=`echo $line| sed -e 's/,/ /g'`; export tmpline
               build_copy $tmpline
            ;;
            *)
               if [ $new_function != null ]
               then
                  #----------------------------------------------------
                  # have a function that is not supported
                  #----------------------------------------------------
                  process_current_copy 
                  current_function=$new_function
                  new_function=null
                  echo "IEBCOPY  (S) function not supported in the current version:"
                  echo $line
                  iebcopy_abort
                  echo $line
               else
                  case $new_keyword in
                     INDD)
                        case $current_function in
                           COPY)
                              # have INDD continuation
                              build_copy $tmpline
                           ;;
                           *)
                             #ignore all keywords for functions other than COPY
                           ;;
                        esac
                     ;;
                     OUTDD)
                     ;;
                     *)
                     ;;
                  esac
               fi
            ;;
         esac
      done
      # may have one last COPY to process
      process_current_copy
   ;;
   *)
      echo " "
      echo "IEBCOPY  (S) unsuccessful: invalid syntax"
      echo "             $line"
      echo " "
      echo 16 > status.${JON}
      exit 16
   ;;
   esac
exit 0

