diff options
Diffstat (limited to 'lib/Nagios')
-rw-r--r-- | lib/Nagios/Plugin/Functions.pm | 4 | ||||
-rw-r--r-- | lib/Nagios/Plugin/Performance.pm | 185 | ||||
-rw-r--r-- | lib/Nagios/Plugin/Range.pm | 44 | ||||
-rw-r--r-- | lib/Nagios/Plugin/Threshold.pm | 43 |
4 files changed, 188 insertions, 88 deletions
diff --git a/lib/Nagios/Plugin/Functions.pm b/lib/Nagios/Plugin/Functions.pm index 43f371c..513501b 100644 --- a/lib/Nagios/Plugin/Functions.pm +++ b/lib/Nagios/Plugin/Functions.pm | |||
@@ -343,8 +343,6 @@ If join_all is supplied, however, it will be used as a string to | |||
343 | join the resultant critical, warning, and ok messages together i.e. | 343 | join the resultant critical, warning, and ok messages together i.e. |
344 | all messages are joined and returned. | 344 | all messages are joined and returned. |
345 | 345 | ||
346 | =back | ||
347 | |||
348 | =item get_shortname | 346 | =item get_shortname |
349 | 347 | ||
350 | Return the default shortname used for this plugin i.e. the first | 348 | Return the default shortname used for this plugin i.e. the first |
@@ -357,8 +355,6 @@ with any leading 'CHECK_' and trailing file suffixes removed. | |||
357 | get_shortname is not exported by default, so must be explicitly | 355 | get_shortname is not exported by default, so must be explicitly |
358 | imported. | 356 | imported. |
359 | 357 | ||
360 | =back | ||
361 | |||
362 | =item max_state(@a) | 358 | =item max_state(@a) |
363 | 359 | ||
364 | Returns the worst state in the array. Order is: CRITICAL, WARNING, OK, UNKNOWN, | 360 | Returns the worst state in the array. Order is: CRITICAL, WARNING, OK, UNKNOWN, |
diff --git a/lib/Nagios/Plugin/Performance.pm b/lib/Nagios/Plugin/Performance.pm index fc1c0bc..1f036f2 100644 --- a/lib/Nagios/Plugin/Performance.pm +++ b/lib/Nagios/Plugin/Performance.pm | |||
@@ -6,41 +6,49 @@ use strict; | |||
6 | use warnings; | 6 | use warnings; |
7 | 7 | ||
8 | use Carp; | 8 | use Carp; |
9 | use Nagios::Plugin::Threshold; | 9 | use base qw(Class::Accessor::Fast); |
10 | Nagios::Plugin::Performance->mk_ro_accessors( | ||
11 | qw(label value uom warning critical min max) | ||
12 | ); | ||
13 | |||
10 | use Nagios::Plugin::Functions; | 14 | use Nagios::Plugin::Functions; |
15 | use Nagios::Plugin::Threshold; | ||
16 | use Nagios::Plugin::Range; | ||
11 | our ($VERSION) = $Nagios::Plugin::Functions::VERSION; | 17 | our ($VERSION) = $Nagios::Plugin::Functions::VERSION; |
12 | 18 | ||
13 | use Class::Struct; | ||
14 | struct "Nagios::Plugin::Performance" => { | ||
15 | label => '$', | ||
16 | value => '$', | ||
17 | uom => '$', | ||
18 | threshold => 'Nagios::Plugin::Threshold', | ||
19 | min => '$', | ||
20 | max => '$', | ||
21 | }; | ||
22 | |||
23 | sub perfoutput { | ||
24 | my $self = shift; | ||
25 | my $output = $self->label."=".$self->value. ($self->uom || "") .";".$self->threshold->warning.";".$self->threshold->critical; | ||
26 | return $output; | ||
27 | } | ||
28 | |||
29 | sub _parse { | 19 | sub _parse { |
30 | my $class = shift; | 20 | my $class = shift; |
31 | my $string = shift; | 21 | my $string = shift; |
32 | my $p = $class->new; | ||
33 | $string =~ s/^([^=]+)=([\d\.]+)(\w*);?([\d\.]+)?;?([\d\.]+)?;?([\d\.]+)?;?([\d\.]+)?\s*//; | 22 | $string =~ s/^([^=]+)=([\d\.]+)(\w*);?([\d\.]+)?;?([\d\.]+)?;?([\d\.]+)?;?([\d\.]+)?\s*//; |
34 | return undef unless ((defined $1 && $1 ne "") && (defined $2 && $2 ne "")); | 23 | return undef unless ((defined $1 && $1 ne "") && (defined $2 && $2 ne "")); |
35 | $p->label($1); | 24 | my $p = $class->new( |
36 | $p->value($2+0); | 25 | label => $1, value => $2+0, uom => $3, warning => $4, critical => $5, |
37 | $p->uom($3); | 26 | min => $6, max => $7 |
38 | $p->threshold(Nagios::Plugin::Threshold->set_thresholds(warning => $4, critical => $5)); | 27 | ); |
39 | $p->min($6); | ||
40 | $p->max($7); | ||
41 | return ($p, $string); | 28 | return ($p, $string); |
42 | } | 29 | } |
43 | 30 | ||
31 | # Map undef to '' | ||
32 | sub _nvl { | ||
33 | my ($self, $value) = @_; | ||
34 | defined $value ? $value : '' | ||
35 | } | ||
36 | |||
37 | sub perfoutput { | ||
38 | my $self = shift; | ||
39 | my $out = sprintf "%s=%s%s;%s;%s;%s;%s", | ||
40 | $self->label, | ||
41 | $self->value, | ||
42 | $self->_nvl($self->uom), | ||
43 | $self->_nvl($self->warning), | ||
44 | $self->_nvl($self->critical), | ||
45 | $self->_nvl($self->min), | ||
46 | $self->_nvl($self->max); | ||
47 | # Previous implementation omitted trailing ;; - do we need this? | ||
48 | $out =~ s/;;$//; | ||
49 | return $out; | ||
50 | } | ||
51 | |||
44 | sub parse_perfstring { | 52 | sub parse_perfstring { |
45 | my ($class, $perfstring) = @_; | 53 | my ($class, $perfstring) = @_; |
46 | my @perfs; | 54 | my @perfs; |
@@ -58,8 +66,9 @@ sub rrdlabel { | |||
58 | my $name = $self->label; | 66 | my $name = $self->label; |
59 | if ($name eq "/") { | 67 | if ($name eq "/") { |
60 | $name = "root"; | 68 | $name = "root"; |
69 | } | ||
61 | # If filesystem name, remove initial / and convert subsequent "/" to "_" | 70 | # If filesystem name, remove initial / and convert subsequent "/" to "_" |
62 | } elsif ($name =~ s/^\///) { | 71 | elsif ($name =~ s/^\///) { |
63 | $name =~ s/\//_/g; | 72 | $name =~ s/\//_/g; |
64 | } | 73 | } |
65 | # Convert bad chars | 74 | # Convert bad chars |
@@ -68,84 +77,150 @@ sub rrdlabel { | |||
68 | return substr( $name, 0, 19 ); | 77 | return substr( $name, 0, 19 ); |
69 | } | 78 | } |
70 | 79 | ||
80 | # Backward compatibility: create a threshold object on the fly as requested | ||
81 | sub threshold | ||
82 | { | ||
83 | my $self = shift; | ||
84 | return Nagios::Plugin::Threshold->set_thresholds( | ||
85 | warning => $self->warning, critical => $self->critical | ||
86 | ); | ||
87 | } | ||
88 | |||
89 | # Constructor - unpack thresholds, map args to hashref | ||
90 | sub new | ||
91 | { | ||
92 | my $class = shift; | ||
93 | my %arg = @_; | ||
94 | |||
95 | # Convert thresholds | ||
96 | if (my $threshold = delete $arg{threshold}) { | ||
97 | $arg{warning} ||= $threshold->warning . ""; | ||
98 | $arg{critical} ||= $threshold->critical . ""; | ||
99 | } | ||
100 | |||
101 | $class->SUPER::new(\%arg); | ||
102 | } | ||
103 | |||
71 | 1; | 104 | 1; |
105 | |||
72 | __END__ | 106 | __END__ |
73 | 107 | ||
74 | =head1 NAME | 108 | =head1 NAME |
75 | 109 | ||
76 | Nagios::Plugin::Performance - Performance information in a perl object | 110 | Nagios::Plugin::Performance - class for handling Nagios::Plugin |
111 | performance data. | ||
77 | 112 | ||
78 | =head1 SYNOPSIS | 113 | =head1 SYNOPSIS |
79 | 114 | ||
80 | use Nagios::Plugin::Performance; | 115 | use Nagios::Plugin::Performance; |
81 | 116 | ||
82 | @p = Nagios::Plugin::Performance->parse_perfstring("/=382MB;15264;15269;; /var=218MB;9443;9448"); | 117 | # Constructor (also accepts a 'threshold' obj instead of warning/critical) |
83 | if (@p) { | 118 | $p = Nagios::Plugin::Performance->new( |
84 | print "1st label = ", $p[0]->label, $/; | 119 | label => 'size', |
85 | print "1st uom = ", $p[0]->uom, $/; | 120 | value => $value, |
86 | print "2nd crit = ", $p[1]->threshold->critical, $/; | 121 | uom => "kB", |
87 | } else { | 122 | warning => $warning, |
88 | print "Cannot parse",$/; | 123 | critical => $critical, |
124 | min => $min, | ||
125 | max => $max, | ||
126 | ); | ||
127 | |||
128 | # Parser | ||
129 | @perf = Nagios::Plugin::Performance->parse_perfstring( | ||
130 | "/=382MB;15264;15269;; /var=218MB;9443;9448" | ||
131 | ) | ||
132 | or warn("Failed to parse perfstring"); | ||
133 | |||
134 | # Accessors | ||
135 | for $p (@perf) { | ||
136 | printf "label: %s\n", $p->label; | ||
137 | printf "value: %s\n", $p->value; | ||
138 | printf "uom: %s\n", $p->uom; | ||
139 | printf "warning: %s\n", $p->warning; | ||
140 | printf "critical: %s\n", $p->critical; | ||
141 | printf "min: %s\n", $p->min; | ||
142 | printf "max: %s\n", $p->max; | ||
143 | # Special accessor returning a threshold obj containing warning/critical | ||
144 | $threshold = $p->threshold; | ||
89 | } | 145 | } |
90 | 146 | ||
147 | # Perfdata output format i.e. label=value[uom];[warn];[crit];[min];[max] | ||
148 | print $p->perfoutput; | ||
149 | |||
150 | |||
91 | =head1 DESCRIPTION | 151 | =head1 DESCRIPTION |
92 | 152 | ||
93 | Handles common Nagios Plugin performance data. This has a public interface because it could be | 153 | Nagios::Plugin class for handling performance data. This is a public |
94 | used by performance graphing routines, such as nagiostat (http://nagiostat.sourceforge.net), | 154 | interface because it could be used by performance graphing routines, |
95 | perfparse (http://perfparse.sourceforge.net), nagiosgraph (http://nagiosgraph.sourceforge.net) or | 155 | such as nagiostat (http://nagiostat.sourceforge.net), perfparse |
96 | NagiosGrapher (http://www.nagiosexchange.org/NagiosGrapher.84.0.html). | 156 | (http://perfparse.sourceforge.net), nagiosgraph |
157 | (http://nagiosgraph.sourceforge.net) or NagiosGrapher | ||
158 | (http://www.nagiosexchange.org/NagiosGrapher.84.0.html). | ||
97 | 159 | ||
98 | Once the performance string has been parsed, you can query the label, value, uom, or thresholds. | 160 | Nagios::Plugin::Performance offers both a parsing interface (via |
161 | parse_perfstring), for turning nagios performance output strings into | ||
162 | their components, and a composition interface (via new), for turning | ||
163 | components into perfdata strings. | ||
99 | 164 | ||
100 | =head1 CLASS METHODS | 165 | =head1 CLASS METHODS |
101 | 166 | ||
102 | =over 4 | 167 | =over 4 |
103 | 168 | ||
169 | =item Nagios::Plugin::Performance->new(%attributes) | ||
170 | |||
171 | Instantiates a new Nagios::Plugin::Performance object with the given | ||
172 | attributes. | ||
173 | |||
104 | =item Nagios::Plugin::Performance->parse_perfstring($string) | 174 | =item Nagios::Plugin::Performance->parse_perfstring($string) |
105 | 175 | ||
106 | Returns an array of Nagios::Plugin::Performance objects based on the string entered. | 176 | Returns an array of Nagios::Plugin::Performance objects based on the string |
107 | If there is an error parsing the string, an empty array is returned. | 177 | entered. If there is an error parsing the string, an empty array is returned. |
108 | 178 | ||
109 | =back | 179 | =back |
110 | 180 | ||
111 | =head1 OBJECT METHODS | 181 | =head1 OBJECT METHODS (ACCESSORS) |
112 | 182 | ||
113 | =over 4 | 183 | =over 4 |
114 | 184 | ||
115 | =item label, value, uom, min, max | 185 | =item label, value, uom, warning, critical, min, max |
116 | 186 | ||
117 | These all return scalars. min and max are not well supported yet. | 187 | These all return scalars. min and max are not well supported yet. |
118 | 188 | ||
189 | =item threshold | ||
190 | |||
191 | Returns a Nagios::Plugin::Threshold object holding the warning and critical | ||
192 | ranges for this performance data (if any). | ||
193 | |||
119 | =item rrdlabel | 194 | =item rrdlabel |
120 | 195 | ||
121 | Returns a label that can be used for the dataset name of an RRD, ie, between 1-19 | 196 | Returns a string based on 'label' that is suitable for use as dataset name of |
122 | characters long with characters [a-zA-Z0-9_]. | 197 | an RRD i.e. munges label to be 1-19 characters long with only characters |
198 | [a-zA-Z0-9_]. | ||
123 | 199 | ||
124 | There is no guarantee that multiple N:P:Performance objects will have unique rrdlabels. | 200 | There is no guarantee that multiple N:P:Performance objects will have unique |
201 | rrdlabels. | ||
125 | 202 | ||
126 | =item threshold | 203 | =item perfoutput |
127 | 204 | ||
128 | This returns a Nagios::Plugin::Threshold object. | 205 | Outputs the data in Nagios::Plugin perfdata format i.e. |
206 | label=value[uom];[warn];[crit];[min];[max]. | ||
129 | 207 | ||
130 | =back | 208 | =back |
131 | 209 | ||
132 | =head1 SEE ALSO | 210 | =head1 SEE ALSO |
133 | 211 | ||
134 | Nagios::Plugin for information about versioning. | 212 | Nagios::Plugin, Nagios::Plugin::Threshold, http://nagiosplug.sourceforge.net. |
135 | |||
136 | http://nagiosplug.sourceforge.net | ||
137 | 213 | ||
138 | =head1 AUTHOR | 214 | =head1 AUTHOR |
139 | 215 | ||
140 | This code is maintained by the Nagios Plugin Development Team: http://nagiosplug.sourceforge.net | 216 | This code is maintained by the Nagios Plugin Development Team: see |
217 | http://nagiosplug.sourceforge.net. | ||
141 | 218 | ||
142 | =head1 COPYRIGHT AND LICENSE | 219 | =head1 COPYRIGHT AND LICENSE |
143 | 220 | ||
144 | Copyright (C) 2006 Nagios Plugin Development Team | 221 | Copyright (C) 2006-2007 Nagios Plugin Development Team |
145 | 222 | ||
146 | This library is free software; you can redistribute it and/or modify | 223 | This library is free software; you can redistribute it and/or modify |
147 | it under the same terms as Perl itself, either Perl version 5.8.4 or, | 224 | it under the same terms as Perl itself. |
148 | at your option, any later version of Perl 5 you may have available. | ||
149 | |||
150 | 225 | ||
151 | =cut | 226 | =cut |
diff --git a/lib/Nagios/Plugin/Range.pm b/lib/Nagios/Plugin/Range.pm index 691506f..dbb637c 100644 --- a/lib/Nagios/Plugin/Range.pm +++ b/lib/Nagios/Plugin/Range.pm | |||
@@ -10,7 +10,7 @@ use Nagios::Plugin::Functions; | |||
10 | our ($VERSION) = $Nagios::Plugin::Functions::VERSION; | 10 | our ($VERSION) = $Nagios::Plugin::Functions::VERSION; |
11 | 11 | ||
12 | use overload | 12 | use overload |
13 | '""' => sub { shift->stringify }; | 13 | '""' => sub { shift->_stringify }; |
14 | 14 | ||
15 | use Class::Struct; | 15 | use Class::Struct; |
16 | struct "Nagios::Plugin::Range" => { | 16 | struct "Nagios::Plugin::Range" => { |
@@ -24,7 +24,7 @@ struct "Nagios::Plugin::Range" => { | |||
24 | use constant OUTSIDE => 0; | 24 | use constant OUTSIDE => 0; |
25 | use constant INSIDE => 1; | 25 | use constant INSIDE => 1; |
26 | 26 | ||
27 | sub stringify { | 27 | sub _stringify { |
28 | my $self = shift; | 28 | my $self = shift; |
29 | return "" unless $self->is_set; | 29 | return "" unless $self->is_set; |
30 | return (($self->alert_on) ? "@" : "") . | 30 | return (($self->alert_on) ? "@" : "") . |
@@ -37,13 +37,13 @@ sub is_set { | |||
37 | (! defined $self->alert_on) ? 0 : 1; | 37 | (! defined $self->alert_on) ? 0 : 1; |
38 | } | 38 | } |
39 | 39 | ||
40 | sub set_range_start { | 40 | sub _set_range_start { |
41 | my ($self, $value) = @_; | 41 | my ($self, $value) = @_; |
42 | $self->start($value+0); # Force scalar into number | 42 | $self->start($value+0); # Force scalar into number |
43 | $self->start_infinity(0); | 43 | $self->start_infinity(0); |
44 | } | 44 | } |
45 | 45 | ||
46 | sub set_range_end { | 46 | sub _set_range_end { |
47 | my ($self, $value) = @_; | 47 | my ($self, $value) = @_; |
48 | $self->end($value+0); # Force scalar into number | 48 | $self->end($value+0); # Force scalar into number |
49 | $self->end_infinity(0); | 49 | $self->end_infinity(0); |
@@ -71,13 +71,13 @@ sub parse_range_string { | |||
71 | } | 71 | } |
72 | if ( $string =~ m/^([\d\.-]+)?:/ ) { # '10:' | 72 | if ( $string =~ m/^([\d\.-]+)?:/ ) { # '10:' |
73 | my $start = $1; | 73 | my $start = $1; |
74 | $range->set_range_start($start) if defined $start; | 74 | $range->_set_range_start($start) if defined $start; |
75 | $range->end_infinity(1); # overridden below if there's an end specified | 75 | $range->end_infinity(1); # overridden below if there's an end specified |
76 | $string =~ s/^([-\d\.]+)?://; | 76 | $string =~ s/^([-\d\.]+)?://; |
77 | $valid++; | 77 | $valid++; |
78 | } | 78 | } |
79 | if ($string =~ /^([-\d\.]+)$/) { # 'x:10' or '10' | 79 | if ($string =~ /^([-\d\.]+)$/) { # 'x:10' or '10' |
80 | $range->set_range_end($string); | 80 | $range->_set_range_end($string); |
81 | $valid++; | 81 | $valid++; |
82 | } | 82 | } |
83 | 83 | ||
@@ -124,23 +124,41 @@ __END__ | |||
124 | 124 | ||
125 | =head1 NAME | 125 | =head1 NAME |
126 | 126 | ||
127 | Nagios::Plugin::Range - Common range functions for Nagios::Plugin | 127 | Nagios::Plugin::Range - class for handling Nagios::Plugin range data. |
128 | |||
129 | =head1 SYNOPSIS | ||
130 | |||
131 | # NB: This is an internal Nagios::Plugin class. | ||
132 | # See Nagios::Plugin itself for public interfaces. | ||
133 | |||
134 | # Instantiate an empty range object | ||
135 | $r = Nagios::Plugin::Range->new; | ||
136 | |||
137 | # Instantiate by parsing a standard nagios range string | ||
138 | $r = Nagios::Plugin::Range->parse_range_string; | ||
139 | |||
140 | # Returns true if the range is defined/non-empty | ||
141 | $r->is_set; | ||
142 | |||
143 | # Returns true if $value matches range, false otherwise | ||
144 | $r->check_range($value); | ||
145 | |||
128 | 146 | ||
129 | =head1 DESCRIPTION | 147 | =head1 DESCRIPTION |
130 | 148 | ||
131 | Handles common Nagios Plugin range data. See Nagios::Plugin for creation interfaces. | 149 | Internal Nagios::Plugin class for handling common range data. See |
150 | Nagios::Plugin for public interfaces. | ||
132 | 151 | ||
133 | =head1 AUTHOR | 152 | =head1 AUTHOR |
134 | 153 | ||
135 | This code is maintained by the Nagios Plugin Development Team: http://nagiosplug.sourceforge.net | 154 | This code is maintained by the Nagios Plugin Development Team: see |
155 | http://nagiosplug.sourceforge.net. | ||
136 | 156 | ||
137 | =head1 COPYRIGHT AND LICENSE | 157 | =head1 COPYRIGHT AND LICENSE |
138 | 158 | ||
139 | Copyright (C) 2006 Nagios Plugin Development Team | 159 | Copyright (C) 2006-2007 Nagios Plugin Development Team |
140 | 160 | ||
141 | This library is free software; you can redistribute it and/or modify | 161 | This library is free software; you can redistribute it and/or modify |
142 | it under the same terms as Perl itself, either Perl version 5.8.4 or, | 162 | it under the same terms as Perl itself. |
143 | at your option, any later version of Perl 5 you may have available. | ||
144 | |||
145 | 163 | ||
146 | =cut | 164 | =cut |
diff --git a/lib/Nagios/Plugin/Threshold.pm b/lib/Nagios/Plugin/Threshold.pm index b2afd8e..0c4805a 100644 --- a/lib/Nagios/Plugin/Threshold.pm +++ b/lib/Nagios/Plugin/Threshold.pm | |||
@@ -58,38 +58,49 @@ __END__ | |||
58 | 58 | ||
59 | =head1 NAME | 59 | =head1 NAME |
60 | 60 | ||
61 | Nagios::Plugin::Threshold - Threshold information in a perl object | 61 | Nagios::Plugin::Threshold - class for handling Nagios::Plugin thresholds. |
62 | 62 | ||
63 | =head1 DESCRIPTION | 63 | =head1 SYNOPSIS |
64 | 64 | ||
65 | Handles common Nagios Plugin threshold data. See Nagios::Plugin or Nagios::Plugin::Performance for | 65 | # NB: This is an internal Nagios::Plugin class. |
66 | creation of this object. | 66 | # See Nagios::Plugin itself for public interfaces. |
67 | |||
68 | # Constructor | ||
69 | $t = Nagios::Plugin::Threshold->set_thresholds( | ||
70 | warning => $warning_range_string, | ||
71 | critical => $critical_range_string, | ||
72 | ); | ||
67 | 73 | ||
68 | =head1 OBJECT METHODS | 74 | # Value checking - returns CRITICAL if in the critical range, |
75 | # WARNING if in the warning range, and OK otherwise | ||
76 | $status = $t->get_status($value); | ||
69 | 77 | ||
70 | =over 4 | 78 | # Accessors - return the associated N::P::Range object |
79 | $warning_range = $t->warning; | ||
80 | $critical_range = $t->critical; | ||
71 | 81 | ||
72 | =item warning, critical | ||
73 | 82 | ||
74 | Returns the warning or critical range as a Nagios::Plugin::Range object. | 83 | =head1 DESCRIPTION |
75 | 84 | ||
76 | =item get_status($value) | 85 | Internal Nagios::Plugin class for handling threshold data. See |
86 | Nagios::Plugin for public interfaces. | ||
77 | 87 | ||
78 | Given a value, will see if the value breaches the critical or the warning range. Returns the status code. | 88 | A threshold object contains (typically) a pair of ranges, associated |
89 | with a particular severity e.g. | ||
79 | 90 | ||
80 | =back | 91 | warning => range1 |
92 | critical => range2 | ||
81 | 93 | ||
82 | =head1 AUTHOR | 94 | =head1 AUTHOR |
83 | 95 | ||
84 | This code is maintained by the Nagios Plugin Development Team: http://nagiosplug.sourceforge.net | 96 | This code is maintained by the Nagios Plugin Development Team: see |
97 | http://nagiosplug.sourceforge.net. | ||
85 | 98 | ||
86 | =head1 COPYRIGHT AND LICENSE | 99 | =head1 COPYRIGHT AND LICENSE |
87 | 100 | ||
88 | Copyright (C) 2006 Nagios Plugin Development Team | 101 | Copyright (C) 2006-2007 Nagios Plugin Development Team |
89 | 102 | ||
90 | This library is free software; you can redistribute it and/or modify | 103 | This library is free software; you can redistribute it and/or modify |
91 | it under the same terms as Perl itself, either Perl version 5.8.4 or, | 104 | it under the same terms as Perl itself. |
92 | at your option, any later version of Perl 5 you may have available. | ||
93 | |||
94 | 105 | ||
95 | =cut | 106 | =cut |