+%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;
+$rspfcheck = 1;
+$eph_restime = 180;
+$eph_info_restime = 60*60;
+$eph_pc15_restime = 6*60;
+$eph_pc34_restime = 30;
+$pingint = 5*60;
+$obscount = 2;
+$chatdupeage = 20 * 60 * 60;
+$chatimportfn = "$main::root/chat_import";
+$investigation_int = 12*60*60; # time between checks to see if we can see this node
+$pc19_version = 5466; # the visible version no for outgoing PC19s generated from pc59
+$pc92_update_period = 60*60; # the period between PC92 C updates
+$pc92_short_update_period = 15*60; # shorten the update period after a connection
+%pc92_find = (); # outstanding pc92 find operations
+$pc92_find_timeout = 30; # maximum time to wait for a reply
+$pc92_obs_timeout = $pc92_update_period; # the time between obscount countdowns
+
+
+
+@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
+ undef,
+ 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,
+ [ qw(i c n) ], # pc90
+);
+
+# 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;
+ $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 && $_[$i] =~ /^[ \*]$/;
+ if ($act eq 'c') {
+ return $i unless is_callsign($_[$i]);
+ } elsif ($act eq 'i') {
+ ; # do nothing
+ } elsif ($act eq 'm') {
+ return $i unless is_pctext($_[$i]);
+ } elsif ($act eq 'p') {
+ return $i unless is_pcflag($_[$i]);
+ } elsif ($act eq 'f') {
+ return $i unless is_freq($_[$i]);
+ } elsif ($act eq 'n') {
+ return $i unless $_[$i] =~ /^[\d ]+$/;
+ } elsif ($act eq 'h') {
+ return $i unless $_[$i] =~ /^H\d\d?$/;
+ } elsif ($act eq 'd') {
+ return $i unless $_[$i] =~ /^\s*\d+-\w\w\w-[12][90]\d\d$/;
+ } elsif ($act eq 't') {
+ return $i unless $_[$i] =~ /^[012]\d[012345]\dZ$/;
+ }
+ }
+ return 0;
+}
+
+sub update_pc92_next
+{
+ my $self = shift;
+ my $period = shift || $pc92_update_period;
+ $self->{next_pc92_update} = $main::systime + $period - int rand($period / 4);
+}