:
# Shell script for Backup Professional that resides on Unix clients
# This script converts the Catalog file summary into a "*.ini" file format
# which is sent for the server and added into the database for that backup
# Copyright (C) 1996, 2001 by UniTrends Software Corporation

set_ECHO() { 
	[ -d /usr/5bin ] && { PATH="/usr/5bin:${PATH}"; export PATH; }
  ECHO="echo -e"; 
  echo -e "hello" | grep "e h" >/dev/null && ECHO="echo"
  OS=`uname 2>/dev/null`
  case "$OS" in
      SunOS) [ -x /usr/5bin/echo ] && ECHO=/usr/5bin/echo ;;
  esac
  unset OS; export ECHO
}
set_ECHO


LOGF=$2
BTYPE=$1
TMP1=/tmp/tmp1.$$
TMP2=/tmp/tmp2.$$
export LOGF BTYPE TMP1 TMP2

usage() {
	${ECHO}
	${ECHO} "Usage: $1: {bvrmi} Catalog_file"
	${ECHO} "  b - backup"
	${ECHO} "  m - master backup"
	${ECHO} "  i - incremental backup"
	${ECHO} "  v - verify"
	${ECHO} "  r - restore"
	exit $2
}

count() { #  Usage: count FILE
	wc -l 2>/dev/null <  $1 | tr -d " "
}

fcount(){
	FCOUNT=`sed -n '/^a /p' $1| wc -l 2>/dev/null| tr -d " "`
	${ECHO} ${FCOUNT:=0}
}

vf_count(){
	FCOUNT=`sed -n '/blocks/p' $1| wc -l 2>/dev/null| tr -d " "`
	${ECHO} ${FCOUNT:=0}
}


show_errmsg() {
#Do not edit or touch below, very precise!!
sed -n '/blocks/h; 
/bkup:/{x;p;x;p;b
;}
/ctar:/{x;p;x;p;b
}
/ failed/p;/not a regular/p;/tarcheck:/p;/<!Byte>/p' $1 |
tr  -d "\007"| sed '/a \., 0 blocks/d;/^$/d' 
}

mk_backup_summary(){

tail -30 $LOGF | sed -n '/==========/,$p' > $TMP1

if [ -s $TMP1 ]
then
	grep "[0-9] 199[56789]" $TMP1| sed 's/^[ 	]*//;s/^/Start="/;s/$/"/'
	grep "Elapsed Time:" $TMP1| sed  's/^.*: /Elapsed="/;s/$/"/;'
	grep "FILES:" $TMP1| sed  's/^.*: /Filecount=/;'
	# WARN - rounds down to whole MB or GB value
	TOTALDATA=`grep "Total DATA"  $TMP1 | sed 's/^.*: //;s/ (.*//'`
	DATANUM=`${ECHO} $TOTALDATA|sed 's/MB//;s/K//;s/GB//'`
	case "$TOTALDATA" in
		*[0-9]GB) TOTALK=`${ECHO} $DATANUM | awk '{printf "%.0f", $1 * 1048576 }'`
		${ECHO} "TotalData=$TOTALK" ;;
		*[0-9]MB) TOTALK=`${ECHO} $DATANUM | awk '{printf "%.0f", $1 * 1024 }'`
		${ECHO} "TotalData=$TOTALK" ;;
		*[0-9]K) ${ECHO} "TotalData=$DATANUM" ;;
	esac
	grep "NOT backed" $TMP1| sed  's/^.*: /Notbacked=/;s/file.*NOT.*//'
	grep "INCOMPLETELY backed" $TMP1| sed  's/^.*: /Incomplete=/;s/file.*//'
	grep "Data Transfer" $TMP1| sed  's/^.*: /Speed="/;s/$/"/;'

	ESTAT=`grep "Exit Status is" $TMP1| sed  's/^.*is //;'`
	${ECHO} "ExitStatus=$ESTAT"
	${ECHO} "Exit_Status_English=\c"

