#!/bin/ksh  -up
#
# Rob Blader
#
# net_xfer
#
# The purpose of this program is to provide the user with a means
# to transfer files between 2 unconnected networks.
#
# A log of transfer activity will be kept in /auto/tmp/file_xfer.
#
# Input parameters:  -f   filename
#		         -l   list of files.
#			   -help display a usage message.
#			   -now mode used as root to actually tar up the files to 
#				  tape.
#
# With the -l options, the user is going to supply a file that has a list
# of file names that are to be copied over.
#
# 1.  First we create a file containing the filename(s) that are to be
# transferred.  
#
# 2.  Then we send notification to the operator stating that files
# have been "staged" and are ready to be copied to tape and then read on 
# the target network.
#
# 3.  This script is invoked with the -now flag to tar it to tape.
#
# 4.  The operator carries the tape to target system and runs read_xfer.
# 
# 5.  The user making the request is sent a mail message describing the status.

dir_parse() 
{

#
# Function dir_parse.  Purpose of this is to get the name of each
# directory in a path and add it to $REQ_FILE as a separate file that
# needs to be transfered.  This is required because if a directory in a
# file path does not exist it will be owned by root and its protections
# will have root's umask applied to it when it gets created on the destination
# network.  
#
FILENAME=$1
VERIFY_SCRIPT=$2
REQ_FILE=$3

#echo "running dir_parse $FILENAME"

DIR=`dirname $FILENAME `

while [ $DIR != "/" ];
do

#
#echo "running dir_parse2 $DIR"
# Only add to verify script, not to the request file.
#

#
# When $DIR (string of directories) equals $FILENAME (filename passed)
# then we are done parsing the directory names and it is time to bail
# out
#

echo "/usr/bin/ls -ld $DIR" >> $VERIFY_SCRIPT
                let $((i+=1))
        DIR=`dirname $DIR`
#		echo $DIR
done
sort -u -o $VERIFY_SCRIPT $VERIFY_SCRIPT
}

#==================================================================

#
#
#
# Variable initialization:
#
export PATH='/usr/bin:/usr/ucb:/usr/sbin'
HOLDING_DIR=/auto/admin/file_xfer
LOGFILE=$HOLDING_DIR/xfer.log
REQ_FILE=$HOLDING_DIR/requests.xfr
RUNDIR=/usr/local/bin/FILE_XFER
${USER:=$(/usr/ucb/whoami)}
#
# Had used $USER for the next 2 file names, but found that $USER is not
# set on rlogin sessions so was unreliable.
#
VERIFY_SCRIPT=/auto/admin/file_xfer/xfer_verify.$USER
VERIFY_SCRIPT_OUT=/auto/admin/file_xfer/xfer_verify.$USER.out
DATE=`date`
TAPE_DRIVE=/dev/rmt/0

#
# It is possible that a user could make multiple requests between
# tranfers.  In that case, just append to THAT verification script.
#

if [ ! -f $VERIFY_SCRIPT ]; then
	echo "#!/bin/sh" > $VERIFY_SCRIPT
fi
	
#
# Get parameters.  If none on call line, force the usage message.
#
while [[ $1 = -* || $# = 0 ]]; do

	case $1 in
		-f)
#
# Create a request file if needed.  This is likely since it is deleted after 
# Root runs and tar up the files referenced by the request file.
#
                    if [ ! -f $REQ_FILE ]; then
                         touch $REQ_FILE
                         chgrp admin $REQ_FILE; chmod 775 $REQ_FILE
                    fi


#
# Simple filename - just append to the end of the requests file.
#
			FILENAME=$2
			echo File is $FILENAME
#
# Need to make sure we have an absolute path for the file or there is 
# no telling where it will wind up.
# If it starts with a / assume we have an absolute path
# and don't do anything
#
		case `echo $FILENAME | cut -c1` in

			/) 
				;;
			*)
#
# Otherwise assume we have a relative path and stick $PWD
# in the front of the filename
#	
			FILENAME=$PWD/$FILENAME
				;;
		esac

			if [ -f $FILENAME ]; then
#
# Since I've been given the requirement that transfers are to happen at
# fixed times (via cron) just take file  names and put then in $REQ_FILE.
#
				echo $FILENAME >> $REQ_FILE
#
# Create and Add xfer_verify script to REQ_FILE
#
				dir_parse $FILENAME $VERIFY_SCRIPT $REQ_FILE
				$RUNDIR/xfer_verify -f $FILENAME >> $VERIFY_SCRIPT
				echo $VERIFY_SCRIPT >> $REQ_FILE
				chmod +x $VERIFY_SCRIPT
				$VERIFY_SCRIPT > $VERIFY_SCRIPT_OUT
				echo $VERIFY_SCRIPT_OUT >> $REQ_FILE
#
#  Do some logging:
#
		if [ ! -w $LOGFILE ]; then
			touch $LOGFILE
			chmod 775 $LOGFILE
		fi
			
		    echo "==========================" >> $LOGFILE
		    echo "The file transfer requested by $LOGNAME" >> $LOGFILE
		    echo "Request made at $DATE" >> $LOGFILE
		    echo "Processing file $FILENAME"  >> $LOGFILE
		    echo "==========================" >> $LOGFILE
		
		   else	

			echo "$FILENAME does not exist"

		   fi
			
			shift

			;;

		-l)
#
#		  List of filenames
#
# The only real difference here is that the tar command needs to have
# a -I flag so it knows to read the contents of the file to get the 
# filelist, and slightly different logging. 
#
#
# Create a request file if needed
#
                    if [ ! -f $REQ_FILE ]; then
                         touch $REQ_FILE
                         chgrp admin $REQ_FILE; chmod 775 $REQ_FILE
                    fi


               FILENAME=$2
