; Edit= 9041 to CLUFRK.MAC on 13-Dec-88 by RASPUZZI
;Finish off some of the security features that were started at one time (like
;password expiration). Also, add new features to help a system manager secure
;the system.
; Edit= 9036 to CLUFRK.MAC on 15-Nov-88 by RASPUZZI
;Make sure that the system's name gets sent over during PHYKLP START/STACK/ACK
;sequence. Also, when the NODE% JSYS changes the name, have the local system
;notify remote systems. Finally, make CLUDGR send over the node name in the
;last 2 words of the optional connection data. I'm out of breath.
; Edit= 9028 to CLUFRK.MAC on 8-Nov-88 by LOMARTIRE
;Merge Production changes to BUG text
; Edit= 8877 to CLUFRK.MAC on 10-Aug-88 by RASPUZZI
;Update BUG. documentation.
; Edit= 8866 to CLUFRK.MAC on 21-Jul-88 by RASPUZZI
;Make the CLUDGR SYSAP correctly handle CLUBUF (SYSAP buffer count) and also
;make CLNEED handle little credit left situations.
;Remove references to CLUBUF from here.
; Edit= 8850 to CLUFRK.MAC on 31-May-88 by RASPUZZI
;Add code to do the TMON% version of .SFSEA and .SFLTS. Also, teach INFO% how
;it must handle ethernet addresses for .SFSEA between remote systems.
; UPD ID= 8492, RIP:<7.MONITOR>CLUFRK.MAC.14, 9-Feb-88 12:18:13 by GSCOTT
;TCO 7.1218 - Insert copyright notice.
; UPD ID= 8388, RIP:<7.MONITOR>CLUFRK.MAC.13, 27-Jan-88 10:30:23 by GSCOTT
;TCO 7.1200 - GETRTL is now in XCDSEC.
; UPD ID= 289, RIP:<7.MONITOR>CLUFRK.MAC.12, 12-Nov-87 15:13:49 by RASPUZZI
;Fix up previous edit. I used an old source for comparison and didn't
;use REDIT to merge the changes in.
; UPD ID= 288, RIP:<7.MONITOR>CLUFRK.MAC.11, 12-Nov-87 15:10:26 by RASPUZZI
;TCO 7.1132 - Bind CLUDGR fork in queue 1 and see how much more the response
; is for cluster SYSTAT. also, set JP%SYS for the CLUDGR fork.
; This is an experiment and maybe changed again later.
; UPD ID= 287, RIP:<7.MONITOR>CLUFRK.MAC.10, 11-Nov-87 14:23:05 by RASPUZZI
;Restore a line that was incidentally removed.
; UPD ID= 242, RIP:<7.MONITOR>CLUFRK.MAC.9, 4-Nov-87 16:29:20 by RASPUZZI
;TCO 7.1114 - Prevent ILMNRFs and KLPHOGs on remote system by making sure
; CLFLNS calculates the send word value correctly
; UPD ID= 233, RIP:<7.MONITOR>CLUFRK.MAC.8, 29-Oct-87 16:21:52 by RASPUZZI
;TCO 7.1105 - Now do TCO 7.1087 right since we are sober.
;TCO 7.1104 - Make CLFMTO execute the MTOPR% JSYS in section 0.
; UPD ID= 230, RIP:<7.MONITOR>CLUFRK.MAC.7, 28-Oct-87 19:01:10 by RASPUZZI
;Add the missing portions of TCO 7.1090 that I didn't put in.
; UPD ID= 225, RIP:<7.MONITOR>CLUFRK.MAC.6, 28-Oct-87 14:16:43 by RASPUZZI
;TCO 7.1094 - Make CLFMSR find structure name in correct location when
; performing remote MSTR function .MSGSS.
; UPD ID= 222, RIP:<7.MONITOR>CLUFRK.MAC.5, 28-Oct-87 10:27:13 by RASPUZZI
;TCO 7.1090 - ***PERFORMANCE*** Only send over the exact number of words
; across the CI to remote system. Also, calls to routine
; FILLIN have to change.
; UPD ID= 218, RIP:<7.MONITOR>CLUFRK.MAC.4, 27-Oct-87 15:57:23 by RASPUZZI
;TCO 7.1087 - Return class scheduling information for .INSYS function
; for remote INFO% request.
; UPD ID= 196, RIP:<7.MONITOR>CLUFRK.MAC.3, 22-Oct-87 14:46:54 by RASPUZZI
;More of TCO 7.1076 - Make CLFSYS use the local job number when obtaining
; logged in directory out of JOBDIR
; UPD ID= 188, RIP:<7.MONITOR>CLUFRK.MAC.2, 21-Oct-87 17:32:16 by RASPUZZI
;TCO 7.1076 - Add CLUDGR SYSYAP. This contains the CLUDGR fork's
; supporting routines.
; COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1988.
; ALL RIGHTS RESERVED.
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
; ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
; INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
; COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
; OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
; TRANSFERRED.
;
; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
; AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
; CORPORATION.
;
; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
; SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL.

