From: eskilb@dhhalden.no (Eskil Brun)
Subject: Free backup scripts...
Summary: Suite of shell scripts to run backup
Keywords: backup script
Organization: Ostfold College
Date: Fri, 20 Nov 1992 09:18:14 GMT

Hi. I've seen many postings about how to run backups.

I've included the scripts we use here to run backup. I wrote these to
use cpio, dd and remote shell. With a little hacking, these scripts
should run on anything that supports no-rewind, berkeley-close tape
devices. You should be able to use any kind of archive program that
can write to stdout. You would have to modify both the backup.sh and
restore.sh scripts to do this. Remote shell access for root is
required in ~root/.rhosts.

We use 4 DDS dat drives connected to HP9000/720 and run compression on
the 720 computers. On the local disks of the computer with the tape
backup rate is ~14+ Megabytes per minute. The average rate is ~10
MB/M. Your mileage will vary according to the speed of your tape
drives, your computers and your disks. I found that compressing data
on a HP9000/720 computer before writing to tape is actually faster
than writing directly to tape. (-:

These scripts are NOT supported by me and I release them on an "as-is"
basis.  If you find them useful or have improvements, I'll be glad to
hear from you. If you do not understand the shell scripts or if you do
not like the way they are written, that's your problem.

I've also included a little perl script to make summaries of the type
below.

I take no responsibility for whatever happens if you use these
scripts.

If you are resonably well versed in /bin/sh, you should have no
problem adopting these scripts to your needs.

Happy hacking...
:-)

P.s: Shell scripts are included in the shar archive is included below
     after the summary from the perl script.

+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
 Eskil Brun                     InterNet: eskil.brun@hrp.no
 Systems Administrator          DingaLingNet: +47 9 183100
 OECD Halden Reactor Project    FaxNet: +47 9 183103
 Norway                         SnailMailNet: P.O. Box 173, N-1751 Halden
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

Here is a summary of last night's backup:

--- chew here ---

Summary of /users/root/backup/backup-log on klaus chuck sleipner volt


MbBU  = Megabytes backed up.
MBWT  = Megabytes written to tape.
Comp% = % size of data after compression. 
Time  = Time used for backup.
KB/S  = Kilobytes Per Second.
MB/M  = Megabytes Per Minute.


======================================================================
                      SUMMARY OF BACKUP FROM klaus
----------------------------------------------------------------------
Hostname      MbBU   MbWT Comp%   Time KB/S   MB/M     Date

snapp          256    102   40%   0:27  162   9.50     Fri Nov 20
klara          202     91   45%   0:23  150   8.77     Fri Nov 20
guffen         188     79   42%   0:21  153   8.94     Fri Nov 20
anton          121     62   51%   0:14  147   8.62     Fri Nov 20
skrue           19     11   55%   0:06   55   3.24     Fri Nov 20
pluto           24     12   52%   0:04  101   5.89     Fri Nov 20
storeulv       151     63   42%   0:28   92   5.40     Fri Nov 20
lilleulv       153     80   52%   0:16  164   9.59     Fri Nov 20
klaus           38     19   51%   0:04  161   9.43     Fri Nov 20
doffen          40     20   50%   0:04  171  10.01     Fri Nov 20
dole            44     22   51%   0:05  149   8.73     Fri Nov 20
bingen         436    226   52%   0:35  213  12.46     Fri Nov 20
----------------------------------------------------------------------
TOTAL/AVG     1671    787   47%   3:07  153   8.94
======================================================================


======================================================================
                      SUMMARY OF BACKUP FROM chuck
----------------------------------------------------------------------
Hostname      MbBU   MbWT Comp%   Time KB/S   MB/M     Date

chuck          307    113   37%   0:26  201  11.80     Fri Nov 20
steve          701    296   42%   2:06   95   5.56     Fri Nov 20
----------------------------------------------------------------------
TOTAL/AVG     1008    409   41%   2:32  113   6.63
======================================================================


======================================================================
                    SUMMARY OF BACKUP FROM sleipner
