blob: 0ab1ad7fd9f35a91822a3afb69a259812ef80feb [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;
apw3812c032006-12-07 21:01:14 +000029use Conmux;
30
31# Basic terminal handling.
32sub termRaw {
33 $termSettings = `stty -g`;
34 system "stty raw -echo opost onlret";
35}
36sub termRestore {
37 system "stty $termSettings";
38}
39
40my $bot;
41my $list;
42my $status;
43GetOptions(
44 'b|bot=s' => \$bot,
45 'l|list' => \$list,
46 's|status' => \$status,
47);
48sub usage {
49 warn "Usage: $P <service>\n";
50 warn " $P <registry>/<service>\n";
51 warn " $P <host>:<port>\n";
52 warn " $P --status <service>\n";
53 die " $P --list [<registry>]\n";
54}
55
56my $id;
57if ($bot) {
58 $id = 'bot:' . $bot;
59} else {
60 $id = 'user:' . $ENV{'LOGNAME'};
61}
62
63#
64# MODE: registry list.
65#
66if ($list) {
67 if ($#ARGV == -1) {
68 print Conmux::Registry::list('-');
69
70 } elsif ($#ARGV == 0) {
71 print Conmux::Registry::list($ARGV[0]);
72
73 } else {
74 usage();
75 }
76 exit 0
77}
78
79#
80# COMMAND: payload status command
81#
82if ($status) {
83 usage() if ($#ARGV != 0);
84
85 my $sock;
86 eval {
87 $sock = Conmux::connect($ARGV[0]);
88 };
89 if ($@) {
90 print "unavailable\n";
91 exit 0
92 }
93 my %r = Conmux::sendCmd($sock, 'CONNECT', { 'id' => $id,
94 'to' => 'console', 'hide' => 1 });
95 if ($r{'status'} ne 'OK') {
96 print "unavailable\n";
97
98 } elsif ($r{'state'}) {
99 print "$r{'state'}\n";
100
101 } else {
102 print "unknown\n";
103 }
104 exit 0;
105}
106
107
108#
109# COMMAND: general payload connect.
110#
111if ($#ARGV != 0) {
112 usage();
113}
114
apw3812c032006-12-07 21:01:14 +0000115# Connect to the host/port specified on the command line,
116# or localhost:23
117my $sock = Conmux::connect($ARGV[0]);
118
119my %r = Conmux::sendCmd($sock, 'CONNECT', { 'id' => $id, 'to' => 'console' });
120die "$P: $ARGV[0]: connect failed - $r{'status'}\n" if ($r{'status'} ne 'OK');
121
122print "Connected to $r{'title'} (~\$quit to exit)\n";
mbligh9b94f3e2008-02-19 15:51:28 +0000123#display message of the day passed by the server e.g. who is already connected
124print "$r{'motd'}";
apw3812c032006-12-07 21:01:14 +0000125
apwac655042007-02-24 11:09:16 +0000126my $rin = $win = $ein = '';
127vec($rin, fileno(STDIN), 1) = 1;
128vec($rin, fileno($sock), 1) = 1;
129my $ein = $rin | $win;
130
apw3812c032006-12-07 21:01:14 +0000131# We want to buffer output to the terminal. This prevents the program
132# from blocking if the user hits CTRL-S for example.
apwac655042007-02-24 11:09:16 +0000133# XXX ^^^
apw3812c032006-12-07 21:01:14 +0000134
135termRaw();
136
apwac655042007-02-24 11:09:16 +0000137# Loop waiting for input from the user, or from the server.
138while (1) {
139 $nfound = select($rout=$rin, $wout=$win, $eout=$ein, undef);
140 if ($nfound < 0) {
141 if ($! == EINTR || $! == EAGAIN) {
142 next;
143 }
144 die "$P: select failed - $!\n";
145 }
apw3812c032006-12-07 21:01:14 +0000146
apwac655042007-02-24 11:09:16 +0000147 if (vec($rout, fileno(STDIN), 1)) {
148 $len = sysread(STDIN, $data, 4096);
149 if ($len <= 0) {
150 if ($len < 0) {
151 if ($! == EINTR || $! == EAGAIN) {
152 next;
153 }
154 die "$P: STDIN: read failed - $!\n";
155 }
156 print STDERR "Connection Closed (client)\n";
157 last;
158 }
159 print $sock $data;
160 }
161 if (vec($rout, fileno($sock), 1)) {
162 $len = sysread($sock, $data, 4096);
163 if ($len <= 0) {
164 if ($len < 0) {
165 if ($! == EINTR || $! == EAGAIN) {
166 next;
167 }
168 die "$P: server: read failed - $!\n";
169 }
170 print STDERR "Connection Closed (server)\n";
171 last;
172 }
173 print $data;
apw3812c032006-12-07 21:01:14 +0000174 }
175}
176
apwac655042007-02-24 11:09:16 +0000177termRestore();