SUBTTL CLUDGR Fork -- CLFRUN (Begin running CLUDGR fork here)
;CLFRUN - This is the entry point given to the MSFRK% JSYS to
;get the CLUDGR fork started in monitor context.
;
; Called with:
; T1/ fork handle
; T2/ XCDSEC,,CLFRUN
; MSFRK%
;
; Returns:
; In theory, this routine does not return. It is the start of
; the CLUDGR fork.
;
; [7.1132] - Note that the CLUDGR fork is bound in queue 1 much the
;same as CHKR. If this degrades performance too much, than it can be
;changed back to run as a normal process.
XSWAPCD ;Process context
CLFRUN::MOVX T1,USRCTX ;Start with user context set
MOVEM T1,FFL ;in PC flags
MCENTR ;Start new process
MOVEI T1,JP%SYS+1 ;[7.1132] Clamp it in queue 1 for responsiveness
MOVEM T1,JOBBIT ;[7.1132] Put in PSB so it is known
MOVE T1,FORKX ;Get our fork number
MOVEM T1,CLFORK ;And store it here for future generations
MOVX T1,<SC%GTB!SC%WHL!SC%OPR!SC%CNF!SC%MNT!SC%IPC!SC%DNA!SC%ANA>
;All this and privs too
MOVEM T1,CAPMSK ;Save the capability mask
MOVEM T1,CAPENB ;Now save as if we enabled all of them
TRVAR <REQBLK,CODE,REQID,FRK,FLAGS,CINODE,REMUSR,REMCID> ;Temp data storage for this fork
; REQBLK - Address of request block we are currently working on
; CODE - Function code to perform for remote user
; REQID - Request ID number from remote system
; FRK - Fork number from remote system
; FLAGS - Flags from remote system
; CINODE - Node number of remote system
; REMUSR - 36 bit user number of remote user
; REMCID - CID to send reply on

CLFRN1: HRRZI T1,CLFWAT ;Get scheduler test. No data
MDISMS ;Now sleep until it is time to do something
CLFR15: CALL ZERDAT ;(/) Zero out CLUDGR fork's data areas
CLFR16: SOS CLUFLG ;Say we have seen one request
XMOVEI Q1,CLREQQ ;Previous entry in queue is held here
SKIPN Q2,CLREQQ ;Get entry from request queue
JRST CLFRN1 ;If there are none, then go back to sleep
CLFRN2: MOVE T2,REQFLG(Q2) ;Get flags for this request
TXNN T2,CL%DED ;Is this a dead letter?
IFSKP. ;Yes, it is
CIOFF ;No interruptions while removing entry
MOVE T2,REQFLK(Q2) ;Get next request after the current one
MOVEM T2,REQFLK(Q1) ;And remove the current one
CION ;OK to let more things come in
MOVE T1,Q2 ;Get request block
CALL CLFDED ;(T1/) Now return stuff
SKIPE CLUFLG ;Still more to do?
JRST CLFR16 ;Yes, find it
JRST CLFRN1 ;No, go back to sleep
ENDIF.
TXNN T2,CL%ALL ;Are all items here?
IFSKP. ;Yes, remove this one
CIOFF ;No interruptions while diddling queue
MOVE T2,REQFLK(Q2) ;Get next request after the current one
MOVEM T2,REQFLK(Q1) ;And remove the current one
CION ;We done touching the queue
MOVE T1,Q2 ;Now do the work
CALL CLFALL ;(T1/) Yes, time to reassemble and do some work
SKIPE CLUFLG ;Still more to do?
JRST CLFR15 ;Yes, find it
JRST CLFRN1 ;No, go back to sleep
ENDIF.
MOVE Q1,Q2 ;Now this entry becomes the previous
SKIPN Q2,REQFLK(Q2) ;Keep scanning queue, get next entry
JRST CLFRN1 ;There are no more, back for a nap
JRST CLFRN2 ;Have next request, check it out

