#!/usr/bin/perl -wT # # namedmon - Starts named if it has died. Run this script from cron(8). # # Copyright (C) 2001 Steven Pritchard # This program is free software; you can redistribute it # and/or modify it under the same terms as Perl itself. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # $Id: namedmon,v 1.1 2001/02/27 23:49:11 steve Exp $ use strict; use FileHandle; use vars qw($command $directory $pidfile $user $group $debug); sub debug(@); # Edit these appropriately. $command="/sbin/service named start"; $directory="/var/named"; $pidfile="/var/run/named.pid"; $user="named"; $group="named"; $debug=0; $debug=$ENV{'DEBUG'} if (defined($ENV{'DEBUG'})); #die "This thing is broken, try something else.\n" if ($debug<2); $ENV{'PATH'}="/bin:/usr/bin:/sbin:/usr/sbin"; chdir $directory or die "Can't chdir() to $directory: $!\n"; my $pidf=new FileHandle "<$pidfile"; if (defined($pidf)) { my $pid=<$pidf>; undef $pidf; chomp $pid; if (-d "/proc/$pid") { # named is running debug "named seems to be running (PID $pid)...\n"; exit 0; } else { # named must have died print STDERR "Removing stale pidfile...\n"; if ($debug<2) { unlink($pidfile) or warn "Couln't unlink $pidfile: $!\n"; } } } my $ps=new FileHandle "/bin/ps -ef |"; die "Failed to run '/bin/ps -ef': $!\n" if (!defined($ps)); my @pids; while (<$ps>) { chomp; if (/^\s*(\S+) # UID \s+(\d+) # PID \s+(\d+) # PPID \s+(?:\d+) # C \s+(?:[A-Z][a-z][a-z]\s?\d\d|\d\d:\d\d(?::\d\d)?) # STIME \s+(?:\S+) # TTY \s+(?:\S+) # TIME \s+(.*) # CMD $/x) { my ($uid,$pid,$ppid,$cmd)=($1,$2,$3,$4); push(@pids,$pid) if (($uid eq $user) && ($ppid eq "1") && ($cmd=~/^\S*named-xfer\s/)); } } if (@pids) { print STDERR "Killing ", scalar(@pids), " named-xfer processes...\n"; debug "@pids\n"; if ($debug<2) { kill(15, @pids); sleep 2; # Give them a couple of seconds to exit. } } print STDERR "Starting named...\n"; if ($debug>1) { debug "(debugging done)\n"; exit 0; } my $ret=system $command; if ($ret != 0) { print STDERR "Failed to start named: "; if ($ret == -1) { print STDERR "$!\n"; } else { if ($ret & 127) { print STDERR "exited on signal ", $ret & 127; print STDERR ", core dumped" if ($ret & 128); } else { print STDERR "exit value ", $ret >> 8; } print STDERR "\n"; } exit 1; } my $count=0; while ((!-f "$pidfile") && ($count++ < 5)) # Wait (about) 10 seconds { print STDERR "Waiting for named to create $pidfile...\n" if ($count == 1); sleep 2; } my $uid=getpwnam($user) or die "Can't get uid for $user: $!\n"; my $gid=getgrnam($group) or die "Can't get gid for $group: $!\n"; chown($uid, $gid, $pidfile) or warn "Couldn't set owner of $pidfile: $!\n"; sub debug(@) { print @_ if ($debug); }