#!/usr/local/bin/perl -w
# 
# @ARGV:
#  0 = STDERR path name
#  1 = tape VSN:file#
#  2 = file system list

use File::Basename;
use POSIX;
use subs qw/fin ini print_report sys/;
use strict;

our ($DB, %DB, $VSN, @VSNS);

my $pid = fork;
if ($pid) {			# parent
    exit;
} elsif (not defined $pid) {
    die "fork() failed: $?";
}

ini;

my $n = 0;

while (<STDIN>) {
    next if /^$?/ or /^\s*$/;
    next if /^Unloading Data Transfer Element/;
    if ( /^tar:/ ) {
	print ERR $_;
	next;
    }
    if (/^  Storage Changer/) {
	my ($nslots) = /(\d+) Slots/;
	$_ = <STDIN>;
	($VSN) = /VolumeTag = (\S+)/;
	$VSN = uc $VSN;
	push @VSNS, $VSN;
	<STDIN> for 1 .. $nslots;
	next;
    }
    last if /^Total bytes written/;

    # Save stat info.
    
    $n++;
    chomp;

    my (@s) = lstat "/$_";

    #  0 dev      device number of filesystem
    #  1 ino      inode number
    #  2 mode     file mode  (type and permissions)
    #  3 nlink    number of (hard) links to the file
    #  4 uid      numeric user ID of file's owner
    #  5 gid      numeric group ID of file's owner
    #  6 rdev     the device identifier (special files only)
    #  7 size     total size of file, in bytes
    #  8 atime    last access time in seconds since the epoch
    #  9 mtime    last modify time in seconds since the epoch
    # 10 ctime    inode change time (NOT creation time!)
    # 11 blksize  preferred block size for file system I/O
    # 12 blocks   actual number of blocks allocated

    if ( not defined $s[7] ) {	# assume special chars > 255
	while ( 1 ) {
	    my ($sc) = /(\\\d+)/;
	    last unless defined $sc;
	    $sc =~ s/\\//;
	    my $ch = chr oct($sc);
	    s/\\\d+/$ch/;
	}
	@s = lstat "/$_";
    }

    if ( not defined $s[7] ) {	# assume escaped Win32 backslashes
	s/\\\\/\\/g;
	@s = lstat "/$_";
    }
	
    print STDERR "UNDEF=$_, s=@s!\n" unless defined $s[7];
    $DB{$_} = "$VSN " . scalar(localtime($s[9])) . " $s[7]";
}

print_report $_;

fin;

sub fin {
    print DB "\nBackup complete, ", `date`;
    close DB;
    close ERR;
}

sub ini {
    open ERR, ">>$ARGV[0]" or die "Cannot write $ARGV[0]: $?";
    $VSN = uc $ARGV[1];
    push @VSNS, $VSN;
    $DB = "/root/admin/backup/db/$VSN.gz";
    open DB, "| /bin/gzip > $DB " or die "DB open failed: $!";
    print DB "Backup start,    ", `date`;
    %DB = ();
}

sub print_report {

    print DB "\nDatabase Report For Tape(s) @VSNS - ", `date`, "\n";
    print DB "backup_list = ", $ARGV[2], "\n";
    foreach my $file (sort keys %DB) {
	printf DB "%-72s = %s\n", $file, $DB{$file};
    }
    print DB "\n$_[0]";
}

sub sys {
    my $cmd = shift;
    system $cmd;
    die "Failed : '$cmd' : $?" if $?;
}
