Prepare for git repository
[spider.git] / perl / DXProt.pm
index 8a672744b45395c7a02450910780cabcea03253c..e7fdff9003fab04001479a32ff916e62689d045d 100644 (file)
@@ -38,19 +38,14 @@ use RouteDB;
 
 use strict;
 
-use vars qw($VERSION $BRANCH);
-$VERSION = sprintf( "%d.%03d", q$Revision$ =~ /(\d+)\.(\d+)/ );
-$BRANCH = sprintf( "%d.%03d", q$Revision$ =~ /\d+\.\d+\.(\d+)\.(\d+)/  || (0,0));
-$main::build += $VERSION;
-$main::branch += $BRANCH;
-
 use vars qw($pc11_max_age $pc23_max_age $last_pc50 $eph_restime $eph_info_restime $eph_pc34_restime
                        $last_hour $last10 %eph  %pings %rcmds $ann_to_talk
                        $pingint $obscount %pc19list $chatdupeage $chatimportfn
                        $investigation_int $pc19_version $myprot_version
                        %nodehops $baddx $badspotter $badnode $censorpc $rspfcheck
                        $allowzero $decode_dk0wcy $send_opernam @checklist
-                       $handle_xml);
+                       $eph_pc15_restime
+                  );
 
 $pc11_max_age = 1*3600;                        # the maximum age for an incoming 'real-time' pc11
 $pc23_max_age = 1*3600;                        # the maximum age for an incoming 'real-time' pc23
@@ -70,6 +65,7 @@ $ann_to_talk = 1;
 $rspfcheck = 1;
 $eph_restime = 180;
 $eph_info_restime = 60*60;
+$eph_pc15_restime = 6*60;
 $eph_pc34_restime = 30;
 $pingint = 5*60;
 $obscount = 2;
@@ -77,7 +73,6 @@ $chatdupeage = 20 * 60 * 60;
 $chatimportfn = "$main::root/chat_import";
 $investigation_int = 12*60*60; # time between checks to see if we can see this node
 $pc19_version = 5466;                  # the visible version no for outgoing PC19s generated from pc59
