.TITLE TLOGGR - TERMINAL ACTIVITY LOGGER TASK .IDENT /JN1.11/ ;WRITTEN BY J. NEELAND ;LAST MODIFIED 790413. ; ;MODIFIED 780715. TO PROVIDE HEADER RECORD WITH # TT'S, VT'S, & BS'S ;MODIFIED 790401. TO PROVIDE SUPPORT FOR WHODIS REQUEST (GET INFO ABOUT ; REQUESTING TERMINAL ;MODIFIED 790413. TO INCLUDE LOGIN SY: DEVICE INFO ; ;PURPOSE: TO RECEIVE MESSAGES FROM OTHER TASKS AND USE THOSE REQUESTS TO ; MANIPULATE THE TERCOM COMMON AREA DATABASE. ;RECEIVE MSG. FORMAT: BYTE 0 IS THE OPCODE. IMPLEMENTED CODES CURRENTLY ARE: ; 0: NO-OP ;-------------------- ; 1: LOGIN TERMINAL ; FORMAT OF INCOMING DATA: ; BYTE 0: OPCODE: =1 ; BYTE 1: TERMINAL # ; BYTE 2-3: TERMINAL TYPE IN ASCII ('TT', 'VT', 'BS', ETC.) ; BYTE 4-5: LOGIN UIC (GROUP,MEMBER) ; BYTE 6-19: LOGIN NAME IF ANY, LEFT-JUSTIFIED AND BLANK-FILLED ; BYTE 20-23: LOGIN SY: DEVICE (DVNN) ; BYTE 24-25: UNDEFINED ;-------------------- ; 2: LOGOUT TERMINAL ; FORMAT OF INCOMING DATA: ; BYTE 0: OPCODE: =2 ; BYTE 1: TERMINAL # ; BYTE 2-3: TERMINAL NAME IN ASCII (SEE LOGIN) ; BYTE 4-25: UNDEFINED ;-------------------- ; 3: WHODIS FUNCTION (RETURN RECORD FOR REQUESTING TERMINAL) ; FORMAT OF INCOMING DATA: ; BYTE 0: OPCODE: =3 ; BYTE 1-25: UNDEFINED ; RETURNS FOLLOWING IN MESSAGE TO REQUESTING TASK: ; BYTE 0: FLAGS (SEE GENERAL TERCOM FORMAT DESCRIPTION FOR MORE INFO) ; BYTE 1: TERMINAL NUMBER (BINARY) ; BYTE 2-3: TERMINAL TYPE IN ASCII ('TT','VT', ETC.) ; BYTE 4-5: LOGIN UIC (GROUP,MEMBER) ; BYTE 6-19: LOGIN NAME (ASCII, TRAILING SPACE-FILLED) ; BYTE 20-25: UNDEFINED ; ------------------ ; ; FORMAT OF 1ST TERCOM RECORD, NOT MODIFIED BY TLOGGR: (64 BYTES LONG) ; WORD 0=#TT'S ; WORD 1=#VT'S ; WORD 2=#BS'S ; FORMAT OF SUCCEEDING TERCOM RECORDS: (64 BYTES LONG) ; BYTE 0: FLAGS: BIT 0=MAICOF ; FLAG FOR MAIL CHK OFF (1=CHECKING OFF) ; BIT 1=LOGFLG ; FLAG FOR THIS TERMINAL LOGGED-IN ; BYTE 1: TERMINAL # (BINARY) ; BYTE 2-3: TERMINAL NAME ('TT', 'VT', 'BS', ETC.) ; BYTE 4-5: LOGIN UIC ; BYTE 6-19: LOGIN NAME (LEFT-JUSTIFIED, SPACE-FILLED) ; BYTE 20-23: LOGIN SY: DEVICE (DVNN) ; BYTE 24-35: LOGIN TIME ; BYTE 36-47: LOGOUT TIME ; BYTE 48-63: UNDEFINED ; ; FORMAT OF TERCOM: (MIN LENGTH = *64. BYTES) ; 1 RECORD TO DEFINE NTT, NVT, & NBS ; NTT RECORDS FOR TTNN: ; NVT RECORDS FOR VTNN: ; NBS RECORDS FOR BSNN: ;DEFINE SOME BITS MAICOF=1 ;BIT FOR MAIL CHECKING OFF LOGFLG=2 ;BIT FOR LOGGED-IN TERMINAL NOTRM=4 ;RETURN THIS BIT ON FOR RCV/SND OPCODES ; WHEN NO CORRESPONDING TERMINAL ; .MCALL DIR$,RCVX$,GTIM$,GLUN$,SDAT$,CALLR DEBUG=0 ;ADD SOME STUFF FOR DEBUGGING PURPOSES .IF DF DEBUG ;INSERT SOME DEBUGGING CALLS, BUFFERS, ETC. .MCALL QIOW$ OUTQIO: QIOW$ IO.WBT,1,1,,,,<0,0,40> OUTBFB: .BYTE 7 ;BELL FOR LEADING TERCOM MSG OUTBUF: .BLKB 80. ;A BUFFER FOR PRINTING TERCOM RESULTS ILCMSG: .ASCII /TLOGGR - ILLEGAL OPCODE RECEIVED/ ILCSIZ=.-ILCMSG .EVEN .ENDC ;DEBUG MSGBUF: .BLKW 2 ;BUFFER FOR RECEIVE MESSAGE MSGTXT: .BLKW 13. ;TEXT AREA OF INCOMING MESSAGE TIMBUF: ;REF. LABEL (SAME BUFFER AS LUNBUF) LUNBUF: .BLKW 8. ;BUFFER FOR LUN & TIME INFORMATION GTILUN: GLUN$ 5,LUNBUF ;GET INFORMATION ABOUT TI: (LUN 5!!) GTM: GTIM$ LUNBUF ;DIRECTIVE TO GET THE CURRENT DATE & TIME RCVX: RCVX$ ,MSGBUF ;DIRECTIVE TO RECEIVE DATA OR EXIT. ;FROM ANY TASK. SNDX: SDAT$ ,MSGTXT ;USE RECEIVE BUFFER TO RESPOND FROM ;FILL IN TASK NAME AT RUN-TIME ; TLOGGR::DIR$ #RCVX ;WHAT IF ANYTHING DO WE HAVE? MOVB MSGTXT,R0 ;GET THE OP-CODE BLT BADCOD ;WAS IS TOO LITTLE? CMPB R0,#MAXOP ;NO, IS IT A LEGAL OP-CODE? BLE OKCODE BADCOD: ;REF. LABEL .IF DF DEBUG ;INSERT SOME DIAGNOSTIC CODE MOV #ILCMSG,OUTQIO+Q.IOPL ;SEND A MESSAGE TO OUR TI: MOV #ILCSIZ,OUTQIO+Q.IOPL+2 DIR$ #OUTQIO .ENDC ;DEBUG ;NORMALLY WE DON'T EXPECT AN ILLEGAL CODE JMP TLOGGR ; & GO TRY FOR ANOTHER MSG. ; OKCODE: ;REF. LABEL ASL R0 ;CONVERT OPCODE TO WORD OFFSET JMP @OPADTB(R0) ;GO TO THE OPCODE ; OPADTB: .WORD OP0 .WORD OP1 .WORD OP2 .WORD OP3 MAXOP=<.-OPADTB>/2 ;CALCULATE NUMBER OF LEGAL OPCODES ; OP0: JMP TLOGGR ;GO TRY FOR A NEW MSG. ; OP1: CALL SETPOS ;SET R5 TO BEGINNING OF REQUESTED RECORD BCS TLOGGR ;GO FOR MORE LEGIT. MESSAGE (WRONG TYPE/NUMBER) MOV R5,-(SP) ;SAVE IT BISB #LOGFLG,(R5)+ ;SET LOGGED-IN STATUS & BUMP POINTER. MOV #MSGTXT+1,R1 ;GET INCOMING BUFFER ADDR. MOV #23.,R4 ;SET COUNT OF BYTES TO COPY CPYOP1: MOVB (R1)+,(R5)+ ;COPY THE DATA INTO THE TERCOM RECORD SOB R4,CPYOP1 CALL GETIM ;SET THE TIME INFO INTO THE TERCOM RECORD MOV (SP)+,R4 ;RECOVER ADDR. OF BEGINNING OF TERCOM RECORD .IF DF DEBUG ;INSERT CODE TO TYPE OUT TERCOM RECORD: CALL DSPIN ;OUTPUT TERMINAL, NAME, ETC. ADD #4,R4 ;SKIP LOGIN SY: DEVICE NAME CALL DATIM ;OUTPUT LOGIN DATE & TIME OUTREC: MOV #OUTBUF,OUTQIO+Q.IOPL ;SET UP QIO TO OUTPUT TEXT SUB #OUTBUF,R0 ;CALC. LENGTH OF MESSAGE MOV R0,OUTQIO+Q.IOPL+2 ;SET IT DIR$ #OUTQIO ;DISPLAY RESULTS MOV #2,OUTQIO+Q.IOLU;GET READY FOR SECOND SEND MOV #OUTBFB,OUTQIO+Q.IOPL ;READJUST PTR TO INCLUDE BELL INC OUTQIO+Q.IOPL+2 ;READJUST LENGTH TO INCLUDE BELL DIR$ #OUTQIO ;DISPLAY RESULTS FOR 2ND TERMINAL MOV #1,OUTQIO+Q.IOLU ;RESET LUN FOR BASIC QIO SKELETON .ENDC ;DEBUG JMP TLOGGR ;GO LOOK FOR ANOTHER MESSAGE ; OP2: CALL SETPOS ;GET THE RECORD START LOCATION BCS TLOGGR ;CARRY SET IF ILLEGAL DEVICE TYPE OR NUMBER MOV R5,-(SP) ;SAVE THE POINTER BICB #LOGFLG,(R5) ;CLEAR THE LOGGED-IN FLAG ADD #36.,R5 ;MOVE POINTER TO LOGOUT TIME FIELD CALL GETIM ;SET IN LOGOUT TIME MOV (SP)+,R4 ;RECOVER THE POINTER TO CLEAN THE STACK .IF DF DEBUG ;IF DEBUGGING, OUTPUT COMPLETE RECORD CALL DSPIN ;GET THE TERMINAL #, NAME, UIC, ETC. ADD #4,R4 ;SKIP THE LOGIN SY: DEVICE CALL DATIM ;DISPLAY LOGIN DATE & TIME CALL DATIM ;CONVERT LOGOUT TIME TOO JMP OUTREC ;GO OUTPUT VIA LOGIN CODE .ENDC ;DEBUG JMP TLOGGR ;GO LOOK FOR ANOTHER MESSAGE OP3: MOV MSGBUF,SNDX+S.DATN ;TRANSFER TASK NAME FROM INCOMING BUFFER MOV MSGBUF+2,SNDX+S.DATN+2 ; TO OUTPUT QIO TO SEND RESPONSE DIR$ #GTILUN ;GET INFO ABOUT MY TI: MOV LUNBUF,MSGTXT+2 ;COPY MY LUN NAME OVER TO RECEIVE BUFFER MOVB LUNBUF+2,MSGTXT+1 ; FOLLOWED BY UNIT NUMBER, TO LOOK SAME AS ; LOGIN MESSAGE FORMAT CALL SETPOS ;TRY TO FIND SUCH A UNIT BCS RETBAD ;IF NOT FOUND, RETURN SPECIAL FLAG SETTING MOV #12.,R1 ;GOOD, RETURN 1ST 12 WORDS FROM RECORD IN TERCOM MOV #MSGTXT,R0 ; TO MESSAGE BUFFER FOR SEND DIRECTIVE CPY10W: MOV (R5)+,(R0)+ SOB R1,CPY10W SNDMSG: DIR$ #SNDX ;SEND RESULTS BACK TO REQUESTER JMP TLOGGR ; & GO LOOK FOR MORE WORK TO DO RETBAD: MOVB #NOTRM,MSGTXT ;RETURN SPECIAL FLAG BIT TO SHOW ERROR BR SNDMSG ; & RESPOND ANYWAY SO TASK WON'T WAIT FOREVER ;+ ;SUBROUTINES ;- SETPOS: MOV #1,R4 ;SET INITIAL OFFSET TO 1ST TT RECORD MOV #TERCOM,R5 ;GET THE COMMON AREA ADDR. MOVB MSGTXT+1,R0 ;GET THE TERMINAL # FOR CHECKING BLT BADARG ;TERMINAL # MUST BE POSITIVE CMPB MSGTXT+2,#'T ;IS THIS TERMINAL A TT? BNE VTQ ;NO, GO TEST FOR A VT CMPB MSGTXT+3,#'T ;IS IT A 'TT'? BNE BADARG ;NO, IGNORE THE MESSAGE CMP R0,(R5) ;YES, IT'S A TTNN:, IS NN CORRECT? ; 1ST WORD OF TERCOM IS NTT'S BGT BADARG ;NO IF TOO LARGE BR ADRGET ;JUMP TO COMMON RECORD ADDRESS GET VTQ: CMPB MSGTXT+2,#'V ;IS THIS A 'VT'? BNE BSQ ;GO CHECK FOR A 'BS' CMPB MSGTXT+3,#'T ;IS IT A 'VT'? BNE BADARG ;NO CMP R0,2(R5) ;YES, BUT IS IT A LEGAL VTNN:? ; 2ND WORD IN TERCOM IS NVT'S BGT BADARG ADD (R5),R4 ;OFFSET BY #TT RECORDS BR ADRGET BSQ: CMPB MSGTXT+3,#'S ;IS THIS REALLY A 'BS' TERMINAL? BNE BADARG ;NO CMP R0,4(R5) ;YES, BY JINGO, BUT IS IT A LEGAL #? BGT BADARG ;WELL, NO ADD (R5),R4 ;ADD OFFSETS FOR #TT'S, #VT'S ADD 2(R5),R4 ADRGET: ADD R0,R4 ;OFFSET BY REQUESTED DEVICE # ASH #6.,R4 ;CONVERT TO A RECORD OFFSET ADD R4,R5 ;ADJUST THE POINTER CLC ;INDICATE SUCCESSFUL OPERATION RETURN BADARG: SEC ;RETURN BAD TYPE/NUMBER FLAG RETURN ; GETIM: DIR$ #GTM ;GET TIME FROM EXEC MOV #6,R3 ;COPY 6 OF THE 8 WDS MOV #TIMBUF,R2 ; IGNORING TICKS AND TICKS/SEC 10$: MOV (R2)+,(R5)+ ;COPY TO PRESET POINTER AREA (R5) SOB R3,10$ RETURN ;DONE COPYING THE DATE, HRS, MINS, & SECS .IF DF DEBUG ;DON'T NEED THIS STUFF EXCEPT FOR DEBUGGING DSPIN: MOV #OUTBUF,R0 ;SET OUTPUT BUFFER POINTER MOVB (R4)+,R1 ;GET THE FLAGS BYTE MOV #1,R2 ;SET FOR NO SUPPRESSION CALL $CBTMG ;DISPLAY FLAGS MOVB (R4)+,-(SP) ;SAVE THE DEVICE NUMBER FOR A MOMENT MOVB (R4)+,(R0)+ ;COPY THE DEVICE NAME MOVB (R4)+,(R0)+ MOVB (SP)+,R1 ;RECOVER THE DEVICE # MOV #11010,R2 ;SET FOR OCTAL CONVERSION, 2 PLACES, NO ZRO SUP. CALL $CBTA ;DO IT MOVB #':,(R0)+ ;INSERT A ':' MOVB #'[,(R0)+ ;SURROUND UIC W/ BRACKETS MOVB (R4)+,R1 ;GET GRP # MOV #1,R2 ;SET FOR NO ZERO SUP. CALL $CBTMG ;CONVERT THE BYTE MOVB #',,(R0)+ ;INSERT A COMMA MOVB (R4)+,R1 ;GET THE MEMBER # MOV #1,R2 ;DO SAME AS FOR GRP CALL $CBTMG MOVB #'],(R0)+ ;CLOSE BRACKETS MOVB #'<,(R0)+ ;BEGIN NAME W/ ANGLE BRACKET MOV #14.,R3 ;SET COUNT OF CHARS TO COPY 10$: MOVB (R4)+,(R0)+ ;COPY THE NAME SOB R3,10$ ;UNTIL ALL 14. CHARS HAVE BEEN MOVED MOVB #'>,(R0)+ ;CLOSE NAME FIELD RETURN ; DATIM: MOVB #40,(R0)+ ;INSERT A SPACE MOV R4,R1 ;SET R1 TO ADDR. OF DATE FIELD CALL $DAT ;CONVERT DATE MOVB #40,(R0)+ ;INSERT A SPACE MOV R4,R1 ;SET R1 TO ADDR. OF TIME FIELD ADD #6,R1 ;BUMP PAST DATE FIELD ADD #12.,R4 ;MOVE R4 PAST DATE & TIME STUFF MOV #3,R2 ;CONVERT TIME TO HH:MM:SS CALLR $TIM ;CALL & USE EXISTING RETURN ; .ENDC ;DEBUG ;END OF DEBUGGING CONVERSION ROUTINES ; .END TLOGGR