RemoteTerminalCommands.mesa
Copyright Ó 1990, 1992 by Xerox Corporation. All rights reserved.
Last tweaked by Mike Spreitzer on July 16, 1991 6:53 pm PDT
Willie-s, April 22, 1992 11:11 am PDT
DIRECTORY Commander, CommanderOps, Convert, HostAndTerminalOps, IO, NetAddressing, PFS, Process, Rope, TerminalMultiServing;
RemoteTerminalCommands:
CEDAR
PROGRAM
IMPORTS Commander, CommanderOps, Convert, HostAndTerminalOps, IO, NetAddressing, PFS, Process, Rope, TerminalMultiServing
=
BEGIN OPEN HAT:HostAndTerminalOps, NA:NetAddressing, TMS:TerminalMultiServing;
ROPE: TYPE ~ Rope.ROPE;
ParseResult: TYPE ~ RECORD [msg: ROPE ¬ NIL, addr: NA.Address ¬ NA.nullAddress];
instDir: PFS.PATH ~ PFS.GetWDir[];
Prepare:
PROC [cmd: Commander.Handle, pkg:
ROPE]
RETURNS [msg:
ROPE ¬
NIL] ~ {
Installit:
PROC ~ {
IF CommanderOps.DoCommand[Rope.Concat["Install ", pkg], cmd] = $Failure
THEN msg ¬ Rope.Cat["Failed to install ", pkg, " in ", PFS.RopeFromPath[instDir]];
RETURN};
PFS.DoInWDir[instDir, Installit];
RETURN};
ConnectTo:
PROC [cmd: Commander.Handle]
RETURNS [result:
REF
ANY ¬
NIL, msg:
ROPE ¬
NIL]
--Commander.CommandProc-- ~ {
argv: CommanderOps.ArgumentVector ~ CommanderOps.Parse[cmd];
FOR i:
NAT
IN [1 .. argv.argc)
DO
{pr: ParseResult ~ NiceParse[argv[i]];
IF pr.msg#NIL THEN {msg ¬ pr.msg; GOTO Dun};
{whyNot: ROPE ~ TMS.ServeHost[pr.addr, IF cmd.procData.clientData = $Secondary THEN secondary ELSE primary];
IF whyNot#NIL THEN cmd.err.PutRope[whyNot]; cmd.err.PutRope["\n"]};
EXITS Dun => result ¬ $Failure;
}ENDLOOP;
RETURN};
Disconnect:
PROC [cmd: Commander.Handle]
RETURNS [result:
REF
ANY ¬
NIL, msg:
ROPE ¬
NIL]
--Commander.CommandProc-- ~ {
argv: CommanderOps.ArgumentVector ~ CommanderOps.Parse[cmd];
IF argv.argc > 1
THEN {
FOR i:
NAT
IN [1 .. argv.argc)
DO
{pr: ParseResult ~ NiceParse[argv[i]];
IF pr.msg#NIL THEN {msg ¬ pr.msg; GOTO Dun};
TMS.DontServeHost[pr.addr];
EXITS Dun => result ¬ $Failure;
}ENDLOOP;
}
ELSE TMS.ServeNoHosts[];
RETURN};
ListHosts:
PROC [cmd: Commander.Handle]
RETURNS [result:
REF
ANY ¬
NIL, msg:
ROPE ¬
NIL]
--Commander.CommandProc-- ~ {
Print:
PROC [addr:
NA.Address] ~ {
cmd.out.PutF1["%g\n", [rope[NA.FormatAddress[addr, TRUE]]]];
RETURN};
TMS.EnumerateHosts[Print];
RETURN};
PrintVersions:
PROC [cmd: Commander.Handle]
RETURNS [result:
REF
ANY ¬
NIL, msg:
ROPE ¬
NIL]
--Commander.CommandProc-- ~ {
Print:
PROC [protocol:
ROPE, pvr:
HAT.ProtocolVersionRange] ~ {
cmd.out.PutF["%g: [%g .. %g]\n", [rope[protocol]], [integer[pvr.min]], [integer[pvr.max]] ];
RETURN};
HAT.EnumerateProtocolVersionsOfSide[SELECT cmd.procData.clientData FROM $Host => Host, $Terminal => Terminal, ENDCASE => ERROR, Print];
};
VersionsAtHost:
PROC [cmd: Commander.Handle]
RETURNS [result:
REF
ANY ¬
NIL, msg:
ROPE ¬
NIL]
--Commander.CommandProc-- ~ {
argv: CommanderOps.ArgumentVector ~ CommanderOps.Parse[cmd];
IF argv.argc#2 THEN RETURN [$Failure, "Usage: VersionsAt HostName"];
{pr: ParseResult ~ NiceParse[argv[1]];
IF pr.msg#NIL THEN RETURN [$Failure, pr.msg];
msg ¬ TMS.GetHisVersions[pr.addr].ans;
RETURN}};
GetHostsTerminal:
PROC [cmd: Commander.Handle]
RETURNS [result:
REF
ANY ¬
NIL, msg:
ROPE ¬
NIL]
--Commander.CommandProc-- ~ {
argv: CommanderOps.ArgumentVector ~ CommanderOps.Parse[cmd];
IF argv.argc#2 THEN RETURN [$Failure, "Usage: GetHostsTerminal HostName"];
{pr: ParseResult ~ NiceParse[argv[1]];
IF pr.msg#NIL THEN RETURN [$Failure, pr.msg];
msg ¬ TMS.GetHisTerminal[pr.addr].ans;
RETURN}};
PrintMe:
PROC [cmd: Commander.Handle]
RETURNS [result:
REF
ANY ¬
NIL, msg:
ROPE ¬
NIL]
--Commander.CommandProc-- ~ {
ProcessBytes: NAT ~ BYTES[PROCESS];
me: PACKED ARRAY [0..ProcessBytes) OF BYTE ~ LOOPHOLE[Process.GetCurrent[]];
cmd.out.PutRope["Running in process "];
FOR i:
NAT
IN [0..ProcessBytes)
DO
IF i>0 AND (i MOD 4) = 0 THEN cmd.out.PutChar[',];
cmd.out.PutF1["%02x", [cardinal[me[i]]]];
ENDLOOP;
cmd.out.PutRope[".\n"];
RETURN};
NiceParse:
PROC [name:
ROPE]
RETURNS [r: ParseResult ¬ []] ~
TRUSTED {
{
ENABLE {
IO.Error, Convert.Error => {r.msg ¬ "address parse&lookup failed"; CONTINUE};
NA.Error => {r.msg ¬ IO.PutFR1["Address parse/lookup failed: %g", [rope[NA.FormatError[codes, msg]]] ]; CONTINUE};
};
r.addr ¬ NA.ParseAddress[name];
IF r.addr = NA.nullAddress THEN r.msg ¬ "Lookup failed"
ELSE {
IF r.addr.socket.Length[] = 0 THEN r.addr.socket ¬ "58812";
r.addr ¬ NA.Canonicalize[r.addr];
};
};
IF r.msg#NIL THEN r.msg ¬ r.msg.Cat[" for ", name]};
Commander.Register["RemoteTerminalConnectTo", ConnectTo, "<HostName> --- establishes RemoteTerminal connection", $Primary];
Commander.Register["RTConnectTo", ConnectTo, "<HostName> --- establishes RemoteTerminal connection", $Primary];
Commander.Register["RTCT", ConnectTo, "<HostName> --- establishes RemoteTerminal connection", $Primary];
Commander.Register["RemoteTerminalObserve", ConnectTo, "<HostName> --- observe output from Host", $Secondary];
Commander.Register["RTObserve", ConnectTo, "<HostName> --- observe output from Host", $Secondary];
Commander.Register["RemoteTerminalDisconnect", Disconnect, "--- tears down a RemoteTerminal connection from the Terminal side"];
Commander.Register["RTDisconnect", Disconnect, "--- tears down a RemoteTerminal connection from the Terminal side"];
Commander.Register["RTD", Disconnect, "--- tears down a RemoteTerminal connection from the Terminal side"];
Commander.Register["ListHosts", ListHosts, "--- lists hosts that we're being a terminal for"];
Commander.Register["HostVersions", PrintVersions, "--- prints installed protocol versions for Host side of RemoteTerminal system", $Host];
Commander.Register["TerminalVersions", PrintVersions, "--- prints installed protocol versions for Terminal side of RemoteTerminal system", $Terminal];
Commander.Register["VersionsAtHost", VersionsAtHost, "<HostName> --- queries given host about protocol versions"];
Commander.Register["GetHostsTerminal", GetHostsTerminal, "<HostName> --- queries given host about its terminal location"];
Commander.Register["PrintProcess", PrintMe, "prints the current PROCESS (in hex)"];
END.