1 # File: Stem/Console.pm
3 # This file is part of Stem.
4 # Copyright (C) 1999, 2000, 2001 Stem Systems, Inc.
6 # Stem is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # Stem is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with Stem; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 # For a license to use the Stem under conditions other than those
21 # described here, to purchase support for this software, or to purchase a
22 # commercial warranty contract, please contact Stem Systems at:
24 # Stem Systems, Inc. 781-643-7504
25 # 79 Everett St. info@stemsystems.com
29 package Stem::Console ;
31 use Stem::Trace 'log' => 'stem_status', 'sub' => 'TraceStatus' ;
32 use Stem::Trace 'log' => 'stem_error' , 'sub' => 'TraceError' ;
46 my( $read_fh, $write_fh, $parent_fh, $child_fh ) ;
48 if ( $^O =~ /Win32/ ) {
54 socketpair( $parent_fh, $child_fh, AF_UNIX, SOCK_STREAM, PF_UNSPEC ) ;
60 $read_fh = $parent_fh ;
61 $write_fh = $parent_fh ;
66 $write_fh = \*STDOUT ;
69 return init() unless $Env{'console_disable'} || $Env{'tty_disable'} ;
80 #syswrite( \*STDERR, "reader started\n" ) ;
81 #warn "reader started2\n" ;
87 my $cnt = sysread( \*STDIN, $buf, 1000 ) ;
89 #syswrite( \*STDERR, $buf ) ;
91 syswrite( $child_fh, $buf ) ;
107 my $cnt = sysread( $child_fh, $buf, 1000 ) ;
109 syswrite( \*STDOUT, $buf ) ;
115 Stem::Route::register_class( __PACKAGE__, 'cons', 'console', 'tty' ) ;
117 $Env{'has_console'} = 1 ;
119 my $self = bless {} ;
121 my $aio = Stem::AsyncIO->new(
124 'read_fh' => $read_fh,
125 'write_fh' => $write_fh,
126 'read_method' => 'stdin_read',
127 'closed_method' => 'stdin_closed',
130 return $aio unless ref $aio ;
132 $self->{'aio'} = $aio ;
134 $self->{'prompt'} = $Env{'prompt'} || "\nStem > " ;
136 $console_obj = $self ;
138 $self->write( "\nEnter 'help' for help\n\n" ) ;
146 my( $self, $line_ref ) = @_ ;
148 $line = ${$line_ref} ;
152 if ( $line =~ /^\s*$/ ) {
158 if ( $line =~ /^quit\s*$/i ) {
160 TraceStatus "quitting" ;
165 if ( $line =~ /^\s*help\s*$/i ) {
172 if ( my( $key, $val ) = $line =~ /^\s*(\w+)\s*=\s*(.+)$/ ) {
178 $self->write( "Setting Environment '$key' to '$val'\n" ) ;
179 $Env{ $key } = $val ;
186 unless ( $line =~ /^\s*(\S+)\s+(.*)$/ ) {
188 $self->write( <<ERR ) ;
189 Console commands must be in the form
190 <Cell Address> command [args ...]
200 my( $cmd_name, $cmd_data ) = split( ' ', $2, 2 ) ;
202 # allow a leading : on the command to make it a regular message instead
204 my $msg_type = ( $cmd_name =~ s/^:// ) ? 'type' : 'cmd' ;
206 my $msg = Stem::Msg->new(
209 $msg_type => $cmd_name,
210 'data' => \$cmd_data,
220 $self->write( "Bad console command message: $msg\n" ) ;
234 $self->write( "EOF (ignored)\n" ) ;
246 my( $self, $msg ) = @_ ;
248 $self = $console_obj unless ref $self ;
250 return unless $self ;
252 my $data = $msg->data() ;
254 $self->write( "\n\n" ) ;
256 if ( $Env{'console_from'} ) {
258 my $from = $msg->from() ;
260 $self->write( "[From: $from]\n" ) ;
263 if ( ref $data eq 'SCALAR' ) {
265 $self->write( ${$data} ) ;
269 $self->write( Dumper( $data ) ) ;
273 $self->write( $data ) ;
281 my( $self, $text ) = @_ ;
283 $self = $console_obj unless ref $self ;
285 $self->{'aio'}->write( $text ) ;
293 return unless $self->{'prompt'} ;
295 $self->write( $self->{'prompt'} ) ;
302 return unless $Env{'console_echo'} ;
304 $self->write( "->$line\n" ) ;
311 $self->write( <<HELP ) ;
315 You can enter various commands to Stem here.
317 If the line is of the form:
321 then the global command args hash %Stem::Vars::Env has that key set to
322 the value. Stem environment variables can be used to control log filters,
323 set cell behavior, set default values for cell attributes and other purposes
325 If the line is of the form:
327 address cmd data_text
329 it is parsed and a command message is created and sent.
331 The address can be in one of these forms:
338 The cmd token is the name of the command for the message. If it is
339 prefixed with a :, then this string becomes the message type instead.
341 The rest of the line is sent as the data of the message.
347 will send a 'status' command message to the 'reg' cell which is the
348 Stem::Route class. A listing of all registered Cells will be returned
353 That will send a 'map' command message to the Cell named 'sw' in the
354 Hub named 'server'. The data will be the string 'a c d'. That is used
355 to change the mapping of target 'a' to c, d in the Switch Cell in the
356 chat and chat2 demos.