----------------------------------------------------------------------
Hostname      MbBU   MbWT Comp%   Time KB/S   MB/M     Date

sleipner       681    193   28%   0:39  298  17.46     Fri Nov 20
draugen        125     57   46%   0:29   73   4.30     Fri Nov 20
oseberg        153     39   26%   0:13  201  11.79     Fri Nov 20
brage          498    114   23%   0:44  193  11.32     Fri Nov 20
----------------------------------------------------------------------
TOTAL/AVG     1457    403   28%   2:05  199  11.65
======================================================================


======================================================================
                      SUMMARY OF BACKUP FROM volt
----------------------------------------------------------------------
Hostname      MbBU   MbWT Comp%   Time KB/S   MB/M     Date

volt          1551    850   55%   1:48  245  14.36     Fri Nov 20
chris          291     87   30%   0:33  151   8.82     Fri Nov 20
thomas         619    251   41%   0:53  199  11.69     Fri Nov 20
uran            91     36   40%   0:07  222  12.98     Fri Nov 20
----------------------------------------------------------------------
TOTAL/AVG     2553   1224   48%   3:21  217  12.70
======================================================================

======================================================================
                      TOTAL/AVG OF ALL BACKUPS
  MbBU   MbWT Comp%   Time KB/S   MB/M

  6688   2824   42%  11:05  172  10.06
======================================================================

--- chew here ---


# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Eskil Brun <eskilb@chuck> on Fri Nov 20 10:05:38 1992
#
# This archive contains:
#	backup	
#

LANG=""; export LANG
PATH=/bin:/usr/bin:$PATH; export PATH

echo mkdir - backup
mkdir backup

echo x - backup/backup.sh
cat >backup/backup.sh <<'@EOF'
#/bin/sh
# Backup script...

# Dirs to backup
dirs="
	./etc
	./usr/spool/lp
	./prj
	./users
	./u[0-9]*
	./disks
	./usr/contrib"

echo Backing up $dirs >&2

#Find files and archive them.
cd /
find `echo $dirs` -fsonly hfs -print |cpio -Bo








@EOF

chmod 755 backup/backup.sh

echo x - backup/catindex.sh
cat >backup/catindex.sh <<'@EOF'
#!/bin/sh


#######################################################################
# IFE DDS Tape backup...
# 	getindex script
#
# Author: Eskil Brun
#
#	wind to end of tape and backspace to read index file
#	cat it to STDOUT
#
#######################################################################


##################################################
# Make sure Search Path is correct.
PATH="/bin:/usr/bin:/etc"
export PATH




##################################################
# Assumptions...

TAPE=/dev/bdds				# Must be raw, Berkeley, no rewind style DDS.


##################################################
# Functions.....


####################
# eod winds to the end of tape

eod()
{
	if [ `uname` = 'HP-UX' ]
	then
		OSVER=` uname -r |sed -e "s/[.A-Za-z]//g" -e "s/^0//" -e "s/00*$//"`
		
		case $OSVER in
			7*)
				true		# Reset $?
				while [ $? = 0 ]
				do
					mt -t $TAPE fsf 1 >/dev/null 2>&1
				done
				;;
			
			8*)
				mt -t $TAPE eod
				;;

			*)
				echo $0 : Error\! eod\(\) must be rewritten for `uname` `uname -r`.
				exit 0
				;;
		esac

	else
	
		echo $0 : Error\! eod\(\) must be rewritten for `uname` `uname -r`.
		exit 0
	fi
}

####################
# Clean up function...

do_cleanup()
{
	echo Cleaning Lady is here... Hum-tidum...
}


####################
# Stop on error function...
stop_on_error()
{
	if [ $? != 0 ]
	then
		echo Woops. An error occured while $*
		do_cleanup
		exit 2
	fi
}



cat_index_file()
{
	# Rewind Tape
	mt -t $TAPE rew	>/dev/null 2>&1

	eod
	
	# Now, Position tape at index file
	mt -t $TAPE bsf 3	|| stop_on_error Backspacing 3 filemarks to INDEX-file.
	mt -t $TAPE fsf 1	|| stop_on_error Forward Spacing to INDEX-file
	cat $TAPE		|| stop_on_error Writing INDEX file STDOUT from tape.
}



