--- loncom/lond 2000/12/05 20:19:46 1.28
+++ loncom/lond 2001/11/29 18:56:31 1.60
@@ -1,6 +1,31 @@
#!/usr/bin/perl
# The LearningOnline Network
# lond "LON Daemon" Server (port "LOND" 5663)
+#
+# $Id: lond,v 1.60 2001/11/29 18:56:31 www Exp $
+#
+# Copyright Michigan State University Board of Trustees
+#
+# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
+#
+# LON-CAPA is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# LON-CAPA is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with LON-CAPA; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# /home/httpd/html/adm/gpl.txt
+#
+# http://www.lon-capa.org/
+#
# 5/26/99,6/4,6/10,6/11,6/14,6/15,6/26,6/28,6/30,
# 7/8,7/9,7/10,7/12,7/17,7/19,9/21,
# 10/7,10/8,10/9,10/11,10/13,10/15,11/4,11/16,
@@ -9,8 +34,18 @@
# 06/26 Scott Harrison
# 06/29,06/30,07/14,07/15,07/17,07/20,07/25,09/18 Gerd Kortemeyer
# 12/05 Scott Harrison
-# 12/05 Gerd Kortemeyer
+# 12/05,12/13,12/29 Gerd Kortemeyer
+# Jan 01 Scott Harrison
+# 02/12 Gerd Kortemeyer
+# 03/15 Scott Harrison
+# 03/24 Gerd Kortemeyer
+# 04/02 Scott Harrison
+# 05/11,05/28,08/30 Gerd Kortemeyer
+# 9/30,10/22,11/13,11/15,11/16 Scott Harrison
+# 11/26,11/27 Gerd Kortemeyer
#
+###
+
# based on "Perl Cookbook" ISBN 1-56592-243-3
# preforker - server who forks first
# runs as a daemon
@@ -26,6 +61,11 @@ use Crypt::IDEA;
use LWP::UserAgent();
use GDBM_File;
use Authen::Krb4;
+use lib '/home/httpd/lib/perl/';
+use localauth;
+
+my $status='';
+my $lastlog='';
# grabs exception and records it to log before exiting
sub catchexception {
@@ -35,26 +75,12 @@ sub catchexception {
&logthis("CRITICAL: "
."ABNORMAL EXIT. Child $$ for server $wasserver died through "
."a crash with this error msg->[$error]");
+ &logthis('Famous last words: '.$status.' - '.$lastlog);
if ($client) { print $client "error: $error\n"; }
+ $server->close();
die($error);
}
-# grabs exception and records it to log before exiting
-# NOTE: we must NOT use the regular (non-overrided) die function in
-# the code because a handler CANNOT be attached to it
-# (despite what some of the documentation says about SIG{__DIE__}.
-
-sub catchdie {
- my ($message)=@_;
- $SIG{'QUIT'}='DEFAULT';
- $SIG{__DIE__}='DEFAULT';
- &logthis("CRITICAL: "
- ."ABNORMAL EXIT. Child $$ for server $wasserver died through "
- ."\_\_DIE\_\_ with this error msg->[$message]");
- if ($client) { print $client "error: $message\n"; }
- die($message);
-}
-
# -------------------------------- Set signal handlers to record abnormal exits
$SIG{'QUIT'}=\&catchexception;
@@ -62,8 +88,7 @@ $SIG{__DIE__}=\&catchexception;
# ------------------------------------ Read httpd access.conf and get variables
-open (CONFIG,"/etc/httpd/conf/access.conf")
- || catchdie "Can't read access.conf";
+open (CONFIG,"/etc/httpd/conf/access.conf") || die "Can't read access.conf";
while ($configline=) {
if ($configline =~ /PerlSetVar/) {
@@ -74,6 +99,16 @@ while ($configline=) {
}
close(CONFIG);
+# ----------------------------- Make sure this process is running from user=www
+my $wwwid=getpwnam('www');
+if ($wwwid!=$<) {
+ $emailto="$perlvar{'lonAdmEMail'},$perlvar{'lonSysEMail'}";
+ $subj="LON: $perlvar{'lonHostID'} User ID mismatch";
+ system("echo 'User ID mismatch. lond must be run as user www.' |\
+ mailto $emailto -s '$subj' > /dev/null");
+ exit 1;
+}
+
# --------------------------------------------- Check if other instance running
my $pidfile="$perlvar{'lonDaemons'}/logs/lond.pid";
@@ -82,15 +117,14 @@ if (-e $pidfile) {
my $lfh=IO::File->new("$pidfile");
my $pide=<$lfh>;
chomp($pide);
- if (kill 0 => $pide) { catchdie "already running"; }
+ if (kill 0 => $pide) { die "already running"; }
}
$PREFORK=4; # number of children to maintain, at least four spare
# ------------------------------------------------------------- Read hosts file
-open (CONFIG,"$perlvar{'lonTabDir'}/hosts.tab")
- || catchdie "Can't read host file";
+open (CONFIG,"$perlvar{'lonTabDir'}/hosts.tab") || die "Can't read host file";
while ($configline=) {
my ($id,$domain,$role,$name,$ip)=split(/:/,$configline);
@@ -107,7 +141,7 @@ $server = IO::Socket::INET->new(LocalPor
Proto => 'tcp',
Reuse => 1,
Listen => 10 )
- or catchdie "making socket: $@\n";
+ or die "making socket: $@\n";
# --------------------------------------------------------- Do global variables
@@ -129,6 +163,7 @@ sub REAPER { # ta
sub HUNTSMAN { # signal handler for SIGINT
local($SIG{CHLD}) = 'IGNORE'; # we're going to kill our children
kill 'INT' => keys %children;
+ &logthis("Free socket: ".shutdown($server,2)); # free up socket
my $execdir=$perlvar{'lonDaemons'};
unlink("$execdir/logs/lond.pid");
&logthis("CRITICAL: Shutting down");
@@ -138,12 +173,26 @@ sub HUNTSMAN { # si
sub HUPSMAN { # signal handler for SIGHUP
local($SIG{CHLD}) = 'IGNORE'; # we're going to kill our children
kill 'INT' => keys %children;
- close($server); # free up socket
+ &logthis("Free socket: ".shutdown($server,2)); # free up socket
&logthis("CRITICAL: Restarting");
+ unlink("$execdir/logs/lond.pid");
my $execdir=$perlvar{'lonDaemons'};
exec("$execdir/lond"); # here we go again
}
+sub checkchildren {
+ &initnewstatus();
+ &logstatus();
+ &logthis('Going to check on the children');
+ map {
+ sleep 1;
+ unless (kill 'USR1' => $_) {
+ &logthis ('Child '.$_.' is dead');
+ &logstatus($$.' is dead');
+ }
+ } sort keys %children;
+}
+
# --------------------------------------------------------------------- Logging
sub logthis {
@@ -152,9 +201,34 @@ sub logthis {
my $fh=IO::File->new(">>$execdir/logs/lond.log");
my $now=time;
my $local=localtime($now);
+ $lastlog=$local.': '.$message;
print $fh "$local ($$): $message\n";
}
+# ------------------------------------------------------------------ Log status
+
+sub logstatus {
+ my $docdir=$perlvar{'lonDocRoot'};
+ my $fh=IO::File->new(">>$docdir/lon-status/londstatus.txt");
+ print $fh $$."\t".$status."\t".$lastlog."\n";
+}
+
+sub initnewstatus {
+ my $docdir=$perlvar{'lonDocRoot'};
+ my $fh=IO::File->new(">$docdir/lon-status/londstatus.txt");
+ my $now=time;
+ my $local=localtime($now);
+ print $fh "LOND status $local - parent $$\n\n";
+}
+
+# -------------------------------------------------------------- Status setting
+
+sub status {
+ my $what=shift;
+ my $now=time;
+ my $local=localtime($now);
+ $status=$local.': '.$what;
+}
# -------------------------------------------------------- Escape Special Chars
@@ -290,9 +364,9 @@ sub ishome {
$fpid=fork;
exit if $fpid;
-catchdie "Couldn't fork: $!" unless defined ($fpid);
+die "Couldn't fork: $!" unless defined ($fpid);
-POSIX::setsid() or catchdie "Can't start new session: $!";
+POSIX::setsid() or die "Can't start new session: $!";
# ------------------------------------------------------- Write our PID on disk
@@ -301,6 +375,7 @@ open (PIDSAVE,">$execdir/logs/lond.pid")
print PIDSAVE "$$\n";
close(PIDSAVE);
&logthis("CRITICAL: ---------- Starting ----------");
+&status('Starting');
# ------------------------------------------------------- Now we are on our own
@@ -311,13 +386,19 @@ for (1 .. $PREFORK) {
# ----------------------------------------------------- Install signal handlers
+&status('Forked children');
+
$SIG{CHLD} = \&REAPER;
$SIG{INT} = $SIG{TERM} = \&HUNTSMAN;
$SIG{HUP} = \&HUPSMAN;
+$SIG{USR1} = \&checkchildren;
# And maintain the population.
while (1) {
+ &status('Sleeping');
sleep; # wait for a signal (i.e., child's death)
+ &logthis('Woke up');
+ &status('Woke up');
for ($i = $children; $i < $PREFORK; $i++) {
make_new_child(); # top up the child pool
}
@@ -331,31 +412,36 @@ sub make_new_child {
# block signal for fork
$sigset = POSIX::SigSet->new(SIGINT);
sigprocmask(SIG_BLOCK, $sigset)
- or catchdie "Can't block SIGINT for fork: $!\n";
+ or die "Can't block SIGINT for fork: $!\n";
- catchdie "fork: $!" unless defined ($pid = fork);
+ die "fork: $!" unless defined ($pid = fork);
if ($pid) {
# Parent records the child's birth and returns.
sigprocmask(SIG_UNBLOCK, $sigset)
- or catchdie "Can't unblock SIGINT for fork: $!\n";
+ or die "Can't unblock SIGINT for fork: $!\n";
$children{$pid} = 1;
$children++;
+ &status('Started child '.$pid);
return;
} else {
# Child can *not* return from this subroutine.
$SIG{INT} = 'DEFAULT'; # make SIGINT kill us as it did before
-
+ $SIG{USR1}= \&logstatus;
+ $lastlog='Forked ';
+ $status='Forked';
+
# unblock signals
sigprocmask(SIG_UNBLOCK, $sigset)
- or catchdie "Can't unblock SIGINT for fork: $!\n";
+ or die "Can't unblock SIGINT for fork: $!\n";
$tmpsnum=0;
# handle connections until we've reached $MAX_CLIENTS_PER_CHILD
for ($i=0; $i < $MAX_CLIENTS_PER_CHILD; $i++) {
+ &status('Idle, waiting for connection');
$client = $server->accept() or last;
-
+ &status('Accepted connection');
# =============================================================================
# do something with the connection
# -----------------------------------------------------------------------------
@@ -365,14 +451,19 @@ sub make_new_child {
my $clientip=inet_ntoa($iaddr);
my $clientrec=($hostid{$clientip} ne undef);
&logthis(
-"INFO: Connect from $clientip ($hostid{$clientip})");
+"INFO: Connection $i, $clientip ($hostid{$clientip})"
+ );
+ &status("Connecting $clientip ($hostid{$clientip})");
my $clientok;
if ($clientrec) {
+ &status("Waiting for init from $clientip ($hostid{$clientip})");
my $remotereq=<$client>;
$remotereq=~s/\W//g;
if ($remotereq eq 'init') {
my $challenge="$$".time;
print $client "$challenge\n";
+ &status(
+ "Waiting for challenge reply from $clientip ($hostid{$clientip})");
$remotereq=<$client>;
$remotereq=~s/\W//g;
if ($challenge eq $remotereq) {
@@ -381,27 +472,29 @@ sub make_new_child {
} else {
&logthis(
"WARNING: $clientip did not reply challenge");
- print $client "bye\n";
+ &status('No challenge reply '.$clientip);
}
} else {
&logthis(
"WARNING: "
."$clientip failed to initialize: >$remotereq< ");
- print $client "bye\n";
+ &status('No init '.$clientip);
}
} else {
&logthis(
"WARNING: Unknown client $clientip");
- print $client "bye\n";
+ &status('Hung up on '.$clientip);
}
if ($clientok) {
# ---------------- New known client connecting, could mean machine online again
&reconlonc("$perlvar{'lonSockDir'}/$hostid{$clientip}");
&logthis(
"Established connection: $hostid{$clientip}");
+ &status('Will listen to '.$hostid{$clientip});
# ------------------------------------------------------------ Process requests
while (my $userinput=<$client>) {
chomp($userinput);
+ &status('Processing '.$hostid{$clientip}.': '.$userinput);
my $wasenc=0;
# ------------------------------------------------------------ See if encrypted
if ($userinput =~ /^enc/) {
@@ -450,6 +543,28 @@ sub make_new_child {
$loadavg =~ s/\s.*//g;
my $loadpercent=100*$loadavg/$perlvar{'lonLoadLim'};
print $client "$loadpercent\n";
+# ----------------------------------------------------------------- currentauth
+ } elsif ($userinput =~ /^currentauth/) {
+ if ($wasenc==1) {
+ my ($cmd,$udom,$uname)=split(/:/,$userinput);
+ my $proname=propath($udom,$uname);
+ my $passfilename="$proname/passwd";
+ if (-e $passfilename) {
+ my $pf = IO::File->new($passfilename);
+ my $realpasswd=<$pf>;
+ chomp($realpasswd);
+ my ($howpwd,$contentpwd)=split(/:/,$realpasswd);
+ my $availablecontent='';
+ if ($howpwd eq 'krb4') {
+ $availablecontent=$contentpwd;
+ }
+ print $client "$howpwd:$availablecontent\n";
+ } else {
+ print $client "unknown_user\n";
+ }
+ } else {
+ print $client "refused\n";
+ }
# ------------------------------------------------------------------------ auth
} elsif ($userinput =~ /^auth/) {
if ($wasenc==1) {
@@ -469,14 +584,27 @@ sub make_new_child {
(crypt($upass,$contentpwd) eq $contentpwd);
} elsif ($howpwd eq 'unix') {
$contentpwd=(getpwnam($uname))[1];
- $pwdcorrect=
- (crypt($upass,$contentpwd) eq $contentpwd);
+ my $pwauth_path="/usr/local/sbin/pwauth";
+ unless ($contentpwd eq 'x') {
+ $pwdcorrect=
+ (crypt($upass,$contentpwd) eq $contentpwd);
+ }
+ elsif (-e $pwauth_path) {
+ open PWAUTH, "|$pwauth_path" or
+ die "Cannot invoke authentication";
+ print PWAUTH "$uname\n$upass\n";
+ close PWAUTH;
+ $pwdcorrect=!$?;
+ }
} elsif ($howpwd eq 'krb4') {
$pwdcorrect=(
Authen::Krb4::get_pw_in_tkt($uname,"",
$contentpwd,'krbtgt',$contentpwd,1,
$upass) == 0);
- }
+ } elsif ($howpwd eq 'localauth') {
+ $pwdcorrect=&localauth::localauth($uname,$upass,
+ $contentpwd);
+ }
if ($pwdcorrect) {
print $client "authorized\n";
} else {
@@ -494,6 +622,8 @@ sub make_new_child {
my
($cmd,$udom,$uname,$upass,$npass)=split(/:/,$userinput);
chomp($npass);
+ $upass=&unescape($upass);
+ $npass=&unescape($npass);
my $proname=propath($udom,$uname);
my $passfilename="$proname/passwd";
if (-e $passfilename) {
@@ -508,7 +638,7 @@ sub make_new_child {
$salt=substr($salt,6,2);
my $ncpass=crypt($npass,$salt);
{ my $pf = IO::File->new(">$passfilename");
- print $pf "internal:$ncpass\n";; }
+ print $pf "internal:$ncpass\n"; }
print $client "ok\n";
} else {
print $client "non_authorized\n";
@@ -522,6 +652,145 @@ sub make_new_child {
} else {
print $client "refused\n";
}
+# -------------------------------------------------------------------- makeuser
+ } elsif ($userinput =~ /^makeuser/) {
+ my $oldumask=umask(0077);
+ if ($wasenc==1) {
+ my
+ ($cmd,$udom,$uname,$umode,$npass)=split(/:/,$userinput);
+ chomp($npass);
+ $npass=&unescape($npass);
+ my $proname=propath($udom,$uname);
+ my $passfilename="$proname/passwd";
+ if (-e $passfilename) {
+ print $client "already_exists\n";
+ } elsif ($udom ne $perlvar{'lonDefDomain'}) {
+ print $client "not_right_domain\n";
+ } else {
+ @fpparts=split(/\//,$proname);
+ $fpnow=$fpparts[0].'/'.$fpparts[1].'/'.$fpparts[2];
+ $fperror='';
+ for ($i=3;$i<=$#fpparts;$i++) {
+ $fpnow.='/'.$fpparts[$i];
+ unless (-e $fpnow) {
+ unless (mkdir($fpnow,0777)) {
+ $fperror="error:$!\n";
+ }
+ }
+ }
+ unless ($fperror) {
+ if ($umode eq 'krb4') {
+ {
+ my $pf = IO::File->new(">$passfilename");
+ print $pf "krb4:$npass\n";
+ }
+ print $client "ok\n";
+ } elsif ($umode eq 'internal') {
+ my $salt=time;
+ $salt=substr($salt,6,2);
+ my $ncpass=crypt($npass,$salt);
+ {
+ my $pf = IO::File->new(">$passfilename");
+ print $pf "internal:$ncpass\n";
+ }
+ print $client "ok\n";
+ } elsif ($umode eq 'localauth') {
+ {
+ my $pf = IO::File->new(">$passfilename");
+ print $pf "localauth:$npass\n";
+ }
+ print $client "ok\n";
+ } elsif ($umode eq 'unix') {
+ {
+ my $execpath="$perlvar{'lonDaemons'}/".
+ "lcuseradd";
+ {
+ my $se = IO::File->new("|$execpath");
+ print $se "$uname\n";
+ print $se "$npass\n";
+ print $se "$npass\n";
+ }
+ my $pf = IO::File->new(">$passfilename");
+ print $pf "unix:\n";
+ }
+ print $client "ok\n";
+ } elsif ($umode eq 'none') {
+ {
+ my $pf = IO::File->new(">$passfilename");
+ print $pf "none:\n";
+ }
+ print $client "ok\n";
+ } else {
+ print $client "auth_mode_error\n";
+ }
+ } else {
+ print $client "$fperror\n";
+ }
+ }
+ } else {
+ print $client "refused\n";
+ }
+ umask($oldumask);
+# -------------------------------------------------------------- changeuserauth
+ } elsif ($userinput =~ /^changeuserauth/) {
+ if ($wasenc==1) {
+ my
+ ($cmd,$udom,$uname,$umode,$npass)=split(/:/,$userinput);
+ chomp($npass);
+ $npass=&unescape($npass);
+ my $proname=propath($udom,$uname);
+ my $passfilename="$proname/passwd";
+ if ($udom ne $perlvar{'lonDefDomain'}) {
+ print $client "not_right_domain\n";
+ } else {
+ if ($umode eq 'krb4') {
+ {
+ my $pf = IO::File->new(">$passfilename");
+ print $pf "krb4:$npass\n";
+ }
+ print $client "ok\n";
+ } elsif ($umode eq 'internal') {
+ my $salt=time;
+ $salt=substr($salt,6,2);
+ my $ncpass=crypt($npass,$salt);
+ {
+ my $pf = IO::File->new(">$passfilename");
+ print $pf "internal:$ncpass\n";
+ }
+ print $client "ok\n";
+ } elsif ($umode eq 'localauth') {
+ {
+ my $pf = IO::File->new(">$passfilename");
+ print $pf "localauth:$npass\n";
+ }
+ print $client "ok\n";
+ } elsif ($umode eq 'unix') {
+ {
+ my $execpath="$perlvar{'lonDaemons'}/".
+ "lcuseradd";
+ {
+ my $se = IO::File->new("|$execpath");
+ print $se "$uname\n";
+ print $se "$npass\n";
+ print $se "$npass\n";
+ }
+ my $pf = IO::File->new(">$passfilename");
+ print $pf "unix:\n";
+ }
+ print $client "ok\n";
+ } elsif ($umode eq 'none') {
+ {
+ my $pf = IO::File->new(">$passfilename");
+ print $pf "none:\n";
+ }
+ print $client "ok\n";
+ } else {
+ print $client "auth_mode_error\n";
+ }
+ }
+ } else {
+ print $client "refused\n";
+ }
# ------------------------------------------------------------------------ home
} elsif ($userinput =~ /^home/) {
my ($cmd,$udom,$uname)=split(/:/,$userinput);
@@ -613,6 +882,9 @@ sub make_new_child {
print $sh "$clientip:$now\n";
}
}
+ unless ($fname=~/\.meta$/) {
+ unlink("$fname.meta.$hostid{$clientip}");
+ }
$fname=~s/\/home\/httpd\/html\/res/raw/;
$fname="http://$thisserver/".$fname;
print $client "$fname\n";
@@ -648,7 +920,7 @@ sub make_new_child {
chomp($what);
my $proname=propath($udom,$uname);
my $now=time;
- {
+ unless ($namespace=~/^nohist\_/) {
my $hfh;
if (
$hfh=IO::File->new(">>$proname/$namespace.hist")
@@ -773,7 +1045,7 @@ sub make_new_child {
chomp($what);
my $proname=propath($udom,$uname);
my $now=time;
- {
+ unless ($namespace=~/^nohist\_/) {
my $hfh;
if (
$hfh=IO::File->new(">>$proname/$namespace.hist")
@@ -844,7 +1116,7 @@ sub make_new_child {
chomp($what);
my $proname=propath($udom,$uname);
my $now=time;
- {
+ unless ($namespace=~/^nohist\_/) {
my $hfh;
if (
$hfh=IO::File->new(">>$proname/$namespace.hist")
@@ -863,7 +1135,8 @@ sub make_new_child {
$allkeys.=$key.':';
$hash{"$version:$rid:$key"}=$value;
}
- $allkeys=~s/:$//;
+ $hash{"$version:$rid:timestamp"}=$now;
+ $allkeys.='timestamp';
$hash{"$version:keys:$rid"}=$allkeys;
if (untie(%hash)) {
print $client "ok\n";
@@ -909,17 +1182,30 @@ sub make_new_child {
}
# ------------------------------------------------------------------- querysend
} elsif ($userinput =~ /^querysend/) {
- my ($cmd,$query)=split(/:/,$userinput);
+ my ($cmd,$query,
+ $custom,$customshow)=split(/:/,$userinput);
$query=~s/\n*$//g;
- print $client sqlreply("$hostid{$clientip}\&$query")."\n";
+ unless ($custom or $customshow) {
+ print $client "".
+ sqlreply("$hostid{$clientip}\&$query")."\n";
+ }
+ else {
+ print $client "".
+ sqlreply("$hostid{$clientip}\&$query".
+ "\&$custom"."\&$customshow")."\n";
+ }
# ------------------------------------------------------------------ queryreply
} elsif ($userinput =~ /^queryreply/) {
my ($cmd,$id,$reply)=split(/:/,$userinput);
my $store;
my $execdir=$perlvar{'lonDaemons'};
if ($store=IO::File->new(">$execdir/tmp/$id")) {
+ $reply=~s/\&/\n/g;
print $store $reply;
close $store;
+ my $store2=IO::File->new(">$execdir/tmp/$id.end");
+ print $store2 "done\n";
+ close $store2;
print $client "ok\n";
}
else {
@@ -1013,24 +1299,38 @@ sub make_new_child {
my $ulsout='';
my $ulsfn;
if (-e $ulsdir) {
- while ($ulsfn=<$ulsdir/*>) {
- my @ulsstats=stat($ulsfn);
+ if (opendir(LSDIR,$ulsdir)) {
+ while ($ulsfn=readdir(LSDIR)) {
+ my @ulsstats=stat($ulsdir.'/'.$ulsfn);
$ulsout.=$ulsfn.'&'.join('&',@ulsstats).':';
}
+ closedir(LSDIR);
+ }
} else {
$ulsout='no_such_dir';
}
if ($ulsout eq '') { $ulsout='empty'; }
print $client "$ulsout\n";
+# ------------------------------------------------------------------ Hanging up
+ } elsif (($userinput =~ /^exit/) ||
+ ($userinput =~ /^init/)) {
+ &logthis(
+ "Client $clientip ($hostid{$clientip}) hanging up: $userinput");
+ print $client "bye\n";
+ $client->close();
+ last;
# ------------------------------------------------------------- unknown command
} else {
# unknown command
print $client "unknown_cmd\n";
}
-# ------------------------------------------------------ client unknown, refuse
+# -------------------------------------------------------------------- complete
+ &status('Listening to '.$hostid{$clientip});
}
+# --------------------------------------------- client unknown or fishy, refuse
} else {
print $client "refused\n";
+ $client->close();
&logthis("WARNING: "
."Rejected client $clientip, closing connection");
}
@@ -1041,6 +1341,9 @@ sub make_new_child {
# tidy up gracefully and finish
+ $client->close();
+ $server->close();
+
# this exit is VERY important, otherwise the child will become
# a producer of more and more children, forking yourself into
# process death.