use Data::Dumper ();
our $InFile;
-our $InDS;
+our $InDS = [];
our $OutFile;
-our $OutDS;
+our $OutDS = [];
GetOptions ("infile|i=s" => \$InFile,
- "inds|s=s" => \$InDS,
+ "inds|s=s" => sub { push (@$InDS, $_[1]); },
"outfile|o=s" => \$OutFile,
- "outds|d=s" => \$OutDS) or exit (1);
+ "outds|d=s" => sub { push (@$OutDS, $_[1]); })
+ or exit (1);
-if (!$InFile || !$OutFile || !$InDS || !$OutDS)
+if (!$InFile || !$OutFile || !@$InDS || !@$OutDS)
{
- print "$InFile $InDS $OutFile $OutDS\n";
- print STDERR "Usage: $0 -i <infile> -I <inds> -o <outfile> -O <outds>\n";
+ print STDERR "Usage: $0 -i <infile> -s <inds> -o <outfile> -d <outds>\n";
exit (1);
}
if (!-f $InFile)
print STDERR "Output file does exist\n";
exit (1);
}
+if ((1 + @$InDS) != (1 + @$OutDS))
+{
+ print STDERR "You need the same amount of in- and out-DSes\n";
+ exit (1);
+}
-extract_ds ($InFile, $OutFile, $InDS, $OutDS);
+extract_ds ($InFile, $OutFile);
exit (0);
{
-my $ds_index = -1;
-my $current_index = -1;
+my $ds_index;
+my $current_index;
# state 0 == searching for DS index
# state 1 == parse RRA header
-# state 2 == parse <ds> in RRA header
-# state 3 == parse values
-my $state = 0;
-my $out_cache = '';
+# state 2 == parse values
+my $state;
+my $out_cache;
sub handle_line
{
my $fh = shift;
if (!defined ($state))
{
- $ds_index = -1;
$current_index = -1;
$state = 0;
- $out_cache = '';
+ $out_cache = [];
+
+ # $ds_index->[new_index] = old_index
+ $ds_index = [];
+ for (my $i = 0; $i < @$InDS; $i++)
+ {
+ $ds_index->[$i] = -1;
+ }
}
if ($state == 0)
{
if ($line =~ m/<ds>/)
{
- $out_cache = $line;
$current_index++;
+ $out_cache->[$current_index] = $line;
}
elsif ($line =~ m#<name>\s*([^<\s]+)\s*</name>#)
{
- if ($1 eq $InDS)
+ # old_index == $current_index
+ # new_index == $i
+ for (my $i = 0; $i < @$InDS; $i++)
{
- $ds_index = $current_index;
- $out_cache .= "\t\t<name>$OutDS</name>\n";
+ next if ($ds_index->[$i] >= 0);
+
+ if ($1 eq $InDS->[$i])
+ {
+ $line =~ s#<name>\s*([^<\s]+)\s*</name>#<name> $OutDS->[$i] </name>#;
+ $ds_index->[$i] = $current_index;
+ last;
+ }
}
+
+ $out_cache->[$current_index] .= $line;
}
elsif ($line =~ m#</ds>#)
{
- $out_cache .= $line;
- if ($ds_index == $current_index)
- {
- print $fh $out_cache;
- }
+ $out_cache->[$current_index] .= $line;
}
elsif ($line =~ m#<rra>#)
{
+ # Print out all the DS definitions we need
+ for (my $new_index = 0; $new_index < @$InDS; $new_index++)
+ {
+ my $old_index = $ds_index->[$new_index];
+ print $fh $out_cache->[$old_index];
+ }
+
+ # Clear the cache - it's used in state1, too.
+ for (my $i = 0; $i <= $current_index; $i++)
+ {
+ $out_cache->[$i] = '';
+ }
+
print $fh $line;
$current_index = -1;
$state = 1;
}
elsif ($current_index == -1)
{
+ # Print all the lines before the first DS definition
print $fh $line;
}
else
{
- $out_cache .= $line;
+ # Something belonging to a DS-definition
+ $out_cache->[$current_index] .= $line;
}
}
elsif ($state == 1)
if ($line =~ m#<ds>#)
{
$current_index++;
- if ($current_index == $ds_index)
+ $out_cache->[$current_index] .= $line;
+ }
+ elsif ($line =~ m#</cdp_prep>#)
+ {
+ # Print out all the DS definitions we need
+ for (my $new_index = 0; $new_index < @$InDS; $new_index++)
{
- print $fh $line;
+ my $old_index = $ds_index->[$new_index];
+ print $fh $out_cache->[$old_index];
+ }
+
+ # Clear the cache
+ for (my $i = 0; $i <= $current_index; $i++)
+ {
+ $out_cache->[$i] = '';
}
- if ($line =~ m#</ds>#) { $state = 1; }
- else { $state = 2; }
- }
- elsif ($line =~ m#<database>#)
- {
print $fh $line;
- $state = 3;
+ $current_index = -1;
}
- else
+ elsif ($line =~ m#<database>#)
{
print $fh $line;
+ $state = 2;
}
- }
- elsif ($state == 2)
- {
- if ($current_index == $ds_index)
+ elsif ($current_index == -1)
{
- print STDERR $line;
+ # Print all the lines before the first DS definition
+ # and after cdp_prep
print $fh $line;
}
- if ($line =~ m#</ds>#)
+ else
{
- $state = 1;
+ # Something belonging to a DS-definition
+ $out_cache->[$current_index] .= $line;
}
}
- else
+ elsif ($state == 2)
{
if ($line =~ m#</database>#)
{
}
else
{
- my $line_begin = "\t\t";
- $current_index = 0;
+ my @values = ();
+ my $i;
+ my $output = "\t\t";
+
if ($line =~ m#(<!-- .*? -->)#)
{
- $line_begin .= "$1 ";
+ $output .= "$1 ";
}
+ $output .= "<row> ";
- while ($line =~ m#<v>\s*([^<\s]+)\s*</v>#)
+ $i = 0;
+ while ($line =~ m#<v>\s*([^<\s]+)\s*</v>#g)
{
- my $value = $1;
- if ($current_index == $ds_index)
- {
- print $fh "$line_begin<row> <v>$value</v> </row>\n";
- last;
- }
- $current_index++;
+ $values[$i] = $1;
+ $i++;
}
+
+ for (my $new_index = 0; $new_index < @$InDS; $new_index++)
+ {
+ my $old_index = $ds_index->[$new_index];
+ $output .= '<v> ' . $values[$old_index] . ' </v> ';
+ }
+ $output .= "</row>\n";
+ print $fh $output;
}
}
+ else
+ {
+ die;
+ }
}} # handle_line
sub extract_ds
{
my $in_file = shift;
my $out_file = shift;
- my $in_ds = shift;
- my $out_ds = shift;
my $in_fh;
my $out_fh;
open ($in_fh, '-|', 'rrdtool', 'dump', $in_file) or die ("open (rrdtool): $!");
- open ($out_fh, '|-', 'rrdtool', 'restore', '-', $out_file) or die ("open (rrdtool): $!");
+# open ($out_fh, '|-', 'rrdtool', 'restore', '-', $out_file) or die ("open (rrdtool): $!");
+ $out_fh = \*STDOUT;
while (my $line = <$in_fh>)
{