! ----- CALC_DUPL_NODES.FUN ----- ! ! ----- FUNCTION TO RETURN A LIST OF ALL NODES (INCLUDING ANY ----- ! ----- DUPLICATE NODES) WHICH MATCH THE PASSED NODE ----- ! ! ----- If the passed node (Default of the disk volume name ----- ! ----- specified in any RIGHTSLIST logical name, otherwise the ----- ! ----- local node) does NOT match any of the nodes listed in ----- ! ----- DUPLICATE_NODES, or the NODUPLICATES logical is defined, ----- ! ----- then only the passed node will be returned. ----- ! ! ----- If the passed node (Default of the disk volume name ----- ! ----- specified in any RIGHTSLIST logical name, otherwise the ----- ! ----- local node) matches any of the nodes listed in ----- ! ----- DUPLICATE_NODES (and the NODUPLICATES logical is NOT ----- ! ----- defined) then that node, and all of its duplicate nodes, ----- ! ----- will be returned. ----- ! ! ---------- PASSED: ---------- ! ----- SPECIFIC_NODE = (Optional) Specific node to return a ! ----- duplicate list for (Default of ! ----- returning a list of duplicates for ! ----- the local node). ! ----- DUPLICATE_NODES = List of nodes to duplicate data ! ----- between. ! ! ---------- RETURNED: ---------- ! ----- CALC_DUPL_NODES will return FALSE if SUCCESSFUL, or TRUE ! ----- if any unexpected error occurs ! ----- NODES_IN_MEMORY = Number of nodes returned in the ! ----- NODE_LISTS() array ! ----- NODE_LISTS() = List of matching nodes (including any ! ----- duplicates) ! ! ----- Last Change 07/07/94 by Brian Lomasky ----- ! FUNCTION WORD CALC_DUPL_NODES(STRING SPECIFIC_NODE) %INCLUDE "NUSER.INC" %INCLUDE "$LNMDEF" %FROM %LIBRARY "SYS$LIBRARY:BASIC$STARLET.TLB" EXTERNAL LONG CONSTANT & SS$_NOLOGNAM ! NO LOGICAL NAME TRANSLATION EXTERNAL LONG CONSTANT & SS$_NORMAL ! NORMAL EXIT STATUS RECORD TRNBUF ! $TRNLNM RECORD WORD BUFFER_LENGTH1 WORD ITEM_CODE1 LONG BUFFER_ADDRESS1 LONG RETURN_LENGTH_ADDRESS1 LONG LIST_TERMINATOR END RECORD TRNBUF DECLARE WORD BAR_LOC ! LOCATION OF BAR IN DUPL_NODES DECLARE STRING CHECK_NODE ! NODE TO BE CHECKED DECLARE WORD COM_LOC ! LOCATION OF COMMA IN NODE_PAIR DECLARE STRING DUPL_NODES ! COPY OF DUPLICATE_NODES DECLARE WORD LOG_LENGTH ! LENGTH OF LOGICAL NAME DECLARE WORD MATCHING_NODE ! TRUE IF MATCHING NODE IN PAIR DECLARE WORD NODE_INDEX ! LIST OF NODES TO GRANT IDENT DECLARE STRING NODE_PAIR ! LIST OF NODE PAIRS DIM STRING NODE_PAIRS(100%) ! LIST OF NODE PAIRS DECLARE WORD PAIR_COUNTER ! COUNT OF NODE PAIRS DECLARE WORD PAIR_INDEX ! INDEX INTO NODE PAIRS DECLARE LONG SYS_STATUS ! SYSTEM SERVICE EXIT STATUS DECLARE STRING TEMP_STRING ! TEMPORARY STRING DECLARE TRNBUF TRNITEM ! EQUATE $TRNLNM RECORD ! ----- LOGICAL NAME FROM $TRNLNM ----- MAP (TRNLNM) STRING LOG_NAME = 255% EXTERNAL LONG FUNCTION LOGICAL_NAME(STRING, & STRING) ! TRANSLATE LOGICAL NAME EXTERNAL LONG FUNCTION & SYS$TRNLNM ! TRANSLATE LOGICAL NAME TRNITEM::BUFFER_LENGTH1 = 255% ! STORE DATA FOR $TRNLNM TRNITEM::ITEM_CODE1 = LNM$_STRING TRNITEM::BUFFER_ADDRESS1 = LOC(LOG_NAME) TRNITEM::RETURN_LENGTH_ADDRESS1 = LOC(LOG_LENGTH) TRNITEM::LIST_TERMINATOR = 0% CALC_DUPL_NODES = TRUE ! ASSUME ERROR STATUS IF DEBUG_MODE THEN PRINT "DEBUG>----- Call CALC_DUPL_NODES" PRINT "DEBUG>SPECIFIC_NODE=" + SPECIFIC_NODE END IF ! ----- CALCULATE LIST OF DUPLICATE NODES TO GRANT THE ----- ! ----- IDENTIFIER ON ----- IF SPECIFIC_NODE = "" THEN ! ----- SEE IF THE RIGHTSLIST LOGICAL NAME EXISTS ----- SYS_STATUS = SYS$TRNLNM(, "LNM$DCL_LOGICAL", & "RIGHTSLIST", , TRNITEM) SELECT SYS_STATUS CASE SS$_NOLOGNAM ! IF NO LOGICAL EQUIVALENT: IF DEBUG_MODE THEN PRINT "DEBUG>NO RIGHTSLIST TRANSLATION" END IF CHECK_NODE = TRM$(RIGHTSLIST_NODES(1%)) CASE SS$_NORMAL IF DEBUG_MODE THEN PRINT "DEBUG>RIGHTSLIST " + & "TRANSLATION IS " + & LEFT(LOG_NAME, LOG_LENGTH) END IF ! ----- EXTRACT LOGICAL NAME ----- IF LOG_LENGTH > 1% THEN TEMP_STRING = & LEFT(LOG_NAME, LOG_LENGTH) ! ----- EXTRACT JUST THE DEVICE ----- ! ----- (LESS ANY "DISK$" AND ":") ----- TEMP_STRING = LEFT(TEMP_STRING, & POS(TEMP_STRING, ":", 1%) - 1%) TEMP_STRING = RIGHT(TEMP_STRING,& 6%) IF LEFT(TEMP_STRING,& 5%) = "DISK$" CHECK_NODE = TEMP_STRING IF DEBUG_MODE THEN PRINT "DEBUG>NODE IS " & + CHECK_NODE END IF ELSE CHECK_NODE = TRM$(RIGHTSLIST_NODES(1%)) END IF END SELECT ELSE CHECK_NODE = SPECIFIC_NODE END IF ! ----- ALWAYS STORE THE SPECIFIED (OR DEFAULT) NODE ----- NODES_IN_MEMORY = 1% NODE_LISTS(1%) = CHECK_NODE ! ----- SEE IF ANY DUPLICATE NODES TO BE PROCESSED ----- IF DEBUG_MODE THEN PRINT "DEBUG>DUPLICATE_NODES=" + DUPLICATE_NODES PRINT "DEBUG>CHECK_NODE=" + CHECK_NODE END IF ! ----- SEE IF THE NODUPLICATES LOGICAL IS DEFINED ----- SYS_STATUS = LOGICAL_NAME("NODUPLICATES", TEMP_STRING) SELECT SYS_STATUS CASE SS$_NORMAL ! SUCCESSFUL ! ----- DO NOT CHECK FOR ANY DUPLICATE_NODES ----- IF DEBUG_MODE THEN PRINT "DEBUG>NODUPLICATES logical is defined" END IF CASE SS$_NOLOGNAM ! NO LOGICAL NAME EXISTS ! ----- CHECK FOR ANY DUPLICATE_NODES ----- IF DEBUG_MODE THEN PRINT "DEBUG>NODUPLICATES logical" + & " is NOT defined" END IF CASE ELSE ! ANY OTHER ERROR PRINT "Unexpected " + NUM1$(SYS_STATUS) + & " error from LOGICAL_NAME in" + & " CALC_DUPL_NODES" + BEL EXIT FUNCTION END SELECT IF DUPLICATE_NODES <> "" AND SYS_STATUS <> SS$_NORMAL THEN DUPL_NODES = DUPLICATE_NODES ! ----- FOR EACH BAR-SEPARATED GROUP: ----- WHILE DUPL_NODES <> "" IF DEBUG_MODE THEN PRINT "DEBUG> DUPL_NODES=" + DUPL_NODES END IF BAR_LOC = POS(DUPL_NODES, "|", 1%) IF BAR_LOC <> 0% THEN NODE_PAIR = LEFT(DUPL_NODES, & BAR_LOC - 1%) DUPL_NODES = RIGHT(DUPL_NODES, & BAR_LOC + 1%) ELSE NODE_PAIR = DUPL_NODES DUPL_NODES = "" END IF IF DEBUG_MODE THEN PRINT "DEBUG> NODE_PAIR=" + NODE_PAIR END IF ! ----- FOR EACH COMMA-SEPARATED NODE ----- ! ----- PAIR: ----- MATCHING_NODE = FALSE PAIR_COUNTER = 0% WHILE NODE_PAIR <> "" COM_LOC = POS(NODE_PAIR, ",", 1%) IF COM_LOC <> 0% THEN TEMP_STRING = LEFT( & NODE_PAIR, COM_LOC - 1%) NODE_PAIR = RIGHT( & NODE_PAIR, COM_LOC + 1%) ELSE TEMP_STRING = NODE_PAIR NODE_PAIR = "" END IF IF DEBUG_MODE THEN PRINT "DEBUG> " + & "A Node=" + & TEMP_STRING END IF ! ----- SEE IF SPECIFIED ----- ! ----- NODE MATCHES A ----- ! ----- NODE IN THIS PAIR ----- IF TEMP_STRING = CHECK_NODE THEN MATCHING_NODE = TRUE END IF PAIR_COUNTER = PAIR_COUNTER + 1% NODE_PAIRS(PAIR_COUNTER) = TEMP_STRING NEXT ! ----- SKIP IF NODE DOES NOT MATCH ANY ----- ! ----- NODE IN THIS PAIR ----- ITERATE IF NOT MATCHING_NODE ! ----- APPEND ALL UNIQUE NODES IN THIS ----- ! ----- PAIR TO THE LIST OF NODES TO BE ----- ! ----- ACCESSED ----- PAIR_INDEX = 0% WHILE PAIR_INDEX < PAIR_COUNTER PAIR_INDEX = PAIR_INDEX + 1% MATCHING_NODE = FALSE NODE_INDEX = 0% WHILE NODE_INDEX < NODES_IN_MEMORY NODE_INDEX = NODE_INDEX + 1% IF NODE_LISTS( & NODE_INDEX) = & NODE_PAIRS(PAIR_INDEX) THEN MATCHING_NODE = TRUE END IF NEXT ITERATE IF MATCHING_NODE NODES_IN_MEMORY = NODES_IN_MEMORY + 1% IF DEBUG_MODE THEN PRINT "DEBUG> " + & "Store " + & NODE_PAIRS( & PAIR_INDEX) + & " in " + & "NODE_LISTS(" & + NUM1$( & NODES_IN_MEMORY) + ")" END IF NODE_LISTS(NODES_IN_MEMORY) = & NODE_PAIRS(PAIR_INDEX) NEXT NEXT END IF IF DEBUG_MODE THEN PRINT "DEBUG>FOUND LIST OF DUPLICATE NODES:" NODE_INDEX = 0% WHILE NODE_INDEX < NODES_IN_MEMORY NODE_INDEX = NODE_INDEX + 1% PRINT " DEBUG>" + NODE_LISTS(NODE_INDEX) NEXT END IF CALC_DUPL_NODES = FALSE ! RETURN SUCCESS STATUS END FUNCTION