#!/bin/ksh
#
#ident	"@(#)rwutil	1.4	04/12/08 SMI"
#
# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
# This script is mainly called by the disk test module to perform
# read/write operations.

# variables
ddout=		# dd output
sec=0		# seconds of transfer
min=0		# minutes of transfer
ddsize=0	# dd size of transfer
avfree=0	# free space
outsize=0	# data value

# functions
err_pg()
{
	echo "\n!ERROR: $1"
	exit 1
}

calc_secs()
{
	((sec=(`echo "$1" | cut -f1 -d'm'`*60)+`echo "$1" | cut -f2 -d'm' | cut -f1 -d'.'`))
}

### MAIN ###

# check args
if [ $# -lt 2 ]
then
	echo "\nUSAGE: $0 [input device] [output device] [[MB size of r/w]]\n"
	exit 1
fi

# check input file
if [ ! -a $1 ]
then
	err_pg "Cannot find file $1"
fi

# check arg 3 
if [ -n "$3" ]
then
	# check numeric arg 3 
	expr $3 + 0 >/dev/null 2>&1
	if [ $? -ne 0 ]
	then
		err_pg "Argument 3 must be a numeric value."
	fi
fi

# check free space
if [ ! -b $2 ]
then
	outsize=`dirname $2`
	((avfree=`df -k $outsize | tail +2 | awk '{print $4}'`/1000))
	outsize=0
	if [ -d $1 ]
	then
		((outsize=`du -sk $1 | awk '{print $1}'`/1000))
	elif [ -f $1 ]
	then
		outsize=`ls -l $1 | awk '{print $5}'`
		((outsize=outsize/1000000))
	fi
	if [ -n "$3" ]
	then
		if [ $outsize -eq 0 ] || [ $outsize -gt $3 ]
		then
			outsize=$3
		fi
	fi
	if [ $avfree -lt $outsize ]
	then
		err_pg "Not enough free space on $2"
	fi
fi	

# do r/w
if [ $outsize -gt 0 ]
then
	echo "Copying ($outsize MBytes) from $1 -> $2"
else
	echo "Copying from $1 -> $2"
fi
if [ -d $1 ]
then
	ddout=`(time (tar cf - $1 | env LANG=C dd of=$2 bs=1000k count=$outsize)) 2>&1` 
else
	ddout=`(time (env LANG=C dd if=$1 of=$2 bs=1000k count=$outsize)) 2>&1`
fi
if [ $? -ne 0 ]
then
	err_pg "$ddout"
fi

# display transfer rate
ddsize=`echo "$ddout" | awk '/out/ {print $1}' | cut -f1 -d'+'`
calc_secs `echo "$ddout" | awk '/real/ {print $2}'`
if [ $sec -gt 0 ]
then
	echo "Transfer rate = $((ddsize/sec)) MBytes/sec" 
else
	echo "Transfer rate = $ddsize MBytes < 1 sec"
fi

# check sums
if [ -f $1 ] && [ -f $2 ]
then
	diff $1 $2 >/dev/null 2>&1
	if [ $? -ne 0 ]
	then
		err_pg "Bad check sum between $1 and $2."	
	fi
fi
