#
#
+
my $self = shift;
return (1, $self->msg('e5')) if $self->inscript;
-# log out text
-if ($self->is_user && -e localdata("logout")) {
- open(I, localdata("logout")) or confess;
- my @in = <I>;
- close(I);
- $self->send_now('D', @in);
- sleep(1);
-}
+my $fn = localdata("logout");
+dbg("fn: $fn " . (-e $fn ? 'exists' : 'missing'));
-#$self->send_now('Z', "");
+if ($self->is_user && -e $fn) {
+ $self->send_file($fn);
+}
$self->disconnect;
$self->send_rcmd_reply($main::mycall, $fromnode, $user, "sorry...!");
return;
}
- Log('rcmd', 'in', ($ref->{priv}||0), $fromnode, $cmd);
+ Log('rcmd', 'in', ($ref->{priv}||0), $fromnode, $cmd, $user);
my $cref = Route::Node::get($fromnode);
unless ($cref && UNIVERSAL::isa($cref, 'Route')) {
dbg("DXProt process_rcmd: Route $fromnode isn't a reference (tell G1TLH)");
while (@_) {
my $line = shift;
$line =~ s/\s*$//;
- Log('rcmd', 'out', $fromnode, $line);
+ Log('rcmd', 'out', $fromnode, $line, $user);
if ($self->is_clx) {
$self->send(pc85($main::mycall, $fromnode, $user, "$main::mycall:$line"));
} else {
use DXDebug;
use Timer;
-use vars qw($now %conns $noconns $cnum $total_in $total_out $connect_timeout);
+use vars qw($now %conns $noconns $cnum $total_in $total_out $connect_timeout $disc_waittime);
$total_in = $total_out = 0;
$cnum = 0;
$connect_timeout = 5;
+$disc_waittime = 3;
+
+our %delqueue;
#
#-----------------------------------------------------------------
return $pid;
}
-sub disconnect
+sub disconnect
{
- my $conn = shift;
- return if exists $conn->{disconnecting};
+ my $conn = shift;
+ my $count = $conn->{disconnecting}++;
+ if (isdbg('connll')) {
+ my ($pkg, $fn, $line) = caller;
+ dbg((ref $conn) . "::disconnect on call $conn->{call} attempt $conn->{disconnecting} called from ${pkg}::${fn} line $line ");
+ }
+ return if $count;
+
+
+ my $sock = $conn->{sock};
+ if ($sock) {
+
+ # remove me from the active list
+ my $call;
+ if ($call = $conn->{call}) {
+ my $ref = $conns{$call};
+ delete $conns{$call} if $ref && $ref == $conn;
+ }
+ $conn->{delay} = Mojo::IOLoop->delay (
+# Mojo::IOLoop->delay (
+ sub {
+ my $delay = shift;
+ dbg("before drain $call");
+ $sock->on(drain => $delay->begin);
+ 1;
+ },
+ sub {
+ my $delay = shift;
+ _close_it($conn);
+ 1;
+ }
+ );
+ $conn->{delay}->wait;
+
+ $delqueue{$conn} = $conn; # save this connection until everything is finished
+ } else {
+ dbg((ref $conn) . " socket missing on $conn->{call}") if isdbg('connll');
+ _close_it($conn);
+ }
+}
- $conn->{disconnecting} = 1;
+sub _close_it
+{
+ my $conn = shift;
my $sock = delete $conn->{sock};
$conn->{state} = 'E';
$conn->{timeout}->del if $conn->{timeout};
+ if (isdbg('connll')) {
+ my ($pkg, $fn, $line) = caller;
+ dbg((ref $conn) . "::_close_it on call $conn->{call} attempt $conn->{disconnecting} called from ${pkg}::${fn} line $line ");
+ }
+
# be careful to delete the correct one
my $call;
if ($call = $conn->{call}) {
delete $conns{$call} if $ref && $ref == $conn;
}
$call ||= 'unallocated';
- dbg((ref $conn) . " Connection $conn->{cnum} $call disconnected") if isdbg('connll');
+
+ dbg((ref $conn) . " Connection $conn->{cnum} $call starting to close") if isdbg('connll');
if ($conn->{on_disconnect}) {
&{$conn->{on_disconnect}}($conn);
}
+ if ($sock) {
+ dbg((ref $conn) . " Connection $conn->{cnum} $call closing gracefully") if isdbg('connll');
+ $sock->close_gracefully;
+ }
+
# get rid of any references
for (keys %$conn) {
if (ref($conn->{$_})) {
}
}
- $sock->close_gracefully if defined $sock && $sock->can('close_gracefully');
- undef $sock;
+ delete $delqueue{$conn}; # finally remove the $conn
unless ($main::is_win) {
kill 'TERM', $conn->{pid} if exists $conn->{pid};
sub DESTROY
{
my $conn = shift;
+ my $call = $conn->{call} || 'unallocated';
+
+ if (isdbg('connll')) {
+ my ($pkg, $fn, $line) = caller;
+ dbg((ref $conn) . "::DESTROY on call $call called from ${pkg}::${fn} line $line ");
+
+ }
+
my $call = $conn->{call} || 'unallocated';
my $host = $conn->{peerhost} || '';
my $port = $conn->{peerport} || '';
my $sock = $conn->{sock};
- $sock->close_gracefully if defined $sock && $sock->can('close_gracefully');
+ if ($sock) {
+ $sock->close_gracefully;
+ }
$noconns--;
dbg((ref $conn) . " Connection $conn->{cnum} $call [$host $port] being destroyed (total $noconns)") if isdbg('connll');
sub idle_loop
{
BPQMsg::process();
+ DXCommandmode::process(); # process ongoing command mode stuff
+ DXProt::process(); # process ongoing ak1a pcxx stuff
if (defined &Local::process) {
eval {
}
IsoTime::update($systime);
DXCron::process(); # do cron jobs
- DXCommandmode::process(); # process ongoing command mode stuff
DXXml::process();
- DXProt::process(); # process ongoing ak1a pcxx stuff
DXConnect::process();
DXMsg::process();
DXDb::process();
DXDupe::process();
DXCron::process(); # do cron jobs
IsoTime::update($systime);
- DXProt::process(); # process ongoing ak1a pcxx stuff
DXConnect::process();
DXUser::process();
AGWMsg::process();