.TITLE lgocli - CLI THAT IMPLEMENTS rmd, who, act /all from logged out ttys .IDENT /1.00/ .enable lc ; author: Edward Cetron ; Center for Biomedical Design ; Univ. of Utah ; 801-581-5304 ; ; creation date: Sept. 1, 1982 ; ; THIS TASK (TMCLI) ILLUSTRATES THE USE OF THE CLI CONTROL DIRECTIVES PRESENT ; IN RSX-11M V4.0 AND RSX-11M-PLUS V2.0. ; ; WHEN SET UP AS A TERMINAL'S CLI, IT PROVIDES THE FOLLOWING COMMANDS: ; ; who -> who ; rmd -> rmd ; hel -> hel ; help -> help ; ; Logged out users will see only the above commands. IF THE "DPR" SWITCH ; IS INCLUDED ON THE CLI /INIT COMMAND, USERS WILL KNOW IMMEDIATELY IF ; THEIR TERMINAL IS SET TO THIS CLI BY THE PRESENCE OF THE DOUBLE RIGHT ; ANGLE BRACKET AS THE PROMPT. ; ; IF IT IS INITIALIZED WITH THE SYSTEM MESSAGE OPTION ENABLED, IT WILL ; GREET USERS WHEN THEIR TERMINAL IS SET TO THE CLI, AND SAY GOODBYE ; TO THEM WHEN THEY SWITCH AWAY. ; ; IN ORDER TO BRING THIS CLI UP ON THE SYSTEM, ISSUE THE FOLLOWING ; COMMAND SEQUENCE: ; ; >MAC lgocli,lgocli/-SP=lgocli ; >TKB lgocli,lgocli/-SP=lgocli,[1,1]EXELIB/LB ; >INS lgocli/CLI=YES/TASK=...lgo ; >CLI /INIT=lgocli/MESSAGE/DPR="<15><12>/>>/"/TASK=...lgo ; ; TO SET TERMINALS TO THIS CLI, ISSUE THE FOLLOWING COMMAND ; WHERE TTN: IS REPLACED BY THE TERMINAL NUMBER OR TI: ; ; >SET /CLI=TTN:lgocli ; ; NOTE THAT THE PROMPT ISSUED IN RESPONSE TO A CONTROL/C DEFAULTS TO THE ; NAME OF THE CLI WHICH IS "lgocli>". ; ; IT CAN BE ELIMINATED FROM THE SYSTEM BY THE FOLLOWING COMMANDS, ASSUMING ; NO TERMINALS ARE SET TO IT: ; ; >CLI /ELIM=lgocli ; >REM ...lgo ; ; EXPERIMENT WITH THE OTHER OPTIONS ON THE CLI /INIT COMMAND, THE ENABLE ; AND DISABLE CLI COMMANDS, AND LEAVING OFF THE /MESSAGE SWITCH ON THE /INIT ; COMMAND TO OBSERVE THE EFFECT THEY HAVE. ALSO TRY CHANGING THE /TASK= ; SWITCH ON THE INS AND CLI /INIT COMMAND TO "/TASK=lgocli" AND NOTICE ; THAT ONLY ONE COPY OF THE TASK WILL EXIST FOR ALL TERMINALS, RATHER THAN ; ONE PER COMMAND. IF THIS IS DONE, YOU SHOULD ALSO CHANGE THE OPTION ; ON THE GCCI$ DIRECTIVE FROM GC.CEX TO GC.CST SO THE TASK WILL STAY ACTIVE ; BUT STOPPED WHEN NO COMMANDS ARE OUTSTANDING FOR IT. ; .MCALL GCCI$,RPOI$,EXIT$S,QIOW$,ALUN$,DIR$ ; ; DIRECTIVE DPBS ; GCCI: GCCI$ CMDBUF,CBLEN,IBUF,IBLEN,0,GC.CEX RPOI: RPOI$ MCR... QIOW: QIOW$ IO.WVB,5,1,,,,<,,40> ALUN: ALUN$ 5 ; ; BUFFER AREAS ; CMDBUF: .BLKB 80.+G.CCBF ;LENGTH = HEADER PLUS COMMAND IN BYTES ;NOTE THAT ON M-PLUS THE MAXIMUM COMMAND ;LENGTH IS 255. BYTES, SO THE LENGTH SHOULD ;BE <255.+G.CCBF> OR CHARACTERS MAY BE LOST. CBLEN=.-CMDBUF ;CALCULATE LENGTH .EVEN IBUF: .BLKB G.CCCA+2 ;LONG ENOUGH TO CONTAIN ALL INFORMATION IBLEN=.-IBUF ;CALCULATE LENGTH .EVEN wnam: .rad50 /...who/ wcmd: .ascii /who/ ; who command wlen=.-wcmd ; who command length .even rnam: .rad50 /...rmd/ rcmd: .ascii /rmd/ ; rmd command rlen=.-rcmd ; length of rmd command .even hlbuf: .blkb 80. ; buffer to generate commands in .even hlpcmd: .ascii /help/ ; basic part of hel... command hlplen=.-hlpcmd ; length of hel... command hlpbuf: .blkb 80.-hlplen ; buffer to generate commands in .even ; ; TEXT TO BE DISPLAYED UPON RECEIPT OF NEW TERMINAL LINKED OR ; TERMINAL REMOVED MESSAGES FROM SYSTEM. ; LKT: .ASCII <15><12>/WELCOME TO THE LOGGED OUT TERMINAL CLI/<15><12> LKTLEN=.-LKT .EVEN RMT: .ASCII <15><12>/GOOD BYE FROM THE LOGGED OUT TERMINAL CLI/<15><12> RMTLEN=.-RMT .EVEN ; ; CHARACTERS LOST DUE TO BUFFER BEING TO SMALL MESSAGE ; CHLOST: .ASCII <15><12>/LGOCLI - SORRY, PART OF YOUR COMMAND WAS LOST/<15><12> CLLEN=.-CHLOST ; ; ILLEGAL COMMAND MESSAGE ; ILL: .ASCII <15><12>/LGOCLI - ILLEGAL COMMAND/<15><12> ILLLEN=.-ILL .EVEN ; ; CLI CODE ; .ENABL LSB START: DIR$ #GCCI ;GET A COMMAND FROM SYSTEM bcc ok ; if cc, ok jmp 100$ ;IF CS, DIRECTIVE ERROR ; ; IF THE GCCI$ DIRECTIVE HAD THE GC.CST OPTION SPECIFIED, WE MAY HAVE ; JUST BEEN UNSTOPPED, SO WE HAVE TO GET THE COMMAND. ; ok: CMP #IS.CLR,$DSW ;WERE WE JUST UNSTOPPED? BEQ START ;IF EQ YES MOV #CMDBUF,R0 ;POINT TO COMMAND BUFFER TST (R0) ;IS THIS A SYSTEM MESSAGE? bne nomsg ; no, it is not jmp MSG ;IF EQ YES ; BPT nomsg: CMPB G.CCCT(R0),G.CCCL(R0) ;DID ENTIRE COMMAND FIT IN BUFFER beq hioreq bhi hioreq ; if hi yes jmp 150$ ;IF LO NO hioreq: MOV #RPOI,R5 ;POINT TO DPB OF RPOI$ DIRECTIVE ; ; AT THIS POINT, THE CLI HAS A COMMAND TO BE PROCESSED. THE CODE FROM ; THE "START:" LABEL TO HERE SHOULD BE FAIRLY COMMON AMONG ALL CLIS. ; FROM THIS POINT ON, THE CODE WILL BE SPECIFIC TO THE PARTICULAR LANGUAGE ; THIS CLI IS IMPLEMENTING. COMMANDS CAN BE ADDED OR DELETED AT WILL ; BY MODIFYING CODE IN THIS SECTION. AS STATED ABOVE, THIS EXTREMELY ; SIMPLE CLI PROVIDES TWO COMMANDS, AND GIVES EVERYTHING ELSE TO MCR. ; THIS CREATES AN OPEN ENDED ENVIRONMENT. REJECTING UNRECOGNIZED COMMANDS ; INSTEAD OF PASSING THEM TO MCR WOULD LIMIT THE TERMINAL USER'S USE OF ; THE SYSTEM TO ONLY THOSE OPERATIONS ALLOWED BY THE CLI. THIS IS ; A SECURE WAY OF CONTROLLING SYSTEM USE, IN CASES WHEN IT IS NECESSARY. ; IN THIS EXAMPLE, CHANGING THE "BNE 50$" BELOW, TO A "BNE 60$" ; WOULD CREATE AN ENVIRONMENT WHERE THE ONLY OPERATION A USER COULD ; PERFORM WOULD BE TO TYPE FILES ON THE TERMINAL, OR SWITCH BACK TO MCR. ; ALL OF THE REST OF RSX IS TOTALLY INACCESSABLE. IF NO MEANS OF SWITCHING ; BACK TO MCR IS PROVIDED, IT WOULD BE IMPOSSIBLE FOR THE USER TO DO ; ANYTHING THE CLI DOES NOT EXPLICITLY LET HIM DO. ; cmp #"wh,g.ccbf(r0) ; is it a who command? beq 10$ ; yes... cmp #"WH,g.ccbf(r0) ; is it a WHO command? beq 10$ ; yes... cmp #"rm,g.ccbf(r0) ; is it a rmd command? beq 20$ ; yes... cmp #"RM,g.ccbf(r0) ; is it a RMD command? beq 20$ ; yes... 2$: cmp #"he,g.ccbf(r0) ; is it a he command? bne 3$ ; no... cmp #"lp,g.ccbf+2(r0) ; is it help? beq 40$ ; yes cmpb #'l,g.ccbf+2(r0); no, so is it hel? beq 50$ ; yes... 3$: cmp #"HE,g.ccbf(r0) ; is it a HE command? bne 4$ cmp #"LP,g.ccbf+2(r0) ; is it HELP? beq 40$ ; yes, help..... cmpb #'L,g.ccbf+2(r0); no, so is it HEL? beq 50$ ; yes 4$: BNE 60$ ;IF NE NO command 10$: mov wnam,r.potk(r5) ; get word 1 of task name mov wnam+2,r.potk+2(r5) ; get word 2 of task name mov #wcmd,r.pobf(r5) ; put address of who command in dpb mov #wlen,r.pobl(r5) ; put length of command in dpb br isscmd ; issue command 20$: mov rnam,r.potk(r5) ; get word 1 of task name mov rnam+2,r.potk+2(r5) ; get word 2 of task name mov #rcmd,r.pobf(r5) ; put address of rmd command in dpb mov #rlen,r.pobl(r5) ; put length of command in dpb br isscmd ; issue command 40$: MOV R0,R1 ;COPY ADDRESS OF BUFFER WITH COMMAND ADD #G.CCBF+4,R1 ;POINT TO SPACE AFTER THE help MOV #hlpBUF,R2 ;POINT TO BUFFER THAT WILL CONTAIN CMD MOV #hlpLEN,R4 ;GET LENGTH OF INITIAL PART OF COMMAND 42$: MOVB (R1)+,R3 ;GET NEXT CHARACTER CMPB #15,R3 ;IS IT THE END OF THE COMMAND BEQ 44$ ;IF EQ YES MOVB R3,(R2)+ ;PUT CHARACTER IN OUTPUT BUFFER INC R4 ;COUNT CHARACTER BR 42$ ;GET NEXT CHARACTER 44$: MOV #hlpCMD,R.POBF(R5);PUT ADDRESS OF CMD TO ISSUE IN DPB MOV R4,R.POBL(R5) ;INSERT LENGTH OF COMMAND br isscmd 50$: MOV R0,R1 ;COPY ADDRESS OF BUFFER WITH COMMAND ADD #G.CCBF,R1 ;POINT TO ENTIRE HEL??? COMMAND MOV #hlBUF,R2 ;POINT TO BUFFER THAT WILL CONTAIN CMD MOV #0,R4 ;SET LENGTH OF INITIAL PART OF COMMAND 52$: MOVB (R1)+,R3 ;GET NEXT CHARACTER CMPB #15,R3 ;IS IT THE END OF THE COMMAND BEQ 54$ ;IF EQ YES MOVB R3,(R2)+ ;PUT CHARACTER IN OUTPUT BUFFER INC R4 ;COUNT CHARACTER BR 52$ ;GET NEXT CHARACTER 54$: MOV #hlbuf,R.POBF(R5);PUT ADDRESS OF CMD TO ISSUE IN DPB MOV R4,R.POBL(R5) ;INSERT LENGTH OF COMMAND ; ; ISSUE RPOI$ DIRECTIVE TO EXECUTE COMMAND ; ISSCMD: MOV (R0),R.PODV(R5) ;PUT NAME OF ISSUING DEVICE IN RPOI MOVB G.CCUN(R0),R.POUN(R5) ;COPY UNIT NUMBER MOVB IBUF+G.CCPU,R.POUM(R5) ;PROPOGATE UIC OF TERMINAL MOVB IBUF+G.CCPU+1,R.POUG(R5) MOV IBUF+G.CCOA,R.POOA(R5) ;COPY ID PARENT IN CASE WE WERE SPAWNED DIR$ #RPOI ;PASS COMMAND TO EXECUTOR TASK bcs 110$ ; error ; mov r.pobf(r5),r1 ; ; mov r.pobl(r5),r2 ; call issmsg jmp START ;IF CC, SUCCESS ; ; CONTROL IS TRANSFERED HERE IF UNKNOWN COMMANDS ARE TO BE REJECTED ; INSTEAD OF BEING PASSED TO MCR. ; 60$: MOV #ILL,R1 ;POINT TO MESSAGE TO BE PRINTED MOV #ILLLEN,R2 ;GET LENGTH OF MESSAGE CALL ISSMSG ;ISSUE MESSAGE jmp START ;TRY FOR NEXT COMMAND ; ; ERROR HANDLING CODE ; 100$: CLR R0 ;FATAL ERROR ON GCCI$ BR 150$ 110$: MOV #1,R0 ;FATAL ERROR ON RPOI$ mov $dsw,r1 120$: IOT ;FATAL 150$: MOV #CHLOST,R1 ;POINT TO MESSAGE TO BE PRINTED MOV #CLLEN,R2 ;GET LENGTH OF MESSAGE CALL ISSMSG ;ISSUE MESSAGE jmp START .DSABL LSB ; ; A SYSTEM MESSAGE WAS RECEIVED INSTEAD OF A COMMAND ; MSG: CMPB #CM.LKT,G.CCUN(R0) ;IS IT A NEW TERMINAL LINKED TO US? BEQ 10$ ;IF EQ YES CMPB #CM.RMT,G.CCUN(R0) ;IS IT A TERMINAL BEING REMOVED BEQ 20$ ;IF EQ YES CMPB #CM.EXT,G.CCUN(R0) ;IS IT A ELIMINATE ALL PACKET BEQ 50$ ;IF EQ YES CMPB #CM.ELM,G.CCUN(R0) ;IS IT A CLI ELIMINATION MESSAGE BEQ 50$ ;IF EQ YES jmp START ;IGNORE ALL OTHER MESSAGES ; ; ISSUE WELCOME MESSAGE ; 10$: MOV #LKT,R1 ;POINT TO MESSAGE TEXT MOV #LKTLEN,R2 ;GET LENGTH ADD #G.CCBF,R0 ;POINT TO TERMINAL THAT WAS SET BR 30$ ; ; ; ISSUE GOOD BYE MESSAGE ; 20$: MOV #RMT,R1 ;POINT TO MESSAGE TEXT MOV #RMTLEN,R2 ;GET LENGTH ADD #G.CCBF,R0 ;POINT TO TERMINAL NAME 30$: CALL ISSMSG ;ISSUE MESSAGE JMP START ;GET NEXT COMMAND ; ; WHEN AN ELIMINATE ALL MESSAGE IS RECEIVED, EXIT IMMEDIATELY ; 50$: EXIT$S ; ; ROUTINE TO PRINT TO TERMINAL ; ; ; INPUTS: ; ; R0=ADDRESS OF NAME OF TERMINAL TO PRINT TO ; R1=ADDRESS OF MESSAGE TO PRINT ; R2=LENGTH OF MESSAGE ; ; OUTPUTS: ; ; NONE ; ; THIS ROUTINE PRINTS THE SPECIFIED MESSAGE ON THE SPECIFIED TERMINAL. ; ALL ERRORS THAT MIGHT RESULT ARE IGNORED. IN GENERAL, CLIS SHOULD ; DO ASYNCHRONOUS I/O WITH COMPLETION AST'S, AND PROVIDE A TIMEOUT ; FACILITY TO KILL THE I/O IF IT HASN'T COMPLETED IN A CERTAIN ; AMOUNT OF TIME IN ORDER TO PREVENT TERMINAL I/O FROM HOLDING UP ; COMMAND PROCESSING. THIS IS NOT DONE HERE FOR SIMPLICITY. ; ISSMSG: MOV (R0),ALUN+A.LUNA ;SET UP DEVICE NAME MOVB 2(R0),ALUN+A.LUNU ;AND UNIT NUMBER CLRB ALUN+A.LUNU+1 ;CLEAR HIGH BYTE DIR$ #ALUN ;ASSIGN LUN 5 TO THE SPECIFIED DEVICE BCS 10$ ;IF CS, SKIP I/O MOV R1,QIOW+Q.IOPL ;SET ADDRESS OF MESSAGE MOV R2,QIOW+Q.IOPL+2 ;INSERT LENGTH OF MESSAGE DIR$ #QIOW ;DO I/O AND WAIT FOR IT 10$: RETURN .END START