C C THIS TASK (TMCLI) ILLUSTRATES THE USE OF THE CLI CONTROL DIRECTIVES PRESENT C IN RSX-11M V4.0 AND RSX-11M-PLUS V2.0. C C WHEN SET UP AS A TERMINAL'S CLI, IT PROVIDES THE FOLLOWING COMMANDS: C C T -> TYPE FILE C M -> SET TERMINAL TO MCR C C IF THE FIRST TWO LETTERS OF THE COMMAND ARE NOT "T" FOLLOWED C BY A SPACE, OR "M" FOLLOWED BY A CARRIAGE RETURN, C THE COMMAND IS PASSED TO MCR FOR EXECUTION. THEREFORE, C USERS AT TERMINALS SET TO THIS CLI WILL SEE THE ENTIRE MCR COMMAND SET C AS BEING PRESENT, PLUS THE "T" AND "M" COMMANDS. IF THE "DPR" SWITCH C IS INCLUDED ON THE CLI /INIT COMMAND, USERS WILL KNOW IMMEDIATELY IF C THEIR TERMINAL IS SET TO THIS CLI BY THE PRESENCE OF THE DOUBLE RIGHT C ANGLE BRACKET AS THE PROMPT. C C IF IT IS INITIALIZED WITH THE SYSTEM MESSAGE OPTION ENABLED, IT WILL C GREET USERS WHEN THEIR TERMINAL IS SET TO THE CLI, AND SAY GOODBYE C TO THEM WHEN THEY SWITCH AWAY. C C IN ORDER TO BRING THIS CLI UP ON THE SYSTEM, ISSUE THE FOLLOWING C COMMAND SEQUENCE: C C >FOR TMCLI,TMCLI/-SP=TMCLI C >TKB TMCLI/FP,TMCLI/-SP=TMCLI,[1,1]FOROTS/LB C >INS TMCLI/CLI=YES/TASK=...TMC C >CLI /INIT=TMCLI/MESSAGE/DPR="<15><12>/>>/"/TASK=...TMC C C IF USING FORTRAN IV-PLUS INSTEAD OF FORTRAN IV, THE FIRST TWO C COMMANDS ABOVE WOULD BE: C C >F4P TMCLI,TMCLI/-SP=TMCLI.FTN C >TKB TMCLI/FP,TMCLI/-SP=TMCLI,[1,1]F4POTS/LB C C TO SET TERMINALS TO THIS CLI, ISSUE THE FOLLOWING COMMAND C WHERE TTN: IS REPLACED BY THE TERMINAL NUMBER OR TI: C C >SET /CLI=TTN:TMCLI C C NOTE THAT THE PROMPT ISSUED IN RESPONSE TO A CONTROL/C DEFAULTS TO THE C NAME OF THE CLI WHICH IS "TMCLI>". C C IT CAN BE ELIMINATED FROM THE SYSTEM BY THE FOLLOWING COMMANDS, ASSUMING C NO TERMINALS ARE SET TO IT: C C >CLI /ELIM=TMCLI C >REM ...TMC C C EXPERIMENT WITH THE OTHER OPTIONS ON THE CLI /INIT COMMAND, THE ENABLE C AND DISABLE CLI COMMANDS, AND LEAVING OFF THE /MESSAGE SWITCH ON THE /INIT C COMMAND TO OBSERVE THE EFFECT THEY HAVE. ALSO TRY CHANGING THE /TASK= C SWITCH ON THE INS AND CLI /INIT COMMAND TO "/TASK=TMCLI" AND NOTICE C THAT ONLY ONE COPY OF THE TASK WILL EXIST FOR ALL TERMINALS, RATHER THAN C ONE PER COMMAND. IF THIS IS DONE, YOU SHOULD ALSO CHANGE THE OPTION C ON THE GTCMCI DIRECTIVE FROM GC.CEX TO GC.CST SO THE TASK WILL STAY ACTIVE C BUT STOPPED WHEN NO COMMANDS ARE OUTSTANDING FOR IT. C C C BUFFER AREAS C C COMMAND BUFFER - THIS BUFFER IS USED IN THE GTCMCI DIRECTIVE. IT CON- C TAINS INFORMATION ON THE COMMAND RECEIVED (8 BYTES) C AND THE COMMAND TEXT. BYTE CMDBUF(264) INTEGER*2 CBLEN ! NOTE THAT ON M+ THE MAXIMUM COMMAND DATA CBLEN/263/ ! LENGTH IS 255. INTEGER*2 GCCDV, GCCCL ! ASCII DEV NAM, # CHARS IN CMD LINE BYTE GCCCT, GCCUN, GCCBF(255) ! # OF CHARS, TERMINAL UNIT #, CMD EQUIVALENCE (GCCDV,CMDBUF), (GCCCL,CMDBUF(5)), (GCCCT,CMDBUF(4)), 1 (GCCBF,CMDBUF(9)), (GCCUN,CMDBUF(3)) C C INFORMATION BUFFER - ALSO RETURNED IN THE GTCMCI DIRECTIVE. C BYTE IBUF(14) INTEGER*2 GCCPU DATA IBLEN/14/,GCCPU/9/ ! LENGTH OF IBUF, LOGIN UIC OFFSET INTEGER*4 GCCOA ! ADDR OF OFFSPRING CONTROL BLOCK FROM PARENT EQUIVALENCE (GCCOA,IBUF(7)) C C BUFFER IN WHICH TO GENERATE COMMANDS C BYTE BUF(72) ! BUFFER IN WHICH TO GENERATE COMMANDS REAL*8 TCMD(2) ! FOR CONVENIENCE IN ASSIGNMENT STATEMENTS EQUIVALENCE (BUF,TCMD) C C MCR TASK NAME IN RAD50 C INTEGER*4 IMCR ! MCR TASK NAME IN RAD50 DATA IMCR/6RMCR.../ C C DIRECTIVE SYMBOLIC VALUE DEFINITIONS C INTEGER*2 GCCCS, GCCEX, GCCST, GCCND DATA GCCCS, GCCEX, GCCST, GCCND /0, 1, 2, 128/ ! INCP VALUES IN GTCMCI DATA ISCLR /0/ ! IS.CLR RETURN CODE INTEGER*2 CMELM, CMEXT, CMLKT, CMRMT ! TERMINAL CODES FOR SYSTEM MSGS DATA CMELM, CMEXT, CMLKT, CMRMT /5, 6, 7, 8/ C C CLI CODE C C TO FORCE THE CLI TO EXIT INSTEAD OF RETURNING, THE GC.CEX OPTION IS SPECI- C FIED IN THE GTCMCI DIRECTIVE BELOW. IF THE CLI IS INSTALLED SO THAT ONLY C ONE COPY OF THE TASK WILL EXIST FOR ALL TERMINALS, CHANGE THE VARIABLE C GCCEX BELOW TO GCCST. THIS SPECIFIES THE GC.CST OPTION SO THAT THE TASK C WILL STAY ACTIVE BUT STOPPED WHEN NO COMMANDS ARE OUTSTANDING FOR IT. C 1 CALL GTCMCI(CMDBUF,CBLEN,IBUF,IBLEN,0,GCCEX,IDS) ! GET CMD FOR CLI IF (IDS .LT. 0) GO TO 100 C C IF THE GTCMCI DIRECTIVE HAD THE GC.CST OPTION SPECIFIED, WE MAY HAVE C JUST BEEN UNSTOPPED, SO WE HAVE TO GET THE COMMAND. C IF (IDS .EQ. ISCLR) GO TO 1 ! WERE WE JUST UNSTOPPED? IF (GCCDV .EQ. 0) GO TO 200 ! IS THIS A SYSTEM MESSAGE? IGCCUN = GCCUN ! CONVERT BYTE TO INTEGER (UNIT #) CALL ASNLUN(5,GCCDV,IGCCUN,IDS) ! ASSIGN TERMINAL TO LUN 5 IGCCCT=GCCCT ! CONVERT BYTE TO INTEGER IF (IGCCCT .GE. 0) GO TO 5 IGCCCT = 256 + IGCCCT ! CONVERT NEGATIVE TO UNSIGNED 5 IF (IGCCCT .LT. GCCCL) GOTO 150 ! DID ENTIRE COMMAND FIT IN BUFFER? C C AT THIS POINT, THE CLI HAS A COMMAND TO BE PROCESSED. THE CODE FROM C THE LABEL 1 TO HERE SHOULD BE FAIRLY COMMON AMONG ALL CLIS. C FROM THIS POINT ON, THE CODE WILL BE SPECIFIC TO THE PARTICULAR LANGUAGE C THIS CLI IS IMPLEMENTING. COMMANDS CAN BE ADDED OR DELETED AT WILL C BY MODIFYING CODE IN THIS SECTION. AS STATED ABOVE, THIS EXTREMELY C SIMPLE CLI PROVIDES TWO COMMANDS, AND GIVES EVERYTHING ELSE TO MCR. C THIS CREATES AN OPEN ENDED ENVIRONMENT. REJECTING UNRECOGNIZED COMMANDS C INSTEAD OF PASSING THEM TO MCR WOULD LIMIT THE TERMINAL USER'S USE OF C THE SYSTEM TO ONLY THOSE OPERATIONS ALLOWED BY THE CLI. THIS IS C A SECURE WAY OF CONTROLLING SYSTEM USE, IN CASES WHEN IT IS NECESSARY. C IN THIS EXAMPLE, CHANGING THE "GO TO 50" BELOW, TO A "GO TO 60" C WOULD CREATE AN ENVIRONMENT WHERE THE ONLY OPERATION A USER COULD C PERFORM WOULD BE TO TYPE FILES ON THE TERMINAL, OR SWITCH BACK TO MCR. C ALL OF THE REST OF RSX IS TOTALLY INACCESSABLE. IF NO MEANS OF SWITCHING C BACK TO MCR IS PROVIDED, IT WOULD BE IMPOSSIBLE FOR THE USER TO DO C ANYTHING THE CLI DOES NOT EXPLICITLY LET HIM DO. C C IS IT A "T" COMMAND? C IF ((GCCBF(1) .EQ. 'T') .AND. (GCCBF(2) .EQ. ' ')) GO TO 10 C C CHANGE THE NEXT IF STATEMENT TO "GO TO 60" TO ELIMINATE PASSING UNKNOWN C COMMANDS TO MCR. C C IS IT ALSO NOT AN "M" COMMAND? C IF ((GCCBF(1) .NE. 'M') .OR. (GCCBF(2) .NE. 13)) GO TO 50 ! M C C THE USER HAS ENTERED AN "M" COMMAND, SO SET THE TERMINAL TO MCR. C TCMD(1) = 'SET /MCR' TCMD(2) = '=TI: ' ! SET /MCR=TI: IGRP = IBUF(GCCPU+1) ! (CONVERT BYTE TO INTEGER) GROUP IMEM = IBUF(GCCPU) ! MEMBER PART OF UIC C C ISSUE RPOI$ DIRECTIVE TO EXECUTE COMMAND C CALL RPOI(IMCR,IGRP,IMEM,,TCMD,12,,GCCDV,IGCCUN,,GCCOA,IDS) IF (IDS .LE. 0) GO TO 110 ! ERROR? GO TO 1 ! BACK TO START C C THE USER HAS ENTERED A "T" COMMAND SO CONSTRUCT THE NECESSARY PIP C COMMAND AND SEND IT TO MCR C 10 TCMD(1) = 'PIP TI:=' ! PUT BEGINNING OF PIP CMD IN BUFFER I2 = 8 ! POINTER INTO TARGET BUFFER DO 20, I1 = 10, CBLEN ! BEGIN AT SPACE AFTER THE T IN CMDBUF IF (CMDBUF(I1) .EQ. 13) GO TO 30 ! END OF COMMAND? () IF (CMDBUF(I1) .EQ. ' ') GO TO 20 ! SKIP ANY SPACES I2 = I2 + 1 ! COUNT CHARACTER BUF(I2) = CMDBUF(I1) ! COPY INTO OUTPUT BUFFER 20 CONTINUE 30 IGRP = IBUF(GCCPU+1) ! (CONVERT BYTE TO INTEGER) GROUP IMEM = IBUF(GCCPU) ! MEMBER PART OF UIC C C ISSUE RPOI$ DIRECTIVE TO EXECUTE COMMAND C CALL RPOI(IMCR,IGRP,IMEM,,TCMD,I2,,GCCDV,IGCCUN,,GCCOA,IDS) IF (IDS .LE. 0) GO TO 110 ! ERROR? GO TO 1 ! BACK TO START C C IN THE ABOVE SECTION OF CODE, THE RPOI DIRECTIVE WAS USED TO PASS C THE PIP COMMAND TO THE MAIN COMMAND DISPATCHER (MCR...) C WHICH WILL START A COPY OF PIP AND GIVE IT THE COMMAND. THE RPOI C DIRECTIVE COULD BE USED TO GIVE THE COMMAND DIRECTLY TO ...PIP AND C GIVE THE RESULTING TASK A DIFFERENT NAME. IN THIS EXAMPLE, C WE COULD CALL THE RESULTING PIP TASK "TYPTNN" WHERE THE LAST C THREE CHARACTERS (TNN) ARE REPLACED BY A DEVICE NAME CHARACTER AND C UNIT NUMBER. FOR EXAMPLE, IF THE "T" COMMAND WAS TYPED ON TT10: C THE RESULTING TASK NAME COULD BE MADE TO BE "TYPT10". THIS HAS THE C ADVANTAGE OF ALLOWING THE TASK TO BE ABORTED BY AN "ABO TYP" COMMAND, C INSTEAD OF "ABO PIP", THUS THE USER WOULD NOT HAVE TO KNOW THAT THE C "T" COMMAND HE ISSUED IS ACTUALLY BE SERVICED BY THE PIP TASK. THIS C IS EXACTLY WHAT THE DCL CLI DOES. IT IS NOT DONE HERE IN ORDER C TO SIMPLIFY THE EXAMPLE. PICKING UP THE TERMINAL NAME AND UNIT C NUMBER, CONVERTING IT TO RAD50, AND SUPPLYING IT IN THE RPOI DIRECTIVE C ALONG WITH A DIRECT REQUEST OF PIP IS LEFT AS AN EXERCISE TO THE USER. C (BE CAREFUL ON M-PLUS SYSTEMS WITH MORE THAN 64. TERMINALS). C NOTE THAT REQUESTING PIP DIRECTLY AVOIDS A SUBSTANTIAL AMOUNT OF SYSTEM C OVERHEAD. C C C C COMMAND IS NOT "T" OR "M", SO GIVE IT TO MCR AS IS. C 50 IGRP = IBUF(GCCPU+1) ! (CONVERT BYTE TO INTEGER) GROUP IMEM = IBUF(GCCPU) ! MEMBER PART OF UIC IGCCCT = GCCCT ! # OF CHARS IN COMMAND C C ISSUE RPOI$ DIRECTIVE TO EXECUTE COMMAND C CALL RPOI(IMCR,IGRP,IMEM,,GCCBF,IGCCCT,,GCCDV,IGCCUN,,GCCOA,IDS) IF (IDS .LE. 0) GO TO 110 ! ERROR? GO TO 1 ! BACK TO START C C CONTROL IS TRANSFERED HERE IF UNKNOWN COMMANDS ARE TO BE REJECTED C INSTEAD OF BEING PASSED TO MCR. C 60 WRITE (5,62) 62 FORMAT('0ILLEGAL COMMAND') GO TO 1 ! BACK TO START C C ERROR HANDLING CODE C 100 WRITE (5,102) IDS ! ERROR IN GTCMCI 102 FORMAT('0FATAL ERROR IN GTCMCI DIRECTIVE. DSW=',I6) GO TO 250 ! EXIT C 110 WRITE (5,112) IDS ! ERROR IN RPOI 112 FORMAT('0FATAL ERROR IN RPOI DIRECTIVE. DSW=',I6) GO TO 250 ! EXIT C 150 WRITE (5,152) ! ENTIRE COMMAND DID NOT FIT IN BUFFER 152 FORMAT('0SORRY, PART OF YOUR COMMAND WAS LOST') GO TO 1 ! BACK TO START C C A SYSTEM MESSAGE WAS RECEIVED INSTEAD OF A COMMAND C 200 CONTINUE IF (GCCUN .EQ. CMLKT) GO TO 210 ! IS IT A NEW TERMINAL LINKED TO US? IF (GCCUN .EQ. CMRMT) GO TO 220 ! IS IT A TERMINAL BEING REMOVED? IF (GCCUN .EQ. CMEXT) GO TO 250 ! IS IT AN ELIMINATE ALL PACKET? IF (GCCUN .EQ. CMELM) GO TO 250 ! IS IT A CLI ELIMINATION MESSAGE? GO TO 1 ! IGNORE ALL OTHER MESSAGES C C ISSUE WELCOME MESSAGE C 210 IGCCUN = CMDBUF(11) ! CONVERT BYTE TERMINAL UNIT # TO INTEGER CALL ASNLUN(5,GCCBF,IGCCUN,IDS) ! ASSIGN LUN 5 TO SPECIFIED DEVICE WRITE (5,212) 212 FORMAT('0WELCOME TO THE EXAMPLE CLI') GO TO 1 ! BACK TO START C C ISSUE GOOD BYE MESSAGE C 220 IGCCUN = CMDBUF(11) ! CONVERT BYTE TERMINAL UNIT # TO INTEGER CALL ASNLUN(5,GCCBF,IGCCUN,IDS) ! ASSIGN LUN 5 TO SPECIFIED DEVICE WRITE (5,222) 222 FORMAT('0GOOD BYE FROM THE EXAMPLE CLI') GO TO 1 ! BACK TO START C C WHEN AN ELIMINATE ALL MESSAGE IS RECEIVED, EXIT IMMEDIATELY C 250 CONTINUE CALL EXIT END