#!/bin/sh
#
#	TapeBackup script using the dialog interface
#
#	$Id: kbackup,v 1.1 1995/08/11 20:59:31 root Exp root $
#	(C) 1995 Karsten Ballder (karsten.ballder@stud.uni-karlsruhe.de)
#
#

#
#	set default values for Variables
#

SED=sed
AWK=awk
FGREP=fgrep
GREP=grep
MAIL=mail

VERSION=`echo $Revision: 1.1 $ | $SED '1,$ s/\$R[a-z]+: \([0-9]+\.[0-9]r+\) \$/\1/g' | $AWK '/.*/ { print $2 }'`

MAILADDRESS="karsten.ballueder@stud.uni-karlsruhe.de"


FILESPERARCHIVE=3	# compression method, cont-dir, archive

KBACKDIRDEFAULT=.KBackup
KBACKRCDEFAULT=.kbackrc


kbackdir=$HOME/$KBACKDIRDEFAULT
parent=/
local=NO
incremental=NO
specifiedfilesonly=NO
datestamp=`date`
directoriesonly=YES
findxpertmode=NO
findxpertflags=-print
compression=GZIP		#valid: GZIP, PGP, NONE, COMPRESS
compress_options=-1
archive_format=TAR		#valid: TAR (future: AFIO)
multivolume=NO
verify_archive=YES
tapelength=250
pgpkey=root
configname=Default
ddbufsize=4096k
double_buffering=YES
device=/dev/tape
resetdevice=/dev/tape-reset
device_is_floppy=NO
floppy_format="1722/1440"
manualedit=NO
followtarops=YES
scheduled=NO
schedulename=.---schedule---
scheduletime="???"
oldconfigname=$configname
scheduled_only_once=YES

TMP=/tmp

TMPFILE=.tmp$$
TMPFILE2=.tmpB$$
BINDIR=.fakegzip$$
COMPRESSFILE=.compress$$
DIALOGFILE=.dialog$$
DIRLISTFILE=.dirlist$$
TARLOGFILE=.tarlog$$
TARLISTFILE=.tarlist$$
PIPEFILE=.pipe$$
MSGFILE=.info$$

TMPFILES="$TMP/$TMPFILE $TMP/$DIRLISTFILE $TMP/$DIALOGFILE \
	$TMP/$TARLOGFILE $TMP/$TARLISTFILE $TMP/$MSGFILE $TMP/$PIPEFILE\
	$TMP/$COMPRESSFILE $TMP/$TMPFILE2 $TMP/$BINDIR"

TAILPID=-1
TARPID=-1
DDPID=-1

#################### MISCELLANEOUS SUBROUTINES ########################

GetPGPPASS()
{
	if [ "$scheduled" = YES -o "$PGPPASS" != "" ]
	then
		return
	fi
	PGPPASS=
	dialog --title " PGP pass phrase " --inputbox "
For decrypting files using pgp(1) you need to specify a 
pass phrase for unlocking your private key.
You can specify it now, so it gets stored in an environ-
ment variable which spares you the repeated prompts for
it (especially when using afio(1) ). 

CAUTION: Storing the passphrase in an environment varia-
ble is extremly unsafe as other users can read your en-
vironment! See the pgp(1) man page for details.
Furtheron you will see what you type now, so make sure
noone sees your screen!
" 20 75 2>$TMP/$DIALOGFILE
	export PGPPASS=`cat $TMP/$DIALOGFILE`
}

choose_dir()
{
	currdir=`pwd`
	default=$1

	cd $default
	while :
	do
		echo "..	Parent"	>$TMP/$TMPFILE
		find . -maxdepth 1 -type d -printf "%f %u\n" | $GREP -v "^. " >>$TMP/$TMPFILE
		echo "A ACCEPT" >>$TMP/$TMPFILE
		sort $TMP/$TMPFILE >$TMP/$TMPFILE2
		lines=`wc -l <$TMP/$TMPFILE2` 
		if [ $lines -gt 15 ]
		then
			lines=15
		fi
		if dialog  --title " Directory selection " --menu \
"Current path:\n`pwd`\nSelect \"ACCEPT\"-entry to accept current path." 23 60 $lines\
		`cat $TMP/$TMPFILE2` 2>$TMP/$DIALOGFILE
		then
			result=`cat $TMP/$DIALOGFILE`
			if [ $result = A ]
			then
				choose_dir_result=`pwd`
				cd $currdir
				return
			else
				cd $result
			fi
		else
			cd $currdir
			choose_dir_result=$default
			return 
		fi
	done
}

write_settings()
{
	cat <<_EOF_
#
#	Configuration "$configname" for KBackup
#
configname=$configname
parent=$parent
local=$local
directoriesonly=$directoriesonly
findxpertmode=$findxpertmode
findxpertflags=$findxpertflags
specifiedfilesonly=$specifiedfilesonly
compression=$compression
compress_options=$compress_options
verify_archive=$verify_archive
archive_format=$archive_format
multivolume=$multivolume
tapelength=$tapelength
pgpkey=$pgpkey
incremental=$incremental
ddbufsize=$ddbufsize
double_buffering=$double_buffering
device=$device
floppy_format=$floppy_format
device_is_floppy=$device_is_floppy
datestamp="$datestamp"
resetdevice=$resetdevice
manualedit=$manualedit
followtarops=$followtarops
scheduled_only_once=$scheduled_only_once
TMP=$TMP
if [ "\$EDITOR" = "" ] 
then
	EDITOR=$EDITOR
fi
_EOF_
}

save_config()
{
	cat >$HOME/$KBACKRCDEFAULT <<_EOF_
#
#	KBackup base configuration
#
kbackdir=$kbackdir
configname=$configname
_EOF_

	mkdir $kbackdir/$configname 2>/dev/null

	write_settings > $kbackdir/$configname/Config
	
	if [ ! -f $kbackdir/$configname/Exclude_Files ] ; then
		cat >$kbackdir/$configname/Exclude_Files <<_EOF_
a.out
core
_EOF_
	fi
}

Init()
{
	echo "Initialising..."

	if [ -r $HOME/$KBACKRCDEFAULT ] ; then
		echo -e "\tReading $HOME/$KBACKRCDEFAULT..."
		source $HOME/$KBACKRCDEFAULT
	fi

	if [ ! -d $kbackdir ] ; then
		echo -e "\tCreating $kbackdir..."
		mkdir $kbackdir
	fi

	if [ ! -d $kbackdir/$configname ] ; then
		echo -e "\tCreating $kbackdir/$configname..."
		mkdir $kbackdir/$configname
	fi

	if [ -r $kbackdir/$configname/Config ] ; then
		echo -e "\tReading $kbackdir/$configname/Config..."
		source $kbackdir/$configname/Config
	fi

	if [ -r $kbackdir/$configname/DateStamp -a -s $kbackdir/$configname/DateStamp ]
	then 
		datestamp=`cat $kbackdir/$configname/DateStamp`
	fi

	if [ "$EDITOR" = "" ] ; then
		EDITOR=vi
	fi
	if ! Mtapelength=`expr $tapelength / 1048576 2>/dev/null` 
	then
		Mtapelength=1
	fi
}

beep()
{
	echo -e "\a"
}

ErrorBox()
{
	if [ $scheduled = YES ]
	then
		if [ -e $TMP/$MSGFILE ] ; then
			echo -e "$*" >>$TMP/$MSGFILE
		else
			echo -e "$*" >&2
		fi
	else
		echo -e "$*" >$TMP/$TMPFILE
		lines=`wc -l <$TMP/$TMPFILE`
		lines=`expr $lines + 3`
		beep
		dialog   --title " Error " --msgbox "$*" $lines 60 
	fi
}

InfoBox()
{
	if [ $scheduled =  YES ]
	then
		if [ -e $TMP/$MSGFILE ] ; then
			echo -e $* >>$TMP/$MSGFILE
		else
			echo -e $* >&2
		fi
	else
		echo -e $* >$TMP/$TMPFILE
		lines=`wc -l <$TMP/$TMPFILE`
		lines=`expr $lines + 3`
		dialog   --title " Status " --infobox "$*" $lines 32
	fi
}

MsgBox()
{
	if [ $scheduled =  YES ]
	then
		if [ -e $TMP/$MSGFILE ] ; then
			echo -e $* >>$TMP/$MSGFILE
		else
			echo -e $* >&2
		fi
	else
		echo -e "$*" >$TMP/$TMPFILE
		lines=`wc -l <$TMP/$TMPFILE`
		lines=`expr $lines + 3`
		dialog   --title " Status " --msgbox "$*" $lines 40
	fi
}

insert_media()
{
	if [ ! -f $device ] # if it is not a regular file
	then
		dialog   --title " Status " --yesno "
Please insert backup medium in
\"$device\".

Ok to continue?
" 10 50
	return $?
	fi
}

