added echo cancelling
authorminima <minima>
Sun, 29 Oct 2000 11:00:06 +0000 (11:00 +0000)
committerminima <minima>
Sun, 29 Oct 2000 11:00:06 +0000 (11:00 +0000)
started new filter code, objectifyed old filter code

Changes
cmd/show/log.pl
perl/DXLogPrint.pm
perl/DXProt.pm
perl/Filter.pm
perl/client.pl
src/client.c
src/cmsg.c

diff --git a/Changes b/Changes
index e446baa86d840b1926c4bc60f5a11732c655f3d4..af1d970e2a6519e64a7efad158e8783dda64257c 100644 (file)
--- 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
index bced585507c753b95bf4420131544a4537fa1760..8a00e3852131b0972bfd44b9971ea185cd97885e 100644 (file)
@@ -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);
index 60f8b685bb8768e3e935629aca988c2b0bcd2d06..185912cda4948abefe7d3408da3d371651921417 100644 (file)
@@ -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;
index 5d2b10b8e38543bce9d20964f09f769152e18aca..db342dfb028c5b0dd57d9fc6415024f167f2821b 100644 (file)
@@ -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};
index a53ae034b6cfc4fd88426a483e171a12aedfb6f7..2b30c8cdea5c8484ca348e21442464cf50c9fe65 100644 (file)
 #
 # $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:-
-#
-# <some comment>
-# @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:-
+#
+# <some comment>
+# @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__
index b84945783155cd70a36685524ab78bf50fd98735..ff2ca473f82b03451e0f023d7d72d3ee6e9adc5b 100755 (executable)
@@ -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
index 167ef647acacc5101cf152223117d25e9023f62c..8df624494b3c7879cc60480458ff860369d4fe92 100644 (file)
@@ -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);
index 8732f19bc422577ed6ef87ac7f9bc8b96b1e1800..c3c79ef8303e0d8b50bddf209f9d989df10359db 100755 (executable)
@@ -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