Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
#!/usr/bin/perl -w #use warnings; use IO::Socket; use MIME::Base64 (); require "zpopd.config.pl"; # ********* FUNCTIONS ********* sub print_timestamp { print time(); print ": "; } sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n" } sub write_child_pid_file { if (!open(PIDFILE, ">$pid_dir/@_")) { print "Error: Could not write child pid to file "; print "$pid_dir/@_\n"; exit; } close(PIDFILE); } my $sleep_time = 2; my %children_pid; my %connection_info; my %children_time; my $result; my $parent_pid; my $pid; my $x; my $received_string; my $n_connections; my $new_sock; $result = 0; $listen_ip_address = $listen_ip_address; $welcome_message = "+OK $welcome_message\r\n"; $goodbye_message = "+OK $goodbye_message\r\n"; $timeout_message = "+OK $timeout_message\r\n"; $global_max_connections = $global_max_connections; $max_connections = $max_connections; $timeout = $timeout; $result = `stat -c %A $pid_dir 2>&1 | cat | cut -b 1`; $result =~ s/\n//; $result =~ s/\r//; if ($result ne "d") { #print "Error: Could not access directory $pid_dir\n"; #exit; } $result = ""; if (!open(PIDFILE, ">$pid_dir/$parent_pid_filename")) { print "Error: Could not write parent pid to file "; print "$pid_dir/$parent_pid_filename\n"; exit; } $pid = $$; printf(PIDFILE $pid); close(PIDFILE); my $sock = new IO::Socket::INET( LocalPort => "$listen_port", Proto => 'tcp', Listen => $global_max_connections, Reuse => 1); die "Could not create socket: $!\n" unless $sock; logmsg "server started on port $listen_port"; $n_connections = 0; local $SIG{ALRM} = sub { foreach my $key (keys %children_time) { if ((time() - $children_time{$key}) >= $timeout) { kill("TERM", $key); delete($children_time{$key}); } } }; local $SIG{INT} = sub { if ($pid == 0) # is this process a child? { unlink("$pid_dir/$$"); } else # or is it a parent { wait(); print_timestamp(); print "Server with PID $$ exiting.\n"; unlink("$pid_dir/$parent_pid_filename"); } exit; }; local $SIG{QUIT} = sub { unlink("$pid_dir/$parent_pid_filename"); unlink("$pid_dir/$parent_pid_filename"); print "Server shutdown cleanly\n"; exit; }; local $SIG{USR1} = sub { my $child_pid; my $client_ip_address; $child_pid = wait(); if ($child_pid != -1) { $client_ip_address = $children_pid{"$child_pid"}; $connection_info{"$client_ip_address"}--; unlink("$pid_dir/$child_pid"); delete($children_pid{"$child_pid"}); delete($children_time{"$child_pid"}); $n_connections--; } }; local $SIG{TERM} = sub { #******************Line 148 is below**************** my $client_sock = getpeername($new_sock); my($client_port,$client_addr) = sockaddr_in($client_sock); my $client_ip_addr = inet_ntoa($client_addr); send($new_sock, $timeout_message, 0); kill("USR1", getppid()); $param = $$."|$client_ip_addr|quit"; $param = MIME::Base64::encode($param); $param =~ s/\r\n/_/g; $param =~ s/\n/_/g; `/usr/local/apache/php/bin/php -f ./zpop.php $param > /dev/null`; exit; }; while (1) { alarm $sleep_time; $new_sock = $sock->accept(); alarm 0; if (($n_connections >= $global_max_connections) && defined($new_s +ock)) { close($new_sock); next; } if (!defined($new_sock)) { next; } my $client_sock = getpeername($new_sock); my($client_port,$client_addr) = sockaddr_in($client_sock); my $client_ip_addr = inet_ntoa($client_addr); if (!defined($connection_info{"$client_ip_addr"})) { $connection_info{"$client_ip_addr"} = 1; } else { if ($connection_info{"$client_ip_addr"} >= $max_connections) { close($new_sock); next; } else { $connection_info{"$client_ip_addr"}++; } } $pid = fork(); if ($pid == 0) # child process { write_child_pid_file($$); send($new_sock, $welcome_message, 0); while(<$new_sock>) { $received_string = $_; if (($received_string =~ /^quit/i)) { send($new_sock, $goodbye_message, 0); $param = $$."|$client_ip_addr|quit"; $param = MIME::Base64::encode($param); $param =~ s/\r\n/_/g; $param =~ s/\n/_/g; `/usr/local/apache/php/bin/php -f ./zpop.php $param > + /dev/null`; close($sock); kill("USR1", getppid()); exit; } else { $param = $$."|$client_ip_addr|".$received_string; $param = MIME::Base64::encode($param); $param =~ s/\r\n/_/g; $param =~ s/\n/_/g; print $new_sock `/usr/local/apache/php/bin/php -f ./zp +op.php $param 2>&1`; } } } else { my $client_sock = getpeername($new_sock); my($client_port,$client_addr) = sockaddr_in($client_sock); my $client_ip_addr = inet_ntoa($client_addr); $children_pid{"$pid"} = $client_ip_addr; $children_time{"$pid"} = time(); $n_connections++; } }
our $listen_ip_address = "localhost";<br> our $listen_port = 110;<br> our $timeout = 300;<br> our $max_connections = 3;<br> our $global_max_connections = SOMAXCONN;<br> our $pid_dir = "./pid/zpopd";<br> our $parent_pid_filename = "parent.pid";<br> our $welcome_message = "POP3 Server Ready";<br> our $goodbye_message = "POP3 Server Signing Off";<br> our $timeout_message = "POP3 Server Signing Off (timeout)";<br>
Readmore tags added by GrandFather
br tags removed from code by GrandFather
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Script Creates Zombies
by cdarke (Prior) on Jun 21, 2009 at 10:17 UTC |