check_compress_success()
{
	ret=$?
	case	$compression in 
		NONE)	
			return $ret
			;;
		GZIP|COMPRESS)	
			if [ $ret = 0 -o $ret = 2 ] ; then
				return 0
			else
				return 1
			fi
			;;
		PGP)
			return $ret
			;;
	esac
}

create_dir_list()
{
	findargs=

	if [ $findxpertmode = YES ]
	then
		findargs=$findargs $findxpertflags
	else
		if [ $incremental = YES ] ; then
			touch -d "$datestamp" $TMP/$TMPFILE
			findargs="$findargs -cnewer $TMP/$TMPFILE"
		fi
	fi

	if [ $local = YES ] ; then
		findargs="$findargs -xdev"
	fi
	if [ $directoriesonly = YES ] ; then
		findargs="$findargs -type d"
	fi
	
	echo >$TMP/$DIRLISTFILE

	find $parent $findargs -fprintf $TMP/$DIRLISTFILE "%p %s %u %g %Tc %m\n"
}

device_err()
{
	beep
	dialog   --title "ERROR" --msgbox \
	"\nAn operation on the device\n\"$device\" failed.\nResetting the driver might help." 11 40
}

#
# creates the file $TMP/$DIRLISTFILE where it keeps the names and information
# about all the files to back up
#
build_dir_list()
{
	if [ $specifiedfilesonly = YES  ]
	then
		cp -f $kbackdir/$configname/Include_Files $TMP/$DIRLISTFILE
		return
	else
		create_dir_list
	fi
}

build_dir_list_for_tar()
{
	if [ $specifiedfilesonly = YES ]
	then
		cp -f $kbackdir/$configname/Include_Files $TMP/$TARLISTFILE
	else
		if [ $manualedit = YES ]
		then
			$AWK '/.*/	{ print $1 }' <$TMP/$DIRLISTFILE >$TMP/$TARLISTFILE
		else
			echo $parent >$TMP/$TARLISTFILE
		fi
	fi
}


set_compress()
{
	pcompress=
	puncompress=
	tarcompress=
	uncompress=
	case $compression in
		NONE)	compress=" cat " 
			uncompress=" cat "
			pcompress=" | cat "
			puncompress=" | cat "
			return
			;;
		GZIP)	compress=" gzip -c "$compress_options" " 
			cat >$TMP/$COMPRESSFILE <<_EOF_
#!/bin/sh
gzip $compress_options \$* 2>/dev/null
_EOF_
			chmod +x $TMP/$COMPRESSFILE
			tarcompress="--block-compress --use-compress-prog $TMP/$COMPRESSFILE"
			uncompress=" $compress -d "
			pcompress=" | $compress "
			puncompress=" | $compress -d "
			;;
			
		COMPRESS) compress=" compress "$compress_options" "
		cat >$TMP/$COMPRESSFILE <<_EOF_
#!/bin/sh
gzip $compress_options \$* 2>/dev/null
_EOF_
			chmod +x $TMP/$COMPRESSFILE
			tarcompress="--block-compress --use-compress-prog $TMP/$COMPRESSFILE"
			uncompress=" $compress -d "
			pcompress=" | $compress "
			puncompress=" | $compress -d "
			;;
			
		PGP) 	compress=" pgp -ef $pgpkey "$compress_options" 2>/dev/null"
			cat >$TMP/$COMPRESSFILE <<_EOF_
#!/bin/sh
cd $TMP 2>/dev/null
if [ "\$1" = "-d" ]
then
	opt=-d
	pgp \$opt -f 2>/dev/tty
else
	opt=-e
	pgp \$opt -f $pgpkey  2>/dev/null
fi
_EOF_
			chmod +x $TMP/$COMPRESSFILE
			tarcompress="--block-compress --use-compress-prog $TMP/$COMPRESSFILE"
			uncompress=" pgp -df $pgpkey "
			pcompress=" | $compress "
			puncompress=" | $uncompress "
	esac
}	

#
#	the sigint_handler() gets installed by Backup to make
#	sure that any tar/dd or tail -f process in the background gets
#	killed when KBackup is interrupted
#
sigint_handler()	# for Backup() 
{
	PGPPASS=
	if [ $TAILPID != -1 ]
	then 
		kill $TAILPID
		TAILPID=-1
	fi
	if [ $TARPID != -1 ]
	then 
		kill $TARPID
		TARPID=-1
	fi
	if [ $DDPID != -1 ]
	then 
		kill $DDPID
		DDPID=-1
	fi
	return 1
}


Calculate_MaxArcLen()
{
	# round to kilobytes and add 4Kb for safety:
	set -f
	bytes_written=`expr \( \( $bytes_written / 1024 \) + 4 \) * 1024`
	set +f

	maxarchivelength=`expr $tapelength - $bytes_written`
}


Tar_Backup()
{
	taropt=

	# trap signal to avoid tar/tail continuing in the background
	trap sigint_handler SIGINT
	trap sigint_handler EXIT

	if [ $followtarops = YES ]
	then
		reset
		clear
	fi
	
	if [ $multivolume = YES -a $device_is_floppy = NO ]
	then
		Calculate_MaxArcLen
		taropt="$taropt -L `expr $maxarchivelength / 1024`"
		clear; reset
	fi

	if [ $verify_archive = YES ]
	then
		taropt="$taropt -W"
	fi

	if [ $local = YES ]
	then
		taropt="$taropt -l"
	fi

	if [ $double_buffering = YES ]
	then
		tar $taropt --create --files-from $TMP/$TARLISTFILE \
			--exclude-from $kbackdir/$configname/Exclude_Files \
			$tarcompress -v -v -f - 2>$TMP/$TARLOGFILE| \
			dd  ibs=512 conv=sync obs=$ddbufsize of=$device 2>$TMP/$TMPFILE & 2>/dev/null
	else
		if [ $followtarops = YES ]
		then
			tar $taropt --create --files-from $TMP/$TARLISTFILE \
				--exclude-from $kbackdir/$configname/Exclude_Files \
				$tarcompress -f $device 2>&1 | tee $TMP/$TARLOGFILE 
		else
			tar $taropt --create --files-from $TMP/$TARLISTFILE \
				--exclude-from $kbackdir/$configname/Exclude_Files \
				$tarcompress -f $device 2>&1 > $TMP/$TARLOGFILE 
		fi
	fi

	TARPID=$!
	if [ $followtarops = YES -a $double_buffering = YES ]
	then
		tail -f $TMP/$TARLOGFILE &
		TAILPID=$!
	fi
	if ! wait $TARPID 2>/dev/null
	then
		beep
		ErrorBox "
Something went wrong while writing
archive.
Read logfile carefully.
"
	else
		if [ $followtarops = YES ]
		then
			echo -en "\nPress RETURN key to continue..."
			read
			kill $TAILPID
		fi
	fi
	TARPID=-1
	TAILPID=-1
	DDPID=-1
	trap SIGINT
}

Afio_Backup()
{
	afioopt=

	if [ $compression != NONE ]
	then
		if [ $compression != GZIP ]
		then
			mkdir $TMP/$BINDIR
			cp $TMP/$COMPRESSFILE  $TMP/$BINDIR/gzip
			oldpath=$PATH
			export PATH=$TMP/$BINDIR:$PATH
		else
			num=`echo $compress_options | $SED '1,$ s/-\([0-9]\).*/\1/g'`
			if [ "$num" != "" ]
			then
				if [ 0 -lt $num -a $num -le 9 ]
				then
					afioopt="$afioopt -G $num"
				fi
			fi
		fi
		afioopt="$afioopt -Z"
	fi

	if [ verify_archive = YES ]
	then
		afioopt="$afioopt -K"
	fi

	if [ $multivolume = YES -a $device_is_floppy = NO ]
	then
		Calculate_MaxArcLen
		afioopt="$afioopt -s $maxarchivelength"
	fi

	if [ $followtarops = YES ]
	then
		clear; reset
	fi
	
	if [ $double_buffering = YES ]
	then
		rm -f $TMP/$PIPEFILE
		mknod $TMP/$PIPEFILE p	# pipe to write archive to

		set -f	# do not expand *
		blocks=`echo $ddbufsize | $SED '1,$ s/\([0-9]*\)[kK]/\1 * 1024/g
		1,$ s/\([0-9]*\)[mM]/\1 * 1024 * 1024/g'`
		blocks=`expr $blocks / 5120`

		set +f	# restore normal * treatment

		if [ $followtarops = YES ]
		then
			find `cat $TMP/$TARLISTFILE` | \
			afio -o -c $blocks -f -v -W $kbackdir/$configname/Exclude_Files $afioopt $device 2>&1 | tee $TMP/$TARLOGFILE 
		else
			find `cat $TMP/$TARLISTFILE` | \
			afio -o -c $blocks -f -v -W $kbackdir/$configname/Exclude_Files $afioopt $device 2>&1 >$TMP/$TARLOGFILE 
		fi
	else
		if [ $device_is_floppy = YES ]
		then
			echo "fdformat $device" >$TMP/$TMPFILE2
			chmod +x $TMP/$TMPFILE2
			blocks=`echo $floppy_format|$SED '1,$ s/\(.*\)\/.*/\1k/g' `
			floppy_opts="-F -s $blocks -R $TMP/$TMPFILE2 "
		else
			floppy_opts=
		fi
		if [ $followtarops = YES ]
		then
			find `cat $TMP/$TARLISTFILE` | \
			afio -o -v $afioopt $floppy_opts -W $kbackdir/$configname/Exclude_Files $device 2>&1 | tee $TMP/$TARLOGFILE 
		else
			find `cat $TMP/$TARLISTFILE` | \
			afio -o -v $afioopt $floppy_opts -W $kbackdir/$configname/Exclude_Files $device 2>&1 >$TMP/$TARLOGFILE 
		fi
	fi

	if [ $? != 0 ]
	then
		dialog   --title "Error" --msgbox "
Something went wrong while writing
archive.
Read logfile carefully.
" 7 40
	else
		if [ $followtarops = YES ]
		then
			echo -en "\nPress RETURN key to continue..."
			read
		fi
	fi
	if [ $compression != GZIP -a $compression != NONE ]
	then
		rm -rf $TMP/$BINDIR
		export PATH=$oldpath
	fi
}

