:
#	@(#) fsphoto.sh 1.3 89/04/12 
#
#	Copyright (C) The Santa Cruz Operation, 1988, 1989
#	This Module contains Proprietary Information of
#	The Santa Cruz Operation, and should be treated as Confidential.
#
# 	fsphoto		Semi automatic scheduled backups
#
#	Dependencies:		/usr/lib/sysadmin/fsave
#				/usr/lib/sysadmin/schedule
#				/usr/lib/sysadmin/last/fs_name(s)
#

: ${OK=0} ${FAIL=1} ${INTERRUPT=2}

LIBSYS=/usr/lib/sysadmin
PATH=/bin:/usr/bin:$LIBSYS
LOGDIR=$LIBSYS/last
SERIES=$LIBSYS/schedule
PAST=$LOGDIR/past
PRESENT=/tmp/backup$$

script=${0-fsphoto}

DUMP0='-	"1 year"	critical	none'
DUMP1='-	"4 months"	necessary	none'
DUMP2='-	"1 month"	important	none'
DUMP3=$DUMP2
DUMP4=$DUMP2
DUMP5=$DUMP2
DUMP6=$DUMP2
DUMP7=$DUMP2
DUMP8='-	"3 weeks"	useful		none'
DUMP9='-	"1 week"	precautionary	none'

date >$PRESENT

# Set up default variable values
setdefault() {
	IGNORE=no
	RESUME=no
	PARTIAL=no
	LINENO=0
	STATUS=
}

# Print an error message
error() {
	echo "\nError: $*" >&2
	return $FAIL
}

# Clean up depending on value passed in as argument (OK,FAIL or INTERRUPT)
cleanup() {
	STATUS="$1"
	case "$STATUS" in
	$OK)	# Everything worked out
			;;
	$FAIL) 	# Backups failed!
			;;
	$INTERRUPT) 	# User quit during backups
		cat $PRESENT >>$PAST
		echo "Backups interrupted, to be resumed later ..."
			;;
	esac
	rm -f $PRESENT 2> /dev/null
	exit $STATUS
}

# Process arguments
checkargs() {
	for ARG in "$@"
	do  case $ARG in
		-i)	IGNORE=yes
			;;
		*)	TAPE=$ARG
			;;
		esac
	done

	[ -s $SERIES ] || {
		error "Missing or empty backup schedule: $SERIES"
		return $FAIL
	}
}

# Read the schedule file one line at a time, and get the media info
# and the filesystem info. Then, for each filesystem,
# see if it needs a backup today, if so, at what level.
#
readseries() {
      while read FILSYS PROGRESSION; do
	LINENO=`expr $LINENO + 1`
	case "$FILSYS" in
		\#*|"")	continue
			;;

		/dev/*)	: Found a filesystem
			;;

		media)	set not- $PROGRESSION	; shift
				TAPE="$1"	; shift
				MEDIA="$*"
			continue
			;;

		[0-9])	LEVEL="$FILSYS"
			eval set not- "$PROGRESSION"	; shift
			case $# in
			4)	: Ok
				;;
			*)	error "$script: Bad description, \
				$SERIES line $LINENO: $PROGRESSION"
				return $FAIL
				;;
			esac
			eval DUMP$LEVEL='"$PROGRESSION"'
			continue
			;;
	
		site)	SITE="$PROGRESSION"
			continue
			;;

		*)	error "$script: Strange entry in $SERIES, \
				line $LINENO: $FILSYS"
			return $FAIL
			;;

		esac

	# Set a trap so if the user deletes out or the program
	# is otherwise halted, we can resume backups where we 
	# left them
	trap "cleanup $INTERRUPT" 1 2 3 15

	if test -r $PAST; then
		case $RESUME.$IGNORE in
		no.no)	echo "Previous backup not finished, resuming ..."
			RESUME=yes
			;;
		no.yes)	echo "CAUTION -- Ignoring previous unfinished backup."
			rm -f $PAST
			;;
		esac

		case $IGNORE in
		no)	if grep "^$FILSYS$" $PAST >/dev/null 2>&1; then
				continue
			fi
			;;
		esac
	fi

	LOGFILE=$LOGDIR/`basename $FILSYS`
	if test ! -s "$LOGFILE"; then
		CYCLE=1
	else
		CYCLE=`cat $LOGFILE`
		if test "$CYCLE" -le 0; then
			error "$script: Non-numeric or out of range \
$FILSYS cycle: $LOGFILE"
			return $FAIL
		fi
		CYCLE=`expr $CYCLE + 1`
	fi

	#peel method from end of progression string and reset progression
	set not- $PROGRESSION
	shift
	PROGRESSION=
	while :	
	do
		[ $# -eq 1 ] && break
		PROGRESSION="$PROGRESSION $1"
		shift
	done
	METHOD=$1
	case "$METHOD" in
	cpio|xbackup) : OK
		;;
	[0-9xX])	#assume last field is part of schedule; use cpio
			PROGRESSION="$PROGRESSION $METHOD"
			METHOD=cpio
			;;
	*)	error "$script: Unknown or missing backup method \
				$FILSYS method: $METHOD"
		return $FAIL
		;;
	esac

	while : ; do
		LEVEL=`echo $PROGRESSION | awk "{print \\$$CYCLE}"`
		case "$LEVEL" in
		[0-9xX])	break
			;;
		"")	case $CYCLE in
			1)	error "$script: Empty progression for $FILSYS"
				return $FAIL
				;;
			*)	# Period less than $CYCLE, so start over
				CYCLE=1
				;;
			esac
			;;
		*)	error "$script: Illegal backup level, \
				$SERIES line $LINENO: $LEVEL"
			return $FAIL
			;;
		esac
	done

	eval INFO=\$DUMP$LEVEL
	fsave $FILSYS "$LEVEL $INFO" "$TAPE $MEDIA" "$SITE"  "$METHOD" </dev/tty
	case $? in
	0)	echo $CYCLE >$LOGFILE
		echo $FILSYS >>$PRESENT
		;;
	*)	PARTIAL=yes
		;;
	esac
    done

	case $PARTIAL.$RESUME in
	yes.*)	cleanup $INTERRUPT
		;;
	no.yes)	echo "The previous backup was resumed and is now complete."
		rm -f $PAST $PRESENT
		cleanup $OK	
		;;
	no.no)	echo "Today's backups are finished.\n"
		cleanup $OK
		;;
	esac

} 

# main

checkargs "$@" || cleanup $FAIL
setdefault
readseries < $SERIES || cleanup $FAIL
cleanup $OK
