-- Copyright (C) 1981, 1984, 1985 by Xerox Corporation. All rights reserved. -- ServerAlloc.mesa, Transport Mechanism Mail Server - managing records of other servers -- -- HGM: 15-Sep-85 4:40:50 -- Randy Gobbel 19-May-81 12:36:43 -- -- Andrew Birrell 29-Dec-81 15:34:31 -- -- Hankins 22-Oct-84 15:32:04 DIRECTORY Ascii USING [CR], BodyDefs USING [RName, RNameSize], EnquiryDefs USING [], GlassDefs USING [Handle], Inline USING [LongCOPY], Process USING [InitializeMonitor], PupDefs USING [AppendPupAddress], ServerDefs USING [ServerHandle, ServerData, ServerName], Storage USING [Node, String], String USING [EquivalentStrings]; ServerAlloc: MONITOR IMPORTS BodyDefs, Inline, Process, PupDefs, Storage, String EXPORTS EnquiryDefs, ServerDefs SHARES ServerDefs = BEGIN OPEN ServerDefs; noServer: ServerHandle = NIL; freeChain: ServerHandle ← noServer; mailChain: ServerHandle ← noServer; CreateServer: INTERNAL PROCEDURE [name: ServerName, leaf: BOOLEAN] RETURNS [res: ServerHandle] = BEGIN chain: POINTER TO ServerHandle = @mailChain; IF freeChain = noServer THEN res ← Storage.Node[SIZE[ServerData]] ELSE BEGIN res ← freeChain; freeChain ← freeChain.next; END; res.next ← chain↑; chain↑ ← res; Process.InitializeMonitor[@res.LOCK]; res.leaf ← leaf; WITH name SELECT FROM rName => BEGIN --copy RName into permanent storage-- size: CARDINAL = BodyDefs.RNameSize[value]; place: BodyDefs.RName = Storage.Node[size]; Inline.LongCOPY[value, size, place]; res.name ← [rName[place]]; res.addrKnown ← FALSE; END; connect => BEGIN --copy connect site into permanent storage -- place: STRING = Storage.String[value.length]; Inline.LongCOPY[@(value.text), (1 + value.length) / 2, @(place.text)]; place.length ← value.length; res.name ← [connect[place]]; res.addrKnown ← FALSE; END; netAddr => BEGIN res.name ← [netAddr[value]]; res.addr ← value; res.addrKnown ← TRUE; END; ENDCASE => ERROR; res.up ← TRUE; res.SL ← NIL; END; GetServer: PUBLIC ENTRY PROCEDURE [name: ServerName] RETURNS [res: ServerHandle] = BEGIN res ← FindServer[name]; IF res = noServer THEN res ← CreateServer[name, FALSE]; END; GetLeafServer: PUBLIC ENTRY PROCEDURE [name: ServerName] RETURNS [res: ServerHandle] = BEGIN res ← FindServer[name]; IF res = noServer THEN res ← CreateServer[name, TRUE]; END; FindServer: INTERNAL PROCEDURE [name: ServerName] RETURNS [res: ServerHandle] = BEGIN FOR res ← mailChain, res.next UNTIL res = noServer DO IF (WITH wanted: name SELECT FROM rName => (WITH found: res.name SELECT FROM rName => String.EquivalentStrings[found.value, wanted.value], --MTP-- connect => --MTP-- String.EquivalentStrings[found.value, wanted.value], ENDCASE => FALSE), connect => (WITH found: res.name SELECT FROM connect => String.EquivalentStrings[found.value, wanted.value], ENDCASE => FALSE), netAddr => (WITH found: res.name SELECT FROM netAddr => found.value = wanted.value, ENDCASE => FALSE), ENDCASE => ERROR) THEN EXIT; ENDLOOP; END; EnumerateAll: PUBLIC ENTRY PROCEDURE [work: PROCEDURE [ServerHandle]] = BEGIN ENABLE UNWIND => NULL; FOR ptr: ServerHandle ← mailChain, ptr.next UNTIL ptr = noServer DO work[ptr] ENDLOOP; END; RemoteServers: PUBLIC PROC [str: GlassDefs.Handle] = BEGIN OPEN str; FOR ptr: ServerHandle ← mailChain, ptr.next UNTIL ptr = noServer DO WriteChar[Ascii.CR]; WriteString[ WITH this: ptr.name SELECT FROM rName => this.value, connect => this.value, netAddr => "[net address]"L, ENDCASE => "[bad name]"L]; WriteString[": "L]; WriteString[IF ptr.up THEN "up"L ELSE "down"L]; IF ptr.leaf THEN WriteString[", leaf"L]; IF ptr.addrKnown THEN BEGIN temp: STRING = [25]; PupDefs.AppendPupAddress[temp, ptr.addr]; WriteString[", "]; WriteString[temp]; END; ENDLOOP; END; END. LOG: 22-Oct-84 15:31:45 - blh: remove serverHandle from RemoteServers printout