/[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.1 - (show annotations)
Fri Jun 14 21:22:09 2002 UTC (22 years, 3 months ago) by cvsjoko
Branch: MAIN
Branch point for: nfo
Initial revision

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

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