SUBTTL CLUDGR Fork -- DOMTO (Section 0 MTOPR%)
;[7.1104]
;Note that the following section of code (no matter how gross or
;disgusting it looks) must be. MTOPR% does not work if it is executed
;outside of section 0! It assumes that T1 will have a OWGB instead
;of a universal device designator.
SWAPCD ;Must be in section 0/1
DOMTO: S0.ENT ;Section 0 darn it!
MTOPR% ;Do MTOPR%
ERJMP R ;We had a failure
RETSKP ;We succeeded so continue

SUBTTL CLUDGR Fork -- CLFTMG (Do TTMSG% request)
;CLFTMG - This is called when in coming packets represent a request for
;a remote TTMSG% and this node is the sucker to do the work. It always
;sends back a one word reply. This word either contains an error code
;when we failed or it has 0 meaning we succeeded.
;
; Call with:
; CLFREA setup
; CALL CLFTMG
;
; Returns:
; +1 - Always, with results sent back to requestor
XSWAPCD ;Fork context code
CLFTMG: XMOVEI T2,CLFREA ;Here's where we find it all
MOVE T1,(T2) ;This gets the terminal designator
MOVE T3,FLAGS ;Get flags from remote system
TXNE T3,CL%PRV!CL%GAL ;Check to see if prived or GALAXY
IFSKP. ;If not,
CAIE T1,.TTTTY ;If user wants all terminals
IFSKP. ;If so, and he ain't prived,
MOVEI T1,GTDIX1 ;Say he needs privs
CALLRET CLFBAD ;And get out of here
ENDIF.
TXZ T1,.TTDES ;Clear terminal designator and just get line #
CAIL T1,0 ;Range check the line
CAILE T1,NLINES ;Is it within range?
JRST CLFTM1 ;No, just TTMSG%, it will fail and then pass back error
JN TTNTM,(T1),NOTMG ;User inhibiting?
JE TTNUM,(T1),CLFTM1 ;Or is he refusing user messages?
JRST NOTMG ;Yes, can't let this go
ELSE.
CAIN T1,.TTTTY ;Want all terminals?
SETO T1, ;Yes, flag so
ENDIF.
CLFTM1: TXO T1,.TTDES ;Make .TTDES again
AOS T2 ;Now this is where the send all stuff is
HRLI T2,(POINT 7,) ;Stuff was sent over in 7 bit
TTMSG% ;The the TTMSG% for the user
ERJMP ERRTMG ;Do last error
SETZM CLFSCR ;This indicates send was successful
CALLRET CL1SND ;Send over 1 word
ERRTMG: SKIPA T1,LSTERR ;Get last error
NOTMG: MOVEI T1,TTMSX2 ;User refusing
TXO T1,IN%RER ;Say error from remote
CALLRET CLFBAD ;Tell remote system

