Subject: | Error parsing continuation lines |
I am seeing a problem with the parsing of Nagios config files containing
continuation lines, e.g.
-----
# new (smarter) notifications
define command {
command_name smart-notify-by-email
command_line /nagios-plugins/local/send-mail-adv \
--destination=email \
--type=service \
--mailto='$CONTACTEMAIL$' \
--hostname='$HOSTNAME$' \
--servicedesc='$SERVICEDESC$' \
--hostaddress='$HOSTADDRESS$' \
--servicestate='$SERVICESTATE$'
}
-----
the final \ line continuation character seems to be ignored, and
the command object parser treats the above as a command object with
9 parameters (7 of which are problematic) rather that one with 2
parameters (one of which is rather long). Again, the config file
works in Nagios (3.0.6).
Attached patch should fix the problem. Attached script shows the
problem.
Encountered on (and patch tested on)
Nagios::Object::Config.pm 0.21.10
Perl 5.8.7
RedHat Enterprise Edition 5 x86_64, kernel 2.6.18-194.3.1.el5
But probably not limited to the above.
Subject: | bug.pl |
#!/usr/local/bin/perl
use strict;
use warnings;
use lib '/homes/payerle/perl/lib';
use Nagios::Object::Config;
my $TESTCFG='./bug.txt';
die "$TESTCFG already exists, not overwriting" if -f $TESTCFG;
open(TESTCFG,">$TESTCFG") or die "Unable to write $TESTCFG";
print TESTCFG <<EOF;
define command {
command_name long-command
command_line /usr/bin/longcommand \\
-options=many \\
-uses=continuation-lines
}
EOF
close(TESTCFG);
my $parser = Nagios::Object::Config->new(Version=>2, regexp_matching=>1);
$parser->parse($TESTCFG);
my $cmds = $parser->list_commands;
my $cmd = $cmds->[0];
my $cmdline = $cmd->command_line;
print $cmdline,"\n";
if ( $cmdline eq '/usr/bin/longcommand \\' )
{ print "Command line truncated\n";
} else
{ print "Command line looks OK\n";
}
unlink $TESTCFG;
Subject: | payerle.patch |
--- 0.21.10/src/lib/Nagios/Object/Config.pm 2010-03-04 11:54:40.000000000 -0500
+++ 0.21.10-patched/src/lib/Nagios/Object/Config.pm 2010-06-25 17:22:53.000000000 -0400
@@ -178,16 +178,25 @@
my ( $append, $type, $current, $in_definition ) = ( '', '', {}, undef );
while ( my $line = strippedline($fh) ) {
- # skip empty lines
- next if ( $line eq ' ' );
-
# append saved text to the current line
if ($append) {
+ $line = '' unless $line;
if ( $append !~ / $/ && $line !~ /^ / ) { $append .= ' ' }
$line = $append . $line;
$append = undef;
}
+ if ( $line && $line =~ /\\$/ )
+ { #Continued line (ends in a '\')
+ #Remove \, append to $append, and let next iteration handle it
+ $line =~ s/\s*\\$//;
+ $append = $line;
+ next;
+ }
+
+ # skip empty lines (don't do earlier because may get stuff prepended)
+ next if ( $line eq ' ' );
+
if ( $line =~ /include_file\s*=\s*([\w\-\/\\\:\.]+)/ ) {
my $incfile = $1;
$self->parse($incfile);