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.