- next if (exists($params{'status'})
- and $find_result->{'status'} ne $params{'status'});
-
- # start setting up a dumpfile hash for this result
- my %dumpfile = (
- 'write_timestamp' => $write_timestamp,
- 'dump_timestamp' => zeropad($find_result->{'timestamp'}),
- 'hostname' => $find_result->{'hostname'},
- 'diskname' => $find_result->{'diskname'},
- 'level' => $find_result->{'level'},
- 'label' => $find_result->{'label'},
- 'filenum' => $find_result->{'filenum'},
- 'status' => $find_result->{'status'},
- 'sec' => $find_result->{'sec'},
- 'kb' => $find_result->{'kb'},
- );
-
- # partnum and nparts takes some special interpretation
- if (my ($partnum, $nparts) = $find_result->{'partnum'} =~ m$(\d+)/(-?\d+)$) {
- $dumpfile{'partnum'} = $partnum+0;
- $dumpfile{'nparts'} = $nparts+0;
+ if ($get_what eq 'parts') {
+ next if (exists($params{'status'})
+ and $find_result->{'status'} ne $params{'status'});
+ }
+
+ # filter each result against dumpspecs, to avoid dumps_match_dumpspecs'
+ # tendency to produce duplicate results
+ next if ($params{'dumpspecs'}
+ and !Amanda::Logfile::dumps_match_dumpspecs([$find_result],
+ $params{'dumpspecs'}, 0));
+
+ my $dump_timestamp = zeropad($find_result->{'timestamp'});
+
+ my $dumpkey = join("\0", $find_result->{'hostname'}, $find_result->{'diskname'},
+ $write_timestamp, $find_result->{'level'});
+ my $dump = $dumps{$dumpkey};
+ if (!defined $dump) {
+ $dump = $dumps{$dumpkey} = {
+ dump_timestamp => $dump_timestamp,
+ write_timestamp => $write_timestamp,
+ hostname => $find_result->{'hostname'},
+ diskname => $find_result->{'diskname'},
+ level => $find_result->{'level'}+0,
+ orig_kb => $find_result->{'orig_kb'},
+ status => $find_result->{'dump_status'},
+ message => $find_result->{'message'},
+ # the rest of these params are unknown until we see a taper
+ # DONE, PARTIAL, or FAIL line, although we count nparts
+ # manually instead of relying on the logfile
+ nparts => 0,
+ kb => -1,
+ sec => -1,
+ };
+ }
+
+ # start setting up a part hash for this result
+ my %part;
+ if ($logfile ne 'holding') {
+ # on-media dump
+ %part = (
+ label => $find_result->{'label'},
+ filenum => $find_result->{'filenum'},
+ dump => $dump,
+ status => $find_result->{'status'},
+ sec => $find_result->{'sec'},
+ kb => $find_result->{'kb'},
+ orig_kb => $find_result->{'orig_kb'},
+ partnum => $find_result->{'partnum'},
+ );
+ } else {
+ # holding disk
+ %part = (
+ holding_file => $find_result->{'label'},
+ dump => $dump,
+ status => $find_result->{'status'},
+ sec => 0.0,
+ kb => $find_result->{'kb'},
+ orig_kb => $find_result->{'orig_kb'},
+ partnum => 1,
+ );
+ # and fix up the dump, too
+ $dump->{'status'} = $find_result->{'status'};
+ $dump->{'kb'} = $find_result->{'kb'};
+ $dump->{'sec'} = $find_result->{'sec'};
+ }
+
+ # weaken the dump ref if we're returning dumps
+ weaken_ref($part{'dump'})
+ if ($get_what eq 'dumps');
+
+ # count the number of successful parts in the dump
+ $dump->{'nparts'}++ if $part{'status'} eq 'OK';
+
+ # and add a ref to the array of parts; if we're getting
+ # parts, then this is a weak ref
+ $dump->{'parts'}[$part{'partnum'}] = \%part;
+ weaken_ref($dump->{'parts'}[$part{'partnum'}])
+ if ($get_what eq 'parts');
+
+ push @parts, \%part;
+ }
+
+ # if these dumps were on the holding disk, then we're done
+ next if $logfile eq 'holding';
+
+ # re-read the logfile to extract dump-level info that's not captured by
+ # search_logfile
+ my $logh = Amanda::Logfile::open_logfile("$logfile_dir/$logfile");
+ die "logfile '$logfile' not found" unless $logh;
+ while (my ($type, $prog, $str) = Amanda::Logfile::get_logline($logh)) {
+ next unless $prog == $P_TAPER;
+ my $status;
+ if ($type == $L_DONE) {
+ $status = 'OK';
+ } elsif ($type == $L_PARTIAL) {
+ $status = 'PARTIAL';
+ } elsif ($type == $L_FAIL) {
+ $status = 'FAIL';
+ } else {
+ next;
+ }
+
+ # now extract the appropriate info; luckily these log lines have the same
+ # format, more or less
+ my ($hostname, $diskname, $dump_timestamp, $nparts, $level, $secs, $kb, $message);
+ ($hostname, $str) = Amanda::Util::skip_quoted_string($str);
+ ($diskname, $str) = Amanda::Util::skip_quoted_string($str);
+ ($dump_timestamp, $str) = Amanda::Util::skip_quoted_string($str);
+ if ($status ne 'FAIL') {
+ ($nparts, $str) = Amanda::Util::skip_quoted_string($str);
+ } else {
+ $nparts = 0;
+ }
+ ($level, $str) = Amanda::Util::skip_quoted_string($str);
+ if ($status ne 'FAIL') {
+ my $s = $str;
+ ($secs, $kb, $str) = ($str =~ /^\[sec ([0-9.]+) kb (\d+) .*\] ?(.*)$/)
+ or die("'$s'");
+ }
+ if ($status ne 'OK') {
+ $message = $str;