-- File: BootServerInfoTool.mesa - last edit: -- WIrish 5-Feb-88 12:01:20 -- HGM 5-Sep-85 19:54:07 -- Copyright (C) 1984, 1985, 1988 by Xerox Corporation. All rights reserved. DIRECTORY AddressTranslation USING [Error, PrintError, StringToNetworkAddress], Environment USING [bytesPerPage], ExpeditedCourier USING [GetDefaultSocketNumber], Format USING [NetworkAddress, StringProc], FormSW USING [ ClientItemsProcType, ProcType, AllocateItemDescriptor, newLine, CommandItem, StringItem], Heap USING [systemZone], Inline USING [LowHalf], Process USING [Yield], Put USING [Char, CR, Date, Line, LongNumber, Number, Text], Runtime USING [GetBcdTime], String USING [AppendString], System USING [gmtEpoch, NetworkAddress, nullSocketNumber, SocketNumber], Time USING [Append, Current, Unpack], Tool USING [Create, MakeSWsProc, MakeFileSW, MakeFormSW, UnusedLogName], ToolWindow USING [TransitionProcType], Unformat USING [Error, NetworkAddress], UserInput USING [UserAbort], Window USING [Handle], BootServer USING [AppendBFN], BootServerInfo USING [ Counters, EnumerateBootTable, Error, FindServers, GetCounters, Info]; BootServerInfoTool: MONITOR IMPORTS AddressTranslation, ExpeditedCourier, Format, FormSW, Heap, Inline, Put, Process, Runtime, String, Time, Tool, Unformat, UserInput, BootServer, BootServerInfo = BEGIN form, log: PUBLIC Window.Handle ← NIL; remoteAddress: LONG STRING ← NIL; z: UNCOUNTED ZONE = Heap.systemZone; Init: PROCEDURE = BEGIN herald: LONG STRING = [100]; String.AppendString[herald, "BootServer Tool of "L]; Time.Append[herald, Time.Unpack[Runtime.GetBcdTime[]]]; [] ← Tool.Create[ name: herald, makeSWsProc: MakeSWs, clientTransition: ClientTransition]; END; FindServers: FormSW.ProcType = BEGIN ShowServer: PROCEDURE [him: System.NetworkAddress] = BEGIN WriteNetworkAddressVerbose[him]; WriteLine["."L]; END; errFlag: BOOLEAN ← FALSE; remoteAddr: System.NetworkAddress; PrintHeader[log, "Find Servers at "L]; WriteString[remoteAddress]; WriteString[" = "L]; remoteAddr ← GetAddress[remoteAddress, ExpeditedCourier.GetDefaultSocketNumber[] ! Trouble => BEGIN WriteLine[reason]; errFlag ← TRUE; CONTINUE; END]; IF errFlag THEN RETURN; WriteNetworkAddressVerbose[remoteAddr]; WriteLine["."L]; BootServerInfo.FindServers[remoteAddr, ShowServer ! BootServerInfo.Error => BEGIN Put.Text[log, "Oops: "L]; Put.Text[log, reason]; Put.Line[log, "."L]; errFlag ← TRUE; CONTINUE; END; ]; END; Info: FormSW.ProcType = BEGIN errFlag: BOOLEAN ← FALSE; remoteAddr: System.NetworkAddress; counters: BootServerInfo.Counters; PrintHeader[log, "Boot File Info from "L]; WriteString[remoteAddress]; WriteString[" = "L]; remoteAddr ← GetAddress[remoteAddress, System.nullSocketNumber ! Trouble => BEGIN WriteString["AddressTranslation troubles: "L]; WriteLine[reason]; errFlag ← TRUE; CONTINUE; END]; IF errFlag THEN RETURN; WriteNetworkAddressVerbose[remoteAddr]; WriteLine["."L]; counters ← BootServerInfo.GetCounters[remoteAddr ! BootServerInfo.Error => BEGIN Put.Text[log, "Oops: "L]; Put.Text[log, reason]; Put.Line[log, "."L]; errFlag ← TRUE; CONTINUE; END; ]; IF errFlag THEN RETURN; PrintCounters[log, @counters]; END; PrintCounters: PROCEDURE [ wh: Window.Handle, counters: LONG POINTER TO BootServerInfo.Counters] = BEGIN PrintMaybe[ wh, "Boot requests"L, counters.bootFilesRequested]; PrintMaybe[ wh, "Boot files sent"L, counters.bootFilesSent]; PrintMaybe[ wh, "Boot files sent slowly"L, counters.bootFilesSentSlowly]; PrintMaybe[ wh, "Microcode requests"L, counters.microcodeBootFilesRequested]; PrintMaybe[ wh, "Microcode boot files sent"L, counters.microcodeBootFilesSent]; PrintMaybe[ wh, "New boot files retrieved"L, counters.newBootFilesRetrieved]; END; PrintMaybe: PROCEDURE [wh: Window.Handle, s: STRING, n: LONG INTEGER] = BEGIN IF n = 0 THEN RETURN; Put.LongNumber[wh, n, [10, FALSE, TRUE, 10]]; Put.Text[wh, " "L]; Put.Text[wh, s]; Put.CR[wh]; END; Table: FormSW.ProcType = BEGIN Stop: ERROR = CODE; PrintOne: PROCEDURE [bf: LONG POINTER TO BootServerInfo.Info] = BEGIN pages: CARDINAL; IF UserInput.UserAbort[log] THEN ERROR Stop; BEGIN temp: STRING = [30]; BootServer.AppendBFN[temp, bf.bfn]; FOR i: CARDINAL IN [temp.length..12) DO Put.Char[log, ' ]; ENDLOOP; Put.Text[log, temp]; END; pages ← Inline.LowHalf[ (bf.bytes + Environment.bytesPerPage - 1)/Environment.bytesPerPage]; Put.Number[log, pages, [10, FALSE, TRUE, 5]]; Put.LongNumber[log, bf.count, [10, FALSE, TRUE, 6]]; IF bf.count = 0 THEN Put.Text[log, " "L] ELSE Put.LongNumber[log, bf.ms/bf.count, [10, FALSE, TRUE, 6]]; Put.Text[log, " "L]; SELECT TRUE FROM bf.bytes = 0 => Put.Text[log, "Not on this disk "L]; (bf.create = System.gmtEpoch) => Put.Text[log, "Unknown "L]; ENDCASE => Put.Date[log, bf.create, dateTime]; SELECT bf.machineType FROM alto => Put.Text[log, " Alto "L]; d0 => Put.Text[log, " D0 "L]; dorado => Put.Text[log, " Dorado "L]; dLion => Put.Text[log, " DLion "L]; dLionTrident => Put.Text[log, " DLionTri"L]; dicentra => Put.Text[log, " Dicentra"L]; dove => Put.Text[log, " Dove"L]; other => Put.Text[log, " Other"L]; ENDCASE => Put.Text[log, " ?? "L]; SELECT bf.fileType FROM microcode => Put.Text[log, " M"L]; germ => Put.Text[log, " G"L]; boot => Put.Text[log, " B"L]; pup => Put.Text[log, " P"L]; ENDCASE => Put.Text[log, " ?"L]; Put.Text[log, " "L]; Put.Text[log, bf.fileName]; Put.CR[log]; DoSomeYields[]; END; errFlag: BOOLEAN ← FALSE; remoteAddr: System.NetworkAddress; fileName: STRING = [100]; Put.CR[log]; PrintHeader[log, "Boot File Table on "L]; WriteString[remoteAddress]; WriteString[" = "L]; remoteAddr ← GetAddress[remoteAddress, System.nullSocketNumber ! Trouble => BEGIN WriteString["AddressTranslation troubles: "L]; WriteLine[reason]; errFlag ← TRUE; CONTINUE; END]; IF errFlag THEN RETURN; WriteNetworkAddressVerbose[remoteAddr]; WriteLine["."L]; Put.Line[log, " Code Pgs Count AvgMs Create Time FileName"L]; BootServerInfo.EnumerateBootTable[remoteAddr, PrintOne ! Stop => CONTINUE; BootServerInfo.Error => BEGIN Put.Text[log, "Oops: "L]; Put.Text[log, reason]; Put.Line[log, "."L]; CONTINUE; END; ]; END; PrintHeader: PROCEDURE [wh: Window.Handle, s: STRING] = BEGIN Put.CR[wh]; Put.Date[wh, Time.Current[], dateTime]; Put.Text[wh, " "L]; Put.Text[wh, s]; END; DoSomeYields: PROCEDURE = BEGIN THROUGH [0..100) DO Process.Yield[]; ENDLOOP; END; MakeSWs: Tool.MakeSWsProc = BEGIN logFileName: STRING = [40]; Tool.UnusedLogName[logFileName, "BootServerInfo.log$"L]; form ← Tool.MakeFormSW[window: window, formProc: MakeForm]; log ← Tool.MakeFileSW[window: window, name: logFileName, allowTypeIn: FALSE]; END; MakeForm: FormSW.ClientItemsProcType = BEGIN nParams: CARDINAL = 4; items ← FormSW.AllocateItemDescriptor[nParams]; items[0] ← FormSW.CommandItem[tag: "Find"L, proc: FindServers, place: FormSW.newLine]; items[1] ← FormSW.CommandItem[tag: "Info"L, proc: Info]; items[2] ← FormSW.CommandItem[tag: "Table"L, proc: Table]; items[3] ← FormSW.StringItem[tag: "Target"L, string: @remoteAddress, inHeap: TRUE]; RETURN[items, TRUE]; END; ClientTransition: ToolWindow.TransitionProcType = BEGIN IF new = inactive THEN BEGIN form ← log ← NIL; END; END; WriteCR: PROCEDURE = BEGIN Put.CR[log]; END; WriteString: PROCEDURE [s: LONG STRING] = BEGIN Put.Text[log, s]; END; WriteLine: PROCEDURE [s: LONG STRING] = BEGIN Put.Line[log, s]; END; WriteNetworkAddressVerbose: PROCEDURE [address: System.NetworkAddress] = BEGIN temp: STRING = [100]; Append: PROCEDURE [s: LONG STRING, clientData: LONG POINTER] = BEGIN String.AppendString[temp, s]; END; Format.NetworkAddress[Append, address, octal]; String.AppendString[temp, " = "L]; Format.NetworkAddress[Append, address, productSoftware]; Put.Text[log, temp]; END; Trouble: ERROR [reason: LONG STRING] = CODE; GetAddress: PROCEDURE [host: LONG STRING, socket: System.SocketNumber] RETURNS [addr: System.NetworkAddress] = BEGIN localFailed: BOOLEAN ← FALSE; IF host = NIL THEN ERROR Trouble["NIL => Address Fault"L]; addr ← Unformat.NetworkAddress[host, octal ! Unformat.Error => BEGIN localFailed ← TRUE; CONTINUE; END ]; IF localFailed THEN BEGIN addr ← AddressTranslation.StringToNetworkAddress[host ! AddressTranslation.Error => BEGIN temp: STRING = [200]; proc: Format.StringProc = {String.AppendString[temp, s]}; AddressTranslation.PrintError[errorRecord, proc]; ERROR Trouble[temp]; END].addr; addr.socket ← socket; -- CH returns trash in socket END; IF addr.socket = System.nullSocketNumber THEN addr.socket ← socket; END; Init[]; END.