#! /usr/local/bin/perl
# 
# Object:
# 	Users should be able to back up their own files.  Package to do so needs
# 	to do the following:
# 	1.	Label the tape.  This label controls the access to the tape.
# 		E.g. if the tape label is not marked for group to read,  other 
# 		users cannot read the tape.  (Writing & reading 
#		currently limited to owners only.)
# 	2.	For each user, keep a record what's on that tape.
# 	3.	Enable users to append information onto a tape.
# 	4.	Keep track of the how much space remains on the tape.  
#	(Not yet implemented)
# 	5.	Make it reasonable for users to recover items from a tape.  
#	(Separate Script)(Not yet implemented)
# 
# Algolrithms & methods
#	The backup machine has a registry of tapes, 
#	Users can label a blank tape with the 
#	/usr/local/bin/LabelTape program. 
#	See that script for details.
#
#	Each user has a directory ~/backups, that belongs to root.
#	In that directory, every time a tar file is put on tape, 
#	the package creates a log file with a list of the contents 
#	of the tar file. This makes it easy for users to keep track 
#	of what they have. 

#	
# 	TapeLibrary sets up the drive, and does a bunch of initialization.

require("TapeLibrary.perl");
$BackupType="Private ";


# Define labels, strings, and so on.

@DirList = @ARGV;
if ($DirList[0] eq "-V") {
	print "VERIFY PASS ONLY  NO BACKUPS WILL BE MADE \n\n";
	$VERIFYONLY = true;
	shift @DirList;
	}
$udir = $ENV{HOME};
if ($udir eq "") { print "No home directory.\n"; &Quit;}
$backdir = $udir."/".backups;
$pwd = `pwd`;
chop($pwd);

# Check that the user has a directory for log files
	if ( ! -d $backdir ) {
		print "You do not have a directory for logging backup results.\n";
		print "        See your System Administrator.\n";
		&Quit;
		}	

# 	Check that all the directories asked for actually exist.
#	Will check as an absolute path, relative to current path, 
#   then relative to home directory.

	$ok = true;
	print " \n Checking to see that everything you want to  \n";
	print " backup actually exists.  (Humans are such rotten typists...)\n\n";
	foreach $DirList ( @DirList ){
		#print $DirList, "\n";		
		if ( substr($DirList,0,1) eq "/") {
			#print "$DirList is an absolute path \n";
			next;
			}	
		if (-e $DirList ) {
			#print "$DirList is relative to current directory  \n";
			$DirList = $pwd."/".$DirList;
			next;
			}	
		if (-e $udir."/".$DirList){
			#print "$DirList is relative to home directory  \n";
			$DirList = $udir."/".$DirList;
			next;
			}
		else {
			print "Humble Tape Servant is unable to find $DirList\n";
			print "Perhaps the great one has made a tiny typing error.\n\n";
			print "The learned master is reminded that directories \n" ;
			print "must be relative to his home directory,\n" ;
			print "the current directory, or must be absolute paths.\n\n";
			&Quit;
			}
		}	#End while -- All DirList now converted to absolute path names.

	#	Now we check that the user owns the directories in question.
	#	He's bumped if he doesn't own the directory.
	
	foreach $DirList ( @DirList ){
		if (! -o $DirList) {
			print "Least worthy servant has discovered that the \n";
			print "directory $DirList exists, but you do not own it.\n";
			print "Must humbly decline making this copy.\n\n";
			&Quit;
			}
		else {
			print "Verified existence & ownership of ", $DirList, "\n";
			}
		}
	print "\n Hit y,Y, or <CR> to proceed, anything else to abort:  ";
	$answer = getc;
	$answer =~ tr/yY\n/Y/;
	if ($answer ne "Y") { &Quit; }

#
# =========================
#
# 	Read Volume label
#
	$tapelabel=&CheckVolumeLabel($Code);
	print "Tape is labeled $tapelabel\n";
#
#	Check the label