#
# Verify that every entry in the file list is an absolute pathname
#
      if [ -a $FILENAME ]; then
			for file_entry in `cat $FILENAME`
			do
    			      case `echo $file_entry | cut -c1` in

              		 /)
#
#              If it starts with a / assume we have an absolute path
#              and don't do anything
#
#			Also verify that the file exists.  We'll do this again
#			later when the tape is made but if we catch a problem
#			then we might be able to save some time for the user.
#
#			Until we get better requirements on this, assume that the
#			user must at least be able to read the file to request its 
#			transfer
#
				
				if [ ! -r $file_entry ]; then
					echo "file_xfer: error - no such file as $file_entry. Will process all others"
				else
					 echo $file_entry >> $REQ_FILE
					dir_parse $file_entry $VERIFY_SCRIPT $REQ_FILE
				fi
                    ;;

               	*)
				echo "One or more of the files in the filelist is"
				echo "not an aboslute pathname".
				echo "Please update the list and rerun the procedure"
				exit 

		
                    ;;
	
	          esac
	done
				
#
# Create and add the verify script to the request list for this case
#
	          for i in `cat $2`
     	    	   do
         	           echo "/usr/bin/ls -ld  $i " >> $VERIFY_SCRIPT 
          	   done
		  
			   echo $VERIFY_SCRIPT >> $REQ_FILE
#
# Run the verify script and save its output for transfer
#
			chmod 755 $VERIFY_SCRIPT
			$VERIFY_SCRIPT > $VERIFY_SCRIPT_OUT
			echo $VERIFY_SCRIPT_OUT >> $REQ_FILE
      else
                    echo "ERROR: $FILENAME not a regular file"
				echo "Please check the name and permissions."
				echo " "
				exit
               fi
		    echo "==========================" >> $LOGFILE
              echo "File transfer request by $LOGNAME " >> $LOGFILE
              echo "Request made at $DATE" >> $LOGFILE
              echo "Processing files "  >> $LOGFILE
#		    cat $FILENAME >> $LOGFILE
		    cat $2 >> $LOGFILE
		    echo "==========================" >> $LOGFILE

		shift	
			;;

		
		-now)
#
# Check that there are actually requests to process
#
if [[ ! -f $REQ_FILE ]]; then
	echo "No requests"
	exit 0
fi

#
# Check that the tape is on-line
#

mt -f $TAPE_DRIVE status
case $? in

	0) echo "Tape on-line...."
		 ;;

	*) echo "file_xfer: tape error..."
	 	/usr/ucb/mail -s "Tape not ready for file transfer. Call operator"  root < /dev/null
		 exit 1
		 ;;

esac


#
# Don't do anything if $REQ_FILE does not exist, as
# no requests have been made since last transfer.
#
if [[ -f $REQ_FILE ]]; then

   tar -cvpf /dev/rmt/0 -I $REQ_FILE
   if [ -f $REQ_FILE.0 ]; then
      rm $REQ_FILE.0
   fi
   mv -f $REQ_FILE $REQ_FILE.0
#
# Once tar'ed we no longer need the verify script(s)
#
# Comment out while testing.
#
   /usr/bin/rm -f /auto/admin/file_xfer/xfer_verify.*

#
# Eject the tape. This has been problematic but MUST happen otherwise
# the operators have no way of knowing that the tape needs to be
# carried over to target system.
#
#
#  An error should indicate that the drive os "off-line or no tape
#	loaded".  So, we will remain in this "holding pattern" until 
#    a non-zero status is returned.
#

# 4/13/99 - This is still a problem, rewind the tape, sleep 60, then push the
#		tape out, and sleep another 60 secs before checking the tape
#		drive status
   mt -f ${TAPE_DRIVE} rewind 2>> /dev/null
   sleep 60
   mt -f ${TAPE_DRIVE} offline 2>> /dev/null
   sleep 60
   mt -f ${TAPE_DRIVE} status 2>> /dev/null

   case $? in

       0) # Re-issue the dismount command and wait, and repeat
		count=0
		while [ true ]
		do
       		   	mt -f  ${TAPE_DRIVE} status 2>> /dev/null
			case $? in

				0) # Re-issue the dismount command and wait, then repeat
					if [ $count -le 5 ]
					then
						mt -f ${TAPE_DRIVE} offline 2>> /dev/null
						sleep 20
						count=`expr $count + 1`
					else
#
# Despite all this, the tape still fails to eject sometimes (Harware problem??)
# Send mail to make certain files transfer even if the tape does not eject as 
# it should.
#
/usr/ucb/mail -s "The tape not ejected, run mt offline command on work station"  root,operator < $LOGFILE
					fi
					;;

				1)
					break
					;;
			esac
		done
		;;
      *)
		#
		# Tape should be offline
		#
		break				
		;;

   esac				

else
      exit 0

fi # End test for request file

				;;

	*help* )  print 'usage: file_xfer'
		  print ' [-f filename] or '
		  print ' [-l file containing a list of files]'
		  exit 0
	esac
#	shift

done


mail $LOGNAME << EOD

	Your file transfer request is being processed.  You will be
notified with a mail message on the target network when it is complete. 
Do not move or delete any of the files you requested transferred until after 
you are notified that they have been moved.

	Any questions, please contact a member of the System Administrator.

EOD

# Notify Operators and Admins that a request has been submitted/processed

/usr/ucb/mail -s "file_xfer log information" root,operator < ${LOGFILE}



