// DLSBackground.bcpl -- Background processes for DLS control // Last modified May 17, 1982 1:55 PM by Taft // Last modified November 14, 1983 11:17 AM by Diebert get "DLSDriver.decl" get "Pup.decl" get "DLSControl.decl" get "AltoDefs.d" external [ // Procedures defined herein DLSBackground; AltoCommand; StatusBackground; DspPuts; WizardMode // Procedures defined elsewhere GetString; Confirm; Error; Disconnect; DLSOutputEmpty; UpdateCarrierOn; CounterJunta; HangUp Enqueue; Unqueue; SetTimer; TimerHasExpired; Dismiss; Block; PutTemplate; Gets; Puts; Endofs; Closes; Ws; Wss; Wns; Allocate; Free; Zero; SetBlock; Noop; SimpleDspResetLine; SimpleDspSetLinePos; GetNumber; ControlOut CloseBSPSocket; BSPForceOutput // Statics defined herein //savedDCBHead; stDis; displayTimeout; keyDsp; postedNotice // Statics defined elsewhere sysZone mainCtx // Pointer to Q of non-interrupt contexts ctxTable // Table of contexts, indexed by line # @lbTable // DLS line block table dsp logstream crlf nPBI dlsInputOverflows ] static [ //stDis // Status display stream //displayTimeout // Timeout for turning off display //savedDCBHead // Place to save head of DCB chain //keyDsp // Special Alto keyboard/display stream postedNotice ] // --------------------------------------------------------------------------- let WizardMode(ctx, tstr) be // --------------------------------------------------------------------------- // Task to process commands from the network [ let dlb = ctx>>CTX.dlb Wss(tstr, "*n*l? Broadcast, Display status, Post Notice, Quit, Remove Notice, ShutDown*n*l") [ // repeat Wss(tstr, "W>") // Prompt let char = Gets(tstr) switchon char into [ case $Q: case $q: Wss(tstr, "Quit out of wizard mode [confirm] ") if Confirm(tstr) then return endcase case $S: case $s: Wss(tstr, "Shutdown DLS [confirm] ") if Confirm(tstr) then ShutDown(ctx, tstr) endcase case $B: case $b: [ Wss(tstr, "Broadcast message") let string = GetMessage(tstr) if string ne 0 then [ BroadcastMessage(tstr, string); Free(sysZone, string) ] Wss(tstr, crlf) endcase ] case $D: case $d: [ Wss(tstr, "Display Status*n*l") PutTemplate(tstr, "Number of PBI's = $D*n*lNumber of Input Buffer Overflows = $UD*n*l*n*l", nPBI, dlsInputOverflows) Wss(tstr, " 0 1 2 3 4 5 6 7*n*l") for i = 0 to numLines - 1 by 8 do [ PutTemplate(tstr, " $D ", i/8) for j = 0 to 7 do [ let ctx = ctxTable!(i + j) let dlb = lbTable!(i + j) test dlb>>LBH.lineType eq ltLog ifso Wss(tstr, " Log") ifnot Wss(tstr, (dlb>>LBH.lineType ls ltData? " -- ", selecton ctx>>CTX.lineState into [ case lineStateOff: " Off" case lineStateOn: " On " case lineStateActive: " Act" case lineStateRemote: " Rem" case lineStateDialOut: " Out" ])) ] Wss(tstr, "*n*l") ] Wss(tstr, "*n*l Line Name*n*l") for i = 0 to numLines - 1 do [ let ctx = ctxTable!i if ctx ne 0 then if ctx>>CTX.name ne 0 then PutTemplate(tstr, " $3O $S*n*l", ctx>>CTX.dlb>>DLB.line, ctx>>CTX.name) ] endcase ] case $P: case $p: [ Wss(tstr, "Post signon message") let string = GetMessage(tstr) if string ne 0 then [ if postedNotice ne 0 then Free(sysZone, postedNotice) postedNotice = string ] endcase ] case $R: case $r: Wss(tstr, "Remove posted notice [confirm]") if Confirm(tstr) & postedNotice ne 0 then [ Free(sysZone, postedNotice); postedNotice = 0 ] endcase case $?: Wss(tstr, "? Broadcast, Display status, Post Notice, Quit, Remove Notice, ShutDown*n*l") endcase case $*n: Wss(tstr, crlf) endcase default: Error(tstr, " ?*n*l", char) endcase ] ] repeat ] //// --------------------------------------------------------------------------- //and AltoCommand() be //// --------------------------------------------------------------------------- //// Task to process commands from Alto keyboard //[ //Ws("*n**") // Prompt //let char = nil // [ char = Gets(keyDsp); Puts(keyDsp, $*l) ] repeatwhile char eq $*s // //switchon char into // [ // case $Q: case $q: // Ws("Quit [confirm]") // if Confirm(keyDsp) then ShutDown(0, keyDsp) // endcase // // case $B: case $b: // [ // Ws("Broadcast message") // let string = GetMessage(keyDsp) // if string ne 0 then [ BroadcastMessage(keyDsp, string); Free(sysZone, string) ] // endcase // ] // // case $P: case $p: // [ // Ws("Post signon message") // let string = GetMessage(keyDsp) // if string ne 0 then // [ // if postedNotice ne 0 then Free(sysZone, postedNotice) // postedNotice = string // ] // endcase // ] // // case $R: case $r: // Ws("Remove posted notice [confirm]") // if Confirm(keyDsp) & postedNotice ne 0 then // [ Free(sysZone, postedNotice); postedNotice = 0 ] // endcase // // case $?: // Ws("? Broadcast, Post, Quit, Remove") // endcase // // case $*n: // endcase // // default: // Error(keyDsp, " ?*n*l", char) // endcase // ] //] repeat // // --------------------------------------------------------------------------- and GetMessage(strm) = valof // --------------------------------------------------------------------------- [ unless Confirm(strm) resultis 0 Wss(strm, "[end with CR, abort with DEL]*n*l") let string = Allocate(sysZone, 51) test GetString(strm, string, 100) & string>>String.length gr 0 ifso resultis string ifnot [ Free(sysZone, string); resultis 0 ] ] // --------------------------------------------------------------------------- and BroadcastMessage(strm, string) be // --------------------------------------------------------------------------- [ Wss(strm, "*n*lSending to line: ") for i = 0 to numLines-1 do [ let ctx, dlb = ctxTable!i, lbTable!i if dlb>>LBH.lineType ge ltData & (ctx>>CTX.lineState eq lineStateActive % ctx>>CTX.lineState eq lineStateRemote) then [ Unqueue(mainCtx, ctx) // Shut off other sources of output if ctx>>CTX.auxCtx ne 0 then Unqueue(mainCtx, ctx>>CTX.auxCtx) Wss(dlb, "*n*l***********007*n*l> ") Wss(dlb, string) Wss(dlb, "*n*l***********007*n*l") Enqueue(mainCtx, ctx) if ctx>>CTX.auxCtx ne 0 then Enqueue(mainCtx, ctx>>CTX.auxCtx) Wns(strm, i, 3, 8) ] ] ] // --------------------------------------------------------------------------- and ShutDown(ctxIn, strm) be // --------------------------------------------------------------------------- [ Wss(strm, "*nBroadcasting shutdown message...") BSPForceOutput(lv ctxIn>>CTX.socket) BroadcastMessage(strm, "DLS going down now...Goodbye!") Wss(strm, "*nClosing connections...") for i = 0 to numLines-1 do if (lbTable!i)>>LBH.lineType gr ltData then [ let ctx = ctxTable!i if ctx ne ctxIn do [ Unqueue(mainCtx, ctx) if ctx>>CTX.auxCtx ne 0 then Unqueue(mainCtx, ctx>>CTX.auxCtx) if ctx>>CTX.socketOpen then Disconnect(ctx, 500) ] ] Dismiss(10) // 100 ms for last character to go out // Turn off all control signals and set all data lines to marking. SetBlock(dlsOutBase, 1, numLines) if ctxIn ne 0 then if ctxIn>>CTX.socketOpen then [ Wss(strm, "Bye!!*n*l"); CloseBSPSocket(lv ctxIn>>CTX.socket, 500) ] @displayListHead = 0 finish ] //// --------------------------------------------------------------------------- //and DspPuts(str, char) be //// --------------------------------------------------------------------------- //[ //@displayListHead = savedDCBHead // Ensure display is on //SetTimer(lv displayTimeout, 120*100) // Reset activity timer //unless char eq $*l do Puts(dsp, char) //] // //// --------------------------------------------------------------------------- //and StatusBackground() be //// --------------------------------------------------------------------------- //// Periodically updates the terminal status display. //// Also turns off display if no keyboard activity for a long time //[ //if @displayListHead ne 0 then // Do this only if display is on // [ // for i = 1 to stDisLines-1 do // [ // SimpleDspSetLinePos(stDis, i) // SimpleDspResetLine(stDis) // let group = (i-1)*8 // Wns(stDis, group, 2, 8) // for line = group to group+7 do // [ // Block() // let ctx = ctxTable!line // let dlb = lbTable!line // test dlb>>LBH.lineType eq ltLog // ifso Wss(stDis, " Log") // ifnot Wss(stDis, (dlb>>LBH.lineType ls ltData? " -- ", // selecton ctx>>CTX.lineState into // [ // case lineStateOff: " Off" // case lineStateOn: " On " // case lineStateActive: " Act" // case lineStateRemote: " Rem" // case lineStateDialOut: " Out" // ])) // ] // Dismiss(1) // Don't hog the machine // ] // if TimerHasExpired(lv displayTimeout) then @displayListHead = 0 // ] //Dismiss(400) // Do this every 4 seconds //] repeat // // --------------------------------------------------------------------------- and DLSBackground() be // --------------------------------------------------------------------------- // This is an independent task that does any necessary periodic // background processing [ UpdateCarrierOn(Noop) // Look for lines that have hung up Dismiss(100) // Wait one second, then repeat ] repeat