blob: f031e5b2c594ce1eb88ad31355a11fc9dfdcc6b2 [file] [log] [blame]
apw3812c032006-12-07 21:01:14 +00001#!/usr/bin/perl
2#
3# console <host>/<machine> -- interactive client interface
4#
5# The main interactive client interace to conmux. Allows direct
6# interaction with the payload, as well as allowing break out
7# to the conmux menu to envoke defined commands; for example
8# hardreset.
9#
10# (C) Copyright IBM Corp. 2004, 2005, 2006
11# Author: Andy Whitcroft <andyw@uk.ibm.com>
12#
13# The Console Multiplexor is released under the GNU Public License V2
14#
15$| = 1;
16
17our $P = 'console';
18
mblighf5180482008-02-20 16:09:08 +000019use FindBin;
apwac655042007-02-24 11:09:16 +000020use POSIX qw(errno_h BUFSIZ);
apw3812c032006-12-07 21:01:14 +000021use IO::Socket;
apw3812c032006-12-07 21:01:14 +000022use Getopt::Long qw(:config no_auto_abbrev);
23
mblighf5180482008-02-20 16:09:08 +000024my $CONMUX = $FindBin::Bin;
apw3812c032006-12-07 21:01:14 +000025my $CONMUX = $ENV{'CONMUX_ROOT'} if ($ENV{'CONMUX_ROOT'});
26
27# Find our internal libraries.
mblighf5180482008-02-20 16:09:08 +000028use lib $FindBin::Bin;
mbligh44f929b2010-02-25 18:42:18 +000029use lib "$FindBin::Bin/../lib/";
30use lib "$FindBin::Bin/lib/";
apw3812c032006-12-07 21:01:14 +000031use Conmux;
32
33# Basic terminal handling.
34sub termRaw {
35 $termSettings = `stty -g`;
36 system "stty raw -echo opost onlret";
37}
38sub termRestore {
39 system "stty $termSettings";
40}
41
42my $bot;
43my $list;
44my $status;
45GetOptions(
46 'b|bot=s' => \$bot,
47 'l|list' => \$list,
48 's|status' => \$status,
49);
50sub usage {
51 warn "Usage: $P <service>\n";
52 warn " $P <registry>/<service>\n";
53 warn " $P <host>:<port>\n";
54 warn " $P --status <service>\n";
55 die " $P --list [<registry>]\n";
56}
57
58my $id;
59if ($bot) {
60 $id = 'bot:' . $bot;
61} else {
62 $id = 'user:' . $ENV{'LOGNAME'};
63}
64
65#
66# MODE: registry list.
67#
68if ($list) {
69 if ($#ARGV == -1) {
70 print Conmux::Registry::list('-');
71
72 } elsif ($#ARGV == 0) {
73 print Conmux::Registry::list($ARGV[0]);
74
75 } else {
76 usage();
77 }
78 exit 0
79}
80
81#
82# COMMAND: payload status command
83#
84if ($status) {
85 usage() if ($#ARGV != 0);
86
87 my $sock;
88 eval {
89 $sock = Conmux::connect($ARGV[0]);
90 };
91 if ($@) {
92 print "unavailable\n";
93 exit 0
94 }
95 my %r = Conmux::sendCmd($sock, 'CONNECT', { 'id' => $id,
96 'to' => 'console', 'hide' => 1 });
97 if ($r{'status'} ne 'OK') {
98 print "unavailable\n";
99
100 } elsif ($r{'state'}) {
101 print "$r{'state'}\n";
102
103 } else {
104 print "unknown\n";
105 }
106 exit 0;
107}
108
109
110#
111# COMMAND: general payload connect.
112#
113if ($#ARGV != 0) {
114 usage();
115}
116
apw3812c032006-12-07 21:01:14 +0000117# Connect to the host/port specified on the command line,
118# or localhost:23
119my $sock = Conmux::connect($ARGV[0]);
120
121my %r = Conmux::sendCmd($sock, 'CONNECT', { 'id' => $id, 'to' => 'console' });
122die "$P: $ARGV[0]: connect failed - $r{'status'}\n" if ($r{'status'} ne 'OK');
123
124print "Connected to $r{'title'} (~\$quit to exit)\n";
mbligh9b94f3e2008-02-19 15:51:28 +0000125#display message of the day passed by the server e.g. who is already connected
126print "$r{'motd'}";
apw3812c032006-12-07 21:01:14 +0000127
apwac655042007-02-24 11:09:16 +0000128my $rin = $win = $ein = '';
129vec($rin, fileno(STDIN), 1) = 1;
130vec($rin, fileno($sock), 1) = 1;
131my $ein = $rin | $win;
132
apw3812c032006-12-07 21:01:14 +0000133# We want to buffer output to the terminal. This prevents the program
134# from blocking if the user hits CTRL-S for example.
apwac655042007-02-24 11:09:16 +0000135# XXX ^^^
apw3812c032006-12-07 21:01:14 +0000136
137termRaw();
138
apwac655042007-02-24 11:09:16 +0000139# Loop waiting for input from the user, or from the server.
140while (1) {
141 $nfound = select($rout=$rin, $wout=$win, $eout=$ein, undef);
142 if ($nfound < 0) {
143 if ($! == EINTR || $! == EAGAIN) {
144 next;
145 }
146 die "$P: select failed - $!\n";
147 }
apw3812c032006-12-07 21:01:14 +0000148
apwac655042007-02-24 11:09:16 +0000149 if (vec($rout, fileno(STDIN), 1)) {
150 $len = sysread(STDIN, $data, 4096);
151 if ($len <= 0) {
152 if ($len < 0) {
153 if ($! == EINTR || $! == EAGAIN) {
154 next;
155 }
156 die "$P: STDIN: read failed - $!\n";
157 }
158 print STDERR "Connection Closed (client)\n";
159 last;
160 }
161 print $sock $data;
162 }
163 if (vec($rout, fileno($sock), 1)) {
164 $len = sysread($sock, $data, 4096);
165 if ($len <= 0) {
166 if ($len < 0) {
167 if ($! == EINTR || $! == EAGAIN) {
168 next;
169 }
170 die "$P: server: read failed - $!\n";
171 }
172 print STDERR "Connection Closed (server)\n";
173 last;
174 }
175 print $data;
apw3812c032006-12-07 21:01:14 +0000176 }
177}
178
apwac655042007-02-24 11:09:16 +0000179termRestore();