-- Copyright (C) 1983 by Xerox Corporation. All rights reserved. -- BootServerInfoServer.mesa, HGM, 23-Sep-83 3:38:16 DIRECTORY Courier USING [ Arguments, Description, ExportRemoteProgram, Handle, nullParameters, SerializeParameters, NoSuchProcedureNumber, Parameters, Results, UnexportRemoteProgram], ExpeditedCourier USING [ DispatcherProc, ExpeditedServiceHandle, ExportExpeditedPrograms, GetDefaultSocketNumber, normalReturnHeader, SerializeHeader, Services, Service, UnexportExpeditedPrograms], Heap USING [systemZone], NetworkStream USING [], Stream USING [Handle], String USING [Copy], System USING [gmtEpoch, NetworkAddress, SocketNumber], NSConstants USING [bootServerSocket], Socket USING [LocalAddressFromSocket], BootServer USING [Counters, GetStatistics], BootServerFriends USING [BootFile, EnumerateBootTable], BootServerInfo USING [ BootFileNumber, programNumber, Counters, DescribeBootFileNumber, DescribeBootServerInfo, DescribeCounters, DescribeNetworkAddress, endEnumeration, Info, Procedures, versionRange]; BootServerInfoServer: PROGRAM IMPORTS Courier, ExpeditedCourier, Heap, String, Socket, BootServer, BootServerFriends, BootServerInfo = BEGIN started: BOOLEAN ← FALSE; expeditedServiceHandle: ExpeditedCourier.ExpeditedServiceHandle; netMgtName: LONG STRING = "Boot Server"; z: UNCOUNTED ZONE = Heap.systemZone; StartServer: PUBLIC PROCEDURE = BEGIN services: ExpeditedCourier.Services ← DESCRIPTOR[service]; service: ARRAY [0..2) OF ExpeditedCourier.Service ← [ [ versionRange: BootServerInfo.versionRange, programNumber: BootServerInfo.programNumber * 200000B, -- WORD ORDER KROCK bindRequestProcedure: BootServerInfo.Procedures.whoAreYou.ORD, dispatcher: PktExchngDispatcher], [ versionRange: BootServerInfo.versionRange, programNumber: BootServerInfo.programNumber, bindRequestProcedure: BootServerInfo.Procedures.whoAreYou.ORD, dispatcher: PktExchngDispatcher] ]; IF started THEN RETURN; started ← TRUE; Courier.ExportRemoteProgram[ BootServerInfo.programNumber, BootServerInfo.versionRange, Dispatcher, netMgtName, Heap.systemZone, transactional]; expeditedServiceHandle ← ExpeditedCourier.ExportExpeditedPrograms[ services: services, socket: ExpeditedCourier.GetDefaultSocketNumber[]]; END; StopServer: PUBLIC PROCEDURE = BEGIN IF ~started THEN RETURN; started ← FALSE; Courier.UnexportRemoteProgram[BootServerInfo.programNumber, BootServerInfo.versionRange]; ExpeditedCourier.UnexportExpeditedPrograms[expeditedServiceHandle]; END; -- Dispatchers Dispatcher: PROCEDURE [cH: Courier.Handle, procedureNumber: CARDINAL, arguments: Courier.Arguments, results: Courier.Results] = BEGIN proc: BootServerInfo.Procedures; IF procedureNumber > BootServerInfo.Procedures.LAST.ORD THEN ERROR Courier.NoSuchProcedureNumber; proc ← VAL[procedureNumber]; SELECT proc FROM whoAreYou => CourierWhoAreYou[arguments, results]; getCounters => CourierGetCounters[arguments, results]; enumerateBootTable => CourierEnumerateBootTable[arguments, results]; ENDCASE => ERROR Courier.NoSuchProcedureNumber; END; PktExchngDispatcher: ExpeditedCourier.DispatcherProc = BEGIN proc: BootServerInfo.Procedures; IF procedureNumber > BootServerInfo.Procedures.LAST.ORD THEN RETURN[FALSE]; -- ERROR Courier.NoSuchProcedureNumber; proc ← VAL[procedureNumber]; SELECT proc FROM whoAreYou => PexWhoAreYou[replyMemoryStream]; getCounters => PexGetCounters[replyMemoryStream]; ENDCASE => RETURN[FALSE]; -- ERROR Courier.NoSuchProcedureNumber; RETURN[TRUE]; END; PexWhoAreYou: PROCEDURE [replyMemoryStream: Stream.Handle] = BEGIN me: System.NetworkAddress ← GetAddress[]; -- no arguments -- send results ExpeditedCourier.SerializeHeader[replyMemoryStream, ExpeditedCourier.normalReturnHeader]; Courier.SerializeParameters [[@me, BootServerInfo.DescribeNetworkAddress], replyMemoryStream]; END; PexGetCounters: PROCEDURE [replyMemoryStream: Stream.Handle] = BEGIN counters: BootServerInfo.Counters ← RealGetCounters[]; -- no arguments -- send results ExpeditedCourier.SerializeHeader[replyMemoryStream, ExpeditedCourier.normalReturnHeader]; Courier.SerializeParameters [[@counters, BootServerInfo.DescribeCounters], replyMemoryStream]; END; CourierWhoAreYou: PROCEDURE [ arguments: Courier.Arguments, results: Courier.Results] = BEGIN me: System.NetworkAddress ← GetAddress[]; args: Courier.Parameters ← Courier.nullParameters; arguments[args]; [] ← results[[@me, BootServerInfo.DescribeNetworkAddress]]; END; GetAddress: PROCEDURE RETURNS [System.NetworkAddress] = BEGIN RETURN[Socket.LocalAddressFromSocket[NSConstants.bootServerSocket]]; END; CourierGetCounters: PROCEDURE [ arguments: Courier.Arguments, results: Courier.Results] = BEGIN counters: BootServerInfo.Counters ← RealGetCounters[]; args: Courier.Parameters ← Courier.nullParameters; arguments[args]; [] ← results[[@counters, BootServerInfo.DescribeCounters]]; END; CourierEnumerateBootTable: PROCEDURE [ arguments: Courier.Arguments, results: Courier.Results] = BEGIN in: BootServerInfo.BootFileNumber; out: BootServerInfo.Info; fileName: STRING = [100]; args: Courier.Parameters ← [@in, BootServerInfo.DescribeBootFileNumber]; arguments[args]; out ← RealEnumerateBootTable[in, fileName]; [] ← results[[@out, BootServerInfo.DescribeBootServerInfo]]; END; Init: PROCEDURE = BEGIN StartServer[]; END; RealGetCounters: PROCEDURE RETURNS [answer: BootServerInfo.Counters] = BEGIN counters: BootServer.Counters ← BootServer.GetStatistics[]; answer ← [ bootFilesRequested: counters.bootFilesRequested, bootFilesSent: counters.bootFilesSent, bootFilesSentSlowly: counters.bootFilesSentSlowly, microcodeBootFilesRequested: counters.microcodeBootFilesRequested, microcodeBootFilesSent: counters.microcodeBootFilesSent, newBootFilesRetrieved: counters.newBootFilesRetrieved]; END; RealEnumerateBootTable: PROCEDURE [ old: BootServerInfo.BootFileNumber, fileName: STRING] RETURNS [new: BootServerInfo.Info] = BEGIN GetNext: PROCEDURE [bf: BootServerFriends.BootFile] = BEGIN IF Less[old, bf.code] AND Less[bf.code, new.bfn] THEN BEGIN new ← [ bfn: bf.code, fileName: fileName, fileType: bf.fileType, machineType: bf.machineType, create: bf.create, bytes: bf.bytes, count: bf.count, ms: bf.ms]; IF bf.unknown THEN bf.bytes ← 0; String.Copy[fileName, bf.fileName]; END; END; new ← [ bfn: BootServerInfo.endEnumeration, fileName: NIL, fileType: reserved, machineType: reserved, create: System.gmtEpoch, bytes: 0, count: 0, ms: 0]; BootServerFriends.EnumerateBootTable[GetNext]; END; Less: PROCEDURE [a, b: BootServerInfo.BootFileNumber] RETURNS [BOOLEAN] = BEGIN Size: TYPE = [0..SIZE[BootServerInfo.BootFileNumber]); aa: POINTER TO ARRAY Size OF WORD ← LOOPHOLE[@a]; bb: POINTER TO ARRAY Size OF WORD ← LOOPHOLE[@b]; FOR i: CARDINAL IN Size DO IF aa[i] < bb[i] THEN RETURN[TRUE]; IF aa[i] > bb[i] THEN RETURN[FALSE]; ENDLOOP; RETURN[FALSE]; END; Init[]; END.