<> <> <> <> <> <> <> <<>> DIRECTORY BasicTime USING [Now], Commander USING [CommandProc, Register], CommandTool USING [ArgumentVector, Failed, Parse], Convert USING [RopeFromTime], FS USING [Error, StreamOpen], IO USING [Close, EndOf, EndOfStream, Error, Flush, GetChar, PutF, PutChar, PutRope, rope, STREAM], Rope USING [ROPE], IPDefs USING [Address], IPName USING [NameToAddress], TCP USING [AbortTCPStream, CreateTCPStream, Error, neverTimeout, Timeout, WaitForListenerOpen]; BuildNameTable: CEDAR PROGRAM IMPORTS BasicTime, Commander, CommandTool, Convert, FS, IO, IPName, TCP = 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 IPDefs.Address; out.PutF["Poking ARPA Name Server for current version.\n"]; where _ IPName.NameToAddress[nameServer ! FS.Error => CONTINUE]; IF where = NIL THEN { out.PutF["Can't lookup IP Address for %G.\n", IO.rope[nameServer]]; 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: nameServerSocket, active: TRUE, timeout: 120000]]; TCP.WaitForListenerOpen[server, TCP.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 TCP.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 IPDefs.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 _ IPName.NameToAddress[nameServer ! FS.Error => CONTINUE]; IF where = NIL THEN { out.PutF["Can't lookup IP Address for %G.\n", IO.rope[nameServer]]; 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: nameServerSocket, active: TRUE, timeout: 120000]]; TCP.WaitForListenerOpen[server, TCP.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 TCP.AbortTCPStream[server]; END; EXITS CantParse => NULL; }; 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 IPDefs.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 _ IPName.NameToAddress[nameServer ! FS.Error => CONTINUE]; 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 { 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; }; }; file.PutRope["FETCHED: "]; file.PutRope[Convert.RopeFromTime[BasicTime.Now[]]]; file.PutRope["\n"]; <> server _ TCP.CreateTCPStream[[ matchLocalPort: FALSE, localPort: 0, matchForeignAddr: TRUE, foreignAddress: where.first, matchForeignPort: TRUE, foreignPort: nameServerSocket, active: TRUE, timeout: 120000]]; TCP.WaitForListenerOpen[server, TCP.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[]; <> server _ TCP.CreateTCPStream[[ matchLocalPort: FALSE, localPort: 0, matchForeignAddr: TRUE, foreignAddress: where.first, matchForeignPort: TRUE, foreignPort: nameServerSocket, active: TRUE, timeout: 120000]]; TCP.WaitForListenerOpen[server, TCP.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 TCP.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.