##################################################
# Main part 


cat_index_file
@EOF

chmod 775 backup/catindex.sh

echo x - backup/master.sh
cat >backup/master.sh <<'@EOF'
#!/bin/sh


#######################################################################
# IFE DDS Tape backup...
# 	Master script
#
# Author: Eskil Brun
#
# 	The $BACKUPMASTER starts a remote shell script on the
#	$NODE, running backup. The script run on the $NODE is assumed
#	to write backup data to STDOUT and messages to STDERR
#
#	The $BACKUPMASTER writes an INDEX at the end of the tape
#	to know which hosts have backups in which position.
#
#######################################################################


##################################################
# Make sure Search Path is correct.
PATH="/bin:/usr/bin:/etc"
export PATH

trap "echo Caught a TERM\(15\) signal. I\'m dying.; exit 1" 15


##################################################
# Assumptions...

TAPE=/dev/bdds					# Must be raw, Berkeley, no rewind style DDS.
CHUNKSIZE=60k					# Tape Block size for dd(1)
INDEXFILE=/users/root/backup/tape-index		# INDEX file name.
LOGFILE=/users/root/backup/backup-log		# Backup log output file.
SCRIPTSDIR=/users/root/backup			# Where we keep backup scripts...
COMPRESS="no"					# Whether we should compress data

##################################################
# List of computers to take backup...

# Master backup computers...
MASTERS="chuck sleipner volt"

# Computers to take backup on chuck's tape
chuck_NODES="chuck steve"
chuck_COMPRESS="yes"

# Computers to take backup on sleipner's tape
sleipner_NODES="sleipner draugen oseberg brage"
sleipner_COMPRESS="yes"

# Computers to take backup on volt's tape
volt_NODES="volt chris thomas uran"
volt_COMPRESS="yes"

##################################################
# Functions.....


####################
# Clean up function...

do_cleanup()
{
	echo Doing Cleanup \(Nothing, Really\).
	echo Right now, I think it\'s smart to quit\!
	kill -TERM $$
}


####################
# Stop on error function...
stop_on_error()
{
	if [ $? != 0 ]
	then
		echo Woops. An error occured while $*
		do_cleanup
	fi
}


####################
# rewind tape function

rewind_tape()
{
	echo Rewinding Tape...
	mt -t $TAPE rew 	|| stop_on_error Rewinding Tape.
}


output_to_tape()
{
	echo Writing DATA to tape >&2
	# write compressed / uncompressed ??
	if [ $COMPRESS = yes ]
	then
		compress | dd ibs=10k obs=$CHUNKSIZE of=$TAPE || stop_on_error Writing compressed DATA to tape
		echo Wrote compressed DATA to tape
	else
		dd ibs=10k obs=$CHUNKSIZE of=$TAPE || stop_on_error Writing uncompressed DATA to tape
		echo Wrote uncompressed DATA to tape
	fi
}


####################
# eject tape function

eject_tape()
{
	echo Ejecting Tape
	mt -t $TAPE offl || stop_on_error Rewinding and Ejecting Tape.
}



####################
# bsdping emulates the bsd version of ping
# usage: bsdping "host"
# if "host" does not exist, bsdping return true!!
# This is not really a serious bug for this script's use

bsdping()
{
	if [ `uname` = 'HP-UX' ]
	then
		OSVER=` uname -r |sed -e "s/[.A-Za-z]//g" -e "s/^0//" -e "s/00*$//"`

		case $OSVER in
			7*)

				if [ $# -eq 0 ] ;then
					return 2
				else
					RES=`ping $1 -n1 |grep -c '0 packets received'`
				return $RES
				fi
				;;

			8*)
				if [ $# -eq 0 ] ;then
					return 2
				else
					RES=`ping $1 64 1 |grep -c '0 packets received'`
					return $RES
				fi
				;;

			*)
				echo $0 : Error\! bsdping\(\) must be rewritten for `uname` `uname -r`.
				exit 0
				;;
		esac

	else

		echo $0 : Error\! bsdping\(\) must be rewritten for `uname` `uname -r`.
		exit 0
	fi
}

