// IfsTelnetInit1.bcpl -- once-only initialization for IFS server telnet
// Copyright Xerox Corporation 1979, 1980
// Last modified April 19, 1980  6:01 PM by Taft

get "Pup0.decl"
get "Pup1.decl"
get "IfsRs.decl"
get "IfsTelnet.decl"
get "Streams.d"

external
[
// outgoing procedures
InitTelnet

// incoming procedures
TelnetGets; TelnetEndofs; TelnetResetIn; TelnetPuts; TelnetResetOut
TelnetTopLevel; TelnetEvent
CreateKeywordTable; InsertKeyword
ExecLogin; ExecLogout; ExecConnect; ExecEnable; ExecDisable; ExecMail
ExecSystat; ExecStatistics; ExecDskStat; ExecList; ExecDelete; ExecRename
ExecCreate; ExecDestroy; ExecShow; ExecChange; ExecHalt; ExecDirectory
ExecBackup; ExecInitialize; ExecExtend; ExecWhat; ExecDayTime
ExecPress; ExecShowPress
OpenLevel1Socket; CreateEvent
Enqueue; Puts; Allocate; SetBlock; Zero; SysErr
ExtractSubstring;

// outgoing statics
noLoginKT; loginKT; enableKT
atSubPrompt; bangSubPrompt; pluralString; singularString;

// incoming statics
sysZone; keys; dsp; rsQ
]

static [ noLoginKT; loginKT; enableKT ]
static [ atSubPrompt; bangSubPrompt; pluralString; singularString; ]

manifest
[
// control bits for keyword insertion
noLogin = 1
login = 2
enable = 4
]

//---------------------------------------------------------------------------
let InitTelnet() be
//---------------------------------------------------------------------------
// Initializes Telnet-related data structures and
//  registers the Telnet socket with the rendezvous socket manager.
[
// Build the telnet input and output streams
keys = Allocate(sysZone, 2*lST); SetBlock(keys, SysErr, 2*lST)
keys>>ST.gets = TelnetGets
keys>>ST.endof = TelnetEndofs
keys>>ST.reset = TelnetResetIn
dsp = keys+lST
dsp>>ST.puts = TelnetPuts
dsp>>ST.reset = TelnetResetOut

// Create top-level command keyword tables
noLoginKT = CreateKeywordTable(5)
loginKT = CreateKeywordTable(17)
enableKT = CreateKeywordTable(26)

TopKeyword("Login", ExecLogin, noLogin)
TopKeyword("Quit", ExecLogout, noLogin+login+enable)
TopKeyword("Systat", ExecSystat, noLogin+login+enable)
TopKeyword("Statistics", ExecStatistics, noLogin+login+enable)
TopKeyword("DayTime", ExecDayTime, noLogin+login+enable)

TopKeyword("Logout", ExecLogout, login+enable)
TopKeyword("Connect", ExecConnect, login+enable)
TopKeyword("Directory", ExecDirectory, login+enable)
TopKeyword("DskStat", ExecDskStat, login+enable)
TopKeyword("List", ExecList, login+enable)
TopKeyword("Delete", ExecDelete, login+enable)
TopKeyword("Rename", ExecRename, login+enable)
TopKeyword("Press", ExecPress, login+enable)
TopKeyword("Print", ExecPress, login+enable)
TopKeyword("Show", ExecShow, login+enable)
TopKeyword("Change", ExecChange, login+enable)
TopKeyword("Enable", ExecEnable, login+enable)
TopKeyword("Cancel", ExecShowPress, login+enable)

TopKeyword("Disable", ExecDisable, enable)
TopKeyword("Create", ExecCreate, enable)
TopKeyword("Destroy", ExecDestroy, enable)
TopKeyword("Halt", ExecHalt, enable)
TopKeyword("Initialize", ExecInitialize, enable)
TopKeyword("Extend", ExecExtend, enable)
TopKeyword("Backup", ExecBackup, enable)
TopKeyword("Mail", ExecMail, enable)
TopKeyword("What", ExecWhat, enable)

// InitTelnet (cont'd)

// Set up the string statics used by the server ctx.
singularString = ExtractSubstring("");
pluralString = ExtractSubstring("s");
bangSubPrompt = ExtractSubstring("*n!!");
atSubPrompt = ExtractSubstring("*n@@");

// Register the telnet rendezvous socket with the socket manager
let rs = Allocate(sysZone, lenRS); Zero(rs, lenRS)
rs>>RS.proc = TelnetTopLevel
rs>>RS.soc = Allocate(sysZone, lenPupSoc)
OpenLevel1Socket(rs>>RS.soc, table [ 0; 0; socketTelnet ])
rs>>RS.extraSpace = lenTCtx-3
rs>>RS.type = jobTypeTelnet
Enqueue(rsQ, rs)

// Fire up the telnet processing task as a periodic event
CreateEvent(TelnetEvent)
]

//---------------------------------------------------------------------------
and TopKeyword(key, Proc, control) be
//---------------------------------------------------------------------------
// Inserts key and Proc into the appropriate top-level keyword tables
//  according to the control parameter.
[
if (control&noLogin) ne 0 then InsertKeyword(noLoginKT, key)!0 = Proc
if (control&login) ne 0 then InsertKeyword(loginKT, key)!0 = Proc
if (control&enable) ne 0 then InsertKeyword(enableKT, key)!0 = Proc
]