home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/perl
-
- $> && die "Not running as root\n";
-
- @INC = $INC[$#INC - 1]; # Use only the perl library.
- die "Perl library is writable by world!!!\n"
- if $< && -W $INC[0];
- die "getopts.pl is writable by world!!!\n"
- if $< && -W "$INC[0]/getopts.pl";
- require "getopts.pl";
- &Getopts('cst');
-
- $wall = !opt_s;
-
- $_ = "$0 @ARGV"; # To allow "ln START STARTxyz"
-
- $ENV{'IFS'} = '' if $ENV{'IFS'}; # plug sh security hole
- $ENV{'PATH'} = '/appl/bin:/bin:/usr/bin:/usr/local/bin';
-
- # Which daemon to start?
-
- if (/abc/) {
- $sys = 'abc';
- $task = 'abcdaemon';
- if (-f '/local/tmp/NO_ABC') {
- die "Can't start abcdaemon while NO_ABC exists\n";
- }
- }
-
- elsif (/def/) {
- $sys = 'def';
- $task = 'def';
- if (-f '/local/tmp/NO_DEF') {
- die "Can't start def while NO_DEF exists\n";
- }
- }
- elsif (/xyz/) {
- $sys = 'xyz';
- $task = 'xyzzy'; # Forks plugh and plover.
- if (-f '/local/tmp/NO_XYZ') {
- die "Can't start lm while NO_XYZ exists\n";
- }
- }
- elsif (/appl/ || !@ARGV) {
- system $0, 'abc';
- system $0, 'def';
- system $0, 'xyz';
- exit 0;
- }
- else {
- die "Usage: START subsystem\n";
- }
-
- # Get info for logging.
-
- chop($whoami = `who am i`);
- $whoami =~ s/[ \t]+/ /g;
-
- chop($tty = `tty`);
- $tty = '' if $tty !~ m|/dev/|;
-
- # Set real uid to effective uid so core dumps will happen.
-
- $< = $>;
-
- # Move to directory for core dumps.
-
- chdir '/local/tmp' || die "Can't chdir to /local/tmp";
-
- # See if they should have run KILL.
-
- chop($oldpid = `/bin/cat .pid$sys 2>&1`);
- if ($oldpid > 0 && kill 0, $oldpid) {
- die "$sys appears to be running already!\n"
- if `/bin/ps -p$oldpid` =~ /START/;
- }
-
- print "Any core dump of $task will be put into /local/tmp.\n";
-
- # Redirect output to log file.
-
- open(STDERR,">/local/tmp/${sys}_err_log")
- || (print STDOUT "Can't open log file\n");
- open(STDOUT,">&STDERR");
-
- # Log the startup.
-
- chop($date = `date`);
- $date =~ s/ [A-Z][DS]T 19[89][0-9]//;
- open(KILLLOG,">>/local/tmp/${sys}_kill_log");
- print KILLLOG $date, ' ', $whoami, " $sys started\n";
- close(KILLLOG);
- if ($tty) {
- open(KILLLOG,">$tty");
- print KILLLOG $date, ' ', $whoami, " $sys started\n";
- close(KILLLOG);
- }
-
- if ($pid = fork) { # Run the rest in background.
- open(PID,">.pid$sys"); # Remember pid for quick check above
- print PID "$pid\n"; # (pid of START, not of $task).
- close(PID);
- sleep(3); # Give each daemon a chance to start
- exit 0;
- }
- defined $pid || die "Can't fork: $!\n";
-
- $SIG{'TERM'} = 'IGNORE';
-
- setpgrp(0,$$); # Prevent kills from infecting other daemons.
-
- # Finally, run the poor daemon and collect its status.
-
- if ($opt_t) {
- $st = (system "/usr/bin/trace /appl/bin/$task");
- }
- else {
- $st = (system "/appl/bin/$task");
- }
-
- # Now get info necessary for logging.
-
- chop($date = `date`);
- $date =~ s/ [A-Z][DS]T 19[89][0-9]//;
-
- # Rename any core dump to a unique name.
-
- if ($st & 128) {
- $tm = join('',unpack("x8 a2 x a2 x a2", $date));
- $tm =~ s/ /0/g;
- rename("/local/tmp/core", "/local/tmp/core.$sys$tm");
- }
-
- sleep(2);
-
- # Log it everywhere that makes sense.
-
- $entry = "$date $whoami $sys exit " . ($st >> 8) . ", sig " .
- ($st & 127) . ($st & 128 ? ", core dump\n" : "\n");
- open(KILLLOG,">>/local/tmp/${sys}_kill_log");
- print KILLLOG $entry;
- close(KILLLOG);
-
- close(STDERR);
- close(STDOUT);
- open(STDOUT,">&STDIN");
- open(ERR,"/local/tmp/${sys}_err_log");
- open(CONSOLE,"/dev/console") if $opt_c;
- $tty = '' unless -t;
- while (<ERR>) {
- if ($_ eq $last) {
- $repeat = 1;
- while (<ERR>) {
- if ($_ eq $last) {
- ++$repeat;
- }
- else {
- $last = "Last message repeated $repeat time" .
- ($repeat == 1 ? "" : "s") . ".\n";
- print CONSOLE $last if $opt_c;
- print STDOUT $last if $tty;
- }
- }
- }
- print CONSOLE $_ if $opt_c;
- print STDOUT $_ if $tty;
- $last = $_;
- }
-
- if ($wall) {
- open(KILLLOG,"| wall"); # Might as well share the good news
- print KILLLOG $entry;
- close(KILLLOG);
- }
-
- unlink "/local/tmp/.pid$sys";
-