use vars qw($me $pc11_max_age $pc23_max_age
$last_hour %pings %rcmds
%nodehops @baddx $baddxfn
- $allowzero $decode_dk0wcy);
+ $allowzero $decode_dk0wcy $send_opernam);
$me = undef; # the channel id for this cluster
-$decode_dk0wcy = undef; # if set use this callsign to decode announces from the EU WWV data beacon
$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
}
# are any of the crucial fields invalid?
- if ($field[2] =~ /[a-z]/ || $field[6] =~ /[a-z]/ || $field[7] =~ /[a-z]/) {
- dbg('chan', "Spot contains lower case callsigns, rejected");
+ if ($field[2] =~ /(?:^\s*$|[a-z])/ || $field[6] =~ /(?:^\s*$|[a-z])/ || $field[7] =~ /(?:^\s*$|[a-z])/) {
+ dbg('chan', "Spot contains lower case callsigns or blanks, rejected");
return;
}
# do some de-duping
+ $field[5] =~ s/^\s+//; # take any leading blanks off
if (Spot::dup($field[1], $field[2], $d, $field[5])) {
dbg('chan', "Duplicate Spot ignored\n");
return;
# you should be able to route on any of these
#
+ # fix up qra locators of known users
+ my $user = DXUser->get_current($spot[4]);
+ if ($user) {
+ my $qra = $user->qra;
+ unless ($qra && DXBearing::is_qra($qra)) {
+ my $lat = $user->lat;
+ my $long = $user->long;
+ if (defined $lat && defined $long) {
+ $user->qra(DXBearing::lltoqra($lat, $long));
+ $user->put;
+ }
+ }
+
+ # send a remote command to a distant cluster if it is visible and there is no
+ # qra locator and we havn't done it for a month.
+
+ unless ($user->qra) {
+ my $node;
+ my $to = $user->homenode;
+ my $last = $user->lastoper || 0;
+ if ($send_opernam && $main::systime > $last + $DXUser::lastoperinterval && $to && ($node = DXCluster->get_exact($to)) ) {
+ my $cmd = "forward/opernam $spot[4]";
+ # send the rcmd but we aren't interested in the replies...
+ if ($node && $node->dxchan && $node->dxchan->is_clx) {
+ route(undef, $to, pc84($main::mycall, $to, $main::mycall, $cmd));
+ } else {
+ route(undef, $to, pc34($main::mycall, $to, $cmd));
+ }
+ if ($to ne $field[7]) {
+ $to = $field[7];
+ $node = DXCluster->get_exact($to);
+ if ($node && $node->dxchan && $node->dxchan->is_clx) {
+ route(undef, $to, pc84($main::mycall, $to, $main::mycall, $cmd));
+ } else {
+ route(undef, $to, pc34($main::mycall, $to, $cmd));
+ }
+ }
+ $user->lastoper($main::systime);
+ $user->put;
+ }
+ }
+ }
+
# local processing
my $r;
eval {
if ($pcno == 12) { # announces
# announce duplicate checking
+ $field[3] =~ s/^\s+//; # remove leading blanks
if (AnnTalk::dup($field[1], $field[2], $field[3])) {
dbg('chan', "Duplicate Announce ignored\n");
return;
# send it
$self->send_announce($line, @field[1..6]);
-
- if ($decode_dk0wcy && $field[1] eq $decode_dk0wcy) {
- my ($hour, $k, $next, $a, $r, $sfi, $alarm) = $field[3] =~ /^Aurora Beacon\s+(\d+)UTC,\s+Kiel\s+K=(\d+),.*ed\s+K=(\d+),\s+A=(\d+),\s+R=(\d+),\s+SFI=(\d+),.*larm:\s+(\w+)/;
- $alarm = ($alarm =~ /^Y/i) ? ', Aurora in DE' : '';
- my $wwv = Geomag::update($main::systime, $hour, $sfi, $a, $k, "R=$r, Next K=$next$alarm", $decode_dk0wcy, $field[5], $r) if $sfi && $r;
- }
-
} else {
$self->route($field[2], $line);
}
my ($lat, $long) = DXBearing::stoll($field[3]);
$user->lat($lat);
$user->long($long);
+ my $qra = $user->qra || DXBearing::lltoqra($lat, $long);
+ $qra = DXBearing::lltoqra($lat, $long) unless $qra && DXBearing::is_qra($qra);
+ $user->qra($qra) if $qra ne $user->qra;
} elsif ($field[2] == 4) {
$user->homenode($field[3]);
}
+ $user->lastoper($main::systime); # to cut down on excessive for/opers being generated
$user->put;
last SWITCH;
}
my $ref = DXUser->get_current($field[2]);
my $cref = DXCluster->get($field[2]);
Log('rcmd', 'in', $ref->{priv}, $field[2], $field[4]);
- unless ($field[3] =~ /rcmd/i || !$cref || !$ref || $cref->mynode->call ne $ref->homenode) { # not allowed to relay RCMDS!
+ unless ($field[4] =~ /rcmd/i || !$cref || !$ref || $cref->mynode->call ne $ref->homenode) { # not allowed to relay RCMDS!
if ($ref->{priv}) { # you have to have SOME privilege, the commands have further filtering
$self->{remotecmd} = 1; # for the benefit of any command that needs to know
my $oldpriv = $self->{priv};
if ($ref && $ref->is_clx) {
$self->route($field[1], $line);
} else {
- route($field[1], pc34($field[2], $field[1], $field[3]));
+ route($field[1], pc34($field[2], $field[1], $field[4]));
}
}
return;
if ($ref && $ref->is_clx) {
$self->route($field[1], $line);
} else {
- route($field[1], pc35($field[2], $field[1], $field[3]));
+ route($field[1], pc35($field[2], $field[1], $field[4]));
}
}
return;
{
my $self = shift;
my $call = $self->call;
- my $nopc39 = shift;
+ my $conn = shift;
my $ref = DXCluster->get_exact($call);
- $self->send_now("D", DXProt::pc39($main::mycall, $self->msg('disc1', "System Op"))) unless $nopc39;
-
# unbusy and stop and outgoing mail
my $mref = DXMsg::get_busy($call);
$mref->stop_msg($call) if $mref;
$dxchan->send($routeit) unless $dxchan->{isolate} || $self->{isolate};
}
} elsif ($dxchan->is_user && $dxchan->{dx}) {
- my $buf = Spot::formatb($_[0], $_[1], $_[2], $_[3], $_[4]);
+ my $buf = Spot::formatb($dxchan->{user}->wantgrid, $_[0], $_[1], $_[2], $_[3], $_[4]);
$buf .= "\a\a" if $dxchan->{beep};
if ($dxchan->{state} eq 'prompt' || $dxchan->{state} eq 'convers') {
$dxchan->send($buf);
route(undef, $to, pc34($main::mycall, $to, $cmd));
}
}
+
+sub disconnect
+{
+ my $self = shift;
+ my $nopc39 = shift;
+
+ if ($self->{conn} && !$nopc39) {
+ $self->send_now("D", DXProt::pc39($main::mycall, $self->msg('disc1', "System Op")));
+ }
+
+ $self->SUPER::disconnect;
+}
1;
__END__