SUBTTL CLUDGR Fork -- CLFBAD (Bad function from remote)
;CLFBAD - Routine to handle a bad function or error. We get here when a
;remote system sends us a CLUDGR request but we can't do it because it is
;not in our dispatch table or if we tried to do the request and some kind of
;error occurred while executing the request.
;
; Call with:
; T1/ Error code (if 0, error code gotten out of LSTERR)
; CALLRET CLFBAD
; or
; CALLRET DOLAST (when LSTERR is to be used)
;
; Returns:
; +1 - Always with remote system notified
XSWAPCD ;Done at process level
DOLAST: SETZ T1, ;Here when we want LSTERR
CLFBAD: STKVAR <ERROR,RETADR,TRIES,SCABUF> ;Place to save error code
SKIPN T1 ;If nothing passed in,
MOVE T1,LSTERR ;then get our last error
MOVEM T1,ERROR ;Save error code whilest we get SCA buffer
MOVEI T1,1 ;Tell SCA we only want a single buffer
CALL <XENT SC.ABF> ;(T1/T1,T2,T3) get an SCA buffer
CLFNOB: BUG.(HLT,CLUOSB,CLUFRK,SOFT,<CLUDGR fork could not get an SCA buffer>,,<
Cause: A request was made for CLUDGR fork to do something. Unfortunately,
this request failed for one reason or another. When CLUDGR fork
tried to tell the remote system it failed, the fork could not
get an SCA buffer to reply. This should not happen as SCA uses
an entire section for buffers.
>) ;What do you mean no buffers?
MOVEM T3,RETADR ;This is where return buffer
MOVEM T1,SCABUF ;Save SCA buffer address
MOVX T2,CL%REQ ;Say this is a response
ANDCAM T2,FLAGS ;By clearing this bit
MOVX T2,CL%ERR ;Now say we had an error
IORM T2,FLAGS ;By setting this bit
BLCAL. (FILLIN,<T1,FLAGS,REQID,CODE,FRK,CINODE,REMUSR,[1]>) ;[7.1090]
;[7.1090] Fill in SCA buffer chain

SUBTTL CLUDGR Fork -- CLFFAL (Send Failure)
;CLFFAL - Here when the CLUDGR fork tried to send something MAXTRY
;times. Now we BUGHLT.
;
; Called with:
; no arguments
; CALL CLFFAL
;
; Returns:
; NEVER
XSWAPCD ;Called by fork
CLFFAL: BUG.(HLT,CLUSCM,CLUFRK,SOFT,<CLUDGR fork send unconditionally failed>,,<
Cause: The local system attempted to send a response to a remote system
MAXTRY times. This BUGHLT indicates that the send failed each
time due to lack of receive credit on the remote system. The
system has used up all of the credits, and the send ties up a fork
on the remote system.
Action: It is possible that CI problems caused this BUGHLT.
>) ;Crash

SUBTTL CLUDGR Fork -- CLFRSP (Reassemble SCA packets)
;CLFRSP - Routine called to reassemble a collection of SCA buffers
;associated with a request that was on the CLREQQ.
;
; Called with:
; T1/ Address of request block
; CALL CLFRSP
;
; Returns:
; +1 - Always, with data in SCA packets reassembled in the CLFREA page
XSWAPCD ;Process level code
CLFRSP: SAVEAC <Q1> ;Save scratch spot
XMOVEI T3,CLFREA ;Start putting stuff at this location
SKIPN Q1,REQSCA(T1) ;Get first SCA buffer
BUG.(HLT,CLFNSB,CLUFRK,SOFT,<No SCA buffers for request>,,<
Cause: This BUG indicates that a request came in from a remote system
for the local CLUDGR fork to perform. However, after the CL%ALL
bit was set in the request block, there were no SCA buffers to
reassemble. CL%ALL must have been erroneously set.
>) ;If no SCA buffers, die now
AOS Q3,CLDLEN(Q1) ;[7.1090] Get words we received
CLFRS1: LOAD T2,.CLPTR,(Q1) ;Get pointer to data area
ADDI T2,CLDFUN ;Find out where data starts (past this word)
ADD T2,Q1 ;Now make it absolute
MOVE T1,Q3 ;[7.1090] Assume we can BLT this many
CAILE T1,<C%MUDA-CLDATA+.MHUDA> ;[7.1090] Too many words?
MOVEI T1,<C%MUDA-CLDATA+.MHUDA> ;[7.1090] Yes, only do this many
CALLX (MSEC1,XBLTAT) ;(T1,T2,T3/T1,T2,T3) Blast data to CLUDGR fork's page
SKIPN Q1,.CLFLI(Q1) ;[7.1090] Get next SCA buffer in chain
IFSKP. ;[7.1090] If another buffer...
SUBI Q3,<C%MUDA-CLDATA+.MHUDA> ;[7.1090] Account for the words we just BLTed
JRST CLFRS1 ;[7.1090] Do next buffer
ENDIF. ;[7.1090]
RET ;All buffers reassembled

