2 # Conmux.pm -- core console multiplexor package
4 # Implements the core multiplexor functionality such as resolution of
5 # names and connecting to the conmux server.
7 # (C) Copyright IBM Corp. 2004, 2005, 2006
8 # Author: Andy Whitcroft <andyw@uk.ibm.com>
10 # The Console Multiplexor is released under the GNU Public License V2
20 my $abs_path = abs_path
($0);
21 my $dir_path = dirname
($abs_path);
23 my $cf = '/usr/local/conmux/etc/config';
24 if (-e
"$dir_path/etc/config") {
25 $cf = "$dir_path/etc/config";
26 } elsif (-e
"$dir_path/../etc/config") {
27 $cf = "$dir_path/../etc/config";
31 open(CFG
, "<$cf") || die "Conmux: $cf: open failed - $!\n";
34 next if (/^#/ || /^\s*$/ || !/=/);
36 my ($name, $value) = split(/=/, $_, 2);
40 # Substitute variables.
41 while ($value =~ /\$([A-Za-z0-9_]+)/) {
42 my $v = $Config->{$1};
45 $Config->{$name} = $value;
55 ##print "0<$_[0]> ref<" . ref($_[0]) . ">\n";
57 # Handle being passed references to hashes too ...
59 $a = $_[0] if (ref($_[0]) eq "HASH");
61 for $n (sort keys %{$a}) {
62 $s .= uri_escape
($n) . '=' . uri_escape
($a->{$n}) .
73 # Decode the standard argument stream.
74 for $nv (split(' ', $s)) {
75 ($n, $v) = split('=', $nv, 2);
76 $a{uri_unescape
($n)} = uri_unescape
($v);
83 my ($fh, $c, $a) = @_;
86 # Send the encoded command ...
87 print $fh $c . " " . encodeArgs
($a) . "\n";
97 my ($fh, $c, $a) = @_;
98 my %a = { 'result' => 'more' };
100 # Send the encoded command ...
101 print $fh $c . " " . encodeArgs
($a) . "\n";
120 my $reg = $Config->{'registry'};
122 $reg = "localhost" if (!$reg);
126 # Connect to the host/port specified on the command line,
134 # Already in the right form.
137 } elsif ($to =~ m@
(.*)/(.*)@
) {
138 my ($host, $service) = ($1, $2);
140 $to = Conmux
::Registry
::lookup
($host, $service);
144 $to = Conmux
::Registry
::lookup
('-', $to);
147 $sock = new IO
::Socket
::INET
(Proto
=> 'tcp', PeerAddr
=> $to)
148 or die "Conmux::connect $to: connect failed - $@\n";
150 # Turn on keep alives by default.
151 $sock->sockopt(SO_KEEPALIVE
, 1);
156 package Conmux
::Registry
;
158 my ($host, $service) = @_;
160 $host = Conmux
::configRegistry
() if ($host eq '-');
162 # Connect to the registry service and lookup the requested service.
163 my $reg = new IO
::Socket
::INET
(Proto
=> 'tcp',
164 PeerAddr
=> "$host", PeerPort
=> 63000)
165 or die "Conmux::connect: registry not available - $@\n";
167 my %r = Conmux
::sendCmd
($reg, 'LOOKUP', { 'service' => $service });
168 die "Conmux::Registry::lookup: $service: error - $r{'status'}\n"
169 if ($r{status
} ne "OK");
177 my ($host, $service, $location) = @_;
179 $host = Conmux
::configRegistry
() if ($host eq '-');
181 # Connect to the registry service and lookup the requested service.
182 my $reg = new IO
::Socket
::INET
(Proto
=> 'tcp',
183 PeerAddr
=> "$host", PeerPort
=> 63000)
184 or die "Conmux::connect: registry not available - $@\n";
186 my %r = Conmux
::sendCmd
($reg, 'ADD', { 'service' => $service,
187 'location' => $location });
188 die "Conmux::Registry::add: $service: error - $r{'status'}\n"
189 if ($r{status
} ne "OK");
197 my ($host, $service, $location) = @_;
200 $host = Conmux
::configRegistry
() if ($host eq '-');
202 # Connect to the registry service and ask for a list.
203 my $reg = new IO
::Socket
::INET
(Proto
=> 'tcp',
204 PeerAddr
=> "$host", PeerPort
=> 63000)
205 or die "Conmux::connect: registry not available - $@\n";
207 %r = Conmux
::sendCmd
($reg, 'LIST', { });
208 ## while ($r{'status'} eq 'more') {
209 ## %r = receiveResult($reg);
210 ## push(@results, $r{'result'});
212 die "Conmux::Registry::list: error - $r{'status'}\n"
213 if ($r{'status'} ne "OK");