remove any leading ::ffff: on ipv4 addresses
[spider.git] / perl / DXCommandmode.pm
index 46e4e03a12dfcd1ba1ff84a31593352aca08303f..3d5ce0c9f6fb5fa9744939c7e121b8429b06b706 100644 (file)
@@ -43,7 +43,7 @@ use JSON;
 use Time::HiRes qw(gettimeofday tv_interval);
 
 use Mojo::IOLoop;
-use Mojo::IOLoop::ForkCall;
+use Mojo::IOLoop::Subprocess;
 use Mojo::UserAgent;
 
 use strict;
@@ -73,7 +73,7 @@ sub new
        my $pkg = shift;
        my $call = shift;
 #      my @rout = $main::routeroot->add_user($call, Route::here(1));
-       DXProt::_add_thingy($main::routeroot, [$call, 0, 0, 1, undef, undef, $self->{conn}->peerhost], );
+       DXProt::_add_thingy($main::routeroot, [$call, 0, 0, 1, undef, undef, $self->hostname], );
 
        # ALWAYS output the user
        my $ref = Route::User::get($call);
@@ -100,7 +100,7 @@ sub start
        my $host = $self->{conn}->peerhost;
        $host ||= "AGW Port #$self->{conn}->{agwport}" if exists $self->{conn}->{agwport};
        $host ||= "unknown";
-       LogDbg('DXCommand', "$call connected from $host");
+       $self->{hostname} = $host;
 
        $self->{name} = $name ? $name : $call;
        $self->send($self->msg('l2',$self->{name}));
@@ -111,9 +111,20 @@ sub start
        $pagelth = $default_pagelth unless defined $pagelth;
        $self->{pagelth} = $pagelth;
        ($self->{width}) = $line =~ /width=(\d+)/; $line =~ s/\s*width=\d+\s*//;
+       if ($line =~ /host=/) {
+               my ($h) = $line =~ /host=(\d+\.\d+\.\d+\.\d+)/;
+               $line =~ s/\s*host=\d+\.\d+\.\d+\.\d+// if $h;
+               unless ($h) {
+                       ($h) = $line =~ /host=([\da..fA..F:]+)/;
+                       $line =~ s/\s*host=[\da..fA..F:]+// if $h;
+               }
+               $self->{hostname} = $h if $h;
+       }
        $self->{width} = 80 unless $self->{width} && $self->{width} > 80;
        $self->{consort} = $line;       # save the connection type
-       
+
+       LogDbg('DXCommand', "$call connected from $self->{hostname}");
+
        # set some necessary flags on the user if they are connecting
        $self->{beep} = $user->wantbeep;
        $self->{ann} = $user->wantann;
@@ -146,7 +157,7 @@ sub start
        $self->send_motd;
 
        # sort out privilege reduction
-       $self->{priv} = 0 if $line =~ /^(ax|te)/ && !$self->conn->{usedpasswd};
+       $self->{priv} = 0 unless $self->{hostname} eq '127.0.0.1' || $self->{hostname} eq '::1' || $self->conn->{usedpasswd};
 
        # get the filters
        my $nossid = $call;
@@ -479,7 +490,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
 #
 
@@ -1254,22 +1265,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
 #
@@ -1298,35 +1293,48 @@ 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
+       return ($cmdref->(@$args)) if $self->{_nospawn};
+       
+       my $fc = Mojo::IOLoop::Subprocess->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('spawn_cmd')) {
+                                        my $s = "line: $line";
+                                        $s .= ", args: " . join(', ', @$args) if $args && @$args;
+                                }
+                                my @res = $cmdref->(@$args);
+#                               diffms("rcmd from $call 1", $line, $t0, scalar @res) if isdbg('chan');
+                                return @res;
+                        },
+#                       $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('chan');
                         });
        
        return @out;