count_filesizes()
{
	findargs=

	if [ $findxpertmode = YES ]
	then
		findargs=$findargs $findxpertflags
	else
		if [ $incremental = YES ] ; then
			touch -d "$datestamp" $TMP/$TMPFILE
			findargs="$findargs -cnewer $TMP/$TMPFILE"
		fi
	fi

	if [ $local = YES ] ; then
		findargs="$findargs -xdev"
	fi
	
	echo >$TMP/$TMPFILE2

	find $parent $findargs -fprintf $TMP/$TMPFILE2 "%k\n"
}

Get_BackupSize()
{
	InfoBox "\nCreating list of files..."
	if [ $specifiedfilesonly = YES ]
	then
		build_dir_list
		find `cat $TMP/$DIRLISTFILE` -printf "%k\n" >$TMP/$TMPFILE
	else
		count_filesizes
	fi

	InfoBox "\nAdding file sizes..."

	size=`$AWK 	'BEGIN	{ kilobytes = 0 }
		/.*/ 	{ kilobytes += $1 }
		END	{ print kilobytes}
		' <$TMP/$TMPFILE2 `
	MsgBox "
Total backup size before compression
is $size KiloBytes ( = `expr $size / 1024` MB).

If using compression you will need
roughly half that space on your 
backup media.
"
}

Backup()
{	
	if [ $scheduled = YES ]
	then
		echo "Starting scheduled backup at `date`.\n\n" >$TMP/$MSGFILE
	else
		if ! insert_media
		then
			return
		fi
	fi
	
	InfoBox "\nCreating list of files..."
	
	build_dir_list

	if [ $scheduled = NO -a $manualedit = YES ] ; then
		$EDITOR $TMP/$DIRLISTFILE
	fi


	if [ -f $device ] ; then # do extra directory file
		dirfile=$device.dir
	else
		if [ $device_is_floppy = NO ]
		then
			dirfile=$device
			InfoBox "\nWriting header..."
			echo "#KBackup" > $TMP/$TMPFILE
			echo backup_version=$VERSION >>$TMP/$TMPFILE
			if [ $incremental = YES ] ; then
				echo backup_type=incremental >>$TMP/$TMPFILE
			else
				echo backup_type=full >>$TMP/$TMPFILE
			fi
			echo backup_compression=$compression >>$TMP/$TMPFILE
			echo backup_date=\"`date`\" >>$TMP/$TMPFILE
			echo backup_donly=$directoriesonly >>$TMP/$TMPFILE
			echo backup_archive_format=$archive_format >>$TMP/$TMPFILE
			echo backup_multivolume=$multivolume >>$TMP/$TMPFILE
			echo >>$TMP/$TMPFILE
			if ! cat $TMP/$TMPFILE | dd ibs=512 conv=sync of=$device  2>/dev/null
			then
				device_err
				return
			fi

			# for multivolume archives:
			bytes_written=`wc -c <$TMP/$TMPFILE`
			
		else	# device is floppy!
			bytes_written=0
			setfdprm $device $floppy_format
		fi
	fi

	set_compress
	if [ $device_is_floppy = NO ]
	then
		InfoBox "\nWriting directory..."
		cat $TMP/$DIRLISTFILE | $compress > $TMP/$TMPFILE
		dd if=$TMP/$TMPFILE ibs=512 conv=sync 2>/dev/null | dd obs=$ddbufsize >$dirfile 2>/dev/null
		# for multivolume archives:
		tmp=`wc -c < $TMP/$TMPFILE`
		bytes_written=`expr $tmp + $bytes_written`
	fi

	InfoBox "\nFiltering list for tar..."
	build_dir_list_for_tar
	
	InfoBox "\nWriting archive..." 

	# set logfile name now to get date/time right:
	logfile=$kbackdir/$configname/Log`date +"%y-%m-%d--%X"`

	if [ $archive_format = AFIO ]
	then
		Afio_Backup
	else
		Tar_Backup
	fi
	
	InfoBox "\nGenerating logfile..."
	if [ $scheduled = YES ]
	then
		cat $TMP/$MSGFILE $TMP/$TMPFILE $TMP/$TARLOGFILE > $logfile
	else
		cat $TMP/$TMPFILE $TMP/$TARLOGFILE > $logfile
	fi
	
	date >$kbackdir/$configname/DateStamp
	beep
	if [ $scheduled = NO ]
	then
		dialog   --title $logfile --textbox $logfile 23 75
	fi
	rm -f $TMP/$MSGFILE
	InfoBox "\nCompressing logfile..."
	cat $logfile | $compress >$TMP/$TMPFILE
	mv -f $TMP/$TMPFILE $logfile
}

View_Logfile()
{
	find $kbackdir -type d -maxdepth 1 -printf "%f %Tx\n" |\
	$FGREP -v `basename $kbackdir` | sort >$TMP/$TMPFILE
	if dialog   --menu "Choose a configuration:" 20 60 `wc -l <$TMP/$TMPFILE` \
		`cat $TMP/$TMPFILE` 2>$TMP/$DIALOGFILE
	then
		dir=`cat $TMP/$DIALOGFILE`
		find $kbackdir/$dir -type f -maxdepth 1 -printf "%f %Tx\n" |\
		$FGREP "Log" | sort >$TMP/$TMPFILE
		if dialog   --menu "Choose a logfile:" 20 60 `wc -l <$TMP/$TMPFILE` \
			`cat $TMP/$TMPFILE` 2>$TMP/$DIALOGFILE
		then
			InfoBox "\nUncompressing logfile..." 
			old_compressio=$compression
			logfile=$kbackdir/$dir/`cat $TMP/$DIALOGFILE`
			filetype=`file $logfile`
			if echo $filetype | $FGREP gzip >/dev/null ; then
				compression=GZIP
			else
				if echo $filetype | $FGREP compress >/dev/null ; then
					compression=COMPRESS
				else
					if echo $filetype | $FGREP text >/dev/null ; then
						compression=NONE
					else
						setco=`$FGREP "compression" <$kbackdir/$dir/Config`
						echo $setco >$TMP/$TMPFILE
						source $TMP/$TMPFILE
					fi
				fi
			fi
			set_compress
			cat < $logfile | $uncompress >$TMP/$TMPFILE
			dialog   --title "`cat $TMP/$DIALOGFILE`" --textbox $TMP/$TMPFILE 23 75 2>/dev/null
			compression=$old_compression
		fi
	fi
}


Delete_Logfile()
{
	find $kbackdir -type d -maxdepth 1 -printf "%f %Tx\n" |\
	$FGREP -v `basename $kbackdir` | sort >$TMP/$TMPFILE
	if dialog   --menu "Choose a configuration:" 20 60 `wc -l <$TMP/$TMPFILE` \
		`cat $TMP/$TMPFILE` 2>$TMP/$DIALOGFILE
	then
		dir=`cat $TMP/$DIALOGFILE`
		find $kbackdir/$dir -type f -maxdepth 1 -printf "%f %Tx\n" |\
		$FGREP "Log" | sort >$TMP/$TMPFILE
		if dialog   --menu "Choose a logfile:" 20 60 `wc -l <$TMP/$TMPFILE` \
			`cat $TMP/$TMPFILE` 2>$TMP/$DIALOGFILE
		then
			filename=`cat $TMP/$DIALOGFILE`
			if [ -f $kbackdir/$dir/$filename ]
			then
				if dialog --title " Please confirm: " --yesno \
				"\nDelete $kbackdir/$dir/$filename ?" 5 60
				then
					delete $kbackdir/$dir/$filename	
				fi
			fi
		fi
	fi
}

