## crack-xserver-address.pkg
#
# A little utility to analyse user-level
# X server specs, often from a DISPLAY
# unix environment string, something like:
# ":0.0"
# "foo.com:0.0"
# "192.168.0.0:0.0"
#
# This is basically dedicated support for
#
#
src/lib/x-kit/xclient/src/wire/display-old.pkg# Compiled by:
#
src/lib/x-kit/xclient/xclient-internals.sublibstipulate
package ss = substring; # substring is from
src/lib/std/substring.pkg# package mps = microthread_preemptive_scheduler; # microthread_preemptive_scheduler is from
src/lib/src/lib/thread-kit/src/core-thread-kit/microthread-preemptive-scheduler.pkg package f = sfprintf; # sfprintf is from
src/lib/src/sfprintf.pkgherein
package crack_xserver_address
: (weak) Crack_Xserver_Address # Crack_Xserver_Address is from
src/lib/x-kit/xclient/src/wire/crack-xserver-address.api {
Xserver_Address
= UNIX String # ":display.screen"
| INET_HOSTNAME (String, Int)
# "hostname: display.screen"
| INET_ADDRESS (String, Int)
# "ddd.ddd.ddd.ddd: display.screen"
;
exception XSERVER_CONNECT_ERROR String;
x_tcpport = 6000;
x_unixpath = "/tmp/.X11-unix/X";
fun to_string address
=
case address
#
UNIX address' => sprintf "UNIX '%s'" address';
INET_HOSTNAME (string, int) => sprintf "INET_HOSTNAME ('%s',%d)" string int;
INET_ADDRESS (string, int) => sprintf "INET_ADDRESS ('%s',%d)" string int;
esac;
fun find_char c (s, j)
=
find j
where
fun find i
=
if (string::get_byte_as_char (s, i) == c) i;
else find (i+1);
fi;
end;
fun make_unix_address (display_number, screen)
=
{ address => UNIX (x_unixpath + (int::to_string display_number)),
canonical_display_name => f::sprintf' "unix:%d.%d" [f::INT display_number, f::INT screen],
screen
};
fun make_internet_address (host, display_number, screen)
=
if (char::is_digit (string::get_byte_as_char (host, 0)))
#
{ address => INET_ADDRESS (host, x_tcpport+display_number),
canonical_display_name => f::sprintf' "%s:%d.%d" [f::STRING host, f::INT display_number, f::INT screen],
screen
};
else
{ address => INET_HOSTNAME (host, x_tcpport+display_number),
canonical_display_name => f::sprintf' "%s:%d.%d" [f::STRING host, f::INT display_number, f::INT screen],
screen
};
fi;
fun crack_xserver_address ""
=>
make_unix_address (0, 0);
crack_xserver_address string
=>
{
fun convert_int substring
=
case (int::scan number_string::DECIMAL substring::getc substring)
#
THE (n, _) => n;
NULL => raise exception XSERVER_CONNECT_ERROR "expected integer";
esac;
# Split "127.0.0.1:0.0" -> ("127.0.0.1", "0.0")
#
my (hostname, rest)
=
( ss::to_string a,
ss::drop_first 1 b # The "drop_first" is to drop the leading ':' from ":0.0"
)
where # split_off_prefix def in
src/lib/core/init/substring.pkg my (a, b)
=
ss::split_off_prefix
{. #c != ':'; }
(ss::from_string string);
end;
# split "0.0" -> [ "0", "0" ]:
#
display_screen
=
ss::tokens
#
\\ '.' => TRUE;
_ => FALSE;
end
#
rest;
my (display, screen)
=
case display_screen
#
[display] => (convert_int display, 0);
[display, screen] => (convert_int display, convert_int screen);
#
[] => raise exception XSERVER_CONNECT_ERROR "missing display";
_ => raise exception XSERVER_CONNECT_ERROR "badly formed address";
esac;
case hostname
#
"" => make_unix_address (display, screen);
"unix" => make_unix_address (display, screen);
name => make_internet_address (name, display, screen);
esac;
};
end;
}; # package crack_xserver_address
end;