<> <> <> DIRECTORY Arpa USING [Address], ArpaConfig, ArpaName USING [SetArpanetRootServers], 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"; ourLocalAddress: PUBLIC Arpa.Address _ [13, 0, 12, 232]; ourLocalName: PUBLIC Rope.ROPE _ "Xerox.COM"; xeroxDomain: PUBLIC ROPE _ "Xerox.COM"; rootServerAddresses: PUBLIC LIST OF Arpa.Address _NIL; -- list of ARPA domain server addresses resolv: PUBLIC REF BOOL _ NEW[BOOL _ TRUE]; -- whether to do full recursive name resolution 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"; <> 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 ~ { <> 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["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]}; ENDCASE => NULL; [] _ f.GetLineRope[]; -- toss text to end of line ENDLOOP; IO.Close[f]; EXITS GiveUp => NULL; }; <> ReadConfigurationFile[]; validDomains _ RopeList.Append[topLevelDomains, specialDomains]; IF rootServerAddresses # NIL THEN ArpaName.SetArpanetRootServers[rootServerAddresses]; END.