#	A series of checks are made.  CheckVolumeLabel tries to read 
#	the first file on the tape.  If that returns blank, or more than a 
#	single line, or a single line that doesn't match with the name of tape, 
#	or a tape name that is not owned by the user, then the user is bumped. 

	if ($Code == 100 ) {
		print "Verified that this tape is registered on this server.\n";
		print "Verified that $user owns this tape. \n";
		}
	if ($Code == 101 ) {
  		print "Begging forgiveness for rude interuption but this tape has no label.\n";
		print "Humble tar slave is not permitted to write to an unlabeled tape.\n\n";
		&Quit(102);
		}
	if ( ! -e "/usr/local/tapelabels/$tapelabel" ) {
  		print "Excuse Interuption, but this label is not registered\n";
		print "Cannot write to unregistered tape.  \n";
		&Quit(101);
		}
	if ( ! -o "/usr/local/tapelabels/$tapelabel" ) {
  		print "Most Humble Apologies, but you do appear to own this tape.\n";
		print "Only the Owner can write on a tape.\n";
		&Quit(102);
		}

#	Check that the user has a backups directory.  This should be owned
#	by root to prevent users from deleting the log files, which is how
#	we keep track of how many files are on the tape.

	chdir $udir; 
	if ( ! -d  $backdir ) {
		print "You don\'t have a backup logging directory";
		print "Logging will fail, and everyone will get confused";
		print "See Y.F.N.S.A. for assistance.";
		&Quit;
		}

#		Position the tape to the current end of tape.

#		Since Next doesn't implement an mt eom command (shame!)
#	we instead count the number of log files that already refer 
#	to this tape, and space forward appropriately.  This can 
#	cause trouble if the script is aborted during the Verify pass.

	$FilesOnTape=`ls -1 ${backdir}/${tapelabel}-* | wc -l`;
	chop($FilesOnTape);	
	$tarnum = $FilesOnTape;
	if 	( $tarnum == "0" ) {
		print "\nNo previous data is registered on this tape.\n";
		print "       Proceeding with backup. \n";
		}
	else{
		print "This tape has $tarnum file(s) on it already.\n"; 
		print "     Moving past these files...\n\n";
		}
#
#	So we move forward the number of backups on the tape + 1 for the tapelabel
#	But Verify does one, so we do tarnum now, and the other one after
#	the VerifyOnly branch

#label.  
	&ForwardSpaceTape( $tarnum );
	if ($ErrorCode != 200) {
		print "Failed to move past existing files on tape.\n";
		print "Error Code: $ErrorCode.\n";
		&ErrorTranslate($ErrorCode);
		&Quit;
		}

	if ($VERIFYONLY) {goto VERIFY;}
	&ForwardSpaceTape(1);

#
# and then back to the front end of the tapemark.
# We erase, because this may be a restarted script.
#
	&BackSpaceTape(1);
	&EraseRestOfTape;
		
# Ok, tape is positioned, now make the backups.
# Each backup is made from the parent directory of it,
# to make it easier to place recovered files in arbitrary places.
#
	foreach $direct ( @DirList ){
		print "\n\nStarting backup of directory $direct. \n";
		# $DirList has been converted to absolute pathnames.
		&TarDir($direct);
	}	# End Foreach

# 	=========================================================	#
#				Reposition tape and compare
# 	=========================================================	#
print "Backing up to today's starting point.\n";
$BErrorCode = &BackSpaceTape($tarnum - $FilesOnTape +1 );

#+1? Yeah.  After writing, the tape is just after a tape mark. 
# So it takes 1 to get at the front of that mark, then one for each
# of the tars added (tarnum - filesontape)

$tarnum =  $FilesOnTape;
# Tarnum should always be the number of marks to move, from the beginning
#of the tape to get to the mark immediately before the current working
#location. 
#At this point we should be at the BOT side of the tape of the last tar
#previously written on the tape.  Remember that verify starts with an fsf.

		
VERIFY:{	
	foreach $direct ( @DirList ){
		&VerifyDir($backdir,$direct);
		}	# End Foreach
	}	# End VERIFY

# =========================
#
#  Housekeeping:
# Take tape offline.
#
	print "Ok, all done.  Please pick up your tape.\n";
	&Quit(0);
#

