// IfsTelnetStat.bcpl -- IFS system statistics commands
// Copyright Xerox Corporation 1979, 1980, 1981
// Last modified November 12, 1981  5:30 PM by Taft

get "Ifs.decl"
get "IfsSystemInfo.decl"
get "IfsRs.decl"
get "IfsFiles.decl"
get "Disks.d"
get "Tfs.d"
get "Pup0.decl"
get "Pup1.decl"

external
[
// outgoing procedures
ExecSystat; ExecDskStat; ExecStatistics; TotalFreePages; ExecDayTime

// incoming procedures
LeafSystat; MemStatistics; DiskStatistics; DirStatistics; MailStatus
ServStatistics
ReadDIF; ReadCalendar; ActiveJobs; Plural; WRITEUDT; PrintPort
TerminatingChar; SelectKeyword
Puts; Wss; Ws; PutTemplate; SysFree; Zero; MoveBlock
DoubleAdd; DoubleSubtract; Div
VFileReadPage

// incoming statics
dsp; CtxRunning; primaryIFS
jobT; maxJobs; lenJobT; leafPresent; infoVMD
]

//---------------------------------------------------------------------------
let ExecDskStat(cs) be
//---------------------------------------------------------------------------
[
let dif = ReadDIF(CtxRunning>>RSCtx.userInfo>>UserInfo.connName)
if dif ne 0 then
   [
   PutTemplate(dsp, "*n$UED pages used out of $UED in directory <$S>.",
    lv dif>>DIF.diskPageUsage, lv dif>>DIF.diskPageLimit,
    CtxRunning>>RSCtx.userInfo>>UserInfo.connName)
   SysFree(dif)
   ]
let free, used = vec 1, vec 1
TotalFreePages(primaryIFS, free, used)
DoubleSubtract(used, free)
PutTemplate(dsp, "*n$ED pages used, $ED left in the system.", used, free)
]

//---------------------------------------------------------------------------
and TotalFreePages(fs, pFree, pTotal; numargs na) be
//---------------------------------------------------------------------------
// Returns in the doubleword pointed to be pFree the total number of
// free pages in the file system fs.  If pTotal supplied, also returns
// the total size of the file system in the doubleword pointed to by pTotal.
[
let foo = nil  // cell after na
if na ls 3 then pTotal = lv na
Zero(pFree, 2); Zero(pTotal, 2)
let pagesH, pagesL = 0, nil
for unit = 0 to fs>>IFS.numUnits-1 do
   [
   let kdh = fs>>IFS.lpdt↑unit>>DSK.diskKd
   pagesL = kdh>>KDH.freePages
   DoubleAdd(pFree, lv pagesH)
   pagesL = kdh>>TFSKD.nVTracks * kdh>>KDH.nHeads * kdh>>KDH.nSectors
   DoubleAdd(pTotal, lv pagesH)
   ]
]

//---------------------------------------------------------------------------
and ExecSystat(cs) be
//---------------------------------------------------------------------------
[
let now = vec 1
ReadCalendar(now)
DoubleSubtract(now, lv VFileReadPage(infoVMD, spPage)>>SysParams.ifsStartTime)
let seconds = nil
let hours = Div(now, 3600, lv seconds)
let users = ActiveJobs()
PutTemplate(dsp, "*nIFS up $D:$2F0D:$2F0D, $D user$S out of $D.",
 hours, seconds/60, seconds rem 60, users, Plural(users), maxJobs)
for i = 0 to lenJobT-1 do
   [
   let ctx = jobT>>JobT↑i
   if ctx ne 0 then
      [
      let name = ctx>>RSCtx.userInfo
      if name ne 0 then name = name>>UserInfo.userName
      if name eq 0 then name = "Not logged in"
      Puts(dsp, $*n); Ws(name)
      for j = name>>String.length to 15 do Puts(dsp, $*s)
      Ws(selecton ctx>>RSCtx.type into
         [
         case jobTypeFTP:           " FTP   "
         case jobTypeMTP:           " MTP   "
         case jobTypeTelnet:        " Telnet"
         case jobTypeBackup:        " Backup"
         case jobTypeMail:          " Mail  "
         case jobTypeMiscellaneous: " Misc. "
         case jobTypeLeaf:          " Leaf  "
         case jobTypePress:         " Press "
         case jobTypeNameUpdate:    " NameUp"
         case jobTypeBootUpdate:    " BootUp"
         case jobTypeCopyDisk:      " CpyDsk"
         default:                   " ??    "
         ])
      if ctx>>RSCtx.bspSoc ne 0 then
         [
         let port = vec lenPort
         MoveBlock(port, lv ctx>>RSCtx.bspSoc>>PupSoc.frnPort, lenPort)
         port>>Port.socket↑1 = 0; port>>Port.socket↑2 = 0
         Ws(" ["); PrintPort(dsp, port); Puts(dsp, $])
         ]
      ]
   ]
if leafPresent then LeafSystat();
]

//---------------------------------------------------------------------------
and ExecStatistics(cs) be
//---------------------------------------------------------------------------
[
test TerminatingChar(cs) eq $*n
   ifso
      [
      MemStatistics(); DiskStatistics(); DirStatistics();
      ServStatistics(); MailStatus()
      ]
   ifnot
      [
      Wss(cs, " (for)")
      switchon SelectKeyword(cs, "Memory", "Disk", "Directory",
       "Mail", "Servers") into
         [
         case 1: MemStatistics(); endcase
         case 2: DiskStatistics(); endcase
         case 3: DirStatistics(); endcase
         case 4: MailStatus(); endcase
         case 5: ServStatistics(); endcase
         ]
      ]
]

//---------------------------------------------------------------------------
and ExecDayTime(cs) be
//---------------------------------------------------------------------------
[
Ws(" = ")
WRITEUDT(dsp, 0, true)
]