// IfsMailCommand.bcpl -- telnet interface to mail system
// Copyright Xerox Corporation 1980, 1981
// Last modified November 14, 1981  10:41 AM by Taft

get "Ifs.decl"
get "IfsSystemInfo.decl"
get "IfsRs.decl"
get "IfsMail.decl"
get "Pup0.decl"

external
[
// outgoing procedures
ExecMail

// incoming procedures
MailStatus; InitMailStats
CreateKeywordTable; InsertKeyword; DestroyKeywordTable
TelnetCommandQuit; TelnetCommandLoop; SelectKeyword
LockCell; UnlockCell; VFileWritePage; VFileReadPage
Enqueue; Unqueue; Free; FreePointer; ExtractSubstring
MoveBlock; Min; Zero; MultEq
Confirm; DefaultPhrase; GetString; EnumeratePupAddresses
Wss; Ws; Errors; PutTemplate; Plural

// incoming statics
mail; infoVMD; dsp; sysZone; socketQ
]

//----------------------------------------------------------------------------
let ExecMail(cs) be
//----------------------------------------------------------------------------
[
let kt = CreateKeywordTable(9)
InsertKeyword(kt, "Dead-Letter")!0 = 1
InsertKeyword(kt, "Distribution-lists")!0 = 2
InsertKeyword(kt, "Disable")!0 = 3
InsertKeyword(kt, "Enable")!0 = 4
InsertKeyword(kt, "Grapevine")!0 = 5
InsertKeyword(kt, "Quit")!0 = 6
InsertKeyword(kt, "Registry")!0 = 7
InsertKeyword(kt, "Reset")!0 = 8
InsertKeyword(kt, "Status")!0 = 9

TelnetCommandLoop(kt, "*N**", 0, 0, 0, 0, MailSubCommand)

DestroyKeywordTable(kt)
]

//----------------------------------------------------------------------------
and MailString(cs, prompt, msOffset, nil; numargs na) = valof
//----------------------------------------------------------------------------
// 3-argument form installs new string in MS page.
// 4-argument form simply returns the new string.
[
PutTemplate(cs, " ($S) ", prompt)
let ms = VFileWritePage(infoVMD, msPage)
LockCell(lv ms)
DefaultPhrase(cs, ms+msOffset)
UnlockCell(lv ms)
let name = GetString(cs, 0, Wss, prompt)
name>>String.length = Min(name>>String.length, maxMailParamChars)
test na eq 3
   ifso
      [
      ms = VFileWritePage(infoVMD, msPage)
      MoveBlock(ms+msOffset, name, name>>String.length rshift 1 +1)
      Free(sysZone, name)
      ]
   ifnot
      resultis name
]

//----------------------------------------------------------------------------
and MailSubCommand(cs, entry, nil) be
//----------------------------------------------------------------------------
switchon entry!0 into
   [
   case 1:  // Dead-letter
      MailString(cs, "recipient name", offset MS.deadLtr/16)
      endcase
   case 2:  // Distribution-lists
      MailString(cs, "directory name", offset MS.nameDirDL/16)
      endcase
   case 3:  // Disable
   case 4:  // Enable
      [
      let enable = entry!0 eq 4
      Wss(cs, " (mail)")
      let which = SelectKeyword(cs, "system",
       (mail>>Mail.enabled? "forwarding", 0))
      if Confirm(cs) then
         [
         let ms = VFileWritePage(infoVMD, msPage)
         // don't bother to LockCell because none of the following can Block
         switchon which into
            [
            case 1:  // system
               if mail>>Mail.enabled eq 0 & enable then
                  Enqueue(socketQ, mail>>Mail.rs>>RS.soc)
               if mail>>Mail.enabled ne 0 & not enable then
                  Unqueue(socketQ, mail>>Mail.rs>>RS.soc)
               mail>>Mail.enabled = enable
               ms>>MS.enabled = enable
               endcase
            case 2:  // forwarding
               mail>>Mail.forward = enable
               ms>>MS.forward = enable
               endcase
            ]
         ]
      endcase
      ]
   case 5:  // Grapevine
      [
      let name = MailString(cs, "server name", offset MS.gvName/16, nil)
      let port = vec lenPort
      if name>>String.length ne 0 then
         unless EnumeratePupAddresses(name, 0, port) eq 0 &
          port>>Port.net ne 0 &
          MultEq(lv port>>Port.socket, table [ 0; socketMail ]) do
            [ Free(sysZone, name); Errors(cs, 0) ]
      MoveBlock(lv VFileWritePage(infoVMD, msPage)>>MS.gvName, name,
       name>>String.length rshift 1 +1)
      Free(sysZone, name)
      endcase
      ]
   case 6:  // Quit
      TelnetCommandQuit(cs)
   case 7:  // Registry
      MailString(cs, "we are part of", offset MS.registry/16)
      endcase
   case 8:  // Reset
      Ws(" (mail statistics)")
      if Confirm(cs) then
         [
         let ms = VFileWritePage(infoVMD, msPage)
         LockCell(lv ms); InitMailStats(ms); UnlockCell(lv ms)
         ]
      endcase
   case 9:  // Status
      MailStatus()
      endcase
   ]