// GateConBoot.bcpl -- talks to the Boot server // Last modified March 6, 1979 10:39 PM by Boggs get "Pup0.decl" get "Pup1.decl" get "PupBootServ.decl" external [ // outgoing procedures CreateBootCtx; RestartBoot; Boot; BootSummary // incoming procedures OpenLevel1Socket; CloseLevel1Socket GetBuf; CompletePup; ReleasePBI Zero; MoveBlock; ReturnFrom Allocate; Free; Enqueue; Dequeue; Noop InitializeContext; Block; SetTimer; TimerHasExpired Ws; Wss; PutTemplate; UNPACKDT; WRITEUDT; Confirm TopLevel; ResetCmdMenu; CreateCmdBox; BoxProc SendCommand; MiscCmd // incoming statics dsp; sysZone; ctxQ; gcHost; oldStatsQ; wheel ] static @bu structure BU: // bu -> this 'global frame' for this module [ soc word // -> PupSoc stats word // -> Boot Server Stats block timer word // update stats when this expires ] manifest lenBU = size BU/16 //---------------------------------------------------------------------------- let CreateBootCtx() be //---------------------------------------------------------------------------- [ Enqueue(ctxQ, InitializeContext(Allocate(sysZone, 150), 150, BootCtx)) bu = Allocate(sysZone, lenBU); Zero(bu, lenBU) bu>>BU.soc = Allocate(sysZone, lenPupSoc); OpenLevel1Socket(bu>>BU.soc) ] //---------------------------------------------------------------------------- and RestartBoot() be //---------------------------------------------------------------------------- [ SetTimer(lv bu>>BU.timer, 0) if bu>>BU.stats ne 0 then [ Enqueue(oldStatsQ, bu>>BU.stats); bu>>BU.stats = 0 ] ] //---------------------------------------------------------------------------- and Boot() be //---------------------------------------------------------------------------- [ ResetCmdMenu() CreateCmdBox(TopLevel, "TopLevel") CreateCmdBox(BootDirectory, "BootDir") if gcHost ne 0 then [ CreateCmdBox(BootStats, "BootStats") if wheel then [ CreateCmdBox(BootLock, "Lock") CreateCmdBox(BootUnlock, "Unlock") ] ] // ResetCmdMenu destroyed the BoxQ which BoxProc is following. // If we just return now, BoxProc will get horribly confused. // So don't let it continue: force a return from BoxProc. ReturnFrom(BoxProc) ] //---------------------------------------------------------------------------- and BootSummary(stream) be //---------------------------------------------------------------------------- [ if bu>>BU.stats ne 0 then PutTemplate(stream, "Boot: $EUD ", lv bu>>BU.stats>>Stats.fastSends) ] //---------------------------------------------------------------------------- and BootCtx(ctx) be //a context //---------------------------------------------------------------------------- [ Block() repeatuntil TimerHasExpired(lv bu>>BU.timer) & gcHost ne 0 SetTimer(lv bu>>BU.timer, 1000) // 10 sec let pbi = GetBuf(bu>>BU.soc) pbi>>PBI.pup.dPort.socket^2 = psMiscServ pbi = SendCommand(pbi, ptBootStatsRequest, pupOvBytes, (bu>>BU.stats? 1, 3)) if pbi ne 0 then [ let stats = lv pbi>>PBI.pup.words if pbi>>PBI.pup.type eq ptBootStatsReply & stats>>Stats.version eq bootStatsVersion then [ if bu>>BU.stats then Enqueue(oldStatsQ, bu>>BU.stats) let lenStatBlock = (pbi>>PBI.pup.length-pupOvBytes+1)/2 bu>>BU.stats = Allocate(sysZone, lenStatBlock) MoveBlock(bu>>BU.stats, stats, lenStatBlock) ] ReleasePBI(pbi) ] ] repeat //---------------------------------------------------------------------------- and BootStats() be //---------------------------------------------------------------------------- [ let oldStats = bu>>BU.stats SetTimer(lv bu>>BU.timer, 0) let timer = nil; SetTimer(lv timer, 500) Block() repeatuntil TimerHasExpired(lv timer) % bu>>BU.stats ne oldStats test bu>>BU.stats ne oldStats ifso Ws("*NBoot Server stats:") ifnot [ Ws("*NThe Boot Server doesn't answer.") if bu>>BU.stats ne 0 then Ws("*NWhen last heard from its stats were:") ] if bu>>BU.stats ne 0 then PutTemplate(dsp, "*NDirs sent: $EUD Files Rcvd: $EUD Fast Sends: $EUD Slow sends: $EUD", lv bu>>BU.stats>>Stats.dirsSent, lv bu>>BU.stats>>Stats.filesRcvd, lv bu>>BU.stats>>Stats.fastSends, lv bu>>BU.stats>>Stats.slowSends) ] //---------------------------------------------------------------------------- and BootDirectory() be //---------------------------------------------------------------------------- [ let soc = vec lenPupSoc; OpenLevel1Socket(soc) let pbi = GetBuf(soc) pbi>>PBI.pup.dPort.socket^2 = psMiscServ pbi = SendCommand(pbi, ptBootDirRequest, pupOvBytes, 1) if pbi then Enqueue(lv soc>>PupSoc.iQ, pbi) let timer = nil; SetTimer(lv timer, 200) // 2 seconds [ Block() repeatuntil soc>>PupSoc.iQ.head ne 0 % TimerHasExpired(lv timer) let pbi = Dequeue(lv soc>>PupSoc.iQ.head); if pbi eq 0 break if pbi>>PBI.pup.type eq ptBootDirReply then [ let ptr = 1 while ptr ls (pbi>>PBI.pup.length-pupOvBytes)/2 do [ let bfd = lv pbi>>PBI.pup.words^ptr PutTemplate(dsp, "*N$S, bfn = $UO, created ", lv bfd>>BFD.name, bfd>>BFD.bfn) let utv = vec 7; UNPACKDT(lv bfd>>BFD.date, utv); WRITEUDT(dsp, utv) ptr = ptr + lenBFD + bfd>>BFD.name.length rshift 1 +1 ] ] ReleasePBI(pbi) ] repeat CloseLevel1Socket(soc) ] //---------------------------------------------------------------------------- and BootLock() be if Confirm("*NLock Boot server") then //---------------------------------------------------------------------------- MiscCmd(ptBootLockRequest, ptBootLockReply, Noop) //---------------------------------------------------------------------------- and BootUnlock() be MiscCmd(ptBootUnlockRequest, ptBootUnlockReply, Noop) //----------------------------------------------------------------------------