File Coverage

lib/Nagios/Cmd.pm
Criterion Covered Total %
statement 51 67 76.1
branch 13 26 50.0
condition 2 6 33.3
subroutine 12 14 85.7
pod 5 8 62.5
total 83 121 68.6


line stmt bran cond sub pod time code
1             ###########################################################################
2             # #
3             # Nagios::Cmd #
4             # Written by Albert Tobey #
5             # Copyright 2003, Albert P Tobey #
6             # #
7             # This program is free software; you can redistribute it and/or modify it #
8             # under the terms of the GNU General Public License as published by the #
9             # Free Software Foundation; either version 2, or (at your option) any #
10             # later version. #
11             # #
12             # This program is distributed in the hope that it will be useful, but #
13             # WITHOUT ANY WARRANTY; without even the implied warranty of #
14             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #
15             # General Public License for more details. #
16             # #
17             ###########################################################################
18             package Nagios::Cmd;
19 21     21   15057 use vars qw( $AUTOLOAD $debug %commands );
  21         21  
  21         1428  
20 21     21   105 use Fcntl qw( :flock SEEK_END O_WRONLY );
  21         42  
  21         4074  
21 21     21   273 use Symbol;
  21         21  
  21         1176  
22 21     21   84 use Carp;
  21         21  
  21         25347  
