Limit depth of recursion for route finding
[spider.git] / perl / DXProtHandle.pm
index e0f327e71de05c3f8778215b4373832aa21c90fa..cb13e37c652b77ba86d7b5ab0332a6c482c8a5fe 100644 (file)
@@ -46,6 +46,7 @@ use vars qw($pc11_max_age $pc23_max_age $last_pc50 $eph_restime $eph_info_restim
                        $eph_pc15_restime $pc9x_past_age $pc9x_dupe_age
                        $pc10_dupe_age $pc92_slug_changes $last_pc92_slug
                        $pc92Ain $pc92Cin $pc92Din $pc92Kin $pc9x_time_tolerance
+                       $pc92filterdef
                   );
 
 $pc9x_dupe_age = 60;                   # catch loops of circular (usually) D records
@@ -57,6 +58,15 @@ $pc9x_past_age = (122*60)+           # maximum age in the past of a px9x (a config record
        $pc9x_time_tolerance;           # thing a node might send - once an hour and we allow an extra hour for luck)
                                 # this is actually the partition between "yesterday" and "today" but old.
 
+$pc92filterdef = bless ([
+                         # tag, sort, field, priv, special parser
+                         ['call', 'c', 0],
+                         ['by', 'c', 0],
+                         ['dxcc', 'nc', 1],
+                         ['itu', 'ni', 2],
+                         ['zone', 'nz', 3],
+                        ], 'Filter::Cmd');
+
 
 # incoming talk commands
 sub handle_10
@@ -226,7 +236,7 @@ sub handle_11
        #
 
        # fix up qra locators of known users
-       my $user = DXUser->get_current($spot[4]);
+       my $user = DXUser::get_current($spot[4]);
        if ($user) {
                my $qra = $user->qra;
                unless ($qra && is_qra($qra)) {
@@ -273,12 +283,13 @@ sub handle_11
        }
 
        # local processing
-       my $r;
-       eval {
-               $r = Local::spot($self, @spot);
-       };
-       #                       dbg("Local::spot1 error $@") if isdbg('local') if $@;
-       return if $r;
+       if (defined &Local::spot) {
+               my $r;
+               eval {
+                       $r = Local::spot($self, @spot);
+               };
+               return if $r;
+       }
 
        # DON'T be silly and send on PC26s!
        return if $pcno == 26;
@@ -357,6 +368,15 @@ sub handle_12
        } else {
                $self->route($_[2], $line);
        }
+
+       # local processing
+       if (defined &Local::ann) {
+               my $r;
+               eval {
+                       $r = Local::ann($self, $line, @_[1..6]);
+               };
+               return if $r;
+       }
 }
 
 sub handle_15
@@ -453,7 +473,7 @@ sub handle_16
 
                # reject this if we think it is a node already
                my $r = Route::Node::get($call);
-               my $u = DXUser->get_current($call) unless $r;
+               my $u = DXUser::get_current($call) unless $r;
                if ($r || ($u && $u->is_node)) {
                        dbg("PCPROT: $call is a node") if isdbg('chanerr');
                        next;
@@ -475,7 +495,7 @@ sub handle_16
                }
 
                # add this station to the user database, if required
-               my $user = DXUser->get_current($ncall);
+               my $user = DXUser::get_current($ncall);
                $user = DXUser->new($call) unless $user;
                $user->homenode($parent->call) if !$user->homenode;
                $user->node($parent->call);
@@ -558,7 +578,7 @@ sub handle_17
        $parent->del_user($uref);
 
        # send info to all logged in thingies
-       my $user = DXUser->get_current($ncall);
+       my $user = DXUser::get_current($ncall);
        $self->tell_login('logoutu', "$ncall: $ucall") if $user && $user->is_local_node;
        $self->tell_buddies('logoutb', $ucall, $ncall);
 
@@ -628,7 +648,7 @@ sub check_add_node
        my $call = shift;
 
        # add this station to the user database, if required (don't remove SSID from nodes)