# Test bsdping
bsdping localhost



##################################################
# Main part


# age LOGFILE. Be silent about it.
mv $LOGFILE.4 $LOGFILE.5 >/dev/null 2>&1
mv $LOGFILE.3 $LOGFILE.4 >/dev/null 2>&1
mv $LOGFILE.2 $LOGFILE.3 >/dev/null 2>&1
mv $LOGFILE.1 $LOGFILE.2 >/dev/null 2>&1
mv $LOGFILE   $LOGFILE.1 >/dev/null 2>&1


# Redirect stdout and stderr to logfile
exec >$LOGFILE 2>&1


trap HUP



# Check if We are a master computer...

MYNAME=`hostname |sed -e "s/\\..*//"`			# get hostname without domain
for MASTER in $MASTERS
do
	[ $MYNAME = $MASTER ] && BACKUPMASTER=$MYNAME
done

# If not, Nothing to do.

if [ "$BACKUPMASTER" = "" ]
then
	echo This Computer is not a BACKUPMASTER
	echo Nothing to do...
	exit 0
fi

# Otherwise, Do backup...


echo Master Backup Script started at `date`


# assure bsdping can be used with this script...
echo Checking bsdping\(\)
bsdping localhost

echo Removing INDEX file.
rm -f $INDEXFILE

echo Creating New INDEX file.
cat /dev/null >$INDEXFILE

echo Getting node names to run backup from.

BACKUP_NODES=`eval echo '$'${BACKUPMASTER}_NODES`

if [ "$BACKUP_NODES" = "" ]
then
	echo No nodes to take backup from.
	echo Nothing to do.
	exit 0
else
	echo $BACKUPMASTER takes backup of $BACKUP_NODES
fi


COMPRESS=`eval echo '$'${BACKUPMASTER}_COMPRESS`


if [ $COMPRESS = yes ]
then
	echo $BACKUPMASTER will compress data before writing to tape
	COMP="COMPRESSED"
else
	echo $BACKUPMASTER will not compress data before writing to tape
	COMP="UNCOMPRESSED"
fi


# Initialize backup tape
rewind_tape


# Initialise POSITION Variable
POSITION=2


# Timestamp Tape
echo Timestamping tape.
echo 0:Backup_Timestamp >>$INDEXFILE
echo "Backup Timestamp: "`date` >$TAPE

# Mark tape COMPRESSED/UNCOMRESSED
echo Marking Tape
echo 1:Compression_Mark >>$INDEXFILE
echo $COMP >$TAPE


for NODE in $BACKUP_NODES
do
	echo ------------------------------------------------------------

	if bsdping $NODE
	then
		if [ $BACKUPMASTER = $NODE ]
		then
			echo Running shell for Computer $NODE Backup at `date`
			$SCRIPTSDIR/backup.sh |output_to_tape
		else
			echo Running remote shell for Computer $NODE Backup at `date`
			remsh $NODE -n $SCRIPTSDIR/backup.sh |output_to_tape
		fi
		echo Updating INDEX file with \"$POSITION\:$NODE\"
		echo $POSITION\:$NODE >>$INDEXFILE
		POSITION=`expr $POSITION + 1`
		echo Done writing Backup for Computer $NODE at `date`
	else
		date
		echo Computer $NODE is unreachable. No backup attempted.
	fi
done
echo ------------------------------------------------------------

echo Writing Logfile to tape... \(no more log on tape after this\).
cat $LOGFILE >$TAPE
echo $POSITION\:Backup_logfile >>$INDEXFILE
POSITION=`expr $POSITION + 1`


echo Writing Index file to tape.
echo $POSITION\:Backup_index >>$INDEXFILE
cat $INDEXFILE >$TAPE

echo Removing Index file.
rm -f $INDEXFILE || stop_on_error Removing Index file


rewind_tape || stop_on_error Rewinding Tape

eject_tape || stop_on_error Ejecting Tape

