but this probably for advanced users...
+=== 8^ACCEPT/route <call> [0-9] <pattern>^Set an 'accept' filter line for routing
+Create an 'accept this routing PC Protocol' line for a filter.
+
+An accept filter line means that if a PC16/17/19/21/24/41/50 matches this filter
+it is passed thru that interface. See HELP FILTERING for more info. Please read this
+to understand how filters work - it will save a lot of grief later on.
+
+You can use any of the following things in this line:-
+
+ call <prefixes> the callsign of the thingy
+ call_dxcc <numbers> eg: 61,62 (from eg: sh/pre G)
+ call_itu <numbers>
+ call_zone <numbers>
+ origin <prefixes> really the interface it came in on
+ origin_dxcc <numbers> eg: 61,62 (from eg: sh/pre G)
+ origin_itu <numbers>
+ origin_zone <numbers>
+
+some examples:-
+
+ acc/route gb7djk call_zone 61,38 (send only UK+EIRE nodes)
+ acc/route gb7djk call gb7djk (equiv to SET/ISOLATE)
+
+You can use the tag 'all' to accept everything eg:
+
+ acc/route all
+
+
=== 8^ACCEPT/SPOTS <call> [input] [0-9] <pattern>^Spot filter sysop version
This version allows a sysop to set a filter for a callsign as well as the
default for nodes and users eg:-
but this probably for advanced users...
+=== 8^REJECT/ROUTE <call> [0-9] <pattern>^Set an 'reject' filter line for routing
+Create an 'reject this routing PC Protocol' line for a filter.
+
+An reject filter line means that if a PC16/17/19/21/24/41/50 matches this filter
+it is NOT passed thru that interface. See HELP FILTERING for more info. Please
+read this to understand how filters work - it will save a lot of grief later on.
+
+You can use any of the following things in this line:-
+
+ call <prefixes> the callsign of the thingy
+ call_dxcc <numbers> eg: 61,62 (from eg: sh/pre G)
+ call_itu <numbers>
+ call_zone <numbers>
+ origin <prefixes> really the interface it came in on
+ origin_dxcc <numbers> eg: 61,62 (from eg: sh/pre G)
+ origin_itu <numbers>
+ origin_zone <numbers>
+
+some examples:-
+
+ rej/route gb7djk call_zone 61,38 (everything except UK+EIRE nodes)
+
+You can use the tag 'all' to reject everything eg:
+
+ rej/route all (equiv to [very] restricted mode)
+
=== 8^REJECT/SPOTS <call> [input] [0-9] <pattern>^Spot filter sysop version
This version allows a sysop to set a filter for a callsign as well as the
default for nodes and users eg:-
my $flags = Route::here($here)|Route::conf($conf);
if ($r && $r->flags != $flags) {
- $r->$flags($flags);
+ $r->flags($flags);
push @rout, $r;
} elsif (!$r) {
push @rout, $parent->add_user($call, $flags);
dbg('chan', "PCPROT: Route::Node $ncall not in config");
return;
}
- my $r = Route::User::get($ucall);
- my @rout = $parent->del_user($ucall) if $r;
+ my @rout = $parent->del_user($ucall);
$self->route_pc17($parent, @rout) if @rout;
return;
}
my $call = uc $field[1];
my @rout;
my $parent = Route::Node::get($self->{call});
+ unless ($parent) {
+ dbg('chan', "PCPROT: Route::Node $call not in config");
+ return;
+ }
+ my $node = Route::Node::get($call);
if ($call ne $main::mycall) { # don't allow malicious buggers to disconnect me!
if ($call eq $self->{call}) {
}
# routing objects
- if ($parent) {
- push @rout, $parent->del_node($call);
- } else {
- dbg('chan', "PCPROT: Route::Node $call not in config");
- }
+ push @rout, $node->del($parent) if $node;
} else {
dbg('chan', "PCPROT: I WILL _NOT_ be disconnected!");
return;
$ref->here($field[2]) if $ref;
$ref = Route::User::get($call);
$ref->here($field[2]) if $ref;
- last SWITCH;
+
+ $self->route_pc24($ref, $field[3]) if $ref && !eph_dup($line);
+ return;
}
if ($pcno == 25) { # merge request
if ($pcno == 41) { # user info
# add this station to the user database, if required
- my $user = DXUser->get_current($field[1]);
- $user = DXUser->new($field[1]) if !$user;
+ my $call = $field[1];
+ my $user = DXUser->get_current($call);
+ $user = DXUser->new($call) if !$user;
if ($field[2] == 1) {
$user->name($field[3]);
}
$user->lastoper($main::systime); # to cut down on excessive for/opers being generated
$user->put;
- last SWITCH;
+ my $ref = Route::get($call);
+ $self->route_pc41($ref, $field[2], $field[3], $field[4]) if $ref && !eph_dup($line);
}
if ($pcno == 43) {
last SWITCH;
}
if ($pcno == 50) { # keep alive/user list
- my $node = Route::Node::get($field[1]);
+ my $call = $field[1];
+ my $node = Route::Node::get($call);
if ($node) {
return unless $node->call eq $self->{call};
$node->usercount($field[2]);
+ $self->route_pc50($node, $field[2], $field[3]) unless eph_dup($line);
}
- last SWITCH;
+ return;
}
if ($pcno == 51) { # incoming ping requests/answers
+ my $to = $field[1];
+ my $from = $field[2];
+ my $flag = $field[3];
# is it for us?
- if ($field[1] eq $main::mycall) {
- my $flag = $field[3];
+ if ($to eq $main::mycall) {
if ($flag == 1) {
- $self->send(pc51($field[2], $field[1], '0'));
+ $self->send(pc51($from, $to, '0'));
} else {
# it's a reply, look in the ping list for this one
- my $ref = $pings{$field[2]};
+ my $ref = $pings{$from};
if ($ref) {
- my $tochan = DXChannel->get($field[2]);
+ my $tochan = DXChannel->get($from);
while (@$ref) {
my $r = shift @$ref;
my $dxchan = DXChannel->get($r->{call});
if ($dxchan->is_user) {
my $s = sprintf "%.2f", $t;
my $ave = sprintf "%.2f", $tochan ? ($tochan->{pingave} || $t) : $t;
- $dxchan->send($dxchan->msg('pingi', $field[2], $s, $ave))
+ $dxchan->send($dxchan->msg('pingi', $from, $s, $ave))
} elsif ($dxchan->is_node) {
if ($tochan) {
$tochan->{nopings} = $tochan->user->nopings || 2; # pump up the timer
}
} else {
# route down an appropriate thingy
- $self->route($field[1], $line);
+ $self->route($to, $line);
}
return;
}
if ($pcno == 75) { # dunno but route it
- if ($field[1] ne $main::mycall) {
- $self->route($field[1], $line);
+ my $call = $field[1];
+ if ($call ne $main::mycall) {
+ $self->route($call, $line);
}
return;
}
if ($pcno == 73) { # WCY broadcasts
+ my $call = $field[1];
# do some de-duping
- my $d = cltounix($field[1], sprintf("%02d18Z", $field[2]));
+ my $d = cltounix($call, sprintf("%02d18Z", $field[2]));
if (($pcno == 23 && $d < $main::systime - $pc23_max_age) || $d > $main::systime + 1500 || $field[2] < 0 || $field[2] > 23) {
- dbg('chan', "PCPROT: WCY Date ($field[1] $field[2]) out of range");
+ dbg('chan', "PCPROT: WCY Date ($call $field[2]) out of range");
return;
}
@field = map { unpad($_) } @field;
}
if ($pcno == 84) { # remote commands (incoming)
- if ($field[1] eq $main::mycall) {
+ my $call = $field[1];
+ if ($call eq $main::mycall) {
my $ref = DXUser->get_current($field[2]);
my $cref = Route::Node::get($field[2]);
Log('rcmd', 'in', $ref->{priv}, $field[2], $field[4]);
$self->send(pc85($main::mycall, $field[2], $field[3],"$main::mycall:your attempt is logged, Tut tut tut...!"));
}
} else {
- my $ref = DXUser->get_current($field[1]);
+ my $ref = DXUser->get_current($call);
if ($ref && $ref->is_clx) {
- $self->route($field[1], $line);
+ $self->route($call, $line);
} else {
- $self->route($field[1], pc34($field[2], $field[1], $field[4]));
+ $self->route($call, pc34($field[2], $call, $field[4]));
}
}
return;
}
if ($pcno == 85) { # remote command replies
- if ($field[1] eq $main::mycall) {
+ my $call = $field[1];
+ if ($call eq $main::mycall) {
my $dxchan = DXChannel->get($field[3]);
if ($dxchan) {
$dxchan->send($field[4]);
}
}
} else {
- my $ref = DXUser->get_current($field[1]);
+ my $ref = DXUser->get_current($call);
if ($ref && $ref->is_clx) {
- $self->route($field[1], $line);
+ $self->route($call, $line);
} else {
- $self->route($field[1], pc35($field[2], $field[1], $field[4]));
+ $self->route($call, pc35($field[2], $call, $field[4]));
}
}
return;
# send a pc50 out on this channel
$dxchan->{pc50_t} = $main::systime unless exists $dxchan->{pc50_t};
if ($t >= $dxchan->{pc50_t} + $DXProt::pc50_interval) {
- my $s = pc50(scalar DXChannel::get_all_users);
+ my $s = pc50($me, scalar DXChannel::get_all_users);
eph_dup($s);
$dxchan->send($s);
$dxchan->{pc50_t} = $t;
($filter) = $dxchan->{spotsfilter}->it(@{$fref}) if ref $fref;
next unless $filter;
}
- next if $sort eq 'ann' && !$dxchan->{ann};
+ next if $sort eq 'ann' && !$dxchan->{ann} && $s !~ /^To\s+LOCAL\s+de\s+(?:$main::myalias|$main::mycall)/i;
next if $sort eq 'wwv' && !$dxchan->{wwv};
next if $sort eq 'wcy' && !$dxchan->{wcy};
next if $sort eq 'wx' && !$dxchan->{wx};
}
# do routing stuff
-# my $node = Route::Node::get($self->{call});
-# my @rout = $node->del_nodes if $node;
- my @rout = $main::routeroot->del_node($call);
- dbg('route', "B/C PC21 (from PC39) for: " . join(',', (map{ $_->call } @rout))) if @rout;
+ my $node = Route::Node::get($call);
+ my @rout = $node->del_nodes; # at the next level
+
+ @rout = $node->del($main::routeroot) if $node;
# unbusy and stop and outgoing mail
my $mref = DXMsg::get_busy($call);
broadcast_route($self, \&pc21, scalar @_, @_);
}
+sub route_pc24
+{
+ my $self = shift;
+ broadcast_route($self, \&pc24, 1, @_);
+}
+
+sub route_pc41
+{
+ my $self = shift;
+ broadcast_route($self, \&pc41, 1, @_);
+}
+
+sub route_pc50
+{
+ my $self = shift;
+ broadcast_route($self, \&pc50, 1, @_);
+}
+
+
+
sub eph_dup
{
my $s = shift;
my $ref = $self->_delparent($pcall);
my @nodes;
- # is this the last connection?
- $self->_del_users;
+ # is this the last connection, I have no parents anymore?
unless (@$ref) {
- push @nodes, $self->del_nodes;
+ my $ncall = $self->{call};
+ foreach my $rcall (@{$self->{nodes}}) {
+ next if grep $rcall eq $_, @_;
+ my $r = Route::Node::get($rcall);
+ push @nodes, $r->del($self, $ncall, @_) if $r;
+ }
+ $self->_del_users;
delete $list{$self->{call}};
push @nodes, $self;
}
return @nodes;
}
+sub del_nodes
+{
+ my $parent = shift;
+ my @out;
+ foreach my $rcall (@{$parent->{nodes}}) {
+ my $r = get($rcall);
+ push @out, $r->del($parent, $parent->{call}, @_) if $r;
+ }
+ return @out;
+}
sub _del_users
{
$self->{users} = [];
}
-# remove all sub nodes from this parent
-sub del_nodes
-{
- my $self = shift;
- my @nodes;
-
- for (@{$self->{nodes}}) {
- next if $self->{call} eq $_;
- push @nodes, $self->del_node($_);
- }
- return @nodes;
-}
-
-# delete a node from this node (ie I am a parent)
-sub del_node
-{
- my $self = shift;
- my $ncall = shift;
- my @out;
- $self->_delnode($ncall);
- if (my $ref = get($ncall)) {
- foreach my $rcall (@{$ref->{nodes}}) {
- next if $rcall eq $ncall || $rcall eq $self->{call};
- push @out, $ref->del_node($rcall);
- }
- push @out, $ref->del($self);
- }
- return @out;
-}
-
# add a user to this node
sub add_user
{
next if grep $call eq $_, @_;
push @out, $call;
my $r = get($call);
- push @out, $r->rnodes(@_, @out) if $r;
+ push @out, $r->rnodes($call, @_) if $r;
}
return @out;
}