BuildNameTable.mesa
Copyright (C) 1983, 1984 by Xerox Corporation. All rights reserved. The following program was created in 1983 but has not been published within the meaning of the copyright law, is furnished under license, and may not be used, copied and/or disclosed except in accordance with the terms of said license.
Last Edited by: Nichols, August 31, 1983 4:07 pm
Last Edited by: Taft, January 21, 1984 5:26:00 pm PST
Last Edited by: HGM, May 22, 1984 5:09:58 pm PDT
Doug Terry, September 23, 1987 3:01:50 pm PDT
Hal Murray June 27, 1985 3:26:44 am PDT
John Larson, November 28, 1987 5:29:46 pm PST
DIRECTORY
Arpa USING [Address],
ArpaName USING [NameToAddressList],
ArpaTCP USING [AbortTCPStream, CreateTCPStream, Error, neverTimeout, Timeout, WaitForListenerOpen],
BasicTime USING [Now],
Commander USING [CommandProc, Register],
CommandTool USING [ArgumentVector, Failed, Parse],
Convert USING [RopeFromTime],
FS USING [StreamOpen],
IO USING [Close, EndOf, EndOfStream, Error, Flush, GetChar, PutF, PutChar, PutRope, rope, STREAM],
Rope USING [ROPE];
BuildNameTable:
CEDAR
PROGRAM
IMPORTS ArpaName, ArpaTCP, BasicTime, Commander, CommandTool, Convert, FS, IO =
BEGIN
nameServerSocket: INT = 145B;
defaultNameServer: Rope.ROPE = "SRI-NIC.ARPA";
defaultFileName: Rope.ROPE = "Hosts.txt";
Version: Commander.CommandProc = {
out: IO.STREAM ← cmd.out;
server: IO.STREAM;
nameServer: Rope.ROPE ← defaultNameServer;
where: LIST OF Arpa.Address;
out.PutF["Poking ARPA Name Server for current version.\n"];
where ← ArpaName.NameToAddressList[nameServer].addrs;
IF where =
NIL
THEN {
out.PutF["Can't lookup IP Address for %G.\n", IO.rope[nameServer]];
RETURN; };
BEGIN
ENABLE {
ArpaTCP.Timeout => {
out.PutRope["[TCP.Timeout.]\n"];
GO TO GiveUp; };
ArpaTCP.Error => {
out.PutRope["[TCP.Error.]\n"];
GO TO GiveUp; };
IO.Error => {
out.PutRope["[IO.Error.]\n"];
GOTO GiveUp; };
};
server ← ArpaTCP.CreateTCPStream[[
matchLocalPort: FALSE,
localPort: 0,
matchForeignAddr: TRUE,
foreignAddress: where.first,
matchForeignPort: TRUE,
foreignPort: nameServerSocket,
active: TRUE,
timeout: 120000]];
ArpaTCP.WaitForListenerOpen[server, ArpaTCP.neverTimeout];
server.PutRope["VERSION\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 ArpaTCP.AbortTCPStream[server];
END;
};
HostName: Commander.CommandProc = {
out: IO.STREAM ← cmd.out;
argv: CommandTool.ArgumentVector = CommandTool.Parse[cmd !
CommandTool.Failed => {out.PutRope[errorMsg]; GOTO CantParse}];
name: Rope.ROPE;
server: IO.STREAM;
nameServer: Rope.ROPE ← defaultNameServer;
where: LIST OF Arpa.Address;
IF argv.argc > 1 THEN name ← argv[1] ELSE name ← "Xerox";
out.PutF["Poking ARPA Name Server for info on %G.\n", [rope[name]] ];
where ← ArpaName.NameToAddressList[nameServer].addrs;
IF where =
NIL
THEN {
out.PutF["Can't lookup IP Address for %G.\n", IO.rope[nameServer]];
RETURN; };
BEGIN
ENABLE {
ArpaTCP.Timeout => {
out.PutRope["[TCP.Timeout.]\n"];
GO TO GiveUp; };
ArpaTCP.Error => {
out.PutRope["[TCP.Error.]\n"];
GO TO GiveUp; };
IO.Error => {
out.PutRope["[IO.Error.]\n"];
GOTO GiveUp; };
};
server ← ArpaTCP.CreateTCPStream[[
matchLocalPort: FALSE,
localPort: 0,
matchForeignAddr: TRUE,
foreignAddress: where.first,
matchForeignPort: TRUE,
foreignPort: nameServerSocket,
active: TRUE,
timeout: 120000]];
ArpaTCP.WaitForListenerOpen[server, ArpaTCP.neverTimeout];
server.PutRope["HNAME "];
server.PutRope[name];
server.PutChar['\n]; server.PutChar['\l]; -- send the LF as well
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 ArpaTCP.AbortTCPStream[server];
END;
};
FetchTable: Commander.CommandProc = {
out: IO.STREAM ← cmd.out;
argv: CommandTool.ArgumentVector = CommandTool.Parse[cmd !
CommandTool.Failed => {out.PutRope[errorMsg]; GOTO CantParse}];
fileName, nameServer: Rope.ROPE;
file, server: IO.STREAM;
where: LIST OF Arpa.Address;
IF argv.argc > 1 THEN fileName ← argv[1] ELSE fileName ← defaultFileName;
IF argv.argc > 2 THEN nameServer ← argv[2] ELSE nameServer ← defaultNameServer;
out.PutF["Fetching new %G from %G.\n", [rope[fileName]], [rope[nameServer]] ];
where ← ArpaName.NameToAddressList[nameServer].addrs;
IF where =
NIL
THEN {
out.PutF["Can't lookup IP Address for %G.\n", IO.rope[nameServer]];
RETURN; };
file ← FS.StreamOpen[fileName, create];
BEGIN
ENABLE {
ArpaTCP.Timeout => {
out.PutRope["[TCP.Timeout.]\n"];
GO TO GiveUp; };
ArpaTCP.Error => {
out.PutRope["[TCP.Error.]\n"];
GO TO GiveUp; };
IO.Error => {
out.PutRope["[IO.Error.]\n"];
GOTO GiveUp; };
};
file.PutRope["FETCHED: "];
file.PutRope[Convert.RopeFromTime[BasicTime.Now[]]];
file.PutRope["\n"];
Include version info in our copy of the file.
server ← ArpaTCP.CreateTCPStream[[
matchLocalPort: FALSE,
localPort: 0,
matchForeignAddr: TRUE,
foreignAddress: where.first,
matchForeignPort: TRUE,
foreignPort: nameServerSocket,
active: TRUE,
timeout: 120000]];
ArpaTCP.WaitForListenerOpen[server, ArpaTCP.neverTimeout];
server.PutRope["VERSION\n\l"];
server.Flush[];
WHILE
NOT server.EndOf[]
DO
c: CHAR ← server.GetChar[ ! IO.EndOfStream => EXIT];
IF c # '\l THEN file.PutChar[c];
ENDLOOP;
server.Close[];
Now, grab the data.
server ← ArpaTCP.CreateTCPStream[[
matchLocalPort: FALSE,
localPort: 0,
matchForeignAddr: TRUE,
foreignAddress: where.first,
matchForeignPort: TRUE,
foreignPort: nameServerSocket,
active: TRUE,
timeout: 120000]];
ArpaTCP.WaitForListenerOpen[server, ArpaTCP.neverTimeout];
server.PutRope["ALL\n\l"];
server.Flush[];
WHILE
NOT server.EndOf[]
DO
c: CHAR ← server.GetChar[ ! IO.EndOfStream => EXIT];
IF c # '\l THEN file.PutChar[c];
ENDLOOP;
server.Close[];
EXITS
GiveUp =>
BEGIN
IF server # NIL THEN ArpaTCP.AbortTCPStream[server];
END;
END;
out.PutChar['\n];
file.Close[];
EXITS CantParse => NULL;
};
Commander.Register[key: "HostName", proc: HostName, doc: "Look up Host Name at NIC's NameServer"];
Commander.Register[key: "NameTableVersion", proc: Version, doc: "Print out VERSION info from NIC's NameServer"];
Commander.Register[key: "FetchNameTable", proc: FetchTable, doc: "Fetch Source for IP name table from NIC"];
END.