View_Contents()
{	
	backup_version=???
	backup_date=???
	backup_compression=???
	backup_type=???
	backup_archive_format=???
	backup_multivolume=???
	backup_donly=???

	if ! insert_media
	then
		return
	fi

	if [ $device_is_floppy = NO ]
	then
		if [ ! -c $device -a ! -L $device ] ; then # do extra directory file
			dirfile=$device.dir
		else
			InfoBox "\nReading header..." 
			dirfile=$device
			if ! cat < $device >$TMP/$TMPFILE
			then
				device_err
				return
			else
				if read firstline < $TMP/$TMPFILE && [ $firstline = "#KBackup" ]
				then
					source $TMP/$TMPFILE && dialog   --title "Archive header information" --msgbox "\n\
Archive created by KBackup Version: $backup_version\n\
Creation date: .................... $backup_date\n\
Backup type: ...................... $backup_type\n\
Archive format: ................... $backup_archive_format\n\
Compression method: ............... $backup_compression\n\
Directories-only flag: ............ $backup_donly\n\
Multivolume flag: ................. $backup_multivolume" 14 75 
				else
					ErrorBox "
File is not a valid KBackup Archive Header.
"
					return
				fi
			fi
		fi
		if [ $compression = PGP ]
		then
			GetPGPPASS
		fi
		set_compress
	
		InfoBox "\nReading directory..." 
		dd ibs=$ddbufsize if=$dirfile 2>/dev/null | $uncompress >$TMP/$TMPFILE 2>/dev/null
		if check_compress_success
		then
			dialog   --title "Archive contents directory" --textbox $TMP/$TMPFILE 23 75
		else
			beep
			ErrorBox "
Cannot read contents directory.
Maybe tape at wrong position?
" 8 40
		fi	
	else		# device is floppy
		if [ $archive_format = TAR ]
		then
			tar -tvf $device 2>&1 >$TMP/$TMPFILE
		else
			blocks=`echo $floppy_format|$SED '1,$ s/\(.*\)\/.*/\1k/g' `
			afio -tlvF -s $blocks $device 2>&1 >$TMP/$TMPFILE
		fi
		if [ $? -eq 0 ]
		then
			dialog   --title "Archive contents directory" --textbox $TMP/$TMPFILE 23 75
		else
			ErrorBox "
Reading of archive contents failed!
"
		fi
	fi
	PGPPASS=
}	

Restore_part_I()
{
	old_compression=$compression
	bytes_written=0	# well, should be bytes_read...
	
	if [ $device_is_floppy = NO ]
	then
		if [ ! -c $device ] ; then # do extra directory file
			dirfile=$device.dir
		else
			dirfile=$device
			InfoBox "\nReading header..."
			if ! cat < $device >$TMP/$TMPFILE 
			then
				device_err
				return 1
			else
				bytes_written=`wc -c <$TMP/$TMPFILE`
				if read firstline < $TMP/$TMPFILE && [ $firstline = "#KBackup" ]
				then
					source $TMP/$TMPFILE
					old_compression=$compression
					compression=$backup_compression
					dialog   --title "Archive header information" --msgbox "\n\
Archive created by KBackup Version: $backup_version\n\
Creation date: .................... $backup_date\n\
Backup type: ...................... $backup_type\n\
Archive format: ................... $backup_archive_format\n\
Compression method: ............... $backup_compression\n\
Directories-only flag: ............ $backup_donly\n\
Multivolume flag: ................. $backup_multivolume" 14 75 
				else
					ErrorBox "
Cannot find a KBackup archive header!"
					return 1
				fi
			fi
		fi
	fi

	MsgBox "
You are now prompted to choose
the relative root directory.

"
	choose_dir /
	restore_dir=$choose_dir_result

	set_compress

	restore_all=NO
	if dialog   --menu "Please choose:" 11 75 4\
		A	"Restore all files from archive" \
		C	"Initialise editable list of files from contents directory"\
		L	"Initialise editable list of files from logfile"\
		R	"Return to main menu" 2>$TMP/$DIALOGFILE 
	then
		case `cat $TMP/$DIALOGFILE` in
		A)	InfoBox "\nReading contents directory..." 
			if [ $device_is_floppy = NO ]
			then
				dd ibs=$ddbufsize if=$dirfile >$TMP/$TMPFILE 2>/dev/null
				tmp=`wc -c < $TMP/$TMPFILE`
				bytes_written=`expr $tmp + $bytes_written`
				$uncompress <$TMP/$TMPFILE >$TMP/$DIRLISTFILE
				if ! check_compress_success 
				then
					beep
					dialog   --title "Error" --msgbox "
Reading/Decompressing contents
directory failed.
" 7 40
					return 1
				fi
			fi
			restore_all=YES
			return 0
			;;
		C)	if [ $device_is_floppy = YES ]
			then
				ErrorBox "
Floppy archives do not have a contents directory!
"
				return 1
			fi
			InfoBox "\nReading contents directory..." 
			dd ibs=$ddbufsize if=$dirfile >$TMP/$TMPFILE 2>/dev/null
			tmp=`wc -c < $TMP/$TMPFILE`
			bytes_written=`expr $tmp + $bytes_written`
			$uncompress <$TMP/$TMPFILE >$TMP/$DIRLISTFILE
			if ! check_compress_success 
			then
				beep
				dialog   --title "Error" --msgbox "
Reading/Decompressing contents
directory failed.
" 7 40
				return 1
			fi
			clear
			reset
			$EDITOR $TMP/$DIRLISTFILE
			;;
		L)	find $kbackdir/$configname -name "*Log*" -printf "%f %Tx\n" | sort >$TMP/$TMPFILE
			dialog   --menu "Choose a logfile:" 20 60 `wc -l <$TMP/$TMPFILE` \
				`cat $TMP/$TMPFILE` 2>$TMP/$DIALOGFILE

			cat $kbackdir/$configname/`cat $TMP/$DIALOGFILE` | $uncompress >$TMP/$DIRLISTFILE
			clear
			reset
			$EDITOR $TMP/$DIRLISTFILE
			if [ $device_is_floppy = NO ]
			then
				InfoBox "\nSkipping contents directory..." 
				dd ibs=$ddbufsize if=$dirfile >$TMP/$TMPFILE 2>/dev/null
				tmp=`wc -c < $TMP/$TMPFILE`
				bytes_written=`expr $tmp + $bytes_written`
			fi
			;;
		R)	compression=$old_compression
			return 1
			;;
		esac
	else
		compression=$old_compression
		return 1
	fi
	return 0
}

Tar_Restore()
{
	xopt=
	if [ $multivolume = YES ]
	then
		reset; clear
		xopt="$xopt -M"
	fi
	if [ $restore_all = NO ]
	then
		xopt="$xopt --files-from $TMP/$TARLISTFILE"
	fi

	if [ $double_buffering = YES ]
	then
		dd  ibs=$ddbufsize if=$device 2>/dev/null | \
			tar $xopt --extract \
				--exclude-from $kbackdir/$configname/Exclude_Files \
				$tarcompress -v -v -f - 2>&1 >$TMP/$TARLOGFILE & 2>/dev/null
		TARPID=$!
	else
		if [ $followtarops = YES ]
		then
			clear
			reset
			xopt="$xopt -v -v"
			tar $xopt --extract \
			--exclude-from $kbackdir/$configname/Exclude_Files \
			$tarcompress -f $device 2>&1 | tee $TMP/$TARLOGFILE
			echo -e "\nPress ENTER to continue..."
			read
		else
			tar $xopt --extract \
			--exclude-from $kbackdir/$configname/Exclude_Files \
			$tarcompress -f $device 2>&1 >$TMP/$TARLOGFILE
		fi
	fi
}

