/[cvs]/joko/Scripts/psh/lib/MJAM/Command/Shell.pm
ViewVC logotype

Annotation of /joko/Scripts/psh/lib/MJAM/Command/Shell.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide annotations)
Sat Jun 15 07:45:19 2002 UTC (22 years, 3 months ago) by cvsjoko
Branch: MAIN
Changes since 1.1: +6 -2 lines
+ change Terminal-ReadMode before exit

1 cvsjoko 1.1 package MJAM::Command::Shell;
2    
3     use strict;
4     use warnings;
5    
6     use Env qw ( HOME );
7     use IO::File;
8     use POE;
9     use MJAM::main;
10 cvsjoko 1.2 use Term::ReadKey;
11 cvsjoko 1.1
12     my @sh_commands_local = qw ( connect sc exit quit help ? );
13     my @sh_commands_remote = qw ( tell bye );
14    
15     my %cfg;
16     $cfg{branding}{console_name} = "jash";
17    
18     my %console;
19     $console{commands} = \@sh_commands_local;
20     $console{context} = "";
21    
22     my %conn;
23     $conn{type} = "";
24     $conn{file_name} = "";
25     $conn{target} = "";
26     $conn{connected} = 0;
27     $conn{user} = 'anonymous';
28     $conn{remote_host} = "";
29     $conn{remote_port} = "";
30     $conn{commands} = \@sh_commands_remote;
31    
32     my $poe_alias;
33    
34     my %helpmsg;
35    
36     $helpmsg{connect} = <<EOH;
37     COMMAND:
38     connect
39    
40     SYNOPSIS:
41     connect
42     connect cmdfile [cmdfile]
43     connect rpc [username\@][hostname]
44    
45     DESCRIPTION:
46     Connect to a local or remote command-engine
47     EOH
48    
49     $helpmsg{sc} = <<EOH;
50     COMMAND:
51     sc (switch context)
52    
53     SYNOPSIS:
54     sc <context>
55    
56     DESCRIPTION:
57     Switches console-context to "<context>".
58     Every remote-command issued from now on will be prefixed by the console-context.
59     Delete a context by just typing "sc".
60     EOH
61    
62     $helpmsg{exit} = <<EOH;
63     COMMAND:
64     exit|quit
65    
66     SYNOPSIS:
67     exit
68     quit
69    
70     DESCRIPTION:
71     Quits from shell.
72     EOH
73     $helpmsg{quit} = $helpmsg{exit};
74    
75     $helpmsg{tell} = <<EOH;
76     COMMAND:
77     tell
78    
79     SYNOPSIS:
80     tell <target>|<alias> <command>
81    
82     DESCRIPTION:
83     Tells an (aliased) target what to do
84     EOH
85    
86    
87     sub getUsage {
88     my $bool_connected = "no";
89     $conn{connected} && ($bool_connected = "yes");
90     my $helpmsg = <<EOH;
91     ----------------------------------------------------------
92     commands:
93     - local-commands: @{$console{commands}}
94     - remote-commands: @{$conn{commands}}
95     ----------------------------------------------------------
96     status:
97     - console-context: $console{context}
98     - connected: $bool_connected
99     - connection-target: $conn{target}
100     ----------------------------------------------------------
101     EOH
102     }
103    
104     sub getHelpMsg {
105     my $helpkey = shift;
106     my $msg = "";
107     if ($helpmsg{$helpkey}) {
108     $msg .= <<MSG;
109     ---------------------------------------------
110     MSG
111     $msg .= $helpmsg{$helpkey};
112     }
113     return $msg;
114     }
115    
116     sub lCmd {
117    
118     my $cmd = shift;
119     #print "lCmd: $cmd", "\n";
120    
121     #if ($cmd eq 'quit' || $cmd eq 'exit') { exit; }
122 cvsjoko 1.2 if ($cmd eq 'quit' || $cmd eq 'exit') {
123     ReadMode 1;
124     exit;
125     }
126 cvsjoko 1.1
127     if ($cmd =~ m/(help|\?)\s*(.*)/) {
128     my $helpkey = $2;
129     if ($helpkey) {
130     return getHelpMsg($helpkey);
131     } else {
132     return getUsage();
133     }
134     }
135    
136     if ($cmd =~ m/connect\s*(.*)/) {
137     my $param = $1;
138     my $c_where = "";
139     my $c_args = "";
140     if ($param =~ m/(cmdfile|rpc)\s*(.*)/) {
141     $c_where = $1;
142     $c_args = $2;
143     } else {
144     $c_where = "cmdfile";
145     }
146     rConnect($c_where, $c_args);
147     return;
148     }
149    
150     if ($cmd =~ m/sc\s*(.*)/) {
151     my $context = $1;
152     $console{context} = '';
153     $console{context} = $1;
154     return;
155     }
156    
157     }
158    
159     sub rConnect {
160     my $where = shift;
161     my $args = shift;
162    
163     # local
164     if ($where eq 'cmdfile') {
165     if (!$args) {
166     $args = $HOME . '/.mjamcmd';
167     }
168     my $file = $args;
169     if (-e $file) {
170     print "trying to connect to $where ($args)", "\n";
171     $conn{type} = "cmdfd";
172     $conn{file_name} = $args;
173     $conn{connected} = 1;
174     $conn{target} = $conn{file_name};
175     }
176     }
177    
178     # rpc
179     if ($where eq 'rpc') {
180     if (!$args) {
181     $args = 'anonymous@localhost:7777';
182     }
183     if ($args =~ m/^(.+)\@(.+):+(.+)$/) {
184     $conn{user} = $1;
185     $conn{remote_host} = $2;
186     $conn{remote_port} = $3;
187     } elsif ($args =~ m/^(.*):*(.*)$/) {
188     $conn{remote_host} = $1;
189     $conn{remote_port} = $2;
190     }
191    
192     $conn{user} || ($conn{user} = "anonymous");
193     $conn{remote_host} || ($conn{remote_host} = "localhost");
194     $conn{remote_port} || ($conn{remote_port} = "7777");
195     my $url = 'http://' . $conn{user} . '@' . $conn{remote_host} . ':' . $conn{remote_port} . '/';
196    
197     if (1) {
198     print "trying to connect to $where ($url)", "\n";
199     $conn{type} = "rpc";
200     $conn{connected} = 1;
201     $conn{target} = $url;
202     $poe_kernel->post('cmdcore', 'docmd', 'tell rpcxmla start');
203     $poe_kernel->run_one_timeslice();
204    
205     my $meta = {
206     Connection => \%conn,
207     RequestSession => '',
208     RequestState => '',
209     ResponseSession => $poe_alias,
210     ResponseState => 'issueResponse',
211     };
212     $poe_kernel->post( rpcxmla => setMeta => $meta );
213     $poe_kernel->post( rpcxmla => 'startAgent' );
214    
215     #$conn{file_name} = $args;
216     #$conn{connected} = 1;
217     #$conn{target} = $conn{file_name};
218     }
219     }
220    
221     }
222    
223     sub rCmd {
224     my $cmd = shift;
225     if (!$conn{connected}) {
226     print "\"$cmd\" is a remote command, please connect first!", "\n";
227     return;
228     }
229     #my $fh = $conn{file_handle};
230     my $handle = IO::File->new($conn{file_name}, "a+");
231     $handle->print($cmd, "\n");
232     $handle->close();
233     return "done???";
234     }
235    
236    
237     sub issueCmd {
238    
239     # ----------------------------------------------------
240     # get poe vars and resolve sender
241     my ( $kernel, $session, $heap, $sender, $cmd, $target ) = @_[ KERNEL, SESSION, HEAP, SENDER, ARG0, ARG1 ];
242     my $recieved = $cmd;
243     if ($sender == $kernel) {
244     my $caller = "Kernel" . " (Kernel " . $sender->ID() . ")";
245     $recieved .= " (from \"" . $caller . "\")";
246     } else {
247     my $sender_heap = $sender->get_heap();
248     my $caller = $sender_heap->{state}{Caption} . " (Session " . $sender->ID() . ")";
249     $recieved .= " (from \"" . $caller . "\")";
250     }
251     DEBUG() && print __PACKAGE__, ": #>", $recieved, "\n";
252     # ----------------------------------------------------
253    
254     $heap->{target} = $target;
255    
256     my $cmd_console = $cmd;
257    
258     my $cmd_issue;
259    
260     # if the console-command is empty, just return
261     if (!$cmd_console) { return; }
262    
263     # split console-command by whitespace
264     my @cmd = split(' ', $cmd_console);
265    
266     # is it a local command ...
267     $cmd_issue = $cmd_console;
268     if (in_array($cmd[0], $console{commands})) {
269     my $result = lCmd($cmd_console);
270     $kernel->post($session => issueResponse => $result);
271     return 1;
272     }
273    
274     # prefix console-command with console-context ;), to build complete remote-command
275     my $context = '';
276     $console{context} && ($context = $console{context} . " ");
277     my $cmd_remote = $context . $cmd_console;
278    
279     # split remote-command by whitespace
280     my @cmdr = split(' ', $cmd_remote);
281    
282     # ... or is it a remote one?
283     $cmd_issue = $cmd_remote;
284     if (in_array($cmdr[0], $conn{commands})) {
285     if ($conn{type} eq 'rpc') {
286     # dispatch to rpc
287     my $data = {
288     method => 'spoo',
289     args => $cmd_remote,
290     };
291     $kernel->post( rpcxmla => request => $data );
292     } else {
293     # dispatch to cmdfd
294     my $result = rCmd($cmd_remote);
295     $kernel->post($session => issueResponse => $result);
296     }
297     return 1;
298     }
299    
300     # unknown command, print this to shell
301     my $result = "unknown command (\"$cmd_issue\"), type ? for help.";
302     #$kernel->post($session => issuePromptChange => 1);
303     $kernel->post($session => issueResponse => $result);
304     return 1;
305    
306     }
307    
308    
309     sub getPromptPart {
310     my @parts;
311     if ($conn{connected}) {
312     my $target_prompt;
313     if ($conn{type} eq "cmdfd") {
314     $target_prompt = "cmdfd";
315     } else {
316     $target_prompt = $conn{remote_host};
317     }
318     push(@parts, "(" . $conn{user} . "\@" . $target_prompt . ")");
319     }
320     if ($console{context}) {
321     push(@parts, "[ $console{context} ]");
322     }
323    
324     my $tmp_login = '';
325     $tmp_login = join(' ', @parts);
326     if ($tmp_login) {
327     return $tmp_login;
328     }
329     }
330    
331    
332     sub issueResponse {
333     my ( $kernel, $session, $heap, $sender, $response ) = @_[ KERNEL, SESSION, HEAP, SENDER, ARG0 ];
334     #if ($sender != $kernel) {
335     #my $sender_heap = $sender->get_heap();
336     # print "rs: ", $heap->{meta}{ResponseSession}, "\n";
337     # print "rs: ", $heap->{meta}{ResponseState}, "\n";
338     # print "response: $response", "\n";
339     $kernel->post($heap->{target}{ResponseSession} => $heap->{target}{PromptChangeState} => getPromptPart());
340     $kernel->post($heap->{target}{ResponseSession} => $heap->{target}{ResponseState} => $response);
341     #if ($response) {
342     #print $response, "\n";
343     #}
344     #return 1;
345     #}
346     }
347    
348     sub issuePromptChange {
349     my ( $kernel, $session, $heap ) = @_[ KERNEL, SESSION, HEAP ];
350     my $prompt = getPrompt();
351     $kernel->post($heap->{target}{ResponseSession} => $heap->{target}{PromptChangeState} => $prompt);
352     }
353    
354    
355     sub _start {
356     my ( $kernel, $session, $heap, $arg0 ) = @_[ KERNEL, SESSION, HEAP, ARG0 ];
357     $kernel->alias_set($poe_alias);
358     DEBUG() && print __PACKAGE__, " started", "\n";
359     }
360    
361    
362     sub start {
363    
364     $poe_alias = shift;
365    
366     my @handlers = qw(
367     _start
368     issueCmd
369     issueResponse
370     issuePromptChange
371     );
372    
373     my $pkg = __PACKAGE__;
374    
375     # the main session for the command-engine
376     POE::Session->create(
377     package_states => [ $pkg => \@handlers ],
378     args => [ ],
379     );
380    
381     }
382    
383    
384 cvsjoko 1.2 1;

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed