-- Copyright (C) 1983  by Xerox Corporation. All rights reserved. 
-- GateControlFinish.mesa, HGM, 23-Sep-83 16:18:05

DIRECTORY
  Ascii USING [CR],
  Event USING [aboutToSwap],
  EventTypes USING [aboutToBoot, aboutToBootPhysicalVolume],
  MFile USING [Error, ReadOnly, Release],
  MStream USING [ReadWrite, GetLength],
  Process USING [Detach, SecondsToTicks],
  Put USING [Line],
  Stream USING [Delete, Handle, PutChar, PutString, SetPosition],
  String USING [AppendString, AppendChar],
  Supervisor USING [EnumerationAborted, NotifyDirectSubsystems],
  System USING [switches],
  TemporaryBooting USING [BootFromPhysicalVolume, BootFromVolume],
  Time USING [AppendCurrent],
  Volume USING [systemID],

  GateControlDefs USING [msg],
  PupDefs USING [AppendHostName, PupBuffer, PupAddress],
  Trouble USING [ForceOutTypescriptFile];

GateControlFinish: MONITOR
  IMPORTS
    Event, MFile, MStream, Process, Put, Stream, String, Supervisor, System,
    TemporaryBooting, Time, Volume, GateControlDefs, PupDefs, Trouble
  EXPORTS GateControlDefs =
  BEGIN

  verbose: BOOLEAN = TRUE;

  restarting: BOOLEAN ← FALSE;

  RestartGateway: PUBLIC ENTRY PROCEDURE [b: PupDefs.PupBuffer] =
    BEGIN
    IF restarting THEN RETURN;
    restarting ← TRUE;
    Process.Detach[FORK Restart[b.pup.source, TRUE]];
    END;

  HaltGateway: PUBLIC ENTRY PROCEDURE [b: PupDefs.PupBuffer] =
    BEGIN
    IF restarting THEN RETURN;
    restarting ← TRUE;
    Process.Detach[FORK Restart[b.pup.source, FALSE]];
    END;

  Restart: ENTRY PROCEDURE [who: PupDefs.PupAddress, restart: BOOLEAN] =
    BEGIN
    sh: Stream.Handle;
    dally: CONDITION ← [timeout: Process.SecondsToTicks[1]];
    StuffCommand: PROCEDURE [s: STRING] =
      BEGIN
      Stream.PutString[sh, s];
      Stream.PutChar[sh, Ascii.CR];
      END;
    IF verbose THEN
      BEGIN
      text: STRING = [100];
      Time.AppendCurrent[text];
      String.AppendString[text, "  Gateway "L];
      String.AppendString[text, IF restart THEN "restarted"L ELSE "halted"L];
      String.AppendString[text, " by "L];
      PupDefs.AppendHostName[text, who];
      String.AppendChar[text, '.];
      LogString[text];
      END;
    -- Pause a while to be sure that GateControl gets the ack.
    THROUGH [0..30) DO WAIT dally; ENDLOOP;
    sh ← MStream.ReadWrite["Rem.cm"L, [], text];
    Stream.SetPosition[sh, MStream.GetLength[sh]];
    Stream.PutChar[sh, Ascii.CR];
    Stream.PutChar[sh, Ascii.CR];
    BEGIN
    ENABLE MFile.Error => CONTINUE;
    MFile.Release[MFile.ReadOnly["NewPupGateway.bcd"L, []]];
    StuffCommand["Delete PupGateway.bcd"L];
    StuffCommand["Rename PupGateway.bcd ← NewPupGateway.bcd"L];
    END;
    BEGIN
    text: STRING = [100];
    String.AppendString[text, "//  Gateway "L];
    String.AppendString[text, IF restart THEN "restarted"L ELSE "halted"L];
    String.AppendString[text, " by "L];
    PupDefs.AppendHostName[text, who];
    StuffCommand[text];
    END;
    Stream.Delete[sh];
    BEGIN
    ENABLE Supervisor.EnumerationAborted => CONTINUE;
    Trouble.ForceOutTypescriptFile[];
    IF restart THEN
      BEGIN
      Supervisor.NotifyDirectSubsystems[
        event: [EventTypes.aboutToBoot], which: clients, subsystem: Event.aboutToSwap];
      TemporaryBooting.BootFromVolume[Volume.systemID, System.switches];
      END
    ELSE
      BEGIN
      Supervisor.NotifyDirectSubsystems[
        event: [EventTypes.aboutToBootPhysicalVolume], which: clients, subsystem: Event.aboutToSwap];
      TemporaryBooting.BootFromPhysicalVolume[Volume.systemID, System.switches];
      END;
    END;
    LogString["Barf, I guess we got Vetoed."L];
    END;

  LogString: PROCEDURE [text: STRING] =
    BEGIN
    IF GateControlDefs.msg # NIL THEN Put.Line[GateControlDefs.msg, text];
    Put.Line[NIL, text];
    END;

  END.