Afio_Restore()
{
	xopt=
	if [ $multivolume = YES -a $device_is_floppy = NO ]
	then
		reset; clear
		Calculate_MaxArcLen
		xopt="$xopt -s $maxarchivelength"
	fi

	if [ $device_is_floppy = YES ]
	then
		blocks=`echo $floppy_format|$SED '1,$ s/\(.*\)\/.*/\1k/g' `
		xopt="$xopt -F -s $blocks "
	fi

	if [ $compression != NONE ]
	then
		xopt="$xopt -Z"
		if [ $compression != GZIP ]
		then
			mkdir $TMP/$BINDIR
			cp $TMP/$COMPRESSFILE  $TMP/$BINDIR/gzip
			oldpath=$PATH
			export PATH=$TMP/$BINDIR:$PATH
		else
			num=`echo $compress_options | $SED '1,$ s/-\([0-9]\).*/\1/g'`
			if [ 0 -lt $num -a $num -le 9 ]
			then
				xopt="$xopt -G $num"
			fi
		fi
	fi
	if [ $double_buffering = YES ]
	then
		set -f	# do not expand *
		blocks=`echo $ddbufsize | $SED '1,$ s/\([0-9]*\)[kK]/\1 * 1024/g
		1,$ s/\([0-9]*\)[mM]/\1 * 1024 * 1024/g'`
		blocks=`expr $blocks / 5120`
		set +f	# restore normal * treatment
		xopt="$xopt -c $blocks -f"
	fi
		
	if [ $restore_all = YES ]
	then
		if [ $followtarops = YES ]
		then
			clear
			reset
			afio -i $xopt -gvz -W $kbackdir/$configname/Exclude_Files $device 2>&1 | tee $TMP/$TARLOGFILE 
			echo -en "\nPress RETURN key to continue..."
			read
		else
			afio -i $xopt -gvz -W $kbackdir/$configname/Exclude_Files $device 2>&1 >$TMP/$TARLOGFILE 
		fi
	else
		if [ $followtarops = YES ]
		then
			clear
			reset
			cat $TMP/$TARLISTFILE | afio -i $xopt -gvz -W $kbackdir/$configname/Exclude_Files $device 2>&1 | tee $TMP/$TARLOGFILE 
			echo -en "\nPress RETURN key to continue..."
			read
		else
			cat $TMP/$TARLISTFILE | afio -i $xopt -gvz -W $kbackdir/$configname/Exclude_Files $device 2>&1 >$TMP/$TARLOGFILE 
		fi
	fi
	if [ $compression != GZIP -a $compression != NONE ]
	then
		rm -rf $TMP/$BINDIR
		export PATH=$oldpath
	fi
}

Restore()
{

	if [ $scheduled = YES ]
	then
		echo "Starting scheduled restore at `date`:" >$TMP/$MSGFILE
	else
		if ! insert_media
		then
			return
		fi

		if ! Restore_part_I
		then
			return
		fi
	fi

	cd $restore_dir

	InfoBox "\nFiltering list for tar..."

	build_dir_list_for_tar

	# strip leading '/'
	$SED '1,$ s/^\/\(.*\)/\1/g' <$TMP/$TARLISTFILE >$TMP/$TMPFILE
	mv $TMP/$TMPFILE $TMP/$TARLISTFILE

	InfoBox "\nRestoring files..."

	if [ $compression = PGP ]
	then
		GetPGPPASS
	fi
	
	if [ $archive_format = TAR ]
	then
		Tar_Restore

	else		# AFIO
		Afio_Restore
	fi
	PGPPASS=
	compression=$old_compression
	logfile=$TMP/RESTORED-`date +"%y-%m-%d--%X"`
	if [ $scheduled = NO ]
	then
		cat $TMP/$TARLOGFILE | $compress >$logfile
		beep
		dialog   --title $logfile --textbox $TMP/$TARLOGFILE 23 75
	else
		cat $TMP/$MSGFILE $TMP/$TARLOGFILE | $compress >$logfile
		rm -rf $kbackdir/$schedulename
		rm -f $TMP/$MSGFILE
	fi
}

schedule()
{
	schedulename=.--scheduled--$$
	oldconfigname=$configname
	configname=$schedulename
	save_config
	configname=$oldconfigname
	echo oldconfigname=$configname >>$kbackdir/$schedulename/Config
	echo scheduled=YES >>$kbackdir/$schedulename/Config
}

unschedule()
{
	configname=$oldconfigname
	if [ $scheduled_only_once = YES ]
	then
		rm -rf $kbackdir/$schedulename
	fi
	save_config
}

enter_time()
{
	if dialog   --inputbox "Please enter time and date in at(1) format:\n\
Current time and date is: `date`." 9 75 2>$TMP/$DIALOGFILE \
		&& test -n "`cat $TMP/$DIALOGFILE`"
	then
		scheduletime=`cat $TMP/$DIALOGFILE`
	fi
}

do_schedule()
{
	while : ; do
	if dialog   --title "Scheduling" --menu "Please choose:" 12 38 5 \
		T	"Set date and time" \
		B	"Schedule a backup" \
		R	"Schedule a restore" \
		O	"Toggle Once Only Flag [$scheduled_only_once]" \
		M	"Back to main menu" 2>$TMP/$DIALOGFILE
	then
		case `cat $TMP/$DIALOGFILE` in
			T)	enter_time
				;;
			B)	schedule
				echo "$0 --scheduled-backup $schedulename" | at $scheduletime 
				exit
				;;
			R)	Restore_part_I
				if [ $restore_part_I = FAILED ]
				then
					return
				fi
				schedule
				pwd
				read
				echo "$0 --scheduled-restore $schedulename" | at $scheduletime 
				exit
				;;
			M)	schedule=NO
				return
				;;
			O)	if dialog --title "Schedule Once Only Flag" --yesno "
If you have specified a time setting that
calls this backup more than only once, its
configuration file must not be removed, so
please choose <NO> here.

If you want this backup to be performed
only once, it can savely remove its confi-
guration file on termination, so please
choose <YES>.

Perform backup only once?
"  16  47
				then
					scheduled_only_once=YES
				else
					scheduled_only_once=NO
				fi
				;;
		esac
	else
		schedule=NO
		return
	fi
	done
}

Verify()
{

	backup_version=???
	backup_date=???
	backup_compression=???
	backup_type=???
	backup_archive_format=???
	backup_multivolume=???
	backup_donly=???
	old_compression=$compression

	if ! insert_media
	then
		return
	fi
	
	if [ $device_is_floppy = YES ]
	then
		ErrorBox "
Verify for disk archives not implemented.
"
		return
	fi
	
	if [ -c $device -o -L $device ]
	then
		InfoBox "\nReading header..." 
		if ! cat < $device >$TMP/$TMPFILE
		then
			device_err
			return
		else
			if read firstline < $TMP/$TMPFILE && [ $firstline = "#KBackup" ]
			then
				source $TMP/$TMPFILE
			else
				ErrorBox "
File is not a valid KBackup Archive Header."
				return
			fi
		fi
	
		dirstatus=
		archstatus=		
				
		dialog   --title "Verify" --infobox "\n\
Archive created by KBackup Version: $backup_version\n\
Creation date: .................... $backup_date\n\
Backup type: ...................... $backup_type\n\
Archive format: ................... $backup_archive_format\n\
Compression method: ............... $backup_compression\n\
Directories-only flag: ............ $backup_donly\n\
Multivolume flag: ................. $backup_multivolume\n\
\n\
Contents directory: ............... $dirstatus\n\
Archive status: ................... $archstatus" 16 75 
		case $backup_compression in
			GZIP) ;;
			COMPRESS) ;;
			NONE) ;;
			PGP) ;;
			*)	beep
				dialog   --title "Error" --msgbox "\nNo KBackup archive or\nunknown compression method." 7 40
				return ;;
		esac
		if [ $backup_compressin != ??? ] ; then
			compression=$backup_compression
			set_compress
		fi

			dialog   --title "Verify" --infobox "\n\
Archive created by KBackup Version: $backup_version\n\
Creation date: .................... $backup_date\n\
Backup type: ...................... $backup_type\n\
Archive format: ................... $backup_archive_format\n\
Compression method: ............... $backup_compression\n\
Directories-only flag: ............ $backup_donly\n\
Multivolume flag: ................. $backup_multivolume\n\
\n\
Contents directory: ............... $dirstatus\n\
Archive status: ................... $archstatus" 16 75 
		dd obs=$ddbufsize if=$device 2>/dev/null | $uncompress >/dev/null
		if check_compress_success
		then
			dirstatus=OK
		else
			dirstatus=ERR
			beep
			if ! dialog   --title "Error" --yesno "\nContents directory corrupted.\nCheck archive contents anyway?" 8 40
			then
				compression=$oldcompression
				return
			fi
		fi
			dialog   --title "Verify" --infobox "\n\
Archive created by KBackup Version: $backup_version\n\
Creation date: .................... $backup_date\n\
Backup type: ...................... $backup_type\n\
Archive format: ................... $backup_archive_format\n\
Compression method: ............... $backup_compression\n\
Directories-only flag: ............ $backup_donly\n\
Multivolume flag: ................. $backup_multivolume\n\
\n\
Contents directory: ............... $dirstatus\n\
Archive status: ................... $archstatus" 16 75 

		if [ $backup_archive_format = TAR ]
		then
			if [ $multivolume = YES ]
			then
				xopt="-M "
			else
				xopt=
			fi
			if [ $double_buffering = ON ]
			then
				dd ibs=$ddbufsize if=$device 2>/dev/null | $uncompress | tar $xopt -t -f - 2>/dev/null >/dev/null
			else
				$uncompress < $device | tar $xopt -t -f - 2>/dev/null
			fi
		else	# AFIO
			xopt=
			if [ $device_is_floppy = YES ]
			then
				blocks=`echo $floppy_format|$SED '1,$ s/\(.*\)\/.*/\1k/g' `
				xopt="$xopt -F -s $blocks "
			fi
	
			if [ $compression = GZIP ]
			then
				xopt="$xopt -Z"
				num=`echo $compress_options | $SED '1,$ s/-\([0-9]\).*/\1/g'`
				if [ 0 -lt $num -a $num -le 9 ]
				then
					xopt="$xopt -G $num"
				fi
			fi
			if [ $double_buffering = YES ]
			then
				set -f	# do not expand *
				blocks=`echo $ddbufsize | $SED '1,$ s/\([0-9]*\)[kK]/\1 * 1024/g
				1,$ s/\([0-9]*\)[mM]/\1 * 1024 * 1024/g'`
				blocks=`expr $blocks / 5120`
				set +f	# restore normal * treatment
				xopt="$xopt -c $blocks -f"
			fi
			if ! afio -t $xopt $device 2>&1 
			then
				ErrorBox "

