From: Sebastian Harl Date: Thu, 19 Feb 2009 11:09:46 +0000 (+0100) Subject: contrib/cussh.pl: Fixed and improved command parsing. X-Git-Tag: collectd-4.5.3~2 X-Git-Url: https://git.octo.it/?p=collectd.git;a=commitdiff_plain;h=937fc4f2d1721b29b1ad4321ac623bbc9699fd2f contrib/cussh.pl: Fixed and improved command parsing. The input line is now split into separate tokens which are either quoted or unquoted strings. This simplifies e.g. the parsing of identifiers as the whole token may be interpreted as just the id string. This allows for specifying a somewhat greedy regex which before led to the whole remainder of the input line ending up in the type or type instance. --- diff --git a/contrib/cussh.pl b/contrib/cussh.pl index 47c72c33..c143aea3 100755 --- a/contrib/cussh.pl +++ b/contrib/cussh.pl @@ -110,13 +110,42 @@ use Collectd::Unixsock(); exit 0; } +sub tokenize { + my $line = shift || return; + my $line_ptr = $line; + my @line = (); + + my $token_pattern = qr/[^"\s]+|"[^"]+"/; + + while (my ($token) = $line_ptr =~ m/^($token_pattern)\s+/) { + $line_ptr = $'; + push @line, $token; + } + + if ($line_ptr =~ m/^$token_pattern$/) { + push @line, $line_ptr; + } + else { + my ($token) = split m/ /, $line_ptr, 1; + print STDERR "Failed to parse line: $line\n"; + print STDERR "Parse error near token \"$token\".\n"; + return; + } + + foreach my $l (@line) { + if ($l =~ m/^"(.*)"$/) { + $l = $1; + } + } + return @line; +} + sub getid { my $string = shift || return; - print $$string . $/; my ($h, $p, $pi, $t, $ti) = - $$string =~ m#^([^/]+)/([^/-]+)(?:-([^/]+))?/([^/-]+)(?:-([^/]+))?\s*#; - $$string = $'; + $string =~ m#^([^/]+)/([^/-]+)(?:-([^/]+))?/([^/-]+)(?:-([^/]+))?\s*#; + $string = $'; return if ((! $h) || (! $p) || (! $t)); @@ -172,7 +201,7 @@ HELP return 1; } # cmd_help -=item B I +=item B I I =cut @@ -180,12 +209,24 @@ sub putval { my $sock = shift || return; my $line = shift || return; - my $id = getid(\$line); + my @line = tokenize($line); + my $id; my $ret; + if (! @line) { + return; + } + + if (scalar(@line) < 2) { + print STDERR "Synopsis: PUTVAL [ ...]" . $/; + return; + } + + $id = getid($line[0]); + if (! $id) { - print STDERR "Invalid id \"$line\"." . $/; + print STDERR "Invalid id \"$line[0]\"." . $/; return; } @@ -198,7 +239,7 @@ sub putval { return $ret; } -=item B I I +=item B I =cut @@ -206,14 +247,28 @@ sub getval { my $sock = shift || return; my $line = shift || return; - my $id = getid(\$line); + my @line = tokenize($line); + + my $id; + my $vals; + + if (! @line) { + return; + } + + if (scalar(@line) < 1) { + print STDERR "Synopsis: GETVAL " . $/; + return; + } + + $id = getid($line[0]); if (! $id) { - print STDERR "Invalid id \"$line\"." . $/; + print STDERR "Invalid id \"$line[0]\"." . $/; return; } - my $vals = $sock->getval(%$id); + $vals = $sock->getval(%$id); if (! $vals) { print STDERR "socket error: " . $sock->{'error'} . $/; @@ -234,6 +289,8 @@ sub flush { my $sock = shift || return; my $line = shift; + my @line = tokenize($line); + my $res; if (! $line) { @@ -242,7 +299,7 @@ sub flush { else { my %args = (); - foreach my $i (split m/ /, $line) { + foreach my $i (@line) { my ($option, $value) = $i =~ m/^([^=]+)=(.+)$/; next if (! ($option && $value)); @@ -282,9 +339,15 @@ sub flush { sub listval { my $sock = shift || return; + my $line = shift; my @res; + if ($line ne "") { + print STDERR "Synopsis: LISTVAL" . $/; + return; + } + @res = $sock->listval(); if (! @res) { @@ -306,16 +369,20 @@ sub putnotif { my $sock = shift || return; my $line = shift || return; + my @line = tokenize($line); + my $ret; my (%values) = (); - foreach my $i (split m/ /, $line) { - my($key,$val) = split m/=/, $i, 2; + foreach my $i (@line) { + my ($key, $val) = split m/=/, $i, 2; if ($key && $val) { $values{$key} = $val; } else { - $values{'message'} .= ' '.$key; + $values{'message'} = defined($values{'message'}) + ? ($values{'message'} . ' ' . $key) + : $key; } } $values{'time'} ||= time();