-- Copyright (C) 1984 by Xerox Corporation. All rights reserved. -- GateControlServer.mesa, HGM, 19-Apr-84 17:04:29 DIRECTORY Inline USING [LowHalf], Process USING [Detach], String USING [AppendString, AppendDecimal], System USING [IsUtilityPilot], Time USING [Current], Volume USING [GetAttributes, SystemID], Window USING [Handle], Buffer USING [ReturnBuffer], BufferOps USING [GetStatistics, Statistics], GateDefs USING [GetVersionText], GateControlDefs USING [ gateControlStatsSend, gateControlStatsAck, gateControlExamine, gateControlDeposit, gateControlRestart, gateControlHalt, GateControlStatsEntry, gateControlVersion, RestartGateway, HaltGateway], CpuIdle USING [GetSmoothedCpuUtilization], PupWireFormat USING [MesaToBcplLongNumber, BcplSTRING], PupDefs USING [ PupAddress, PupBuffer, GetPupContentsBytes, SetPupContentsWords, PupRouterSendThis, SwapPupSourceAndDest, PupSocket, PupSocketMake, veryLongWait], PupTypes USING [fillInPupAddress], Stats; GateControlServer: PROGRAM IMPORTS Inline, Process, String, System, Time, Volume, Buffer, BufferOps, GateDefs, GateControlDefs, CpuIdle, Stats, PupWireFormat, PupDefs EXPORTS GateControlDefs = BEGIN OPEN Stats, PupDefs; msg: PUBLIC Window.Handle ← NIL; version: LONG STRING ← GateDefs.GetVersionText[]; statsCounters: LONG POINTER TO ARRAY StatCounterIndex OF LONG CARDINAL = StatsGetCounters[]; soc: PupSocket; GateControlServerOn: PUBLIC PROCEDURE = BEGIN Process.Detach[FORK Server[]]; END; Server: PROCEDURE = BEGIN b: PupBuffer; soc ← PupSocketMake[[31415, 9265], PupTypes.fillInPupAddress, veryLongWait]; DO -- forever IF (b ← soc.get[]) # NIL THEN BEGIN OPEN GateControlDefs; IF b.pup.pupID.a # 27182 THEN GOTO Ignore; SELECT b.pup.pupType FROM gateControlStatsSend => BEGIN info: ARRAY BufferOps.Statistics OF CARDINAL ← BufferOps.GetStatistics[]; temp: STRING = [200]; gse: LONG POINTER TO GateControlStatsEntry; now: LONG CARDINAL ← Time.Current[]; free: LONG CARDINAL ← 0; IF ~System.IsUtilityPilot[] THEN free ← Volume.GetAttributes[Volume.SystemID[]].freePageCount; Stats.StatUpdate[]; -- be sure statSeconds is up-to-date IF GetPupContentsBytes[b] # 0 THEN GOTO Ignore; gse ← LOOPHOLE[@b.pup.pupBody]; -- Beware: Constructor needs space for a copy on the frame gse.version ← GateControlDefs.gateControlVersion; gse.startTime ← PupWireFormat.MesaToBcplLongNumber[ -- we can't just save the start time since we might not know the time yet LOOPHOLE[LOOPHOLE[now, LONG INTEGER] - statsCounters[statSeconds]]]; gse.ftpStatus ← 0; gse.freeBuffers ← info[available]; gse.freeDiskPages ← IF free < 50000 THEN Inline.LowHalf[free] ELSE 50000; String.AppendString[temp, version]; String.AppendString[temp, ", "L]; String.AppendDecimal[temp, CpuIdle.GetSmoothedCpuUtilization[]]; String.AppendString[temp, "%"L]; CopyString[temp, @gse.versionText]; -- This sends more than we need to SetPupContentsWords[b, SIZE[GateControlStatsEntry]]; GOTO Send; END; gateControlExamine => BEGIN p: POINTER TO ARRAY [0..0) OF WORD ← LOOPHOLE[b.pup.pupWords[0]]; i, words: CARDINAL; Stats.StatUpdate[]; -- might look at the time IF GetPupContentsBytes[b] # 2*2 THEN GOTO Ignore; words ← b.pup.pupWords[1]; FOR i IN [0..words) DO b.pup.pupWords[2 + i] ← p[i]; ENDLOOP; SetPupContentsWords[b, (words + 2)]; GOTO Send; END; gateControlDeposit => BEGIN -- I hope you know what you are doing p: POINTER TO ARRAY [0..0) OF WORD ← LOOPHOLE[b.pup.pupWords[0]]; i, words: CARDINAL; words ← b.pup.pupWords[1]; IF GetPupContentsBytes[b] # 2*(words + 2) THEN GOTO Ignore; FOR i IN [0..b.pup.pupWords[1]) DO p[i] ← b.pup.pupWords[2 + i]; ENDLOOP; SetPupContentsWords[b, 0]; GOTO Send; END; gateControlRestart => BEGIN GateControlDefs.RestartGateway[b]; SetPupContentsWords[b, 0]; GOTO Send; END; gateControlHalt => BEGIN GateControlDefs.HaltGateway[b]; SetPupContentsWords[b, 0]; GOTO Send; END; error => GOTO Ignore; ENDCASE => GOTO Ignore; EXITS Send => BEGIN -- pupLength already setup b.pup.pupType ← gateControlStatsAck; SwapPupSourceAndDest[b]; PupRouterSendThis[b]; END; Ignore => BEGIN Buffer.ReturnBuffer[b]; END; END; ENDLOOP; END; CopyString: PROCEDURE [ s: LONG STRING, d: LONG POINTER TO PupWireFormat.BcplSTRING] = BEGIN i: CARDINAL; d.length ← s.length; FOR i IN [0..s.length) DO d.char[i] ← s[i]; ENDLOOP; END; -- initialization GateControlServerOn[]; END.