use FileHandle;
use Getopt::Long;
+use Text::ParseWords;
use Carp;
use POSIX;
+delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV', 'PATH'};
+$ENV{'PATH'} = "/usr/bin:/usr/sbin:/sbin:/bin";
+
sub Usage {
print STDERR <<END;
-Usage: $0 [[-config] CONFIG] [-hostwidth width] [-diskwidth width] [-skipmissed] [-verbose]
+Usage: $0 [[-config] CONFIG] [-hostwidth width] [-diskwidth width] [-skipmissed] [-last] [-num0] [-togo0] [-verbose]
This script generates to standard output an overview of the filesystems
dumped over time and the type of dump done on a particular day, such as
my $opt_hostwidth = 8;
my $opt_diskwidth = 20;
my $opt_skipmissed = 0;
+my $opt_last = 0;
+my $opt_num0 = 0;
+my $opt_togo0 = 0;
my $opt_verbose = 0;
GetOptions('config=s' => \$opt_config,
'hostwidth=i' => \$opt_hostwidth,
'diskwidth=i' => \$opt_diskwidth,
'skipmissed' => \$opt_skipmissed,
+ 'last' => \$opt_last,
+ 'num0' => \$opt_num0,
+ 'togo0' => \$opt_togo0,
'verbose' => \$opt_verbose)
or Usage();
Usage();
}
+#untaint user input $ARGV[0]
+
+if ($opt_config =~ /^([\w.-]+)$/) { # $1 is untainted
+ $opt_config = $1;
+} else {
+ die "filename '$opt_config' has invalid characters.\n";
+}
+
+
-d "$confdir/$opt_config" or
die "$0: directory `$confdir/$opt_config' does not exist.\n";
die "$0: error in opening `$amadmin $opt_config disklist' pipe: $!\n";
$/ = "";
while (<$dlfh>) {
- ($host, $disk) = m/ host (.*?):.* disk (.*?):/s;
+ ($host, $disk) = m/ host (.*?):.* disk (.*?):.*strategy (STANDARD|NOFULL|NOINC|HANOI|INCRONLY).*ignore NO/s;
next unless $host;
$disks{$host}{$disk}++;
}
next if /found Amanda directory/;
next if /skipping cruft directory/;
next if /skip-incr/;
- ($date, $host, $disk, $level, $tape, $file, $status) = split ' ', $_;
+
+ ($date, $time, $host, $disk, $level, $tape, $file, $part, $status) = shellwords($_);
+
next if $date eq 'date';
next if $date eq 'Warning:';
next if $date eq 'Scanning';
next if $date eq "";
+
+ if($time !~/^\d\d:\d\d:\d\d$/) {
+ $status = $part;
+ $part = $file;
+ $file = $tape;
+ $tape = $level;
+ $level = $disk;
+ $disk = $host;
+ $host = $time;
+ }
+
if ($date =~ /^\d\d\d\d-\d\d-\d\d$/) {
- defined($level{$host}{$disk}{$date}) or
- $level{$host}{$disk}{$date} = '';
- $level{$host}{$disk}{$date} .= ($status eq 'OK') ? $level : 'E';
- $dates{$date}++;
+ if(defined $disks{$host}{$disk}) {
+ defined($level{$host}{$disk}{$date}) or
+ $level{$host}{$disk}{$date} = '';
+ $level{$host}{$disk}{$date} .= ($status eq 'OK') ? $level : 'E';
+ $dates{$date}++;
+ }
}
else {
print "bad date $date in $_\n";
die "$0: error in closing `$amadmin $opt_config find|' pipe: $!\n";
# Process the status to arrive at a "last" status
-for $host (sort keys %disks) {
- for $disk (sort keys %{$disks{$host}}) {
- $level{$host}{$disk}{"0000-LA-ST"} = '';
- for $date (sort keys %dates) {
- if ($level{$host}{$disk}{$date} eq "E"
- && $level{$host}{$disk}{"0000-LA-ST"} =~ /^\d/ ) {
- $level{$host}{$disk}{"0000-LA-ST"} .= $level{$host}{$disk}{$date};
- } elsif ($level{$host}{$disk}{$date} eq "") {
- $level{$host}{$disk}{"0000-LA-ST"} =~ s/E//;
- } else {
- $level{$host}{$disk}{"0000-LA-ST"} = $level{$host}{$disk}{$date};
+if ($opt_last) {
+ for $host (sort keys %disks) {
+ for $disk (sort keys %{$disks{$host}}) {
+ $level{$host}{$disk}{"0000-LA-ST"} = '';
+ for $date (sort keys %dates) {
+ if ($level{$host}{$disk}{$date} eq "E"
+ && $level{$host}{$disk}{"0000-LA-ST"} =~ /^\d/ ) {
+ $level{$host}{$disk}{"0000-LA-ST"} .= $level{$host}{$disk}{$date};
+ } elsif ($level{$host}{$disk}{$date} eq "") {
+ $level{$host}{$disk}{"0000-LA-ST"} =~ s/E//;
+ } else {
+ $level{$host}{$disk}{"0000-LA-ST"} = $level{$host}{$disk}{$date};
+ }
}
- }
+ }
+ }
+}
+
+# Number of level 0 backups
+if ($opt_num0) {
+ for $host (sort keys %disks) {
+ for $disk (sort keys %{$disks{$host}}) {
+ $level{$host}{$disk}{'0000-NM-L0'} = 0;
+ for $date (sort keys %dates) {
+ if ($level{$host}{$disk}{$date} =~ /0/) {
+ $level{$host}{$disk}{'0000-NM-L0'} += 1;
+ }
+ }
+ }
+ }
+}
+
+# Runs to the last level 0
+if ($opt_togo0) {
+ for $host (sort keys %disks) {
+ for $disk (sort keys %{$disks{$host}}) {
+ $level{$host}{$disk}{'0000-TO-GO'} = 0;
+ my $togo=0;
+ for $date (sort keys %dates) {
+ if ($level{$host}{$disk}{$date} =~ /0/) {
+ $level{$host}{$disk}{'0000-TO-GO'} = $togo;
+ }
+ $togo++;
+ }
+ }
}
}
}
#Add the "last" entry
-$dates{"0000-LA-ST"}=1;
+$dates{"0000-LA-ST"}=1 if ($opt_last);
+
+#Add the "Number of Level 0s" entry
+$dates{"0000-NM-L0"}=1 if ($opt_num0);
+
+#Add the "Runs to go" entry
+$dates{"0000-TO-GO"}=1 if ($opt_togo0);
# make formats