pick up freeside-sqlradius-radacctd again after all these years, now it just needs...
[freeside.git] / FS / FS / Daemon.pm
1 package FS::Daemon;
2
3 use vars qw( @ISA @EXPORT_OK );
4 use vars qw( $pid_dir $me $pid_file $sigint $sigterm $logfile );
5 use Exporter;
6 use Fcntl qw(:flock);
7 use POSIX qw(setsid);
8 use Date::Format;
9
10 #this is a simple refactoring of the stuff from freeside-queued, just to
11 #avoid duplicate code.  eventually this should use something from CPAN.
12
13 @ISA = qw(Exporter);
14 @EXPORT_OK = qw( daemonize1 drop_root daemonize2 sigint sigterm logfile );
15
16 $pid_dir = '/var/run';
17
18 sub daemonize1 {
19   $me = shift;
20
21   $pid_file = "$pid_dir/$me";
22   $pid_file .= '.'.shift if scalar(@_);
23   $pid_file .= '.pid';
24
25   chdir "/" or die "Can't chdir to /: $!";
26   open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
27   defined(my $pid = fork) or die "Can't fork: $!";
28   if ( $pid ) {
29     print "$me started with pid $pid\n"; #logging to $log_file\n";
30     exit unless $pid_file;
31     my $pidfh = new IO::File ">$pid_file" or exit;
32     print $pidfh "$pid\n";
33     exit;
34   }
35
36   #sub REAPER { my $pid = wait; $SIG{CHLD} = \&REAPER; $kids--; }
37   #$SIG{CHLD} =  \&REAPER;
38   $sigterm = 0;
39   $sigint = 0;
40   $SIG{INT}  = sub { warn "SIGINT received; shutting down\n"; $sigint++;  };
41   $SIG{TERM} = sub { warn "SIGTERM received; shutting down\n"; $sigterm++; };
42 }
43
44 sub drop_root {
45   my $freeside_gid = scalar(getgrnam('freeside'))
46     or die "can't find freeside group\n";
47   $) = $freeside_gid;
48   $( = $freeside_gid;
49   #if freebsd can't setuid(), presumably it can't setgid() either.  grr fleabsd
50   ($(,$)) = ($),$();
51   $) = $freeside_gid;
52   
53   $> = $FS::UID::freeside_uid;
54   $< = $FS::UID::freeside_uid;
55   #freebsd is sofa king broken, won't setuid()
56   ($<,$>) = ($>,$<);
57   $> = $FS::UID::freeside_uid;
58 }
59
60 sub daemonize2 {
61   open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!";
62   setsid                    or die "Can't start a new session: $!";
63   open STDERR, '>&STDOUT'   or die "Can't dup stdout: $!";
64
65   $SIG{__DIE__} = \&_die;
66   $SIG{__WARN__} = \&_logmsg;
67
68   warn "$me starting\n";
69 }
70
71 sub sigint  { $sigint; }
72 sub sigterm { $sigterm; }
73
74 sub logfile { $logfile = shift; } #_logmsg('test'); }
75
76 sub _die {
77   my $msg = shift;
78   unlink $pid_file if -e $pid_file;
79   _logmsg($msg);
80 }
81
82 sub _logmsg {
83   chomp( my $msg = shift );
84   my $log = new IO::File ">>$logfile";
85   flock($log, LOCK_EX);
86   seek($log, 0, 2);
87   print $log "[". time2str("%a %b %e %T %Y",time). "] [$$] $msg\n";
88   flock($log, LOCK_UN);
89   close $log;
90 }
91