else # Probably aborted, or cannot access device
# Had case of 2048 k written, then an error 6 Tape WRITE Error
# Offset is xxxx
	if sed -n '1,30p;31q' $LOGF| grep "Attempt to access" >/dev/null
	then
		ESTAT=1
		${ECHO} "Filecount=0" 
		${ECHO} "Elapsed=0 seconds"
		${ECHO} "TotalData=0"
		${ECHO} "Speed=0"
	else
		if tail $LOGF| grep "Tape Write ERROR" >$TMP1
		then
			ESTAT=4
			${ECHO} "Elapsed=????"
			${ECHO} "Filecount=`fcount $LOGF`" 
			sed -n '1,10p;11q' $LOGF | grep "[0-9] 199[56789]" | 
				sed 's/^[ 	]*//;s/^/Start="/;s/$/"/'
			NB=`grep "NOT backed" $LOGF | wc -l 2>/dev/null | tr -d " "`
			[ -n "$NB" ] && ${ECHO} "Notbacked=${NB:=0}"
			INC=`grep "Incompletely backed" $LOGF|wc -l 2>/dev/null |tr -d " "`
			[ -n "$INC" ] && ${ECHO} "Incomplete=${INC}"
			# WARN - assume "Offset is xxxxK"
			OFFSET_K=`tail $LOGF| sed -n '/^Offset/p' |
				sed 's/^.* is //;s/[Kk]//;s/[GM]b//;'`
			${ECHO} "TotalData=${OFFSET_K:=0}"
			${ECHO} "Speed=????"
		else
		ESTAT=11
		${ECHO} "Elapsed=Interrupted"
		sed -n '1,10p;11q' $LOGF | grep "[0-9] 199[56789]" | 
			sed 's/^[ 	]*//;s/^/Start="/;s/$/"/'
		${ECHO} "Filecount=`fcount $LOGF`" # WARN - estimate only,
		NB=`grep "NOT backed" $LOGF | wc -l 2>/dev/null | tr -d " "`
		[ -n "$NB" ] && ${ECHO} "Notbacked=${NB:=0}"
		INC=`grep "Incompletely backed" $LOGF | wc -l 2>/dev/null | tr -d " "`
		[ -n "$INC" ] && ${ECHO} "Incomplete=${INC}"
		${ECHO} "TotalData=0" # Must be in K
		${ECHO} "Speed=????"
		fi
	fi
	${ECHO} "ExitStatus=$ESTAT"
	${ECHO} "Exit_Status_English=\c"
fi

ERR_STATUS=$ESTAT
case "$ESTAT" in
	0) ${ECHO} "Successfull" ;;
	1) ${ECHO} "Error in usage options of CLIENT" ;;
	2) ${ECHO} "An ERROR occurred which is fatal" ;;
	3) ${ECHO} "Device or Network Socket read error" ;;
	4) ${ECHO} "Device or Network Socket write error" ;;
	5) ${ECHO} "An ERROR occurred opening a FILE on the HARD DISK" ;;
	6) ${ECHO} "HARDWARE ERROR while READING a FILE on the DISK" ;;
	7) ${ECHO} "HARDWARE ERROR while WRITING to a FILE on the DISK";;
	8) ${ECHO} "Ran out of MEMORY" ;;
	9) ${ECHO} "Virtual pipe error" ;;
	10) ${ECHO} "Directory format error" ;;
	11) ${ECHO} "Process Interrupted";;
	12) ${ECHO} "Disk seek error";;
	13) ${ECHO} "Verify was bad";;
	14) ${ECHO} "Bit Level verify failed" ;;
	15) ${ECHO} "Incomplete Backup";;
	16) ${ECHO} "Semaphore initialization failure";;
	17) ${ECHO} "Share memory initialization failure";;
	18) ${ECHO} "An ERROR occurred with Double Buffering";;

	# WARN - the following information won't show since CLIENT aborts 
	# and never prints this error status code.  Only a calling
	# program would know the following exit codes.

	132) ${ECHO} "Illegal Instruction  - found in the binary"
		${ECHO} "Wrong version/machine mismatch or upgrade problem"
		${ECHO} "Call for technical support";;
	136) ${ECHO} "Floating point exception occurred"
		 ${ECHO} "Call technical support";;
	137) ${ECHO} "Someone terminated CLIENT with a kill -9 !!";;
	139) ${ECHO} "Out of bounds memory fault occurred" ;;

	140) ${ECHO} "A bad system call was encountered.  This means your kernel"
	${ECHO} "does not support a system call CLIENT made."
	;;
	141)
	${ECHO} "The Network link failed.  This is usually due to a problem"
	${ECHO} "on the node computer where the tape drive is"
	;;
	142)
	${ECHO} "CLIENT received an alarm signal and terminated.  Most likely someone"
	${ECHO} "typed \"kill -14 pid##\", when they meant to type kill -15 pid##"
	;;
	143) ${ECHO} "CLIENT task was cancelled by user (kill -15 was used).";;
	# Get left over signals not picked up above - 32 signals total
	12[89]|13*|14*|15*|16*) export ERR_STATUS; SIGNAL=`expr "$ERR_STATUS" - 128`
	${ECHO} "CLIENT received a signal $SIGNAL"
	${ECHO} "This may be an internal signal or generated with kill -$SIGNAL"
	${ECHO} "You can type \"man signal\" to find out about signal $SIGNAL"
	${ECHO} "or you can look it up in \"/usr/include/sys/signal.h\""
	;;
	20)
	${ECHO} "CLIENT ERROR: $ERR_STATUS - SERIOUS LICENSE ERROR "
	${ECHO} "Call for assistance!!"
	;;

	"") ${ECHO} "Exit Status was never set";;
	* ) 
	${ECHO} "CLIENT ERROR: $ERR_STATUS - SERIOUS ERROR (No further information)"
	;;
