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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (show annotations)
Sat Jun 15 08:10:01 2002 UTC (22 years, 3 months ago) by cvsjoko
Branch: MAIN
Changes since 1.2: +10 -1 lines
+ modifications in Term::ReadKey behaviour
+ header

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

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