Copyright (C) 1987 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.
ArpaConfigImpl.mesa
John Larson, November 30, 1987 12:14:27 pm PST
DIRECTORY
Arpa USING [Address],
ArpaConfig,
ArpaName USING [SetArpanetRootServers, SetLocalRootServers],
Ascii USING [Digit],
FS USING [Error, StreamOpen],
IO USING [Close, EndOf, EndOfStream, Error, GetChar, GetLineRope, GetTokenRope, IDProc, PeekChar, STREAM],
MessageWindow USING [Append],
Rope USING [Cat, Equal, ROPE],
RopeList USING [Append];
ArpaConfigImpl: CEDAR MONITOR
IMPORTS ArpaName, Ascii, FS, IO, MessageWindow, Rope, RopeList
EXPORTS ArpaConfig =
BEGIN OPEN ArpaConfig;
ROPE: TYPE = Rope.ROPE;
gvMSName: PUBLIC ROPE ← "ArpaGateway.ms";
specialGateways: PUBLIC LIST OF Arpa.Address; -- list of special BBN gateways
ourLocalAddress: PUBLIC Arpa.Address ← [10, 1, 0, 32];
ourLocalName: PUBLIC Rope.ROPE ← "Xerox.COM";
xeroxDomain: PUBLIC ROPE ← "Xerox.COM";
rootServers: PUBLIC LIST OF Rope.ROPE; -- list of ARPA domain servers
rootServerAddresses: PUBLIC LIST OF Arpa.Address; -- list of ARPA domain server addresses
specialDomains: PUBLIC LIST OF Rope.ROPE;
topLevelDomains: PUBLIC LIST OF Rope.ROPE;
validDomains: PUBLIC LIST OF Rope.ROPE;
uucpGateway: PUBLIC Rope.ROPE ← "seismo.css.gov";
csnetGateway: PUBLIC Rope.ROPE ← "relay.cs.net";
bitnetGateway: PUBLIC Rope.ROPE ← "WISCVM.WISC.EDU";
configFileName: ROPE ← "ArpaConfig.data";
Read Configuration File
ParseAddress: PROC [s: IO.STREAM] RETURNS [a: Arpa.Address] = {
AToI: PROC [s: IO.STREAM] RETURNS [i: INT ← 0] = {
WHILE ~IO.EndOf[s] AND Ascii.Digit[IO.PeekChar[s]] DO
i ← i*10 + (s.GetChar[]-'0);
ENDLOOP; };
WHILE IO.PeekChar[s] = ' DO [] ← IO.GetChar[s]; ENDLOOP;
IF IO.PeekChar[s] = '[ THEN [] ← IO.GetChar[s];
FOR i: INT IN [0..3] DO
SELECT i FROM
0 => a.a ← AToI[s];
1 => a.b ← AToI[s];
2 => a.c ← AToI[s];
3 => a.d ← AToI[s];
ENDCASE;
IF ~IO.EndOf[s] AND IO.PeekChar[s] = '. THEN [] ← IO.GetChar[s];
ENDLOOP;
IF ~IO.EndOf[s] AND IO.PeekChar[s] = '] THEN [] ← IO.GetChar[s]; };
ReadConfigurationFile: PUBLIC PROC ~ {
Look for a configuration file and use it for some parameter values.
ENABLE {
IO.EndOfStream => GO TO GiveUp;
IO.Error => {
MessageWindow.Append[message: Rope.Cat["Syntax error in ", configFileName], clearFirst: TRUE];
GO TO GiveUp;
};
};
f: IO.STREAM;
t: Rope.ROPE;
SkipWhite: PROC [s: IO.STREAM] ~ {
WHILE s.PeekChar[] = ' OR s.PeekChar[] = '\t DO
[] ← s.GetChar[];
ENDLOOP;
};
ParseRopeList: PROC [s: IO.STREAM] RETURNS [list: LIST OF Rope.ROPE] = {
DO
SkipWhite[s];
IF s.PeekChar = '\n THEN EXIT;
list ← RopeList.Append[list, LIST[s.GetTokenRope[IO.IDProc].token]];
ENDLOOP;
};
f ← FS.StreamOpen[configFileName ! FS.Error => {
MessageWindow.Append[message: error.explanation, clearFirst: TRUE];
GO TO GiveUp}];
WHILE NOT f.EndOf[] DO
[token: t] ← f.GetTokenRope[IO.IDProc];
SkipWhite[f];
IF f.PeekChar[] = ': THEN
[] ← f.GetChar[];
SELECT TRUE FROM
t.Equal["ArpaAddress"] => ourLocalAddress ← ParseAddress[f];
t.Equal["SpecialGateways"] => {
specialGateways ← NIL;
DO
addr: LIST OF Arpa.Address;
SkipWhite[f];
IF f.PeekChar = '\n THEN
EXIT;
addr ← CONS[ParseAddress[f], NIL];
IF specialGateways = NIL THEN specialGateways ← addr
ELSE
FOR list: LIST OF Arpa.Address ← specialGateways, list.rest UNTIL list = NIL DO
IF list.rest = NIL THEN {list.rest ← addr; EXIT; };
ENDLOOP;
ENDLOOP;
};
t.Equal["RootServerAddresses"] => {
rootServerAddresses ← NIL;
DO
addr: LIST OF Arpa.Address;
SkipWhite[f];
IF f.PeekChar = '\n THEN
EXIT;
addr ← CONS[ParseAddress[f], NIL];
IF rootServerAddresses = NIL THEN rootServerAddresses ← addr
ELSE
FOR list: LIST OF Arpa.Address ← rootServerAddresses, list.rest UNTIL list = NIL DO
IF list.rest = NIL THEN {list.rest ← addr; EXIT; };
ENDLOOP;
ENDLOOP;
};
t.Equal["GVMSName"] => [token: gvMSName] ← f.GetTokenRope[IO.IDProc];
t.Equal["ArpaName"] => [token: ourLocalName] ← f.GetTokenRope[IO.IDProc];
t.Equal["DomainName"] => [token: xeroxDomain] ← f.GetTokenRope[IO.IDProc];
t.Equal["UUCPGateway"] => [token: uucpGateway] ← f.GetTokenRope[IO.IDProc];
t.Equal["CSNETGateway"] => [token: csnetGateway] ← f.GetTokenRope[IO.IDProc];
t.Equal["BitnetGateway"] => [token: bitnetGateway] ← f.GetTokenRope[IO.IDProc];
t.Equal["SpecialDomains"] => {specialDomains ← ParseRopeList[f]};
t.Equal["TopLevelDomains"] => {topLevelDomains ← ParseRopeList[f]};
t.Equal["RootServers"] => {rootServers ← ParseRopeList[f]};
ENDCASE => NULL;
[] ← f.GetLineRope[]; -- toss text to end of line
ENDLOOP;
IO.Close[f];
EXITS
GiveUp => NULL;
};
Initialization code
ReadConfigurationFile[];
validDomains ← RopeList.Append[topLevelDomains, specialDomains];
ArpaName.SetLocalRootServers[rootServerAddresses]; -- until I get recursive name service
ArpaName.SetArpanetRootServers[rootServerAddresses];
END.