From 952342cbed7424da1c0216a238bbb77007a10131 Mon Sep 17 00:00:00 2001 From: Stephen L Johnson Date: Wed, 1 Mar 2000 22:13:41 +0000 Subject: [PATCH] cleared out signal mask in case of inherited blocked signals. moved call to &already_running() to handle_signals() --- src/spong-server.pl | 188 ++++++++++++++++++++++++++++---------------- 1 file changed, 120 insertions(+), 68 deletions(-) diff --git a/src/spong-server.pl b/src/spong-server.pl index 45b6d68..40cce7d 100755 --- a/src/spong-server.pl +++ b/src/spong-server.pl @@ -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 = ; chomp $header; + my( $header, $ok ) = ( "", 0 ); my( $message, $cnt, $line ) = ( "", "", "" ); - while( defined( $line = ) ) { - 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 = ; chomp $header; + my( $header, $ok ) = ( "", 0 ); my( $message, $cnt, $line ) = ( "", "", "" ); - while( defined( $line = ) ) { - 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 = ; 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 = ; 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. -- 2.30.2