Archive is corrupted.

"	
			fi
			return
		fi

		if [ $? -eq 0 ]
		then
			archstatus=OK
		else
			archstatus=Corrupted
		fi
		
			dialog   --title "Verify" --msgbox "\n\
Archive created by KBackup Version: $backup_version\n\
Creation date: .................... $backup_date\n\
Backup type: ...................... $backup_type\n\
Archive format: ................... $backup_archive_format\n\
Compression method: ............... $backup_compression\n\
Directories-only flag: ............ $backup_donly\n\
Multivolume flag: ................. $backup_multivolume\n\
\n\
Contents directory: ............... $dirstatus\n\
Archive status: ................... $archstatus" 16 75 
	else
		if $uncompress <$device | tar -t -f - 2>/dev/null >/dev/null
		then
			dialog   --title " Verify " --msgbox "\nArchive file is OK." 5 40
		else
			beep
			dialog   --title "Error" --msgbox "\nThere's no verify for files." 7 40
		fi
	fi
}

cleanup()
{
	rm -rf $TMPFILES
}

set_multivolume()
{
	multivolume=YES

	if [ $archive_format = TAR ]
	then
		if [ $compression != NONE ]
		then
			compression=NONE
			MsgBox "\nSwitching off compression for multi-\nvolume tar-archives.\n"
		fi
		if [ $double_buffering = YES ]
		then
			double_buffering=NO
			MsgBox "\nSwitching off double buffering\nfor multivolume tar-archives.\n"
		fi
	fi
}

#
#	check wether combination of options is valid:
#
Check_Settings()
{
	if [ $archive_format = TAR ]
	then
		if [ $multivolume = YES ]
		then
			if [ $compression != NONE ]
			then
				ErrorBox "
If you want to use compressed multivolume archives,
you must use the AFIO-format, TAR is not capable of
this. Otherwise, you cannot compress or just write
archives of at most one volume's length.
Setting archive format to AFIO.
"
				archive_format=AFIO
			fi
			if [ $double_buffering = YES ]
			then
				ErrorBox "
You cannot use double buffering with multivolume
archives in TAR-format. 
As TAR does not support compression with multi-
volume archives, this should not be necessary
anyway.
Switching off double buffering.
"
				double_buffering=NO
			fi
		fi
#	else	# AFIO
#		if [ $compression != GZIP ]
#		then
#			ErrorBox "
#For compressing multivolume archives, you can only
#use GZIP as this is the only program directly supported
#by AFIO.
#Setting compression program to GZIP.
#"
#		fi
	fi


	if [ $double_buffering = YES ]
	then
		if [ -z "$ddbufsize" ]
		then
			ErrorBox "
You must specify a buffersize when using double
buffering.
Setting it to 4096k.
"
			ddbufsize=4096k
		fi
		if [ $device_is_floppy = YES ]
		then
			ErrorBox "
You selected double buffering for a floppy
drive. This is not possible.
Disabling double buffering.
"
		double_buffering=NO
		fi
	fi
}	

############################### MENU ROUTINES ##################

Compression_Menu()
{
	while :
	do
	if dialog   --title " Compression menu " --menu "\n\
Please choose one of the following compression methods. Before using\n\
pgp(1) for public key encryption, you should know what you are doing!\n\n\
The current compression is $compression, Options: $compress_options\n" 18 75 6 \
		N	"No compression" \
		G	"Compress using Gzip" \
		C	"Compress using Compress" \
		P	"Compress + Encrypt using Pgp" \
		O	"Set Command-line Optons for compression program" \
		B	"Return to Backup Parameters Menu" 2>$TMP/$DIALOGFILE
	then
		case `cat $TMP/$DIALOGFILE` in
		N)	compression=NONE
			;;
		G)	compression=GZIP
			;;
		C)	compression=COMPRESS
			;;
		P)	compression=PGP
			if dialog   --inputbox "Please enter name of pgp key:" 8 75 2>$TMP/$DIALOGFILE \
			 && test -n "`cat $TMP/$DIALOGFILE`"
			then
				pgpkey=`cat $TMP/$DIALOGFILE`
			fi
			;;
		O)	if dialog   --inputbox "Please enter any optional command line arguments\n\
for the compression program (e.g. -1 for gzip).\n\
Default is: \"$compress_options\"\n(Enter a single space for no options.)" 13 75 2>$TMP/$DIALOGFILE
			then
				if [ "`cat $TMP/$DIALOGFILE`" != "" ] ; then
					compress_options=`cat $TMP/$DIALOGFILE`
				fi
			fi
			;;
		B)	return
			;;
		esac
	else
		return
	fi
	done
}

Floppy_Format_Menu()
{
	while : ; do
	if dialog --title " Floppy Format Menu " --menu "\n\
Please choose a disk format to use:\n(current: $floppy_format)\n" 17 70 6\
		"1722/1440"	"1.7Mb  on a 3.5  drive" \
		"1440/1440"	"1.44Mb on a 3.5 or 5.25 drive" \
		"720/1440"	"720Kb  on a 3.5  drive" \
		"1200/1200"	"1.2Mb  on a 5.25 drive" \
		"720/1200"	"720Kb  on a 5.25  drive" \
		D		"Return to Device Menu" 2>$TMP/$DIALOGFILE 
	then
		case `cat $TMP/$DIALOGFILE` in
			D)	return
				;;
			*)	floppy_format=`cat $TMP/$DIALOGFILE`
				;;
		esac
	else
		return
	fi
	done
}

Device_Menu()
{
	while : ; do
	if dialog --title " Device Menu " --menu "\n\
Choose a device for your backup and optionally set the device related\n\
options. Current setting: $device" 18 77 8 \
		"/dev/fd0" 	"First floppy drive"\
		"/dev/fd1" 	"Second floppy drive"\
		"/dev/tape" 	"Tape drive (symbolic link?)"\
		"Other" 	"Enter your own device/archive file"\
		D		"Set Device-Is-A-Floppy-Drive flag [$device_is_floppy]"\
		F		"Set Floppy format                 [$floppy_format]"\
		R		"Set device for resetting driver   [$resetdevice]"\
		P		"Return to Parameters Menu" 2>$TMP/$DIALOGFILE
	then
		case `cat $TMP/$DIALOGFILE` in
		F)	Floppy_Format_Menu
			;;
		D)	if [ $device_is_floppy = YES ]
			then
				device_is_floppy=NO
			else
				device_is_floppy=YES
			fi
			;;
		/dev/fd0|/dev/fd1)
			device_is_floppy=YES
			device=`cat $TMP/$DIALOGFILE`
			Floppy_Format_Menu
			;;
		/dev/tape)
			device_is_floppy=NO
			device="/dev/tape"
			;;
		Other)	if dialog   --inputbox "Please specify the device/file to use.\n(default: $device)" \
			9 75 2>$TMP/$DIALOGFILE
			then
				newdevice=`cat $TMP/$DIALOGFILE`
				if [ -n "$newdevice" ]
				then
					device=$newdevice
				fi
				if [ -c $device ] ; then
					device_is_floppy=NO
					MsgBox "\nYou specified a character device,\nassuming it is a tape streamer."
				else
					if [ -L $device ] ; then
						device_is_floppy=NO
						MsgBox "\nYou specified a symbolic link,\nassuming it is a tape streamer."
					else
						if [ -b $device ] ; then
							device_is_floppy=YES
							MsgBox "\nYou specified a block device,\nassuming it is a floppy drive."
						else
							ErrorBox "