-       my $user = DXUser->get_current($call);
+       my $user = DXUser::get_current($call);
        if (!$user) {
                $user = DXUser->new($call);
                $user->priv(1);         # I have relented and defaulted nodes
@@ -937,12 +957,13 @@ sub handle_23
        # note this only takes the first one it gets
        Geomag::update($d, $_[2], $sfi, $k, $i, @_[6..8], $r);
 
-       my $rep;
-       eval {
-               $rep = Local::wwv($self, $_[1], $_[2], $sfi, $k, $i, @_[6..8], $r);
-       };
-       #                       dbg("Local::wwv2 error $@") if isdbg('local') if $@;
-       return if $rep;
+       if (defined &Local::wwv) {
+               my $rep;
+               eval {
+                       $rep = Local::wwv($self, $_[1], $_[2], $sfi, $k, $i, @_[6..8], $r);
+               };
+               return if $rep;
+       }
 
        # DON'T be silly and send on PC27s!
        return if $pcno == 27;
@@ -1131,7 +1152,7 @@ sub handle_41
        }
 
        # add this station to the user database, if required
-       my $user = DXUser->get_current($call);
+       my $user = DXUser::get_current($call);
        $user = DXUser->new($call) unless $user;
 
        if ($sort == 1) {
@@ -1307,12 +1328,13 @@ sub handle_73
 
        my $wcy = WCY::update($d, @_[2..12]);
 
-       my $rep;
-       eval {
-               $rep = Local::wcy($self, @_[1..12]);
-       };
-       # dbg("Local::wcy error $@") if isdbg('local') if $@;
-       return if $rep;
+       if (defined &Local::wcy) {
+               my $rep;
+               eval {
+                       $rep = Local::wcy($self, @_[1..12]);
+               };
+               return if $rep;
+       }
 
        # broadcast to the eager world
        send_wcy_spot($self, $line, $d, @_[2..12]);
@@ -1524,6 +1546,13 @@ sub check_pc9x_t
                                } elsif ($t == $lastid) {
                                        dbg("PCPROT: dup id on $t == lastid $lastid, ignored") if isdbg('chanerr') || isdbg('pc92dedupe');
                                        return undef;
+                               } else {
+                                       # check that if we have a low number in lastid that yesterday's numbers
+                                       # (likely in the 85000+ area) don't override them, thus causing flip flopping
+                                       if ($lastid+86400-$t < $pc9x_past_age) {
+                                               dbg("PCPROT: dup id on $t in yesterday, lastid $lastid, ignored") if isdbg('chanerr') || isdbg('pc92dedupe');
+                                               return undef;
+                                       }
                                }
                        }
                }
@@ -1690,7 +1719,7 @@ sub handle_92
                }
 
        } elsif ($sort eq 'K') {
-               $pc92Kin += length $line if $sort eq 'K';
+               $pc92Kin += length $line;
 
                # remember the last channel we arrived on
                $parent->PC92C_dxchan($self->{call}) unless $self->{call} eq $parent->call;
@@ -1875,6 +1904,12 @@ sub handle_93
                return;
        }
 
+       # ignore PC93 coming in from outside this node with a target of local
+       if ($to eq 'LOCAL' && $self != $main::me) {
+               dbg("PCPROT: incoming LOCAL chat not from local node, ignored") if isdbg('chanerr');
+               return;
+       }
+
        # if it is routeable then then treat it like a talk
        my $ref = Route::get($to);
        if ($ref) {
@@ -1922,7 +1957,9 @@ sub handle_93
                # chat messages to non-pc9x nodes
                $self->send_chat(1, pc12($from, $text, undef, $to, undef, $pcall), $from, '*', $text, $to, $pcall, '0');
        }
-       $self->broadcast_route_pc9x($pcall, undef, $line, 0);
+
+       # broadcast this chat sentence everywhere unless it is targetted to 'LOCAL'
+       $self->broadcast_route_pc9x($pcall, undef, $line, 0) unless $to eq 'LOCAL' || $via eq 'LOCAL';
 }
 
 # if get here then rebroadcast the thing with its Hop count decremented (if