put in a prototype echo handler in Msg/ExtMsg
[spider.git] / perl / Msg.pm
index 6e2082e55ca86bcbaf1f1d221bd87625fb621eef..615feb1987e4a102def727f208d093107f63d85b 100644 (file)
 package Msg;
 
 use strict;
+
+use vars qw($VERSION $BRANCH);
+$VERSION = sprintf( "%d.%03d", q$Revision$ =~ /(\d+)\.(\d+)/ );
+$BRANCH = sprintf( "%d.%03d", q$Revision$ =~ /\d+\.\d+\.(\d+)\.(\d+)/ ) || 0;
+$main::build += $VERSION;
+$main::branch += $BRANCH;
+
 use IO::Select;
 use IO::Socket;
 use DXDebug;
 use Timer;
 
-use vars qw(%rd_callbacks %wt_callbacks %er_callbacks $rd_handles $wt_handles $er_handles $now %conns $noconns $blocking_supported);
+use vars qw(%rd_callbacks %wt_callbacks %er_callbacks $rd_handles $wt_handles $er_handles $now %conns $noconns $blocking_supported $cnum);
 
 %rd_callbacks = ();
 %wt_callbacks = ();
@@ -53,6 +60,8 @@ my $eagain = eval {EAGAIN()};
 my $einprogress = eval {EINPROGRESS()};
 my $ewouldblock = eval {EWOULDBLOCK()};
 $^W = $w;
+$cnum = 0;
+
 
 #
 #-----------------------------------------------------------------
@@ -73,10 +82,12 @@ sub new
                csort => 'telnet',
                timeval => 60,
                blocking => 0,
-               cnum => ++$noconns,
+               cnum => (($cnum < 999) ? (++$cnum) : ($cnum = 1)),
     };
 
-       dbg('connll', "Connection created ($noconns)");
+       $noconns++;
+       
+       dbg("Connection created ($noconns)") if isdbg('connll');
        return bless $conn, $class;
 }
 
@@ -118,11 +129,11 @@ sub conns
        if (ref $pkg) {
                $call = $pkg->{call} unless $call;
                return undef unless $call;
-               dbg('connll', "changing $pkg->{call} to $call") if exists $pkg->{call} && $call ne $pkg->{call};
-               delete $conns{$pkg->{call}} if $pkg->{call} ne $call; 
+               dbg("changing $pkg->{call} to $call") if isdbg('connll') && exists $pkg->{call} && $call ne $pkg->{call};
+               delete $conns{$pkg->{call}} if exists $pkg->{call} && exists $conns{$pkg->{call}} && $pkg->{call} ne $call; 
                $pkg->{call} = $call;
                $ref = $conns{$call} = $pkg;
-               dbg('connll', "Connection $pkg->{cnum} $call stored");
+               dbg("Connection $pkg->{cnum} $call stored") if isdbg('connll');
        } else {
                $ref = $conns{$call};
        }
@@ -195,7 +206,7 @@ sub disconnect {
                delete $conns{$call} if $ref && $ref == $conn;
        }
        $call ||= 'unallocated';
-       dbg('connll', "Connection $conn->{cnum} $call disconnected");
+       dbg("Connection $conn->{cnum} $call disconnected") if isdbg('connll');
        
        unless ($main::is_win) {
                kill 'TERM', $conn->{pid} if exists $conn->{pid};
@@ -283,13 +294,11 @@ sub _send {
         delete $conn->{send_offset};
         $offset = 0;
         shift @$rq;
-        last unless $flush; # Go back to select and wait
+        #last unless $flush; # Go back to select and wait
                             # for it to fire again.
     }
     # Call me back if queue has not been drained.
-    if (@$rq) {
-        set_event_handler ($sock, write => sub {$conn->_send(0)});
-    } else {
+    unless (@$rq) {
         set_event_handler ($sock, write => undef);
                if (exists $conn->{close_on_empty}) {
                        &{$conn->{eproc}}($conn, undef) if exists $conn->{eproc};
@@ -377,11 +386,29 @@ sub _rcv {                     # Complement to _send
        $bytes_read = sysread ($sock, $msg, 1024, 0);
        if (defined ($bytes_read)) {
                if ($bytes_read > 0) {
-                       $conn->{msg} .= $msg;
                        if (isdbg('raw')) {
                                my $call = $conn->{call} || 'none';
                                dbgdump('raw', "$call read $bytes_read: ", $msg);
                        }
+                       if ($conn->{echo}) {
+                               my @ch = split //, $msg;
+                               my $out;
+                               for (@ch) {
+                                       if (/[\cH\x7f]/) {
+                                               $out .= "\cH \cH";
+                                               $conn->{msg} =~ s/.$//;
+                                       } else {
+                                               $out .= $_;
+                                               $conn->{msg} .= $_;
+                                       }
+                               }
+                               if (defined $out) {
+                                       set_event_handler ($sock, write => sub{$conn->_send(0)});
+                                       push @{$conn->{outqueue}}, $out;
+                               }
+                       } else {
+                               $conn->{msg} .= $msg;
+                       }
                } 
        } else {
                if (_err_will_block($!)) {
@@ -396,7 +423,9 @@ FINISH:
                &{$conn->{eproc}}($conn, $!) if exists $conn->{eproc};
                $conn->disconnect;
     } else {
-               $conn->dequeue if exists $conn->{msg};
+               unless ($conn->{disable_read}) {
+                       $conn->dequeue if exists $conn->{msg};
+               }
        }
 }
 
@@ -423,7 +452,7 @@ sub new_client {
                        $conn->disconnect();
                }
        } else {
-               dbg('err', "Msg: error on accept ($!)");
+               dbg("Msg: error on accept ($!)") if isdbg('err');
        }
 }
 
@@ -442,6 +471,13 @@ sub close_all_clients
        }
 }
 
+sub disable_read
+{
+       my $conn = shift;
+       set_event_handler ($conn->{sock}, read => undef);
+       return $_[0] ? $conn->{disable_read} = $_[0] : $_[0];
+}
+
 #
 #----------------------------------------------------
 # Event loop routines used by both client and server
@@ -525,7 +561,7 @@ sub DESTROY
        my $call = $conn->{call} || 'unallocated';
        my $host = $conn->{peerhost} || '';
        my $port = $conn->{peerport} || '';
-       dbg('connll', "Connection $conn->{cnum} $call [$host $port] being destroyed");
+       dbg("Connection $conn->{cnum} $call [$host $port] being destroyed") if isdbg('connll');
        $noconns--;
 }