No character device!
Keeping old value.
"
						fi
					fi
				fi
			fi
			;;
		R)	if dialog   --inputbox "Please specify the device for resetting the driver:\n(default: $resetdevice)" \
			9 75 2>$TMP/$DIALOGFILE && test -n "`cat $TMP/$DIALOGFILE`"
			then
				if [ -c `cat $TMP/$DIALOGFILE` ] ; then
					resetdevice=`cat $TMP/$DIALOGFILE`
				else
					dialog   --msgbox "\nNo character device!\nKeeping old value." 5 40
				fi
			fi
			;;
		P)	return
			;;
		esac
	else
		return
	fi
	done
}

Set_TapeLength()
{
	Mtapelength=`expr $tapelength / 1048576`
	
	if dialog   --title " Multivolumer Archive Length " --inputbox "
Please specify the maximum archive length for multivolume archives.
This should be the (uncompressed) capacity of your tape/device. 
Please give the length in megabytes, like e.g. 250 for a 250mb tape.
Use the suffix 'g' to specify gigabytes instead (like 5g for 5GB).

The default value is: $Mtapelength MBytes

		" 20 75 2>$TMP/$DIALOGFILE
		then
			newlen=`cat $TMP/$DIALOGFILE`
			if [ "$newlen" != "" ]
			then
				set -f	# do not expand *
				Mtapelength=`echo $newlen | \
				$SED '1,$ s/\(.*\)[mM].*/\1/g
				     1,$ s/\(.*\)[gG].*/\1 * 1024/g'`
				tapelength=`expr $Mtapelength * 1048576`
				set +f # normal operation
			fi
		fi
}


Parameters_Menu()
{
	while : ; do
		if dialog   --title " Parameters Menu " --menu "\n\
Here you can set the options deciding how KBackup operates.\n" 24 77 15 \
			E	"Toggle Local Filesystem Mode              [$local]" \
			I	"Toggle Incremental Mode                   [$incremental]" \
			D	"Set date for incremental backup           "\
			C	"Set compression/encryption mode           [$compression, Opt:\"$compress_options\"]"\
			B	"Switch double buffering on/off            [$double_buffering]"\
			S	"Set memory size for double buffering      [$ddbufsize]"\
			R	"Verify archive after writing              [$verify_archive]"\
			A	"Multivolume Archives                      [$multivolume]"\
			L	"    Set multivolume archive length        [$Mtapelength Mb]"\
			Y	"Archive type                              [$archive_format]"\
			F	"Follow backup/restore-process on screen   [$followtarops]"\
			T	"Change KBackup directory                  [$kbackdir]"\
			V	"Select device for backup                  [$device]"\
			M	"Set directory for temporary files         [$TMP]"\
			O	"Return to Options Menu" 2>$TMP/$DIALOGFILE
		then
		case	`cat $TMP/$DIALOGFILE` in
			C)	Compression_Menu
				;;
			L)	Set_TapeLength
				;;
			R)	if [ $verify_archive = YES ]
				then
					verify_archive=NO
				else
					verify_archive=YES
				fi
				;;
			Y)	if [ $archive_format = TAR ]
				then
					archive_format=AFIO
				else
					archive_format=TAR
				fi
				;;
			A)	if [ $multivolume = NO ]
				then
					set_multivolume
				else
					multivolume=NO
				fi
				;;
			E)	if [ $local = YES ] ; then
					local=NO
				else
					local=YES
				fi
				;;
			F)	if [ $followtarops = YES ] ; then
					followtarops=NO
				else
					followtarops=YES
				fi
				;;
			M)	if [ $multivolume = YES ] ; then
					multivolume=NO
				else
					set_multivolume
				fi
				;;
			I)	if [ $incremental = YES ] ; then
					incremental=NO
				else
					incremental=YES
				fi
				;;
			B)	if [ $double_buffering = YES ] ; then
					double_buffering=NO
				else
					double_buffering=YES
				fi
				;;
			D)	if dialog   --inputbox \
				"Please specify the date:\n(default: $datestamp):" 9 75 2>$TMP/$DIALOGFILE
				then
					if [ "`cat $TMP/$DIALOGFILE`" != "" ]
					then
						datestamp=`cat $TMP/$DIALOGFILE`
					fi
				fi
				;;
			S)	if dialog   --inputbox "Please specify memory size for double buffering.\n(e.g. 4096k, 207152)" \
				9 75 2>$TMP/$DIALOGFILE && test -n "`cat $TMP/$DIALOGFILE`"
				then
					ddbufsize=`cat $TMP/$DIALOGFILE`
					if [ $ddbufsize -lt 512 ] ; then
						$ddbufsize=512
					fi
				fi
				;;
			T)	if dialog   --inputbox "Please enter the KBackup directory (default: ~/$KBACKDIRDEFAULT)" \
				9 75 2>$TMP/$DIALOGFILE && test -n "`cat $TMP/$DIALOGFILE`"
				then
					kbackdir=`cat $TMP/$DIALOGFILE`
				fi
				;;
			M)	if dialog   --inputbox "Please enter the directory for temporary files:" \
				9 75 2>$TMP/$DIALOGFILE && test -n "`cat $TMP/$DIALOGFILE`"
				then
					TMP=`cat $TMP/$DIALOGFILE`
				fi
				;;
			V)	Device_Menu
				return
				;;
			O)	return
			;;
		esac
		else
			return
		fi
	done
}

AdvOptions_Menu()
{

	while : ; do
		if dialog   --title " Advanced Options Menu " --menu "\n\
The options in this menu deeply affect the operation of KBackup. You\n\
should know what you are doing before making any changes. If you are\n\
not sure, go back to the main menu and read the manual first.\n" 20 77 8 \
			D	"Toggle Directories-Only Flag              [$directoriesonly]" \
			S	"Backup only files specified               [$specifiedfilesonly]"\
			N	"    Edit list of files to include in backup" \
			I	"    Initialise list of files to include" \
			X	"Set Find-Expert Mode                      [$findxpertmode]"\
			F	"Set find-options for Find-Expert Mode"\
			E	"Set option to manually edit list of files [$manualedit]"\
			O	"Return to Options Menu" 2>$TMP/$DIALOGFILE
		then
		case	`cat $TMP/$DIALOGFILE` in
			D)	if [ $directoriesonly = YES ] ; then
					directoriesonly=NO
				else
					directoriesonly=YES
				fi
				;;
			S)	if [ $specifiedfilesonly = YES ] ; then
					specifiedfilesonly=NO
				else
					specifiedfilesonly=YES
				fi
				;;
			N)	$EDITOR $kbackdir/$configname/Include_Files
				;;
			I)	InfoBox "\nReading files..." 
				create_dir_list
				cp -f $TMP/$DIRLISTFILE $kbackdir/$configname/Include_Files
				;;
			E)	if [ $manualedit = YES ] ; then
					manualedit=NO
				else
					manualedit=YES
				fi
				;;
			X)	if [ $findxpertmode = YES ] ; then
					findxpertmode=NO
				else
					findxpertmode=YES
				fi
				;;
			F)	if dialog   --inputbox "Please enter options for find(1) command:\n(default: $findxpertflags)"\
					11 75 2>$TMP/$DIALOGFILE
				then
					if [ -n "`cat $TMP/$DIALOGFILE`" ]
					then
						$findxpertflags=`cat $TMP/$DIALOGFILE`
					fi
				fi
				;;
			O)	return
			;;
		esac
		else
			return
		fi
	done
}