-$handle_xml = 0;                               # handle XML sentences
 
 @checklist = 
 (
@@ -234,6 +229,14 @@ sub new
        # add this node to the table, the values get filled in later
        my $pkg = shift;
        my $call = shift;
+
+       # if we have an entry already, then send a PC21 to all connect
+       # old style connections, because we are about to get the real deal
+       if (my $ref = Route::Node::get($call)) {
+               dbg("ROUTE: $call is already in the routing table, deleting") if isdbg('route');
+               my @rout = $ref->delete;
+               $self->route_pc21($main::mycall, undef, @rout) if @rout;
+       }
        $main::routeroot->add($call, '5000', Route::here(1)) if $call ne $main::mycall;
 
        return $self;
@@ -333,7 +336,7 @@ sub normal
 {
        my ($self, $line) = @_;
 
-       if ($line =~ '^<\w+\s') {
+       if ($line =~ '^<\w+\s' && $main::do_xml) {
                DXXml::normal($self, $line);
                return;
        }
@@ -348,7 +351,7 @@ sub normal
        
        # process PC frames, this will fail unless the frame starts PCnn
        my ($pcno) = $field[0] =~ /^PC(\d\d)/; # just get the number
-       unless (defined $pcno && $pcno >= 10 && $pcno <= 99) {
+       unless (defined $pcno && $pcno >= 10 && $pcno <= 89) { # reject PC9x messages
                dbg("PCPROT: unknown protocol") if isdbg('chanerr');
                return;
        }
@@ -700,6 +703,23 @@ sub handle_12
                $self->route($_[2], $line);
        }
 }
+
+
+sub handle_15
+{
+       my $self = shift;
+       my $pcno = shift;
+       my $line = shift;
+       my $origin = shift;
+
+       if (eph_dup($line, $eph_pc15_restime)) {
+               dbg("PCPROT: Ephemeral dup, dropped") if isdbg('chanerr');
+       } else {
+               unless ($self->{isolate}) {
+                       DXChannel::broadcast_nodes($line, $self) if $line =~ /\^H\d+\^?~?$/; # send it to everyone but me
+               }
+       }
+}
                
 # incoming user                
 sub handle_16
@@ -721,7 +741,11 @@ sub handle_16
        }
        # is it me?
        if ($ncall eq $main::mycall) {
-               dbg("PCPROT: trying to alter config on this node from outside!") if isdbg('chanerr');
+               dbg("PCPROT: trying to alter my config from outside!") if isdbg('chanerr');
+               return;
+       }
+       if (DXChannel::get($ncall) && $ncall ne $self->{call}) {
+               dbg("PCPROT: trying to alter locally connected $ncall from $self->{call}, ignored") if isdbg('chanerr');
                return;
        }
 
@@ -847,7 +871,7 @@ sub handle_16
                
                # send info to all logged in thingies
                $self->tell_login('loginu', "$ncall: $call") if DXUser->get_current($ncall)->is_local_node;
-               $self->tell_buddies('loginb', "$ncall: $call");
+               $self->tell_buddies('loginb', $call, $ncall);
                                
                # add this station to the user database, if required
 #              $call =~ s/-\d+$//o;    # remove ssid for users
@@ -899,36 +923,33 @@ sub handle_17
        my $uref = Route::User::get($ucall);
        unless ($uref) {
                dbg("PCPROT: Route::User $ucall not in config") if isdbg('chanerr');
+               return;
        }
        my $parent = Route::Node::get($ncall);
        unless ($parent) {
                dbg("PCPROT: Route::Node $ncall not in config") if isdbg('chanerr');
+               return;
        }                       
 
-       $dxchan = $parent->dxchan if $parent;
+       $dxchan = DXChannel::get($ncall);
        if ($dxchan && $dxchan ne $self) {
                dbg("PCPROT: PC17 from $self->{call} trying to alter locally connected $ncall, ignored!") if isdbg('chanerr');
                return;
        }
 
        # input filter if required and then remove user if present
-       if ($parent) {
 #              return unless $self->in_filter_route($parent);  
-               $parent->del_user($uref) if $uref;
-       } else {
-               $parent = Route->new($ncall);  # throw away
-       }
+       $parent->del_user($uref);
 
        # send info to all logged in thingies
        $self->tell_login('logoutu', "$ncall: $ucall") if DXUser->get_current($ncall)->is_local_node;
-       $self->tell_buddies('logoutb', "$ncall: $ucall");
+       $self->tell_buddies('logoutb', $ucall, $ncall);
 
        if (eph_dup($line)) {
                dbg("PCPROT: dup PC17 detected") if isdbg('chanerr');
                return;
        }
 
-       $uref = Route->new($ucall) unless $uref; # throw away
        $self->route_pc17($origin, $line, $parent, $uref);
 }
                
@@ -952,7 +973,7 @@ sub handle_18
                        $self->user->put;
                        $self->sort('S');
                }
-               $self->{handle_xml}++ if $main::do_xml && $_[1] =~ /\bxml\b/;
+               $self->{handle_xml}++ if DXXml::available() && $_[1] =~ /\bxml\b/;
        } else {
                $self->version(50.0);
                $self->version($_[2] / 100) if $_[2] && $_[2] =~ /^\d+$/;
@@ -1460,6 +1481,10 @@ sub handle_41
        $user = DXUser->new($call) unless $user;
                        
        if ($_[2] == 1) {
+               if (($_[3] =~ /spotter/i || $_[3] =~ /self/i) && $user->name && $user->name ne $_[3]) {
+                       dbg("PCPROT: invalid name") if isdbg('chanerr');
+                       return;
+               }
                $user->name($_[3]);
        } elsif ($_[2] == 2) {
                $user->qth($_[3]);