! ! Version X-4 ! !**************************************************************************** !* * !* COPYRIGHT (c) 1978, 1980, 1982, 1984, 1992 BY * !* DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS. * !* ALL RIGHTS RESERVED. * !* * !* THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED * !* ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE * !* INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER * !* COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY * !* OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY * !* TRANSFERRED. * !* * !* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE * !* AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT * !* CORPORATION. * !* * !* DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS * !* SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. * !* * !* * !**************************************************************************** !++ ! ! FACILITY: Miscellaneous utilities ! ! ABSTRACT: ! ! These procedures are used to emulate the functions of the VMS V4.0 ! ACL editor. ! ! ENVIRONMENT: ! ! TPU section. ! !-- ! ! ! AUTHOR: L. Mark Pilant CREATION DATE: 1-Aug-1985 ! ! MODIFIED BY: ! ! X-4 LBB0125 Lee Barton 15-May-1992 ! Add help strings for new ACE types. Reset ident to ! agree with VSC generation number. ! ! X-12U2 SAS0221 Scott A. Shurts 29-Mar-1990 ! Undo X-12U1, rearrange the message file, since they ! are not suppose to change (introduce bases). ! ! X-12U1 SAS0220 Scott A. Shurts 26-Mar-1990 ! Fix message mismatch problem. ! ! X-12 MVI0025 Michael V. Iles, 13-JUL-1989 14:56:08.88 ! Changed status line format so that object type was shown ! and that format was dictated by window width ! ! Note. Intervening edits X-9, X-10, X-11 not documented ! CMS generation number was out of step ! ! X-8 LMP-TPU L. Mark Pilant, 12-FEB-1987 10:27 ! Track TPU naming changes. ! ! X-7 LMP0432 L. Mark Pilant, 14-JAN-1987 15:40 ! Fix misspellings and error message handling. ! ! X-6 LMP0398 L. Mark Pilant, 4-FEB-1986 13:25 ! Make non-file object's work correctly. ! ! X-5 LMP0383 L. Mark Pilant, 20-NOV-1985 10:12 ! Track $CHANGE_ACL changes, and misc bug fixes. ! ! X-4 LMP0376 L. Mark Pilant, 15-Oct-1985 15:41 ! Make sure that the help libraries come from SYS$HELP, not ! SYS$LIBRARY. Also, make sure that the complied section is ! put in the correct place. ! !** ! ! ROUTINE NAME: ACLEDIT$DEFINE_KEYS ! ! ROUTINE DESCRIPTION: Define the keys used by the ACL editor ! PROCEDURE ACLEDIT$DEFINE_KEYS ! Define the basic keypad keys ! First row. DEFINE_KEY ("ACLEDIT$X_HELP_FORMAT := 0; ACLEDIT$HELP", PF2, "PF2_KEY"); DEFINE_KEY ("ACLEDIT$X_HELP_FORMAT := 1; ACLEDIT$HELP", KEY_NAME (PF2, SHIFT_KEY), "PF2_KEY"); DEFINE_KEY ("ACLEDIT$LOCATE_NEXT", PF3, "PF3_KEY"); DEFINE_KEY ("ACLEDIT$LOCATE_STRING", KEY_NAME (PF3, SHIFT_KEY), "PF3_KEY"); DEFINE_KEY ("ACLEDIT$DELETE_ACE", PF4, "PF4_KEY"); DEFINE_KEY ("ACLEDIT$UNDELETE_ACE", KEY_NAME (PF4, SHIFT_KEY), "PF4_KEY"); ! Second row. DEFINE_KEY ("ACLEDIT$NEXT_FIELD (ACLEDIT$C_SELECT_FIELD)", KP7, "KP7_KEY"); DEFINE_KEY ("ACLEDIT$NEXT_FIELD (ACLEDIT$C_ADVANCE_FIELD)", KEY_NAME (KP7, SHIFT_KEY), "KP7_KEY"); DEFINE_KEY ("ACLEDIT$MOVE_SCREEN", KP8, "KP8_KEY"); DEFINE_KEY ('MESSAGE ("KP9 not yet implemented")', KP9); DEFINE_KEY ("ACLEDIT$DELETE_WORD", MINUS, "KPMINUS_KEY"); DEFINE_KEY ("ACLEDIT$UNDELETE_WORD", KEY_NAME (MINUS, SHIFT_KEY), "KPMINUS_KEY"); ! Third row. DEFINE_KEY ("ACLEDIT$FORWARD", KP4, "KP4_KEY"); DEFINE_KEY ("ACLEDIT$BOTTOM", KEY_NAME (KP4, SHIFT_KEY), "KP4_KEY"); DEFINE_KEY ("ACLEDIT$BACKWARD", KP5, "KP5_KEY"); DEFINE_KEY ("ACLEDIT$TOP", KEY_NAME (KP5, SHIFT_KEY), "KP5_KEY"); DEFINE_KEY ('MESSAGE ("KP6 not yet implemented")', KP6); DEFINE_KEY ("ACLEDIT$DELETE_CHAR", COMMA, "KPCOMMA_KEY"); DEFINE_KEY ("ACLEDIT$UNDELETE_CHAR", KEY_NAME (COMMA, SHIFT_KEY), "KPCOMMA_KEY"); ! Forth row. DEFINE_KEY ("ACLEDIT$MOVE_WORD", KP1, "KP1_KEY"); DEFINE_KEY ("ACLEDIT$MOVE_LINE", KP2, "KP2_KEY"); DEFINE_KEY ("ACLEDIT$DELETE_EOL", KEY_NAME (KP2, SHIFT_KEY), "KP2_KEY"); DEFINE_KEY ('MESSAGE ("KP3 not yet implemented")', KP3); ! Fifth row. DEFINE_KEY ("ACLEDIT$MOVE_ACE (ACLEDIT$C_ENTER)", KP0, "KP0_KEY"); DEFINE_KEY ("ACLEDIT$INSERT_ACE", KEY_NAME (KP0, SHIFT_KEY), "KP0_KEY"); DEFINE_KEY ("ACLEDIT$SELECT_ITEM", PERIOD, "KPERIOD_KEY"); DEFINE_KEY ("ACLEDIT$ENTER_ACE (ACLEDIT$C_REPOSITION)", ENTER, "ENTER_KEY"); ! Define the LK201 function keys. DEFINE_KEY ("ACLEDIT$EXIT", F10, "F10_KEY"); DEFINE_KEY ("ACLEDIT$QUIT", KEY_NAME (F10, SHIFT_KEY), "F10_KEY"); DEFINE_KEY ("ACLEDIT$MOVE_BOL", F12, "F12_KEY"); DEFINE_KEY ("ACLEDIT$RUBOUT_WORD", F13, "F13_KEY"); DEFINE_KEY ("ACLEDIT$X_HELP_FORMAT := 0; ACLEDIT$HELP", F15, "F15_KEY"); DEFINE_KEY ("ACLEDIT$X_HELP_FORMAT := 1; ACLEDIT$HELP", KEY_NAME (F15, SHIFT_KEY), "F15_KEY"); DEFINE_KEY ("ACLEDIT$ENTER_ACE (ACLEDIT$C_REPOSITION)", F16, "F16_KEY"); ! Define the LK201 auxiliary keypad DEFINE_KEY ("ACLEDIT$LOCATE_STRING", E1, "E1_KEY"); DEFINE_KEY ("ACLEDIT$INSERT_KEY", E2, "E2_KEY"); DEFINE_KEY ("ACLEDIT$REMOVE_TEXT (ACLEDIT$C_REMOVE_TEXT)", E3, "E3_KEY"); DEFINE_KEY ("ACLEDIT$REMOVE_TEXT (ACLEDIT$C_KEEP_TEXT)", KEY_NAME (E3, SHIFT_KEY), "E3_KEY"); DEFINE_KEY ("ACLEDIT$SELECT_TEXT", E4, "E4_KEY"); DEFINE_KEY ("ACLEDIT$PREVIOUS_SCREEN", E5, "E5_KEY"); DEFINE_KEY ("ACLEDIT$NEXT_SCREEN", E6, "E6_KEY"); ! Define the arrow keys DEFINE_KEY ("ACLEDIT$UP", UP, "UP_ARROW"); DEFINE_KEY ("ACLEDIT$DOWN", DOWN, "DOWN_ARROW"); DEFINE_KEY ("ACLEDIT$RIGHT", RIGHT, "RIGHT_ARROW"); DEFINE_KEY ("ACLEDIT$SHIFT_RIGHT", KEY_NAME (RIGHT, SHIFT_KEY), "RIGHT_ARROW"); DEFINE_KEY ("ACLEDIT$LEFT", LEFT, "LEFT_ARROW"); DEFINE_KEY ("ACLEDIT$SHIFT_LEFT", KEY_NAME (LEFT, SHIFT_KEY), "LEFT_ARROW"); ! Define the remaining miscellaneous keys DEFINE_KEY ("ACLEDIT$INSERT_OVERSTRIKE", CTRL_A_KEY, "CTRLA_KEY"); DEFINE_KEY ("ACLEDIT$TPU_COMMAND", CTRL_D_KEY, "CTRLD_KEY"); DEFINE_KEY ("ACLEDIT$MOVE_BOL", CTRL_H_KEY, "CTRLH_KEY"); DEFINE_KEY ("ACLEDIT$EMULATE_TAB", CTRL_I_KEY, "ACE_FORMAT"); DEFINE_KEY ("ACLEDIT$RUBOUT_WORD", CTRL_J_KEY, "CTRLJ_KEY"); DEFINE_KEY ("ACLEDIT$ENTER_ACE (ACLEDIT$C_REPOSITION)", RET_KEY, "RESTART_HELP"); DEFINE_KEY ("ACLEDIT$REFRESH", CTRL_R_KEY, "CTRLR_KEY"); DEFINE_KEY ("ACLEDIT$REFRESH", CTRL_W_KEY, "CTRLW_KEY"); DEFINE_KEY ("ACLEDIT$RESET", KEY_NAME (CTRL_R_KEY, SHIFT_KEY), "CTRLR_KEY"); DEFINE_KEY ("ACLEDIT$RESET", KEY_NAME (CTRL_W_KEY, SHIFT_KEY), "CTRLW_KEY"); DEFINE_KEY ("ACLEDIT$RUBOUT_BOL", CTRL_U_KEY, "CTRLU_KEY"); DEFINE_KEY ("ACLEDIT$UNDELETE_LINE", KEY_NAME (CTRL_U_KEY, SHIFT_KEY), "CTRLU_KEY"); DEFINE_KEY ("ACLEDIT$EXIT", CTRL_Z_KEY, "CTRLZ_KEY"); DEFINE_KEY ("ACLEDIT$QUIT", KEY_NAME (CTRL_Z_KEY, SHIFT_KEY), "CTRLZ_KEY"); DEFINE_KEY ("ACLEDIT$RUBOUT_CHAR", DEL_KEY, "RUBOUT_KEY"); ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$INIT_STORAGE ! ! ROUTINE DESCRIPTION: This procedure initializes all of the ACL editor ! specific storage. ! PROCEDURE ACLEDIT$INIT_STORAGE ! Define the CALL_USER function codes. These include the ACL editor's ! facility code in the upper 16 bits to identify the function code. ACLEDIT$C_PARSE_ACE := 18153473; ! Check syntax of specified ACE ACLEDIT$C_CHECK_MODIFY := 18153474; ! See if ACE may be modified ACLEDIT$C_PROMPT_MODE := 18153475; ! See if prompt mode set ACLEDIT$C_CHECK_ACE := 18153476; ! Parse ACE and highlight if bad ACLEDIT$C_CHECK_DIR := 18153477; ! See if object is a directory file ACLEDIT$C_SET_CANDIDATE := 18153478; ! Set candidate ACE for dup check ACLEDIT$C_CHECK_DUP := 18153479; ! Check ACE for being a duplicate ACLEDIT$C_SET_OBJ_TYP := 18153480; ! Set object type for next READ_FILE ACLEDIT$C_GET_OBJ_TYP := 18153481; ! Get original object type ACLEDIT$C_MESSAGE := 18153482; ! Output ACL editor error message ! Define the ACL editor error message codes. These must parallel the ! definitions in AEDMESSAG.MSG. ACLEDIT$_PREVDUPACE := 18186280; ACLEDIT$_PROTECTED := 18186288; ACLEDIT$_SUCCDUPACE := 18186296; ACLEDIT$_SYNTAX := 18186304; ! Define the word terminators. ACLEDIT$X_WORD_SEPARATORS := " ()+,:= "; ACLEDIT$X_SPACES := " " + " " + " "; ! 132 spaces ! Initialize the various strings used to store deleted text. ACLEDIT$X_NULL := ""; ! Null string ACLEDIT$X_DELETE_ACE := ACLEDIT$X_NULL; ! Deleted ACE ACLEDIT$X_DELETE_EOL := ACLEDIT$X_NULL; ! Line deleted to EOL ACLEDIT$X_RUBOUT_BOL := ACLEDIT$X_NULL; ! Line deleted to BOL ACLEDIT$X_DELETE_WORD := ACLEDIT$X_NULL; ! Word deleted (forward) ACLEDIT$X_RUBOUT_WORD := ACLEDIT$X_NULL; ! Word rubbed out (reverse) ACLEDIT$X_DELETE_CHAR := ACLEDIT$X_NULL; ! Character deleted (forward) ACLEDIT$X_RUBOUT_CHAR := ACLEDIT$X_NULL; ! Character rubbed out (reverse) ! Initialize other miscellaneous strings. ACLEDIT$X_LINE_TERM_CHAR:= "|"; ! Line termination character ACLEDIT$X_ACE_MARKER := "¿"; ! Marker used when collapsing ACE ACLEDIT$X_INPUT_FILE := ACLEDIT$X_NULL; ! Object associated with main buffer ACLEDIT$X_OBJECT_TYPE := ACLEDIT$X_NULL; ! Object type ACLEDIT$X_STATUS := ACLEDIT$X_NULL; ! Procedure return status ACLEDIT$X_SEARCH_STRING := ACLEDIT$X_NULL; ! String to search for ACLEDIT$X_ORIGINAL_ACE := ACLEDIT$X_NULL; ! Copy of ACE before editing ACLEDIT$X_COMPRESSED_ACE:= ACLEDIT$X_NULL; ! Compressed original ACE ACLEDIT$X_BINARY_ACE := ACLEDIT$X_NULL; ! Binary ACE ACLEDIT$X_HELP_WINDOW := ACLEDIT$X_NULL; ! Help window ACLEDIT$X_SELECT_START := ACLEDIT$X_NULL; ! Start of select range ! Initialize miscellaneous flags. ACLEDIT$X_PROMPT := 0; ! Whether or not using prompt mode ACLEDIT$X_CHECK_MODIFY := 1; ! 0 = don't check for untouchable ACEs ! 1 = check for untouchable ACEs ACLEDIT$X_CHECK_DUPLICATES := 1; ! 0 = don't check for duplicate ACE entries ! 1 = check for duplicate ACE entries ACLEDIT$X_USE_DEFAULT_OPT := 0; ! 0 = don't use the default option ! 1 = use the default option ACLEDIT$X_DIRECTORY_FILE := 0; ! 0 = object is not a directory file ! 1 = object is a directory file ACLEDIT$X_PASTE_BUFFER := 0; ! 0 = no paste buffer support ! 1 = provide paste buffer support ! Initialize strings that represent miscellaneous constants. ACLEDIT$C_NOPOSITION := 0; ! No positioning after ACE on enter ACLEDIT$C_REPOSITION := 1; ! Position to next/previous ACE on enter ACLEDIT$C_NOENTER := 0; ! Don't enter ACE before moving ACLEDIT$C_ENTER := 1; ! Enter ACE before movein cursor ACLEDIT$C_NOREPLACE := 0; ! Don't replace modified ACE with original ACLEDIT$C_REPLACE := 1; ! Replace modified ACE with original ACLEDIT$C_REMOVE_TEXT := 0; ! Remove text to paste buffer ACLEDIT$C_KEEP_TEXT := 1; ! Copy text to paste buffer ACLEDIT$C_SELECT_FIELD := 1; ! Select next field in sequence ACLEDIT$C_ADVANCE_FIELD := 2; ! Skip to next major (keyword) field ACLEDIT$C_CHECK_PREVIOUS:= 1; ! CHECK_MODIFY for previous ACE ACLEDIT$C_CHECK_CURRENT := 2; ! CHECK_MODIFY for current ACE ACLEDIT$C_CHECK_NEXT := 3; ! CHECK_MODIFY for next ACE ACLEDIT$C_WINDOW_SHIFT := 8; ! Number of columns to shift window ACLEDIT$C_MAXBUFNAMLEN := 12; ! Max size of buffer name in status line ACLEDIT$C_MAXOBJTYPLEN := 12; ! Max size of object type ACLEDIT$C_FIXEDWIDTH := 28; ! Pre-assigned space in the status line ! excluding buffer name, object type and name ! Miscellaneous other variables that need to be initialized. ACLEDIT$X_SPLIT_ACE := 0; ! Pointer to the split portion of the ACE ACLEDIT$X_ACE_TYPE := 0; ! Type of ACE being built ACLEDIT$X_MIN_OPT_FIELD := 0; ! First subfield number of the OPTION field ACLEDIT$X_MAX_OPT_FIELD := 0; ! Last subfield number of the OPTION field ACLEDIT$X_MIN_FIELD_3 := 0; ! First subfield number of the ACCES/protection field ACLEDIT$X_MAX_FIELD_3 := 0; ! Last subfield number of the ACCES/protection field ! Define the various types of ACEs allowed. This should parallel the $ACEDEF macro. ACE$C_KEYID := 1; ACE$C_RMSJNL_BI := 2; ACE$C_RMSJNL_AI := 3; ACE$C_RMSJNL_AT := 4; ACE$C_AUDIT := 5; ACE$C_ALARM := 6; ACE$C_INFO := 7; ACE$C_RMSJNL_RU_DEFAULT := 8; ACE$C_DIRDEF := 9; ACE$C_RMSJNL_RU := 10; ACE$C_RESERVED := 255; ! Define various search patterns. ACLEDIT$WORD_END_PATTERN := (ANY (ACLEDIT$X_WORD_SEPARATORS) | LINE_BEGIN | LINE_END); ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$WORD_BEGIN ! ! ROUTINE DESCRIPTION: This procedure returns the offset from the current ! position to the beginning of the current word. ! PROCEDURE ACLEDIT$WORD_BEGIN LOCAL SAVED_POSITION, POSITION_OFFSET; ! If currently at the beginning of the line, return now. IF CURRENT_OFFSET = 0 THEN RETURN 0; ENDIF; SAVED_POSITION := MARK (NONE); ! Note the current position MOVE_HORIZONTAL (-1); ! Skip the current character POSITION_OFFSET := 1; ! Skip over any spaces. LOOP EXITIF CURRENT_OFFSET = 0; EXITIF CURRENT_CHARACTER <> " "; MOVE_HORIZONTAL (-1); POSITION_OFFSET := POSITION_OFFSET + 1; ENDLOOP; ! If currently positioned over a word terminator, them we're done. Otherwise ! search for the next word terminator. IF INDEX (ACLEDIT$X_WORD_SEPARATORS, CURRENT_CHARACTER) = 0 THEN LOOP EXITIF CURRENT_OFFSET = 0; MOVE_HORIZONTAL (-1); IF INDEX (ACLEDIT$X_WORD_SEPARATORS, CURRENT_CHARACTER) <> 0 THEN MOVE_HORIZONTAL (1); EXITIF 1; ENDIF; POSITION_OFFSET := POSITION_OFFSET + 1; ENDLOOP; ENDIF; POSITION (SAVED_POSITION); ! Restore porition RETURN -POSITION_OFFSET; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$WORD_END ! ! ROUTINE DESCRIPTION: This procedure returns the offset from the current ! position to the end of the current word. ! PROCEDURE ACLEDIT$WORD_END LOCAL SAVED_POSITION, POSITION_OFFSET, POSITION_RANGE; ! If at the end of the current buffer, return now. IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN RETURN 0; ENDIF; ! If at the end of the current line, return now. IF CURRENT_OFFSET = LENGTH (CURRENT_LINE) THEN RETURN 0; ENDIF; SAVED_POSITION := MARK (NONE); ! Note current position. ! Skip any trailing blanks. LOOP EXITIF CURRENT_OFFSET = LENGTH (CURRENT_LINE); EXITIF CURRENT_CHARACTER <> " "; MOVE_HORIZONTAL (1); ENDLOOP; ! Search for the next word terminator if not at the end of the line. IF CURRENT_OFFSET < LENGTH (CURRENT_LINE) THEN IF INDEX (ACLEDIT$X_WORD_SEPARATORS, CURRENT_CHARACTER) <> 0 THEN MOVE_HORIZONTAL (1); ELSE POSITION_RANGE := SEARCH (ACLEDIT$WORD_END_PATTERN, FORWARD); POSITION (END_OF (POSITION_RANGE)); IF CURRENT_OFFSET = 0 THEN MOVE_HORIZONTAL (-1); ENDIF; ENDIF; ENDIF; POSITION_OFFSET := CURRENT_OFFSET; POSITION (SAVED_POSITION); POSITION_OFFSET := POSITION_OFFSET - CURRENT_OFFSET; RETURN POSITION_OFFSET; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$SET_STATUS_LINE ! ! ROUTINE DESCRIPTION: This procedure sets up the information in the ! status line. ! ! The status line consists of fixed and varaible text as follows ! Numbers above indicate width, {} indicates variable text: ! ! 7 ? 1 ? 1 ? 1 10 1 7 ! Buffer: {buffer_name} _ {object_type} : {object_name} _ Overstrike _ Forward ! __Insert__ _ Reverse ! ! ACLEDIT$C_FIXEDWIDTH is defined elsewhere as (7+1+1+1+10+1+7)= 28 ! ACLEDIT$C_MAXBUFNAMLEN is defined elsewhere as 12, the field will always be this ! ACLEDIT$C_MAXOBJTYPLEN is defined elsewhere as 12 and will be forced not to exceed this ! ! Thus the space available for object name, is given by ! avail_width = window_width - (ACLEDIT$C_FIXEDWIDTH ! + ACLEDIT$C_MAXBUFNAMLEN ! + MAX(ACLEDIT$C_MAXOBJTYPLEN,LENGTH(object_type)) ! PROCEDURE ACLEDIT$SET_STATUS_LINE LOCAL BUFFER_POINTER, ! Current buffer MODE, ! Insert/overstrike mode DIRECTION, ! Current direction BUFFER_NAME, ! Current buffer's name AVAIL_WIDTH, ! Available width in window for object description OBJECT_DESC; ! Description of object, type and name BUFFER_POINTER := GET_INFO (CURRENT_WINDOW, "BUFFER"); ! If the current window does not have an associated status line, this ! procedure is a no-op. IF (BUFFER_POINTER = 0) OR (GET_INFO (CURRENT_WINDOW, "STATUS_LINE") = 0) THEN RETURN ENDIF; ! Get the information needed to build the status line. IF GET_INFO (BUFFER_POINTER, "MODE") = INSERT THEN MODE := " Insert "; ELSE MODE := "Overstrike"; ENDIF; IF GET_INFO (BUFFER_POINTER, "DIRECTION") = FORWARD THEN DIRECTION := "Forward"; ELSE DIRECTION := "Reverse"; ENDIF; ! Force buffer name text to preset length, ! truncate or space fill as necessary BUFFER_NAME := GET_INFO (BUFFER_POINTER, "NAME"); IF LENGTH (BUFFER_NAME) > ACLEDIT$C_MAXBUFNAMLEN THEN BUFFER_NAME := SUBSTR (BUFFER_NAME, 1, ACLEDIT$C_MAXBUFNAMLEN); ELSE BUFFER_NAME := BUFFER_NAME + SUBSTR (ACLEDIT$X_SPACES, 1, ACLEDIT$C_MAXBUFNAMLEN - LENGTH (BUFFER_NAME)); ENDIF; ! Force object type to maximum size OBJECT_DESC := SUBSTR (ACLEDIT$X_OBJECT_TYPE, 1, ACLEDIT$C_MAXOBJTYPLEN); ! Find how much space for the object description ! Note the assumption that terminal width will not be less than the fixed part AVAIL_WIDTH := GET_INFO ( CURRENT_WINDOW, "WIDTH") - (ACLEDIT$C_FIXEDWIDTH + ACLEDIT$C_MAXBUFNAMLEN + LENGTH (OBJECT_DESC)); ! Force object name to exactly AVAIL_WIDTH IF LENGTH (ACLEDIT$X_INPUT_FILE) > AVAIL_WIDTH THEN OBJECT_DESC := OBJECT_DESC + ":" + SUBSTR (ACLEDIT$X_INPUT_FILE, 1, AVAIL_WIDTH); ELSE OBJECT_DESC := OBJECT_DESC + ":" + ACLEDIT$X_INPUT_FILE + SUBSTR (ACLEDIT$X_SPACES, 1, AVAIL_WIDTH - LENGTH (ACLEDIT$X_INPUT_FILE)); ENDIF; ! Modify the current window's status line. SET (STATUS_LINE, CURRENT_WINDOW, REVERSE, "Buffer:" + BUFFER_NAME + " " + OBJECT_DESC + " " + MODE + " " + DIRECTION); ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$SET_CURRENT_ACE ! ! ROUTINE DESCRIPTION: This procedure sets up the variables describing the ! original ACE and compressed ACE for the current ACE. ! PROCEDURE ACLEDIT$SET_CURRENT_ACE IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN ACLEDIT$X_ORIGINAL_ACE := ACLEDIT$X_NULL; ACLEDIT$X_COMPRESSED_ACE := ACLEDIT$X_NULL; ELSE ACLEDIT$X_ORIGINAL_ACE := CURRENT_LINE; ACLEDIT$X_COMPRESSED_ACE := CURRENT_LINE; EDIT (ACLEDIT$X_COMPRESSED_ACE, COLLAPSE, UPPER); ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$CHECK_MODIFY_ACE (ARG1, ARG2) ! ! INPUT PARAMETERS: ARG1: ACLEDIT$C_NOREPLACE - Don't replace untouchable ! ACE with original ! ACLEDIT$C_REPLACE - Replace untouchable ACE with ! original ! ARG2: ACLEDIT$C_CHECK_PREVIOUS - to check previous ACE ! ACLEDIT$C_CHECK_CURRENT - to check current ACE ! ACLEDIT$C_CHECK_NEXT - to check next ACE ! ! ROUTINE DESCRIPTION: This procedure returns a string to indicate whether ! or not the current ACE may be modified. ! ! ROUTINE VALUE: 'MODIFY' - if the ACE may be modified ! 'NO_MODIFY' - if the ACE cannot be modified ! PROCEDURE ACLEDIT$CHECK_MODIFY_ACE (REPLACE_FLAG, ACE_TO_USE) LOCAL SAVED_ERROR, SAVED_POSITION, ORIGINAL_ACE, COMPRESSED_ACE, SEARCH_RANGE; ! If an error occurs searching, then the ACE may be modified. ON_ERROR SAVED_ERROR := ERROR; IF (SAVED_ERROR = TPU$_STRNOTFOUND) OR (SAVED_ERROR = TPU$_BEGOFBUF) OR (SAVED_ERROR = TPU$_ENDOFBUF) THEN POSITION (SAVED_POSITION); RETURN 'MODIFY'; ENDIF; ENDON_ERROR; ! If not checking for untouchable ACEs, return now. IF NOT ACLEDIT$X_CHECK_MODIFY THEN RETURN 'MODIFY'; ENDIF; ! Pick up a reference point. SAVED_POSITION := MARK (NONE); ! Set up the necessary original ACE and compressed ACE variables. IF ACE_TO_USE = ACLEDIT$C_CHECK_PREVIOUS THEN MOVE_HORIZONTAL (-CURRENT_OFFSET); IF MARK (NONE) = BEGINNING_OF (CURRENT_BUFFER) THEN POSITION (SAVED_POSITION); RETURN 'MODIFY'; ENDIF; MOVE_HORIZONTAL (-1); ORIGINAL_ACE := CURRENT_LINE; COMPRESSED_ACE := CURRENT_LINE; EDIT (COMPRESSED_ACE, COLLAPSE, UPPER); ENDIF; IF ACE_TO_USE = ACLEDIT$C_CHECK_CURRENT THEN ORIGINAL_ACE := ACLEDIT$X_ORIGINAL_ACE; COMPRESSED_ACE := ACLEDIT$X_COMPRESSED_ACE; ENDIF; IF ACE_TO_USE = ACLEDIT$C_CHECK_NEXT THEN MOVE_HORIZONTAL (LENGTH (CURRENT_LINE) - CURRENT_OFFSET + 1); IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN POSITION (SAVED_POSITION); RETURN 'MODIFY'; ENDIF; ORIGINAL_ACE := CURRENT_LINE; COMPRESSED_ACE := CURRENT_LINE; EDIT (COMPRESSED_ACE, COLLAPSE, UPPER); ENDIF; ! First, check to see if the current ACE may be modified. IF (CALL_USER (ACLEDIT$C_CHECK_MODIFY, CURRENT_LINE) = 'READ_ONLY') THEN ACLEDIT$X_DUMMY := CALL_USER (ACLEDIT$C_MESSAGE, STR (ACLEDIT$_PROTECTED)); IF REPLACE_FLAG THEN ERASE_CHARACTER (LENGTH (CURRENT_LINE)); COPY_TEXT (ORIGINAL_ACE); MOVE_HORIZONTAL (-CURRENT_OFFSET); ENDIF; POSITION (SAVED_POSITION); RETURN 'NO_MODIFY'; ENDIF; ! If there is not original ACE, (i.e., null), return now. IF COMPRESSED_ACE = ACLEDIT$X_NULL THEN POSITION (SAVED_POSITION); RETURN 'MODIFY'; ENDIF; ! Switch over to the protected ACE buffer to check for ACEs that cannot be ! modified. POSITION (BEGINNING_OF (PROTECTED_ACE_BUFFER)); ! Search for the ACE in the protected ACE buffer. SEARCH_RANGE := SEARCH (COMPRESSED_ACE, FORWARD, EXACT); ! If the ACE was found, it cannot be modified. Otherwise, anything goes. POSITION (SAVED_POSITION); IF SEARCH_RANGE = 0 THEN RETURN 'MODIFY'; ELSE ACLEDIT$X_DUMMY := CALL_USER (ACLEDIT$C_MESSAGE, STR (ACLEDIT$_PROTECTED)); IF REPLACE_FLAG THEN ERASE_CHARACTER (LENGTH (CURRENT_LINE)); COPY_TEXT (ORIGINAL_ACE); MOVE_HORIZONTAL (-CURRENT_OFFSET); ENDIF; RETURN 'NO_MODIFY'; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$CHECK_DUPLICATE_ACE ! ! ROUTINE DESCRIPTION: This procedure returns a string to indicate whether ! or not the current ACE is a duplicate of another ACE ! in the object's ACL. ! ! ROUTINE VALUE: 'DUPLICATE_ACE' - if the ACE is a duplicate ! 'UNIQUE_ACE' - if the ACE is not a duplicate ! PROCEDURE ACLEDIT$CHECK_DUPLICATE_ACE LOCAL SAVED_POSITION, START_CURRENT_ACE, DUMMY; ! See if checking for duplicates is necessary. IF NOT ACLEDIT$X_CHECK_DUPLICATES THEN RETURN 'UNIQUE'; ENDIF; ! Remember some needed positions. SAVED_POSITION := MARK (NONE); MOVE_HORIZONTAL (-CURRENT_OFFSET); START_CURRENT_ACE := MARK (NONE); DUMMY:=CALL_USER (ACLEDIT$C_SET_CANDIDATE, CURRENT_LINE); ! Now start checking for duplicates, from the beginning of the ACL. POSITION (BEGINNING_OF (CURRENT_BUFFER)); LOOP EXITIF MARK (NONE) = END_OF (CURRENT_BUFFER); IF MARK (NONE) <> START_CURRENT_ACE THEN IF CALL_USER (ACLEDIT$C_CHECK_DUP, CURRENT_LINE) = "DUPLICATE_ACE" THEN IF MARK (NONE) < START_CURRENT_ACE THEN ACLEDIT$X_DUMMY := CALL_USER (ACLEDIT$C_MESSAGE, STR (ACLEDIT$_PREVDUPACE)); POSITION (SAVED_POSITION); RETURN "DUPLICATE_ACE"; ELSE ACLEDIT$X_DUMMY := CALL_USER (ACLEDIT$C_MESSAGE, STR (ACLEDIT$_SUCCDUPACE)); POSITION (SAVED_POSITION); RETURN "DUPLICATE_ACE"; ENDIF; ENDIF; ENDIF; MOVE_VERTICAL (1); ENDLOOP; ! Restore position and return/ POSITION (SAVED_POSITION); RETURN "UNIQUE_ACE"; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$HELP ! ! ROUTINE DESCRIPTION: Supply interactive help for the ACL editor. ! PROCEDURE ACLEDIT$HELP LOCAL HOME_BOTTOM, SAVED_POSITION, USER_KEY, USER_KEY_TYPE, USER_KEY_INDEX, USER_KEY_PROGRAM, USER_KEY_COMMENT, FIELD_INDEX, ITEM_INDEX, MAX_ITEM_INDEX; HOME_BOTTOM := ASCII (27) + "["+ STR (ACLEDIT$X_SCREEN_LENGTH - 2) + ";1f"; ! If a window and buffer have not already been created, do it now. IF ACLEDIT$X_HELP_WINDOW = ACLEDIT$X_NULL THEN ACLEDIT$X_HELP_BUFFER := CREATE_BUFFER ("EDITOR_HELP"); SET (EOB_TEXT, ACLEDIT$X_HELP_BUFFER, ACLEDIT$X_NULL); SET (NO_WRITE, ACLEDIT$X_HELP_BUFFER); ACLEDIT$X_HELP_WINDOW := CREATE_WINDOW (1, ACLEDIT$X_SCREEN_LENGTH, OFF); SET (TEXT, ACLEDIT$X_HELP_WINDOW, NO_TRANSLATE); ENDIF; ERASE(ACLEDIT$X_HELP_BUFFER); SAVED_POSITION := MARK (NONE); MAP (ACLEDIT$X_HELP_WINDOW, ACLEDIT$X_HELP_BUFFER); ! Initialize local storage. FIELD_INDEX := 0; ITEM_INDEX := 0; ! Supply a definition for the space, tab, and question mark keys since they ! have special meaning in the help context. DEFINE_KEY ('X:="*"', KEY_NAME (" "), "SPACE_KEY"); DEFINE_KEY ('X:="*"', KEY_NAME (" "), "ACE_FORMAT"); DEFINE_KEY ('X:="*"', KEY_NAME ("?"), "STARTING_UP"); ! Display the initial keypad. IF ACLEDIT$X_HELP_FORMAT = 0 THEN FORMAT_HELP_STRING := ACLEDIT$X_TERMINAL_TYPE; ELSE FORMAT_HELP_STRING := "ACE_FORMAT"; ENDIF; HELP_TEXT ("SYS$HELP:ACLEDT", FORMAT_HELP_STRING, OFF, ACLEDIT$X_HELP_BUFFER); ! Display the help text. POSITION (BEGINNING_OF (ACLEDIT$X_HELP_BUFFER)); ERASE_LINE; ERASE_LINE; ERASE_LINE; ! The following loop is a kludge. LOOP EXITIF MARK (NONE) = END_OF (ACLEDIT$X_HELP_BUFFER); IF CURRENT_CHARACTER = " " THEN ERASE_CHARACTER (1); IF CURRENT_CHARACTER = " " THEN ERASE_CHARACTER (1); ENDIF; ENDIF; MOVE_VERTICAL (1); ENDLOOP; IF FORMAT_HELP_STRING <> ACLEDIT$X_TERMINAL_TYPE THEN POSITION (END_OF (ACLEDIT$X_HELP_BUFFER)); COPY_TEXT ("---------------"); SPLIT_LINE; COPY_TEXT ("To return to the keypad diagram, press the return key"); SPLIT_LINE; COPY_TEXT ("To exit from HELP, press the spacebar"); SPLIT_LINE; COPY_TEXT ("For help on getting started, press the question mark key"); SPLIT_LINE; COPY_TEXT ("To select the next field, press the keypad 7"); SPLIT_LINE; COPY_TEXT ("To select the next item, press the keypad period"); SPLIT_LINE; COPY_TEXT (HOME_BOTTOM); ENDIF; POSITION (BEGINNING_OF (ACLEDIT$X_HELP_BUFFER)); UPDATE (ACLEDIT$X_HELP_WINDOW); ! Get the key for which help is desired. LOOP ERASE(ACLEDIT$X_HELP_BUFFER); USER_KEY := READ_KEY; USER_KEY_COMMENT := LOOKUP_KEY (USER_KEY, COMMENT); IF USER_KEY_COMMENT <> ACLEDIT$X_NULL THEN EXITIF USER_KEY_COMMENT = "SPACE_KEY"; IF USER_KEY_COMMENT = "ACE_FORMAT" THEN FORMAT_HELP_STRING := USER_KEY_COMMENT; ACLEDIT$X_HELP_FORMAT := 1; FIELD_INDEX := 0; ITEM_INDEX := 0; ENDIF; IF ACLEDIT$X_HELP_FORMAT = 0 THEN FORMAT_HELP_STRING := USER_KEY_COMMENT; IF FORMAT_HELP_STRING = "RESTART_HELP" THEN FORMAT_HELP_STRING := ACLEDIT$X_TERMINAL_TYPE; ENDIF; ELSE IF (USER_KEY_COMMENT = "RESTART_HELP") OR (USER_KEY_COMMENT = "KP7_KEY") OR (USER_KEY_COMMENT = "KPERIOD_KEY") THEN IF USER_KEY_COMMENT = "RESTART_HELP" THEN ACLEDIT$X_HELP_FORMAT := 0; FORMAT_HELP_STRING := ACLEDIT$X_TERMINAL_TYPE; FIELD_INDEX := 0; ITEM_INDEX := 0; ELSE IF USER_KEY_COMMENT = "KP7_KEY" THEN FIELD_INDEX := FIELD_INDEX + 1; IF FIELD_INDEX > 3 THEN FIELD_INDEX := 1; ENDIF; ITEM_INDEX := 0; CASE FIELD_INDEX FROM 1 TO 3 [1]: FORMAT_HELP_STRING := "ACE_TYPES"; MAX_ITEM_INDEX := 6; [2]: IF ACLEDIT$X_CHECK_MODIFY THEN FORMAT_HELP_STRING := "ACE_FLAGS_NOHID"; ELSE FORMAT_HELP_STRING := "ACE_FLAGS"; ENDIF; MAX_ITEM_INDEX := 5; [3]: FORMAT_HELP_STRING := "ACCESS_TYPES"; MAX_ITEM_INDEX := 8; ENDCASE; ELSE IF (USER_KEY_COMMENT = "KPERIOD_KEY") AND (FIELD_INDEX > 0) THEN ITEM_INDEX := ITEM_INDEX + 1; IF ITEM_INDEX > MAX_ITEM_INDEX THEN ITEM_INDEX := 1; ENDIF; CASE FIELD_INDEX FROM 1 TO 3 [1]: CASE ITEM_INDEX FROM 1 TO 6 [1]: FORMAT_HELP_STRING := "IDENTIFIER_ACE"; [2]: FORMAT_HELP_STRING := "ALARM_ACE"; [3]: FORMAT_HELP_STRING := "AUDIT_ACE"; [4]: FORMAT_HELP_STRING := "DEFPRO_ACE"; [5]: FORMAT_HELP_STRING := "CREATOR_ACE"; [6]: FORMAT_HELP_STRING := "SUBSYSTEM_ACE"; ENDCASE; [2]: IF (ITEM_INDEX = 3) AND (ACLEDIT$X_CHECK_MODIFY) THEN ITEM_INDEX := ITEM_INDEX + 1; ENDIF; CASE ITEM_INDEX FROM 1 TO 5 [1]: FORMAT_HELP_STRING := "NONE_FLAG"; [2]: FORMAT_HELP_STRING := "DEFAULT_FLAG"; [3]: FORMAT_HELP_STRING := "HIDDEN_FLAG"; [4]: FORMAT_HELP_STRING := "PROTECTED_FLAG"; [5]: FORMAT_HELP_STRING := "NOPROP_FLAG"; ENDCASE; [3]: CASE ITEM_INDEX FROM 1 TO 8 [1]: FORMAT_HELP_STRING := "NONE_ACCESS"; [2]: FORMAT_HELP_STRING := "READ_ACCESS"; [3]: FORMAT_HELP_STRING := "WRITE_ACCESS"; [4]: FORMAT_HELP_STRING := "EXECUTE_ACCESS"; [5]: FORMAT_HELP_STRING := "DELETE_ACCESS"; [6]: FORMAT_HELP_STRING := "CONTROL_ACCESS"; [7]: FORMAT_HELP_STRING := "SUCCESS_ACCESS"; [8]: FORMAT_HELP_STRING := "FAILED_ACCESS"; ENDCASE; ENDCASE; ENDIF; ENDIF; ENDIF; ENDIF; ENDIF; HELP_TEXT ("SYS$HELP:ACLEDT", FORMAT_HELP_STRING, OFF, ACLEDIT$X_HELP_BUFFER); ! Display the help text. POSITION (BEGINNING_OF (ACLEDIT$X_HELP_BUFFER)); ERASE_LINE; ERASE_LINE; ERASE_LINE; ! The following loop is a kludge. LOOP EXITIF MARK (NONE) = END_OF (ACLEDIT$X_HELP_BUFFER); IF CURRENT_CHARACTER = " " THEN ERASE_CHARACTER (1); IF CURRENT_CHARACTER = " " THEN ERASE_CHARACTER (1); ENDIF; ENDIF; MOVE_VERTICAL (1); ENDLOOP; IF FORMAT_HELP_STRING <> ACLEDIT$X_TERMINAL_TYPE THEN POSITION (END_OF (ACLEDIT$X_HELP_BUFFER)); COPY_TEXT ("---------------"); SPLIT_LINE; COPY_TEXT ("To return to the keypad diagram, press the return key"); SPLIT_LINE; COPY_TEXT ("To exit from HELP, press the spacebar"); SPLIT_LINE; COPY_TEXT ("For help on getting started, press the question mark key"); SPLIT_LINE; IF ACLEDIT$X_HELP_FORMAT <> 0 THEN COPY_TEXT ("To select the next field, press the keypad 7"); SPLIT_LINE; COPY_TEXT ("To select the next item, press the keypad period"); SPLIT_LINE; ELSE COPY_TEXT ("For help of the ACE format press the tab key"); SPLIT_LINE; COPY_TEXT ("For help on any other keypad key, press the key"); SPLIT_LINE; ENDIF; COPY_TEXT (HOME_BOTTOM); ENDIF; POSITION (BEGINNING_OF (ACLEDIT$X_HELP_BUFFER)); UPDATE (ACLEDIT$X_HELP_WINDOW); ENDIF; ENDLOOP; ! Remove the temporary key definitions. UNDEFINE_KEY (KEY_NAME (" ")); UNDEFINE_KEY (KEY_NAME (" ")); UNDEFINE_KEY (KEY_NAME ("?")); ! Now remove the help window, and return. UNMAP (ACLEDIT$X_HELP_WINDOW); POSITION (SAVED_POSITION); REFRESH; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$LOCATE_NEXT ! ! ROUTINE DESCRIPTION: Locate the next occurrance of a previously specified ! string. ! PROCEDURE ACLEDIT$LOCATE_NEXT LOCAL SEARCH_OFFSET, SAVED_ERROR, SAVED_POSITION, BOL_MARKER, EOL_MARKER, SEARCH_RANGE; ON_ERROR SAVED_ERROR := ERROR; IF (SAVED_ERROR = TPU$_STRNOTFOUND) OR (SAVED_ERROR = TPU$_BEGOFBUF) OR (SAVED_ERROR = TPU$_ENDOFBUF) THEN MESSAGE ('String was not found'); IF SAVED_POSITION <> 0 THEN POSITION (SAVED_POSITION); RETURN; ENDIF; IF (SAVED_ERROR = TPU$_BEGOFBUF) OR (SAVED_ERROR = TPU$_ENDOFBUF) THEN RETURN ENDIF; ENDIF; ENDON_ERROR; ! If there is not already a search string, get one. IF ACLEDIT$X_SEARCH_STRING = ACLEDIT$X_NULL THEN ACLEDIT$X_SEARCH_STRING := READ_LINE ('Search for: '); ENDIF; ! If the string terminator was the advance or backup key, change the movement ! direction. IF LAST_KEY = KP5 THEN SET (REVERSE, CURRENT_BUFFER); ACLEDIT$SET_STATUS_LINE; ELSE IF LAST_KEY = KP4 THEN SET (FORWARD, CURRENT_BUFFER); ACLEDIT$SET_STATUS_LINE; ELSE IF LAST_KEY = CTRL_U_KEY THEN RETURN; ENDIF; ENDIF; ENDIF; ! Set the default offset, based upon the movement direction. This offset is ! necessary to skip over the string just found (assuming that the current ! position is the beginning of the located string). IF CURRENT_DIRECTION = FORWARD THEN IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN MESSAGE ('String was not found'); RETURN; ENDIF; SEARCH_OFFSET := 1; ELSE IF MARK (NONE) = BEGINNING_OF (CURRENT_BUFFER) THEN MESSAGE ('String was not found'); RETURN; ENDIF; SEARCH_OFFSET := -1; ENDIF; ! Note the current position, and the boundaries of the current line. SAVED_POSITION := MARK (NONE); MOVE_HORIZONTAL (-CURRENT_OFFSET); BOL_MARKER := MARK (NONE); MOVE_HORIZONTAL (LENGTH (CURRENT_LINE)); EOL_MARKER := MARK (NONE); POSITION (SAVED_POSITION); ! Try to find the next occurrance of the specified string. MOVE_HORIZONTAL (SEARCH_OFFSET); SEARCH_RANGE := SEARCH (ACLEDIT$X_SEARCH_STRING, CURRENT_DIRECTION, NO_EXACT); IF SEARCH_RANGE <> 0 THEN ! If the next occurrance of the string is outside the bounds of the current ! ACE, try to enter the current ACE. IF (BEGINNING_OF (SEARCH_RANGE) > EOL_MARKER) OR (BEGINNING_OF (SEARCH_RANGE) < BOL_MARKER) THEN ACLEDIT$S_STATUS := ACLEDIT$ENTER_ACE (ACLEDIT$C_NOPOSITION); IF ACLEDIT$X_STATUS = 'ACE_ERROR' THEN RETURN; ENDIF; ENDIF; POSITION (BEGINNING_OF (SEARCH_RANGE)); ACLEDIT$SET_CURRENT_ACE; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$LOCATE_STRING ! ! ROUTINE DESCRIPTION: Obtain and/or locate the next occurrance of a string. ! PROCEDURE ACLEDIT$LOCATE_STRING ! Set the search string to be null. This will force a new prompt. ACLEDIT$X_SEARCH_STRING := ACLEDIT$X_NULL; ACLEDIT$LOCATE_NEXT; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$DELETE_ACE ! ! ROUTINE DESCRIPTION: This procedure is called to delete the current ACE. ! PROCEDURE ACLEDIT$DELETE_ACE ! Check to see if this ACE may be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT)= 'NO_MODIFY' THEN RETURN; ENDIF; ! Delete the entire line. ACLEDIT$X_DELETE_ACE := ERASE_LINE; ACLEDIT$SET_CURRENT_ACE; IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN IF ACLEDIT$X_PROMPT THEN ACLEDIT$INSERT_ACE; ENDIF; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$UNDELETE_ACE ! ! ROUTINE DESCRIPTION: This procedure is called to restore the previously ! deleted ACE. The cursor is left positioned at the ! beginning of the undeleted ACE. ! PROCEDURE ACLEDIT$UNDELETE_ACE ! If there is anything to restore, do it. IF ACLEDIT$X_DELETE_ACE <> ACLEDIT$X_NULL THEN ! Enter the current ACE. ACLEDIT$X_STATUS := ACLEDIT$ENTER_ACE (ACLEDIT$C_NOPOSITION); IF ACLEDIT$X_STATUS = 'ACE_ERROR' THEN RETURN; ENDIF; ! Restore the deleted ACE. MOVE_HORIZONTAL (-CURRENT_OFFSET); IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN COPY_TEXT (ACLEDIT$X_DELETE_ACE); MOVE_HORIZONTAL (-LENGTH (ACLEDIT$X_DELETE_ACE)); ELSE COPY_TEXT (ACLEDIT$X_DELETE_ACE); SPLIT_LINE; MOVE_HORIZONTAL (-(LENGTH (ACLEDIT$X_DELETE_ACE) + 1)); ENDIF; ! If the restored text is the initial ACE prompt, set the ACE type. IF INDEX("(IDENTIFIER=", CURRENT_LINE) <> 0 THEN ACLEDIT$X_ACE_TYPE := ACE$C_KEYID; ENDIF; IF INDEX("(ALARM=SECURITY", CURRENT_LINE) <> 0 THEN ACLEDIT$X_ACE_TYPE := ACE$C_ALARM; ENDIF; IF INDEX("(DEFAULT_PROTECTION", CURRENT_LINE) <> 0 THEN ACLEDIT$X_ACE_TYPE := ACE$C_DIRDEF; ENDIF; ! Kludge up the original and compressed ACE. ACLEDIT$X_ORIGINAL_ACE := ACLEDIT$X_NULL; ACLEDIT$X_COMPRESSED_ACE := ACLEDIT$X_NULL; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$NEXT_FIELD (ARG1) ! ! ROUTINE DESCRIPTION: Advance to the next ACE field or subfield. ! ! The field numbers used for the various ACE types are as follows: ! ! Type: ACE$C_KEYID ! ! (type=keyword, OPT = DEF + HID + PROT + NOPROP + NONE, ACC = R + W + E + D + C + NONE) ! ^----0-----^ 1 2 3 4 5 6 7 8 9 1 1 1 1 ! 0 1 2 3 ! ! Type: ACE$C_ALARM and ACE$C_AUDIT ! ! (type=keyword, OPT = DEF + HID + PROT + NOPROP + NONE, ACC = R + W + E + D + C + S + F + NONE) ! ^----0-----^ 1 2 3 4 5 6 7 8 9 1 1 1 1 1 1 ! 0 1 2 3 4 5 ! ! Type: ACE$C_DIRDEF ! ! (DEFAULT_PROT, OPT = DEF + HID + PROT + NOPROP + NONE, SYS:xxx, OWN:xxx, GRP:xxx, WOR:xxx) ! ^----0-----^ 1 2 3 4 5 6 7 8 9 1 ! 0 ! PROCEDURE ACLEDIT$NEXT_FIELD (ADVANCE_OPTION) LOCAL SAVED_POSITION, COMPLETE_ACE, OPEN_UIC_ID, LAST_CHARACTER, SAVED_DIRECTION; ! Since the position within the ACE may have changed, it is necessary to ! recalculate the current field position. SAVED_POSITION := MARK (NONE); MOVE_HORIZONTAL (-CURRENT_OFFSET); ACLEDIT$X_FIELD := 0; LOOP EXITIF MARK (NONE) = SAVED_POSITION; IF CURRENT_CHARACTER = ")" THEN COMPLETE_ACE := 1; ENDIF; IF CURRENT_CHARACTER = "[" THEN OPEN_UIC_ID := 1; ENDIF; IF CURRENT_CHARACTER = "]" THEN OPEN_UIC_ID := 0; ENDIF; IF OPEN_UIC_ID = 0 THEN IF CURRENT_CHARACTER = "," THEN ACLEDIT$X_FIELD := ACLEDIT$X_FIELD + 1; IF (ACLEDIT$X_FIELD > ACLEDIT$X_MIN_OPT_FIELD) AND (ACLEDIT$X_FIELD <= ACLEDIT$X_MAX_OPT_FIELD) THEN ACLEDIT$X_FIELD := ACLEDIT$X_MIN_FIELD_3; ENDIF; ENDIF; IF ACLEDIT$X_FIELD >= ACLEDIT$X_MIN_OPT_FIELD THEN IF (CURRENT_CHARACTER = "=") OR (CURRENT_CHARACTER = "+") THEN ACLEDIT$X_FIELD := ACLEDIT$X_FIELD + 1; ENDIF; ENDIF; ENDIF; MOVE_HORIZONTAL (1); ENDLOOP; POSITION (SAVED_POSITION); ! If the ACE is complete and we are positioned at the end of the ACE ! or there is no more to add to this ACE, this key is a no-op. IF (COMPLETE_ACE <> 0) AND (CURRENT_OFFSET = LENGTH (CURRENT_LINE)) THEN RETURN; ENDIF; ! If at the end of the ACE, things are relatively simple. IF CURRENT_OFFSET = LENGTH (CURRENT_LINE) THEN ! If the identifier is a UIC, and it is incomplete, note the error and trip ! out now. IF OPEN_UIC_ID <> 0 THEN MESSAGE ("Must complete UIC before advancing"); RETURN; ENDIF; ! If this is the beginning of a new ACE, set up the opening character. IF LENGTH (CURRENT_LINE) = 0 THEN COPY_TEXT ("("); ACLEDIT$X_ACE_TYPE := 0; ENDIF; ! Skip over (and remove) any trailing spaces. MOVE_HORIZONTAL (-1); LOOP EXITIF CURRENT_CHARACTER <> " "; EXITIF CURRENT_OFFSET = 0; MOVE_HORIZONTAL (-1); ENDLOOP; IF CURRENT_OFFSET < LENGTH (CURRENT_LINE) - 1 THEN MOVE_HORIZONTAL (1); ERASE_CHARACTER (LENGTH (CURRENT_LINE) - CURRENT_OFFSET); MOVE_HORIZONTAL (-1); ENDIF; ! If this is an advance, as opposed to a select, it may be necessary to diddle ! the field number. IF ADVANCE_OPTION = ACLEDIT$C_ADVANCE_FIELD THEN IF (ACLEDIT$X_FIELD >= ACLEDIT$X_MIN_OPT_FIELD) AND (ACLEDIT$X_FIELD <= ACLEDIT$X_MAX_OPT_FIELD - 1) THEN IF (ACLEDIT$X_FIELD = ACLEDIT$X_MIN_OPT_FIELD) AND (CURRENT_CHARACTER = ",") THEN MOVE_HORIZONTAL (1); COPY_TEXT ("OPTIONS=NONE"); ENDIF; IF (ACLEDIT$X_FIELD = ACLEDIT$X_MIN_OPT_FIELD + 1) AND (CURRENT_CHARACTER = "=") THEN MOVE_HORIZONTAL (1); COPY_TEXT ("NONE"); ENDIF; ACLEDIT$X_FIELD := ACLEDIT$X_MAX_OPT_FIELD; ENDIF; IF (ACLEDIT$X_FIELD >= ACLEDIT$X_MIN_FIELD_3 + 1) AND (ACLEDIT$X_ACE_TYPE <> ACE$C_DIRDEF) THEN IF CURRENT_CHARACTER = "+" THEN ERASE_CHARACTER (1); MOVE_HORIZONTAL (-1); ENDIF; IF (CURRENT_CHARACTER = "=") AND (ACLEDIT$X_FIELD = ACLEDIT$X_MIN_FIELD_3 + 1) THEN MOVE_HORIZONTAL (1); COPY_TEXT ("NONE)"); RETURN; ELSE MOVE_HORIZONTAL (1); COPY_TEXT (")"); RETURN; ENDIF; ENDIF; ENDIF; ! Now that the current field has been determined, tie off the current field ! if necessary. LAST_CHARACTER := CURRENT_CHARACTER; MOVE_HORIZONTAL (1); IF (ACLEDIT$X_FIELD >= ACLEDIT$X_MIN_FIELD_3) AND (ACLEDIT$X_FIELD <= ACLEDIT$X_MAX_FIELD_3) THEN IF (LAST_CHARACTER <> ",") AND (LAST_CHARACTER <> "+") THEN IF ACLEDIT$X_ACE_TYPE <> ACE$C_DIRDEF THEN IF ACLEDIT$X_FIELD = ACLEDIT$X_MIN_FIELD_3 THEN COPY_TEXT ("="); ACLEDIT$X_ITEM := 0; ELSE IF (ACLEDIT$X_FIELD = ACLEDIT$X_MIN_FIELD_3 + 1) AND (LAST_CHARACTER = "=") THEN ACLEDIT$X_FIELD := ACLEDIT$X_FIELD - 1; ACLEDIT$X_ITEM := 0; ELSE IF ACLEDIT$X_FIELD = ACLEDIT$X_MAX_FIELD_3 - 1 THEN COPY_TEXT (")"); RETURN; ELSE COPY_TEXT ("+"); ENDIF; ENDIF; ENDIF; ACLEDIT$X_FIELD := ACLEDIT$X_FIELD + 1; ELSE IF ACLEDIT$X_FIELD = ACLEDIT$X_MAX_FIELD_3 THEN COPY_TEXT (")"); RETURN ELSE COPY_TEXT (","); ENDIF; ENDIF; ELSE IF (LAST_CHARACTER = "+") AND (ACLEDIT$X_FIELD = ACLEDIT$X_MAX_FIELD_3) THEN ERASE_CHARACTER (-1); COPY_TEXT (")"); RETURN; ENDIF; ENDIF; ENDIF; IF (ACLEDIT$X_FIELD >= ACLEDIT$X_MIN_OPT_FIELD) AND (ACLEDIT$X_FIELD <= ACLEDIT$X_MAX_OPT_FIELD) THEN IF (LAST_CHARACTER <> ",") AND (LAST_CHARACTER <> "+") THEN IF ACLEDIT$X_FIELD = ACLEDIT$X_MIN_OPT_FIELD THEN COPY_TEXT ("="); ACLEDIT$X_ITEM := 0; ELSE IF (ACLEDIT$X_FIELD = ACLEDIT$X_MIN_OPT_FIELD + 1) AND (LAST_CHARACTER = "=") THEN ACLEDIT$X_FIELD := ACLEDIT$X_FIELD - 1; ACLEDIT$X_ITEM := 0; ELSE IF ACLEDIT$X_FIELD = ACLEDIT$X_MAX_OPT_FIELD - 1 THEN COPY_TEXT (","); ACLEDIT$X_FIELD := ACLEDIT$X_MIN_FIELD_3 - 1; ACLEDIT$X_ITEM := 0; ELSE COPY_TEXT ("+"); ENDIF; ENDIF; ENDIF; ACLEDIT$X_FIELD := ACLEDIT$X_FIELD + 1; ELSE IF (LAST_CHARACTER = "+") AND (ACLEDIT$X_FIELD = ACLEDIT$X_MAX_OPT_FIELD) THEN ERASE_CHARACTER (-1); COPY_TEXT (","); ACLEDIT$X_FIELD := ACLEDIT$X_MIN_FIELD_3; ACLEDIT$X_ITEM := 0; ENDIF; ENDIF; ENDIF; IF ACLEDIT$X_FIELD = 0 THEN MOVE_HORIZONTAL (LENGTH (CURRENT_LINE) - CURRENT_OFFSET); COPY_TEXT (","); ACLEDIT$X_FIELD := ACLEDIT$X_FIELD + 1; ACLEDIT$X_ITEM := 0; ENDIF; ! If at the field for the NONE item, advance to the next field if there have ! already been items selected for this field. IF ACLEDIT$X_FIELD = ACLEDIT$X_MAX_OPT_FIELD THEN ACLEDIT$X_FIELD := ACLEDIT$X_MIN_FIELD_3;; ENDIF; IF (((ACLEDIT$X_FIELD >= ACLEDIT$X_MIN_OPT_FIELD + 2) AND (ACLEDIT$X_FIELD <= ACLEDIT$X_MAX_OPT_FIELD) AND (ACLEDIT$X_ITEM = 4)) OR ((ACLEDIT$X_FIELD >= ACLEDIT$X_MIN_FIELD_3 + 1) AND (ACLEDIT$X_ITEM = ACLEDIT$X_MAX_FIELD_3 - ACLEDIT$X_MIN_FIELD_3 - 1))) AND (ACLEDIT$X_ACE_TYPE <> ACE$C_DIRDEF) THEN ACLEDIT$X_ITEM := 0; ENDIF; ! If starting a major field, add the appropriate keyword. IF ACLEDIT$X_FIELD = ACLEDIT$X_MIN_OPT_FIELD THEN COPY_TEXT ("OPTIONS="); ACLEDIT$X_ITEM := 0; ENDIF; IF (ACLEDIT$X_FIELD = ACLEDIT$X_MIN_FIELD_3) AND (ACLEDIT$X_ACE_TYPE <> ACE$C_DIRDEF) THEN COPY_TEXT ("ACCESS="); ACLEDIT$X_ITEM := 0; ENDIF; ! Since we are currently position at the end of the ACE, the current item ! is null. MOVE_HORIZONTAL (LENGTH (CURRENT_LINE) - CURRENT_OFFSET); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); ACLEDIT$X_END_ITEM := MARK (NONE); ! If past the last field, no more is necessary. ACLEDIT$SELECT_ITEM; ELSE ! Since this is an existing ACE, things get a little more interresting when ! selecting fields. Note that the field delimitors are the same as the ! standard word delimiters. IF ACLEDIT$X_FIELD = 0 THEN LOOP EXITIF CURRENT_OFFSET = LENGTH (CURRENT_LINE); IF CURRENT_CHARACTER = "[" THEN OPEN_UIC_ID := 1; ENDIF; IF CURRENT_CHARACTER = "]" THEN OPEN_UIC_ID := 0; ENDIF; IF OPEN_UIC_ID = 0 THEN EXITIF CURRENT_CHARACTER = "," ENDIF; MOVE_HORIZONTAL (1); ENDLOOP; IF CURRENT_CHARACTER <> ACLEDIT$X_NULL THEN MOVE_HORIZONTAL (1); ENDIF; ELSE IF CURRENT_CHARACTER <> ")" THEN SAVED_DIRECTION := CURRENT_DIRECTION; SET (FORWARD, CURRENT_BUFFER); ACLEDIT$MOVE_WORD; SET (SAVED_DIRECTION, CURRENT_BUFFER); IF (CURRENT_OFFSET <> 0) AND (CURRENT_CHARACTER <> ACLEDIT$X_NULL) AND (CURRENT_CHARACTER <> ")") THEN MOVE_HORIZONTAL (1); ENDIF; ENDIF; ENDIF; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$MOVE_SCREEN ! ! ROUTINE DESCRIPTION: This procedure move the cursor one screen in the ! appropriate direction. ! PROCEDURE ACLEDIT$MOVE_SCREEN IF CURRENT_DIRECTION = FORWARD THEN ACLEDIT$NEXT_SCREEN; ELSE ACLEDIT$PREVIOUS_SCREEN; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$DELETE_WORD ! ! ROUTINE DESCRIPTION: This procedure deletes the word starting at the ! current cursoe position. ! PROCEDURE ACLEDIT$DELETE_WORD LOCAL OFFSET; ! Check to see if this ACE may be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT)= 'NO_MODIFY' THEN RETURN; ENDIF; ! Wipe out the current word, and stash away the deleted text. OFFSET := ACLEDIT$WORD_END; IF OFFSET = 0 THEN ! Check to see if the next ACE may be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_NEXT)= 'NO_MODIFY' THEN RETURN; ENDIF; ! Zap the line terminator. MOVE_HORIZONTAL (1); IF MARK (NONE) <> END_OF (CURRENT_BUFFER) THEN APPEND_LINE; ELSE MOVE_HORIZONTAL (-1); ENDIF; ACLEDIT$X_DELETE_WORD := ACLEDIT$X_LINE_TERM_CHAR; ACLEDIT$SET_CURRENT_ACE; ELSE ACLEDIT$X_DELETE_WORD := ERASE_CHARACTER (OFFSET); ENDIF; ACLEDIT$X_RUBOUT_WORD := ACLEDIT$X_NULL; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$UNDELETE_WORD ! ! ROUTINE DESCRIPTION: Restore the previously deleted word. ! PROCEDURE ACLEDIT$UNDELETE_WORD ! If the deleted word was the previous word, restore it, and position ! the cursor after it. IF ACLEDIT$X_RUBOUT_WORD <> ACLEDIT$X_NULL THEN IF ACLEDIT$X_RUBOUT_WORD = ACLEDIT$X_LINE_TERM_CHAR THEN IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN RETURN; ENDIF; IF (CURRENT_OFFSET = 0) OR (CURRENT_OFFSET = LENGTH (CURRENT_LINE)) THEN RETURN; ENDIF; ! Check to see if the current ACE can be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT) = 'NO_MODIFY' THEN RETURN; ENDIF; ! Otherwise, split the line at the current position. SPLIT_LINE; ! ***** Really need to parse both halves of the now split apart ACE. ELSE ! Check to see if the current ACE can be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT) = 'NO_MODIFY' THEN RETURN; ENDIF; COPY_TEXT (ACLEDIT$X_RUBOUT_WORD); ENDIF; ENDIF; ! If the deleted word was the previous word, restore it, and position ! the cursor after it. IF ACLEDIT$X_DELETE_WORD <> ACLEDIT$X_NULL THEN IF ACLEDIT$X_DELETE_WORD = ACLEDIT$X_LINE_TERM_CHAR THEN IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN RETURN; ENDIF; IF (CURRENT_OFFSET = 0) OR (CURRENT_OFFSET = LENGTH (CURRENT_LINE)) THEN RETURN; ENDIF; ! Check to see if the current ACE can be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT) = 'NO_MODIFY' THEN RETURN; ENDIF; ! Otherwise, split the line at the current position. SPLIT_LINE; ! ***** Really need to parse both halves of the now split apart ACE. ELSE ! Check to see if the current ACE can be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT) = 'NO_MODIFY' THEN RETURN; ENDIF; COPY_TEXT (ACLEDIT$X_DELETE_WORD); ENDIF; MOVE_HORIZONTAL (-LENGTH (ACLEDIT$X_DELETE_WORD)); ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$FORWARD ! ! ROUTINE DESCRIPTION: This procedure sets the current direction to be forward. ! PROCEDURE ACLEDIT$FORWARD SET (FORWARD, CURRENT_BUFFER); ACLEDIT$SET_STATUS_LINE; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$BOTTOM ! ! ROUTINE DESCRIPTION: This procedure positions to the end of the ACL. ! PROCEDURE ACLEDIT$BOTTOM ! Before moving attempt to enter the current ACE. ACLEDIT$X_STATUS := ACLEDIT$ENTER_ACE (ACLEDIT$C_NOPOSITION); IF ACLEDIT$X_STATUS <> 'ACE_ERROR' THEN POSITION (END_OF (CURRENT_BUFFER)); ACLEDIT$SET_CURRENT_ACE; IF ACLEDIT$X_PROMPT THEN ACLEDIT$INSERT_ACE; ENDIF; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$BACKWARD ! ! ROUTINE DESCRIPTION: This procedure sets the current direction to be reverse. ! PROCEDURE ACLEDIT$BACKWARD SET (REVERSE, CURRENT_BUFFER); ACLEDIT$SET_STATUS_LINE; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$TOP ! ! ROUTINE DESCRIPTION: This procedure positions to the beginning of the ACL. ! PROCEDURE ACLEDIT$TOP ! Before moving attempt to enter the current ACE. ACLEDIT$X_STATUS := ACLEDIT$ENTER_ACE (ACLEDIT$C_NOPOSITION); IF ACLEDIT$X_STATUS <> 'ACE_ERROR' THEN POSITION (BEGINNING_OF (CURRENT_BUFFER)); ACLEDIT$SET_CURRENT_ACE; ENDIF; ! Check to see if a new ACE must be started up. IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN IF ACLEDIT$X_PROMPT THEN ACLEDIT$INSERT_ACE; ENDIF; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$DELETE_CHAR ! ! ROUTINE DESCRIPTION: This procedure deletes the character under the cursor. ! PROCEDURE ACLEDIT$DELETE_CHAR ! If at the end of the current buffer, this is a no-op. IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN RETURN; ENDIF; ! Check to see if this ACE may be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT) = 'NO_MODIFY' THEN RETURN; ENDIF; ! Stash away the text and wipe out the current character. IF CURRENT_OFFSET = LENGTH (CURRENT_LINE) THEN ! Check to see if this ACE may be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_NEXT)= 'NO_MODIFY' THEN RETURN; ENDIF; ! Zap the line terminator. IF MARK (NONE) <> END_OF (CURRENT_BUFFER) THEN MOVE_HORIZONTAL (1); APPEND_LINE; ENDIF; ACLEDIT$X_DELETE_CHAR := ACLEDIT$X_LINE_TERM_CHAR ELSE ACLEDIT$X_DELETE_CHAR := ERASE_CHARACTER (1); ENDIF; ACLEDIT$X_RUBOUT_CHAR := ACLEDIT$X_NULL; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$UNDELETE_CHAR ! ! ROUTINE DESCRIPTION: Restore the previously deleted character. ! PROCEDURE ACLEDIT$UNDELETE_CHAR ! If the deleted character was the previous character, restore it, and position ! the cursor after it. IF ACLEDIT$X_RUBOUT_CHAR <> ACLEDIT$X_NULL THEN IF ACLEDIT$X_RUBOUT_CHAR = ACLEDIT$X_LINE_TERM_CHAR THEN IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN RETURN; ENDIF; IF (CURRENT_OFFSET = 0) OR (CURRENT_OFFSET = LENGTH (CURRENT_LINE)) THEN RETURN ENDIF; ! Check to see if the current ACE can be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT) = 'NO_MODIFY' THEN RETURN; ENDIF; ! Otherwise, split the line at the current position. SPLIT_LINE; ! ***** Really need to parse both halves of the now split apart ACE. ELSE ! Check to see if the current ACE can be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT) = 'NO_MODIFY' THEN RETURN; ENDIF; COPY_TEXT (ACLEDIT$X_RUBOUT_CHAR); ENDIF; ENDIF; ! If the deleted character was the current character, restore it, and position ! the cursor over it. IF ACLEDIT$X_DELETE_CHAR <> ACLEDIT$X_NULL THEN IF ACLEDIT$X_DELETE_CHAR = ACLEDIT$X_LINE_TERM_CHAR THEN IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN RETURN; ENDIF; IF (CURRENT_OFFSET = 0) OR (CURRENT_OFFSET = LENGTH (CURRENT_LINE)) THEN RETURN ENDIF; ! Check to see if the current ACE can be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT) = 'NO_MODIFY' THEN RETURN; ENDIF; ! Otherwise, split the line at the current position. SPLIT_LINE; ! ***** Really need to parse both halves of the now split apart ACE. ELSE ! Check to see if the current ACE can be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT) = 'NO_MODIFY' THEN RETURN; ENDIF; COPY_TEXT (ACLEDIT$X_DELETE_CHAR); ENDIF; MOVE_HORIZONTAL (-1); ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$MOVE_WORD ! ! ROUTINE DESCRIPTION: This procedure moves forward or backward to the next ! word boundary. If a line boundary is crossed, the ! current ACE is implicitly entered. ! PROCEDURE ACLEDIT$MOVE_WORD LOCAL OFFSET; ! Move by a word. IF CURRENT_DIRECTION = FORWARD THEN OFFSET := ACLEDIT$WORD_END; ELSE OFFSET := ACLEDIT$WORD_BEGIN; ENDIF; ! If the offset to the next word is zero, it means a line boundary has been ! reached. In this case, the current ACE is implicitly entered. IF OFFSET = 0 THEN ACLEDIT$X_STATUS := ACLEDIT$ENTER_ACE (ACLEDIT$C_NOPOSITION); IF ACLEDIT$X_STATUS = 'ACE_ERROR' THEN RETURN; ENDIF; ! Figure out which way to move. IF CURRENT_DIRECTION = FORWARD THEN OFFSET := 1; ELSE OFFSET := -1; ENDIF; ! If the ACE parsed was null, eliminate it and adjust the number/direction of ! characters to move. IF (ACLEDIT$X_STATUS = 'ACE_NULL') AND (CURRENT_DIRECTION = FORWARD) THEN OFFSET := 0; ENDIF; ! Position across the line boundary. MOVE_HORIZONTAL (OFFSET); ACLEDIT$SET_CURRENT_ACE; ! If necessary, start up a new ACE. IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN IF ACLEDIT$X_PROMPT THEN ACLEDIT$INSERT_ACE; ENDIF; ENDIF; ELSE ! Position the the word boundary. MOVE_HORIZONTAL (OFFSET); ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$MOVE_LINE ! ! ROUTINE DESCRIPTION: This procedure moves forward or backward to the next ! line boundary. The current ACE is implicitly entered. ! PROCEDURE ACLEDIT$MOVE_LINE LOCAL SAVED_POSITION, BOL_MARKER, EOL_MARKER; ! Move to the end of the appropriate line (based upon the current direction). IF CURRENT_DIRECTION = FORWARD THEN IF CURRENT_OFFSET = LENGTH (CURRENT_LINE) THEN ! Attempt to enter the current line. If it succeeds, move the cursor. ACLEDIT$X_STATUS := ACLEDIT$ENTER_ACE (ACLEDIT$C_NOPOSITION); IF ACLEDIT$X_STATUS = 'ACE_ERROR' THEN RETURN; ENDIF; ! If it was a null ACE, don't move (since I'm now at the beginning of the ! next ACE) otherwise, move to the next ACE. IF ACLEDIT$X_STATUS <> 'ACE_NULL' THEN MOVE_HORIZONTAL (1); ENDIF; ACLEDIT$SET_CURRENT_ACE; ENDIF; IF MARK (NONE) <> END_OF (CURRENT_BUFFER) THEN MOVE_HORIZONTAL (LENGTH (CURRENT_LINE) - CURRENT_OFFSET); ENDIF; ELSE ! Attempt to enter the current line. If it succeeds, move the cursor. ACLEDIT$X_STATUS := ACLEDIT$ENTER_ACE (ACLEDIT$C_NOPOSITION); IF ACLEDIT$X_STATUS = 'ACE_ERROR' THEN RETURN; ENDIF; ! Position to the end of the previous line, or end of current line if at the ! beginning of the buffer. MOVE_HORIZONTAL (-CURRENT_OFFSET); IF MARK (NONE) = BEGINNING_OF (CURRENT_BUFFER) THEN MOVE_HORIZONTAL (LENGTH (CURRENT_LINE)); ELSE MOVE_HORIZONTAL (-1); ENDIF; ACLEDIT$SET_CURRENT_ACE; ENDIF; ! If the current position is at the end of the ACL, and prompt mode is ! enabled, start up a new ACE. IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN IF ACLEDIT$X_PROMPT THEN ACLEDIT$INSERT_ACE; ENDIF; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$DELETE_EOL ! ! ROUTINE DESCRIPTION: Delete to the end of the current line. If at the ! end of the line, delete line terminator. ! PROCEDURE ACLEDIT$DELETE_EOL ! Check to see if this ACE may be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT) = 'NO_MODIFY' THEN RETURN; ENDIF; ! Erase through the end of the line. IF CURRENT_OFFSET < LENGTH (CURRENT_LINE) THEN ACLEDIT$X_DELETE_EOL := ERASE_CHARACTER (LENGTH (CURRENT_LINE) - CURRENT_OFFSET); ELSE ! Check to see if the next ACE may be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_NEXT)= 'NO_MODIFY' THEN RETURN; ENDIF; ! Zap the next line. MOVE_HORIZONTAL (1); IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN MOVE_HORIZONTAL (-1); RETURN; ENDIF; ACLEDIT$X_DELETE_EOL := ACLEDIT$X_LINE_TERM_CHAR + ERASE_LINE; ACLEDIT$SET_CURRENT_ACE; ! If necessary, start up a new ACE. IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN IF ACLEDIT$X_PROMPT THEN ACLEDIT$INSERT_ACE; ENDIF; ENDIF; ENDIF; ACLEDIT$X_RUBOUT_BOL := ACLEDIT$X_NULL ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$MOVE_ACE (ARG1) ! ! INPUT PARAMETERS: ARG1: ACLEDIT$C_NOENTER - Don't enter current ACE ! before moving cursor ! ACLEDIT$C_ENTER - Enter current ACE before moving ! cursor ! ! ROUTINE DESCRIPTION: This procedure moves the cursor to the beginning of the ! next/previous ACE (depending on the current direction). ! If necessary, the current ACE is entered. ! PROCEDURE ACLEDIT$MOVE_ACE (ENTER_FLAG) LOCAL OFFSET; ! Set the move offset based upon the direction of travel. IF CURRENT_DIRECTION = FORWARD THEN OFFSET := 1; ELSE OFFSET := -1; ENDIF; ! If necessary, enter the current ACE. IF ENTER_FLAG = ACLEDIT$C_ENTER THEN ACLEDIT$X_STATUS := ACLEDIT$ENTER_ACE (ACLEDIT$C_NOPOSITION); IF ACLEDIT$X_STATUS = 'ACE_ERROR' THEN RETURN; ELSE IF (ACLEDIT$X_STATUS = 'ACE_NULL') AND (CURRENT_DIRECTION = FORWARD) THEN OFFSET := 0; ENDIF; ENDIF; ENDIF; ! Move to the beginning of the next/previous ACE as needed. IF MARK (NONE) <> END_OF (CURRENT_BUFFER) THEN MOVE_HORIZONTAL (-CURRENT_OFFSET); MOVE_VERTICAL (OFFSET); ELSE IF CURRENT_DIRECTION = REVERSE THEN MOVE_VERTICAL (-1); MOVE_HORIZONTAL (-CURRENT_OFFSET); ENDIF; ENDIF; ACLEDIT$SET_CURRENT_ACE; ! If needed, start up a new ACE. IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN IF ACLEDIT$X_PROMPT THEN ACLEDIT$INSERT_ACE; ENDIF; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$INSERT_ACE ! ! ROUTINE DESCRIPTION: Insert an new ACE before the current ACE. ! PROCEDURE ACLEDIT$INSERT_ACE ! Enter the current ACE. ACLEDIT$ENTER_ACE (ACLEDIT$C_NOPOSITION); ! Set up the initial part of the new ACE. IF MARK (NONE) <> END_OF (CURRENT_BUFFER) THEN MOVE_HORIZONTAL (-CURRENT_OFFSET); SPLIT_LINE; MOVE_HORIZONTAL (-1); ENDIF; ! If not prompting, skip out now. ACLEDIT$SET_CURRENT_ACE; IF NOT ACLEDIT$X_PROMPT THEN RETURN; ENDIF; ! Set up the first field. COPY_TEXT ("("); ACLEDIT$X_FIELD := 0; ACLEDIT$X_ITEM := 0; ACLEDIT$X_BEGIN_ITEM := MARK (NONE); ACLEDIT$X_END_ITEM := MARK (NONE); ACLEDIT$SELECT_ITEM; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$SELECT_ITEM ! ! ROUTINE DESCRIPTION: Select the next item for the specified field or ! subfield. ! ! The field numbers used for the various ACE types are as follows: ! ! Type: ACE$C_KEYID ! ! (type=keyword, OPT = DEF + HID + PROT + NOPROP + NONE, ACC = R + W + E + D + C + NONE) ! ^----0-----^ 1 2 3 4 5 6 7 8 9 1 1 1 1 ! 0 1 2 3 ! ! Type: ACE$C_ALARM and ACE$C_AUDIT ! ! (type=keyword, OPT = DEF + HID + PROT + NOPROP + NONE, ACC = R + W + E + D + C + S + F + NONE) ! ^----0-----^ 1 2 3 4 5 6 7 8 9 1 1 1 1 1 1 ! 0 1 2 3 4 5 ! ! Type: ACE$C_DIRDEF ! ! (DEFAULT_PROT, OPT = DEF + HID + PROT + NOPROP + NONE, SYS:xxx, OWN:xxx, GRP:xxx, WOR:xxx) ! ^----0-----^ 1 2 3 4 5 6 7 8 9 1 ! 0 ! PROCEDURE ACLEDIT$SELECT_ITEM LOCAL SAVED_POSITION, SET_NEW_END, TEMP_RANGE; ! If the current position is not the end of the ACE, then this key is a no-op. IF CURRENT_OFFSET <> LENGTH (CURRENT_LINE) THEN RETURN; ENDIF; IF ACLEDIT$X_END_ITEM <> ACLEDIT$X_BEGIN_ITEM THEN SAVED_POSITION := MARK (NONE); POSITION (ACLEDIT$X_END_ITEM); MOVE_HORIZONTAL (1); IF MARK (NONE) <> SAVED_POSITION THEN POSITION (SAVED_POSITION); RETURN; ENDIF; ENDIF; ! If the previous major field keyword has been removed, add it in again. IF (ACLEDIT$X_BEGIN_ITEM = ACLEDIT$X_END_ITEM) AND (SUBSTR (CURRENT_LINE, CURRENT_OFFSET, 1) = ',') THEN IF ACLEDIT$X_FIELD = ACLEDIT$X_MIN_OPT_FIELD THEN COPY_TEXT ("OPTIONS="); ENDIF; IF (ACLEDIT$X_FIELD = ACLEDIT$X_MIN_FIELD_3) AND (ACLEDIT$X_ACE_TYPE <> ACE$C_DIRDEF) THEN COPY_TEXT ("ACCESS="); ENDIF; ENDIF; ! Remove any previous item. POSITION (ACLEDIT$X_BEGIN_ITEM); IF ACLEDIT$X_BEGIN_ITEM <> ACLEDIT$X_END_ITEM THEN TEMP_RANGE := CREATE_RANGE (ACLEDIT$X_BEGIN_ITEM, ACLEDIT$X_END_ITEM, NONE); ERASE (TEMP_RANGE); ENDIF; ACLEDIT$X_ITEM := ACLEDIT$X_ITEM + 1; ! If this is a brand new ACE, set up the ACE type text and other characteristics ! particular to the ACE type. IF ACLEDIT$X_FIELD = 0 THEN ! Option field limits are the same for all ACEs. ACLEDIT$X_MIN_OPT_FIELD := 1; ACLEDIT$X_MAX_OPT_FIELD := 4; IF NOT ACLEDIT$X_CHECK_MODIFY THEN ACLEDIT$X_MAX_OPT_FIELD := ACLEDIT$X_MAX_OPT_FIELD + 1; ENDIF; IF ACLEDIT$X_USE_DEFAULT_OPT THEN ACLEDIT$X_MAX_OPT_FIELD := ACLEDIT$X_MAX_OPT_FIELD + 1; ENDIF; ! Starting field number is the same for all ACEs. ACLEDIT$X_MIN_FIELD_3 := ACLEDIT$X_MAX_OPT_FIELD + 1; ! Now for the ACE type text itself. IF (NOT ACLEDIT$X_DIRECTORY_FILE) AND (ACLEDIT$X_ITEM = 3) THEN ACLEDIT$X_ITEM := ACLEDIT$X_ITEM + 1; ENDIF; IF ACLEDIT$X_ITEM > 3 THEN ACLEDIT$X_ITEM := 1; ENDIF; CASE ACLEDIT$X_ITEM FROM 1 TO 3 [1]: COPY_TEXT ("IDENTIFIER="); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("IDENTIFIER=") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); ACLEDIT$X_ACE_TYPE := ACE$C_KEYID; ACLEDIT$X_MAX_FIELD_3 := ACLEDIT$X_MIN_FIELD_3 + 6; [2]: COPY_TEXT ("ALARM=SECURITY"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("ALARM=SECURITY") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); ACLEDIT$X_ACE_TYPE := ACE$C_ALARM; ACLEDIT$X_MAX_FIELD_3 := ACLEDIT$X_MIN_FIELD_3 + 8; [3]: COPY_TEXT ("DEFAULT_PROTECTION"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("DEFAULT_PROTECTION") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); ACLEDIT$X_ACE_TYPE := ACE$C_DIRDEF; ACLEDIT$X_MAX_FIELD_3 := ACLEDIT$X_MIN_FIELD_3 + 3; ENDCASE; ENDIF; ! Set up the new option field text for the ACE. IF (ACLEDIT$X_FIELD >= ACLEDIT$X_MIN_OPT_FIELD) AND (ACLEDIT$X_FIELD <= ACLEDIT$X_MAX_OPT_FIELD) THEN ! The order of the following tests are critical. IF (ACLEDIT$X_ITEM > 5) OR ((ACLEDIT$X_ITEM = 5) AND (ACLEDIT$X_FIELD > ACLEDIT$X_MIN_OPT_FIELD + 1)) THEN ACLEDIT$X_ITEM := 1; ENDIF; IF (ACLEDIT$X_ITEM = 1) AND (NOT ACLEDIT$X_USE_DEFAULT_OPT) THEN ACLEDIT$X_ITEM := ACLEDIT$X_ITEM + 1; ENDIF; IF (ACLEDIT$X_ITEM = 2) AND (ACLEDIT$X_CHECK_MODIFY) THEN ACLEDIT$X_ITEM := ACLEDIT$X_ITEM + 1; ENDIF; CASE ACLEDIT$X_ITEM FROM 1 TO 5 [1]: COPY_TEXT ("DEFAULT+"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("DEFAULT+") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); [2]: COPY_TEXT ("HIDDEN+"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("HIDDEN+") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); [3]: COPY_TEXT ("PROTECTED+"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("PROTECTED+") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); [4]: COPY_TEXT ("NOPROPAGATE+"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("NOPROPAGATE+") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); [5]: COPY_TEXT ("NONE+"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("NONE+") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); ENDCASE; ENDIF; ! Set up the new ACCESS/protection field text. IF (ACLEDIT$X_FIELD >= ACLEDIT$X_MIN_FIELD_3) AND (ACLEDIT$X_FIELD <= ACLEDIT$X_MAX_FIELD_3) THEN IF ACLEDIT$X_ACE_TYPE <> ACE$C_DIRDEF THEN ! The order of the following tests are critical. IF (ACLEDIT$X_ACE_TYPE = ACE$C_KEYID) AND ((ACLEDIT$X_ITEM = 6) OR (ACLEDIT$X_ITEM = 7)) THEN ACLEDIT$X_ITEM := 8; ENDIF; IF (ACLEDIT$X_ITEM > 8) OR ((ACLEDIT$X_ITEM = 8) AND (ACLEDIT$X_FIELD > ACLEDIT$X_MIN_FIELD_3 + 1)) THEN ACLEDIT$X_ITEM := 1; ENDIF; CASE ACLEDIT$X_ITEM FROM 1 TO 8 [1]: COPY_TEXT ("READ+"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("READ+") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); [2]: COPY_TEXT ("WRITE+"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("WRITE+") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); [3]: COPY_TEXT ("EXECUTE+"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("EXECUTE+") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); [4]: COPY_TEXT ("DELETE+"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("DELETE+") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); [5]: COPY_TEXT ("CONTROL+"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("CONTROL+") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); [6]: COPY_TEXT ("SUCCESS+"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("SUCCESS+") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); [7]: COPY_TEXT ("FAILURE+"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("FAILURE+") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); [8]: COPY_TEXT ("NONE+"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("NONE+") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); ENDCASE; ELSE IF ACLEDIT$X_ITEM > 4 THEN ACLEDIT$X_ITEM := 1; ENDIF; CASE ACLEDIT$X_ITEM FROM 1 TO 8 [1]: COPY_TEXT ("SYSTEM:"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("SYSTEM:") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); [2]: COPY_TEXT ("OWNER:"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("OWNER:") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); [3]: COPY_TEXT ("GROUP:"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("GROUP:") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); [4]: COPY_TEXT ("WORLD:"); MOVE_HORIZONTAL (-1); ACLEDIT$X_END_ITEM := MARK (NONE); MOVE_HORIZONTAL (-(LENGTH ("WORLD:") - 1)); ACLEDIT$X_BEGIN_ITEM := MARK (NONE); ENDCASE; ENDIF; ENDIF; POSITION (ACLEDIT$X_END_ITEM); MOVE_HORIZONTAL (1); ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$ENTER_ACE (ARG1) ! ! INPUT PARAMETERS: ARG1: ACLEDIT$C_NOPOSITION - Leave cursor position to ! end of ACE ! ACLEDIT$C_REPOSITION - Position to beginning of ! next/previous ACE ! ! ROUTINE DESCRIPTION: This procedure attempts to enter the ACE represented ! by the builtin CURRENT_LINE. It does this by first ! properly terminating the ACE is not already done, ! parsing the resulting ACE. If the parse results in ! an error, the cursor is position to the point of ! failure and the string "ACE_ERROR" is returned. ! Otherwise, the cursor is positioned to the beginning ! of the ACE and the string "ACE_CORRECT" is returned. ! PROCEDURE ACLEDIT$ENTER_ACE (POSITION_FLAG) LOCAL TEMP_LINE, SAVED_POSITION; ! If the current line is null, return a correct status message. IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN ! Position to the next ACE, if necessary. IF POSITION_FLAG = ACLEDIT$C_REPOSITION THEN ACLEDIT$MOVE_ACE (ACLEDIT$C_NOENTER); ENDIF; RETURN 'ACE_NULL'; ENDIF; IF LENGTH (CURRENT_LINE) = 0 THEN ERASE_LINE; ! Position to the next ACE, if necessary. IF (POSITION_FLAG = ACLEDIT$C_REPOSITION) AND (CURRENT_DIRECTION = REVERSE) THEN ACLEDIT$MOVE_ACE (ACLEDIT$C_NOENTER); ENDIF; RETURN 'ACE_NULL'; ENDIF; ! Compress the current line. TEMP_LINE := CURRENT_LINE; EDIT (TEMP_LINE, COLLAPSE, UPPER); ! If using prompt mode and the ACE consists of only the initial ACE type text, ! wipe it out and position to the next ACE if so specified. IF (((INDEX ('(IDENTIFIER=', TEMP_LINE) <> 0) OR (INDEX ('(ALARM=SECURITY', TEMP_LINE) <> 0) OR (INDEX ('(DEFAULT_PROTECTION', TEMP_LINE) <> 0)) AND (ACLEDIT$X_PROMPT)) OR (LENGTH (CURRENT_LINE) = 0) THEN MOVE_HORIZONTAL (-CURRENT_OFFSET); ERASE_LINE; ! Position to the next ACE, if necessary. IF (POSITION_FLAG = ACLEDIT$C_REPOSITION) THEN IF (CURRENT_DIRECTION = REVERSE) OR ((CURRENT_DIRECTION = FORWARD) AND (MARK (NONE) = END_OF (CURRENT_BUFFER))) THEN ACLEDIT$MOVE_ACE (ACLEDIT$C_NOENTER); ELSE ACLEDIT$SET_CURRENT_ACE; ENDIF; ENDIF; RETURN 'ACE_NULL'; ENDIF; ! If the line has changed, see if the ACE is terminated properly. IF TEMP_LINE <> ACLEDIT$X_COMPRESSED_ACE THEN ! If the ACE is protected, complain to the user, and replace the user's ! modified ACE with the original one. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_REPLACE, ACLEDIT$C_CHECK_CURRENT) = 'NO_MODIFY' THEN RETURN 'ACE_CORRECT'; ENDIF; ! Insert a special character in the current line so that the position may be ! maintained in the compressed line (if necessary). COPY_TEXT (ACLEDIT$X_ACE_MARKER); TEMP_LINE := CURRENT_LINE; EDIT (TEMP_LINE, COLLAPSE); ! Since the line is different, replace it. ERASE_LINE; SPLIT_LINE; MOVE_HORIZONTAL (-1); COPY_TEXT (TEMP_LINE); ! See if the ACE is properly terminated. MOVE_HORIZONTAL (LENGTH (CURRENT_LINE) - CURRENT_OFFSET - 1); IF CURRENT_CHARACTER = ACLEDIT$X_ACE_MARKER THEN MOVE_HORIZONTAL (-1); ENDIF; IF CURRENT_CHARACTER <> ")" THEN IF CURRENT_CHARACTER = "+" THEN ERASE_CHARACTER (1); ELSE MOVE_HORIZONTAL (1); ENDIF; COPY_TEXT (")"); UPDATE (CURRENT_WINDOW); ENDIF; ! Now locate the special character to determine where to place the cursor. ! (Also to remove the special character so the parse won't barf.) MOVE_HORIZONTAL (-CURRENT_OFFSET); SAVED_POSITION := BEGINNING_OF (SEARCH (ACLEDIT$X_ACE_MARKER, FORWARD, EXACT)); POSITION (SAVED_POSITION); ERASE_CHARACTER (1); SAVED_POSITION := MARK (NONE); ! Attempt to parse the current ACE. MOVE_HORIZONTAL (-CURRENT_OFFSET); ! Set a reference point ACLEDIT$X_BINARY_ACE := CALL_USER (ACLEDIT$C_PARSE_ACE, CURRENT_LINE); ! If an error occurs parsing the current ACE, note the error. IF SUBSTR (ACLEDIT$X_BINARY_ACE, 1, 1) = ASCII (0) THEN ACLEDIT$X_DUMMY := CALL_USER (ACLEDIT$C_MESSAGE, STR (ACLEDIT$_SYNTAX)); MESSAGE (' '+SUBSTR (ACLEDIT$X_BINARY_ACE, 3, LENGTH (ACLEDIT$X_BINARY_ACE) - 2)); MOVE_HORIZONTAL (LENGTH (CURRENT_LINE) - (LENGTH (ACLEDIT$X_BINARY_ACE) - 2)); RETURN 'ACE_ERROR'; ENDIF; ! Otherwise, check for a duplicate ACE. IF ACLEDIT$CHECK_DUPLICATE_ACE = "DUPLICATE_ACE" THEN RETURN 'ACE_ERROR'; ENDIF; ELSE SAVED_POSITION := MARK (NONE); ENDIF; ! Position to the next ACE, if necessary. IF POSITION_FLAG = ACLEDIT$C_REPOSITION THEN ACLEDIT$MOVE_ACE (ACLEDIT$C_NOENTER); ELSE POSITION (SAVED_POSITION); ENDIF; RETURN 'ACE_CORRECT'; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$EXIT ! ! ROUTINE DESCRIPTION: This procedure enters the current ACE, and then ! exits the ACL editor. ! PROCEDURE ACLEDIT$EXIT ! Attempt to enter the current ACE. ACLEDIT$X_STATUS := ACLEDIT$ENTER_ACE (ACLEDIT$C_NOPOSITION); IF ACLEDIT$X_STATUS <> 'ACE_ERROR' THEN EXIT; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$QUIT ! ! ROUTINE DESCRIPTION: This procedure exits the ACL editor ignoring any ! changes made to the object's ACL. ! PROCEDURE ACLEDIT$QUIT QUIT; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$MOVE_BOL ! ! ROUTINE DESCRIPTION: Move to the beginning of the current line. If at ! the beginning of a line, move to the beginning of ! the previous line. ! PROCEDURE ACLEDIT$MOVE_BOL LOCAL OFFSET; IF CURRENT_OFFSET = 0 THEN ! If at the beginning of the line, and the position is at the beginning of an ! ACE, attempt to enter the current ACE. Otherwise, simple move to the start ! of the previous line. ACLEDIT$X_STATUS := ACLEDIT$ENTER_ACE (ACLEDIT$C_NOPOSITION); IF ACLEDIT$X_STATUS = 'ACE_ERROR' THEN RETURN; ENDIF; MOVE_HORIZONTAL (-(CURRENT_OFFSET + 1)); ACLEDIT$SET_CURRENT_ACE; ENDIF; ! Move to the beginning of the line. MOVE_HORIZONTAL (-CURRENT_OFFSET); ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$RUBOUT_WORD ! ! ROUTINE DESCRIPTION: Delete the word immediately preceeding the cursor. ! PROCEDURE ACLEDIT$RUBOUT_WORD LOCAL OFFSET; ! Check to see if this ACE may be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT)= 'NO_MODIFY' THEN RETURN; ENDIF; ! Wipe out the previous word, and stash away the deleted text. OFFSET := ACLEDIT$WORD_BEGIN; IF OFFSET = 0 THEN IF MARK (NONE) <> BEGINNING_OF (CURRENT_BUFFER) THEN ! Check to see if the previous ACE may be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_PREVIOUS) = 'NO_MODIFY' THEN RETURN; ENDIF; APPEND_LINE; ELSE MOVE_HORIZONTAL (-1); ENDIF; ACLEDIT$X_RUBOUT_WORD := ACLEDIT$X_LINE_TERM_CHAR ELSE ACLEDIT$X_RUBOUT_WORD := ERASE_CHARACTER (OFFSET); ENDIF; ACLEDIT$X_DELETE_WORD := ACLEDIT$X_NULL; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$INSERT_KEY ! ! ROUTINE DESCRIPTION: This procedure handles the key on the ! LK201, and either starts up a new ACE or inserts text ! from the paste buffer. ! PROCEDURE ACLEDIT$INSERT_KEY ! If not supporting the paste buffer, start up a new ACE. IF NOT ACLEDIT$X_PASTE_BUFFER THEN ACLEDIT$INSERT_ACE; RETURN; ENDIF; ! If the paste buffer is not empty, insert the text. IF BEGINNING_OF (ACL_PASTE_BUFFER) <> END_OF (ACL_PASTE_BUFFER) THEN COPY_TEXT (ACL_PASTE_BUFFER); APPEND_LINE; ELSE MESSAGE ("Paste buffer is empty"); ENDIF; ENDPROCEDURE ! ! ROUTINE: ACLEDIT$SELECT_TEXT ! ! ROUTINE DESCRIPTION: This procedure sets up the start of a new select ! range or deletes the select range (not the text) if ! a select range is already active. ! PROCEDURE ACLEDIT$SELECT_TEXT ! If the paste buffer is not supported, return now. IF NOT ACLEDIT$X_PASTE_BUFFER THEN RETURN; ENDIF; ! Otherwise, find out what to do. IF ACLEDIT$X_SELECT_START <> ACLEDIT$X_NULL THEN DELETE (ACLEDIT$X_SELECT_START); ACLEDIT$X_SELECT_START := ACLEDIT$X_NULL; ELSE ACLEDIT$X_SELECT_START := SELECT (REVERSE); ENDIF; ENDPROCEDURE ! ! ROUTINE: ACLEDIT$REMOVE_TEXT (ARG1) ! ! INPUT PARAMETERS: ARG1: ACLEDIT$C_REMOVE_TEXT - Copy text to paste buffer and ! remove original text ! ACLEDIT$C_KEEP_TEXT - Copy text to paste buffer and ! preserve original text ! ! ROUTINE DESCRIPTION: This procedure takes the pre-selected text, and removes ! it to the paste buffer. ! PROCEDURE ACLEDIT$REMOVE_TEXT (REMOVE_OPTION) LOCAL REMOVE_RANGE, SAVED_POSITION; ! If the paste buffer is not supported, return now. IF NOT ACLEDIT$X_PASTE_BUFFER THEN RETURN; ENDIF; ! Otherwise, clear out any existing text in the paste buffer. ERASE (ACL_PASTE_BUFFER); ! Get the selected range. REMOVE_RANGE := SELECT_RANGE; DELETE (ACLEDIT$X_SELECT_START); ACLEDIT$X_SELECT_START := ACLEDIT$X_NULL; ! If there isn't anything in the range, return now. Otherwise, move the ! selected text to the paste buffer. IF LENGTH (REMOVE_RANGE) = 0 THEN RETURN ENDIF; SAVED_POSITION := MARK (NONE); POSITION (ACL_PASTE_BUFFER); SPLIT_LINE; MOVE_VERTICAL (-1); IF REMOVE_OPTION = ACLEDIT$C_REMOVE_TEXT THEN MOVE_TEXT (REMOVE_RANGE); ELSE COPY_TEXT (REMOVE_RANGE); ENDIF; POSITION (SAVED_POSITION); ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$PREVIOUS_SCREEN ! ! ROUTINE DESCRIPTION: This procedure positions to the previous screen. The ! current ACE is implicitly entered. ! PROCEDURE ACLEDIT$PREVIOUS_SCREEN ! Enter the current ACE before changing the current position. ACLEDIT$X_STATUS := ACLEDIT$ENTER_ACE (ACLEDIT$C_NOPOSITION); IF ACLEDIT$X_STATUS = 'ACE_ERROR' THEN RETURN; ENDIF; MOVE_VERTICAL (-((ACLEDIT$X_SCREEN_LENGTH * 2) / 3)); ACLEDIT$SET_CURRENT_ACE; ! If now at the end of the ACL, and prompt mode is enabled, start up a new ACE. IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN IF ACLEDIT$X_PROMPT THEN ACLEDIT$INSERT_ACE; ENDIF; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$NEXT_SCREEN ! ! ROUTINE DESCRIPTION: This procedure positions to the next screen. The ! current ACE is implicitly entered. ! PROCEDURE ACLEDIT$NEXT_SCREEN ! Enter the current ACE before changing the current position. ACLEDIT$X_STATUS := ACLEDIT$ENTER_ACE (ACLEDIT$C_NOPOSITION); IF ACLEDIT$X_STATUS = 'ACE_ERROR' THEN RETURN; ENDIF; MOVE_VERTICAL ((ACLEDIT$X_SCREEN_LENGTH * 2) / 3); ACLEDIT$SET_CURRENT_ACE; ! If now at the end of the ACL, and prompt mode is enabled, start up a new ACE. IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN IF ACLEDIT$X_PROMPT THEN ACLEDIT$INSERT_ACE; ENDIF; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$UP ! ! ROUTINE DESCRIPTION: This procedure positions the cursor to the previous ! line. The current ACE is implicitly entered. ! PROCEDURE ACLEDIT$UP LOCAL OFFSET; OFFSET := CURRENT_OFFSET; ! Enter the current ACE before changing the current position. ACLEDIT$X_STATUS := ACLEDIT$ENTER_ACE (ACLEDIT$C_NOPOSITION); IF ACLEDIT$X_STATUS = 'ACE_ERROR' THEN RETURN; ENDIF; ! Now move the cursor up one line. MOVE_VERTICAL (-1); ACLEDIT$SET_CURRENT_ACE; IF ACLEDIT$X_STATUS = 'ACE_NULL' THEN IF MARK (NONE) <> END_OF (CURRENT_BUFFER) THEN IF OFFSET > LENGTH (CURRENT_LINE) THEN MOVE_HORIZONTAL (LENGTH (CURRENT_LINE)); ELSE MOVE_HORIZONTAL (OFFSET); ENDIF; ENDIF; ENDIF; ! If now at the end of the ACL, and prompt mode is enabled, start up a new ACE. IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN IF ACLEDIT$X_PROMPT THEN ACLEDIT$INSERT_ACE; ENDIF; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$DOWN ! ! ROUTINE DESCRIPTION: This procedure positions the cursor to the next line. ! The current ACE is implicitly entered. ! PROCEDURE ACLEDIT$DOWN LOCAL OFFSET; OFFSET := CURRENT_OFFSET; ! Enter the current ACE before changing the current position. ACLEDIT$X_STATUS := ACLEDIT$ENTER_ACE (ACLEDIT$C_NOPOSITION); IF ACLEDIT$X_STATUS = 'ACE_ERROR' THEN RETURN; ENDIF; ! Now move the cursor down one line. IF (ACLEDIT$X_STATUS = 'ACE_NULL') AND (MARK (NONE) <> END_OF (CURRENT_BUFFER)) THEN IF OFFSET > LENGTH (CURRENT_LINE) THEN MOVE_HORIZONTAL (LENGTH (CURRENT_LINE)); ELSE MOVE_HORIZONTAL (OFFSET); ENDIF; ELSE MOVE_VERTICAL (1); ENDIF; ACLEDIT$SET_CURRENT_ACE; ! If needed, start up a new ACE. IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN IF ACLEDIT$X_PROMPT THEN ACLEDIT$INSERT_ACE; ENDIF; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$RIGHT ! ! ROUTINE DESCRIPTION: This procedure positions the cursor to the next ! character on the right (or the beginning of the ! next line if at the end of the current line). ! If a line boundary is crossed, the current ACE ! is entered. ! PROCEDURE ACLEDIT$RIGHT LOCAL OFFSET; OFFSET := 1; ! If at the end of the line, attempt to enter the current ACE. IF MARK (NONE) <> END_OF (CURRENT_BUFFER) THEN IF CURRENT_OFFSET = LENGTH (CURRENT_LINE) THEN ACLEDIT$X_STATUS := ACLEDIT$ENTER_ACE (ACLEDIT$C_NOPOSITION); IF ACLEDIT$X_STATUS = 'ACE_ERROR' THEN RETURN; ELSE IF ACLEDIT$X_STATUS = 'ACE_NULL' THEN OFFSET := 0; ENDIF; ENDIF; ! Move the currsor, if necessary, and set new original and compressed ACEs. MOVE_HORIZONTAL (OFFSET); ACLEDIT$SET_CURRENT_ACE; ELSE MOVE_HORIZONTAL (OFFSET); ENDIF; ELSE ! Move the cursor to the right. MOVE_HORIZONTAL (OFFSET); ENDIF; ! If necessary, start up a new ACE. IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN IF ACLEDIT$X_PROMPT THEN ACLEDIT$INSERT_ACE; ENDIF; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$SHIFT_RIGHT ! ! ROUTINE DESCRIPTION: This procedure shifts the screen to the right. ! PROCEDURE ACLEDIT$SHIFT_RIGHT SHIFT (CURRENT_WINDOW, -ACLEDIT$C_WINDOW_SHIFT); ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$LEFT ! ! ROUTINE DESCRIPTION: This procedure positions the cursor to the next ! character on the left (or the end of the previous ! line if at the beginning of the line). If a line ! boundary is crossed, the current ACE is implicitly ! entered. ! PROCEDURE ACLEDIT$LEFT ! If at the beginning of the line, attempt to enter the current ACE before ! moving the cursor. Otherwise, simply move the cursor. IF CURRENT_OFFSET = 0 THEN ACLEDIT$X_STATUS := ACLEDIT$ENTER_ACE (ACLEDIT$C_NOPOSITION); IF ACLEDIT$X_STATUS = 'ACE_ERROR' THEN RETURN; ENDIF; ENDIF; MOVE_HORIZONTAL (-1); ACLEDIT$SET_CURRENT_ACE; ! If necessary, start up a new ACE. IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN IF ACLEDIT$X_PROMPT THEN ACLEDIT$INSERT_ACE; ENDIF; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$SHIFT_LEFT ! ! ROUTINE DESCRIPTION: This procedure shifts the screen to the left. ! PROCEDURE ACLEDIT$SHIFT_LEFT SHIFT (CURRENT_WINDOW, ACLEDIT$C_WINDOW_SHIFT); ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$INSERT_OVERSTRIKE ! ! ROUTINE DESCRIPTION: Flip between insert and overstrike mode. ! PROCEDURE ACLEDIT$INSERT_OVERSTRIKE IF GET_INFO (CURRENT_BUFFER, "MODE") = INSERT THEN SET (OVERSTRIKE, ACLEDIT$X_MAIN_BUFFER); ACLEDIT$SET_STATUS_LINE; ELSE SET (INSERT, ACLEDIT$X_MAIN_BUFFER); ACLEDIT$SET_STATUS_LINE; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$TPU_COMMAND ! ! ROUTINE DESCRIPTION: Compile and execute a TPU command. ! PROCEDURE ACLEDIT$TPU_COMMAND LOCAL TPU_COMMAND, TPU_COMMAND_CODE; TPU_COMMAND := READ_LINE ("TPU Command: "); IF TPU_COMMAND <> ACLEDIT$X_NULL THEN TPU_COMMAND_CODE := COMPILE (TPU_COMMAND); EXECUTE (TPU_COMMAND_CODE); UPDATE (ACLEDIT$X_MAIN_WINDOW); UPDATE (ACLEDIT$X_MESSAGE_WINDOW); ACLEDIT$SET_STATUS_LINE; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$EMULATE_TAB ! ! ROUTINE DESCRIPTION: This routine inserts multiple spaces in place of tabs. ! PROCEDURE ACLEDIT$EMULATE_TAB LOCAL SPACE_COUNT; SPACE_COUNT := 8 - (CURRENT_OFFSET - ((CURRENT_OFFSET / 8) * 8)); IF SPACE_COUNT = 0 THEN SPACE_COUNT := 8; ENDIF; COPY_TEXT (SUBSTR (" ",1,SPACE_COUNT)); ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$REFRESH ! ! ROUTINE DESCRIPTION: Refresh the screen. ! PROCEDURE ACLEDIT$REFRESH REFRESH; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$RESET ! ! ROUTINE DESCRIPTION: Restore the in memory copy of the ACL to its initial ! state. ! PROCEDURE ACLEDIT$RESET ! Erase and re-fill the main buffer. ERASE (ACLEDIT$X_MAIN_BUFFER); COPY_TEXT (ORIGINAL_ACL_BUFFER); POSITION (BEGINNING_OF (ACLEDIT$X_MAIN_BUFFER)); ! If prompt mode is set, and the current ACE (line) is null, start off with ! the prompt text. IF ACLEDIT$X_PROMPT THEN ! If the current ACE is null, insert a new one. IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN ACLEDIT$INSERT_ACE; ELSE IF (LENGTH (CURRENT_LINE) = 0) THEN ACLEDIT$INSERT_ACE; ENDIF; ENDIF; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$RUBOUT_BOL ! ! ROUTINE DESCRIPTION: Delete to the beginning of the line. If currently ! at the beginning of a line, delete the previous line. ! PROCEDURE ACLEDIT$RUBOUT_BOL ! If at the beginning of the line, wipe out the previous line. Otherwise, just ! erase to the beginning of the line. IF CURRENT_OFFSET = 0 THEN IF MARK (NONE) <> BEGINNING_OF (CURRENT_BUFFER) THEN ! Since the current and previous ACEs are to be joined, check to see if the ! current and previous ACEs may be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT)= 'NO_MODIFY' THEN RETURN; ENDIF; IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_PREVIOUS) = 'NO_MODIFY' THEN RETURN; ENDIF; ! It can, so back up to the end of the line and delete the line. MOVE_HORIZONTAL (-1); COPY_TEXT (ACLEDIT$X_LINE_TERM_CHAR); MOVE_HORIZONTAL (-CURRENT_OFFSET); ACLEDIT$X_RUBOUT_BOL := ERASE_CHARACTER (LENGTH (CURRENT_LINE)); ERASE_LINE; ENDIF; ELSE ! Check to see if this ACE may be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT)= 'NO_MODIFY' THEN RETURN; ENDIF; ACLEDIT$X_RUBOUT_BOL := ERASE_CHARACTER (-CURRENT_OFFSET); ! If the entire line was erased, and prompting is enabled, start up a new ! ACE. IF (LENGTH (CURRENT_LINE) = 0) AND (ACLEDIT$X_PROMPT) THEN ERASE_LINE; SPLIT_LINE; MOVE_HORIZONTAL (-1); COPY_TEXT ("("); ACLEDIT$X_FIELD := 0; IF (ACLEDIT$X_ACE_TYPE = 0) OR (ACLEDIT$X_ACE_TYPE = ACE$C_KEYID) THEN ACLEDIT$X_ITEM := 0; ENDIF; IF ACLEDIT$X_ACE_TYPE = ACE$C_ALARM THEN ACLEDIT$X_ITEM := 1; ENDIF; IF ACLEDIT$X_ACE_TYPE = ACE$C_DIRDEF THEN ACLEDIT$X_ITEM := 2; ENDIF; ACLEDIT$X_BEGIN_ITEM := MARK (NONE); ACLEDIT$X_END_ITEM := MARK (NONE); ACLEDIT$SELECT_ITEM; ENDIF; ENDIF; ACLEDIT$X_DELETE_EOL := ACLEDIT$X_NULL ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$UNDELETE_LINE ! ! ROUTINE DESCRIPTION: Restore the previously deleted line. ! PROCEDURE ACLEDIT$UNDELETE_LINE ! If the deleted line was to the beginning of the line, restore it, and position ! the cursor after it. IF ACLEDIT$X_RUBOUT_BOL <> ACLEDIT$X_NULL THEN IF SUBSTR (ACLEDIT$X_RUBOUT_BOL, LENGTH (ACLEDIT$X_RUBOUT_BOL), 1) = ACLEDIT$X_LINE_TERM_CHAR THEN IF MARK (NONE) <> END_OF (CURRENT_BUFFER) THEN IF CURRENT_OFFSET > 0 THEN IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT) = 'NO_MODIFY' THEN RETURN; ENDIF; ENDIF; ENDIF; ACLEDIT$X_STATUS := ACLEDIT$ENTER_ACE (ACLEDIT$C_NOPOSITION); IF ACLEDIT$X_STATUS = 'ACE_ERROR' THEN RETURN; ENDIF; COPY_TEXT (ACLEDIT$X_RUBOUT_BOL); ERASE_CHARACTER (-1); IF MARK (NONE) <> END_OF (CURRENT_BUFFER) THEN ! ***** In this case, the previous line has not been parsed. SPLIT_LINE; ELSE ACLEDIT$SET_CURRENT_ACE; ENDIF; ELSE ! Check to see if this ACE may be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT)= 'NO_MODIFY' THEN RETURN; ENDIF; IF (((INDEX ('(IDENTIFIER=', CURRENT_LINE) <> 0) OR (INDEX ('(ALARM=SECURITY', CURRENT_LINE) <> 0) OR (INDEX ('(DEFAULT_PROTECTION', CURRENT_LINE) <> 0)) AND (ACLEDIT$X_PROMPT)) THEN ERASE_CHARACTER (-CURRENT_OFFSET); ENDIF; COPY_TEXT (ACLEDIT$X_RUBOUT_BOL); ENDIF; ENDIF; ! If the deleted line was to the beginning of the line, restore it, and position ! the cursor after it. IF ACLEDIT$X_DELETE_EOL <> ACLEDIT$X_NULL THEN IF SUBSTR (ACLEDIT$X_DELETE_EOL, 1, 1) = ACLEDIT$X_LINE_TERM_CHAR THEN IF MARK (NONE) <> END_OF (CURRENT_BUFFER) THEN IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT) = 'NO_MODIFY' THEN RETURN; ENDIF; IF (CURRENT_OFFSET <> 0) AND (MARK (NONE) <> BEGINNING_OF (CURRENT_BUFFER)) THEN SPLIT_LINE; ENDIF; ENDIF; COPY_TEXT (ACLEDIT$X_DELETE_EOL); MOVE_HORIZONTAL (-LENGTH (ACLEDIT$X_DELETE_EOL)); ERASE_CHARACTER (1); IF MARK (NONE) <> BEGINNING_OF (CURRENT_BUFFER) THEN MOVE_HORIZONTAL (-1); ENDIF; ACLEDIT$SET_CURRENT_ACE; IF (LENGTH (CURRENT_LINE) = 0) AND (ACLEDIT$X_PROMPT) THEN ERASE_LINE; ACLEDIT$INSERT_ACE; ENDIF; ELSE ! Check to see if this ACE may be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT)= 'NO_MODIFY' THEN RETURN; ENDIF; COPY_TEXT (ACLEDIT$X_DELETE_EOL); MOVE_HORIZONTAL (-LENGTH (ACLEDIT$X_DELETE_EOL)); ENDIF; ENDIF; ENDPROCEDURE ! ! ROUTINE NAME: ACLEDIT$RUBOUT_CHAR ! ! ROUTINE DESCRIPTION: Delete the character immediately preceeding the ! cursor. ! PROCEDURE ACLEDIT$RUBOUT_CHAR ! If at the beginning of the buffer, this is a no-op. IF MARK (NONE) = BEGINNING_OF (CURRENT_BUFFER) THEN RETURN; ENDIF; ! Check to see if this ACE may be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_CURRENT)= 'NO_MODIFY' THEN RETURN; ENDIF; ! Delete the previous character. IF CURRENT_OFFSET = 0 THEN IF MARK (NONE) <> BEGINNING_OF (CURRENT_BUFFER) THEN ! Check to see if the previous ACE may be modified. IF ACLEDIT$CHECK_MODIFY_ACE (ACLEDIT$C_NOREPLACE, ACLEDIT$C_CHECK_PREVIOUS) = 'NO_MODIFY' THEN RETURN; ENDIF; APPEND_LINE; ACLEDIT$X_RUBOUT_CHAR := ACLEDIT$X_LINE_TERM_CHAR; ENDIF; ELSE ACLEDIT$X_RUBOUT_CHAR := ERASE_CHARACTER (-1); ENDIF; ACLEDIT$X_DELETE_CHAR := ACLEDIT$X_NULL ENDPROCEDURE ! ! ROUTINE NAME: TPU$LOCAL_INIT ! ! ROUTINE DESCRIPTION: This procedure performs user initialization. ! PROCEDURE TPU$LOCAL_INIT ENDPROCEDURE ! ! ROUTINE NAME: TPU$INIT_PROCEDURE ! ! ROUTINE DESCRIPTION: ACL editor interface initialization procedure. ! PROCEDURE TPU$INIT_PROCEDURE LOCAL MESSAGE_WINDOW_SIZE, DEFAULT_JOURNAL_NAME, AUX_JOURNAL_NAME, SAVED_POSITION, TEMP_LINE; SET (FACILITY_NAME, "ACLEDIT"); ! Initialize ACL editor global variables. ACLEDIT$INIT_STORAGE; ACLEDIT$X_SCREEN_LENGTH := GET_INFO (SCREEN, "VISIBLE_LENGTH"); ! Assume an LK201 terminal, unless a VT100 or GIGI (VK100). ACLEDIT$X_TERMINAL_TYPE := "VT200"; IF GET_INFO (SCREEN, "VT100") THEN ACLEDIT$X_TERMINAL_TYPE := "VT100"; ENDIF; IF GET_INFO (SCREEN, "VK100") THEN ACLEDIT$X_TERMINAL_TYPE := "VT100"; ENDIF; ! Create the needed default buffers and windows. MESSAGE_WINDOW_SIZE := (ACLEDIT$X_SCREEN_LENGTH + 5) / 10; ! 10% for messages IF MESSAGE_WINDOW_SIZE < 3 THEN MESSAGE_WINDOW_SIZE := 3; ENDIF; MESSAGE_BUFFER := CREATE_BUFFER ("MESSAGES"); SET (EOB_TEXT, MESSAGE_BUFFER, ""); SET (PERMANENT, MESSAGE_BUFFER); SET (NO_WRITE, MESSAGE_BUFFER); SET (SYSTEM, MESSAGE_BUFFER); ACLEDIT$X_MESSAGE_WINDOW := CREATE_WINDOW ((ACLEDIT$X_SCREEN_LENGTH - (MESSAGE_WINDOW_SIZE - 1)), MESSAGE_WINDOW_SIZE, OFF); SET (VIDEO, ACLEDIT$X_MESSAGE_WINDOW, NONE); MAP (ACLEDIT$X_MESSAGE_WINDOW, MESSAGE_BUFFER); PROTECTED_ACE_BUFFER := CREATE_BUFFER ("PROTECTED_ACE"); SET (EOB_TEXT, PROTECTED_ACE_BUFFER, "[End of protected ACEs]"); SET (PERMANENT, PROTECTED_ACE_BUFFER); SET (NO_WRITE, PROTECTED_ACE_BUFFER); SET (SYSTEM, PROTECTED_ACE_BUFFER); ORIGINAL_ACL_BUFFER := CREATE_BUFFER ("ORIGINAL_ACL"); SET (EOB_TEXT, ORIGINAL_ACL_BUFFER, "[End of ACL]"); SET (PERMANENT, ORIGINAL_ACL_BUFFER); SET (NO_WRITE, ORIGINAL_ACL_BUFFER); SET (SYSTEM, ORIGINAL_ACL_BUFFER); ACL_PASTE_BUFFER := CREATE_BUFFER ("PASTE_BUFFER"); SET (EOB_TEXT, ACL_PASTE_BUFFER, "[End of paste buffer]"); SET (PERMANENT, ACL_PASTE_BUFFER); SET (NO_WRITE, ACL_PASTE_BUFFER); SET (SYSTEM, ACL_PASTE_BUFFER); ! Set up the prompt area. SET (PROMPT_AREA, ACLEDIT$X_SCREEN_LENGTH - MESSAGE_WINDOW_SIZE, 1, REVERSE); ! Create the main buffer, filling it with the ACL from the selected object. ACLEDIT$X_INPUT_FILE := GET_INFO (COMMAND_LINE, "FILE_NAME"); ACLEDIT$X_MAIN_BUFFER := CREATE_BUFFER ("MAIN", ACLEDIT$X_INPUT_FILE); ! Now set up the main editing buffer. SET (OUTPUT_FILE, ACLEDIT$X_MAIN_BUFFER, ACLEDIT$X_INPUT_FILE); SET (EOB_TEXT, ACLEDIT$X_MAIN_BUFFER, "[End of ACL]"); SET (PERMANENT, ACLEDIT$X_MAIN_BUFFER); SET (SYSTEM, ACLEDIT$X_MAIN_BUFFER); ACLEDIT$X_MAIN_WINDOW := CREATE_WINDOW (1, (ACLEDIT$X_SCREEN_LENGTH - (MESSAGE_WINDOW_SIZE + 1)), ON); MAP (ACLEDIT$X_MAIN_WINDOW, ACLEDIT$X_MAIN_BUFFER); ! Find what object we are dealing with ACLEDIT$X_OBJECT_TYPE := CALL_USER (ACLEDIT$C_GET_OBJ_TYP, ""); ACLEDIT$SET_STATUS_LINE; UPDATE (ACLEDIT$X_MAIN_WINDOW); ! Set the main window scrolling to be similar to EDT. SET (SCROLLING, ACLEDIT$X_MAIN_WINDOW, ON, 6, 7, 0); ! Start journaling if necessary. IF (GET_INFO (COMMAND_LINE, "JOURNAL") = 1) THEN AUX_JOURNAL_NAME := GET_INFO (ACLEDIT$X_MAIN_BUFFER, "OUTPUT_FILE"); IF ACLEDIT$X_OBJECT_TYPE = "Device" THEN IF SUBSTR (AUX_JOURNAL_NAME, LENGTH (AUX_JOURNAL_NAME), 1) = ":" THEN AUX_JOURNAL_NAME := SUBSTR (AUX_JOURNAL_NAME, 1, LENGTH (AUX_JOURNAL_NAME) - 1); ENDIF; ENDIF; DEFAULT_JOURNAL_NAME := ".TJL"; JOURNAL_FILE := GET_INFO (COMMAND_LINE, "JOURNAL_FILE"); JOURNAL_FILE := FILE_PARSE (JOURNAL_FILE, DEFAULT_JOURNAL_NAME, AUX_JOURNAL_NAME); JOURNAL_OPEN (JOURNAL_FILE); ENDIF; ! Copy the original ACL for later use. POSITION (ORIGINAL_ACL_BUFFER); COPY_TEXT (ACLEDIT$X_MAIN_BUFFER); SET (NO_WRITE, ORIGINAL_ACL_BUFFER); ! Set initial position and initial original ACE. POSITION (BEGINNING_OF (ACLEDIT$X_MAIN_BUFFER)); ACLEDIT$SET_CURRENT_ACE; ! Loop through all the ACEs, copying those that the user is not allowed to ! modify. LOOP EXITIF MARK (NONE) = END_OF (CURRENT_BUFFER); ACLEDIT$X_STATUS := CALL_USER (ACLEDIT$C_CHECK_MODIFY, CURRENT_LINE); IF ACLEDIT$X_STATUS = 'READ_ONLY' THEN SAVED_POSITION := MARK (NONE); TEMP_LINE := CURRENT_LINE; EDIT (TEMP_LINE, COMPRESS, UPPER); POSITION (END_OF (PROTECTED_ACE_BUFFER)); COPY_TEXT (TEMP_LINE); POSITION (SAVED_POSITION); ENDIF; MOVE_VERTICAL (1); ENDLOOP; SET (NO_WRITE, PROTECTED_ACE_BUFFER); POSITION (BEGINNING_OF (ACLEDIT$X_MAIN_BUFFER)); ! Note whether the object whose ACL is being edited is a directory file. IF (CALL_USER (ACLEDIT$C_CHECK_DIR, ACLEDIT$X_NULL) = 'DIRECTORY_FILE') THEN ACLEDIT$X_USE_DEFAULT_OPT := 1; ACLEDIT$X_DIRECTORY_FILE := 1; ENDIF; ! If prompt mode is set, and the current ACE (line) is null, start off with ! the prompt text. IF (CALL_USER (ACLEDIT$C_PROMPT_MODE, ACLEDIT$X_NULL) = 'PROMPT_MODE') THEN ACLEDIT$X_PROMPT := 1; ! Note that prompt mode is enabled ! If the current ACE is null, insert a new one. IF MARK (NONE) = END_OF (CURRENT_BUFFER) THEN ACLEDIT$INSERT_ACE; ELSE IF (LENGTH (CURRENT_LINE) = 0) THEN ACLEDIT$INSERT_ACE; ENDIF; ENDIF; ENDIF; ! Invoke local initialization procedure. TPU$LOCAL_INIT; ENDPROCEDURE ! The following section of code will only be executed when the section is ! being built. Note that the ACL editor section must be built using the ! following DCL command: ! ! $ EDIT/TPU/NOSECTION/COMMAND=SYS$LIBRARY:ACLEDIT ! ACLEDIT$DEFINE_KEYS; ! Bind the key definitions ! Relinquish the memory taken up (unnecessarily) by the ACLEDIT$DEFINE_KEYS ! procedure. COMPILE ('PROCEDURE ACLEDIT$DEFINE_KEYS ENDPROCEDURE'); SAVE ('SYS$DISK:[]ACLEDT$SECTION'); ! That's all folks. QUIT