Runcheckdir now works as a well-behaved system daemon
[chksht.git] / runcheckdir
1 #!/usr/bin/perl
2 use Getopt::Long;
3 use Cwd qw/abs_path/;
4 use POSIX qw/setsid setuid setgid/;
5 use strict;
6
7 my ($nodaemon, $verbose, $pidfile, $logfile, $user, $group, $uid, $gid);
8 $pidfile = '/var/run/runcheckdir.pid';
9 $logfile = '/var/log/runcheckdir.log';
10
11 GetOptions(
12         "nodaemon" => \$nodaemon,
13         "verbose"  => \$verbose,
14         "pidfile=s"  => \$pidfile,
15         "logfile=s"  => \$logfile,
16         "user=s"  => \$user,
17         "group=s"  => \$group,
18 );
19
20 my $dir = abs_path(shift);
21 unless ($dir) {
22         print "No directory specified\n";
23         exit 1;
24 }
25 unless (-d $dir) {
26         print "$dir is not a directory\n";
27         exit 1;
28 }
29
30 $uid = (getpwnam($user))[2] if $user;
31 $gid = (getpwnam($group))[3] if $group;
32
33 sub daemonize {
34         if (fork()) {
35                 exit 0;
36         }
37         setsid();
38
39         umask 027;
40         if (open STDOUT, ">>$logfile") {
41                 open STDERR, ">>$logfile";
42                 chown $uid, $gid, $logfile;
43         } else {
44                 print "WARNING: Could not open logfile. You will get NO error output.\n";
45                 open STDOUT, ">/dev/null";
46                 open STDERR, ">/dev/null";
47         }
48         open STDIN, "/dev/null";
49
50         open PID, ">$pidfile" or warn "Could not write PID file\n";
51         print PID "$$\n";
52         close PID;
53         chown $uid, $gid, $pidfile;
54
55         chdir '/';
56         print "Daemon started at ",scalar gmtime(),"\n";
57 }
58
59 daemonize unless $nodaemon;
60
61 setuid($uid) if $uid;
62 setgid($uid) if $gid;
63
64 $|++;
65
66 while (1) {
67         opendir(CHECKS, $dir);
68         while (my $d = readdir(CHECKS)) {
69                 next if (! -d "$dir/$d" || $d eq '.' || $d eq '..');
70                 unless (-f "$dir/$d/check") {
71                         print "No check script in $dir/$d\n";
72                         next;
73                 }
74                 print "Running check $dir/$d: ";
75                 system("runcheck $dir/$d");
76                 my $exitstatus = $? >> 8;
77                 if ($exitstatus) {
78                         print "FAILURE\n";
79                 } else {
80                         print "OK\n";
81                 }
82                 sleep 10;
83         }
84         closedir(CHECKS);
85 }