esac
return 0
}

mk_verify_summary(){
	# WARN TT may not always be true, could be TVfbkT
	if sed -n '2p;3q' $LOGF | grep "T.*T" >/dev/null
	then # Level 2 verify
		tail $LOGF > $TMP1
		if grep SUMMARY $TMP1 >/dev/null # Level 2 verify
		then 
			sed -n '/SUMMARY/,$p' $TMP1 | sed '/See the file:/d;s///;'
		else # Probably interrupted!!
			${ECHO} "SUMMARY: Byte by Byte Verification"
			VFILES=`vf_count $LOGF`
			${ECHO} "         $VFILES file(s) encountered"
			${ECHO} "         VERIFY was interrupted or encountered a serious error!!"
			if [ "$VFILES" -gt 0 ]
			then
				${ECHO} "         Last file was: "
				sed -n '$p' $TMP1
			fi
		fi
	else # Level 1 verify, get last line only
			tail $LOGF |sed -n '$p'
	fi
	return 0
}

mk_restore_summary(){
	# Capture tail end which shows successful as well as incomplete stats
	tail $LOGF | sed -n '/FILES /p;/[	 ][Ff][Ii][Ll][Ee][s ] /p'   >$TMP1 
	cat $TMP1
	RFILES=`grep 'restored: ' $TMP1 2>/dev/null  | sed 's/.*restored: //' `
	if [ ! -s $TMP1 ]
	then
		RFILES=`sed -n '/ blocks/p' $LOGF| wc -l 2>/dev/null | tr -d " "`
		${ECHO} "FILES restored: $RFILES"
		${ECHO} "Restore may have aborted, since agent summary was incomplete"
		# Show Last 5 lines
		tail -5 $LOGF  
	fi
	${ECHO} "Filecount=$RFILES" 
	return 0
}

#################
##    Main     ##
#################

trap 'rm -f $TMP1 $TMP2; exit 1' 2

if [ -z "$LOGF" ]
then
	${ECHO}
	${ECHO} "$0: No logfile was specified to capture summary from."
	usage $0 100
fi

if [ ! -f "$LOGF" ]
then
	${ECHO}
	${ECHO} "$0: The logfile \"$LOGF\" does not exist."
	${ECHO} "$0: Check spelling or permissions."
	exit 100
fi
if [ -z "$BTYPE" ]
then
	${ECHO}
	${ECHO} "$0: No backup type {b,v,r,m,i} was passed to this script."
	usage $0 100
fi

case "$BTYPE" in
	b|m|i) mk_backup_summary; RET=$?;;
	v) mk_verify_summary;     RET=$?;;
	r) mk_restore_summary;    RET=$?;;
	l) RET=0;; # Not a lot we can do, there is not summary
esac

show_errmsg $LOGF > $TMP1

# strip out any lines starting with "a " "t " or "T " since they are informational messages.
# prevents filenames that match error strings from showing as errors.
grep -v "^a " $TMP1 | grep -v "^t " | grep -v "^T " > $TMP2
cp $TMP2 $TMP1

# If cancelled, we are not interested in unresolved links
# This would be expected, so we weed them out
if [ "${ESTAT:=0}" -eq 143 ] 
then
	grep -v "Unresolved links to" $TMP1 | grep -v "bkup: Program terminated" |
	grep "bkup:" > $TMP2
	cp $TMP2 $TMP1
fi

[ $BTYPE = v ] && {
	if grep "<!Byte>" $TMP1 > $TMP2 
	then
		${ECHO} "\nThe following files FAILED VERIFICATION:"
		cat $TMP2; 
		grep -v "<!Byte>" $TMP1 >$TMP2
		cp $TMP2 $TMP1
	fi
}
if [ -s $TMP1 -a "$ESTAT" !=  20 ] 
then
	${ECHO} "\nERRORS/WARNINGS encountered:"
	cat $TMP1
	# Would be nice to split out WARNINGS from ERRORS but this
	# is difficult because some messages come in paired lines and
	# others don't 
	#grep -v WARNING $TMP1 # All bkup: error messages
	#if grep WARNING $TMP1 > /dev/null
	#then
	## We only show warnings preceeded by bkup: (serious ones)
	#${ECHO} "WARNINGS encountered:"
	#grep WARNING $TMP1
	#fi
fi

rm -f $TMP1 $TMP2

exit $RET
