]> git.etc.gen.nz Git - spong.git/commitdiff
cleared out signal mask in case of inherited blocked signals.
authorStephen L Johnson <sjohnson@monsters.org>
Wed, 1 Mar 2000 22:13:41 +0000 (22:13 +0000)
committerStephen L Johnson <sjohnson@monsters.org>
Wed, 1 Mar 2000 22:13:41 +0000 (22:13 +0000)
moved call to &already_running() to handle_signals()

src/spong-server.pl

index 45b6d6822128b66823c8422bd0bb1d39870b45ca..40cce7d158f30278ee147578ec26cb750b0fbc56 100755 (executable)
@@ -33,6 +33,7 @@ use IO::Socket;
 use Config;
 use Time::Local;
 use Getopt::Long;
+use POSIX;
 
 $debug = $restart = $kill = 0;
 
@@ -164,7 +165,6 @@ sub listen_for_clients {
    };
 
    $sock = IO::Socket::INET->new( Listen   => SOMAXCONN,
-#                                 LocalHost => INADDR_ANY,
                                   LocalPort => $main::SPONG_CLIENT_PORT,
                                   Proto    => 'tcp',
                                   Timeout  => 30,
@@ -179,14 +179,11 @@ sub listen_for_clients {
 
       $paddr = $client->peerhost();
 
-&debug("[$$] Connection from $paddr");
-
       # &validate_connection( $paddr );  - need to do something here...
 
       # Read all from the client, and disconnect, we process the message next.
 
       my $header = <$client>; chomp $header;
-&debug("[$$] header = $header");
 
       # Now depending on what kind of message it is, pass it off to a routine
       # that can process the message. 
@@ -206,48 +203,64 @@ sub listen_for_clients {
 # just continues to listen for update messages.
 
 sub listen_for_updates {
-   # Set up the socket to listen to
 
    $SIG{'PIPE'} = 'IGNORE';
-   $SIG{'TERM'} = $SIG{'HUP'} = $SIG{'QUIT'} = sub {
-      &debug('spong updates caught QUIT signal, exiting',3);
-      close SERVER; exit;
-   };
-
+   $SIG{'QUIT'} = sub {&debug('spong updates caught QUIT signal, exiting');
+                       close SERVER; exit;};
+   $SIG{'HUP'} = sub {&debug('spong updates caught HUP signal, exiting');
+                       close SERVER; exit;};
 
-   my $proto = getprotobyname( 'tcp' );
-   my $p     = pack( "l", 1 );
 
-   socket( SERVER, PF_INET, SOCK_STREAM, $proto )        || die "socket: $!";
-   setsockopt( SERVER, SOL_SOCKET, SO_REUSEADDR, $p )    || die "sockopt: $!";
-   bind( SERVER, sockaddr_in( $SPONG_UPDATE_PORT, INADDR_ANY ) ) || 
-      die "bind: $!";
-   listen( SERVER, SOMAXCONN )                           || die "listen: $!";
+   # Set up the socket to listen to
+   my( $sock, $client );
+   $sock = IO::Socket::INET->new( Listen   => SOMAXCONN,
+                                  LocalPort => $main::SPONG_UPDATE_PORT,
+                                  Proto    => 'tcp',
+                                  Timeout  => 30,
+                                  Reuse    => 1,
+                                );
+   if (! defined $sock ) { die "socket: $!"; }
 
    &debug( "update server socket setup, listening for connections" );
 
    while( 1 ) {
-      next unless ( $paddr = accept( CLIENT, SERVER ) );
+      next unless ( $client = $sock->accept() );
+      my $paddr = $client->peerhost();
 
       # &validate_connection( $paddr );  - need to do something here...
 
       # Read all from the client, and disconnect, we process the message next.
 
-      my $header = <CLIENT>; chomp $header;
+      my( $header, $ok ) = ( "", 0 );
       my( $message, $cnt, $line ) = ( "", "", "" );
-      while( defined( $line = <CLIENT> ) ) { 
-        last if ($cnt += length($line)) > 100000;
-        $message .= $line; 
-      }
-      close( CLIENT );
+
+      # Set an alarm on this block in case the client runs into problems
+      eval 
+      {  
+         local $SIG{'ALRM'} = sub { die; };
+         alarm($SPONG_SERVER_ALARM) if $SPONG_SERVER_ALARM;
+
+         $header = <$client>; chomp $header;
+         while( defined( $line = <$client> ) ) { 
+           last if ($cnt += length($line)) > 100000;
+           $message .= $line; 
+         }
+
+         $ok = 1;
+      };
+      alarm(0);
+      undef $client;
+
+      if ( ! $ok ) {
+         &error( "ss_update: Connection from $paddr timed out" );
+         next;
+     }
 
       # Now depending on what kind of message it is, pass it off to a routine
       # that can process the message.  Currently valid messages are "status", 
       # "ack", "config", and "stat".
 
       if( $header =~ /^status\b/ ) { &save_status( $header, $message ); next; }
-      if( $header =~ /^event\b/ ) { &save_event( $header, $message ); next; }
-      if( $header =~ /^page\b/ ) { &save_page( $header, $message ); next; }
       if( $header =~ /^ack-del\b/ ) { &del_ack( $header, $message ); next; }
       if( $header =~ /^ack\b/ )     { &save_ack( $header, $message ); next; }
       #   if( $header =~ /^config\b/ ) { &save_config( $header, $message ); }
@@ -255,6 +268,7 @@ sub listen_for_updates {
    }
 }
 
+
 # This procedure listens for connections at port 1984 (the BigBrother port), and
 # each time a connection is made, it grabs the info that is being sent to us,
 # and hands it off to the function that saves that info to the database.  Then
@@ -262,53 +276,65 @@ sub listen_for_updates {
 # just continues to listen for update messages.
 
 sub listen_for_bb_updates {
-   # Set up the socket to listen to
 
    $SIG{'PIPE'} = 'IGNORE';
    $SIG{'TERM'} = $SIG{'HUP'} = $SIG{'QUIT'} = sub {
-      &debug('spong updates caught QUIT signal, exiting',3);
-      close SERVER; exit;
+      &debug('spong updates caught signal, exiting',3);
+      exit;
    };
-   $SIG{'HUP'} = sub {&debug('bb updates caught HUP signal, exiting',3);
-                       close SERVER; exit;};
-
-   my $proto = getprotobyname( 'tcp' );
-   my $p     = pack( "l", 1 );
 
-   socket( SERVER, PF_INET, SOCK_STREAM, $proto )        || die "socket: $!";
-   setsockopt( SERVER, SOL_SOCKET, SO_REUSEADDR, $p )    || die "sockopt: $!";
-   bind( SERVER, sockaddr_in( $SPONG_BB_UPDATE_PORT, INADDR_ANY ) ) || 
-      die "bind: $!";
-   listen( SERVER, SOMAXCONN )                           || die "listen: $!";
+   # Set up the socket to listen to
+   my( $sock, $client );
+   $sock = IO::Socket::INET->new( Listen   => SOMAXCONN,
+                                  LocalPort => $main::SPONG_BB_UPDATE_PORT,
+                                  Proto    => 'tcp',
+                                  Timeout  => 30,
+                                  Reuse    => 1,
+                                );
+   if (! defined $sock ) { die "socket: $!"; }
 
    &debug( "bb update server socket setup, listening for connections" );
 
    while( 1 ) {
-      next unless ( $paddr = accept( CLIENT, SERVER ) );
+      next unless ( $client = $sock->accept() );
+      my $paddr = $client->peerhost();
 
       # &validate_connection( $paddr );  - need to do something here...
 
       # Read all from the client, and disconnect, we process the message next.
 
-      my $header = <CLIENT>; chomp $header;
+      my( $header, $ok ) = ( "", 0 );
       my( $message, $cnt, $line ) = ( "", "", "" );
-      while( defined( $line = <CLIENT> ) ) { 
-        last if ($cnt += length($line)) > 100000;
-        $message .= $line; 
+
+      eval {
+         local $SIG{'ALRM'} = sub { die; };
+         alarm($SPONG_SERVER_ALARM) if $SPONG_SERVER_ALARM;
+
+         $header = <$client>; chomp $header;
+         while( defined( $line = <$client> ) ) { 
+           last if ($cnt += length($line)) > 100000;
+           $message .= $line; 
+         }
+
+         $ok = 1;
+      };
+      alarm(0);
+      undef $client;
+
+      if ( ! $ok ) {
+         &error( "ss_update: Connection from $paddr timed out" );
+         next;
       }
-      close( CLIENT );
 
-   &debug($message,8);
+      &debug($message,8);
 
-#      # Now depending on what kind of message it is, pass it off to a routine
-#      # that can process the message.  Currently valid messages are "status", 
-#      # "ack", "config", and "stat".
+      # Now depending on what kind of message it is, pass it off to a routine
+      # that can process the message. 
 
-      if( $header =~ /^status\b/ )  { &save_bb_status( $header, $message ); next;}
-#      if( $header =~ /^ack-del\b/ ) { &del_ack( $header, $message ); next; }
-#      if( $header =~ /^ack\b/ )     { &save_ack( $header, $message ); next; }
-#      #   if( $header =~ /^config\b/ ) { &save_config( $header, $message ); }
-#      #   if( $header =~ /^stat\b/ )   { &save_stat( $header, $message ); }
+      if( $header =~ /^status\b/ ) {
+          &save_bb_status( $header, $message );
+          next;
+      }
    }
 }
 
@@ -319,7 +345,6 @@ sub listen_for_bb_updates {
 # that will be passed back to the client making the request.  This procedure does not exit, it just to listen for more query requests.
 
 sub listen_for_queries {
-   # Set up the socket to listen to
 
    $SIG{'PIPE'} = 'IGNORE';
    $SIG{'TERM'} = $SIG{'HUP'} = $SIG{'QUIT'} = sub {
@@ -327,19 +352,21 @@ sub listen_for_queries {
       close SERVER; exit;
    };
 
-   my $proto = getprotobyname( 'tcp' );
-   my $p     = pack( "l", 1 );
-
-   socket( SERVER, PF_INET, SOCK_STREAM, $proto )        || die "socket: $!";
-   setsockopt( SERVER, SOL_SOCKET, SO_REUSEADDR, $p )    || die "sockopt: $!";
-   bind( SERVER, sockaddr_in( $SPONG_QUERY_PORT, INADDR_ANY ) ) || 
-      die "bind: $!";
-   listen( SERVER, SOMAXCONN )                           || die "listen: $!";
+   # Set up the socket to listen to
+   my( $sock, $client );
+   $sock = IO::Socket::INET->new( Listen   => SOMAXCONN,
+                                  LocalPort => $main::SPONG_QUERY_PORT,
+                                  Proto    => 'tcp',
+                                  Timeout  => 30,
+                                  Reuse    => 1,
+                                );
+   if (! defined $sock ) { die "socket: $!"; }
 
    &debug( "query server socket setup, listening for connections" );
 
    while( 1 ) {
-      next unless ( $paddr = accept( CLIENT, SERVER ) );
+      next unless ( $client = $sock->accept() );
+      my $paddr = $client->peerhost();
 
       # &validate_connection( $paddr );  - need to do something here...
 
@@ -347,7 +374,7 @@ sub listen_for_queries {
       # updates however, as we need to send back some information.  Query
       # requests are simple one line messages.
 
-      my $header = <CLIENT>; chomp $header; $header =~ s/\r//;
+      my $header = <$client>; chomp $header; $header =~ s/\r//;
       my( $query, $hosts, $type, $view, $other ) =
         ( $header =~ /^(\w+)\s+\[([^\]]*)\]\s+(\w+)\s+(\w+)\b\s*(.*)$/ );
 
@@ -355,12 +382,12 @@ sub listen_for_queries {
       # that can process the message.  
 
       my( @args ) = ( $hosts, $type, $view );   # Just shortens up the code...
-      my $output = select CLIENT;
+      my $output = select $client;
 
       &debug( "[$$] showing $query information for $hosts [$type:$view]" );
 
       if( $query eq "problems" ) { &show_problems( @args ); }
-# Disabled for now into all of Herbies web enchanges are added
+# Disabled for now into all of Herbie's web enchanges are added
 #      if( $query eq "warnings" ) { &show_warnings( @args ); }
       if( $query eq "summary" )  { &show_summary( @args ); }
       if( $query eq "history" )  { &show_history( @args ); }
@@ -375,7 +402,7 @@ sub listen_for_queries {
       if( $query eq "overview" ) { &show_overview( @args, $other ); }
       if( $query eq "ovproblems" ) { &show_ovproblems( @args, $other ); }
 
-      close( CLIENT );
+      undef $client;
       select $output;
    }
 }
@@ -1108,6 +1135,11 @@ sub load_config_files {
 
 sub handle_signals {
 
+   # Clear out signal mask in case we inherit any blocked sigs
+
+   my $sigset = POSIX::SigSet->new;
+   sigprocmask(SIG_SETMASK, $sigset );
+
    # Set up some signal handlers to handle our death gracefully, and also
    # listen for the HUP signal, and if we see that, we re-exec ourself.
 
@@ -1115,6 +1147,7 @@ sub handle_signals {
    $SIG{'TERM'} = \&exit_handler;
    $SIG{'HUP'}  = \&hup_handler;
 
+
    # If the user gives us the --restart or --kill flags, then we signal the
    # currently running spong-client process, and tell it to either die, or
    # re-exec itself (which causes it to re-read it's configuration files.
@@ -1132,6 +1165,9 @@ sub handle_signals {
       exit(0);
    }
 
+   # Check to see if we are already running 
+   &already_running();
+
    # Write out our pid files, so that others can signal us.
 
    system( "echo $$ >$SPONGTMP/spong-server.pid" );
@@ -1184,6 +1220,22 @@ sub save_data {
    }
 }
 
+# This routine check to see if another instance of spong-server is already
+# running. If there is another instance, this instance will complain and die
+sub already_running {
+   # if there is a PID file
+   if ( -f "$SPONGTMP/spong-server.pid" ) {
+      # Read the pid
+      open( PID, "$SPONGTMP/spong-server.pid" ) || die "Can't open pid: $!";
+      my $pid = <PID>; chomp $pid;
+      close PID;
+
+      if ( kill 0,$pid ) {
+         &error("Spong-server is already running as pid $pid");
+         exit 1;
+      }
+   }
+}
 
 # Output functions, one for debugging information, the other for errors.