23             $debug = undef;
24              
25             %commands = (
26             ADD_HOST_COMMENT => [qw(host persistent author comment)],
27             ADD_SVC_COMMENT => [qw(host service persistent author comment)],
28             DEL_HOST_COMMENT => [qw(comment_id)],
29             DEL_ALL_HOST_COMMENTS => [qw(host)],
30             DEL_SVC_COMMENT => [qw(comment_id)],
31             DEL_ALL_SVC_COMMENTS => [qw(host service)],
32             DELAY_HOST_NOTIFICATION => [qw(host next_notification_time)],
33             DELAY_SVC_NOTIFICATION => [qw(host service next_check_time)],
34             SCHEDULE_HOST_SVC_CHECKS => [qw(host next_check_time)],
35             ENABLE_SVC_CHECKS => [qw(host service)],
36             DISABLE_SVC_CHECKS => [qw(host service)],
37             ENABLE_SVC_NOTIFICATIONS => [qw(host service)],
38             DISABLE_SVC_NOTIFICATIONS => [qw(host service)],
39             ENABLE_HOST_SVC_NOTIFICATIONS => [qw(host)],
40             DISABLE_HOST_SVC_NOTIFICATIONS => [qw(host)],
41             ENABLE_HOST_SVC_CHECKS => [qw(host)],
42             DISABLE_HOST_SVC_CHECKS => [qw(host)],
43             ENABLE_HOST_NOTIFICATIONS => [qw(host)],
44             DISABLE_HOST_NOTIFICATIONS => [qw(host)],
45             ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST => [qw(host)],
46             DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST => [qw(host)],
47             ENABLE_NOTIFICATIONS => [qw(time)],
48             DISABLE_NOTIFICATIONS => [qw(time)],
49             SHUTDOWN_PROGRAM => [qw(time)],
50             RESTART_PROGRAM => [qw(time)],
51             PROCESS_SERVICE_CHECK_RESULT => [qw(host service return_code plugin_output)],
52             PROCESS_HOST_CHECK_RESULT => [qw(host return_code plugin_output)],
53             SAVE_STATE_INFORMATION => [qw(time)],
54             READ_STATE_INFORMATION => [qw(time)],
55             START_EXECUTING_SVC_CHECKS => undef,
56             STOP_EXECUTING_SVC_CHECKS => undef,
57             START_ACCEPTING_PASSIVE_SVC_CHECKS => undef,
58             STOP_ACCEPTING_PASSIVE_SVC_CHECKS => undef,
59             ENABLE_PASSIVE_SVC_CHECKS => [qw(host service)],
60             DISABLE_PASSIVE_SV_CHECKS => [qw(host service)],
61             ACKNOWLEDGE_SVC_PROBLEM => [qw(host service persistent comment)],
62             ACKNOWLEDGE_HOST_PROBLEM => [qw(host persistent comment)]
63             );
64              
65             sub nagios_cmd {
66 1061     1061 1 2018 my( $self, $cmd ) = @_;
67              
68             # there can be only one "\n" and this function is used for passing through
69             # custom commands, too
70 1061         1319 chomp( $cmd );
71              
72 1061         3007 my $fh = gensym;
73             # cannot open in append mode, since that causes a seek
74 1061 50       72227 sysopen( $fh, $$self, O_WRONLY )
75             || croak "could not sysopen $$self for writing: $!";
76            
77 1061         190201 flock $fh, LOCK_EX;
78             # only seek to end of file on regular files
79 1061 100       26258 seek( $fh, 0, SEEK_END ) if ( -f $$self );
80 1061         10210 print $fh "$cmd\n";
81 1061         78422 flock $fh, LOCK_UN;
82 1061         30803 close $fh;
83             }
84            
85             sub new {
86 21     21 1 42 my( $type, $cmdfile ) = @_;
87 21 50       441 croak "$cmdfile does not exist!" unless ( -e $cmdfile );
88 21 50       336 croak "$cmdfile is not a pipe!" unless ( -p $cmdfile );
89 21         105 return bless \$cmdfile, $type;
90             }
91              
92             # allow use of any file instead of a fifo (great for testing)
93             sub new_anyfile {
94 42     42 1 182931 my( $type, $cmdfile ) = @_;
95 42         693 return bless \$cmdfile, $type;
96             }
97              
98             # host service return_code plugin_output
99             sub service_check {
100 221     221 1 3458 shift->nagios_cmd( "[".time()."] ". join(";", process_args('PROCESS_SERVICE_CHECK_RESULT',@_)) );
101             }
102              
103             # host return_code plugin_output
104             sub host_check {
105 21     21 1 399 shift->nagios_cmd( "[".time()."] ". join(";", process_args('PROCESS_HOST_CHECK_RESULT',@_)) );
106             }
107              
108 63     63   18326 sub DESTROY { 1 }
109              
110             sub AUTOLOAD {
111 819     819   259791 my $self = shift;
112              
113 819         2772 $AUTOLOAD =~ m/Nagios::Cmd::(\w+)$/;
114 819         1386 my $method = $1;
115              
116 819 50       1512 print "method $method called with arguments: '", join(', ', @_), "'\n"
117             if ( $debug );
118              
119 819 50       1701 confess "invalid method call '$method'"
120             unless ( exists($commands{$method}) );
121              
122             # process method arguments to allow hash, hashref, or list
123 819         1722 my @command = process_args( $method, @_ );
124              
125             # get the current time for the command's timestamp
126 819         1575 my $time = '[' . time() . '] ';
127              
128 819 50       1239 print "writing '", $time, join(';', @command), "' to command file ...\n"
129             if ( $debug );
130              
131             # write to the command pipe
132 819         2625 $self->nagios_cmd( $time . join(';', @command) );
133             }
134              
135             sub process_args {
136 1061     1061 0 3251 my( $method, @input ) = @_;
137 1061         1297 my @command = ();
138              
139             # a few commands take no arguments, so skip this block of code in that case
140 1061 100       2742 if ( defined($commands{$method}) ) {
141             # get the list of expected argument keys
142 935         1415 my @parts = @{ $commands{$method} };
  935         3163  
143              
144             # call to method used named parameters - put them into a hashref
145             # and use the hashref parsing to do the rest
146 935 50 33     4108 if ( @input > @parts && @input % 2 == 0 ) {
147 0         0 my %tmp = @input;
148 0         0 @input = ( \%tmp );
149             }
150              
151             # process hashed arguments
152 935 50       2167 if ( ref($input[0]) eq 'HASH' ) {
153 0         0 my $args = shift(@input);
154 0         0 for ( my $i=0; $i<=$#parts; $i++ ) {
155 0 0       0 if ( !exists($args->{$parts[$i]}) ) {
156 0         0 croak "insufficient arguments to $method - '$parts[$i]' argument is missing";
157             }
158             else {
159 0         0 $command[$i + 1] = $args->{$parts[$i]};
160             }
161             }
162             }
163              
164             # user sent us a list (presumably) already in the right order
165             else {
166 935         3222 splice( @command, @command, 0, @input );
167             }
168             }
169              
170             # run through and resolve Nagios::Object objects into their textual names
171             # name() is a Nagios::Object specific method for doing polymorphic stuff
172             # like this
173 1061         1754 foreach ( @command ) {
174 2228 50 33     8989 if ( ref $_ =~ /^Nagios::/ && $_->can('name') ) {
175 0         0 $_ = $_->name;
176             }
177             }
178              
179 1061         2260 unshift( @command, $method );
180 1061         20548 return @command;
181             }
182              
183             sub Help {
184 0     0 0   my $func = shift;
185              
186 0 0         if ( !$func ) {
187 0           foreach my $cmd ( keys(%commands) ) {
188 0           print "$cmd(", join(', ', @{$commands{$cmd}}), ")\n";
  0            
189             }
190             }
191             else {
192 0           print "$func(", join(', ', @{$commands{$func}}), ")\n";
  0            
193             }
194             }
195              
196             sub Commands {
197 0     0 0   return \%commands;
198             }
199              
200             1;
201              
202             __END__