+15Mar99=======================================================================
+1. added $actiondata to filter line to allow per action data such as no of hops
+2. fixed a silly problem in talk for non-existant callsigns
+3. Added sysop command
02Mar99========================================================================
1. Changed DXUser so that it uses a homemade import/export hash routine
2. DXUser now uses a DB_BTREE file
explicitly to 0 will disable paging.
SET/PAGE 30
SET/PAGE 0
-
-=== 0^SHOW/PROGRAM^Show the locations of all the included program modules
-Show the name and location where every program module was load from. This
-is useful for checking where you think you have loaded a .pm file from.
=== 9^SET/PRIVILEGE <n> <call> [<call..]^Set privilege level on a call
Set the privilege level on a callsign. The privilege levels that pertain
If you are a sysop and you come in as a normal user on a remote connection
your privilege will automatically be set to 0.
+=== 9^SET/PASSWORD <callsign> <string>^Set a users password
+The password for a user can only be set by a full sysop. The string can contain
+any characters but any spaces are removed (you can type in spaces - but they
+won't appear in the password). You can see the result with STAT/USER.
+
=== 0^SET/QRA <locator>^Set your QRA locator
=== 9^SET/SYS_QRA <locator>^Set your cluster QRA locator
Tell the system what your QRA (or Maidenhead) locator is. If you have not
See also SHOW/DXCC
+=== 0^SHOW/PROGRAM^Show the locations of all the included program modules
+Show the name and location where every program module was load from. This
+is useful for checking where you think you have loaded a .pm file from.
+
=== 0^SHOW/WWV^Show last 10 WWV broadcasts
=== 0^SHOW/WWV <n>^Show last <n> WWV broadcasts
Display the most recent WWV information that has been received by the system
Only the fields that are defined (in perl term) will be displayed.
+=== 0^SYSOP^Regain your privileges if you login remotely
+The system automatically reduces your privilege level to that of a normal user
+if you login in remotely. This command allows you to regain your normal privilege
+level. It uses the normal system: five numbers are returned that are indexes into
+the character array that is your assigned password (see set/password). The indexes
+start from zero.
+
+You are expected to return a string which contains the characters required in the
+correct order. You may intersperse those characters with others to obscure your
+reply for any watchers. For example (and these values are for explanation :-):
+
+password = 012345678901234567890123456789
+ > sysop
+22 10 15 17 3
+you type:-
+aa2bbbb0ccc5ddd7xxx3n
+or 2 0 5 7 3
+or 20573
+
+They will all match. If there is no password you will still be offered numbers but
+nothing will happen when you input a string. Any match is case sensitive.
+
=== 0^TALK <call> <text>^Send a text message to another station
=== 0^TALK <call> > <node> <text>^Send a text message to another station via a node
Send a short message to any other station that is visible on the cluster
# Copyright (c) 1998 Iain Phillips G0RDI
# 21-Dec-1998
#
-# Syntax: set/pass <password> <callsign>
+# Syntax: set/pass <callsign> <password>
#
my ($self, $line) = @_;
my @args = split /\s+/, $line;
-my $call;
-my $pass = shift @args;
+my $call = shift @args;
my @out;
my $user;
my $ref;
return (1, $self->msg('e5')) if $self->priv < 9;
-foreach $call (@args) {
- $call = uc $call;
- if ($ref = DXUser->get_current($call)) {
- $ref->passwd($pass);
- $ref->put();
- push @out, $self->msg("password", $call);
- } else {
- push @out, $self->msg('e3', 'User record for', $call);
- }
+if ($ref = DXUser->get_current($call)) {
+ $line =~ s/^\s*$call\s+//;
+ $line =~ s/\s+//og; # remove any blanks
+ $ref->passwd($line);
+ $ref->put();
+ push @out, $self->msg("password", $call);
+} else {
+ push @out, $self->msg('e3', 'User record for', $call);
}
+
return (1, @out);
# if we haven't got an explicit via and we can't see them, try their node
unless ($ref || $via) {
my $user = DXUser->get($call);
- $ref = DXCluster->get_exact($user->node);
+ $ref = DXCluster->get_exact($user->node) if $user;
if ($ref) {
$via = $user->node;
push @out, "trying via $via..";
# 10 = spotter's itu
# 11 = spotter's cq
#
+# The spot data (in this case '15') is the used as the hop count
+# if this is missing then the normal default applies
+#
$in = [
- [ 1, 9, 'n', [ 14,15 ] ], # 14 and 15 is CQ region for europe
- [ 1, 11, 'n', [ 14,15 ] ],
+ [ 1, 9, 'n', [ 14,15 ], 15 ], # 14 and 15 is CQ region for europe
+ [ 1, 11, 'n', [ 14,15 ], 15 ],
[ 0, 0, 'd' ],
];
# 10 = spotter's itu
# 11 = spotter's cq
#
+# The spot data (in this case '15') is the used as the hop count
+# if this is missing then the normal default applies
+#
$in = [
- [ 1, 5, 'n', [ 226 ] ], # dxcc country 226 is the US
- [ 1, 6, 'a', [ 226 ] ],
+ [ 1, 5, 'n', [ 226 ], 15 ], # dxcc country 226 is the US
+ [ 1, 6, 'a', [ 226 ], 15 ],
[ 0, 0, 'd' ], # default action (don't forward)
];
annfilter => '9,Announce Filter',
wwvfilter => '9,WWV Filter',
spotfilter => '9,Spot Filter',
+ passwd => '9,Passwd List,parray',
);
# create a new channel object [$obj = DXChannel->new($call, $msg_conn_obj, $user_obj)]
} else {
$self->state('prompt');
}
+ } elsif ($self->{state} eq 'sysop') {
+ my $passwd = $self->{user}->passwd;
+ my @pw = split / */, $passwd;
+ if ($passwd) {
+ my @l = @{$self->{passwd}};
+ my $str = "$pw[$l[0]].*$pw[$l[1]].*$pw[$l[2]].*$pw[$l[3]].*$pw[$l[4]]";
+ if ($cmdline =~ /$str/) {
+ $self->{priv} = $self->{user}->priv;
+ } else {
+ $self->send($self->msg('sorry'));
+ }
+ }
+ delete $self->{passwd};
+ $self->state('prompt');
} else {
@ans = run_cmd($self, $cmdline); # if length $cmdline;
my $dxchan;
# send it if it isn't the except list and isn't isolated and still has a hop count
+ # taking into account filtering and so on
foreach $dxchan (@dxchan) {
next if $dxchan == $self;
- my $filter = Filter::it($dxchan->{spotfilter}, @spot) if $dxchan->{spotfilter};
- my $routeit = adjust_hops($dxchan, $line); # adjust its hop count by node name
- next unless $routeit;
+ my $routeit;
+ my ($filter, $hops) = Filter::it($dxchan->{spotfilter}, @spot) if $dxchan->{spotfilter};
+ if ($hops) {
+ $line =~ s/\^H\d+\^\~$/\^H$hops\^\~/;
+ } else {
+ $routeit = adjust_hops($dxchan, $line); # adjust its hop count by node name
+ next unless $routeit;
+ }
if ($filter) {
$dxchan->send($routeit) if $routeit;
} else {
if ($sort eq 'dx') {
next unless $dxchan->{dx};
- $filter = Filter::it($dxchan->{spotfilter}, @{$fref}) if ref $fref;
+ ($filter) = Filter::it($dxchan->{spotfilter}, @{$fref}) if ref $fref;
next unless $filter;
}
next if $sort eq 'ann' && !$dxchan->{ann};
my ($pkg, $fn, $mode) = @_;
confess "need a filename in User" if !$fn;
- $fn .= ".new";
+ $fn .= ".v2";
if ($mode) {
$dbm = tie (%u, 'DB_File', $fn, O_CREAT|O_RDWR, 0666, $DB_BTREE) or confess "can't open user file: $fn ($!)";
} else {
#
# <some comment>
# @in = (
-# [ action, fieldno, fieldsort, comparison ],
+# [ action, fieldno, fieldsort, comparison, action data ],
# ...
# );
#
# 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. The fields
+# 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.
#
sub it
{
my $filter = shift;
+ my ($action, $field, $fieldsort, $comp, $actiondata);
my $ref;
# default action is 1
- return 1 if !$filter;
-
+ $action = 1;
+ $actiondata = "";
+ return ($action, $actiondata) if !$filter;
+
for $ref (@{$filter}) {
- my ($action, $field, $fieldsort, $comp) = @{$ref};
+ ($action, $field, $fieldsort, $comp, $actiondata) = @{$ref};
if ($fieldsort eq 'n') {
my $val = $_[$field];
- return $action if grep $_ == $val, @{$comp};
+ 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 if $val >= $range[$i] && $val <= $range[$i+1];
+ return ($action, $actiondata) if $val >= $range[$i] && $val <= $range[$i+1];
}
} elsif ($fieldsort eq 'a') {
- return $action if $_[$field] =~ m{$comp};
+ return ($action, $actiondata) if $_[$field] =~ m{$comp};
} else {
- return $action; # the default action
+ return ($action, $actiondata); # the default action
}
}
}
}
my $today = localtime;
- print FILTER "#
+ print FILTER "#!/usr/bin/perl
+#
# Filter for $call stored $today
#
\$in = [
my $ref;
for $ref (@_) {
- my ($action, $field, $fieldsort, $comp) = @{$ref};
+ my ($action, $field, $fieldsort, $comp, $actiondata) = @{$ref};
print FILTER "\t[ $action, $field, $fieldsort,";
if ($fieldsort eq 'n' || $fieldsort eq 'r') {
print FILTER "[ ", join (',', $comp), " ],";
shutting => '$main::mycall shutting down...',
sloc => 'Cluster lat $_[0] long $_[1], DON\'T FORGET TO CHANGE YOUR DXVars.pm',
sqra => 'Cluster QRA Locator$_[0], DON\'T FORGET TO CHANGE YOUR DXVars.pm',
+ sorry => 'Sorry',
talks => 'Talk flag set on $_[0]',
talku => 'Talk flag unset on $_[0]',
usernf => '*** User record for $_[0] not found ***',
for $a (@all) {
my $ref = DXUser->get($a);
- my $s = $ref->encode();
+ my $s = $ref->encode() if $ref;
print OUT "'$a' => q{$s},\n" if $a;
$count++;
}
use Carp;
$userfn = $ARGV[0] if @ARGV;
-unless ($userfn) {
- croak "need a filename";
-}
+croak "need a filename" unless $userfn;
+croak "$userfn.asc doesn't exist" unless -e "$userfn.asc";
DXUser->init($userfn, 1);