add more routing code together with associated commands
[spider.git] / perl / DXCommandmode.pm
index aea2064e615b3754bfb6ec849428211455702d94..0f80232ac8432636ef1d65a6f9a0bf609672e960 100644 (file)
@@ -32,13 +32,14 @@ use Sun;
 use Internet;
 
 use strict;
-use vars qw(%Cache %cmd_cache $errstr %aliases $scriptbase);
+use vars qw(%Cache %cmd_cache $errstr %aliases $scriptbase $maxerrors);
 
 %Cache = ();                                   # cache of dynamically loaded routine's mod times
 %cmd_cache = ();                               # cache of short names
 $errstr = ();                                  # error string from eval
 %aliases = ();                                 # aliases for (parts of) commands
 $scriptbase = "$main::root/scripts"; # the place where all users start scripts go
+$maxerrors = 20;                               # the maximum number of concurrent errors allowed before disconnection
 
 #
 # obtain a new connection this is derived from dxchannel
@@ -102,6 +103,11 @@ sub start
        my $cuser = DXNodeuser->new($self, $node, $call, 0, 1);
        $node->dxchan($self) if $call eq $main::myalias; # send all output for mycall to myalias
 
+       # routing version
+       my $pref = Route::Node::get($main::mycall)  or die "$main::mycall not allocated in Route database";
+       $pref->add_user($call, Route::here($self->{here}));
+       dbg('route', "B/C PC16 on $main::mycall for: $call");
+       
        # issue a pc16 to everybody interested
        my $nchan = DXChannel->get($main::mycall);
        my @pc16 = DXProt::pc16($nchan, $cuser);
@@ -351,12 +357,27 @@ sub run_cmd
                                }
                        } else {
                                dbg('command', "cmd: $cmd not found");
-                               return ($self->msg('e1'));
+                               if (++$self->{errors} > $maxerrors) {
+                                       $self->send($self->msg('e26'));
+                                       $self->disconnect;
+                                       return ();
+                               } else {
+                                       return ($self->msg('e1'));
+                               }
                        }
                }
        }
        
-       shift @ans;
+       my $ok = shift @ans;
+       if ($ok) {
+               delete $self->{errors};
+       } else {
+               if (++$self->{errors} > $maxerrors) {
+                       $self->send($self->msg('e26'));
+                       $self->disconnect;
+                       return ();
+               }
+       }
        return (@ans);
 }
 
@@ -384,7 +405,7 @@ sub process
 #
 # finish up a user context
 #
-sub finish
+sub disconnect
 {
        my $self = shift;
        my $call = $self->call;
@@ -395,6 +416,12 @@ sub finish
                $node->dxchan($DXProt::me);
        }
 
+       my $pref = Route::Node::get($main::mycall);
+       if ($pref) {
+               my @rout = $pref->del_user($main::mycall);
+               dbg('route', "B/C PC17 on $main::mycall for: $call");
+       }
+
        # I was the last node visited
     $self->user->node($main::mycall);
                
@@ -409,6 +436,8 @@ sub finish
        Log('DXCommand', "$call disconnected");
        my $ref = DXCluster->get_exact($call);
        $ref->del() if $ref;
+
+       $self->SUPER::disconnect;
 }
 
 #