From: minima Date: Sun, 29 Oct 2000 11:00:06 +0000 (+0000) Subject: added echo cancelling X-Git-Tag: R_1_45~73 X-Git-Url: http://www.dxcluster.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=c20a2c1e01d707d6c3fa25067df93d491aba8fff;p=spider.git added echo cancelling started new filter code, objectifyed old filter code --- diff --git a/Changes b/Changes index e446baa8..af1d970e 100644 --- a/Changes +++ b/Changes @@ -1,9 +1,16 @@ +29Oct00======================================================================= +1. put in echo cancelling measures into the clients. This doesn't mean you +shouldn't take steps to prevent echoing on node links, but it may help where +(whatever you do) it still bloody echos! This is experimental. 28Oct00======================================================================= 1. updated show/sun and show/moon from stuff sent by Steve Franke K9AN 2. added show/call which queries jeifer.pineknot.com for any call in the world (as opposed to UALR which only does US calls). Inspired by a bit of perl sent to me by Steve Franke (again!) and also Angel EA7WA who gave me the pineknot ip address. +3. fixed clients so that they accept -0 as a valid SSID and then strip it off +as though they had come in without (why has this taken so long to appear? How +long have we been running this code ??????). 27Oct00======================================================================= 1. alter the code in clean_old of DXMsg system to see if we get some different behaviour with random crashing diff --git a/cmd/show/log.pl b/cmd/show/log.pl index bced5855..8a00e385 100644 --- a/cmd/show/log.pl +++ b/cmd/show/log.pl @@ -35,5 +35,5 @@ if ($self->priv < 6) { return (1, $self->msg('e5')) if $who ne $self->call; } -@out = DXLog::print($from, $to, $main::systime, undef, $who); +@out = DXLog::print($from, $to, $main::systime, $who); return (1, @out); diff --git a/perl/DXLogPrint.pm b/perl/DXLogPrint.pm index 60f8b685..185912cd 100644 --- a/perl/DXLogPrint.pm +++ b/perl/DXLogPrint.pm @@ -37,9 +37,9 @@ sub print my $count; $search = '1' unless $pattern || $who; - $search = "\$ref->[1] =~ /$pattern/" if $pattern; + $search = "\$ref->[1] =~ /$pattern/i" if $pattern; $search .= ' && ' if $pattern && $who; - $search .= "(\$ref->[2] =~ /$who/ || \$ref->[3] =~ /$who/)" if $who; + $search .= "(\$ref->[2] =~ /$who/i || \$ref->[3] =~ /$who/i)" if $who; $eval = qq( my \$c; my \$ref; diff --git a/perl/DXProt.pm b/perl/DXProt.pm index 5d2b10b8..db342dfb 100644 --- a/perl/DXProt.pm +++ b/perl/DXProt.pm @@ -466,7 +466,7 @@ sub normal $org_itu = $dxcc[1]->itu; $org_cq = $dxcc[1]->cq(); } - my ($filter, $hops) = Filter::it($self->{inannfilter}, @field[1..6], $self->{call}, + my ($filter, $hops) = $self->{inannfilter}->it(@field[1..6], $self->{call}, $ann_dxcc, $ann_itu, $ann_cq, $org_dxcc, $org_itu, $org_cq); unless ($filter) { dbg('chan', "Rejected by filter"); @@ -1139,7 +1139,7 @@ sub send_dx_spot my ($filter, $hops); if ($dxchan->{spotfilter}) { - ($filter, $hops) = Filter::it($dxchan->{spotfilter}, @_, $self->{call} ); + ($filter, $hops) = $dxchan->{spotfilter}->it(@_, $self->{call} ); next unless $filter; } @@ -1184,7 +1184,7 @@ sub send_wwv_spot my ($filter, $hops); if ($dxchan->{wwvfilter}) { - ($filter, $hops) = Filter::it($dxchan->{wwvfilter}, @_, $self->{call} ); + ($filter, $hops) = $dxchan->{wwvfilter}->it(@_, $self->{call} ); next unless $filter; } if ($dxchan->is_node) { @@ -1228,7 +1228,7 @@ sub send_wcy_spot my ($filter, $hops); if ($dxchan->{wcyfilter}) { - ($filter, $hops) = Filter::it($dxchan->{wcyfilter}, @_, $self->{call} ); + ($filter, $hops) = $dxchan->{wcyfilter}->it(@_, $self->{call} ); next unless $filter; } if ($dxchan->is_clx || $dxchan->is_spider) { @@ -1303,7 +1303,7 @@ sub send_announce $org_itu = $dxcc[1]->itu; $org_cq = $dxcc[1]->cq; } - ($filter, $hops) = Filter::it($dxchan->{annfilter}, @_, $self->{call}, $ann_dxcc, $ann_itu, $ann_cq, $org_dxcc, $org_itu, $org_cq); + ($filter, $hops) = $dxchan->{annfilter}->it(@_, $self->{call}, $ann_dxcc, $ann_itu, $ann_cq, $org_dxcc, $org_itu, $org_cq); next unless $filter; } if ($dxchan->is_node && $_[1] ne $main::mycall) { # i.e not specifically routed to me @@ -1473,7 +1473,7 @@ sub broadcast_list if ($sort eq 'dx') { next unless $dxchan->{dx}; - ($filter) = Filter::it($dxchan->{spotfilter}, @{$fref}) if ref $fref; + ($filter) = $dxchan->{spotfilter}->it(@{$fref}) if ref $fref; next unless $filter; } next if $sort eq 'ann' && !$dxchan->{ann}; diff --git a/perl/Filter.pm b/perl/Filter.pm index a53ae034..2b30c8cd 100644 --- a/perl/Filter.pm +++ b/perl/Filter.pm @@ -12,42 +12,24 @@ # # $Id$ # -# The INSTRUCTIONS +# The NEW INSTRUCTIONS +# +# use the commands accept/spot|ann|wwv|wcy and reject/spot|ann|wwv|wcy +# also show/filter spot|ann|wwv|wcy # # The filters live in a directory tree of their own in $main::root/filter # # Each type of filter (e.g. spot, wwv) live in a tree of their own so you # can have different filters for different things for the same callsign. # -# Each filter file has the same structure:- -# -# -# @in = ( -# [ action, fieldno, fieldsort, comparison, action data ], -# ... -# ); -# -# The action is usually 1 or 0 but could be any numeric value -# -# The fieldno is the field no in the list of fields that is presented -# to 'Filter::it' -# -# The fieldsort is the type of field that we are dealing with which -# currently can be 'a', 'n', 'r' or 'd'. 'a' is alphanumeric, 'n' is -# numeric, 'r' is ranges of pairs of numeric values and 'd' is default. -# -# Filter::it basically goes thru the list of comparisons from top to -# bottom and when one matches it will return the action and the action data as a list. -# The fields -# are the element nos of the list that is presented to Filter::it. Element -# 0 is the first field of the list. -# + package Filter; use DXVars; use DXUtil; use DXDebug; +use Data::Dumper; use strict; @@ -62,40 +44,6 @@ sub init } -# -# takes the reference to the filter (the first argument) and applies -# it to the subsequent arguments and returns the action specified. -# -sub it -{ - my $filter = shift; - my ($action, $field, $fieldsort, $comp, $actiondata); - my $ref; - - # default action is 1 - $action = 1; - $actiondata = ""; - return ($action, $actiondata) if !$filter; - - for $ref (@{$filter}) { - ($action, $field, $fieldsort, $comp, $actiondata) = @{$ref}; - if ($fieldsort eq 'n') { - my $val = $_[$field]; - return ($action, $actiondata) if grep $_ == $val, @{$comp}; - } elsif ($fieldsort eq 'r') { - my $val = $_[$field]; - my $i; - my @range = @{$comp}; - for ($i = 0; $i < @range; $i += 2) { - return ($action, $actiondata) if $val >= $range[$i] && $val <= $range[$i+1]; - } - } elsif ($fieldsort eq 'a') { - return ($action, $actiondata) if $_[$field] =~ m{$comp}; - } else { - return ($action, $actiondata); # the default action - } - } -} # this reads in a filter statement and returns it as a list # @@ -120,17 +68,22 @@ sub read_in # load it if (-e $fn) { - do "$fn"; + $in = undef; + my $s = readfilestr($fn); + my $newin = eval $s; dbg('conn', "$@") if $@; - return $in; + return bless [ @$in ], 'Filter::Old' if $in; + return $newin; } return undef; } # this writes out the filter in a form suitable to be read in by 'read_in' # It expects a list of references to filter lines -sub write_out +sub write { + my $self = shift; + my $sort = shift; my $call = shift; my $fn = "$filterbasefn/$sort"; @@ -170,5 +123,74 @@ sub write_out close FILTER; } +package Filter::Old; + +use strict; +use vars qw(@ISA); +@ISA = qw(Filter); + +# the OLD instructions! +# +# Each filter file has the same structure:- +# +# +# @in = ( +# [ action, fieldno, fieldsort, comparison, action data ], +# ... +# ); +# +# The action is usually 1 or 0 but could be any numeric value +# +# The fieldno is the field no in the list of fields that is presented +# to 'Filter::it' +# +# The fieldsort is the type of field that we are dealing with which +# currently can be 'a', 'n', 'r' or 'd'. 'a' is alphanumeric, 'n' is +# numeric, 'r' is ranges of pairs of numeric values and 'd' is default. +# +# Filter::it basically goes thru the list of comparisons from top to +# bottom and when one matches it will return the action and the action data as a list. +# The fields +# are the element nos of the list that is presented to Filter::it. Element +# 0 is the first field of the list. +# + +# +# takes the reference to the filter (the first argument) and applies +# it to the subsequent arguments and returns the action specified. +# +sub it +{ + my $filter = shift; # this is now a bless ref of course but so what + + my ($action, $field, $fieldsort, $comp, $actiondata); + my $ref; + + # default action is 1 + $action = 1; + $actiondata = ""; + return ($action, $actiondata) if !$filter; + + for $ref (@{$filter}) { + ($action, $field, $fieldsort, $comp, $actiondata) = @{$ref}; + if ($fieldsort eq 'n') { + my $val = $_[$field]; + return ($action, $actiondata) if grep $_ == $val, @{$comp}; + } elsif ($fieldsort eq 'r') { + my $val = $_[$field]; + my $i; + my @range = @{$comp}; + for ($i = 0; $i < @range; $i += 2) { + return ($action, $actiondata) if $val >= $range[$i] && $val <= $range[$i+1]; + } + } elsif ($fieldsort eq 'a') { + return ($action, $actiondata) if $_[$field] =~ m{$comp}; + } else { + return ($action, $actiondata); # the default action + } + } +} + + 1; __END__ diff --git a/perl/client.pl b/perl/client.pl index b8494578..ff2ca473 100755 --- a/perl/client.pl +++ b/perl/client.pl @@ -119,6 +119,8 @@ sub rec_socket if ($buffered) { if (length $outqueue >= $client_buffer_lth) { print $stdout $outqueue; + pop @echo if @echo > $maxecho; + push @echo, $outqueue; $outqueue = ""; } $outqueue .= "$savenl$line$snl"; @@ -144,6 +146,8 @@ sub rec_socket } elsif ($sort eq 'B') { if ($buffered && $outqueue) { print $stdout $outqueue; + pop @echo if @echo > $maxecho; + push @echo, $outqueue; $outqueue = ""; } $buffered = $line; # set buffered or unbuffered @@ -199,6 +203,7 @@ sub rec_stdin unshift @lines, ($lastbit . $first) if ($first); foreach $first (@lines) { # print "send_now $call $first\n"; + next if grep {$_ eq $first } @echo; $conn->send_later("I$call|$first"); } $lastbit = $buf; @@ -340,6 +345,7 @@ $savenl = ""; # an NL that has been saved from last time $timeout = 60; # default timeout for connects $abort = ""; # the current abort string $cpath = "$root/connect"; # the basic connect directory +$maxecho = 5; # length of max echo queue $pid = 0; # the pid of the child program $csort = ""; # the connection type diff --git a/src/client.c b/src/client.c index 167ef647..8df62449 100644 --- a/src/client.c +++ b/src/client.c @@ -34,6 +34,7 @@ #include "sel.h" #include "cmsg.h" +#include "chain.h" #include "debug.h" #define TEXT 1 @@ -95,8 +96,9 @@ int tabsize = 8; /* default tabsize for text messages */ char *connsort = "local"; /* the connection variety */ int state = 0; /* the current state of the connection */ int laststate = 0; /* the last state we were in */ - - +reft echobase; /* the anti echo queue */ +int maxecho = 5; /* the depth of the anti echo queue */ +int echon; /* no of entries in the anti echo queue */ #define CONNECTED 100 #define WAITLOGIN 1 @@ -221,7 +223,22 @@ fcb_t *fcb_new(int cnum, int sort) void flush_text(fcb_t *f) { if (f->obuf) { - cmsg_send(f->outq, f->obuf, 0); + /* save this onto the front of the echo chain */ + cmsg_t *imp = f->obuf; + int size = imp->inp - imp->data; + cmsg_t *emp = cmsg_new(size, imp->sort, imp->portp); + + emp->size = size; + memcpy(emp->data, imp->data, size); + emp->inp = emp->data + size; /* just in case */ + chain_add(&echobase, emp); + if (++echon > maxecho) { + emp = cmsg_prev(&echobase); + cmsg_free(emp); + } + + /* queue it for sending */ + cmsg_send(f->outq, imp, 0); f->sp->flags |= SEL_OUTPUT; f->obuf = 0; } @@ -572,12 +589,20 @@ void setmode(char *m) void process_stdin() { - cmsg_t *mp = cmsg_next(in->inq); + cmsg_t *wmp, *mp = cmsg_next(in->inq); char *p, hasa, hasn, i; char callsign[MAXCALLSIGN+1]; if (mp) { dbg(DMSG, "MSG size: %d", mp->size); + + /* check for echos */ + for (wmp = 0; wmp = chain_get_next(&echobase, wmp); ) { + if (!memcmp(wmp->data, mp->data, wmp->size)) { + cmsg_callback(mp, 0); + return; + } + } switch (state) { case CONNECTED: @@ -854,6 +879,8 @@ main(int argc, char *argv[]) #ifdef SIGPWR signal(SIGPWR, terminate); #endif + /* init a few things */ + chain_init(&echobase); /* connect up stdin */ in = fcb_new(0, TEXT); diff --git a/src/cmsg.c b/src/cmsg.c index 8732f19b..c3c79ef8 100755 --- a/src/cmsg.c +++ b/src/cmsg.c @@ -91,6 +91,7 @@ cmsg_t *cmsg_new(int size, int sort, void *pp) return mp; } + void cmsg_send(reft *base, cmsg_t *mp, void (*callback)()) { time(&mp->t); @@ -177,7 +178,11 @@ void cmsg_flush(reft *base, int reply) /* * * $Log$ - * Revision 1.2 2000-07-20 14:16:00 minima + * Revision 1.3 2000-10-29 11:00:07 minima + * added echo cancelling + * started new filter code, objectifyed old filter code + * + * Revision 1.2 2000/07/20 14:16:00 minima * can use Sourceforge now! * added user->qra cleaning * added 4 digit qra to user broadcast dxspots if available