:
#	@(#) cbackup.sh 1.2 89/07/20 
#
#	Copyright (C) The Santa Cruz Operation, 1989.
#	This Module contains Proprietary Information of
#	The Santa Cruz Operation, and should be treated as Confidential.
#
#	cbackup	
#
#	Incremental filesystem backup using cpio; designed for use with 
#	fsphoto and fsave
#
#	Usage: $0 level len device [density] filesystem
#
#	Dependencies:	/usr/lib/sysadmin/cstamps	(will make on demand)

: ${OK=0} ${FAIL=1} ${USAGE=2} ${POSTPONED=3}
PATH=/bin:/usr/bin:/etc

STAMPROOT=/usr/lib/sysadmin/cstamps
CPIO=cpio
CPIOFLAGS="-o -C 10240"
MESSAGE="Insert volume %d and press <RETURN> to continue or 'q' to exit."
COMMAND=`basename $0`

#error message on stderr
error(){
	echo "$COMMAND: $*" 1>&2
}

#usage message on stderr
usage(){
	 echo "Usage: $0 level len device [density] filesystem" 1>&2
}

#For traps
interrupt(){
	echo "Backup interrupted!" 2>&1
	rm -f /tmp/CPIO$$ 
	exit "$POSTPONED"
}

#calculate "-newer filename" arg for find
setdate(){
	STAMPDIR=${STAMPROOT}${FILSYS}
	if [ "$LEVEL" -gt 0 -a -d "$STAMPDIR" ] 
	then
		HISTORY=`ls -t $STAMPDIR`
		[ "$HISTORY" ] && {
			for FILE in $HISTORY
			do
				if [ "$FILE" -lt "$LEVEL" ]
				then
					STAMP=$STAMPDIR/$FILE
					LASTLEVEL=$FILE
					break
				fi
			done
		}
	fi
	[ -f "$STAMP" ] && {
		LASTBACKUP="Level $LASTLEVEL on `cat $STAMP`"
		NEWER="-newer $STAMP"
	}
}

#Locate all files to be backed up
search(){
	echo "Generating a list of pathnames for backing up . . .\c"
	cd $1
	#don't leave the current filesystem
	find . -mount $2 -print > /tmp/CPIO$$	
	echo
}

#invoke cpio for the backup
docpio() {
	cat /tmp/CPIO$$   | cpio $CPIOFLAGS -M"$MESSAGE" -O $DEVICE -K$LEN
}


# make a complete pathname, e.g. may require several mkdir's
# assumes last component is to be a directory
mkpath(){
	PATHNAME=$1
	BASE=
	while [ "$PATHNAME" ]
	do
		[ -d "$PATHNAME" ] && break
		[ "$PATHNAME" = "." -o "$PATHNAME" = "/" ] && break
		BASE="`basename $PATHNAME` $BASE"
		PATHNAME=`dirname $PATHNAME`
	done
	for DIR in $BASE
	do
		PATHNAME="$PATHNAME/$DIR"
		mkdir $PATHNAME
	done
}

#Make a time stamp for this backup
#Use the complete filesystem pathname for a stamp in case different device
#files have differing prefixes but the same filename component. 
record(){
	[ -d "$STAMPROOT" ] || {
		mkdir "$STAMPROOT" 2> /dev/null  || {
			error "Cannot make $STAMPROOT"
			exit $FAIL
		}
	}
	[ -d "$STAMDIR" ] || {
		mkpath "$STAMPDIR" 2> /dev/null  || {
			error "Cannot make $STAMPDIR"
			exit $FAIL
		}
	}
	set `date`
	echo $3 $2 $6 > ${STAMPDIR}/$LEVEL
}


#set and test command line arguments
checkargs(){
	LEVEL=$1
	LEN=$2
	DEVICE=$3
	case $# in
	4)	FILSYS=$4
		;;
	5)	DENSITY=$4
		FILSYS=$5
		;;
	*)	usage	
		exit $USAGE
		;;
	esac
	[ -c "$DEVICE" ] || { 
		error "Not a magtape or floppy drive: $DEVICE"
		#exit $USAGE
	}
	#need the block device file to check against mount
	[ -c "$FILSYS" ] && {
		BASE=`basename $FILSYS`
		BASE=`expr "$BASE" : '.\(.*\)'`
		FILSYS=`dirname $FILSYS`/$BASE
	}
	[ -b "$FILSYS" ] || {
		error "Not a filesystem: $FILSYS"
		exit $USAGE
	}
	#The following differs between 3.2 UNIX and XENIX 
	#/etc/mount returns information in differing formats
	#UNIX 3.2
	set not- `/etc/mount | grep "on[ 	][ 	]*$FILSYS"`
	#XENIX
	#set not- `/etc/mount | grep "^$FILSYS"`
	if [ $# -lt 2  ]
	then
		error "\"$FILSYS\" must be mounted for backup with cpio"
		exit $FAIL
	else
		#UNIX 3.2
		DIR=$2
		#XENIX
		#DIR=$4
	fi
}


#Main
checkargs "$@"

#Determine most reccent backup at a lesser level 
setdate

trap "interrupt" 1 2 3 15

echo "\nLevel $LEVEL backup of filesystem: $FILSYS"
if [ $LEVEL -gt 0 -a -n "$NEWER" ]
then
	echo "Backing up all files modified since:\n\t${LASTBACKUP}\n"
else
	echo "Backing up all files\n"
fi

#Generate list of files for backup
search $DIR "$NEWER" 

#perform backup
docpio
RC=$?
rm -f /tmp/CPIO$$ 

#Leave a record of this backup
if [ "$RC" -eq 0 ] 
then
	record
else
	error "Backup NOT recorded"
fi
case "$RC" in
0)	exit $OK
	;;
4)	exit $POSTPONED
	;;
*)	exit $FAIL
	;;
esac
