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