WhoIsImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Hal Murray May 16, 1985 3:20:40 am PDT
John Larson, June 12, 1987 1:14:29 pm PDT
Sharon Johnson, June 12, 1987 1:37:15 pm PDT
DIRECTORY
Commander USING [CommandProc, Register],
CommandTool USING [ArgumentVector, Failed, Parse],
IO USING [Close, EndOf, EndOfStream, Error, Flush, GetChar, PutF, PutFR, PutChar, PutRope, rope, RopeFromROS, ROS, STREAM],
Rope USING [ROPE],
IPDefs USING [Address],
IPName USING [NameToAddress],
IPRouter USING [BestAddress],
Process USING [SecondsToTicks],
TCP USING [AbortTCPStream, CreateTCPStream, Error, neverTimeout, Timeout, WaitForListenerOpen],
WhoIs;
WhoIsImpl: CEDAR MONITOR
IMPORTS Commander, CommandTool, IO, IPName, IPRouter, Process, TCP
EXPORTS WhoIs
=
BEGIN
whoIsSocket: INT = 43;
serverName: Rope.ROPE = "SRI-NIC.ARPA";
nRetries: INT ← 5;
seconds: CARDINAL ← 2;
Query: PUBLIC ENTRY PROC [pattern: Rope.ROPE] RETURNS[rope: Rope.ROPE] = {
snooz: CONDITION ← [timeout: Process.SecondsToTicks[seconds]];
FOR i: INT IN [0..nRetries) DO
rope ← QueryOnce[pattern];
IF rope # NIL THEN RETURN[rope];
WAIT snooz;
ENDLOOP;
RETURN[IO.PutFR["Problems connecting to %g. Try again later.", IO.rope[serverName]]];
};
QueryOnce: PROC [pattern: Rope.ROPE] RETURNS[rope: Rope.ROPENIL] = {
server: IO.STREAM;
out: IO.STREAMIO.ROS[];
where: LIST OF IPDefs.Address;
where ← IPName.NameToAddress[serverName];
IF where = NIL THEN {
RETURN[IO.PutFR["Can't lookup IP Address for %G.", IO.rope[serverName]]];
};
BEGIN
ENABLE {
TCP.Timeout => {
out.PutRope["[TCP.Timeout.]\n"];
GO TO GiveUp; };
TCP.Error => {
out.PutRope["[TCP.Error.]\n"];
GO TO GiveUp; };
IO.Error => {
out.PutRope["[IO.Error.]\n"];
GOTO GiveUp; };
};
server ← TCP.CreateTCPStream[[
matchLocalPort: FALSE,
localPort: 0,
matchForeignAddr: TRUE,
foreignAddress: IPRouter.BestAddress[where],
matchForeignPort: TRUE,
foreignPort: whoIsSocket,
active: TRUE,
timeout: 120000]];
TCP.WaitForListenerOpen[server, TCP.neverTimeout];
server.PutRope[pattern];
server.PutRope["\n\l"];
server.Flush[];
WHILE NOT server.EndOf[] DO
c: CHAR ← server.GetChar[ ! IO.EndOfStream => EXIT];
IF c # '\l THEN out.PutChar[c]
ENDLOOP;
rope ← IO.RopeFromROS[out];
server.Close[];
out.Close[];
EXITS GiveUp => {IF server # NIL THEN TCP.AbortTCPStream[server];
RETURN[NIL];};
END;
};
DoItLocal: Commander.CommandProc = {
out: IO.STREAM ← cmd.out;
argv: CommandTool.ArgumentVector = CommandTool.Parse[cmd !
CommandTool.Failed => {out.PutRope[errorMsg]; GOTO CantParse}];
server: IO.STREAM;
where: LIST OF IPDefs.Address;
name: Rope.ROPE;
IF argv.argc > 1 THEN name ← argv[1] ELSE name ← "Xerox";
where ← IPName.NameToAddress[serverName];
IF where = NIL THEN {
out.PutF["Can't lookup IP Address for %G.\n", IO.rope[serverName]];
RETURN; };
BEGIN
ENABLE {
TCP.Timeout => {
out.PutRope["[TCP.Timeout.]\n"];
GO TO GiveUp; };
TCP.Error => {
out.PutRope["[TCP.Error.]\n"];
GO TO GiveUp; };
IO.Error => {
out.PutRope["[IO.Error.]\n"];
GOTO GiveUp; };
};
server ← TCP.CreateTCPStream[[
matchLocalPort: FALSE,
localPort: 0,
matchForeignAddr: TRUE,
foreignAddress: where.first,
matchForeignPort: TRUE,
foreignPort: whoIsSocket,
active: TRUE,
timeout: 120000]];
TCP.WaitForListenerOpen[server, TCP.neverTimeout];
server.PutRope[name];
server.PutRope["\n\l"];
server.Flush[];
WHILE NOT server.EndOf[] DO
c: CHAR ← server.GetChar[ ! IO.EndOfStream => EXIT];
IF c # '\l THEN out.PutChar[c];
ENDLOOP;
server.Close[];
EXITS GiveUp => IF server # NIL THEN TCP.AbortTCPStream[server];
END;
EXITS CantParse => NULL; };
Commander.Register[key: "WhoIs", proc: DoItLocal, doc: "Poke WhoIs server at NIC"];
END.