.TITLE FTS "Main FTS code module" .IDENT /b1.0/ ;+ ; Facility: ; FTS.MAR - Functionality Testing Suite ; FTS.C Copyright (c) 1991 Bruce R. Miller and TGV Inc. ; ; Abstract: ; Self-defence for the VMS system hacker ; ; Author: ; Bruce R. Miller, MILLER@TGV.COM ; TGV, Inc. ; 603 Mission St. ; Santa Cruz, CA 95060 ; (408) 427-4366 ; ; Date: May 14,1991 ; ; Wishlist: ; Can we monitor timer activity? ; Ned's library monitor ; Ehud's hotkey code ; ; Copyright (c) 1991 Bruce R. Miller ; All rights reserved. ; ; Redistribution and use in source and binary forms are permitted ; provided that the above copyright notice and this paragraph are ; duplicated in all such forms and that any documentation, ; advertising materials, and other materials related to such ; distribution and use acknowledge that the software was developed ; by Bruce R. Miller. ; THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR ; IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ; WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ; ; Modifications: ; ;- .link "sys$system:sys.stb"/SELECTIVE_SEARCH .library "sys$Library:lib.mlb" $chfdef $climsgdef $rmsdef $ssdef $stsdef $smgdef .EXTERNAL FTS_parse exit_condition: .BLKL ; condition causing exit exh_block: .LONG 0 ; Forward link .LONG Exit_Handler ; Exit handler routine address .LONG 0 ; arg_count .LONG exit_condition ; pointer to exit signal .LONG 0 ; first arg Exit_error_str: .ASCID /Leaving in a huff... !XL/ ;++ ; Exit_Handler ; ; Function: ; This routine is an exit handler. It cleans up cleanly. ; ; Input: ; 4(AP) - Condition address ;-- .entry Exit_Handler,^m ; Did we get an error code? MOVL @4(AP),R2 BLBS R2,100$ ; Print an error message PUSHL R2 PUSHAB Exit_error_str CALLS #2,Print_String 100$: ; Call it a day MOVL R2,R0 RET ;++ ; FTS_Handler - FTS signal catcher ; ; Input: ; 4(AP) - address of signal array ; 8(AP) - address of mechanism array ; 12(AP) - address of enable array ; ;-- .entry FTS_Handler,^m MOVL #SS$_RESIGNAL,R0 ; Resignal by default MOVL 4(AP),R1 ; Get signal array MOVL chf$l_sig_name(R1),R1 ; get signal code CMPL R1,#SS$_UNWIND ; An unwind signal? BNEQ 20$ ; br if not MOVL #SS$_NORMAL,R0 ; BRB 100$ 20$: CMPL R1,#CLI$_NOCOMD ; No command? BNEQ 30$ ; br if not MOVL #SS$_CONTINUE,R0 ; BRB 100$ 30$: CMPL R1,#RMS$_EOF ; End of file? BNEQ 100$ ; br if not CLRQ -(SP) ; push two zeros CALLS #2,G^SYS$UNWIND ; unwind the stack 100$: RET ;++ ; Do_Abort - FTS command has failed, return to FTS> prompt ; ; Input: ; 4(AP) - address of signal array ; 8(AP) - address of mechanism array ;-- .entry Do_Abort,^M MOVL 4(AP),R2 ; Get signal array MOVL 8(AP),R3 ; Get mechanism array SUBL #2,chf$l_sig_args(R2) ; decrement arg count CLRL -(SP) CLRL -(SP) CLRL -(SP) PUSHL R2 CALLS #4,G^SYS$PUTMSG ; Print an error message MOVL chf$l_sig_name(R2),- chf$l_mch_savr0(R3) CLRQ -(SP) CALLS #2,G^SYS$UNWIND RET ;++ ; Do_Continue - Print an error message then continue ; ; Input: ; 4(AP) - address of signal array ; 8(AP) - address of mechanism array ;-- .entry Do_Continue,^M MOVL 4(AP),R2 ; Get signal array ; MOVL 8(AP),R3 ; Get mechanism array SUBL #2,chf$l_sig_args(R2) ; decrement arg count CLRL -(SP) CLRL -(SP) CLRL -(SP) PUSHL R2 CALLS #4,G^SYS$PUTMSG ; Print an error message MOVL #SS$_CONTINUE,R0 RET ;++ ; Do_Exit - Print an error message then exit image ; ; Input: ; 4(AP) - address of signal array ; 8(AP) - address of mechanism array ;-- .entry Do_Exit,^M MOVL 4(AP),R2 ; Get signal array MOVL 8(AP),R3 ; Get mechanism array SUBL #2,chf$l_sig_args(R2) ; decrement arg count CLRL -(SP) CLRL -(SP) CLRL -(SP) PUSHL R2 CALLS #4,G^SYS$PUTMSG ; Print an error message MOVL chf$l_sig_name(R2),- chf$l_mch_savr0(R3) PUSHL chf$l_sig_name(R2) BISL #STS$M_INHIB_MSG,(SP) CALLS #2,G^SYS$EXIT RET ;++ ; FTS_Routine_Handler - Caught a signal ; ; Functional Description: ; Conditions that occure while processing FTS commands ; come through here. We decide whether to continue, ; exit the image, or unwind back to the FTS> prompt. ; We also handle internal signals here, like ACCVIO. ; ; Input: ; 4(AP) - address of signal array ; 8(AP) - address of mechanism array ; 12(AP) - address of enable array ; ;-- .entry FTS_Routine_Handler,^m MOVL 4(AP),R1 ; Get signal array MOVL chf$l_sig_name(R1),R1 CMPL R1,#SS$_UNWIND ; An unwind signal? BNEQ 20$ ; br if not MOVL #SS$_NORMAL,R0 BRB 100$ 20$: ; Something as common and nasty as an ACCVIO we want to pass on CMPL R1,#SS$_ACCVIO ; An accvio? BEQL 25$ ; br if not CMPL R1,#SS$_ROPRAND ; Reserved operand? BEQL 25$ ; br if not CMPL R1,#SS$_TBIT ; Trace failure? BEQL 25$ ; br if not CMPL R1,#SS$_RADRMOD ; Reserved address mode? BEQL 25$ ; br if not CMPL R1,#SS$_DEBUG ; the DEBUG signal BEQL 25$ ; br if not BRB 30$ 25$: MOVL R1,R0 BRB 100$ 30$: ; Call one of the routines above to handle the signal PUSHL 8(AP) ; Push mech array PUSHL 4(AP) ; Push Signal array CALLS #2,Do_Abort ; CALLS #2,Do_Continue ; CALLS #2,Do_Exit 100$: RET .EXTERNAL FTS_Get_Input prompt: .ASCID /FTS> / Hello_Sailor_str: .ASCID /Hello, sailor!!!\nFor assistance, type 'HELP' at the FTS> prompt./ ;++ ; Do_Parse - Run the command line through DCL ; ; Functional Description: ; A routine to call the CLI$DCL_Parse routine with the right ; arguements. The reason that this isn't inline is because it ; sets up the condition handler for handling the errors and ; warnings and Control_C situations. ; ; So, if someone types Control_C while getting input, he ; will handle the Control_C in the appropriate fashion. ; ; Input: ; None ; ; Values Returned: ; ; 1) Anything returned by the CLI Routines. Or ; 2) Anything that FTS_GET_INPUT would return. ; ; Note: that some CLI routine values are signalled others are merely ; returned. ;-- .entry Do_Parse,^m ; Establish a condition handler MOVAB FTS_Routine_Handler,(FP) CLRQ -(SP) MOVB #DSC$K_DTYPE_T,2(SP) MOVB #DSC$K_CLASS_D,3(SP) MOVL SP,R2 CLRL -(SP) PUSHL SP ; pointer to length PUSHAB prompt ; pointer to prompt descriptor PUSHL R2 ; push input string descriptor CALLS #3,FTS_Get_Input ; Get the command line CMPL R0,#RMS$_EOF ; End of input? BEQL 100$ ; if so, ignore it BLBC R0,110$ ; br on error POPL R3 ; Get the line length BEQL 20$ MOVL @4(R2),R4 CMPB R4,#^A/?/ BNEQ 20$ PUSHL Hello_Sailor_str CALLS #1,Print_String MOVL #SS$_NORMAL,R3 BRB 30$ 20$: ; Send the line down to DCL to be parsed CLRL -(SP) CLRL -(SP) CLRL -(SP) PUSHAB FTS_parse PUSHL R2 CALLS #5,G^CLI$DCL_PARSE MOVL R0,R3 30$: ; Free up the command line string PUSHL R2 CALLS #1,G^STR$FREE1_DX BLBC R0,110$ MOVL R3,R0 100$: RET 110$: ; Signal this error PUSHL R0 CALLS #1,G^LIB$SIGNAL BRB 100$ ;++ ; FTS_Dispatch - ; ; Functional Description: ; ; This routine simply calls CLI$DISPATCH. The reason we don't ; call CLI$DISPATCH directly is that we might want to attach ; a condition handler to this stack frame. Then, when a command ; fails, we can unwind back to this point. ; ; Input: ; None. ; ; Output: ; Whatever the dispatched routines return. ;-- .entry FTS_Dispatch,^m MOVAB FTS_Routine_Handler,(FP) CALLS #0,G^CLI$DISPATCH RET ;++ ; Command_Loop ; ; Functional Description: ; This routines prompts for the command and then ; dispatches to the correct routine. ;-- .entry Command_Loop,^m 10$: CALLS #0,Do_Parse BLBC R0,20$ CALLS #0,FTS_Dispatch 20$: CMPL R0,#RMS$_EOF BEQL 100$ BRB 10$ 100$: MOVL #SS$_NORMAL,R0 RET ;++ ; Check_Invocation_Line ; ; Functional Description: ; Parse the arguements on the command line when program invoked. ;-- .entry Check_Invocation_Line,^m ; Establish a condition catcher ; MOVAB FTS_Routine_Handler,(FP) ; Read command line CLRQ -(SP) ; build descriptor MOVB #DSC$K_DTYPE_T,2(SP) MOVB #DSC$K_CLASS_D,3(SP) MOVL SP,R5 CLRL -(SP) ; longward for length MOVL SP,R2 CLRL -(SP) ; PUSHL R2 ; pointer to length CLRL -(SP) ; PUSHL R5 ; Input line descriptor CALLS #4,G^LIB$GET_FOREIGN ; read in the line BLBS R0,10$ BRW 100$ 10$: POPL R0 BEQL 100$ MOVL @4(R5),R4 CMPB R4,#^A/?/ BNEQ 20$ PUSHL Hello_Sailor_str CALLS #1,Print_String MOVL #SS$_NORMAL,R3 BRB 30$ 20$: ; Send the line down to DCL to be parsed CLRL -(SP) CLRL -(SP) CLRL -(SP) PUSHAB FTS_parse PUSHL R5 ; Input line descriptor CALLS #5,G^CLI$DCL_PARSE BLBS R0,25$ MOVL #SS$_NORMAL,R0 BRB 100$ 25$: CALLS #0,FTS_Dispatch MOVL R0,R3 30$: ; Free up the command line string PUSHL R5 CALLS #1,G^STR$FREE1_DX BLBC R0,110$ ; MOVL R3,R0 MOVL #SS$_NORMAL,R0 100$: RET 110$: ; Signal this error PUSHL R0 CALLS #1,G^LIB$SIGNAL BRB 100$ .EXTERNAL FTS_SMG_Init .entry FTS_Init,^m ; Declare the exit handler block PUSHAB exh_block CALLS #1,G^SYS$DCLEXH BLBC R0,110$ ; Initialize the terminal interface CALLS #0,FTS_SMG_Init 100$: RET 110$: ; Signal this error PUSHL R0 CALLS #1,G^LIB$SIGNAL BRB 100$ ;++ ; main - image entry point ; ; Functional Description: ; The main routine. Parse the arguements. Get the log file. ; Start the I/O. Then Hibernate while the AST's do all the ; work. ;-- .entry main,^m ; Establish a condition handler, first thing MOVAB FTS_Handler,(FP) ; Do initialization CALLS #0,FTS_Init ; Invoked with a command line? CALLS #0,Check_Invocation_Line BLBS R0,100$ ; if not, EXIT 10$: CALLS #0,Command_Loop MOVL #SS$_NORMAL,R0 100$: PUSHL R0 CALLS #1,G^SYS$EXIT RET .END main