4. Added 'catchup' command which will 'catchup' messages to date for a node.
This means that when you start forwarding to a node, it doesn't get all the
messages queued up that are probably old.
+5. added 'uncatchup' which does the opposite of the above.
+6. fixed kill full and PC49 handling so that it actually works.
21Jun99=======================================================================
1. changed regex for cluster->client msgs so that strings like |---| are no
longer ignored.
use the script in /spider/connect/<callsign> to effect the 'chat' exchange
necessary to traverse the network(s) to logon to the cluster <callsign>.
+=== 9^CATCH <node call> All|[<msgno> ...]^Mark a message as sent
+=== 9^UNCATCH <node call> All|[msgno> ...]^Unmark a message as sent
+When you send messages the fact that you have forwarded it to another node
+is remembered so that it isn't sent again. When you have a new partner
+node and you add their callsign to your /spider/msg/forward.pl file, all
+outstanding non-private messages will be forwarded to them. This may well
+be ALL the non-private messages. You can prevent this by using these
+commmands:-
+
+ catch GB7DJK all
+ catch GB7DJK 300 301 302 303
+
+and to undo what you have just done:-
+
+ uncatch GB7DJK all
+ uncatch GB7DJK 300 301 302 303
+
+which will arrange for them to be forward candidates again.
+
=== 9^DEBUG^Set the cluster program into debug mode
Executing this command will only have an effect if you are running the cluster
in debug mode i.e.
#
my ($self, $line) = @_;
+return (1, $self->msg('e5')) if $self->priv < 9;
+
my @f = split /\s+/, $line;
+return (1, "usage: catchup <node call> all|[<msgno ...]") unless @f >= 2;
+
my $call = uc shift @f;
+my $user = DXUser->get_current($call);
+return (1, "$call not a node") unless $user && $user->sort ne 'U';
+
my @out;
+my $ref;
+my @ref;
+
+# get a more or less valid set of messages
+foreach my $msgno (@f) {
+ if ($msgno =~ /^al/oi) {
+ @ref = DXMsg::get_all();
+ last;
+ }
+ $ref = DXMsg::get($msgno);
+ unless ($ref) {
+ push @out, $self->msg('m13', $msgno);
+ next;
+ }
+ push @ref, $ref;
+}
+foreach $ref (@ref) {
+ next if $ref->{private};
+ unless (grep {$_ eq $call} @{$ref->{gotit}}) {
+ push @{$ref->{gotit}}, $call; # mark this up as being received
+ $ref->store( [ $ref->read_msg_body() ] ); # re- store the file
+ push @out, $self->msg('m14', $ref->{msgno}, $call);
+ }
+}
return (1, @out);
foreach $ref ( @refs) {
Log('msg', "Message $ref->{msgno} from $ref->{from} to $ref->{to} deleted by $call");
if ($full) {
- DXProt::broadcast_all_ak1a(DXProt::pc49($self->call, $ref->{subject}), $DXProt::me);
+ DXProt::broadcast_ak1a(DXProt::pc49($ref->{from}, $ref->{subject}), $DXProt::me);
}
$ref->del_msg;
- push @out, "Message $ref->{msgno} deleted";
+ push @out, $self->msg('m12', $ref->msgno);
}
return (1, @out);
#
-# uncatchup some or all of the non-private messages for a node.
+# catchup some or all of the non-private messages for a node.
#
-# in other words mark messages as NOT being already received
+# in other words mark all messages as being already received
# by this node.
#
# $Id$
#
my ($self, $line) = @_;
+return (1, $self->msg('e5')) if $self->priv < 9;
+
my @f = split /\s+/, $line;
+return (1, "usage: catchup <node call> all|[<msgno ...]") unless @f >= 2;
+
my $call = uc shift @f;
+my $user = DXUser->get_current($call);
+return (1, "$call not a node") unless $user && $user->sort ne 'U';
+
my @out;
+my $ref;
+my @ref;
+
+# get a more or less valid set of messages
+foreach my $msgno (@f) {
+ if ($msgno =~ /^al/oi) {
+ @ref = DXMsg::get_all();
+ last;
+ }
+ $ref = DXMsg::get($msgno);
+ unless ($ref) {
+ push @out, $self->msg('m13', $msgno);
+ next;
+ }
+ push @ref, $ref;
+}
+foreach $ref (@ref) {
+ next if $ref->{private};
+ if (grep {$_ eq $call} @{$ref->{gotit}}) {
+ $ref->{gotit} = [ grep {$_ ne $call} @{$ref->{gotit}} ]; # mark this up as NOT being received
+ $ref->store( [ $ref->read_msg_body() ] ); # re- store the file
+ push @out, $self->msg('m15', $ref->{msgno}, $call);
+ }
+}
return (1, @out);
+
$self->send($self->msg('qthe1')) if !$user->qth;
$self->send($self->msg('qll')) if !$user->qra || (!$user->lat && !$user->long);
$self->send($self->msg('hnodee1')) if !$user->qth;
- $self->send($self->msg('msgnew')) if DXMsg::for_me($call);
+ $self->send($self->msg('m9')) if DXMsg::for_me($call);
# get the filters
$self->{spotfilter} = Filter::read_in('spots', $call);
my ($self, $line) = @_;
# this is periodic processing
- if (undef $self || undef $line) {
+ if (!$self || !$line) {
# wander down the work queue stopping any messages that have timed out
- for (keys %work) {
- my $ref = $work{$_};
+ for (keys %busy) {
+ my $node = $_;
+ my $ref = $busy{$_};
if ($main::systime > $ref->{lastt} + $timeout) {
- my $tonode = $ref->{tonode};
- $ref->stop_msg();
+ $ref->stop_msg($node);
# delay any outgoing messages that fail
- $ref->{waitt} = $main::systime + $waittime if $tonode ne $main::mycall;
+ $ref->{waitt} = $main::systime + $waittime if $node ne $main::mycall;
}
}
if (exists $busy{$f[2]}) {
my $ref = $busy{$f[2]};
my $tonode = $ref->{tonode};
- $ref->stop_msg();
+ $ref->stop_msg($self->call);
}
my $t = cltounix($f[5], $f[6]);
my $m;
for $m (@msg) {
if ($ref->{subject} eq $m->{subject} && $ref->{t} == $m->{t} && $ref->{from} eq $m->{from}) {
- $ref->stop_msg();
+ $ref->stop_msg($self->call);
my $msgno = $m->{msgno};
dbg('msg', "duplicate message to $msgno\n");
Log('msg', "duplicate message to $msgno");
# look for 'bad' to addresses
if (grep $ref->{to} eq $_, @badmsg) {
- $ref->stop_msg();
+ $ref->stop_msg($self->call);
dbg('msg', "'Bad' TO address $ref->{to}");
Log('msg', "'Bad' TO address $ref->{to}");
return;
Log('msg', "Message $ref->{msgno} from $ref->{from} received from $f[2] for $ref->{to}");
}
}
- $ref->stop_msg();
+ $ref->stop_msg($self->call);
queue_msg(0);
} else {
$self->send(DXProt::pc42($f[2], $f[1], $f[3])); # unknown stream
push @{$ref->{gotit}}, $f[2]; # mark this up as being received
$ref->store($ref->{lines}); # re- store the file
}
- $ref->stop_msg();
+ $ref->stop_msg($self->call);
} else {
$self->send(DXProt::pc42($f[2], $f[1], $f[3])); # unknown stream
}
dbg('msg', "stream $f[3]: abort received\n");
my $ref = $work{"$f[2]$f[3]"};
if ($ref) {
- $ref->stop_msg();
+ $ref->stop_msg($self->call);
$ref = undef;
}
if ($pcno == 49) { # global delete on subject
for (@msg) {
- if ($_->{subject} eq $f[2]) {
+ if ($_->{from} eq $f[1] && $_->{subject} eq $f[2]) {
$_->del_msg();
- Log('msg', "Message $_->{msgno} fully deleted by $f[1]");
+ Log('msg', "Message $_->{msgno} from $_->{from} ($_->{subject}) fully deleted");
+ DXProt::broadcast_ak1a($line, $self);
}
}
}
$self->{count} = 0;
$self->{tonode} = $dxchan->call;
$self->{fromnode} = $main::mycall;
- $busy{$dxchan->call} = $self;
- $work{"$self->{tonode}"} = $self;
+ $busy{$self->{tonode}} = $self;
+ $work{$self->{tonode}} = $self;
$dxchan->send(DXProt::pc28($self->{tonode}, $self->{fromnode}, $self->{to}, $self->{from}, $self->{t}, $self->{private}, $self->{subject}, $self->{origin}, $self->{rrreq}));
}
# stop a message from continuing, clean it out, unlock interlocks etc
sub stop_msg
{
- my ($self, $dxchan) = @_;
- my $node = $self->{tonode}
+ my $self = shift;
+ my $node = shift;
my $stream = $self->{stream} if exists $self->{stream};
$loc->{lines} = [];
$self->state('sendbody');
#push @out, $self->msg('sendbody');
- push @out, $self->msg('m8');)
+ push @out, $self->msg('m8');
} elsif ($self->state eq 'sendbody') {
confess "local var gone missing" if !ref $self->{loc};
my $loc = $self->{loc};
}
if (($pcno >= 28 && $pcno <= 33) || $pcno == 40 || $pcno == 42 || $pcno == 49) { # mail/file handling
- if ($field[1] eq $main::mycall) {
+ if ($pcno == 49 || $field[1] eq $main::mycall) {
DXMsg::process($self, $line);
} else {
route($field[1], $line);
if ($pcno == 43) {
last SWITCH;
}
- if ($pcno == 37 || $pcno == 44 || $pcno == 45 || $pcno == 46 || $pcno == 47 || $pcno == 49) {
+ if ($pcno == 37 || $pcno == 44 || $pcno == 45 || $pcno == 46 || $pcno == 47) {
if ($field[1] eq $main::mycall) {
;
} else {
m9 => 'New mail has arrived for you',
m10 => 'Message Aborted',
m11 => 'Message no $_[0] saved and directed to $_[1]',
+ m12 => 'Message no $_[0] deleted',
+ m13 => 'Message no $_[0] missing',
+ m14 => 'Message no $_[0] marked as sent to $_[1]',
+ m15 => 'Message no $_[0] unmarked as sent to $_[1]',
merge1 => 'Merge request for $_[1] spots and $_[2] WWV sent to $_[0]',
namee1 => 'Please enter your name, set/name <your name>',
namee2 => 'Can\'t find user $_[0]!',