Added tool that parses and runs a check based on the contents of a directory
[chksht.git] / runcheckdir.pl
1 #!/usr/bin/perl
2 use File::Basename;
3 use strict;
4
5
6 my $dir = shift;
7 unless (-d $dir) {
8         print "Arg is not a directory";
9         exit 1;
10 }
11 my $me = basename $dir;
12 my ($status, $details);
13
14 sub do_command {
15         my $command = shift;
16         $command =~ /^(\w+)(\s+(.*))?$/;
17         my ($do, $args) = ($1, $3);
18         if ($do eq 'mail') {
19                 open MAIL, '|-', qq!mail -s "$me $status" $args! or die "Could not mail";
20                 print MAIL $details,"\n";
21                 close MAIL;
22         } elsif ($do eq 'exec') {
23                 system($args);
24         } elsif ($do eq 'pipe') {
25                 open PIPE, '|-', $args;
26                 print PIPE "$status\n";
27                 print PIPE $details;
28                 close PIPE;
29         }
30 }
31
32
33 my ($checkcommand, %on);
34 $on{success} = [];
35 $on{failure} = [];
36 $on{change} = [];
37
38 open CONFIG, "$dir/check";
39 while (<CONFIG>) {
40         my @words = split(/\s+/);
41         my $command = shift @words;
42         if ($command eq 'check') {
43                 $checkcommand = join(' ', @words);
44         } elsif ($command eq 'on') {
45                 my $when = shift @words;
46                 if ($when eq 'failure') {
47                         push @{$on{failure}}, join(' ', @words);
48                 } elsif ($when eq 'success') {
49                         push @{$on{success}}, join(' ', @words);
50                 } elsif ($when eq 'change') {
51                         push @{$on{change}}, join(' ', @words);
52                 } else {
53                         print "Unknown event in 'on', $dir/check line $.\n";
54                 }
55         } else {
56                 print "Unknown command '$command', $dir/check line $.\n";
57         }
58 }
59 close CONFIG;
60
61 unless ($checkcommand) {
62         print "Check command not specified in $dir/check\n";
63         exit 1;
64 }
65 unless (@{$on{failure}} || @{$on{success}} || @{$on{change}}) {
66         print "No actions specified in $dir/check. This is probably a mistake.\n";
67 }
68
69 open STATUS, "$dir/checkstatus";
70 chomp(my $oldstatus = <STATUS>);
71 close STATUS;
72
73 open CHECK, '-|', $checkcommand;
74 $status = <CHECK>;
75 $details = join('', <CHECK>);
76 close CHECK;
77 my $exitstatus = $? >> 8;
78
79 if ($exitstatus == 0) {
80         foreach my $command (@{$on{success}}) {
81                 do_command $command;
82         }
83 } else {
84         foreach my $command (@{$on{failure}}) {
85                 do_command $command;
86         }
87 }
88 if ($exitstatus != $oldstatus) {
89         foreach my $command(@{$on{change}}) {
90                 do_command $command;
91         }
92 }
93
94 open STATUS, ">$dir/checkstatus";
95 print STATUS "$exitstatus\n";
96 close STATUS;