-- Copyright (C) 1981, 1984, 1985  by Xerox Corporation. All rights reserved. 
-- ServerAlloc.mesa, Transport Mechanism Mail Server - managing records of other servers --

-- HGM: 22-Oct-85  5:25:02
-- 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],
  EnquiryDefs USING [],
  GlassDefs USING [Handle],
  Heap USING [systemMDSZone, systemZone],
  Process USING [InitializeMonitor],
  PupDefs USING [AppendPupAddress],
  ServerDefs USING [ServerHandle, ServerData, ServerName],
  String USING [AppendString, EquivalentStrings];

ServerAlloc: MONITOR
  IMPORTS Heap, Process, PupDefs, String
  EXPORTS EnquiryDefs, ServerDefs
  SHARES ServerDefs =
  BEGIN OPEN ServerDefs;

  mailChain: ServerHandle ← NIL;

  CreateServer: INTERNAL PROCEDURE [name: ServerName, leaf: BOOLEAN]
    RETURNS [res: ServerHandle] =
    BEGIN
    res ← Heap.systemMDSZone.NEW[ServerData];
    res.next ← mailChain;
    mailChain ← res;
    Process.InitializeMonitor[@res.LOCK];
    res.leaf ← leaf;
    WITH name SELECT FROM
      rName =>
        BEGIN  --copy RName into permanent storage
        place: BodyDefs.RName = Heap.systemZone.NEW[StringBody[value.length]];
        String.AppendString[place, value];
        res.name ← [rName[place]];
        res.addrKnown ← FALSE;
        END;
      connect =>
        BEGIN  --copy connect site into permanent storage
        place: LONG STRING = Heap.systemZone.NEW[StringBody[value.length]];
        String.AppendString[place, value];
        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 = NIL THEN res ← CreateServer[name, FALSE];
    END;
  
  GetLeafServer: PUBLIC ENTRY PROCEDURE [name: ServerName] RETURNS [res: ServerHandle] =
    BEGIN
    res ← FindServer[name];
    IF res = NIL THEN res ← CreateServer[name, TRUE];
    END;
  
  FindServer: INTERNAL PROCEDURE [name: ServerName]
    RETURNS [res: ServerHandle] =
    BEGIN
    FOR res ← mailChain, res.next UNTIL res = NIL 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 = NIL DO
      work[ptr] ENDLOOP;
    END;

  RemoteServers: PUBLIC PROC [str: GlassDefs.Handle] =
    BEGIN OPEN str;
    FOR ptr: ServerHandle ← mailChain, ptr.next UNTIL ptr = NIL 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