echo Master Backup Script stopped at `date`

@EOF

chmod 755 backup/master.sh

echo x - backup/restore.sh
cat >backup/restore.sh <<'@EOF'
#!/bin/sh



##################################################
# Make sure Search Path is correct.
PATH="/bin:/usr/bin:/etc"
export PATH


##################################################
# Trap errors...
trap "echo Caught a TERM\(15\) signal. I\'m dying.; exit 1" 15



##################################################
# Assumptions...
TAPE=/dev/bdds
CHUNKSIZE=60k
INDEXFILE=/tmp/restore.sh.index.$$
COMPRESS="no"

##################################################
# Functions.....


####################
# Clean up function...

do_cleanup()
{
	echo Removing Temporary files...
	#rm -f /tmp/restore.sh.*.$$ 
}


####################
# Stop on error function...
stop_on_error()
{
	echo Woops. An error occured while $*
	echo Sending my self a TERM signal.
	kill -TERM $$
}

####################
# eod winds to the end of tape

eod()
{
	if [ `uname` = 'HP-UX' ]
	then
		OSVER=` uname -r |sed -e "s/[.A-Za-z]//g" -e "s/^0//" -e "s/00*$//"`
		
		case $OSVER in
			7*)
				true		# Reset $?
				while [ $? = 0 ]
				do
					mt -t $TAPE fsf 1 >/dev/null 2>&1
				done
				;;
			
			8*)
				mt -t $TAPE eod
				;;

			*)
				echo $0 : Error\! eod\(\) must be rewritten for `uname` `uname -r`.
				exit 0
				;;
		esac

	else
	
		echo $0 : Error\! eod\(\) must be rewritten for `uname` `uname -r`.
		exit 0
	fi
}


cat_index_file()
{

	# Wind to end of tape.
	
	eod
	
	# Now, Position tape at index file
	mt -t $TAPE bsf 3	|| stop_on_error Backspacing 3 filemarks to INDEX-file.
	mt -t $TAPE fsf 1	|| stop_on_error Forward Spacing to INDEX-file
	cat $TAPE		|| stop_on_error Writing INDEX file STDOUT from tape.
}



# Main part of script...

##################################################
# check parameters...

