// IfsTelnetSysParam2.bcpl -- System parameters maintenance
// Copyright Xerox Corporation 1979, 1980, 1981, 1982
// Last modified July 24, 1982  5:23 PM by Taft

get "Pup0.decl"
get "Pup1.decl"  // needed by IfsBootServ.decl
get Lock from "Ifs.decl"
get "IfsSystemInfo.decl"
get Protection, world from "IfsFiles.decl"
get RSCtx from "IfsRS.decl"
get "IfsInit.decl"
// there are also some "gets" in the code below

external
[
// outgoing procedures
ExecChangeSysParam; ExecShowSysParams; InstallSysParams

// incoming procedures
SysParamSubcommand; GetGroupName
ResetTimeServ; EnableTimeServ; EnableNameServ; InitCachedDIF
EnableBootServ; EnablePress; EnableLeaf; EnableCopyDisk; EnableLookupFileServ
InitJobPolicyControls
CreateKeywordIntegerMap; DestroyKeywordTable
TelnetCommandLoop; TelnetSubcommandPrompt
VFileReadPage; VFileWritePage; LockCell; UnlockCell; ResetStrings
MoveBlock; Mul; Umin
DoubleAdd; DoubleSubtract; FreePointer; ExtractSubstring
PutTemplate; Ws; SysFree

// incoming statics
maxJobs; lenJobT; infoVMD; leafEnabled; leafPresent; cdrs; isb; ClockSecond
enablePasswordLog; enableGrapevineAuth; enableGrapevineGroup; defaultRegistry
@bs; @ns; @ts; @pps; @lfs
dsp; CtxRunning
]

//---------------------------------------------------------------------------
let ExecChangeSysParam(cs) be
//---------------------------------------------------------------------------
[
let kt = CreateKeywordIntegerMap("Quit", "Server-Limit", "Clock-Correction",
 "Reset-Time", "Group-Name", "World", "Default-Registry",
 "Enable", "Disable")
ResetStrings()

let sp = VFileWritePage(infoVMD, spPage)
LockCell(lv sp)

TelnetCommandLoop(kt, TelnetSubcommandPrompt(), true, sp, 0, 0,
 SysParamSubcommand)

UnlockCell(lv sp)
DestroyKeywordTable(kt)
]

//---------------------------------------------------------------------------
and ExecShowSysParams() be
//---------------------------------------------------------------------------
[
PutTemplate(dsp, "*nServer-limit: $D; lenJobT: $D", maxJobs, lenJobT)
let corr = VFileReadPage(infoVMD, spPage)>>SysParams.clockCorrection
PutTemplate(dsp, "*nClock correction: $S$D seconds/day",
 (corr ls 0? "", "+"), corr)

// "get" files are enclosed in local scopes because they contain
// some conflicting names.
   [
   let foo = nil
   get "IfsBootServ.decl"
   ShowServerEnabled("Boot server", bs>>BS.externalLock eq 0)
   if bs>>BS.externalLock eq 0 then
      ShowServerEnabled("New boot file acquisition", bs>>BS.noNewBootFiles eq 0)
   ]
   [
   let foo = nil
   get "IfsNameServ.decl"
   ShowServerEnabled("Name server", ns>>NS.externalLock eq 0)
   ]
   [
   let foo = nil
   get "IfsTimeServ.decl"
   ShowServerEnabled("Time server", ts>>TS.externalLock eq 0)
   ]
   [
   let foo = nil
   get "IfsPress.decl"
   ShowServerEnabled("Press printing", pps>>PPS.enable)
   ]

ShowServerEnabled("Leaf server", leafEnabled)
ShowServerEnabled("CopyDisk server", cdrs ne 0)
ShowServerEnabled("LookupFile server", lfs ne 0)
ShowServerEnabled("Grapevine authentication", enableGrapevineAuth)
ShowServerEnabled("Grapevine group checking", enableGrapevineGroup)
if defaultRegistry ne 0 then
   PutTemplate(dsp, "*nDefault registry: $S", defaultRegistry)
Ws("*n*nProtection group names:")
for group = 0 to size Protection-1 do
   [
   let name = GetGroupName(group)
   if name ne 0 then
      [
      PutTemplate(dsp, "*n  $2D  $S", group, name)
      SysFree(name)
      if group eq offset Protection.world & enableGrapevineGroup then
         [
         name = GetGroupName(size Protection)
         if name ne 0 then
            [ PutTemplate(dsp, " = $S", name); SysFree(name) ]
         ]
      ]
   ]
]

//---------------------------------------------------------------------------
and ShowServerEnabled(name, flag) be
//---------------------------------------------------------------------------
   PutTemplate(dsp, "*n$S is $Sabled", name, (flag? "en", "dis"))

//---------------------------------------------------------------------------
and InstallSysParams(init) be
//---------------------------------------------------------------------------
// This isn't really the right place for this, but where would you put it?
// Installs system parameters from <System>Info into the running system.
// init = true if being called from startup-time initialization,
// false if being called from Change System-parameters command.
[
// Set various system cells
let sp = VFileReadPage(infoVMD, spPage)
LockCell(lv sp)
if sp>>SysParams.maxJobs eq 0 then
   VFileWritePage(infoVMD, spPage)>>SysParams.maxJobs = maxJobs
maxJobs = Umin(sp>>SysParams.maxJobs, lenJobT)
InitJobPolicyControls()

enablePasswordLog = sp>>SysParams.enablePasswordLog
enableGrapevineAuth = sp>>SysParams.enableGrapevineAuth
enableGrapevineGroup = sp>>SysParams.enableGrapevineGroup
let reg = lv sp>>SysParams.defaultRegistry
reg = reg>>String.length eq 0? 0, ExtractSubstring(reg)
FreePointer(lv defaultRegistry)
defaultRegistry = reg

// Enable or disable servers as appropriate
if init then
   [  // set from <System>Info file only at startup time
   let enableMiscServers = isb>>ISB.enableMiscServers
   EnableTimeServ(sp>>SysParams.enableTimeServ & enableMiscServers)
   EnableNameServ(sp>>SysParams.enableNameServ & enableMiscServers)
   EnableBootServ(sp>>SysParams.enableBootServ & enableMiscServers,
    sp>>SysParams.noNewBootFiles)
   EnablePress(sp>>SysParams.enablePress)
   EnableLeaf(sp>>SysParams.enableLeaf & leafPresent)
   EnableCopyDisk(sp>>SysParams.enableCopyDisk)
   EnableLookupFileServ(sp>>SysParams.enableLookupFileServ)
   ]

// Set nominal ticks/second of 1680000, then correct it by clockCorr,
// which is in units of seconds/day.  1680000/86400 = ~19.
let corr = sp>>SysParams.clockCorrection
MoveBlock(ClockSecond, table [ 25; #121200 ], 2)
let corrV = vec 2
Mul(0, 19, (corr ge 0? corr, -corr), corrV)
(corr ge 0? DoubleSubtract, DoubleAdd)(ClockSecond, corrV)
UnlockCell(lv sp)
]