X-Git-Url: http://git.bytex64.net/?a=blobdiff_plain;f=runcheckdir;h=15d7762aa79e9dd91ec55f8a0d0987e08febdc15;hb=7b9555afd472cf6ddd388aabedd57f8b42bc5f27;hp=d6589f2f5c8716a06c0c29636933bbd6911402ca;hpb=98307380429da3ad6e18c99200da6449719dc106;p=chksht.git diff --git a/runcheckdir b/runcheckdir index d6589f2..15d7762 100755 --- a/runcheckdir +++ b/runcheckdir @@ -1,118 +1,85 @@ #!/usr/bin/perl -use File::Basename; +use Getopt::Long; +use Cwd qw/abs_path/; +use POSIX qw/setsid setuid setgid/; use strict; +my ($nodaemon, $verbose, $pidfile, $logfile, $user, $group, $uid, $gid); +$pidfile = '/var/run/runcheckdir.pid'; +$logfile = '/var/log/runcheckdir.log'; -my $dir = shift; -unless (-d $dir) { - print "Arg is not a directory"; +GetOptions( + "nodaemon" => \$nodaemon, + "verbose" => \$verbose, + "pidfile=s" => \$pidfile, + "logfile=s" => \$logfile, + "user=s" => \$user, + "group=s" => \$group, +); + +my $dir = abs_path(shift); +unless ($dir) { + print "No directory specified\n"; exit 1; } -my $me = basename $dir; -my ($status, $details); - -sub do_command { - my $command = shift; - $command =~ /^(\w+)(\s+(.*))?$/; - my ($do, $args) = ($1, $3); - if ($do eq 'mail') { - open MAIL, '|-', qq!mail -s "$me $status" $args! or die "Could not mail"; - print MAIL $details,"\n"; - close MAIL; - } elsif ($do eq 'exec') { - system($args); - } elsif ($do eq 'pipe') { - open PIPE, '|-', $args; - print PIPE "$status\n"; - print PIPE $details; - close PIPE; - } +unless (-d $dir) { + print "$dir is not a directory\n"; + exit 1; } +$uid = (getpwnam($user))[2] if $user; +$gid = (getpwnam($group))[3] if $group; -my ($checkcommand, $every, %on); -$on{success} = []; -$on{failure} = []; -$on{change} = []; +sub daemonize { + if (fork()) { + exit 0; + } + setsid(); -open CONFIG, "$dir/check"; -while () { - my @words = split(/\s+/); - my $command = shift @words; - if ($command eq 'check') { - $checkcommand = join(' ', @words); - } elsif ($command eq 'on') { - my $when = shift @words; - if ($when eq 'failure') { - push @{$on{failure}}, join(' ', @words); - } elsif ($when eq 'success') { - push @{$on{success}}, join(' ', @words); - } elsif ($when eq 'change') { - push @{$on{change}}, join(' ', @words); - } else { - print "Unknown event in 'on', $dir/check line $.\n"; - } - } elsif ($command eq 'every') { - $every = $words[0]; + umask 027; + if (open STDOUT, ">>$logfile") { + open STDERR, ">>$logfile"; + chown $uid, $gid, $logfile; } else { - print "Unknown command '$command', $dir/check line $.\n"; + print "WARNING: Could not open logfile. You will get NO error output.\n"; + open STDOUT, ">/dev/null"; + open STDERR, ">/dev/null"; } -} -close CONFIG; - -unless ($checkcommand) { - print "Check command not specified in $dir/check\n"; - exit 1; -} -unless (@{$on{failure}} || @{$on{success}} || @{$on{change}}) { - print "No actions specified in $dir/check. This is probably a mistake.\n"; -} + open STDIN, "/dev/null"; -open STATUS, "$dir/checkstatus"; -chomp(my $oldstatus = ); -my $oldtime = (stat(STATUS))[9]; -close STATUS; + open PID, ">$pidfile" or warn "Could not write PID file\n"; + print PID "$$\n"; + close PID; + chown $uid, $gid, $pidfile; -my $td = time() - $oldtime; -if ($td < $every) { - # Not time to recheck yet - #print "Not rechecking; ", $every - $td, " seconds to go.\n"; - exit $oldstatus; + chdir '/'; + print "Daemon started at ",scalar gmtime(),"\n"; } -my ($pid, $hung, $exitstatus); -$SIG{ALRM} = sub { - kill 9, $pid; - $hung = 1; -}; -alarm 10; - -$pid = open CHECK, '-|', $checkcommand; -$status = ; -$details = join('', ); -close CHECK; -if ($hung) { - $status = 'TIMEOUT'; - $details = 'Check did not complete within ten seconds'; - $exitstatus = -1; -} else { - $exitstatus = $? >> 8; -} +daemonize unless $nodaemon; -if ($exitstatus == 0 && $oldstatus != 0) { - do_command($_) foreach @{$on{success}}; -} -if ($exitstatus != 0 && $oldstatus == 0) { - do_command($_) foreach @{$on{failure}}; -} -if ($exitstatus != $oldstatus) { - do_command($_) foreach @{$on{change}}; -} +setuid($uid) if $uid; +setgid($uid) if $gid; -open STATUS, ">$dir/checkstatus"; -print STATUS "$exitstatus\n"; -print STATUS "$status\n"; -print STATUS "$details\n"; -close STATUS; +$|++; -exit $exitstatus; +while (1) { + opendir(CHECKS, $dir); + while (my $d = readdir(CHECKS)) { + next if (! -d "$dir/$d" || $d eq '.' || $d eq '..'); + unless (-f "$dir/$d/check") { + print "No check script in $dir/$d\n"; + next; + } + print "Running check $dir/$d: "; + system("runcheck $dir/$d"); + my $exitstatus = $? >> 8; + if ($exitstatus) { + print "FAILURE\n"; + } else { + print "OK\n"; + } + sleep 10; + } + closedir(CHECKS); +}