// IfsTimeServ.bcpl - Pup Time Server, main-line code
//  Adapted from PupTimeServ.bcpl, the time server used in gateways
// Copyright Xerox Corporation 1979, 1981
// Last modified November 1, 1981  1:03 PM by Taft

get "pup0.decl"
get "pup1.decl"
get "IfsTimeServ.decl"

external
[
// outgoing procedures
TimeServ; GetTime

// incoming procedures
ResetTimeServ; EnableTimeServ
ExchangePorts; CompletePup; ReleasePBI
ReadCalendar; MoveBlock; DoubleIncrement

// outgoing statics
@ts
]

static @ts

//----------------------------------------------------------------------------
let TimeServ(pbi) be
//----------------------------------------------------------------------------
// Called from Misc Server, pbi contains a time protocol Pup
[
ExchangePorts(pbi)
switchon pbi>>PBI.pup.type into
   [
   case ptAltoTimeRequest:
      // reject request if don't know time.  Reject broadcast request if
      // time server is disabled, but accept non-broadcast request.
      if ts>>TS.dontKnowTime %
       (ts>>TS.externalLock & pbi>>PBI.pup.sPort.host eq 0) then endcase
      ReadCalendar(lv pbi>>PBI.pup.words↑1)
      MoveBlock(lv pbi>>PBI.pup.words↑3, lv ts>>TS.timeParams, 3)
      CompletePup(pbi, ptAltoTimeReply, pupOvBytes+10)
      DoubleIncrement(lv ts>>TS.stats.altoReqs)
      return
   case ptTimeStatsRequest:
      MoveBlock(lv pbi>>PBI.pup.words, lv ts>>TS.stats, size Stats/16)
      CompletePup(pbi, ptTimeStatsReply, pupOvBytes+size Stats/8)
      return
   case ptLockTimeRequest:
      unless pbi>>PBI.pup.id↑1 eq 27182 & pbi>>PBI.pup.sPort.host ne 0 endcase
      EnableTimeServ(false)
      CompletePup(pbi, ptLockTimeReply, pupOvBytes)
      return
   case ptResetTimeRequest:
      unless pbi>>PBI.pup.id↑1 eq 27182 & pbi>>PBI.pup.sPort.host ne 0 endcase
      EnableTimeServ(true)
      ResetTimeServ(lv pbi>>PBI.pup.words)
      CompletePup(pbi, ptResetTimeReply, pupOvBytes)
      return
   ]
ReleasePBI(pbi)  // Failure: discard the Pup.
]

//----------------------------------------------------------------------------
and GetTime(time) = valof
//----------------------------------------------------------------------------
[
ReadCalendar(time)
resultis ts>>TS.dontKnowTime eq 0
]