+use vars qw($pc11_max_age $pc23_max_age $last_pc50 $eph_restime $eph_info_restime $eph_pc34_restime
+ $last_hour $last10 %eph %pings %rcmds $ann_to_talk
+ $pingint $obscount %pc19list $chatdupeage $chatimportfn
+ $pc19_version $myprot_version
+ %nodehops $baddx $badspotter $badnode $censorpc
+ $allowzero $decode_dk0wcy $send_opernam @checklist
+ $eph_pc15_restime $pc92_update_period $pc92_obs_timeout
+ %pc92_find $pc92_find_timeout $pc92_short_update_period
+ $next_pc92_obs_timeout $pc92_slug_changes $last_pc92_slug
+ $pc92_extnode_update_period $pc50_interval
+ $pc92_keepalive_period $senderverify
+ );
+
+$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
+
+$last_hour = time; # last time I did an hourly periodic update
+%rcmds = (); # outstanding rcmd requests outbound
+%nodehops = (); # node specific hop control
+%pc19list = (); # list of outstanding PC19s that haven't had PC16s on them
+
+$censorpc = 1; # Do a BadWords::check on text fields and reject things
+ # loads of 'bad things'
+$baddx = new DXHash "baddx";
+$badspotter = new DXHash "badspotter";
+$badnode = new DXHash "badnode";
+$last10 = $last_pc50 = time;
+$ann_to_talk = 1;
+$eph_restime = 60;
+$eph_info_restime = 18*60*60;
+$eph_pc15_restime = 6*60;
+$eph_pc34_restime = 30;
+$pingint = 5*60;
+$obscount = 2;
+$chatdupeage = 20 * 60;
+$chatimportfn = "$main::root/chat_import";
+$pc19_version = 5455; # the visible version no for outgoing PC19s generated from pc59
+$pc92_update_period = 4*60*60; # the period between outgoing PC92 C updates
+$pc92_short_update_period = 15*60; # shorten the update period after a connection or start up
+$pc92_extnode_update_period = 1*60*60; # the update period for external nodes
+$pc92_keepalive_period = 1*60*60; # frequency of PC92 K (keepalive) records
+%pc92_find = (); # outstanding pc92 find operations
+$pc92_find_timeout = 30; # maximum time to wait for a reply
+$senderverify = 0; # 1 = check spotter is on node it says it is and check ip address if available
+ # 2 = do 1 and dump if check
+
+
+@checklist =
+(
+ [ qw(i c c m bp bc c) ], # pc10
+ [ qw(i f m d t m c c h) ], # pc11
+ [ qw(i c bm m bm bm p h) ], # pc12
+ [ qw(i c h) ], #
+ [ qw(i c h) ], #
+ [ qw(i c m h) ], #
+ undef , # pc16 has to be validated manually
+ [ qw(i c c h) ], # pc17
+ [ qw(i m n) ], # pc18
+ undef , # pc19 has to be validated manually
+ undef , # pc20 no validation
+ [ qw(i c m h) ], # pc21
+ undef , # pc22 no validation
+ [ qw(i d n n n n m c c h) ], # pc23
+ [ qw(i c p h) ], # pc24
+ [ qw(i c c n n) ], # pc25
+ [ qw(i f m d t m c c bc) ], # pc26
+ [ qw(i d n n n n m c c bc) ], # pc27
+ [ qw(i c c m c d t p m bp n p bp bc) ], # pc28
+ [ qw(i c c n m) ], # pc29
+ [ qw(i c c n) ], # pc30
+ [ qw(i c c n) ], # pc31
+ [ qw(i c c n) ], # pc32
+ [ qw(i c c n) ], # pc33
+ [ qw(i c c m) ], # pc34
+ [ qw(i c c m) ], # pc35
+ [ qw(i c c m) ], # pc36
+ [ qw(i c c n m) ], # pc37
+ undef, # pc38 not interested
+ [ qw(i c m) ], # pc39
+ [ qw(i c c m p n) ], # pc40
+ [ qw(i c n m h) ], # pc41
+ [ qw(i c c n) ], # pc42
+ undef, # pc43 don't handle it
+ [ qw(i c c n m m c) ], # pc44
+ [ qw(i c c n m) ], # pc45
+ [ qw(i c c n) ], # pc46
+ undef, # pc47
+ undef, # pc48
+ [ qw(i c m h) ], # pc49
+ [ qw(i c n h) ], # pc50
+ [ qw(i c c n) ], # pc51
+ undef,
+ undef,
+ undef,
+ undef,
+ undef,
+ undef,
+ undef,
+ undef,
+ undef, # pc60
+ [ qw(i f m d t m c c a h) ], # pc61
+ undef,
+ undef,
+ undef,
+ undef,
+ undef,
+ undef,
+ undef,
+ undef,
+ undef, # pc70
+ undef,
+ undef,
+ [ qw(i d n n n n n n m m m c c h) ], # pc73
+ undef,
+ undef,
+ undef,
+ undef,
+ undef,
+ undef,
+ undef, # pc80
+ undef,
+ undef,
+ undef,
+ [ qw(i c c c m) ], # pc84
+ [ qw(i c c c m) ], # pc85
+ undef,
+ undef,
+ undef,
+ undef,
+ undef, # pc90
+ undef,
+ [ qw(i c f l)], # pc92
+ [ qw(i c f *m c *c m)], # pc93
+);
+
+# use the entry in the check list to check the field list presented
+# return OK if line NOT in check list (for now)
+sub check
+{
+ my $n = shift;
+ my $pc = shift;
+
+ $n -= 10;
+ return 0 if $n < 0 || $n > @checklist;
+ my $ref = $checklist[$n];
+ return 0 unless ref $ref;
+
+ my $i;
+ for ($i = 1; $i < @$ref; $i++) {
+ my ($blank, $act) = $$ref[$i] =~ /^(b?)(\w)$/;
+ return 0 unless $act;
+ next if $blank eq 'b' && $pc->[$i] =~ /^[ \*]$/;
+ next if $blank eq '*' && $pc->[$i] =~ /^\*$/;
+ if ($act eq 'c') {
+ return $i unless is_callsign($pc->[$i]);
+ } elsif ($act eq 'i') {
+ ; # do nothing
+ } elsif ($act eq 'm') {
+ return $i unless is_pctext($pc->[$i]);
+ } elsif ($act eq 'p') {
+ return $i unless is_pcflag($pc->[$i]);
+ } elsif ($act eq 'f') {
+ return $i unless is_freq($pc->[$i]);
+ } elsif ($act eq 'n') {
+ return $i unless $pc->[$i] =~ /^[\d ]+$/;
+ } elsif ($act eq 'h') {
+ return $i unless $pc->[$i] =~ /^H\d\d?$/;
+ } elsif ($act eq 'd') {
+ return $i unless $pc->[$i] =~ /^\s*\d+-\w\w\w-[12][90]\d\d$/;
+ } elsif ($act eq 't') {
+ return $i unless $pc->[$i] =~ /^[012]\d[012345]\dZ$/;
+ } elsif ($act eq 'l') {
+ return $i unless $pc->[$i] =~ /^[A-Z]$/;
+ } elsif ($act eq 'a') {
+ return $i unless is_ipaddr($pc->[$i]);
+ }
+ }
+ return 0;
+}
+
+sub update_pc92_next
+{
+ my $self = shift;
+ my $period = shift || ($self->{do_pc9x} ? $pc92_update_period : $pc92_extnode_update_period);
+ $self->{next_pc92_update} = $main::systime + $period - int rand($period / 4);
+ dbg("ROUTE: update_pc92_next: $self->{call} " . atime($self->{next_pc92_update})) if isdbg('obscount');
+}
+
+sub update_pc92_keepalive
+{
+ my $self = shift;
+ my $period = shift || $pc92_keepalive_period;
+ $self->{next_pc92_keepalive} = $main::systime + $period - int rand($period / 4);
+ dbg("ROUTE: update_pc92_keepalive: $self->{call} " . atime($self->{next_pc92_keepalive})) if isdbg('obscount');
+}