.TITLE VTL - Virtual Terminal Logger .IDENT /V01.0/ .ENABLE LC .NLIST BEX ; ; ; ; Version 1.0 Rick Webster June 18, 1984 ; ;+ ; Function: ; VTL is a utility to allow a virtual terminal to be ; accessed from an actual physical terminal. Commands ; can be entered to the VTL> prompt the same as to an ; MCR prompt ">". VTL will spawn the command to MCR ; running on the virtual terminal that VTL creates. ; Any output directed to the virtual terminal by any ; spawned task will be displayed on the user's TI: ; Optionally, the data can be logged to a file at the ; same time, creating an exact log of all the data that ; appears on the screen during the interactive terminal ; session. While VTL is waiting for a spawned task to ; complete, the user can force VTL to detach his TI: ; so that he can do something else. In the meantime, VTL ; will still log everything that would have appeared on the ; screen to the log file. ; ; Operation: ; ; VTL ; ; Constraints: ; You should not run tasks which rely on unsolicited character ; input (such as RMD) or use single character reads to handle ; escape sequences (such as EDT in screen mode). There is no ; way to pass unsolicited input to a task spawned on a virtual ; terminal. If you do start RMD for example, it will have to ; be aborted from another terminal or in response to a VTL ; unsolicited CTRL-C prompt. Since VTL attaches your terminal ; for unsolicited input while it is waiting for a spawned ; command, single character reads of cursor and aux. keypad ; keys is not possible. The first character will go to ; the task but the remaining will probably be sucked up by ; VTL's unsolicited char AST routine causing invalid input ; error messages from VTL. ; ; Program ; I/O: ; o Communications to spawned tasks via QIO's to virtual terminal ; o Output to user terminal, optionally disabled ; o Optional writing to a log file ; ; Directive ; Macro ; Calls: ; .MCALL ALUN$ .MCALL ASTX$S .MCALL CLEF$S .MCALL CRVT$S .MCALL DIR$ .MCALL EXIT$S .MCALL FCSMC$ .MCALL GIN$S .MCALL MRKT$S .MCALL QIO$ .MCALL QIO$S .MCALL QIOW$ .MCALL QIOW$S .MCALL RCVD$ .MCALL RCVD$S .MCALL RQST$ .MCALL SDAT$ .MCALL SETF$S .MCALL SPWN$ .MCALL SRDA$S .MCALL STSE$S .MCALL WTSE$S ; ;- .PAGE .SBTTL VTL Data ; FCSMC$ FSRSZ$ 1 .PSECT VTLDAT,RW,D VTUNIT: .WORD 0 ; Virtual terminal unit number ASTBUF: .BLKB 84. ; Input buffer in AST routines CMDLIN: .BLKB 84. ; Command line to be spawned INBUF: .BLKW 300. ; Data input from tasks running on VT IBUFSZ=.-INBUF ; Max size of input TTSTAT: .WORD 0,0 ; TI: I/O status block when in AST routine PRSTAT: .WORD 0,0 ; TI: I/O stat block when not in AST INSTAT: .WORD 0,0 ; I/O stat block for data input from VT STSTAT: .WORD 0,0 ; I/O stat. block for IO.STC UNSTAT: .WORD 0,0 ; TI: I/O stat block for CTRL-C routine INCNT: .WORD 0 ; Number of bytes to read from VT ANSEX: .WORD 0 ; Response for exit question RDABUF: .BLKW 15. ; Receive data buffer PUTCNT: .WORD 0 ; Number of bytes to write to log file PUTBUF: .BLKW 512. ; Log file buffer PUTBFL=.-PUTBUF .BLKW 10. ; Slop for above FDX: .BYTE TC.FDX ; Full duplex IO.SMC characteristic .BYTE 0 SMCHAR: .BYTE TC.TTP ; Set terminal type .BYTE T.V100 ; to VT100 .BYTE TC.SMR ; Upper case conversion .BYTE 1 ; disabled .BYTE TC.SCP ; Terminal is .BYTE 1 ; a scope SMCLTH=.-SMCHAR TTIN: QIOW$ IO.RLB,5,8.,,TTSTAT,, TTOUT: QIOW$ IO.WLB,5,8.,,TTSTAT,, INQIO: QIOW$ IO.RAL,1,1,,INSTAT,, OUQIO: QIOW$ IO.WLB,1,1,,,, STCQIO: QIOW$ IO.STC,1,1,,STSTAT,,<1,0,0> SPAWN: SPWN$ MCR...,,,,,7,,,CMDLIN ASNLUN: ALUN$ 1,VT FDB: FDBDF$ FDAT$A R.VAR,FD.CR FDRC$A FDOP$A 3,,FNAM,,FA.ENB!FA.DLK ; Do not lock log file FNAM: NMBLK$ VTL,LOG,,SY,0 ; Log file name is SY:VTL.LOG UNSCHR: .BYTE 0 ; Unsolicited input character OPENFL: .BYTE 1 ; Log file open (1 = no, -1 = yes) PUTFLG: .BYTE 0 ; File data to be flushed? (1=yes, 0=no) FSTAT: .BYTE -1 ; File (^F) status (1 = on, -1 = off) RNEFLG: .BYTE 0 ; Last TT read used TF.RNE (1=yes, 0=no) DETFLG: .BYTE 0 ; TI: is detached (1=yes, 0=no) EXFLAG: .BYTE 0 ; Exit VTL flag (1=yes, 0=no) PRFLAG: .BYTE 0 ; VTL prompt active (1=yes, 0=no) ATTFLG: .BYTE 0 ; VT attached flag (1=yes, 0=no) BYE: .ASCII /BYE/ ; ; Messages: ; VTLPR: .ASCII <15><12>/VTL>/<0><0> ENDMSG: .ASCII <15>/VTL -- Exiting/ ENDMSL=.-ENDMSG OPNERR: .ASCII <15><12><7>/VTL -- Log file open failure/<15><12> OPNERL=.-OPNERR BUFERR: .ASCII <15><12><7>/VTL -- Buffer capacity exceeded, characters truncated/<15><12> BUFERL=.-BUFERR LOGEN: .ASCII <15><12><12><7>/VTL -- Log file enabled/<15><12> LOGENL=.-LOGEN LOGDIS: .ASCII <15><12><12><7>/VTL -- Log file disabled/<15><12> LOGDIL=.-LOGDIS UNSQ: .ASCII <15><12><12><7>/VTL -- Command>/ UNSQL=.-UNSQ ASKEX: .ASCII <15><12><12><7>/VTL -- Are you sure you want to exit? / ASKEXL=.-ASKEX INVUNS: .ASCII <15><12><12><7>/VTL -- Only ^A, ^C, ^D, ^F and ^Z are valid/<15><12> INVUNL=.-INVUNS TMOMSG: .ASCII /^U/<15><12><12> TMOMSL=.-TMOMSG RETMSG: .ASCII <15><12><12><7>/VTL -- Terminal being attached/<15><12> RETMSL=.-RETMSG DETMSG: .ASCII <15><12><12><7>/VTL -- Terminal being detached/<15><12>/>/ DETMSL=.-DETMSG CONMSG: .ASCII <15><12>/VTL -- Connected to VT/ CONUN: .ASCII / / CONMSL=.-CONMSG .EVEN ; ; Data for WRATT routine ; HA.UAT=4 ;WRITE USER FILE ATTRIBUTES CODE PRMLST: ;QIO PARAMETER LIST .WORD 0 ;FILE ID POINTER .WORD ATTLST ;POINTER TO ATTRIBUTE LIST ATTLST: ;QIO ATTRIBUTE LIST .BYTE HA.UAT,S.FATT ;WRITE USER FILE ATTRIBUTES ATTADR: .WORD 0 ;THEY RESIDE AT THE BEGINNING OF THE FDB .WORD 0 ;ATTRIBUTE LIST STOPPER ; .page .SBTTL Mainline code .PSECT VTL: CRVT$S #INAST,#OUAST ; Create a virtual terminal BCC 10$ ; Branch on success MOV $DSW,R0 ; Put error in R0 MOV #1,R1 ; Flag program location IOT ; Bail out 10$: MOV $DSW,VTUNIT ; Get unit number of VT: just created MOV #CONUN,R0 ; Address to store converted number MOV VTUNIT,R1 ; Number to convert MOV #14010,R2 ; Octal, zero suppress, 3 digits CALL $CBTA ; Convert unit to ASCII MOVB #':,(R0) ; Append a colon QIOW$S #IO.WVB,#5,#5.,,,,<#CONMSG,#CONMSL> ; Tell user what VT: he has MRKT$S ,#1,#3,#LOGTMR ; Start log file output timer MOV VTUNIT,ASNLUN+A.LUNU ; Assign lun 1 to DIR$ #ASNLUN ; VT: unit just created QIOW$S #SF.SMC,#1,#1,,,,<#SMCHAR,#SMCLTH> ; Set the characteristics MOV VTUNIT,SPAWN+S.PWVT ; Set VT: as spawn terminal CALL HELCHK ; Go attempt to log this guy on QIOW$S #IO.ATA,#5,#5,,,,<,,#UNSIN> ; Attach TI: for unsolicited input ; ; SRDA$S #RDAAST ; RDDAST is recieve data AST address TTGET: TSTB DETFLG ; Is TI: detached? BEQ 5$ ; No, branch QIOW$S #IO.ATA,#5,#5.,,,,<,,#UNSIN> ; Yes, re-attach it QIOW$S #IO.WVB,#5,#5.,,,,<#RETMSG,#RETMSL> ; Tell user we re-attached CLRB DETFLG ; Indicate TI: is attached 5$: CLR CMDLIN ; Initialize input buffer MOVB #1,FDX+1 ; Set TI: to INCB PRFLAG ; Indicate prompt is active QIOW$S #SF.SMC,#5,#5,,,,<#FDX,#2> ; Full-duplex QIOW$S #IO.RPR,#5,#5,,#PRSTAT,,<#CMDLIN,#84.,,#VTLPR,#8.,#0> ; Get cmd CLRB PRFLAG ; Indicate prompt not active 10$: CMPB #IS.SUC,PRSTAT ; Successful input? BEQ 20$ ; Yes, branch CMPB #IE.EOF,PRSTAT ; CTRL-Z entered? BEQ 15$ ; Yes, go terminate CMPB #IE.ABO,PRSTAT ; Was I/O killed? BEQ TTGET ; Yes, go ask again MOV #2,R0 ; Hardware error on TI: MOV PRSTAT,R1 ; Put I/O status MOV PRSTAT+2,R2 ; block in registers IOT ; and bail out 15$: QIOW$S #IO.WVB,#5,#5,,,,<#ENDMSG,#ENDMSL,#40> ; Print "exit" message TST PUTCNT ; Any data left to go into log file? BEQ 16$ ; No, branch PUT$ #FDB,#PUTBUF,PUTCNT ; Put last bit of data in log file 16$: CLRB FDX+1 ; Set TI: to QIOW$S #SF.SMC,#5,#5,,,,<#FDX,#2> ; half duplex MOVB #1,EXFLAG ; Set exit flag MOV #BYE,SPAWN+S.PWCA MOV #3,SPAWN+S.PWCL DIR$ #SPAWN ; Spawn command line BCS 17$ ; Branch on error STSE$S #7 ; Wait for bye to exit 17$: CLOSE$ #FDB ; Close log file EXIT$S 20$: QIOW$S #IO.WVB,#5,#5,,,,<#VTLPR,#1,#0> ; Output carriage return CMPB CMDLIN,#1 ; ^A (Terminate) entered? BEQ 15$ ; Yes, do it CMPB CMDLIN,#6 ; ^F (Toggle lof file output) entered? BNE 24$ ; No, press on CALL TGLLOG ; Toggle log file output JMP TTGET ; Get another command 24$: MOV PRSTAT+2,SPAWN+S.PWCL ; Length of command line to be spawned TSTB FSTAT ; Logging to Log file? BMI 2498$ ; No, branch TST PUTCNT ; Anything to output? BEQ 2405$ ; No, branch PUT$ #FDB,#PUTBUF,PUTCNT ; Write data to log file MOVB #1,PUTFLG ; Indicate data in FSR CLR PUTCNT ; Indicate put buffer empty 2405$: MOV #PUTBUF,R4 ; Stick an MCR prompt MOVB #'>,(R4)+ ; in log file buffer INC PUTCNT ; Update buffer count MOV PRSTAT+2,R3 ; Any characters entered? BEQ 2499$ ; No, branch MOV #CMDLIN,R2 ; Address of characters entered? 2410$: MOVB (R2)+,(R4)+ ; Put characters in log file buffer SOB R3,2410$ ADD PRSTAT+2,PUTCNT ; Update buffer count BR 25$ ; Continue 2498$: TST PRSTAT+2 ; Any characters in commnad line BNE 25$ ; Yes, branch 2499$: JMP TTGET ; Go get another command line 25$: CLRB FDX+1 ; Set TI: to QIOW$S #SF.SMC,#5,#5,,,,<#FDX,#2> ; half duplex DIR$ #SPAWN ; Spawn command line BCC 30$ ; Branch on success MOV #4,R1 ; Indicate SPAWN error MOV $DSW,R0 ; Put error code with no BIC #177400,R0 ; sign extend in R0 IOT ; Bail out 30$: STSE$S #7 ; Wait for SPAWN'ed task to exit TSTB EXFLAG ; Is exit flag set? BEQ 35$ ; No, continue STSE$S #9. ; Wait for BYE to exit TST PUTCNT ; Any data left to go into log file? BEQ 32$ ; No, branch PUT$ #FDB,#PUTBUF,PUTCNT ; Put last bit of data in log file 32$: CLOSE$ #FDB EXIT$S ; Yes, exit 35$: JMP TTGET ; Get another command line ; ; .PAGE .SBTTL INAST Input from VT AST routine ;+ ; Function: ; This AST routine is executed whenever a task running on ; the virtual terminal, requires input ; ; INAST: TSTB DETFLG ; Is TI: detached? BEQ 4$ ; No, branch QIOW$S #IO.ATA,#5,#8.,,,,<,,#UNSIN> ; Re-attach TI: QIOW$S #IO.WVB,#5,#8.,,,,<#RETMSG,#RETMSL> ; Tell user we did it CLRB DETFLG ; Indicate that TI: is attached DIR$ #TTOUT ; Write last thing that would have been ; written if TI: had been attached 4$: MOV (SP)+,R3 ; R3 gets I/O subfunction bits SWAB R3 ; of offspring tasks request BIC #177400,R3 ; Make sure of no sign extend MOV R3,TTIN+Q.IOFN ; Put subfuntion bits into input QIO MOV (SP),TTIN+Q.IOPL+2 ; Put byte count into input QIO MOV (SP)+,OUQIO+Q.IOPL+2 ; Put byte count into output QIO TST (SP)+ ; Don't need VFC of offspring request CLRB RNEFLG ; Assume not "Read-no-echo" BITB #TF.RNE,TTIN+Q.IOFN ; Was it? BEQ 5$ ; No, branch INCB RNEFLG ; Yes, set "Read-no-echo" flag 5$: BIS #IO.RLB,TTIN+Q.IOFN ; Or function with subfunctions TSTB PRFLAG ; VTL prompt active? BEQ 6$ ; No, branch QIO$S #IO.KIL,#5 STSE$S #5 ; Wait for kill to complete 6$: DIR$ #TTIN ; Get input from TI: 10$: MOV #IO.RLB,TTIN+Q.IOFN ; Reset input QIO function code MOV #84.,TTIN+Q.IOPL+2 ; Reset byte count 50$: MOV TTSTAT,OUQIO+Q.IOPL+4 ; Put I/O status in returned status 100$: MOV TTSTAT+2,OUQIO+Q.IOPL+2 ; Put byte count in output QIO TST TTSTAT+2 ; Any characters to return BNE 200$ ; Yes, branch MOV TTSTAT,STCQIO+Q.IOPL+4 ; No, set up status only return QIO DIR$ #STCQIO ; Send status to offspring BR 300$ 200$: TSTB RNEFLG ; "Read-no-echo" ? BNE 250$ ; Yes, don't log TSTB FSTAT ; Logging to Log file? BMI 250$ ; No, branch MOV #PUTBUF,R4 ; R4 gets address to store ADD PUTCNT,R4 ; next character in log file buffer MOV TTSTAT+2,R3 ; R3 has number of chacters MOV #ASTBUF,R2 ; R2 has address of input buffer 220$: MOVB (R2)+,(R4)+ ; Copy input buffer to log file buffer SOB R3,220$ ADD TTSTAT+2,PUTCNT ; Update log file buffer count 250$: DIR$ #OUQIO ; Send input buffer to offspring 300$: ASTX$S ; Exit AST service routine ; ; ; .PAGE .SBTTL OUAST Output to VT AST routine ;+ ; Function: ; This AST routine is executed whenever a task running on ; the virtual terminal, desires to output data to VT ; ; OUAST: MOV (SP)+,R3 ; R3 gets subfuntion bits SWAB R3 ; from offspring request BIC #177400,R3 ; Make sure no sign extend MOV R3,TTOUT+Q.IOFN ; Put it into input QIO MOV (SP)+,INCNT ; Get number of bytes in request MOV (SP)+,TTOUT+Q.IOPL+4 ; Put VFC in TI: QIO CMP INCNT,#IBUFSZ ; Is buffer big enough? BLE 5$ ; Yes, branch MOV #IBUFSZ,INCNT ; Truncate byte count QIOW$S #IO.WVB,#5,#8.,,,,<#BUFERR,#BUFERL> ; Tell user about truncation 5$: MOV INCNT,INQIO+Q.IOPL+2 ; Set number of bytes to read DIR$ #INQIO ; Read data from offspring task TSTB EXFLAG ; Exit flag set? BEQ 9$ ; No, branch CMPB INBUF+1,#'M ; Do not print out BNE 9$ ; any MCR errors CMP INBUF+2,#"CR ; If user has already logged off BNE 9$ ; the BYE automatically spawned CMP INBUF+4,#" - ; will cause the message BEQ 20$ ; "MCR -- Not logged in" 9$: TSTB FSTAT ; Logging to log file? BMI 10$ ; No, branch CALL FILOUT ; Go log it 10$: MOV INCNT,TTOUT+Q.IOPL+2 ; Number of chars to output to TI: BIS #IO.WLB,TTOUT+Q.IOFN ; Or WLB with subfuntion bits BIC #TF.WBT,TTOUT+Q.IOFN ; Don't need BREAKTHROUGH write to TI: TSTB DETFLG ; Is TI: detached? BNE 20$ ; Yes, don't write to TI: DIR$ #TTOUT ; No, write data to TI: 20$: ASTX$S ; Exit AST service routine ; ; .PAGE .SBTTL TGLLOG Toggle output to log file ;+ ; Function: ; This routine will turn logging on if it was off and ; turn it off if it was on. ; ; ; TGLLOG: NEGB FSTAT ; Toggle file control? BMI 15$ ; MI means turned off TSTB OPENFL ; Log file open already? BMI 11$ ; Yes, branch NEGB OPENFL ; Indicate that logfile is open OPEN$W #FDB ; Open log file BCC 11$ ; Branch on success QIOW$S #IO.WVB,#5,#8.,,,,<#OPNERR,#OPNERL> ; Tell user "Open error" NEGB OPENFL ; Indicate that log file not open NEGB FSTAT ; Indicate logging not on BR 15$ 11$: MOVB #'<,VTLPR+5 ; Set VTL prompt to "VTL" MOVB #'F,VTLPR+6 MOVB #'>,VTLPR+7 QIOW$S #IO.WVB,#5,#8.,,,,<#LOGEN,#LOGENL> ; Tell user logging enabled BR 20$ 15$: MOVB #'>,VTLPR+5 ; Set VTL prompt to "VTL>" MOVB #0,VTLPR+6 MOVB #0,VTLPR+7 QIOW$S #IO.WVB,#5,#8.,,,,<#LOGDIS,#LOGDIL> ; Tell user logging disabled 20$: RETURN ; ; .PAGE .SBTTL FILOUT Output data to log file ;+ ; Function: ; This routine takes care of writing data from the offspring ; tasks to the log file. If the data has imbedded carriage ; return, line feeds, it will break it up into multiple records. ; If the data will exceed the log buffer size, it writes out ; the buffer before loading the new data. This will cause ; an extra to occur when the file is printed. ; FILOUT: MOV TTOUT+Q.IOPL+4,R1 ; Put carriage control in R1 MOV INCNT,R2 ; R2 gets character count CMP R1,#'+ ; "+" carriage control? BEQ 100$ ; Yes, branch don't output to file yet TST R1 ; Null carriage control? BEQ 100$ ; Yes, branch, no output to file 10$: PUT$ #FDB,#PUTBUF,PUTCNT ; Write data to log file MOVB #1,PUTFLG ; Indicate data in FSR CLR PUTCNT ; Clear PUT buffer char count 100$: MOV #PUTBFL,R3 ; R3 has length of PUT buffer SUB PUTCNT,R3 ; R3 has # chars available in PUT buffer CMP R3,INCNT ; Room in PUT buffer for current record? BLT 10$ ; No, go flush PUT buffer to log file MOV #PUTBUF,R4 ; R4 points to PUT buffer ADD PUTCNT,R4 ; R4 points to next avail. char in PUT buf CMP R1,#'1 ; Is carriage control formfeed? BNE 105$ ; No, branch MOVB #14,(R4)+ ; Yes, put a formfeed in the buffer INC PUTCNT ; Adjust PUT buffer char count 105$: MOV INCNT,R3 ; R3 has # of chars in current record BEQ 120$ ; If no chars then branch MOV #INBUF,R5 ; R5 points to input buffer 110$: CMP R1,#'0 ; "double space" carriage control? BNE 115$ ; No, branch PUT$ #FDB,#PUTBUF,#0 ; Output a null record to log file MOVB #1,PUTFLG ; Indicate data in FSR 115$: CMPB (R5),#15 ; Found a in input buffer? BNE 120$ ; No, branch CMP R3,#1 ; Is by itself? BEQ 120$ ; Yes, branch CMPB 1(R5),#12 ; Found a combination? BNE 120$ ; No, branch PUT$ #FDB,#PUTBUF,PUTCNT ; Yes, write data in PUT buffer MOVB #1,PUTFLG ; Indicate data in FSR CLR PUTCNT ; Clear PUT buffer count MOV #PUTBUF,R4 ; R4 has PUT buffer address ADD #2,R5 ; Bypass in input buffer DEC R3 ; Adjust loop counter BR 130$ ; Continue looping 120$: MOVB (R5)+,(R4)+ ; Put next input character into PUT buf INC PUTCNT ; Adjust PUT buffer count 130$: SOB R3,115$ ; Loop until input buffer exhausted CMP R1,#40 ; Was carriage control a space ? BEQ 150$ ; Yes, branch CMP R1,#'0 ; Was carriage control a "0" ? BEQ 150$ ; Yes, branch CMP R1,#'1 ; Was carriage control a "1" ? BEQ 150$ ; Yes, branch CMP R1,#'+ ; Was carriage control a "+" ? BEQ 150$ ; Yes, branch BR 200$ ; Don't append a 150$: MOVB #15,(R4) ; Put a into PUT buffer INC PUTCNT ; Adjust PUT buffer count 200$: RETURN .PAGE .SBTTL LOGTMR Log timer AST routine ;+ ; Function: ; This routine is entered every minute through a mark time ; directive. If there is any data in the File Storage Region ; (FSR), it will flush the block buffer (using the FCS .FLUSH ; routine) and then call WRATT to updat the files EOF block. ; This is done so that the log file can be read by other tasks ; even when VTL has it open. Also it makes the log file ; "crash-proof". The most that the file will lose is anything ; that has occurred in the last minute only. ; ; LOGTMR: TST (SP)+ ; Pop event flag mask word from stack TSTB PUTFLG ; Anything to flush? BEQ 20$ ; No, branch MOV R0,-(SP) ; Save R0 thru R5 MOV R1,-(SP) ; " MOV R2,-(SP) ; " MOV R3,-(SP) ; " MOV R4,-(SP) ; " MOV R5,-(SP) ; " MOV #FDB,R0 ; R0 points to log file FDB CALL .FLUSH ; Flush FCS block buffer CALL WRATT ; Update log file's EOF CLRB PUTFLG ; Indicate FSR is empty MOV (SP)+,R5 ; Restore R0 thru R5 MOV (SP)+,R4 ; " MOV (SP)+,R3 ; " MOV (SP)+,R2 ; " MOV (SP)+,R1 ; " MOV (SP)+,R0 ; " 20$: MRKT$S ,#1,#3,#LOGTMR ; Restart log timer ASTX$S ; .PAGE .SBTTL WRATT Write attributes from FDB ;+ ; Function: ; This routine requests the F11ACP to write the file ; attributes from the FCS file descriptor block. When a file ; is being written, some file attributes (notably F.EFBK and ; F.HIBK, the end-of-file and high-allocation block numbers) ; are not written to the file header by FCS until the file is ; closed. Thus, even if frequent calls of .FLUSH are used to ; ensure that a file contains recent information, the file ; header will not reflect this fact while the file is open. ; Another task trying to read the file (open for shared read) ; will find an end-of-file error returned on the first GET$. ; If a system crash occurs, the data in the file is ; recoverable, but only by manipulating the end-of-file block ; number in the file header, as with PIP /EOF. ; ; Attributes may be written back to the file header while a ; file is open by using a write-attributes QIO, function code ; IO.WAT, using attribute 4. ( See QIO interface to the ACPs ; in the I/O Drivers Reference Manual.) ; ; Note: This routine and the above expanation were taken from FCS.HLP ; distributed with RSX11M+ V2.1. See HELP FCS FLUSH ; ; Input: R0 = File descriptor block address ; ; Output: R0, R4, R5 - Preserved ; R1, R2, R3 - Altered ; CC - No error ; CS - FCS error code in F.ERR(R0) ;- WRATT: MOV #IO.WAT,R1 ; Write attributes function code MOV #2,R2 ; There are two DPB parameters... MOV #PRMLST,R3 ; ...at this address MOV R0,(R3) ; ADD #F.FNB+N.FID,(R3) ; FID address is the first parameter MOV R0,ATTADR ; FDB address is addr of attributes JMP .XQIO ; Have fcs execute the QIO$ .PAGE .SBTTL UNSIN Unsolicited input AST routine ;+ ; Function: ; This routine handles unsolicited input to VTL while VTL ; is waiting for a spawned task (ie. no VTL> prompt on TI:). ; The following characters are valid unsolicited input: ; ; CTRL-C - Requests VTL to read and spawn another command ; line to MCR. Note however that VTL does not wait ; for this command to complete. When the VTL> prompt ; is again displayed, it only means that the original ; command has completed, not this one. ; ; CTRL-Z - Requests that VTL terminate. The user will be ; or asked if this is really what he intended. If so ; CTRL-A VTL will log off the virtual terminal, consequently ; aborting active tasks and the virtual terminal will ; be eliminated. ; ; CTRL-F - Toggles log file output. If not currently logging, ; then logging is enabled. If currently logging then ; logging is disabled. ; ; CTRL-D - This causes VTL to detach from TI:, freeing the ; user's terminal for other uses. CTRL-D forces ; logging to be enabled so that data will be logged ; but it won't be displayed on the user's terminal. ; The terminal will automatically be re-attached when ; either a spawned task or VTL itself requires input ; from the user. VTL also displays the last line that ; would have been written to the terminal had it been ; attached so that the user has some idea of what the ; task is asking for. ; ; Any other unsolicited characters result in an error message. ; ; ; UNSIN: MOVB (SP)+,UNSCHR ; Get unsolicited character CMPB UNSCHR,#3 ; CTRL-C entered? BEQ 5$ ; Yes, branch JMP 150$ ; No, branch 5$: CLR ASTBUF ; Clear answer, prompt user for input QIOW$S #IO.RPR!TF.TMO,#5,#8.,,#UNSTAT,,<#ASTBUF,#84.,#3,#UNSQ,#UNSQL,#0> CMPB #IS.SUC,UNSTAT ; Successful input? BEQ 20$ ; Yes, branch CMPB #IS.TMO,UNSTAT ; Input timeout BNE 10$ ; No, branch QIOW$S #IO.WVB,#5,#8.,,,,<#TMOMSG,#TMOMSL> ; Echo ^U to user JMP 140$ ; Go exit AST 10$: CMPB #IE.EOF,UNSTAT ; CTRL-Z entered? BEQ 40$ ; Yes, branch JMP 140$ ; Go exit AST 20$: CMP UNSTAT+2,#1 ; One character entered? BEQ 30$ JMP 110$ ; No, branch 30$: CMPB ASTBUF,#1 ; ^A entered? BEQ 40$ ; Yes, treat the same as CTRL-Z JMP 90$ ; No, branch 40$: CLR ANSEX ; Clear answer, and ask user if he ; really wants to exit QIOW$S #IO.RPR!TF.TMO,#5,#8.,,#UNSTAT,,<#ANSEX,#2,#3,#ASKEX,#ASKEXL,#0> CMPB #IS.TMO,UNSTAT ; Response timeout? BNE 50$ ; No, branch QIOW$S #IO.WVB,#5,#8.,,,,<#TMOMSG,#TMOMSL> ; Yes, display ^U BR 80$ ; Go exit AST 50$: TST UNSTAT+2 ; Anything entered? BEQ 80$ ; No, assume he means no CMPB ANSEX,#'Y ; Was answer "Y" BEQ 60$ ; Yes, branch CMPB ANSEX,#'y ; Lowercase "y" BNE 80$ ; No, guess he means no 60$: QIOW$S #IO.WVB,#5,#8.,,,,<#ENDMSG,#ENDMSL,#40> ; Tell user we are exiting TST PUTCNT ; Anything to go to log file BEQ 70$ ; No, branch PUT$ #FDB,#PUTBUF,PUTCNT ; Output data to log file MOVB #1,PUTFLG ; Indicate data in FSR 70$: MOV #BYE,SPAWN+S.PWCA ; Set up spawn DPB MOV #3,SPAWN+S.PWCL ; spawn BYE MOV #9.,SPAWN+S.PWEF ; Use EFN 9 to indicate BYE completion DIR$ #SPAWN ; Spawn BYE SETF$S #7 ; Unstop VTL mainline code MOVB #1,EXFLAG ; Set exit flag 80$: QIOW$S #IO.WVB,#5,#8.,,,,<#VTLPR,#2,#0> ; Output JMP 160$ ; Go exit AST 90$: CMPB ASTBUF,#6 ; ^F entered BNE 100$ ; No, branch CALL TGLLOG ; Yes, toggle log file output BR 160$ ; Go exit AST 100$: CMPB ASTBUF,#4 ; ^D entered? BNE 150$ ; No, branch QIOW$S #IO.DET,#5,#8.,,,,<#UNSIN> ; Detach user's TI: QIOW$S #IO.WVB,#5,#8.,,,,<#DETMSG,#DETMSL> ; Tell him about it INCB DETFLG ; Set detach flag TSTB FSTAT ; Logging to Log file? BPL 160$ ; Yes, branch CALL TGLLOG ; No, force logging BR 160$ ; Go exit AST 110$: MOV SPAWN+S.PWCA,-(SP) ; Save spawn command line address MOV SPAWN+S.PWCL,-(SP) ; Save spawn command line length MOV SPAWN+S.PWEF,-(SP) ; Save spawn event flag number CLR SPAWN+S.PWEF ; Clear EFN so no wait on spawn MOV #ASTBUF,SPAWN+S.PWCA ; Buffer address for command line MOV UNSTAT+2,SPAWN+S.PWCL ; Command line length TST UNSTAT+2 ; Anything entered? BEQ 130$ ; No, restore spawn DPB 120$: DIR$ #SPAWN ; Spawn new command line 130$: MOV (SP)+,SPAWN+S.PWEF ; Restore spawn DPB MOV (SP)+,SPAWN+S.PWCL ; " MOV (SP)+,SPAWN+S.PWCA ; " 140$: QIOW$S #IO.WVB,#5,#8.,,,,<#VTLPR,#2,#0> ; Output JMP 160$ ; Go exit AST 150$: QIOW$S #IO.WVB,#5,#8.,,,,<#INVUNS,#INVUNL> ; Tell user invalid input 160$: ASTX$S ; .PAGE .SBTTL RDAAST Receive data AST routine ;+ ; Function: ; This routine handles re-attaching the terminal if it ; receives an appropriate receive data buffer ; RDAAST: 10$: RCVD$S ,#RDABUF CMPB #IS.SUC,$DSW BNE 100$ CMP RDABUF+4,#"AT BNE 10$ TSTB DETFLG BEQ 10$ MOV #5,ASNLUN+A.LULU MOV #"TT,ASNLUN+A.LUNA MOV RDABUF+6,ASNLUN+A.LUNU DIR$ #ASNLUN BCC 20$ MOV #"TI,ASNLUN+A.LUNA CLR ASNLUN+A.LUNU DIR$ #ASNLUN 20$: QIOW$S #IO.ATA,#5,#8.,,,,<,,#UNSIN> QIOW$S #IO.WVB,#5,#8.,,,,<#RETMSG,#RETMSL> CLRB DETFLG 100$: ASTX$S ; .PAGE .SBTTL HELCHK Attempt to log user on ;+ ; Function: ; This routine will attempt to get data from get the user's ; log in UIC from SYSLOG (M+ system accounting). It then uses ; the log in uic to log the user on. Note that an undocumented ; feature of HEL is that if a privileged task spawns HEL, then it ; can log on to an account without having to enter a password. ; After log on, it will attempt to spawn UIC (the LOG task from ; the MSDGEN distribution kit) to show the user where he is. ; The the GIN$ directive is used to set VTL non-privileged. ; This is done so that the user can log off and log back on ; using normal methods as well as keeping him from logging ; on to other accounts. If VTL is privileged, a spawned HEL ; only allows login by account number, not name, and the ; password is not required. ; ; If accounting is not running, VTL will not log on ; automatically and the user will have to log on manually. ; ; Calling sequence: ; ; CALL HELCHK ; ; Inputs: ; ; Outputs: ; ; Carry clear - success ; Carry set - error ; ; ; Info from GIN$ directive: ; ; After GI.UIC GIN$S, INBUF will contain the following: ; ; Word Description ; ---- ----------------------------------------------- ; 0 System UIC ; 1 Library UIC ; 2 H.DUIC default UIC for this task ; 3 H.CUIC protection UIC for this task ; 4 Login UIC for this terminal ; 5 Current UIC for this terminal ; 6,7 RAD50 CLI name ; 8,9,10 ASCII system name ; 11 Network UIC ; 12 System size in 32-word blocks ; ; ; ; ; Check to see if accounting is running, if not then don't try ; to log on because GI.UIC may be returning the wrong log in UIC. ; This would be the case for privileged users who have changed ; their UIC (with SET /UIC) since log in. ; HELCHK: GIN$S #GI.UAB,#INBUF,#132.,#0,#0 ; See if accounting is running BCS 100$ ; Nope, branch GIN$S #GI.UIC,#INBUF,#32. ; Get UIC info BCS 100$ ; Error, don't try to log on MOV #CMDLIN,R0 ; R0 gets command line buffer address MOVB #'H,(R0)+ ; Put "HEL " MOVB #'E,(R0)+ ; into MOVB #'L,(R0)+ ; command MOVB #' ,(R0)+ ; line MOVB INBUF+11,R1 ; Get group number of login UIC BIC #177400,R1 ; Make sure no sign extend MOV #14010,R2 ; Octal, field width = 3, suppress leading 0's CALL $CBTA ; Convert Group code to ascii MOVB #',,(R0)+ ; Append a comma MOVB INBUF+10,R1 ; Get owner code of login UIC MOV #14010,R2 ; Octal, field width = 3, suppress leading 0's CALL $CBTA ; Convert Owner code to ASCII MOV R0,SPAWN+S.PWCL ; Put command line address in spawn DPB SUB #CMDLIN,SPAWN+S.PWCL ; Length of command line DIR$ #SPAWN ; Spawn HEL BCS 100$ ; If bad, forget trying to log on STSE$S #7 ; Wait for HEL to complete MOVB #'U,CMDLIN ; Set up spawn MOVB #'I,CMDLIN+1 ; DPB MOVB #'C,CMDLIN+2 ; to MOV #3,SPAWN+S.PWCL ; spawn DIR$ #SPAWN ; UIC to show user where he's at BCS 100$ ; If failure, don't wait STSE$S #7 ; Wait for UIC to complete 100$: GIN$S #GI.SPR,#0 ; Turn off privileged task bit RETURN ;DONE! ; ; .END VTL