X-Git-Url: http://dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl%2FDXCommandmode.pm;h=38773783798e61d6191121d79192f3bab9859b06;hb=431c8a14cdecd0ec455b6619380687dbe84e2a35;hp=cbba3b79210bf5ebfa0a77f8377ad57ff80816a6;hpb=0de1a272bd43c887020d9e03a4f56f44ab4bb080;p=spider.git diff --git a/perl/DXCommandmode.pm b/perl/DXCommandmode.pm index cbba3b79..38773783 100644 --- a/perl/DXCommandmode.pm +++ b/perl/DXCommandmode.pm @@ -13,7 +13,7 @@ package DXCommandmode; @ISA = qw(DXChannel); -require 5.10.1; +use 5.10.1; use POSIX qw(:math_h); use DXUtil; @@ -43,12 +43,12 @@ use JSON; use Time::HiRes qw(gettimeofday tv_interval); use Mojo::IOLoop; -use Mojo::IOLoop::ForkCall; +use DXSubprocess; use Mojo::UserAgent; use strict; use vars qw(%Cache %cmd_cache $errstr %aliases $scriptbase %nothereslug - $maxbadcount $msgpolltime $default_pagelth $cmdimportdir); + $maxbadcount $msgpolltime $default_pagelth $cmdimportdir $users $maxusers); %Cache = (); # cache of dynamically loaded routine's mod times %cmd_cache = (); # cache of short names @@ -59,7 +59,8 @@ $maxbadcount = 3; # no of bad words allowed before disconnection $msgpolltime = 3600; # the time between polls for new messages $cmdimportdir = "$main::root/cmd_import"; # the base directory for importing command scripts # this does not exist as default, you need to create it manually -# +$users = 0; # no of users on this node currently +$maxusers = 0; # max no users on this node for this run # # obtain a new connection this is derived from dxchannel @@ -135,6 +136,7 @@ sub start $self->{dx} = $user->wantdx; $self->{logininfo} = $user->wantlogininfo; $self->{ann_talk} = $user->wantann_talk; + $self->{wantrbn} = $user->wantrbn; $self->{here} = 1; $self->{prompt} = $user->prompt if $user->prompt; $self->{lastmsgpoll} = 0; @@ -175,7 +177,10 @@ sub start $self->{annfilter} = Filter::read_in('ann', $call, 0) || Filter::read_in('ann', $nossid, 0) || Filter::read_in('ann', 'user_default', 0) ; - + $self->{rbnfilter} = Filter::read_in('rbn', $call, 0) + || Filter::read_in('rbn', $nossid, 0) + || Filter::read_in('rbn', 'user_default', 0); + # clean up qra locators my $qra = $user->qra; $qra = undef if ($qra && !DXBearing::is_qra($qra)); @@ -209,8 +214,7 @@ sub start $script->run($self) if $script; # send cluster info - my $info = Route::cluster(); - $self->send("Cluster:$info"); + $self->send($self->run_cmd("show/cluster")); # send prompts for qth, name and things $self->send($self->msg('namee1')) if !$user->name; @@ -490,7 +494,7 @@ sub send_ans } # -# this is the thing that runs the command, it is done like this for the +# this is the thing that preps for running the command, it is done like this for the # benefit of remote command execution # @@ -544,8 +548,17 @@ sub run_cmd if ($package && $self->can("${package}::handle")) { no strict 'refs'; dbg("cmd: package $package") if isdbg('command'); + my $t0 = [gettimeofday]; eval { @ans = &{"${package}::handle"}($self, $args) }; - return (DXDebug::shortmess($@)) if $@; + if ($@) { + DXDebug::dbgprintring(25); + return (DXDebug::shortmess($@)); + } + if (isdbg('progress')) { + my $msecs = _diffms($t0); + my $s = "CMD: '$cmd $args' by $call ip: $self->{hostname} ${msecs}mS"; + dbg($s) if $cmd !~ /^(?:echo|blank)/ || isdbg('echo'); # cut down a bit on HRD and other clients' noise + } } else { dbg("cmd: $package not present") if isdbg('command'); return $self->_error_out('e1'); @@ -578,7 +591,8 @@ sub process my $t = time; my @dxchan = DXChannel::get_all(); my $dxchan; - + + $users = 0; foreach $dxchan (@dxchan) { next unless $dxchan->is_user; @@ -593,6 +607,8 @@ sub process $dxchan->prompt() if $dxchan->{state} =~ /^prompt/o; $dxchan->t($t); } + ++$users; + $maxusers = $users if $users > $maxusers; } while (my ($k, $v) = each %nothereslug) { @@ -683,7 +699,7 @@ sub broadcast # gimme all the users sub get_all { - return grep {$_->is_user} DXChannel::get_all(); + goto &DXChannel::get_all_users; } # run a script for this user @@ -823,7 +839,7 @@ sub find_cmd_name { }; #wrap the code into a subroutine inside our unique package - my $eval = qq(package DXCommandmode::$package; use POSIX qw{:math_h}; use DXLog; use DXDebug; use DXUser; use DXUtil; our \@ISA = qw{DXCommandmode}; ); + my $eval = qq(package DXCommandmode::$package; use 5.10.1; use POSIX qw{:math_h}; use DXLog; use DXDebug; use DXUser; use DXUtil; our \@ISA = qw{DXCommandmode}; ); if ($sub =~ m|\s*sub\s+handle\n|) { @@ -980,29 +996,37 @@ sub format_dx_spot my $t = ztime($_[2]); my $loc = ''; - my $clth = $self->{consort} eq 'local' ? 29 : 30; + my $clth = 30; + # --$clth if $self->{consort} eq 'local'; + my $comment = substr (($_[3] || ''), 0, $clth); - $comment .= ' ' x ($clth - length($comment)); - if ($self->{user}->wantgrid) { - my $ref = DXUser::get_current($_[4]); - if ($ref) { - $loc = $ref->qra || ''; - $loc = ' ' . substr($loc, 0, 4) if $loc; + $comment .= ' ' x ($clth - (length($comment))); + + if ($self->{user}->wantgrid) { + my $ref = DXUser::get_current($_[1]); + if ($ref && $ref->qra) { + my $cloc = ' ' . substr($ref->qra, 0, 4); + $comment = substr $comment, 0, ($clth - (length($comment)+length($cloc))); + $comment .= $cloc; } - } - - if ($self->{user}->wantdxitu) { + my $origin = $_[4]; + $origin =~ s/-#$//; # sigh...... + $ref = DXUser::get_current($origin); + if ($ref && $ref->qra) { + $loc = ' ' . substr($ref->qra, 0, 4); + } + } elsif ($self->{user}->wantdxitu) { $loc = ' ' . sprintf("%2d", $_[10]) if defined $_[10]; - $comment = substr($comment, 0, $self->{consort} eq 'local' ? 26 : 27) . ' ' . sprintf("%2d", $_[8]) if defined $_[8]; + $comment = substr($comment, 0, $clth-3) . ' ' . sprintf("%2d", $_[8]) if defined $_[8]; } elsif ($self->{user}->wantdxcq) { $loc = ' ' . sprintf("%2d", $_[11]) if defined $_[11]; - $comment = substr($comment, 0, $self->{consort} eq 'local' ? 26 : 27) . ' ' . sprintf("%2d", $_[9]) if defined $_[9]; + $comment = substr($comment, 0, $clth-3) . ' ' . sprintf("%2d", $_[9]) if defined $_[9]; } elsif ($self->{user}->wantusstate) { $loc = ' ' . $_[13] if $_[13]; - $comment = substr($comment, 0, $self->{consort} eq 'local' ? 26 : 27) . ' ' . $_[12] if $_[12]; + $comment = substr($comment, 0, $clth-3) . ' ' . $_[12] if $_[12]; } - return sprintf "DX de %-7.7s%11.1f %-12.12s %-s $t$loc", "$_[4]:", $_[0], $_[1], $comment; + return sprintf "DX de %-9.9s%10.1f %-12.12s %-s $t$loc", "$_[4]:", $_[0], $_[1], $comment; } # send a dx spot @@ -1265,22 +1289,6 @@ sub send_motd $self->send_file($motd) if -e $motd; } -sub _diffms -{ - return unless isdbg('chan'); - my $call = shift; - my $line = shift; - my $ta = shift; - my $tb = shift || [gettimeofday]; - - my $a = int($ta->[0] * 1000) + int($ta->[1] / 1000); - my $b = int($tb->[0] * 1000) + int($tb->[1] / 1000); - my $msecs = $b - $a; - - my $s = "forkcall stats: $call '$line' "; - $s .= "${msecs}mS"; - dbg($s); -} # Punt off a long running command into a separate process # @@ -1309,39 +1317,67 @@ sub spawn_cmd my $t0 = [gettimeofday]; no strict 'refs'; - - my $fc = Mojo::IOLoop::ForkCall->new; - $fc->serializer(\&encode_json); - $fc->deserializer(\&decode_json); + + # just behave normally if something has set the "one-shot" _nospawn in the channel + if ($self->{_nospawn}) { + eval { @out = $cmdref->(@$args); }; + if ($@) { + DXDebug::dbgprintring(25); + push @out, DXDebug::shortmess($@); + } + return @out; + } + + my $fc = DXSubprocess->new; +# $fc->serializer(\&encode_json); +# $fc->deserializer(\&decode_json); $fc->run( - sub {my @args = @_; my @res = $cmdref->(@args); return @res}, - $args, + sub { + my $subpro = shift; + if (isdbg('progress')) { + my $s = qq{line: "$line"}; + $s .= ", args: " . join(', ', map { defined $_ ? qq{'$_'} : q{'undef'} } @$args) if $args && @$args; + dbg($s); + } + eval { @out = $cmdref->(@$args); }; + if ($@) { + DXDebug::dbgprintring(25); + push @out, DXDebug::shortmess($@); + } + return @out; + }, +# $args, sub { my ($fc, $err, @res) = @_; my $dxchan = DXChannel::get($call); return unless $dxchan; - if (defined $err) { - my $s = "DXCommand::spawn_cmd: call $call error $err"; + if ($err) { + my $s = "DXProt::spawn_cmd: call $call error $err"; dbg($s) if isdbg('chan'); $dxchan->send($s); return; } if ($cb) { - $cb->($dxchan, @res); - } else { - return unless @res; + # transform output if required + @res = $cb->($dxchan, @res); + } + if (@res) { if (defined $prefix) { $dxchan->send(map {"$prefix$_"} @res); } else { $dxchan->send(@res); } } - _diffms($call, $line, $t0); + diffms("by $call", $line, $t0, scalar @res) if isdbg('progress'); }); return @out; } +sub user_count +{ + return ($users, $maxusers); +} 1; __END__