Configuration_Menu()
{
	while : ; do
		if dialog   --title " Configuration Menu " --menu "\n\
Here you can set the most commonly changed options. For further confi-\n\
guring KBackup look into the \"Backup Parameters\" or the \"Advanced\n\
Options\" menus below.\n\nThe current configuration is \"$configname\".\n\
The current parent directory is \"$parent\".\n" 24 77 9 \
			P	"Set parent directory for backup/restore " \
			X	"Edit list of files to exclude" \
			E	"Set name of editor to use               [$EDITOR]" \
			B	"Set backup parameters" \
			O	"Set advanced options" \
			W	"Write a configuration file" \
			L	"Load a configuration file" \
			D	"Delete a configuration file"\
			M	"Return to main menu" 2>$TMP/$DIALOGFILE
		then
		case	`cat $TMP/$DIALOGFILE` in
			B)	Parameters_Menu
				;;
			O)	AdvOptions_Menu
				;;
			X)	$EDITOR $kbackdir/$configname/Exclude_Files
				$SED "1,$ s/^\///g" <$kbackdir/$configname/Exclude_Files >$TMP/$TMPFILE 
				cat <$TMP/$TMPFILE >$kbackdir/$configname/Exclude_Files 
				;;
			P)	choose_dir $parent
				parent=$choose_dir_result
				;;
			E)	if dialog   --inputbox "Please specify the editor you want to use:" \
					9 75 2>$TMP/$DIALOGFILE && test -n "`cat $TMP/$DIALOGFILE`"
				then
					EDITOR=`cat $TMP/$DIALOGFILE`
				fi
				;;
			W)	Check_Settings
				if dialog   --inputbox "Please specify a unique name for this configuration:" \
					9 75 2>$TMP/$DIALOGFILE && test -n "`cat $TMP/$DIALOGFILE`"
				then
					configname=`cat $TMP/$DIALOGFILE`
					save_config
				fi
				;;
			L)	find $kbackdir/* -type d -maxdepth 0 -printf "%f %Tx\n" |\
					$FGREP -v "$KBACKDIRDEFAULT" | sort >$TMP/$TMPFILE
				if dialog   --menu "Choose a configuration:" 20 60 `wc -l <$TMP/$TMPFILE` \
					`cat $TMP/$TMPFILE` 2>$TMP/$DIALOGFILE
				then
					source $kbackdir/`cat $TMP/$DIALOGFILE`/Config
				fi
				;;
			D)	find $kbackdir/* -type d -maxdepth 0 -printf "%f %Tx\n" |\
					$FGREP -v "$KBACKDIRDEFAULT" | sort >$TMP/$TMPFILE
				if dialog --menu "Choose a configuration to delete:" 20 60 `wc -l <$TMP/$TMPFILE` \
					`cat $TMP/$TMPFILE` 2>$TMP/$DIALOGFILE
				then
					rm -rf $kbackdir/`cat $TMP/$DIALOGFILE`
				fi
				;;
			M)	Check_Settings
				return
			;;
		esac
		else
			Check_Settings
			return
		fi
	done
}




Tape_Operation_Menu()
{
	if ! [ -c $device -o -L $device -o -b $device ] ; then
		ErrorBox "
You can only perform these operations on a device
that is a tape drive, not on an archive file!
"
		return
	fi
	
	while :
	do
	if dialog   --title " Operations on Tape Drives " --menu "" 16 35 7\
		R	"Rewind tape" \
		D	"Try to reset tape driver" \
		G	"Go to n-th backup on tape" \
		N	"Go to end of written data"\
		E	"Erase tape" \
		T	"Retension tape" \
		A	"Return to Actions Menu" 2>$TMP/$DIALOGFILE
	then
		case `cat $TMP/$DIALOGFILE` in
			R)	if [ -c $device -o -L $device ] ; then
					InfoBox "\nRewinding tape..." 
					mt -f $device rewind || device_err
				fi
				;;
			D)	if [ -c $device -o -L $device ] ; then
					InfoBox "\nResetting tape driver..." 
					cat <$resetdevice 2>&1 >/dev/null
				fi
				;;
			G)	if [ -c $device -o -L $device ] ; then
					if dialog   --inputbox "Please give the number of the backup to go to:" 9 75 2>$TMP/$DIALOGFILE
					then
						num=`cat $TMP/$DIALOGFILE`
						InfoBox "\nRewinding tape..." 
						mt -f $device rewind || device_err
						InfoBox "\nSearching for $num. backup..." 
						if ! mt -f $device fsf `expr \( $num - 1 \) \* $FILESPERARCHIVE`
						then
							beep
							dialog   --title "Error" --msgbox "\nCould not find $num-th backup (`expr $num \* 2`-th file) on tape!" 7 40
						fi
					fi
				fi
				;;
			N)	if [ -c $device -o -L $device ] ; then
					InfoBox "\nSearching for end of data..." 
					mt -f $device eod 2>/dev/null || device_err
				fi
				;;
			E)	beep
				if dialog   --title " DANGEROUS! " --yesno "\nDo you really want to erase the\nwhole tape?" 8 40 2>$TMP/$DIALOGFILE
				then
					InfoBox "\nErasing tape..." 
					if ! mt -f $device erase 2>/dev/null
					then
						device_err
						break
					fi
					beep
				fi
				;;
			T)	InfoBox "\nRetensioning tape..."
				if ! mt -f $device reten 2>/dev/null
				then
					device_err
					break
				fi
				;;
			A)	return
				;;
		esac
	else
		return
	fi
	done
}

Actions_Menu()
{
	while :
	do
	if dialog   --title " Actions Menu " --menu "\n\
Actions, apart from backup and restore,\nthat operate on archives.\n" 18 45 8 \
		T	"Tape Operation" \
		V	"Verify backup" \
		S	"Get backup size" \
		C	"View archive contents" \
		L	"View a logfile"\
		D	"Delete a logfile"\
		B	"Send a bug report" \
		M	"Return to main menu" 2>$TMP/$DIALOGFILE
	then
		case `cat $TMP/$DIALOGFILE` in
			V)	Verify
				;;
			C)	View_Contents
				;;
			S)	Get_BackupSize
				;;
			L)	View_Logfile
				;;
			D)	Delete_Logfile
				;;
			T)	Tape_Operation_Menu
				;;
			B)	echo -e "Subject: KBackup $VERSION bug report\n(Please fill in the form below:)\n\
			
Problem description:\n\n\n\
-------------------------- KBackup configuration: -------------------------\n\
" >$TMP/$TMPFILE

				write_settings >>$TMP/$TMPFILE
				echo -e "
-------------------------- System information: ----------------------------\n\
" >>$TMP/$TMPFILE
				uname -a >>$TMP/$TMPFILE
				cat /proc/devices >>$TMP/$TMPFILE
				$EDITOR $TMP/$TMPFILE
				if dialog --title " BUG REPORT " --yesno "
Ok to send the Bug Report to
$MAILADDRESS   ?
"	7 50			
				then
					if ! $MAIL $MAILADDRESS <$TMP/$TMPFILE
					then
						ErrorBox "
Could not send bugreport.
($MAIL missing?)
"
					else
						MsgBox "\nBugreport sent."
					fi
				fi
				;;
			M)	return
				;;
		esac
	else
		return
	fi
	done
}

view_manual()
{
	if !	dialog   --title "KBackup Online Manual" --textbox $kbackdir/manual.asc 23 78 2>/dev/null
	then
		ErrorBox "
Cannot access online manual at
$kbackdir/manual.asc
"
	fi
}


############################## MAIN MENU ###########################

Main_Menu()
{
	while : ; do
	if dialog   --title " KBackup $VERSION -- Main Menu " \
	--menu "\nThe current configuration is:\n$configname" 17 35 7 \
		C	"Configuration" \
		B	"Backup" \
		R	"Restore" \
		A	"Other Actions" \
		S	"Scheduling menu"\
		H	"Help -- view online manual" \
		X	"Exit"	2>$TMP/$DIALOGFILE
	then
		case `cat $TMP/$DIALOGFILE` in
			C)	Configuration_Menu
				;;
			A)	Actions_Menu
				;;
			B)	Backup
				;;
			R)	Restore
				;;
			S)	do_schedule
				;;
			H)	view_manual
				;;
			X)	clear
				reset
				return	
				;;
		esac
	else
		return
	fi
	done
}


################# OPTIONS PROCESSING ######################

nargs=$#
while [ $nargs -gt 0 ] 
do
	opt=$1
	case $opt in
		"--scheduled-restore")
			shift
			schedulename=$1
			shift
			configname=$schedulename
			Init
			scheduled=YES
			Restore
			unschedule
			exit
			;;
		"--scheduled-backup")
			shift
			schedulename=$1
			shift
			configname=$schedulename
			Init
			a=$configname
			configname=KKK
			save_config
			configname=$a
			scheduled=YES
			Backup
			unschedule
			exit
			;;
		*)	echo Unknown argument: $opt
			exit
			;;
	esac
done


Init



dialog   --title "Welcome to KBackup" --msgbox \
"
     #    #  ######
     #   #   #     #    ##     ####   #    #  #    #  #####
     #  #    #     #   #  #   #    #  #   #   #    #  #    #
     ###     ######   #    #  #       ####    #    #  #    #
     #  #    #     #  ######  #       #  #    #    #  #####
     #   #   #     #  #    #  #    #  #   #   #    #  #
     #    #  ######   #    #   ####   #    #   ####   #


					Revision $VERSION

	(C) 1995 by Karsten Ballder
		    (karsten.ballueder@stud.uni-karlsruhe.de)
		    
   KBackup comes with ABSOLUTELY NO WARRANTY; for details see
   the section COPYRIGHT in the manual. This is free software
   and you are welcome to redistribute it under certain con-
   ditions. If you use KBackup, don't forget to send me a post-
   card!
" 24 70

Main_Menu

cleanup

