.TITLE CATCMD - CATCHALL ACTION ROUTINES .IDENT /1.6/ .ENABL LC ;+ ; ; Free software BY ; Project Software & Development, Inc. ; ; This software is furnished for free and may be used and copied as ; desired. This software or any other copies thereof may be provided or ; otherwise made available to any other person. No title to and ; ownership of the software is hereby transferred or allowed. ; ; The information in this software is subject to change without notice ; and should not be construed as a commitment by PROJECT SOFTWARE ; AND DEVELOPMENT, INC. ; ; PROJECT SOFTWARE assumes no responsibility for the use or reliability ; of this software on any equipment whatsoever. ; ; Project Software & Development, Inc. ; 14 Story St. ; Cambridge, Ma. 02138 ; 617-661-1444 ; ; ; Title: CATCMD.MAC ; Author: Robin Miller ; Date: September 22, 1982 ; ; Description: ; ; This module contains the various Catchall commands. ; ; Modification History: ; ; October 11, 1985 by Robin Miller. Version 1.6 ; Add the CHECK routine which determines if a terminal is busy ; or logged on by another user. ; ; October 9, 1985 by Robin Miller. Version 1.5 ; Changes: ; o Change the SEND routine to write specified string with no ; carriage control if a double plus sign "++" is specified. ; o Change the WAITS routine to delay in one second intervals ; so we can detect when something has arrived faster. ; ; January 14, 1985 by Robin Miller. Version 1.4 ; Changes: ; o Add HANGUP command to hangup a modem port. ; o Add WAIT command to wait with timeout for a string. ; o Change the FRANK command to SEND. ; ; January 3, 1985 by Robin Miller. Version 1.3 ; Spawn the "SET DEF" command to DCL twice for a privileged user. ; The first command resets the UIC to the login UIC and the second ; command resets SY0: to the login device. ; ; December 14, 1984 by Robin Miller. Version 1.2 ; Add action routine for the CHD command to pass the login UIC if ; nothing is specified and the terminal is privileged. ; ; December 13, 1984 by Robin Miller. Version 1.1 ; Changes: ; o Add action routines for EOF, ROFF, RONLY, RWE, & RWED commands. ; o Output a formfeed on the CLR command for an LA100 terminal type. ; ;- .NLIST BEX .MCALL DIR$, GLUN$, QIOW$, QIO$S, QIOW$S, WTSE$S ; Local storage: GLUN: GLUN$ TOLUN,LUNBUF ; Get LUN for the terminal. LUNBUF: .BLKW 6 ; Buffer for $GLUN. .SBTTL ATS - Issue "ACT /ALL" OR "ACT /TERM=TTnn:" Command ; ATS - List all active tasks (or only those for a terminal) ATSM1: .ASCIZ \/ALL\ ATSM2: .ASCIZ \ /TERM=\ .EVEN ATS:: TSTB STATUS ; WAS A TERMINAL SPECIFIED ? BMI ATSTTY ; IF MI, YES MOV #ATSM1,R0 ; SET TO APPEND " /ALL" CALL MOVEC ; MOVE IT TO SPAWN BUFFER RETURN ATSTTY::MOV #ATSM2,R0 ; SET TO MOVE "/TERM=" CALL MOVEC ; MOVE IT TO SPAWN BUFFER MOV SCMD,R0 ; START OF COMMAND LINE CALL SKIP ; SKIP ANY LEADING SPACES CALL MOVEC ; AND MOVE IT TO SPAWN BUFFER CMPB -1(R1),#': ; DID USER SPECIFY COLON ? BEQ 10$ ; IF EQ, YES MOVB #':,(R1)+ ; OTHERWISE PUT COLON IN 10$: RETURN .SBTTL CHD - Change Directory Command. ;+ ; ; CHD - Change directory command. ; ; This action routine is called to fill in the login UIC if none was ; specified, and the terminal is privileged. This is done since DCL ; uses the login UIC from the UCB instead of the accounting block. ; This prevents us from getting set back to our home directory. ; ; Inputs: ; R1 = The spawn buffer address. ; ; Outputs: ; R1 = The updated spawn buffer. ; R5 must be preserved. ; ;- CHD:: TSTB STATUS ; Any command entered ? BMI 100$ ; If MI, yes. BIT #S.PRIV,STATUS ; On a privileged terminal ? BEQ 100$ ; If EQ, no. MOV R1,-(SP) ; Save the spawn buffer address. MOV R1,R2 ; Copy the spawn buffer address. MOV TSKBUF+G.TSDU,R3 ; Copy the binary login UIC. CLR R4 ; Suppress zeros/insert separators. CALL .PPASC ; Convert binary UIC to ASCII. CLRB (R2) ; Terminate string with a null. ;*** MOV R2,R1 ; Reset the output buffer address. CALL SPAWN ; Spawn the first DCL command. MOV (SP)+,R1 ; Restore the spawn buffer address. CLRB (R1) ; Terminate after "SET DEF" string. 100$: BIC #B.MULT,O.STAT(R5) ; Reset the multiple commands flag. RETURN .SBTTL CHECK - Check Terminal Availability. ;+ ; ; CHECK - Check for termnal availability. ; ; This routine determines if a specified terminal is available by ; checking for busy (attaching the terminal) and by checking for a ; user being logged on via the GIN$ directive. ; ; Outputs: ; Exits with status: ; success = 1 = the terminal is available. ; warning = 0 = no device or not a terminal. ; error = 2 = the terminal is logged on. ; severe = 4 = the terminal is busy. ;- CHECK:: MOV SCMD,R0 ; Copy start of command address. CALL ASSLUN ; Try to assign the output LUN. BCS 70$ ; If CS, we had an error. ; Must do a get LUN to find physical terminal name and unit. DIR$ #GLUN ; Get LUN information. CALL CHKDIR ; Check/report directive errors. BCS 100$ ; If CS, we had an error. BIT #FD.TTY,LUNBUF+G.LUCW ; Is this a terminal device ? BEQ 70$ ; If EQ, no. ; Now try to get the users' account block. MOV LUNBUF+G.LUNA,R1 ; Copy the device name. MOVB LUNBUF+G.LUNU,R2 ; Copy the terminal number. CALL GETUAB ; Get the user account block. BCC 60$ ; If CC, user is logged on. ; Not logged on, see if the terminal is busy. CALL ATTALT ; Try to attach the terminal. BCS 80$ ; If CS, the attach failed. JMP EXISUC ; Else, terminal is available. 60$: JMP EXIERR ; Exit with error status. 70$: JMP EXIWAR ; Exit with warning status. 80$: JMP EXISEV ; Exit with severe error status. 100$: MOV $DSW,R0 ; Copy the directive error code. JMP EXST ; And exit with this as status. .SBTTL CLRSCR -- Clear Terminal Screen ; CLRSCR - Clear the terminal screen. CLRVT1: .ASCII %[H%%[J% ; VT100 ERASE SCREEN VT1SIZ = .-CLRVT1 CLRVT5: .ASCII %H%%J% ; VT52 ERASE SCREEN VT5SIZ = .-CLRVT5 CLRTEK: .BYTE , ; TEKTRONIX CLEAR SCREEN TEKSIZ = .-CLRTEK CLRPAG: .BYTE ; LA120/LA38 TOP OF PAGE PAGSIZ = .-CLRPAG .EVEN CLRDPB: QIOW$ IO.WAL,TILUN,TIEFN,,IOSB,, CLRSCR::MOVB TTYPE,R0 ; GET TERMINAL TYPE MOV #CLRDPB+Q.IOPL,R1 ; ADDRESS FOR BUFFER MOV #CLRDPB+Q.IOPL+2,R2 ; ADDRESS FOR BYTE COUNT BIT #S.VFAM,STATUS ; VT100 FAMILY TERMINAL ? BNE 100$ ; IF NE, YES MOV #CLRVT5,(R1) ; SET VT52 CLEAR SCREEN MOV #VT5SIZ,(R2) ; AND THE SIZE CMPB #T.VT52,R0 ; IS THIS A VT52 ? BEQ 100$ ; IF EQ, YES MOV #CLRTEK,(R1) ; SET VT52 CLEAR SCREEN MOV #TEKSIZ,(R2) ; AND THE SIZE CMPB #T.LA36,R0 ; IS THIS AN LA36 ? BEQ 50$ ; IF EQ, YES (PRESUME TEKTRONIX) CMPB #T.UNK0,R0 ; IS TERMINAL UNKNOWN ? BEQ 50$ ; IF EQ, YES (PRESUME TEKTRONIX) MOV #CLRPAG,(R1) ; SET LA120/LA38 CLEAR PAGE MOV #PAGSIZ,(R2) ; AND THE SIZE CMPB #T.L100,R0 ; Is this an LA100 ? BEQ 100$ ; If EQ, yes (output a formfeed). CMPB #T.L120,R0 ; IS THIS AN LA120 ? BEQ 100$ ; IF EQ, YES CMPB #T.L180,R0 ; IS THIS AN LA180 ? BEQ 100$ ; IF EQ, YES BR 110$ ; ELSE IGNORE... 50$: DIR$ #CLRDPB ; CLEAR TEKTRONIX SCREEN DIR$ #MRKTIM ; MARK TIME FOR 2 SECONDS BCS 110$ ; IF CS, DON'T HANG DIR$ #MRKWAT ; WAIT FOR MARK TIME BR 110$ ; BR TO COMMON EXIT 100$: DIR$ #CLRDPB ; CLEAR CRT SCREEN 110$: JMP EXISUC ; EXIT WITH SUCCESS .SBTTL HANGUP - Hangup A Modem Port. ;+ ; ; HANGUP - Hangup a modem port. ; ; Format: HANGUP TTnn: ; ;- HANGUP::MOV SCMD,R0 ; Copy start of command address. CALL ASSLUN ; Try to assign the output LUN. BCS 100$ ; If CS, we had an error. CALL ATTERM ; Try to attach the terminal. BCS 100$ ; If CS, the attach failed. QIOW$S #IO.HNG,#TOLUN,#TOEFN,,#IOSB,, ; Hangup the modem port. CALL CHKERR ; Check/report any errors. 100$: JMP EXISUC ; Now exit ... .SBTTL FREE - Show Free Blocks On a Disk ; FREE - Show free blocks on system disk (or specified disk). FREM2: .ASCIZ \/FR\ .EVEN FREE:: TSTB STATUS ; WAS A DEVICE SPECIFIED ? BPL 10$ ; IF PL, NO CMPB -1(R1),#COLON ; DID USER SPECIFY COLON ? BEQ 10$ ; IF EQ, YES MOVB #COLON,(R1)+ ; OTHERWISE PUT IT IN 10$: MOV #FREM2,R0 ; POINT TO SECOND HALF OF MESSAGE CALL MOVEC ; MOVE LAST HALF RETURN .SBTTL PURGE - Additional Processing of DCL Purge ; PURGE - DCL Purge - append *.* if no file(s) specified. DEFM: .ASCIZ "*.*" ; Default file specification. PURM: .ASCIZ "" ; No terminating string. .EVEN PURGE:: MOV #DEFM,R0 ; Set default file specification. MOV #PURM,R2 ; Set terminating string address. JMP CHKDEF ; Setup command string and return. .SBTTL Set File Protections ;+ ; ; These action routines are called to set various file protections. ; ; Inputs: ; R1 = The output buffer address. ; ; Outputs: ; R1 = The updated output buffer. ; R5 must be preserved. ; ;- ; ; Protection word: ; ; World Group Owner System ; +-------------------+-------------------+-------------------+-------------------+ ; | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | 07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | ; +-------------------+-------------------+-------------------+-------------------+ ; | D | E | W | R | D | E | W | R | D | E | W | R | D | E | W | R | ; +-------------------+-------------------+-------------------+-------------------+ ; ; A bit ON = deny privilege ; ROFM: .ASCIZ "/PR:160000" ; [RWED,RWED,RWED,R] RONM: .ASCIZ "/PR:167356" ; [R,R,R,R] RWEM: .ASCIZ "/PR:164210" ; [RWE,RWE,RWE,R] RWEDM: .ASCIZ "/PR:0" ; [RWED,RWED,RWED,RWED] .EVEN .ENABL LSB ROFF:: MOV #ROFM,R2 ; Set string address to copy. BR 10$ ; Use common code ... RONLY:: MOV #RONM,R2 ; Set string address to copy. BR 10$ ; Use common code ... RWE:: MOV #RWEM,R2 ; Set string address to copy. BR 10$ ; Use common code ... RWED:: MOV #RWEDM,R2 ; Set string address to copy. BR 10$ ; Use common code ... 10$: MOV #DEFM,R0 ; Set default file specification. JMP CHKDEF ; Setup command line and return. .DSABL LSB .SBTTL SEND - Send String To Terminal. ;+ ; ; SEND - Do write breakthrough to specified terminal. ; ; Format: SEND TTnn: Text_to_send [+] ; ; The plus sign (+) causes overprint carriage control to be used. ; ;- SEND:: MOV SCMD,R0 ; Copy start of command address. CALL ASSLUN ; Try to assign the output LUN. BCS 90$ ; If CS, we had an error. MOV #40,R2 ; Presume single spacing. TST STATUS ; Is debugging enabled ? BPL 10$ ; If PL, no. MOVB #'+,R2 ; Yes, use overprint VFC. 10$: CALL GETLEN ; Get length of string into R1. MOV R0,R3 ; Copy the starting address. ADD R1,R3 ; Point to end of the string. CMPB -1(R3),#'+ ; Terminated by two plus signs ? BNE 20$ ; If NE, no. DEC R1 ; Adjust the string byte count. CLR R2 ; Yes, set for no carriage control. 20$: QIOW$S #IO.WBT,#TOLUN,#TOEFN,,#IOSB,, ; Write the text. CALL CHKERR ; Check/report any I/O errors. BCC 100$ ; If CC, success. 90$: JMP EXISEV ; Exit with fatal error. 100$: JMP EXISUC ; Exit with successful status. .SBTTL TRUNCATE - Truncate File(s) to Logical End of File ; TRUNCATE - Truncate file(s) to logical end of file TRUM: .ASCIZ "/TR" .EVEN TRUNCATE:: MOV #DEFM,R0 ; Set default file specification. MOV #TRUM,R2 ; Set default terminating string. JMP CHKDEF ; Setup the command line & return. .SBTTL EOF - Set End Of File ; EOF - Set end of file on a file not closed properly. DEFM1: .ASCIZ "" ; Default file specification. EOFM: .ASCIZ "/EOF" ; Terminating command string. .EVEN EOF:: MOV #DEFM1,R0 ; Set default file specification. MOV #EOFM,R2 ; Set default terminating string. JMP CHKDEF ; Setup the command line & return. .SBTTL NARROW - Set The Terminal Width Narrow ; NARROW - Put VT100 in 80 column mode. .ENABL LSB NARROW::BIT #S.VFAM,STATUS ; VT100 FAMILY TERMINAL ? BEQ 10$ ; IF EQ, NO VTWRT NARSCR,<[?3l> ; PUT VT100 IN 80 COLUMN MODE 10$: RETURN .DSABL LSB .SBTTL WIDE - Set The Terminal Width Wide ; WIDE - Put the VT100 in 132 column mode. .ENABL LSB WIDE:: BIT #S.VFAM,STATUS ; VT100 FAMILY TERMINAL ? BEQ 10$ ; IF EQ, NO VTWRT WIDSCR,<[?3h> ; PUT VT100 IN 132 COLUMN MODE 10$: RETURN .DSABL LSB .SBTTL VT100 - Put The VT100 in VT100 (ANSI) Mode ; VT100 - Put VT100 in VT100 (ANSI) mode VT100:: VTWRT ANSIM,^/ ; SET VT52 MODE RETURN .SBTTL WAITS - Wait For String From a Terminal. ;+ ; ; WAITS - Wait for string from a terminal. ; ; Format: WAIT[/D:n] TTnn: match_string [+] ; ; The /D:n is the number of seconds to delay before issuing the read. ; If not specified, we wait 1 second. The number of characters in the ; typehead buffer is then read and if non-zero, the read is issued. If ; a match string is specified, then the buffer read is searched for that ; substring. The plus sign (+) causes the characters read to be displayed. ; ; Outputs: ; Exits with status: ; success = 1 = read and match of substring. ; warning = 0 = no characters in typehead to read. ; error = 2 = read with no match of substring. ; fatal = 4 = directive or syntax error. ;- WAITS:: MOV SCMD,R0 ; Copy start of command address. MOV #1,R1 ; Set default # of seconds to delay. CMPB (R0),#'/ ; Was a switch specified ? BNE 10$ ; If NE, no. INC R0 ; Skip over the slash. CMPB (R0)+,#'D ; Start of "/D:" switch ? BNE 80$ ; If NE, no (syntax error). CMPB (R0)+,#': ; End of "/D:" switch ? BNE 80$ ; If NE, no (syntax error). CALL $CDTB ; Convert decimal ASCII to binary. ; The binary value is in R1. CMP R2,#SPACE ; Terminating character = space ? BNE 80$ ; If NE, no (syntax error). ; Assign the LUN and attach the specified terminal. 10$: CALL ASSLUN ; Try to assign the output LUN. BCS 80$ ; If CS, we had an error. CALL ATTERM ; Try to attach the terminal. BCS 80$ ; If CS, the attach failed. MOV R0,R2 ; Save the buffer pointer. MOV R1,R3 ; Copy # of seconds to delay. ; Sit in the delay loop up till 'n' seconds. 20$: MOV #1,R1 ; Set to delay for one second. CALL DELAY ; Delay for "n" seconds in R1. CALL GTYPAH ; Get the typeahead buffer count. ; Returns the typehead count in R1. TST R1 ; Any characters in the typehead ? BNE 30$ ; If NE, yes. SOB R3,20$ ; No, loop for 'n' seconds. BR 70$ ; Timeout, nothing to read. ; ; At this point, we know something is in the typeahead buffer. ; Now we sit in a one second loop until the typeahead count does ; not change. ; 30$: MOV R1,R3 ; Save the typahead buffer count. MOV #1,R1 ; Set number of seconds to delay. CALL DELAY ; Delay for "n" seconds in R1. CALL GTYPAH ; Get the typeahead buffer count. CMP R1,R3 ; Did the typehead count change ? BNE 30$ ; If NE, yes (loop some more). ; ; Issue read with 10 second timeout count. ; MOV #SPNBUF,R0 ; Set the input buffer address. QIOW$S #IO.RAL!TF.TMO!TF.RNE,#TOLUN,#TOEFN,,#IOSB,, CALL CHKERR ; Check/report any errors. MOV IOSB+2,R1 ; Copy number of bytes read. TST STATUS ; Is debugging enabled ? BPL 40$ ; If PL, no (don't display). CLR VFC ; Set for no carriage control. CALL WRITE ; Display the characters read. 40$: ADD R0,R1 ; Point to end of input buffer. CLRB (R1) ; Terminate buffer with a NULL. ; If a match string was specified, search for that substring. 50$: MOV R2,R1 ; Restore pointer to input buffer. TSTB (R1) ; Was a match string specified ? BEQ 90$ ; If EQ, no (exit with success). CALL FNDSUB ; Try to find the substring. BCC 90$ ; If CC, the string was found. 60$: JMP EXIERR ; Exit with error status. 70$: JMP EXIWAR ; Exit with warning status. 80$: JMP EXISEV ; Exit with severe error status. 90$: JMP EXISUC ; Now exit ... .SBTTL CHKDEF - Check Command Defaults. ;+ ; ; CHKDEF - Check for default file specification. ; ; This routine appends a default file specification if none exists or ; only the device name or account was specified, the appends the switch ; string (i.e., /PU or /TR). ; ; Inputs: ; R0 = Address of default file specification. ; R1 = The output buffer address. ; R2 = Address of terminating string. ; ; Ouputs: ; R1 = The updated output buffer. ; ;- CHKDEF: TSTB STATUS ; Was a file string specified ? BPL 10$ ; If PL, no (add the default). CMPB -1(R1),#': ; Only the device specified ? BEQ 10$ ; If EQ, yes (add default spec). CMPB -1(R1),#'] ; Only the account specified ? BNE 20$ ; If NE, no (skip the default). ; Yes, add the default below. 10$: CALL MOVEC ; Copy the default file spec. 20$: MOV R2,R0 ; Copy the terminating string. CALL MOVEC ; And copy it. RETURN .END