10 ! ----- [LOMASKY.SYS.RIGHTSLIST]COMPARE_RIGHTSLISTS.BAS ----- ! ! ----- This program compares the contents of two RIGHTSLIST.DAT ----- ! ----- files, creating a COMPARE_RIGHTSLISTS.LIS report file ----- ! ! ----- The program will exit with a status of %X10000000 if the ----- ! ----- files contain any matching identifier name which has ----- ! ----- different identifier values in the two files ----- ! ! ----- Restrictions: ----- ! ! ----- 1) TOOLS:RIGHTSLIST_SPECS.DAT must exist; It must ----- ! ----- contain the actual filespecs of the RIGHTSLIST ----- ! ----- files on all cluster-wide nodes to be possibly ----- ! ----- accessed by this program. ----- ! ! ----- 2) SYSPRV (or equiv) privilege required ----- ! ! ----- 3) Requires BASIC V3.n ----- ! ! ----- Teradyne, Inc., 321 Harrison Avenue, M/S H87, Boston, MA 02118 ! ----- Brian Lomasky: (617) 422-2259 ! ! ----- Neither Brian Lomasky nor Teradyne, Inc. implicitly or ----- ! ----- explicitly implies this program is usable in any way. ----- ! ----- This program is released to the public domain in an ----- ! ----- "AS-IS" condition. ----- ! ! Compile and Link COMPARE_RIGHTSLISTS as follows: ! $BASIC/LONG COMPARE_RIGHTSLISTS ! $LINK/NOTRACEBACK COMPARE_RIGHTSLISTS ! ! ------------------------ Modification History ------------------------ ! ----- Date Version Description ----- ! ----- 07/11/93 2.0 Add held identifier search compare ----- ! ----- 01/18/93 1.0 Original ----- ! ---------------------------------------------------------------------- ! OPTION TYPE = EXPLICIT %LET %DEBUG = 0% ! 1 IF DEBUG ON, 0 IF OFF ! ----- FAB AND NAM DEFINITIONS REQUIRED FOR SYS$PARSE ----- %INCLUDE "$DVIDEF" %FROM %LIBRARY "SYS$LIBRARY:BASIC$STARLET.TLB" ! ----- SYSTEM SERVICE ERROR CODES AND FUNCTION VALUES ----- EXTERNAL WORD CONSTANT DSC$K_DTYPE_T ! TEXT SORT DATATYPE EXTERNAL LONG CONSTANT JPI$_USERNAME ! USERNAME FOR $GETJPIW EXTERNAL LONG CONSTANT SS$_ABORT ! ABORT STATUS EXTERNAL LONG CONSTANT SS$_ENDOFFILE ! END-OF-FILE FROM SORT READ EXTERNAL LONG CONSTANT SS$_IVDEVNAM ! INVALID DEVICE NAME EXTERNAL LONG CONSTANT SS$_IVLOGNAM ! INVALID LOGICAL NAME EXTERNAL LONG CONSTANT SS$_NORMAL ! NORMAL SUCCESS STATUS EXTERNAL LONG CONSTANT SS$_NOSUCHDEV ! NO SUCH DEVICE ! ----- COMMON CONSTANTS ----- DECLARE WORD CONSTANT TRUE = (1% = 1%) DECLARE WORD CONSTANT FALSE = NOT TRUE DECLARE LONG CONSTANT MAX_IDENTS = 200% ! MAX NUMBER OF HELD IDENTS DECLARE WORD CONSTANT MAX_RIGHTS = 40% ! MAX NUMBER OF RIGHTSLIST FILES ! ----- TO RETURN ERROR (2) IN $STATUS BUT HAVE NO MESSAGE ----- ! ----- DISPLAYED ON THE SCREEN, ALSO SET BIT 28 (HEX 10000000) IN ----- ! ----- THE VALUE YOU PASS TO SYS$EXIT ----- DECLARE LONG CONSTANT ERROR_WITH_NO_PUTMSG = X"10000002"L ! ----- TO RETURN WARNING (0) IN $STATUS BUT HAVE NO MESSAGE ----- ! ----- DISPLAYED ON THE SCREEN, ALSO SET BIT 28 (HEX 10000000) IN ----- ! ----- THE VALUE YOU PASS TO SYS$EXIT ----- DECLARE LONG CONSTANT WARNING_WITH_NO_PUTMSG = X"10000000"L ! ----- BASIC ERROR CODE CONSTANTS ----- DECLARE WORD CONSTANT BUCKET_LOCKED = 154% DECLARE WORD CONSTANT CANNOT_OPEN_FILE = 162% DECLARE WORD CONSTANT DUPLICATE_KEY = 134% DECLARE WORD CONSTANT END_OF_FILE = 11% DECLARE WORD CONSTANT FILE_NOT_FOUND = 5% DECLARE WORD CONSTANT ILLEGAL_USAGE_FOR_DEVICE = 133% DECLARE WORD CONSTANT PROTECTION_VIOLATION = 10% DECLARE WORD CONSTANT REC_NOT_FOUND = 155% RECORD DVIBUF ! $GETDVIW RECORD VARIANT CASE WORD BUFFER_LENGTH WORD ITEM_CODE LONG BUFFER_ADDRESS LONG RETURN_LENGTH_ADDRESS CASE LONG LIST_TERMINATOR END VARIANT END RECORD DVIBUF RECORD JPIBUF ! $GETJPIW RECORD WORD BUFFER_LENGTH WORD ITEM_CODE LONG BUFFER_ADDRESS LONG RETURN_LENGTH_ADDRESS LONG LIST_TERMINATOR END RECORD JPIBUF ! ----- VARIABLE DECLARATIONS ----- DECLARE WORD ANY_DIFFS ! TRUE IF FILES ARE DIFFERENT DECLARE WORD COMPARE_ONLY_HOLDERS ! TRUE TO COMPARE ONLY HOLDERS DECLARE LONG DEC_DIV ! FOR DEC_TO_OCT FUNCTION DECLARE LONG DEC_INPUT ! FOR DEC_TO_OCT FUNCTION DIM DVIBUF DVIITEM(2%) ! EQUATE $GETDVIW RECORD DECLARE WORD EOF_FLAG ! TRUE IF DONE SEARCHING UAF DECLARE WORD EOF_HELD ! TRUE IF EOF ON HELD IDENT CHNL DECLARE WORD FIRST_CHNL ! FIRST I/O CHNL TO BE COMPARED DECLARE WORD FIRST_EOF ! EOF FLAG FOR FIRST FILE DECLARE LONG FIRST_HELD_INDEX ! FIRST HELD IDENT INDEX TO GET DECLARE STRING FIRST_NAME ! FIRST HELD IDENT NAME TO COMP DECLARE WORD GET_FIRST ! TRUE TO GET FIRST RECORD DECLARE WORD GET_FIRST_HELD ! TRUE TO GET FIRST HELD IDENT DECLARE WORD GET_SECOND ! TRUE TO GET SECOND RECORD DECLARE WORD GET_SECOND_HELD ! TRUE TO GET SECOND HELD IDENT DIM STRING HELD_IDENTS(MAX_IDENTS) ! LIST OF HELD IDENTIFIER NAMES DECLARE LONG HOST_AVAIL ! 1 IF HOST IS AVAILABLE DECLARE LONG HOST_AVAIL_LENGTH ! LENGTH OF HOST_AVAIL DECLARE LONG I_O_CHNL ! RIGHTSLIST I/O CHNL TO ACCESS DIM LONG ID_VALUES(MAX_IDENTS) ! LIST OF HELD IDENTIFIER VALUES DECLARE JPIBUF JPIITEM ! EQUATE $GETJPIW RECORD DIM WORD KEY_BUFFER(4%) ! KEY BUFFER FOR SORT DECLARE LONG LINE_COUNTER ! COUNT OF REPORT LINES DECLARE WORD LONGEST_RECORD ! LONGEST RECORD FOR SORT DECLARE LONG MOUNTED ! NON-ZERO IF DEVICE MOUNTED DECLARE LONG MOUNTED_LENGTH ! LENGTH OF MOUNTED DECLARE LONG OCT_OUTPUT ! FOR DEC_TO_OCT FUNCTION DECLARE WORD ONLY_MATCHING_NON_MATCHES ! TRUE IF ONLY NON-MATCHING VALS DECLARE LONG PAGE_COUNTER ! COUNT OF REPORT PAGES DECLARE WORD RECORD_FOUND ! TRUE IF MATCHING RECORD FOUND DECLARE WORD RIGHTSLIST_COUNTER ! COUNT OF RIGHTSLIST FILESPECS DIM STRING RIGHTSLIST_NODES(MAX_RIGHTS) ! LIST OF ALL RIGHTSLIST NODES DIM STRING RIGHTSLIST_SPECS(MAX_RIGHTS) ! LIST OF ALL RIGHTSLIST FILES DECLARE LONG SAVE_CTR ! COUNT OF SAVED HELD IDENTS DIM STRING SAVE_HELD_IDENTS(MAX_IDENTS) ! SAVED LIST OF HELD IDENT NAMES DECLARE LONG SAVE_KGB1_IDENTIFIER ! SAVED KGB1_IDENTIFIER DECLARE STRING SAVE_KGB1_NAME ! SAVED KGB1_NAME DECLARE LONG SAVE_KGB2_IDENTIFIER ! SAVED KGB2_IDENTIFIER DECLARE STRING SAVE_KGB2_NAME ! SAVED KGB2_NAME DECLARE WORD SECOND_CHNL ! SECOND I/O CHNL TO BE COMPARED DECLARE WORD SECOND_EOF ! EOF FLAG FOR SECOND FILE DECLARE LONG SECOND_HELD_INDEX ! SECOND HELD IDENT INDEX TO GET DECLARE STRING SECOND_NAME ! SECOND HELD IDENT NAME TO COMP DECLARE WORD SKIP_SINGLE_NODE_UIC_FORMAT! TRUE TO SKIP NON-MATCH UICS DECLARE LONG SYS_STATUS ! SYSTEM SERVICE STATUS DECLARE WORD TEMP ! TEMPORARY WORD VARIABLE DECLARE LONG TEMP_LONG ! TEMPORARY LONGWORD VARIABLE DECLARE STRING TEMP_STRING ! TEMPORARY STRING DECLARE WORD THE_CHNL ! CALCULATED I/O CHANNEL DECLARE LONG TOTAL_IDS ! TOTAL NUMBER OF HELD IDENTS DECLARE LONG UIC_GROUP ! CALCULATED OCTAL UIC GROUP DECLARE LONG UIC_MEMBER ! CALCULATED OCTAL UIC MEMBER DECLARE WORD USERNAME_LENGTH ! LENGTH OF THE_USERNAME DECLARE WORD VALID_ENTRY ! TRUE IF VALID ENTRY ! ----- MAPPED VARIABLE FOR HELD IDENTIFIER KEY SEARCH ----- MAP (GETID_MAP) STRING SAVE_ALT_KEY = 8%! SAVED ALTERNATE KEY #1 ! ----- MAPPED VARIABLE FOR OTS$CVT_L_TZ SYSTEM SERVICE ----- MAP (HEXMAP) STRING OUTPUT_STRING = 8% ! ----- MAPPED VARIABLE FOR SYS$GETJPIW SYSTEM SERVICE ----- MAP (JPIMAP) STRING THE_USERNAME=12% ! PROCESS USERNAME ! ----- RECORD FORMAT FOR RIGHTSLIST.DAT FILE(S) ----- ! ---------- FIRST FILE: ---------- MAP (RIGHT1) ! ----- KGB1_IDENTIFIER contains 0 if this -----& ! ----- is a maintenance record, else this -----& ! ----- is an identifier or a holder ----- & ! ----- record and this field contains the -----& ! ----- binary identifier value. ----- & ! ----- (Values above 0 contain the ----- & ! ----- longword UIC associated with the ----- & ! ----- Identifier Name and only occur ----- & ! ----- when reading an identifier record; -----& ! ----- Values under 0 contain a longword ----- & ! ----- identifier value - If the holder ----- & ! ----- field is also zero, this is an ----- & ! ----- identifier record and the ----- & ! ----- Identifier Name is the Name of ----- & ! ----- this identifier - If the holder ----- & ! ----- field is non-zero, this is a ----- & ! ----- holder record, containing the UIC ----- & ! ----- of a holder of this identifier) ----- & ! ----- KGB1_IDENTIFIER IS THE PRIMARY KEY -----& ! ----- (DUPLICATES, NO CHANGES) ----- & LONG KGB1_IDENTIFIER, ! IDENTIFIER NUMBER & ! ----- KGB1_ATTRIBUTES contains 32 bits: ----- & ! ----- Bit 0 = Resource; Resource use ----- & ! ----- allowed ----- & ! ----- Bit 1 = Dynamic; Ident may be ----- & ! ----- enabled or disabled ----- & ! ----- Bit 2 = Access; Ident used in ----- & ! ----- protection checks ----- & ! ----- Bits 3 - 31 = ----- & LONG KGB1_ATTRIBUTES, ! IDENTIFIER ATTRIBUTES & ! ----- KGB1_HOLDER(0) contains 0 if this ----- & ! ----- is an identifier record, else this -----& ! ----- is a holder record and this field ----- & ! ----- will contain the UIC of the holder -----& ! ----- KGB1_HOLDER() IS ALTERNATE KEY #1 ----- & ! ----- (DUPLICATES, CHANGES) ----- & LONG KGB1_HOLDER(1%), ! UIC OF IDENT HOLDER & ! & ! ********** END of HOLDER record ********** & ! & ! ----- KGB1_NAME IS ALTERNATE KEY #2 ----- & ! ----- (DUPLICATES, CHANGES) ----- & STRING KGB1_NAME = 32%, ! IDENTIFIER NAME & ! & ! ******** END of IDENTIFIER record ********* & ! & WORD KGB1_LEVEL, ! FILE STRUCTURE LEVEL & STRING FILL = 2%, ! & LONG KGB1_SYSID(1%), ! SYSTEM IDENTIFIER & LONG KGB1_NEXT_ID ! NEXT AVAIL IDENTIFIER ! ! ******** END of MAINTENANCE record ******** ! ----- Redefine the Identifier Value if a UIC ----- MAP (RIGHT1) WORD KGB1_UIC_MEMBER, & WORD KGB1_UIC_GROUP, & STRING FILL = 4%, & ! ----- Redefine the holder as a string ----- & STRING KGB1_HOLDER_STRING = 8% ! ---------- SECOND FILE: ---------- MAP (RIGHT2) ! ----- KGB2_IDENTIFIER contains 0 if this -----& ! ----- is a maintenance record, else this -----& ! ----- is an identifier or a holder ----- & ! ----- record and this field contains the -----& ! ----- binary identifier value. ----- & ! ----- (Values above 0 contain the ----- & ! ----- longword UIC associated with the ----- & ! ----- Identifier Name and only occur ----- & ! ----- when reading an identifier record; -----& ! ----- Values under 0 contain a longword ----- & ! ----- identifier value - If the holder ----- & ! ----- field is also zero, this is an ----- & ! ----- identifier record and the ----- & ! ----- Identifier Name is the Name of ----- & ! ----- this identifier - If the holder ----- & ! ----- field is non-zero, this is a ----- & ! ----- holder record, containing the UIC ----- & ! ----- of a holder of this identifier) ----- & ! ----- KGB2_IDENTIFIER IS THE PRIMARY KEY -----& ! ----- (DUPLICATES, NO CHANGES) ----- & LONG KGB2_IDENTIFIER, ! IDENTIFIER NUMBER & ! ----- KGB2_ATTRIBUTES contains 32 bits: ----- & ! ----- Bit 0 = Resource; Resource use ----- & ! ----- allowed ----- & ! ----- Bit 1 = Dynamic; Ident may be ----- & ! ----- enabled or disabled ----- & ! ----- Bit 2 = Access; Ident used in ----- & ! ----- protection checks ----- & ! ----- Bits 3 - 31 = ----- & LONG KGB2_ATTRIBUTES, ! IDENTIFIER ATTRIBUTES & ! ----- KGB2_HOLDER(0) contains 0 if this ----- & ! ----- is an identifier record, else this -----& ! ----- is a holder record and this field ----- & ! ----- will contain the UIC of the holder -----& ! ----- KGB2_HOLDER() IS ALTERNATE KEY #1 ----- & ! ----- (DUPLICATES, CHANGES) ----- & LONG KGB2_HOLDER(1%), ! UIC OF IDENT HOLDER & ! & ! ********** END of HOLDER record ********** & ! & ! ----- KGB2_NAME IS ALTERNATE KEY #2 ----- & ! ----- (DUPLICATES, CHANGES) ----- & STRING KGB2_NAME = 32%, ! IDENTIFIER NAME & ! & ! ******** END of IDENTIFIER record ********* & ! & WORD KGB2_LEVEL, ! FILE STRUCTURE LEVEL & STRING FILL = 2%, ! & LONG KGB2_SYSID(1%), ! SYSTEM IDENTIFIER & LONG KGB2_NEXT_ID ! NEXT AVAIL IDENTIFIER ! ! ******** END of MAINTENANCE record ******** ! ----- Redefine the Identifier Value if a UIC ----- MAP (RIGHT2) WORD KGB2_UIC_MEMBER, & WORD KGB2_UIC_GROUP, & STRING FILL = 4%, & ! ----- Redefine the holder as a string ----- & STRING KGB2_HOLDER_STRING = 8% ! ----- RECORD FORMAT FOR RIGHTSLIST.DAT FILE (OPENED ON CHNL 3+4) ----- MAP (RIGHT3) LONG KGB3_IDENTIFIER, ! IDENTIFIER NUMBER & LONG KGB3_ATTRIBUTES, ! IDENTIFIER ATTRIBUTES & LONG KGB3_HOLDER(1%), ! UIC OF IDENT HOLDER & STRING KGB3_NAME = 32%, ! IDENTIFIER NAME & WORD KGB3_LEVEL, ! FILE STRUCTURE LEVEL & STRING FILL = 2%, ! & LONG KGB3_SYSID(1%), ! SYSTEM IDENTIFIER & LONG KGB3_NEXT_ID ! NEXT AVAIL IDENTIFIER ! ----- Redefine the Identifier Value if a UIC ----- MAP (RIGHT3) STRING FILL = 8%, & ! ----- Redefine the holder as a string ----- & STRING KGB3_HOLDER_STRING = 8% ! ----- EXTERNAL FUNCTIONS ----- EXTERNAL LONG FUNCTION OTS$CVT_L_TZ ! CONVERT LONGWORD TO HEX STRING EXTERNAL LONG FUNCTION SOR$BEGIN_SORT ! BEGIN SORT EXTERNAL LONG FUNCTION SOR$END_SORT ! END SORT EXTERNAL LONG FUNCTION SOR$RELEASE_REC ! RELEASE RECORD TO SORT EXTERNAL LONG FUNCTION SOR$RETURN_REC ! RETURN RECORD FROM SORT EXTERNAL LONG FUNCTION SOR$SORT_MERGE ! PERFORM THE ACTUAL SORT EXTERNAL LONG FUNCTION SYS$EXIT ! EXIT PROCESS WITH STATUS EXTERNAL LONG FUNCTION SYS$GETDVIW ! GET DEVICE INFORMATION/WAIT EXTERNAL LONG FUNCTION SYS$GETJPIW ! GET JOB INFORMATION AND WAIT ! ----- LOCAL FUNCTION TO READ IN ALL RIGHTSLIST FILE SPECS ----- DEF WORD READ_ALL_RIGHTSLIST_SPECS READ_ALL_RIGHTSLIST_SPECS = 0% ! ALWAYS RETURN ZERO RIGHTSLIST_COUNTER = 0% EOF_FLAG = FALSE WHILE NOT EOF_FLAG WHEN ERROR IN LINPUT #99%, TEMP_STRING USE IF ERR = END_OF_FILE THEN EOF_FLAG = TRUE CONTINUE END IF PRINT PRINT "Unexpected BASIC Error " + & NUM1$(ERR) + " while reading" + & " TOOLS:RIGHTSLIST_SPECS.DAT" + BEL EXIT HANDLER END WHEN IF EOF_FLAG THEN EXIT DEF END IF RIGHTSLIST_COUNTER = RIGHTSLIST_COUNTER + 1% RIGHTSLIST_SPECS(RIGHTSLIST_COUNTER) = TEMP_STRING ! ----- EXTRACT NODE ----- TEMP_STRING = LEFT(TEMP_STRING, & POS(TEMP_STRING, ":", 1%) - 1%) TEMP_STRING = RIGHT(TEMP_STRING, 6%) & IF LEFT(TEMP_STRING, 5%) = "DISK$" RIGHTSLIST_NODES(RIGHTSLIST_COUNTER) = TEMP_STRING NEXT END DEF ! ----- LOCAL FUNCTION THAT RETURNS TRUE IF THE DISK PORTION OF ----- ! ----- THE PASSED FILESPEC DOES NOT HAVE AN AVAILABLE HOST OR IS ----- ! ----- NOT MOUNTED ----- DEF WORD SYSTEM_DISK_UNAVAILABLE SYSTEM_DISK_UNAVAILABLE = TRUE ! ASSUME ERROR STATUS ! ----- EXTRACT DISK SPECIFICATION (LESS :) ----- TEMP_STRING = LEFT(TEMP_STRING, POS(TEMP_STRING, ":", 1%) - 1%) EXIT DEF IF TEMP_STRING = "" ! ----- GET DEVICE INFO FOR THIS DISK ----- SYS_STATUS = SYS$GETDVIW(, , TEMP_STRING, & DVIITEM() BY REF, , , , ) SELECT SYS_STATUS CASE SS$_NORMAL ! ----- EXIT IF HOST IS NOT AVAILABLE ----- EXIT DEF IF HOST_AVAIL = 0% ! ----- EXIT IF DEVICE IS NOT MOUNTED ----- EXIT DEF IF MOUNTED = 0% CASE SS$_NOSUCHDEV, SS$_IVDEVNAM, SS$_IVLOGNAM EXIT DEF ! EXIT IF NO SUCH / INVALID DEV CASE ELSE PRINT "Unexpected $GETDVI Error " + & NUM1$(SYS_STATUS) + " - Continuing..." + BEL END SELECT SYSTEM_DISK_UNAVAILABLE = FALSE ! RETURN SUCCESS STATUS END DEF ! ----- DECIMAL-TO-OCTAL CONVERSION FUNCTION ----- DEF LONG DEC_TO_OCT(WORD DEC_UIC) DEC_INPUT = DEC_UIC DEC_INPUT = DEC_INPUT + 65536% IF DEC_UIC < 0% OCT_OUTPUT = 0% FOR TEMP = 7% TO 0% STEP -1% DEC_DIV = INT(DEC_INPUT / 8%^TEMP) IF DEC_DIV > 0% THEN OCT_OUTPUT = OCT_OUTPUT + 10%^TEMP * DEC_DIV DEC_INPUT = DEC_INPUT - 8%^TEMP * DEC_DIV END IF NEXT TEMP DEC_TO_OCT = OCT_OUTPUT END DEF ! ----- LOCAL FUNCTION TO CONVERT A LONGWORD IDENTIFIER TO AN ----- ! ----- 8-CHAR HEX STRING VALUE ----- DEF STRING TO_HEX(LONG THE_VALUE) ! ----- CONVERT LONGWORD TO HEX STRING ----- SYS_STATUS = OTS$CVT_L_TZ(THE_VALUE, OUTPUT_STRING, & 8% BY VALUE) IF SYS_STATUS <> SS$_NORMAL THEN PRINT NUM1$(SYS_STATUS) + " error while" + & " calling OTS$CVT_L_TZ for " + & NUM1$(THE_VALUE) + " - Continuing..." TO_HEX = "** " + NUM1$(THE_VALUE) + " **" ELSE TO_HEX = OUTPUT_STRING ! RETURN THE CONVERTED STRING END IF END DEF ! ----- LOCAL FUNCTION TO CONVERT A LONGWORD IDENTIFIER TO A ----- ! ----- 1->32 CHAR UIC OR AN IDENTIFIER, AS APPROPRIATE ----- DEF STRING LONG_TO_IDENT(LONG THE_VALUE, WORD A_CHNL) ! THE_CHNL = A_CHNL + 2% ! EOF_FLAG = FALSE ! WHEN ERROR IN ! GET #THE_CHNL, KEY #0% GE THE_VALUE, REGARDLESS ! USE ! IF ERR = BUCKET_LOCKED THEN ! SLEEP 1% ! RETRY ! END IF ! IF ERR = REC_NOT_FOUND OR ERR = END_OF_FILE THEN ! EOF_FLAG = TRUE ! CONTINUE ! END IF ! PRINT "Unexpected error reading file #" + & ! NUM1$(THE_CHNL) ! PRINT "VMS error status value:"; VMSSTATUS ! EXIT HANDLER ! END WHEN ! IF EOF_FLAG THEN LONG_TO_IDENT = TO_HEX(THE_VALUE) ! EXIT DEF ! END IF ! ----- UNTIL IDENTIFIER RECORD FOUND: ----- ! WHILE KGB3_HOLDER(0%) <> 0% ! IF KGB3_IDENTIFIER <> THE_VALUE THEN ! UNLOCK #THE_CHNL ! LONG_TO_IDENT = TO_HEX(THE_VALUE) ! EXIT DEF ! END IF ! GET #THE_CHNL, REGARDLESS ! NEXT ! UNLOCK #THE_CHNL ! LONG_TO_IDENT = TRM$(KGB3_NAME) END DEF ! ----- LOCAL FUNCTION TO CONVERT AN IDENTIFIER VALUE TO A 1->20 ----- ! ----- CHAR HEX VALUE OR UIC-FORMATTED STRING ----- DEF STRING TO_VALUE(LONG AN_IDENT, WORD THE_CHNL) IF AN_IDENT > 0% THEN ! SEE IF IDENT IN UIC FORMAT: IF THE_CHNL = 1% THEN UIC_GROUP = DEC_TO_OCT(KGB1_UIC_GROUP) UIC_MEMBER = DEC_TO_OCT(KGB1_UIC_MEMBER) ELSE UIC_GROUP = DEC_TO_OCT(KGB2_UIC_GROUP) UIC_MEMBER = DEC_TO_OCT(KGB2_UIC_MEMBER) END IF TO_VALUE = "[" + NUM1$(UIC_GROUP) + "," + & NUM1$(UIC_MEMBER) + "]" ELSE TO_VALUE = LONG_TO_IDENT(AN_IDENT, THE_CHNL) END IF END DEF ! ----- LOCAL FUNCTION TO CHECK FOR AND PRINT ANY HEADINGS ----- DEF WORD CHECK_FOR_HEADINGS CHECK_FOR_HEADINGS = 0% ! ALWAYS RETURN ZERO EXIT DEF IF LINE_COUNTER < 63% PAGE_COUNTER = PAGE_COUNTER + 1% PRINT #10%, FF + "Page " + NUM1$(PAGE_COUNTER); & TAB(26%); "Rightslist Comparison Report"; & TAB(60%); DATE$(0%) + " " + TIME$(0%) PRINT #10% IF ONLY_MATCHING_NON_MATCHES THEN PRINT #10%, "Name"; TAB(40%); & RIGHTSLIST_NODES(FIRST_CHNL) + & "'s value"; TAB(60%); & RIGHTSLIST_NODES(SECOND_CHNL) + "'s value" ELSE PRINT #10%, "Name"; TAB(40%); "Only in file 1"; & TAB(60%); "Only in file 2" END IF PRINT #10%, "--------------------------------"; & TAB(40%); "-------------------"; & TAB(60%); "-------------------" LINE_COUNTER = 4% END DEF ! ----- LOCAL FUNCTION TO RETURN A SORTED LIST OF ALL HELD ----- ! ----- IDENTIFIERS WHICH ARE HELD BY A SPECIFIC IDENTIFIER VALUE ----- DEF LONG GET_HELD_IDENTS(LONG ID_VALUE, LONG CHNL_TO_USE) GET_HELD_IDENTS = 0% ! ALWAYS RETURN ZERO SYS_STATUS = SOR$END_SORT ! TERMINATE ANY PREV SORT CONTXT LONGEST_RECORD = LEN(KGB3_NAME) ! SPECIFY LENGTH OF LONGEST REC SYS_STATUS = SOR$BEGIN_SORT(KEY_BUFFER() BY REF, & LONGEST_RECORD BY REF) IF SYS_STATUS <> SS$_NORMAL THEN PRINT "GET_HELD_IDENTS ERROR FROM SOR$BEGIN_SORT" CALL LIB$STOP(SYS_STATUS BY VALUE) END IF TOTAL_IDS = 0% ! INIT TOTAL NUMBER OF IDENTS EOF_HELD = FALSE ! ASSUME NOT AT END-OF-FILE ! ----- CALCULATE SEARCH KEY ----- KGB3_HOLDER(0%) = ID_VALUE ! STORE UIC TO SEARCH FOR KGB3_HOLDER(1%) = 0% SAVE_ALT_KEY = KGB3_HOLDER_STRING ! SAVE IN TEMP STRING ! ----- LOCATE FIRST HOLDER RECORD FOR THIS IDENTIFIER ----- ! ----- RECORD ----- WHEN ERROR IN GET #CHNL_TO_USE, KEY #1% GE SAVE_ALT_KEY, REGARDLESS USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF EXIT HANDLER IF ERR <> END_OF_FILE AND & ERR <> REC_NOT_FOUND EOF_HELD = TRUE ! SET END-OF-FILE FLAG CONTINUE ! AND CONTINUE AFTER HANDLER END WHEN ! ----- FIND ALL HELD IDENTIFIERS FOR THIS HOLDER UIC ----- WHILE NOT EOF_HELD ! UNTIL END-OF-FILE REACHED: ! ----- DONE IF HOLDER UIC DOES NOT MATCH ----- IF SAVE_ALT_KEY <> KGB3_HOLDER_STRING THEN ! ----- SET END-OF-FILE FLAG ----- EOF_HELD = TRUE ITERATE ! EXIT LOOP END IF ! ----- WE FOUND A HELD IDENTIFIER RECORD ----- ! ----- INCREMENT IDENTIFIER TOTAL ----- TOTAL_IDS = TOTAL_IDS + 1% IF TOTAL_IDS >= MAX_IDENTS THEN PRINT "GET_HELD_IDENTS ERROR:" + & " TOO MANY IDENTS FOR CHNL " + & NUM1$(CHNL_TO_USE) + & ", ID VALUE OF " + NUM1$(ID_VALUE) CALL LIB$STOP(SS$_ABORT BY VALUE) END IF ID_VALUES(TOTAL_IDS) = KGB3_IDENTIFIER ! ----- READ NEXT HOLDER RECORD ----- WHEN ERROR IN GET #CHNL_TO_USE, REGARDLESS USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF EXIT HANDLER IF ERR <> END_OF_FILE AND & ERR <> REC_NOT_FOUND ! ----- SET END-OF-FILE FLAG ----- EOF_HELD = TRUE CONTINUE ! AND CONTINUE AFTER HANDLER END WHEN NEXT ! ----- END-OF-FILE REACHED WHILE READING THE RIGHTSLIST ----- ! ----- FILE ----- ! ----- CONVERT EACH LONGWORD IDENTIFIER TO A 32-CHAR UIC ----- ! ----- OR IDENTIFIER, AS APPROPRIATE ----- TEMP = 0% WHILE TEMP < TOTAL_IDS TEMP = TEMP + 1% KGB3_IDENTIFIER = ID_VALUES(TEMP) EOF_HELD = FALSE ! ASSUME NOT AT END-OF-FILE WHEN ERROR IN GET #CHNL_TO_USE, KEY #0% GE & KGB3_IDENTIFIER, REGARDLESS USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF EXIT HANDLER IF ERR <> END_OF_FILE AND & ERR <> REC_NOT_FOUND EOF_HELD = TRUE ! SET END-OF-FILE FLAG CONTINUE ! AND CONTINUE AFTER HANDLER END WHEN KGB3_NAME = NUM1$(ID_VALUES(TEMP)) IF EOF_HELD WHILE NOT EOF_HELD ! UNTIL END-OF-FILE REACHED: ! ----- DONE IF NO MATCHING ----- ! ----- IDENTIFIER/HOLDER RECORD ----- IF KGB3_IDENTIFIER <> ID_VALUES(TEMP) THEN KGB3_NAME = NUM1$(ID_VALUES(TEMP)) ! ----- SET END-OF-FILE FLAG ----- EOF_HELD = TRUE ITERATE END IF ! ----- DONE IF IDENTIFIER RECORD FOUND ----- IF KGB3_HOLDER(0%) = 0% THEN ! ----- SET END-OF-FILE FLAG ----- EOF_HELD = TRUE ITERATE END IF WHEN ERROR IN GET #CHNL_TO_USE, REGARDLESS USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF EXIT HANDLER IF ERR <> & END_OF_FILE AND & ERR <> REC_NOT_FOUND ! ----- SET END-OF-FILE FLAG ----- EOF_HELD = TRUE CONTINUE! AND CONTINUE AFTER HANDLER END WHEN NEXT ! ----- STORE THE SORT KEY FIELD ----- SYS_STATUS = SOR$RELEASE_REC(KGB3_NAME) IF SYS_STATUS <> SS$_NORMAL THEN PRINT "GET_HELD_IDENTS ERROR FROM" + & " SOR$RELEASE_REC" CALL LIB$STOP(SYS_STATUS BY VALUE) END IF NEXT UNLOCK #CHNL_TO_USE ! ----- EXTRACT AND STORE ALL DATA WHICH WAS SENT TO SORT ----- IF TOTAL_IDS = 0% THEN ! NO SORT IF NO HELD IDENTIFIERS %IF %DEBUG = 1% %THEN PRINT "GET_HELD_IDENTS DEBUG>NO HELD IDENTS" %END %IF EXIT DEF END IF TOTAL_IDS = 0% ! INIT TOTAL NUMBER SYS_STATUS = SOR$SORT_MERGE ! DO THE SORT IF SYS_STATUS <> SS$_NORMAL THEN PRINT "GET_HELD_IDENTS ERROR FROM SOR$SORT_MERGE" CALL LIB$STOP(SYS_STATUS BY VALUE) END IF WHILE SYS_STATUS = SS$_NORMAL ! ----- GET NEXT RECORD FROM SORT ----- SYS_STATUS = SOR$RETURN_REC(KGB3_NAME) ITERATE IF SYS_STATUS <> SS$_NORMAL ! ----- STORE THIS IDENTIFIER IN MEMORY ----- ! ----- INCR TOTAL NUMBER OF IDENTS ----- TOTAL_IDS = TOTAL_IDS + 1% %IF %DEBUG = 1% %THEN PRINT "GET_HELD_IDENTS DEBUG>" + & "STORE ID #" + & NUM1$(TOTAL_IDS) + "=" + TRM$(KGB3_NAME) %END %IF ! ----- STORE HELD IDENT IN MEMORY ----- HELD_IDENTS(TOTAL_IDS) = TRM$(KGB3_NAME) NEXT ! ----- TRAP END-OF-FILE ERROR WHEN READING RECORDS ----- SELECT SYS_STATUS CASE SS$_ENDOFFILE SYS_STATUS = SOR$END_SORT! TERMINATE CURRENT SORT CONTXT IF SYS_STATUS <> SS$_NORMAL THEN PRINT "GET_HELD_IDENTS ERROR FROM SOR$END_SORT" CALL LIB$STOP(SYS_STATUS BY VALUE) END IF CASE <> SS$_NORMAL PRINT "GET_HELD_IDENTS ERROR FROM SOR$RETURN_REC" CALL LIB$STOP(SYS_STATUS BY VALUE) END SELECT END DEF ! ----- INITIALIZE VAX SORT KEY INFO ----- KEY_BUFFER(0%) = 1% ! NUMBER OF KEYS WHICH FOLLOW: ! ----- DEFINE 1ST SORT KEY (KGB3_NAME) IN THE NEXT 4 WORDS ----- KEY_BUFFER(1%) = DSC$K_DTYPE_T ! TEXT DATATYPE KEY_BUFFER(2%) = 0% ! 0=ASCENDING SORT, 1=DESCENDING KEY_BUFFER(3%) = 0% ! BYTE OFFSET (0=FIRST BYTE) KEY_BUFFER(4%) = 32% ! BYTE LENGTH OF SORT FIELD ! ----- STORE DATA FOR $GETDVIW ----- DVIITEM(0%)::BUFFER_LENGTH = 4% DVIITEM(0%)::ITEM_CODE = DVI$_HOST_AVAIL DVIITEM(0%)::BUFFER_ADDRESS = LOC(HOST_AVAIL) DVIITEM(0%)::RETURN_LENGTH_ADDRESS = LOC(HOST_AVAIL_LENGTH) DVIITEM(1%)::BUFFER_LENGTH = 4% DVIITEM(1%)::ITEM_CODE = DVI$_MOUNTCNT DVIITEM(1%)::BUFFER_ADDRESS = LOC(MOUNTED) DVIITEM(1%)::RETURN_LENGTH_ADDRESS = LOC(MOUNTED_LENGTH) DVIITEM(2%)::LIST_TERMINATOR = 0% JPIITEM::BUFFER_LENGTH = 12% JPIITEM::ITEM_CODE = JPI$_USERNAME JPIITEM::BUFFER_ADDRESS = LOC(THE_USERNAME) JPIITEM::RETURN_LENGTH_ADDRESS = LOC(USERNAME_LENGTH) JPIITEM::LIST_TERMINATOR = 0% ! ----- GET JOB INFO ----- SYS_STATUS = SYS$GETJPIW(, , , JPIITEM, , , ) IF SYS_STATUS <> SS$_NORMAL THEN PRINT "Error while getting JPI" CALL LIB$STOP(SYS_STATUS BY VALUE) END IF ! ----- OPEN DATA FILE, PROMPT FOR FILES TO BE COMPARED, AND ----- ! ----- THEN OPEN THEM ----- EOF_FLAG = FALSE WHEN ERROR IN OPEN "TOOLS:RIGHTSLIST_SPECS.DAT" FOR INPUT & AS FILE #99%, SEQUENTIAL, ACCESS READ, & ALLOW READ, RECORDTYPE ANY USE IF ERR = FILE_NOT_FOUND THEN PRINT "Error - Can't find any existing" + & " TOOLS:RIGHTSLIST_SPECS.DAT file" + BEL EOF_FLAG = TRUE CONTINUE END IF IF ERR = PROTECTION_VIOLATION THEN PRINT "You do not have the privilege to open" + & " TOOLS:RIGHTSLIST_SPECS.DAT file" + BEL EOF_FLAG = TRUE CONTINUE END IF IF ERR = CANNOT_OPEN_FILE THEN PRINT "Error - Can't open any existing" + & " TOOLS:RIGHTSLIST_SPECS.DAT file" + BEL PRINT "VMS error status value:"; VMSSTATUS EOF_FLAG = TRUE CONTINUE END IF PRINT "VMS error status value:"; VMSSTATUS EXIT HANDLER END WHEN CALL SYS$EXIT(ERROR_WITH_NO_PUTMSG BY VALUE) IF EOF_FLAG TEMP = READ_ALL_RIGHTSLIST_SPECS ! READ IN ALL FILE SPECS CLOSE #99% IF RIGHTSLIST_COUNTER = 0% THEN PRINT PRINT "Error - No file specs found in" + & " TOOLS:RIGHTSLIST_SPECS.DAT" + BEL CALL SYS$EXIT(ERROR_WITH_NO_PUTMSG BY VALUE) END IF IF RIGHTSLIST_COUNTER < 2% THEN PRINT PRINT "Error - Not enough file specs found in" + & " TOOLS:RIGHTSLIST_SPECS.DAT" + BEL CALL SYS$EXIT(ERROR_WITH_NO_PUTMSG BY VALUE) END IF ! ----- SEE IF EACH RIGHTSLIST DISK IS AVAILABLE ----- I_O_CHNL = 0% TEMP_LONG = RIGHTSLIST_COUNTER WHILE I_O_CHNL < RIGHTSLIST_COUNTER I_O_CHNL = I_O_CHNL + 1% TEMP_STRING = RIGHTSLIST_SPECS(I_O_CHNL) ITERATE IF TEMP_STRING = "" IF SYSTEM_DISK_UNAVAILABLE THEN ! ----- EXTRACT NODE NAME ----- TEMP_STRING = RIGHTSLIST_SPECS(I_O_CHNL) TEMP_STRING = LEFT(TEMP_STRING, & POS(TEMP_STRING, ":", 1%) - 1%) TEMP_STRING = RIGHT(TEMP_STRING, 6%) & IF LEFT(TEMP_STRING, 5%) = "DISK$" PRINT "Warning: Rightslist on node " + & TEMP_STRING + " is unavailable" + BEL RIGHTSLIST_SPECS(I_O_CHNL) = "" TEMP_LONG = TEMP_LONG - 1% END IF NEXT IF TEMP_LONG = 0% THEN PRINT PRINT "Error - No rightslist filespecs can be accessed!" + BEL CALL SYS$EXIT(ERROR_WITH_NO_PUTMSG BY VALUE) END IF IF TEMP_LONG < 2% THEN PRINT PRINT "Error - Not enough valid rightslist file" + & "specs found!" + BEL CALL SYS$EXIT(ERROR_WITH_NO_PUTMSG BY VALUE) END IF PRINT PRINT "COMPARE_RIGHTSLISTS - Rightslist Comparison Program" PRINT VALID_ENTRY = FALSE WHILE NOT VALID_ENTRY RECORD_FOUND = TRUE PRINT I_O_CHNL = 0% ! INIT I/O CHANNEL COUNTER WHILE I_O_CHNL < RIGHTSLIST_COUNTER I_O_CHNL = I_O_CHNL + 1% ITERATE IF RIGHTSLIST_SPECS(I_O_CHNL) = "" PRINT NUM1$(I_O_CHNL) + ") " + & RIGHTSLIST_SPECS(I_O_CHNL) NEXT PRINT PRINT "Enter the digits (as a single 2-digit number)" + & " of the two filespecs" PRINT "to be compared" WHEN ERROR IN LINPUT " (or press Control/Z to exit program) "; & TEMP_STRING USE RECORD_FOUND = FALSE CONTINUE END WHEN IF NOT RECORD_FOUND THEN PRINT PRINT "Aborted..." CALL SYS$EXIT(1% BY VALUE) END IF ! ----- UPPERCASE AND DISCARD ANY GARBAGE CHARS ----- TEMP_STRING = EDIT$(TEMP_STRING, 38%) IF LEN(TEMP_STRING) <> 2% THEN PRINT PRINT "Error - Invalid response, try again" + BEL PRINT ITERATE END IF ! ----- VALIDATE RIGHTSLIST FILESPECS ----- FIRST_CHNL = 0% SECOND_CHNL = 0% I_O_CHNL = 0% ! INIT I/O CHANNEL COUNTER WHILE I_O_CHNL < RIGHTSLIST_COUNTER I_O_CHNL = I_O_CHNL + 1% ITERATE IF RIGHTSLIST_SPECS(I_O_CHNL) = "" IF LEFT(TEMP_STRING, 1%) = NUM1$(I_O_CHNL) THEN FIRST_CHNL = I_O_CHNL END IF IF RIGHT(TEMP_STRING, 2%) = NUM1$(I_O_CHNL) THEN SECOND_CHNL = I_O_CHNL END IF NEXT IF FIRST_CHNL = 0% OR SECOND_CHNL = 0% OR FIRST_CHNL = & SECOND_CHNL THEN PRINT PRINT "Error - Invalid response, try again" + BEL PRINT ITERATE END IF ! ----- TRY TO OPEN THE FIRST SELECTED RIGHTSLIST FILE ----- EOF_FLAG = FALSE TEMP_STRING = RIGHTSLIST_SPECS(FIRST_CHNL) WHEN ERROR IN OPEN TEMP_STRING FOR INPUT AS FILE #1%, & RECORDSIZE 64%, & ACCESS READ, & ALLOW MODIFY, & INDEXED VARIABLE, & MAP RIGHT1, & RECORDTYPE ANY OPEN TEMP_STRING FOR INPUT AS FILE #3%, & RECORDSIZE 64%, & ACCESS READ, & ALLOW MODIFY, & INDEXED VARIABLE, & MAP RIGHT3, & RECORDTYPE ANY, & CONNECT 1 ! CONNECT TO STREAM #1 USE IF ERR = ILLEGAL_USAGE_FOR_DEVICE THEN ! ----- EXTRACT NODE NAME ----- TEMP_STRING = RIGHTSLIST_SPECS(FIRST_CHNL) TEMP_STRING = LEFT(TEMP_STRING, & POS(TEMP_STRING, ":", 1%) - 1%) TEMP_STRING = RIGHT(TEMP_STRING, 6%) & IF LEFT(TEMP_STRING, 5%) = "DISK$" PRINT PRINT "Error - Rightslist on node " + & TEMP_STRING + " is unavailable" + BEL EOF_FLAG = TRUE CONTINUE END IF IF ERR = FILE_NOT_FOUND THEN PRINT PRINT "Error - Can't find " + TEMP_STRING + BEL EOF_FLAG = TRUE CONTINUE END IF IF ERR = PROTECTION_VIOLATION THEN PRINT PRINT "You do not have the privilege" + & " to open " + TEMP_STRING + BEL EOF_FLAG = TRUE CONTINUE END IF IF ERR = CANNOT_OPEN_FILE THEN PRINT PRINT "Error - Can't open " + TEMP_STRING + BEL EOF_FLAG = TRUE CONTINUE END IF PRINT "VMS error status value:"; VMSSTATUS EXIT HANDLER END WHEN CALL SYS$EXIT(ERROR_WITH_NO_PUTMSG BY VALUE) IF EOF_FLAG ! ----- TRY TO OPEN THE SECOND SELECTED RIGHTSLIST FILE ----- TEMP_STRING = RIGHTSLIST_SPECS(SECOND_CHNL) WHEN ERROR IN OPEN TEMP_STRING FOR INPUT AS FILE #2%, & RECORDSIZE 64%, & ACCESS READ, & ALLOW MODIFY, & INDEXED VARIABLE, & MAP RIGHT2, & RECORDTYPE ANY OPEN TEMP_STRING FOR INPUT AS FILE #4%, & RECORDSIZE 64%, & ACCESS READ, & ALLOW MODIFY, & INDEXED VARIABLE, & MAP RIGHT3, & RECORDTYPE ANY, & CONNECT 2 ! CONNECT TO STREAM #2 USE IF ERR = ILLEGAL_USAGE_FOR_DEVICE THEN ! ----- EXTRACT NODE NAME ----- TEMP_STRING = RIGHTSLIST_SPECS(SECOND_CHNL) TEMP_STRING = LEFT(TEMP_STRING, & POS(TEMP_STRING, ":", 1%) - 1%) TEMP_STRING = RIGHT(TEMP_STRING, 6%) & IF LEFT(TEMP_STRING, 5%) = "DISK$" PRINT PRINT "Error - Rightslist on node " + & TEMP_STRING + " is unavailable" + BEL EOF_FLAG = TRUE CONTINUE END IF IF ERR = FILE_NOT_FOUND THEN PRINT PRINT "Error - Can't find " + TEMP_STRING + BEL EOF_FLAG = TRUE CONTINUE END IF IF ERR = PROTECTION_VIOLATION THEN PRINT PRINT "You do not have the privilege" + & " to open " + TEMP_STRING + BEL EOF_FLAG = TRUE CONTINUE END IF IF ERR = CANNOT_OPEN_FILE THEN PRINT PRINT "Error - Can't open " + TEMP_STRING + BEL EOF_FLAG = TRUE CONTINUE END IF PRINT "VMS error status value:"; VMSSTATUS EXIT HANDLER END WHEN CALL SYS$EXIT(ERROR_WITH_NO_PUTMSG BY VALUE) IF EOF_FLAG VALID_ENTRY = TRUE NEXT VALID_ENTRY = FALSE WHILE NOT VALID_ENTRY RECORD_FOUND = TRUE PRINT PRINT "Do you want to print ONLY matching identifier" + & " NAMES which have non-matching" PRINT "identifier VALUES?" WHEN ERROR IN LINPUT " (Enter Y or N ) "; & TEMP_STRING USE RECORD_FOUND = FALSE CONTINUE END WHEN IF NOT RECORD_FOUND THEN PRINT PRINT "Aborted..." CALL SYS$EXIT(1% BY VALUE) END IF ! ----- UPPERCASE AND DISCARD ANY GARBAGE CHARS ----- TEMP_STRING = EDIT$(TEMP_STRING, 38%) TEMP_STRING = "N" IF TEMP_STRING = "" SELECT TEMP_STRING CASE "Y" ONLY_MATCHING_NON_MATCHES = TRUE CASE "N" ONLY_MATCHING_NON_MATCHES = FALSE CASE ELSE PRINT PRINT "Error - Invalid response, try again" + BEL PRINT ITERATE END SELECT VALID_ENTRY = TRUE NEXT IF ONLY_MATCHING_NON_MATCHES THEN SKIP_SINGLE_NODE_UIC_FORMAT = FALSE VALID_ENTRY = TRUE ELSE VALID_ENTRY = FALSE END IF WHILE NOT VALID_ENTRY RECORD_FOUND = TRUE PRINT PRINT "Do you want to skip UIC-format identifiers" + & " which only exist on one node?" WHEN ERROR IN LINPUT " (Enter Y or N ) "; & TEMP_STRING USE RECORD_FOUND = FALSE CONTINUE END WHEN IF NOT RECORD_FOUND THEN PRINT PRINT "Aborted..." CALL SYS$EXIT(1% BY VALUE) END IF ! ----- UPPERCASE AND DISCARD ANY GARBAGE CHARS ----- TEMP_STRING = EDIT$(TEMP_STRING, 38%) TEMP_STRING = "Y" IF TEMP_STRING = "" SELECT TEMP_STRING CASE "Y" SKIP_SINGLE_NODE_UIC_FORMAT = TRUE CASE "N" SKIP_SINGLE_NODE_UIC_FORMAT = FALSE CASE ELSE PRINT PRINT "Error - Invalid response, try again" + BEL PRINT ITERATE END SELECT VALID_ENTRY = TRUE NEXT VALID_ENTRY = FALSE WHILE NOT VALID_ENTRY RECORD_FOUND = TRUE PRINT PRINT "Do you want to compare ONLY the holder" + & " identifier values?" PRINT " (i.e. Skip the comparison of all held identifiers)" WHEN ERROR IN LINPUT " (Enter Y or N ) "; & TEMP_STRING USE RECORD_FOUND = FALSE CONTINUE END WHEN IF NOT RECORD_FOUND THEN PRINT PRINT "Aborted..." CALL SYS$EXIT(1% BY VALUE) END IF ! ----- UPPERCASE AND DISCARD ANY GARBAGE CHARS ----- TEMP_STRING = EDIT$(TEMP_STRING, 38%) TEMP_STRING = "N" IF TEMP_STRING = "" SELECT TEMP_STRING CASE "Y" COMPARE_ONLY_HOLDERS = TRUE CASE "N" COMPARE_ONLY_HOLDERS = FALSE CASE ELSE PRINT PRINT "Error - Invalid response, try again" + BEL PRINT ITERATE END SELECT VALID_ENTRY = TRUE NEXT OPEN "COMPARE_RIGHTSLISTS.LIS" FOR OUTPUT AS FILE #10%, SEQUENTIAL PAGE_COUNTER = 1% PRINT #10%, "Page " + NUM1$(PAGE_COUNTER); & TAB(26%); "Rightslist Comparison Report"; & TAB(60%); DATE$(0%) + " " + TIME$(0%) PRINT #10% PRINT #10%, "Comparing " + RIGHTSLIST_SPECS(FIRST_CHNL) PRINT #10%, "Against " + RIGHTSLIST_SPECS(SECOND_CHNL) PRINT #10% IF ONLY_MATCHING_NON_MATCHES THEN PRINT #10%, "Name"; TAB(40%); & RIGHTSLIST_NODES(FIRST_CHNL) + "'s value"; & TAB(60%); RIGHTSLIST_NODES(SECOND_CHNL) + & "'s value" ELSE PRINT #10%, "Name"; TAB(40%); "Only in file 1"; & TAB(60%); "Only in file 2" END IF PRINT #10%, "--------------------------------"; & TAB(40%); "-------------------"; & TAB(60%); "-------------------" LINE_COUNTER = 7% ! ----- READ AND COMPARE THE TWO FILES ----- ANY_DIFFS = FALSE ! ASSUME NO FILE DIFFERENCES FIRST_EOF = FALSE ! INIT EOF FLAG FOR FIRST FILE SECOND_EOF = FALSE ! INIT EOF FLAG FOR SECOND FILE GET_FIRST = TRUE ! SET FLAG TO READ FIRST FILE GET_SECOND = TRUE ! SET FLAG TO READ SECOND FILE WHEN ERROR IN RESET #1%, KEY #2% USE GET_FIRST = FALSE ! SET FLAG TO NOT READ 1ST FILE FIRST_EOF = TRUE ! SET END OF FILE FLAG CONTINUE ! CONTINUE WITH NEXT STATEMENT END WHEN WHEN ERROR IN RESET #2%, KEY #2% USE GET_SECOND = FALSE ! SET FLAG TO NOT READ 2ND FILE SECOND_EOF = TRUE ! SET END OF FILE FLAG CONTINUE ! CONTINUE WITH NEXT STATEMENT END WHEN ! ----- PROCESS DATA UNTIL EOF FLAG SET FOR BOTH FILES ----- WHILE NOT FIRST_EOF AND NOT SECOND_EOF IF GET_FIRST THEN GET_FIRST = FALSE ! SET TO NOT GET FIRST FILE WHEN ERROR IN GET #1%, REGARDLESS USE EXIT HANDLER IF ERR <> END_OF_FILE FIRST_EOF = TRUE! SET END OF FILE FLAG CONTINUE ! CONTINUE WITH NEXT STATEMENT END WHEN ! ----- SEE IF DONE WITH BOTH FILES ----- ITERATE IF FIRST_EOF AND SECOND_EOF ! ----- SKIP MAINTENANCE RECORD ----- IF KGB1_IDENTIFIER = 0% THEN GET_FIRST = TRUE! SET FLAG TO READ FIRST FILE ITERATE END IF END IF IF GET_SECOND THEN GET_SECOND = FALSE ! SET TO NOT GET SECOND FILE WHEN ERROR IN GET #2%, REGARDLESS USE EXIT HANDLER IF ERR <> END_OF_FILE SECOND_EOF = TRUE! SET END OF FILE FLAG CONTINUE ! CONTINUE WITH NEXT STATEMENT END WHEN ! ----- SEE IF DONE WITH BOTH FILES ----- ITERATE IF FIRST_EOF AND SECOND_EOF ! ----- SKIP MAINTENANCE RECORD ----- IF KGB2_IDENTIFIER = 0% THEN GET_SECOND =TRUE! SET FLAG TO READ SECOND FILE ITERATE END IF END IF ! ----- COMPARE THE (POSSIBLY) TWO IDENTIFIERS ----- IF FIRST_EOF THEN ! ----- IDENTIFIER EXISTS ONLY IN THE SECOND FILE ----- ! ----- SEE IF UIC FORMAT IDENTIFIERS ARE TO BE ----- ! ----- SKIPPED ----- IF NOT SKIP_SINGLE_NODE_UIC_FORMAT OR & KGB2_IDENTIFIER < 0% THEN IF NOT ONLY_MATCHING_NON_MATCHES THEN TEMP = CHECK_FOR_HEADINGS PRINT #10%, KGB2_NAME; TAB(67%); "*" LINE_COUNTER = LINE_COUNTER + 1% END IF END IF GET_SECOND = TRUE ! SET TO GET SECOND FILE ITERATE END IF IF SECOND_EOF THEN ! ----- IDENTIFIER EXISTS ONLY IN THE FIRST FILE ----- ! ----- SEE IF UIC FORMAT IDENTIFIERS ARE TO BE ----- ! ----- SKIPPED ----- IF NOT SKIP_SINGLE_NODE_UIC_FORMAT OR & KGB1_IDENTIFIER < 0% THEN IF NOT ONLY_MATCHING_NON_MATCHES THEN TEMP = CHECK_FOR_HEADINGS PRINT #10%, KGB1_NAME; TAB(47%); "*" LINE_COUNTER = LINE_COUNTER + 1% END IF END IF GET_FIRST = TRUE ! SET TO GET FIRST FILE ITERATE END IF IF KGB1_NAME = KGB2_NAME THEN ! ----- IDENTIFIER NAME EXISTS IN BOTH FILES ----- GET_FIRST = TRUE ! SET TO GET FIRST FILE GET_SECOND = TRUE ! SET TO GET SECOND FILE ! ----- SKIP IF THE IDENTIFIER VALUES DO NOT MATCH ----- IF KGB1_IDENTIFIER <> KGB2_IDENTIFIER THEN ANY_DIFFS = TRUE! FILES ARE DIFFERENT TEMP = CHECK_FOR_HEADINGS PRINT #10%, KGB1_NAME; & TAB(40%); & TO_VALUE(KGB1_IDENTIFIER, 1%); & TAB(60%); TO_VALUE(KGB2_IDENTIFIER, 2%) LINE_COUNTER = LINE_COUNTER + 1% END IF ITERATE IF COMPARE_ONLY_HOLDERS SAVE_KGB1_IDENTIFIER = KGB1_IDENTIFIER SAVE_KGB1_NAME = KGB1_NAME SAVE_KGB2_IDENTIFIER = KGB2_IDENTIFIER SAVE_KGB2_NAME = KGB2_NAME ! ----- GET LIST OF HELD IDENTIFIERS FOR FILE 1 ----- ! ----- DONE IF WE DID NOT FIND AN IDENTIFIER ----- ! ----- RECORD OR THE IDENTIFIER IS NOT IN A UIC ----- ! ----- FORMAT ----- IF KGB1_IDENTIFIER <= 0% OR KGB1_HOLDER(0%) <> 0% THEN %IF %DEBUG = 1% %THEN PRINT "DEBUG>KGB1_IDENTIFIER IS NON-UIC" %END %IF TOTAL_IDS = 0% ELSE TEMP = GET_HELD_IDENTS(KGB1_IDENTIFIER, 3%) END IF SAVE_CTR = 0% WHILE SAVE_CTR < TOTAL_IDS SAVE_CTR = SAVE_CTR + 1% SAVE_HELD_IDENTS(SAVE_CTR) = & HELD_IDENTS(SAVE_CTR) NEXT ! ----- GET LIST OF HELD IDENTIFIERS FOR FILE 2 ----- ! ----- DONE IF WE DID NOT FIND AN IDENTIFIER ----- ! ----- RECORD OR THE IDENTIFIER IS NOT IN A UIC ----- ! ----- FORMAT ----- IF KGB2_IDENTIFIER <= 0% OR KGB2_HOLDER(0%) <> 0% THEN %IF %DEBUG = 1% %THEN PRINT "DEBUG>KGB2_IDENTIFIER IS NON-UIC" %END %IF TOTAL_IDS = 0% ELSE TEMP = GET_HELD_IDENTS(KGB2_IDENTIFIER, 4%) END IF KGB1_IDENTIFIER = SAVE_KGB1_IDENTIFIER KGB1_NAME = SAVE_KGB1_NAME KGB2_IDENTIFIER = SAVE_KGB2_IDENTIFIER KGB2_NAME = SAVE_KGB2_NAME ! ----- PRINT ANY NON-MATCHING HELD IDENTIFIERS ----- FIRST_HELD_INDEX = 0% SECOND_HELD_INDEX = 0% GET_FIRST_HELD = TRUE GET_SECOND_HELD = TRUE WHILE FIRST_HELD_INDEX <> 999% OR & SECOND_HELD_INDEX <> 999% IF GET_FIRST_HELD THEN ! ----- SET TO NOT GET FIRST HELD ----- ! ----- IDENT ----- GET_FIRST_HELD = FALSE FIRST_HELD_INDEX = FIRST_HELD_INDEX + 1% IF FIRST_HELD_INDEX <= SAVE_CTR THEN FIRST_NAME = & SAVE_HELD_IDENTS& (FIRST_HELD_INDEX) ELSE FIRST_HELD_INDEX = 999% ! ----- SEE IF DONE WITH ----- ! ----- BOTH LISTS OF ----- ! ----- IDENTIFIERS ----- IF SECOND_HELD_INDEX = 999% THEN ITERATE END IF END IF END IF IF GET_SECOND_HELD THEN ! ----- SET TO NOT GET SECOND HELD ----- ! ----- IDENT ----- GET_SECOND_HELD = FALSE SECOND_HELD_INDEX = & SECOND_HELD_INDEX + 1% IF SECOND_HELD_INDEX <= TOTAL_IDS THEN SECOND_NAME = & HELD_IDENTS( & SECOND_HELD_INDEX) ELSE SECOND_HELD_INDEX = 999% ! ----- SEE IF DONE WITH ----- ! ----- BOTH LISTS OF ----- ! ----- IDENTIFIERS ----- IF FIRST_HELD_INDEX = 999% THEN ITERATE END IF END IF END IF ! ----- COMPARE THE (POSSIBLY) TWO HELD ----- ! ----- IDENTIFIERS ----- IF FIRST_HELD_INDEX = 999% THEN ! ----- HELD IDENTIFIER EXISTS ----- ! ----- ONLY IN THE SECOND FILE ----- TEMP = CHECK_FOR_HEADINGS PRINT #10%, KGB2_NAME; & TAB(67%); "Held: " + SECOND_NAME LINE_COUNTER = LINE_COUNTER + 1% ! ----- SET TO GET SECOND HELD ID ----- GET_SECOND_HELD = TRUE ! ----- FILES ARE DIFFERENT ----- ANY_DIFFS = TRUE ITERATE END IF IF SECOND_HELD_INDEX = 999% THEN ! ----- HELD IDENTIFIER EXISTS ----- ! ----- ONLY IN THE FIRST FILE ----- TEMP = CHECK_FOR_HEADINGS PRINT #10%, KGB1_NAME; TAB(47%);& "Held: " + FIRST_NAME LINE_COUNTER = LINE_COUNTER + 1% ! ----- SET TO GET FIRST HELD ID ----- GET_FIRST_HELD = TRUE ! ----- FILES ARE DIFFERENT ----- ANY_DIFFS = TRUE ITERATE END IF ! ----- SOME IDENTIFIER NAME EXISTS IN ----- ! ----- BOTH FILES ----- IF FIRST_NAME = SECOND_NAME THEN GET_FIRST_HELD = TRUE GET_SECOND_HELD = TRUE ITERATE END IF TEMP = CHECK_FOR_HEADINGS IF FIRST_NAME < SECOND_NAME THEN ! ----- HELD IDENTIFIER EXISTS ----- ! ----- ONLY IN THE FIRST FILE ----- GET_FIRST_HELD = TRUE PRINT #10%, KGB1_NAME; TAB(47%);& "Held: " + FIRST_NAME ELSE ! ----- HELD IDENTIFIER EXISTS ----- ! ----- ONLY IN THE SECOND FILE ----- GET_SECOND_HELD = TRUE PRINT #10%, KGB2_NAME; TAB(67%);& "Held: " + SECOND_NAME END IF LINE_COUNTER = LINE_COUNTER + 1% ! ----- FILES ARE DIFFERENT ----- ANY_DIFFS = TRUE NEXT ITERATE END IF IF KGB1_NAME < KGB2_NAME THEN ! ----- IDENTIFIER EXISTS ONLY IN THE FIRST FILE ----- GET_FIRST = TRUE ! SET TO GET FIRST FILE ! ----- SEE IF UIC FORMAT IDENTIFIERS ARE TO BE ----- ! ----- SKIPPED ----- IF NOT SKIP_SINGLE_NODE_UIC_FORMAT OR & KGB1_IDENTIFIER < 0% THEN IF NOT ONLY_MATCHING_NON_MATCHES THEN TEMP = CHECK_FOR_HEADINGS PRINT #10%, KGB1_NAME; TAB(47%); "*" LINE_COUNTER = LINE_COUNTER + 1% END IF END IF ELSE ! ----- IDENTIFIER EXISTS ONLY IN THE SECOND FILE ----- GET_SECOND = TRUE ! SET TO GET SECOND FILE ! ----- SEE IF UIC FORMAT IDENTIFIERS ARE TO BE ----- ! ----- SKIPPED ----- IF NOT SKIP_SINGLE_NODE_UIC_FORMAT OR & KGB2_IDENTIFIER < 0% THEN IF NOT ONLY_MATCHING_NON_MATCHES THEN TEMP = CHECK_FOR_HEADINGS PRINT #10%, KGB2_NAME; TAB(67%); "*" LINE_COUNTER = LINE_COUNTER + 1% END IF END IF END IF NEXT CLOSE #1%, 2%, 3%, 4%, 10% ! CLOSE ALL OPEN FILES PRINT PRINT "Done - Created COMPARE_RIGHTSLISTS.LIS..." IF ANY_DIFFS THEN ! ERROR EXIT IF FILES DIFFERENT PRINT " **** FILES ARE DIFFERENT ****" + BEL CALL SYS$EXIT(WARNING_WITH_NO_PUTMSG BY VALUE) END IF END