if [ $# -lt 2 ]
then
	echo "usage: $0 <host> <file> [file] [file] ..."
	exit 1
fi


# Trap interrupts etc...
trap "do_cleanup" 0
trap "do_cleanup; kill -TERM $$" 2 3 


# Get hostname without domain (if any)
HOST="`echo $1 |sed -e \"s/\..*//\"`"
shift

# Make sure shell does not glob filename arguments...

FILES=\'$*\'
FILES="`echo $FILES |sed -e \"s/[ 	][ 	]*/' '/g\"`"

# Remove / in front of filenames...
FILES="`echo $FILES |sed -e \"s,'/,',g\"`"


echo FILES=$FILES

# Check if host is available... (strip domain when hostname returned from host)
if [ "`remsh $HOST hostname |sed -e \"s/\..*//\"`" != "$HOST" ]
then
	echo Cannot contact $HOST via network.
	echo Restore cannot complete.
	stop_on_error Trying to reach computer $HOST via network.
fi


# Rewind Tape.

mt -t $TAPE rew || stop_on_error rewinding tape.


# Get timestamp from tape
echo Getting Timestamp from tape.
TIMESTAMP="`cat $TAPE`" || stop_on_error Reading timestamp from tape.

echo TIMESTAMP=$TIMESTAMP

# Get compression mark from tape
echo Getting Compression Mark from tape.
COMPRESS="`cat $TAPE`" || stop_on_error Reading compression mark from tape.

echo COMPRESS=$COMPRESS

# Get index from tape.
echo Getting Index from tape.
cat_index_file >$INDEXFILE || stop_on_error Reading compression mark from tape.

echo ------------ index ---------
cat $INDEXFILE
echo ----------------------------

# Search index for $HOST
echo Searching index for $HOST
if [ "`egrep '^[0-9][0-9]*:'$HOST'$' $INDEXFILE |cut -d: -f2`" != $HOST ]
then
	echo Computer $HOST has no filess on this backup tape.
	stop_on_error Searching indexfile for computer $HOST
fi


# Position to correct fileset
echo Getting Position for correct fileset.
POSITION="`egrep '^[0-9][0-9]*:'$HOST'$' $INDEXFILE |cut -d: -f1`"
[ -z "$POSITION" ] && stop_on_error Could not determine position of $HOST in index.
echo ${HOST}\'s backup is located on fileset $POSITION

# rewind Tape 
echo Rewinding Tape.
mt -t $TAPE rew || stop_on_error Rewinding Tape

echo Winding to Fileset no $POSITION
mt -t $TAPE fsf $POSITION || stop_on_error Positioning tape to fileset $POSITION



# Restore file(s)

echo Restoring Files...


#
# I had to include the 'cat | cpio' instead of plain cpio.
# when using plain cpio, cpio would go out of sync.
# i think this has to do with how remsh handles the pipe to cpio
# Eskil...


if [ "$COMPRESS" = "COMPRESSED" ]
then
	dd if=$TAPE ibs=$CHUNKSIZE obs=10k |uncompress |remsh $HOST "cd /;" 'cat | cpio' -RBivdumx $FILES
	# for debugging
	# dd if=$TAPE ibs=$CHUNKSIZE obs=10k |uncompress |remsh $HOST "cd /;" 'cat | cpio' -RBivt $FILES


elif [ "$COMPRESS" = "UNCOMPRESSED" ]
then

	dd if=$TAPE ibs=$CHUNKSIZE obs=10k |remsh $HOST "cd /;" 'cat |cpio' -RBivdumx $FILES
	# for debugging
	# dd if=$TAPE ibs=$CHUNKSIZE obs=10k |remsh $HOST "cd /;" 'cat |cpio' -RBivt $FILES
else
	echo Could not resolve wheter tape is compressed or not.
	echo No files restored...
	do_cleanup
fi




@EOF

chmod 755 backup/restore.sh

echo x - backup/backup-stats.pl
sed 's/^@//' >backup/backup-stats.pl <<'@EOF'
#!/usr/local/gnu/bin/perl 


@@BACKUPMASTERS=(klaus,chuck,sleipner,volt);


$BACKUPFILE="/users/root/backup/backup-log";

if ( $ARGV[0] =~ /^[0-9]$/ )
{
   $BACKUPFILE="$BACKUPFILE\.$ARGV[0]";
   
}

print "Summary of $BACKUPFILE on @BACKUPMASTERS\n\n";

format HEADER =

======================================================================
@@||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$HEADER
----------------------------------------------------------------------
Hostname      MbBU   MbWT Comp%   Time KB/S   MB/M     Date

@.

format LINE =
@@<<<<<<<<<< @##### @##### @###% @>>>>> @### @##.##     @<<<<<<<<<<<
$HOST,      $MB,   $MBOUT,$COMPRESSION, $TIME, $KBPS, $MBPM, $DATE
@.

format TOTAL =
----------------------------------------------------------------------
TOTAL/AVG   @##### @##### @###% @>>>>> @### @##.## 
            $TOTALMB, $TOTALMBOUT, $TOTALCOMPRESSION,$TOTALTIME,$TOTALKBPS, $TOTALMBPM
======================================================================

@.

format SUM =
======================================================================
                      TOTAL/AVG OF ALL BACKUPS
  MbBU   MbWT Comp%   Time KB/S   MB/M

@@##### @##### @###% @>>>>> @### @##.##
$SUMMB, $SUMMBOUT, $SUMCOMPRESSION, $SUMTIME, $SUMKBPS, $SUMMBPM
======================================================================
@.



sub tominutes
{
	local($ARG) = @_;
	local($HOURS,$MINUTES) = split(':',$ARG);
	return ( $HOURS * 60 ) + $MINUTES;
}






# Main.

print "\
MbBU  = Megabytes backed up.\
MBWT  = Megabytes written to tape.\
Comp% = % size of data after compression. \
Time  = Time used for backup.\
KB/S  = Kilobytes Per Second.\
MB/M  = Megabytes Per Minute.\
\
";









foreach $MASTER (@BACKUPMASTERS) 
{
	open(MASTERFILE,"remsh $MASTER /bin/cat $BACKUPFILE|");

	$~ = HEADER;
	$HEADER ="SUMMARY OF BACKUP FROM $MASTER";
	write;
	
	$TOTALKB = $TOTALKBOUT = $TOTALMINUTES = $TOTALCOMPRESSION = $TOTALKBPS = $TOTALMBPM = 0;





















	while (<MASTERFILE>)
	{
         
		/^Backing up (.*)$/ && ($DIRS=$1);
		/^([0-9]+) blocks$/ && ($BLOCKS=$1);
		if (/^Running .*((Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s[0-9]+)\s([0-9]+:[0-9]+:)/)
	    	{
			$DATE=$1;
			$STARTTIME=&tominutes($4);
		}
		
		/^([0-9+]+) (records|blocks) out$/ && ($BLOCKSOUT=$1);
		/^Updating INDEX file with "[0-9]+:([0-9a-zA-Z]+)"$/ && ($HOST=$1);
		if (/^Done .*([0-9]+:[0-9]+:)/)
		{
			$ENDTIME=&tominutes($1);
			$MINUTES=$ENDTIME-$STARTTIME;
			$TOTALMINUTES += $MINUTES;
			$SUMMINUTES += $MINUTES;
			$TIME=sprintf("%d:%2.2d",($MINUTES / 60),($MINUTES % 60));
			eval("\$BLOCKS=$BLOCKS");
			eval("\$BLOCKSOUT=$BLOCKSOUT");
			$KB=$BLOCKS/2;
			$KBOUT=$BLOCKSOUT*60;
			$TOTALKB += $KB;
			$TOTALKBOUT += $KBOUT;
			$SUMKB += $KB;
			if ($MINUTES > 0)
		    	{
				$KBPS=($KB / ($MINUTES * 60));
				$MBPM=(($KB/1024) / $MINUTES);
			}
			else
			{
				$KBPS = 0;
				$MBPM = 0;
			}
			

			$MB=$KB/1024;
			
			$MBOUT=$KBOUT/1024;
		
			if ($KB > 0)
			{
				$COMPRESSION=($KBOUT/$KB)*100;
			}
			else
			{
				$COMPRESSION=0;
			}
			
			$~ = LINE;
			write;
			$BLOCKS=0;
			$BLOCKSOUT=0;
			$DIRS="";
			$HOST="";
		}	
	}
	
	$TOTALTIME=sprintf("%d:%2.2d",($TOTALMINUTES / 60),($TOTALMINUTES % 60));
	$TOTALMB=$TOTALKB/1024;
	$TOTALMBOUT=$TOTALKBOUT/1024;
	if ($TOTALKB > 0)
	{
		$TOTALCOMPRESSION=($TOTALKBOUT/$TOTALKB)*100;
	}

	if ($TOTALMINUTES > 0)
	{
		$TOTALKBPS = ($TOTALKB / ( $TOTALMINUTES * 60));
		$TOTALMBPM = (($TOTALKB / 1024) / $TOTALMINUTES);
	}
	
	close(BACKUPFILE);
	$~ = TOTAL; write;

	$SUMMB += $TOTALMB;
	$SUMMBOUT += $TOTALMBOUT;
}




if ($SUMMB > 0)
{
	$SUMCOMPRESSION = ($SUMMBOUT/$SUMMB)*100;
}

if ($SUMMINUTES > 0)
{
	$SUMKBPS = ($SUMKB / ( $SUMMINUTES * 60));
	$SUMMBPM = (($SUMKB / 1024) / $SUMMINUTES);
}


$SUMTIME=sprintf("%d:%2.2d",($SUMMINUTES / 60),($SUMMINUTES % 60));


$~ = SUM;
write;
@EOF

chmod 775 backup/backup-stats.pl

chmod 777 backup

exit 0
Newsgroups: comp.sys.hp