SUBTTL CLUDGR Fork -- CLFWAT (Scheduler test to wait for action)
;CLFWAT - Scheduler test used by the CLUDGR fork. The CLUDGR fork will
;will use this to wait for something to do.
;
; Called with:
; no arguments
; MDISMS to CLFWAT
;
; Returns:
; +1 - Go back to sleep, nothing to do
; +2 - CLUFLG was set, time to check out the action
RESCD ;Like all good scheduler tests
CLFWAT: SKIPN CLUFLG ;Is it time to process goodies?
RET ;No, too early to go to work
RETSKP ;Respond to alarm clock

SUBTTL CLUDGR Fork -- CLFSND (Routine to send results)
;CLFSND - This routine is the responder. It sends the data obtained
;by the function and put into CLFSCR back to the requestor on the
;remote system.
;
; Call with:
; T1/ number of words in CLFSCR to be sent and
; CLFSCR setup
; CALL CLFSND
;
; Or call with:
; no arguments
; CALL CLxSND (where 0<x<4 and X is the number of words to send
;
; Returns:
; +1 - Always, data sent. However, this routine may block
; while several attempts to make the send are tried.
; If the send fails MAXTRY times, we crash.
XSWAPCD ;Fork fun
CL1SND: MOVEI T1,1 ;Send over 1 word
JRST CLFSND ;Common code
CL2SND: MOVEI T1,2 ;Send over 2 words
JRST CLFSND ;Join common code
CL3SND: MOVEI T1,3 ;Send over 3 words
JRST CLFSND ;Join common code
CLFSND: SAVEQ ;[7.1090] Save what we use
STKVAR <TRIES,WRDS,BUFCHN,NEXT,RETBUF> ;Temp data storage
MOVEM T1,WRDS ;Save the number of words
MOVEI T1,MAXTRY ;Max number of tries
MOVEM T1,TRIES ;Stash it for now
CLFSN1: HRR T2,WRDS ;Get count of words to move
HRLI T2,<CLDATA-.MHUDA> ;Start putting data in at this word
XMOVEI T1,CLFSCR ;Here's the data
NOINT ;To satisfy SC.BRK
CALL SC.BRK ;(T1,T2/T1,T2,T3) Put stuff in SCA message buffers
IFNSK. ;If we failed,
SOSGE TRIES ;See if we failed too much
BUG.(HLT,CLOUTB,CLUFRK,SOFT,<System out of SCA buffers>,,<
Cause: The CLUDGR fork was trying to send a response to a remote
system. However, it could not obtain the SCA bufferage to
do so.
Action: Find out who is eating up the SCA buffers.
>) ;We've had enough
OKINT ;Undo NOINT
MOVEI T1,WAIT ;Sleep a bit
DISMS% ;Maybe buffers will come back
JRST CLFSN1 ;Try it again
ENDIF.
OKINT ;All set now

;Here when send failed somehow. We are now going to give back
;the rest of the SCA buffers.
PNTCHN: MOVE T1,BUFCHN ;Get buffer back
CALLX (MSEC1,SC.RBF) ;(T1/) Now return it
SKIPN T1,NEXT ;Was there more?
RET ;No more, go back
MOVEM T1,BUFCHN ;Put it here
MOVE T1,.PKFLI(T1) ;Get the next one in line
MOVEM T1,NEXT ;And stash it here
JRST PNTCHN ;And punt the rest of the chain
ENDSV.