!***COPYRIGHT (C) 1974, 1975, 1976, 1977 DIGITAL EQUIPMENT CORP., MAYNARD, MASS.*** MODULE MISCMD(RESERVE(#11,#12,#13,#14),SREG=#17,FREG=#16,DREGS=4, VREG=#15,MLIST,TIMER=EXTERNAL(SIX12),FSAVE)= BEGIN REQUIRE DATA.BLI; !ALL KINDS OF GOOD STUFF EXTERNAL MOVE; COMMENT; ! SUBROUTINE INIT ! ========== ==== ! THIS ROUTINE LOOKS AT THE PAGE, CALLS KERNEL GETMPPSTATUS, TO DETERMINE IF THE JOB ! IS STARTED BY MCP FOR SOME INPUT QUEUE, IT ALSO SETS UP THE RETURN PAGE ! LAST MODIFIED: 21 JUN 76 BY CDO GLOBAL ROUTINE INIT(JOBSLOT,PAGEADDR) = BEGIN REGISTER STATUS, NODEPTR; EXTERNAL ?JB$UDX; !KERNEL MCS STARTED JOB TABLE MAP FORMAT NODEPTR; MACRO WHICHNODE = RH$; STATUS _ GETMPPSTATUS(.JOBSLOT); ZERO ((.PAGEADDR)[P0PRIM] %THRU%, (.PAGEADDR)[P0SUB3] + LEAFNAMLEN - 1); ! ZERO QUEUE NAMES IN THE PAGE IF .?JB$UDX[.JOBSLOT] GTR 0 THEN ! IF -1, THEN NOT MCS SCEDULED BEGIN IF (NODEPTR _ .STATUS) NEQ 0 THEN !IF THE NODE PTR IS NOT NULL, THE MPP IS !SCHEDULED DUE TO SOME INPUT QUEUE. BEGIN (.PAGEADDR)[P0STATUS] _ STSGOOD; !SET THE STATUS FILED IN PAGE TO GOOD. !GET THE INPUT QUEUE NAMES AND STORE THEM IN THE PAGE. DECR I FROM .NODEPTR[N0LEVEL] TO 0 DO BEGIN MOVE(NODEPTR[N0NAME],(.PAGEADDR)[P0PRIM+(.NODEPTR[N0LEVEL])*LEAFNAMLEN],LEAFNAMLEN); NODEPTR _ .NODEPTR[N0PARENT] END END ELSE (.PAGEADDR)[P0STATUS] _ STSNOTNODE; !IF WHICHNODE IS NULL, THEN THE MPP WAS NOT !SCHEDULED FOR SOME INPUT QUEUE, THEN STORE THE STSNOTNODE INTO !THE STATUS FIELD IN THE PAGE. END ELSE (.PAGEADDR)[P0STATUS] _ STSNOTMCS; SENDPAGE !RETURN END; EXTERNAL QHASH; COMMENT; ! LAST MODIFIED 2-FEB-74 / AG ! AC ROUTINE ! == ======= ! ROUTINE TO EXECUTE THE ACCEPT COUNT FUNCTION GLOBAL ROUTINE AC(JSN,PAGEADDR)= BEGIN REGISTER NODEPTR; MAP FORMAT NODEPTR; ! GET A NODE ADDRESS WITH QHASH IF (NODEPTR _ QHASH( (.PAGEADDR )[ P0PRIM ])) EQL 0 THEN BEGIN ! IF THE NODE ADDRESS IS ZERO THEN WE HAVE AN ERROR SO (.PAGEADDR)[P0MGC] _ 0; ! RETURN A ZERO MESSAGE COUNT AND (.PAGEADDR)[P0STATUS] _ STSILLQNAME; ! SET STATUS TO BAD NODE NAME END ELSE ! IF THE NODE ADDRESS WAS NON ZERO THEN DO GOOD THINGS BEGIN (.PAGEADDR)[P0STATUS] _ STSGOOD; ! SET STATUS TO OK (.PAGEADDR)[P0MGC] _ .NODEPTR[N0TSCNT] ! SET MESSAGE COUNT END; SENDPAGE ! ALWAYS GIVE THE PAGE BACK TO THE USER END; EXTERNAL COMPARE; COMMENT; ! LAST MODIFIED 6 FEB 74 BY AG ! ILLPSWRD ROUTINE ! ======== ======= ! ROUTINE TO CHECK PASSWORDS FOR ENABLE & DISABLE VERBS ! ILLPSWRD RETURNS TRUE IF THE PASSWORD IS ILLEGAL ! ==== ======= ! AND FALSE IF IT IS OK ROUTINE ILLPSWRD(PAGEADDR)= BEGIN BIND GOOD=FALSE, BAD=TRUE; EXTERNAL PSWRDTAB, PSWRDCOUNT; IF .PSWRDCOUNT EQL 0 THEN RETURN BAD; ! IF NO PASSWORDS SPECIFIED ! THEN DON'T LET HIM DO ANYTHING ANYTHING DECR I FROM (.PSWRDCOUNT-1)*2 TO 0 BY 2 DO ! OTHERWISE SEARCH THE PASSWORD TABLE IF COMPARE( (.PAGEADDR)[P0PSWORD], PSWRDTAB[.I], 2) THEN RETURN GOOD; BAD END; EXTERNAL COMPARE, QHASH; COMMENT; ! ROUTINES: DISABLE INPUT & ENABLE INPUT ! ======= ===== ====== ===== ! LAST MODIFIED: 10 FEB 74 BY AG ! XTRIM ROUTINE ! ===== ======= ! ROUTINE TO ENABLE AND DISABLE LEAVES GLOBAL ROUTINE XTRIM(PTR,TYPE)= ! PTR = LOC(NODE) TO BE ENABLED OR DISABLED ! TYPE = 1 IF TO DISABLE ! TYPE = 0 IF TO ENABLE ! RETURNS 0 ALWAYS BEGIN MACRO LEAF = (.NODEPTR[N0NXTND] EQL 0)$, ! THIS MACRO PRODUCES A ! TRUE VALUE IF THE CURRENT NODE IS A LEAF MARK = NODEPTR[N0ED] _ .TRIMR$, ! SETS OR CLEARS E/D BIT DROP = NODEPTR _ .NODEPTR[N0NXTND]$; ! TAKES THE NODEPOINTER ! DOWN TO THE NEXT LEVEL REGISTER NODEPTR, OLDNODEPTR, TRIMR; MAP FORMAT NODEPTR; NODEPTR _ OLDNODEPTR _ .PTR; ! GET ONLY RH OTHERWISE THE ! RETURN ON .OLDNODEPTR WON'T GO TRIMR _ .TYPE; IF LEAF THEN MARK ! IF LEAF THEN MARK AND RETURN ELSE WHILE 1 DO IF NOT LEAF THEN DROP ! OTHERWISE MARK ALL LEAVES UNDER THIS NODE ELSE WHILE LEAF DO BEGIN MARK; WHILE .NODEPTR[N0SAMND] EQL 0 DO BEGIN NODEPTR _ .NODEPTR[N0PARENT]; IF .NODEPTR EQL .OLDNODEPTR THEN RETURN 0! RETURNS 0 ALWAYS END; NODEPTR _ .NODEPTR[N0SAMND] END; END; COMMENT; ! ROUTINE DISABLE INPUT ! ======= ===== GLOBAL ROUTINE DI(JSN,PAGEADDR)= BEGIN REGISTER NODEPTR; MAP FORMAT NODEPTR; IF ILLPSWRD(.PAGEADDR) THEN ! CHECK PASSWORD BEGIN ! IF ILLEGAL THEN (.PAGEADDR)[P0STATUS]_STSILLPSWRD ! SET ILLEGAL PASSWORD ! STATUS CODE END ELSE BEGIN ! IF LEGAL THEN IF (NODEPTR_QHASH( (.PAGEADDR)[ P0PRIM ])) EQL 0 THEN ! GET NODE POINTER BEGIN (.PAGEADDR)[P0STATUS]_STSILLQNAME ! IF ILLEGAL NODE NAME ! SET ILLEGAL QUEUENAME STATUS CODE IN THE COMMAND PAGE END ELSE BEGIN TRIM(.NODEPTR); ! ELSE DISABLE THAT NODE (.PAGEADDR)[P0STATUS]_STSGOOD ! AND SET GOOD STATUS END END; SENDPAGE ! ALWAYS RETURN SENDPAGE END; COMMENT; ! ROUTINE ENABLE INPUT ! ====== ===== GLOBAL ROUTINE EI(JSN,PAGEADDR)= BEGIN REGISTER NODEPTR; MAP FORMAT NODEPTR; IF ILLPSWRD(.PAGEADDR) THEN ! CHECK PASSWORD BEGIN ! IF ILLEGAL THEN (.PAGEADDR)[P0STATUS]_STSILLPSWRD ! SET ILLEGAL PASSWORD ! STATUS CODE END ELSE BEGIN ! IF LEGAL THEN IF (NODEPTR_QHASH( (.PAGEADDR)[ P0PRIM ])) EQL 0 THEN ! GET A NODE POINTER BEGIN ! IF ILLEGAL NODE NAME ! SET ILLEGAL QUEUENAME STATUS IN THE PAGE (.PAGEADDR)[P0STATUS]_STSILLQNAME END ELSE BEGIN UNTRIM(.NODEPTR); ! ELSE ENABLE AND (.PAGEADDR)[P0STATUS]_STSGOOD !SET STATUS ALL OK END END; SENDPAGE ! ALWAYS RETURN SENDPAGE END; EXTERNAL QHASH, CHKSRCTAB; COMMENT; ! SUBROUTINE DITEIT ! ================= ! THIS ROUTINE HANDLES THE DIT AND EIT FUNCTIONS ! LAST MODIFIED: 31 OCT 74 BY AG FORWARD XDITEIT; GLOBAL ROUTINE DITEIT(JOBSLOT,PAGEADDR) = BEGIN REGISTER FCN; IF ILLPSWRD(.PAGEADDR) THEN !IF ILLEGAL PASSWORD IN PAGE, !ERROR RETURN. BEGIN (.PAGEADDR)[P0STATUS] _ STSILLPSWRD; RETURN SENDPAGE END; FCN _ IF .(.PAGEADDR)[P0FCN] EQL EITC THEN 0 ELSE 1; !IF EIT FUNCTION, SET FCN = 0, !IF DIT FUNCTION, SET FCN = 1, (.PAGEADDR)[ P0STATUS ] _ XDITEIT( (.PAGEADDR)[ P0SRCE ], IF .(.PAGEADDR)[ P0PRIM ] NEQ 0 THEN (.PAGEADDR)[ P0PRIM ] ELSE 0, .FCN ); SENDPAGE END; COMMENT; ! ROUTINE XDITEIT ! ======= ======= ! THIS ROUTINE PERFORMS THE ACTUAL ENABLING OR DISABLING FOR DITEIT, OPRDIT, & OPREIT GLOBAL ROUTINE XDITEIT( DEST, NODE, FCN ) = BEGIN REGISTER SRCPTR, LAST, START; OWN NPTR,STS; MAP FORMAT NODE; MAP FORMAT SRCPTR; SRCPTR _ CHKSRCTAB( .DEST ); !CHECK THE LEGALITY OF THE SOURCE SPECIFIED IN THE PAGE. IF .SRCPTR EQL 0 THEN RETURN STSUNKDST; IF .NODE EQL 0 THEN !THE SOURCE IS LEGAL, CHECK THE QUEUE NAMES. !IF THE PRIMARY QUEUE NAME IS NULL, INDICATING IT IS EITHER !"DIT ALL" OR "EIT ALL" FUNCTION BEGIN IF .FCN THEN SRCPTR[S0DIT] _ 3 !IF "DIT ALL" SET THE STATUS OF SOURCE IN SRCTAB TO 3 ELSE SRCPTR[S0DIT] _ 0; !IF "EIT ALL" SET THE STATUS OF SOURCE IN SRCTAB TO 0 START _ 0; !SET THE STARTING AND ENDING VALUES FOR !LEAF-NUMBERS TO INDICATE ALL OF THEM. LAST _ .N0LFNO END ELSE BEGIN !IF NEITHER "DIT ALL" NOR "EIT ALL", CHECK THE !EXISTENCE OF THE INPUT QUEUE NAMES SPECIFIED IN PAGE. NODE _ QHASH( .NODE ); IF .NODE EQL 0 THEN RETURN STSILLQNAME; !FOR LEGAL QUEUE NAME, GET THE NODE, SET THE !SOURCE STATUS IN SRCTAB TO "DIT SOME" (2, OR 10). !AND GET THE LOGICAL LEAF NUMBERS FOR THE FIRST !AND THE LAST LEAVES UNDER THIS NODE. SRCPTR[S0DIT] _ 2; NPTR _ .NODE; IF .NODE[N0NXTND] EQL 0 THEN START _ LAST _ .NODE[N0LLFNO] ELSE BEGIN ! FIND THE FIRST LEAF & SAVE IT'S LEAF NUMBER UNTIL .NODE[N0NXTND] EQL 0 DO NODE _ .NODE[N0NXTND]; START _ .NODE[N0LLFNO]; ! FIND THE LAST LEAF IN THE UNDER THIS NODE NODE _ .NPTR; WHILE .NODE[N0NXTND] NEQ 0 DO BEGIN NODE _ .NODE[N0NXTND]; WHILE .NODE[N0SAMND] NEQ 0 DO NODE _ .NODE[N0SAMND]; END; LAST _ .NODE[N0LLFNO]; END END; STS_STSGOOD; !SET INITIALLY TO GOOD INCR I FROM .START TO .LAST DO !SET THE BITS OF ALL THE CORRESPONDING LEAVES !IN THE SOURCE'S LEAF STATUS TABLE TO THE APPROPRIATE VALUES. BEGIN SRCPTR[S0LFSTS(.I,1)] _ .FCN; IF .SRCPTR[S0LFSTS(.I,2)] GEQ 2 THEN STS_STSSRCNOTASS END; .STS END; EXTERNAL CHKSRCTAB, CHKLFTAB, LINK, INCREMENT, CHKRUN; COMMENT; ! SUBROUTINE DOEO ! ========== ==== ! LAST MODIFIED: 31 OCT 74 BY AG ! THIS ROUTINE HANDLES THE DO(DISABLE OUTPUT) AND ! THE EO(ENABLE OUTPUT) FUNCTIONS. FORWARD XDOEO; GLOBAL ROUTINE DOEO(JOBSLOT,PAGEADDR) = BEGIN REGISTER BADDSTS, FCN, DEST; LABEL LOOP; BADDSTS _ 0; IF ILLPSWRD(.PAGEADDR) THEN !IF ILLEGAL PASSWORD IN PAGE, !ERROR RETURN. BEGIN (.PAGEADDR)[P0STATUS] _ STSILLPSWRD; RETURN SENDPAGE END; FCN _ IF .(.PAGEADDR)[P0FCN] EQL EOC THEN 0 ELSE 1; !IF EO FUNCTION, SET FCN=0, !IF DO FUNCTION, SET FCN=1, INCR J FROM 0 TO .(.PAGEADDR)[P0DSCNT]-1 DO !STEP THROUGH THE DESTINATION TABLE IN THE PAGE. LOOP: BEGIN %%%% DEST _ (.PAGEADDR)[P0DTAB+.J*3]; !GET ONE DESTINATION FROM THE DESTTAB IF XDOEO( .DEST, .FCN ) THEN !IF DISABLE/ENABLE SUCEEDS THENSTORE STSGOODDST IN THE ERROR KEY FIELD ! OF THE DEST. IN THE DESTTAB IN PAGE (.DEST+2) _ STSGOODDST ELSE BEGIN !IF DEST. IS NOT FOUND ANYWHERE, STORE STSBADDST !IN THE ERROR KEY FIELD FOR THE DEST. IN DESTTAB. !AND INCREMENT BADDSTS BY ONE (.DEST+2) _ STSBADDST; BADDSTS _ .BADDSTS + 1 END END; (.PAGEADDR)[P0STATUS] _ SELECT TRUE OF NSET .BADDSTS EQL .(.PAGEADDR)[P0DSCNT]: STSALLDSTUNK; !IF .BADDSTS=DSCNT, THAT MEANS NONE OF !THE DESTINATION IN DESTINATION TABLE IN PAGE IS ANY GOOD, !STORE STSALLDSTUNK IN THE STATUS FIELD IN PAGE. .BADDSTS EQL 0: STSGOOD; !IF BADDSTS = 0, THAT MEANS EVERYTHING IS FINE, NORMAL RETURN OTHERWISE: STSUNKDST; !IF BADDSTS IS NOT 0 AND NOT ALL, SOME ILLEGAL DESTINATIONS !IN THE DESTTAB, STORE STSUNKDST IN THE STATUS FIELD IN PAGE. TESN; SENDPAGE !RETURN END; COMMENT; ! ROUTINE XDOEO ! ======= ===== ! THIS ROUTINE PERFORMS THE DISABLING AND ENABLING FOR DOEO, OPRDO, & OPREO FORWARD XDOEOSRC, XDOEOLF; GLOBAL ROUTINE XDOEO( DEST, FCN ) = BEGIN REGISTER I, SRCPTR; MAP FORMAT SRCPTR; SRCPTR _ CHKSRCTAB(.DEST); !CHECK THE LEGALITY OF THE DEST. IN SRCTAB. IF .SRCPTR NEQ 0 THEN !IF THE DEST. IS IN THE SRCTAB, THEN BEGIN XDOEOSRC( .SRCPTR, .FCN ); ! DISABLE/ENABLE THE TERMINAL RETURN TRUE ! RETURN SUCCESSFUL DOEO END; IF .LFTAB NEQ 0 THEN !IF THE DEST. IS NO IN SRCTAB, AND LFTAB IS NOT NULL THEN BEGIN I _ CHKLFTAB(.DEST); !CHECK IF THE DEST. IS IN LFTAB, IF .I NEQ 0 THEN !IF YES, SET THE ENABLE/DISABLED FLAG TO THE CORRESPONDING VALUE !FOR THE LEAF IN THE LFTAB BEGIN XDOEOLF( .I, .FCN ); ! DISABLE/ENABLE THE LEAF RETURN TRUE ! RETURN SUCCESSFUL DOEO END END; FALSE ! COULDN'T FIND THE TERMINAL OR LEAF END; COMMENT; ! ROUTINE XDOEOSRC ! ======= ======== ! THIS ROUTINE DISABLES OR ENABLES OUTPUT FOR A SINGLE SRC GLOBAL ROUTINE XDOEOSRC( SRCPTR, FCN ) = BEGIN MAP FORMAT SRCPTR; EXTERNAL RUNMSW; EXTERNAL RUNMSR; RUNMSW _ RUNMSR _ -1; !FORCE READ/WRITE PROCESSES TO RUN SRCPTR[S0ED] _ .FCN !SET S0ED FLAG FOR THE DEST. IN SRCTAB, !TO THE RIGHT STATUS. END; COMMENT; ! ROUTINE XDOEOLF ! ======= ======= ! THIS ROUTINE DISABLES OR ENABLES OUTPUT FOR A LEAF GLOBAL ROUTINE XDOEOLF( I, FCN ) = BEGIN REGISTER I, LFTABPTR, LEAFPTR; MAP FORMAT LFTABPTR; MAP FORMAT LEAFPTR; LFTABPTR _ .LFTAB; LFTABPTR[L0ED(.I)] _ .FCN; IF .FCN EQL 0 AND .LFTABPTR[L0TSCNT(.I)] NEQ 0 THEN BEGIN !IF EO FUNCTION, AND THE PTR TO THE LAST GH FOR THE LEAF IN LFTAB !IS NOT NULL, CHAIN ALL THE GH'S FROM THE LFTAB TO THE LEAF. LEAFPTR _ .LFTABPTR[L0LFPTR(.I)]; LINK(LEAFPTR[N0GHS],.LFTABPTR[L0FGH(.I)]); ! SEE IF WE CAN START SOMETHING CHKRUN(.LEAFPTR, .LFTABPTR[L0TSCNT(.I)], .LFTABPTR[L0FGH(.I)]); ! CLEAN UP THE LEAF TABLE LFTABPTR[L0TSCNT(.I)] _ 0; LFTABPTR[L0GHS(.I)] _ 0; END END; END;