*DECK     DB$VEMD 
USETEXT CDCSCTX 
      PROC DB$VEMD; 
      BEGIN 
 #
* *   DB$VEMD - FIND VERSIONS DATA ON THE MD     PAGE  1
* *   A W ALLEN                                  DATE  01/30/81 
* 
* DC  PURPOSE 
* 
*     CONTAINS ALL THE ROUTINES THAT ARE USED TO FIND DATABASE VERSION
*     DATA ON THE MASTER DIRECTORY. 
* 
*     EMBEDDED ROUTINES--THESE ROUTINES ARE ALL EXTERNALLY CALLABLE.
* 
# 
      XDEF PROC DB$VEFI;           # GET MODEL FIT FOR AN AREA         #
      XDEF PROC DB$VEPF;           # GET PF INFO FOR VERSION OF AN AREA#
      XDEF PROC DB$VEPN;           # GET PRIMARY VERSION NAME          #
      XDEF PROC DB$VERL;           # VERSION NAME LOOK-UP              #
# 
* 
* DC  DESCRIPTION 
* 
*     THESE ROUTINES ARE USED TO FIND VERSION NAME, PRIMARY VERSION 
*     NAME, VERSION PERMANENT FILE INFORMATION AND MODEL FIT FROM THE 
*     MASTER DIRECTORY FILE.  THE ROUTINES MAY BE CALLED AS FOLLOWS-- 
* 
*     DB$VERL    FIND VERSION NAME IN VERSION DIRECTORY TABLE.
*                INPUTS  - VERSION NAME 
*                OUTPUTS - VERSION SUBSCRIPT
* 
*     DB$VEPN    FIND PRIMARY VERSION NAME IN VERSION INFORMATION TABLE.
*                INPUTS  - VERSION SUBSCRIPT (FROM DB$VERL) 
*                          AREA ID
*                OUTPUTS - PRIMARY VERSION NAME 
*                          LOCATION OF PF INFO IN MD
* 
*     DB$VEPF    READ PERMANENT FILE INFORMATION FROM THE MD. 
*                INPUTS  - LOCATION OF PF INFO IN MD (FROM DB$VEPN) 
*                          WORKING STORAGE ADDRESS FOR PF INFO
*                OUTPUTS - PF INFO IS IN CMM AT WSA 
* 
*     DB$VEFI    READ MODEL FIT FROM MD.
*                INPUTS  - AREA ID
*                          WORKING STORAGE ADDRESS FOR MODEL FIT
*                OUTPUTS - MODEL FIT IS IN CMM AT WSA 
* 
 #
      CONTROL EJECT;
      PROC DB$VEFI(ARID,WSA); 
      BEGIN 
 #
* *   DB$VEMD                                    PAGE  1
* *   DB$VEFI--GET MODEL FIT FOR AN AREA
* *   A W ALLEN                                  DATE  01/30/81 
* 
* DC  PURPOSE 
* 
*     READ MODEL FIT FROM MASTER DIRECTORY. 
* 
* DC  ENTRY CONDITIONS
* 
*     PARAMETERS
* 
# 
      ITEM ARID U;                 # AREA ID (INPUT)                   #
      ARRAY WSA;;                  # CMM BLOCK FOR MODEL FIT (INPUT)   #
# 
*     ASSUMPTIONS 
* 
*     SALX INDEX IS SET.
*     CMM BLOCK IS ALLOCATED AT WSA.
* 
* DC  EXIT CONDITIONS 
* 
*     NORMAL EXIT--MODEL FIT IS READ INTO MEMORY
* 
*     ABNORMAL EXIT--VIA DB$MDER FOR I/O ERRORS ON THE MD.
* 
* DC  CALLING ROUTINES
* 
*     DB$ACAI                      ATTACH AREA AND INDEX FILES FOR
*                                  SYSTEM RECOVERY
*     DB$ADAX                      ATTACH DATABASE AND INDEX FILES. 
*     DB$ARAT                      RECOVER/RESTORE ATTACH PROCESSOR.
* 
* DC  CALLED ROUTINES 
* 
# 
      XREF PROC DB$FLOP;           # GENERATE A FLOW POINT             #
      XREF PROC DB$MDER;           # MASTER DIRECTORY ERROR ROUTINE    #
      XREF PROC DB$WGET;           # WORD ADDRESSABLE READ             #
# 
* DC  NON-LOCAL VARIABLES 
# 
      XREF ARRAY DB$FTMD;;         # MASTER DIRECTORY FIT              #
# 
* DC  DESCRIPTION 
* 
*     DETERMINE WA OF AREA INFORMATION TABLE. 
*     ADD OFFSET TO GET TO MODEL FIT. 
*     READ THE MODEL FIT INTO WSA.
* 
 #
  
  
#     S T A R T   O F   D B $ V E F I   E X E C U T A B L E   C O D E  #
  
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("VEFI   ");        # GENERATE A FLOW POINT.            #
      CONTROL ENDIF;
  
      DB$WGET(DB$FTMD,             # MASTER DIRECTORY FIT              #
              WSA,                 # CMM ADDRESS FOR MODEL FIT         #
              DFFITSIZE,           # WORDS TO READ = FIT LENGTH        #
              SASCWAAD[SALX] + SASCADSZ[SALX] 
                + (ARID - 1)*DFMDAIEN 
                + DFMDPITEN,       # WORD ADDRESS OF MODEL FIT IN MD   #
              DB$MDER);            # ADDRESS OF ERROR ROUTINE          #
      RETURN; 
      END                          # END OF DB$VEFI                    #
      CONTROL EJECT;
      PROC DB$VEPF(PFOFF,WSA);
      BEGIN 
 #
* *   DB$VEMD                                    PAGE  1
* *   DB$VEPF--GET PF INFO FOR VERSION OF AN AREA 
* *   A W ALLEN                                  DATE  01/30/81 
* 
* DC  PURPOSE 
* 
*     READ PERMANENT FILE INFORMATION TABLE FOR A VERSION OF AN AREA
*     FROM MASTER DIRECTORY.
* 
* DC  ENTRY CONDITIONS
* 
*     PARAMETERS
* 
# 
      ITEM PFOFF  U;               # OFFSET OF THIS PERMANENT FILE     #
                                   # ENTRY FROM THE START OF THE       #
                                   # PERMANENT FILE INFORMATION TABLE  #
                                   # IN THE MASTER DIRECTORY.  (INPUT) #
      ARRAY WSA;;                  # CMM BLOCK FOR PF INFORMATION.     #
                                   # (INPUT)                           #
# 
* 
*     ASSUMPTIONS 
* 
*     SALX INDEX IS SET.
*     CMM BLOCK IS ALLOCATED AT WSA.
* 
* DC  EXIT CONDITIONS 
* 
*     NORMAL EXIT--PF INFO IS READ INTO MEMORY
* 
*     ABNORMAL EXIT--VIA DB$MDER FOR I/O ERRORS ON THE MD.
* 
* DC  CALLING ROUTINES
* 
*     DBQRFA                       APPLY QRF TO A DATABASE
*                                  (INTERNAL PROC ATTACHAREA) 
*     DB$ACAI                      ATTACH AREA AND INDEX FILES FOR
*                                  SYSTEM RECOVERY
*     DB$ADAX                      ATTACH DATABASE AND INDEX FILES
*     DB$ARAT                      RECOVER/RESTORE ATTACH PROCESSOR 
* 
* DC  CALLED ROUTINES 
* 
# 
      XREF PROC DB$FLOP;           # GENERATE A FLOW POINT             #
      XREF PROC DB$MDER;           # MASTER DIRECTORY ERROR ROUTINE    #
      XREF PROC DB$WGET;           # WORD ADDRESSABLE READ             #
# 
* 
* DC  NON-LOCAL VARIABLES 
# 
      XREF ARRAY DB$FTMD;;         # MASTER DIRECTORY FIT              #
# 
* 
* DC  DESCRIPTION 
* 
*     CALCULATE WORD ADDRESS OF PERMANENT FILE INFORMATION AND READ 
*     MASTER DIRECTORY. 
* 
 #
  
#     S T A R T   O F   D B $ V E P F   E X E C U T A B L E   C O D E  #
  
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("VEPF   ");        # GENERATE A FLOW POINT.            #
      CONTROL ENDIF;
  
      DB$WGET(DB$FTMD,             # MASTER DIRECTORY FIT              #
              WSA,                 # CMM ADDRESS FOR PF INFORMATION    #
              DFMDPITEN,           # WORDS TO READ = PIT ENTRY LENGTH  #
              SASCWAPIT[SALX] + PFOFF,   # WORD ADDRESS OF PIT ENTRY   #
              DB$MDER);            # ADDRESS OF ERROR ROUTINE          #
      RETURN; 
      END                          # END OF DB$VEPF                    #
      CONTROL EJECT;
      PROC DB$VEPN(VERSUB,ARID,PVENAM,PFOFF); 
      BEGIN 
 #
* *   DB$VEMD                                    PAGE  1
* *   DB$VEPN--GET PRIMARY VERSION NAME 
* *   A W ALLEN                                  DATE  01/30/81 
* 
* DC  PURPOSE 
* 
*     READ THE MASTER DIRECTORY VERSION INFORMATION TABLE TO FIND 
*     PRIMARY VERSION NAME AND PERMANENT FILE OFFSET. 
* 
* DC  ENTRY CONDITIONS
* 
*     PARAMETERS
* 
# 
      ITEM VERSUB      U;          # VERSION SUBSCRIPT (INPUT)         #
      ITEM ARID        U;          # AREA ID (INPUT)                   #
      ITEM PVENAM  C(07);          # PRIMARY VERSION NAME (OUTPUT)     #
      ITEM PFOFF       U;          # OFFSET OF PF INFO FROM START OF   #
                                   # PF INFORMATION TABLE IN MASTER    #
                                   # DIRECTORY (OUTPUT).               #
# 
* 
*     ASSUMPTIONS 
* 
*     SALX INDEX IS SET.
*     VERSUB IS THE SUBSCRIPT OF A VALID VERSION. 
*       (FIRST VERSION HAS A SUBSCRIPT OF ONE)
* 
* 
* DC  EXIT CONDITIONS 
* 
*     NORMAL EXIT--PVENAM AND PFOFF ARE SET.
* 
*     ABNORMAL EXIT--VIA DB$MDER FOR I/O ERRORS ON THE MD.
* 
* DC  CALLING ROUTINES
* 
*     DBQRFA                       APPLY QRF TO A DATABASE
*     DB$ACAI                      ATTACH AREA AND INDEX FILES FOR
*                                  SYSTEM RECOVERY
*     DB$ADAX                      ATTACH DATABASE AND INDEX FILES
*     DB$RPUT                      WRITE SELECT FILE RECORD 
*                                  (RECOVER/RESTORE)
* 
* DC  CALLED ROUTINES 
* 
# 
      XREF PROC DB$FLOP;           # GENERATE A FLOW POINT             #
      XREF PROC DB$MDER;           # MASTER DIRECTORY ERROR ROUTINE    #
      XREF PROC DB$WGET;           # WORD ADDRESSABLE READ             #
# 
* 
* DC  NON-LOCAL VARIABLES 
# 
      XREF ARRAY DB$FTMD;;         # MASTER DIRECTORY FIT              #
# 
* DC  DESCRIPTION 
* 
*     CALCULATE WA OF VERSION INFORMATION ENTRY.
*     READ VIT ENTRY FROM MASTER DIRECTORY. 
*     SET PRIMARY VERSION NAME PARAMETER (PVENAM) AND PF OFFSET 
*       PARAMETER (PFOFF).
* 
 #
# 
*     LOCAL VARIABLES 
# 
      ARRAY VIT S(DFMDVIEN);       # VERSION INFORMATION TABLE ENTRY   #
        BEGIN 
*CALL     MDVITDCLS 
        END 
  
  
#     S T A R T   O F   D B $ V E P N   E X E C U T A B L E   C O D E  #
  
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("VEPN   ");        # GENERATE A FLOW POINT.            #
      CONTROL ENDIF;
  
      DB$WGET(DB$FTMD,             # MASTER DIRECTORY FIT              #
              VIT,                 # VIT ENTRY IN CMM                  #
              DFMDVIEN,            # WORDS TO READ = VIT ENTRY LENGTH  #
              SASCWAVD[SALX] + (SASCNOVER[SALX]*DFMDVDEN) 
                + (VERSUB - 1)*DFMDVIEN*SASCNBAR[SALX]
                + (ARID - 1)*DFMDVIEN,
                                   # WORD ADDRESS OF VIT ENTRY IN MD   #
              DB$MDER);            # ADDRESS OF ERROR ROUTINE          #
      PVENAM = MDVITNAME[0];       # SET PRIMARY VERSION NAME          #
      PFOFF = MDVITFOFF[0];        # SET OFFSET OF PERMANENT FILE INFO #
      RETURN; 
      END                          # END OF DB$VEPN                    #
      CONTROL EJECT;
      PROC DB$VERL(VENAM,VERSUB); 
      BEGIN 
 #
* *   DB$VEMD                                    PAGE  1
* *   DB$VERL--VERSION NAME LOOK-UP 
* *   A W ALLEN                                  DATE  01/30/81 
* 
* DC  PURPOSE 
* 
*     FIND A VERSION NAME IN THE MASTER DIRECTORY.
* 
* DC  ENTRY CONDITIONS
* 
*     PARAMETERS
* 
# 
      ITEM VENAM  C(07);           # VERSION NAME (INPUT)              #
      ITEM VERSUB     U;           # VERSION SUBSCRIPT (OUTPUT)        #
                                   # = 0 IF VERSION NAME NOT FOUND.    #
# 
* 
*     ASSUMPTIONS 
* 
*     SALX INDEX IS SET.
* 
* DC  EXIT CONDITIONS 
* 
*     NORMAL EXIT--VERSUB IS SET.  VERSION NAME LIST (VNL) IS CREATED 
*                  AND LINKED TO SAL. 
* 
*     ABNORMAL EXIT--VIA DB$MDER FOR I/O ERRORS ON THE MD.
* 
* DC  CALLING ROUTINES
* 
*     DBQRFA                       APPLY QRF TO A DATABASE
*     DB$ACAI                      ATTACH AREA AND INDEX FILES FOR
*                                  SYSTEM RECOVERY
*     DB$CRIN                      RECOVER/RESTORE--CRACK INPUT SYNTAX
*                                  (INTERNAL PROC VERSION)
*     DB$INV$                      INVOKE CONTROL SYMBIONT
*     DB$VER$                      VERSION CHANGE SYMBIONT
* 
* DC  CALLED ROUTINES 
* 
# 
      XREF PROC DB$FLOP;           # GENERATE A FLOW POINT             #
      XREF PROC DB$MDER;           # MASTER DIRECTORY ERROR ROUTINE    #
      XREF PROC DB$MFA;            # ALLOCATE A FIXED MEMORY BLOCK     #
      XREF PROC DB$WGET;           # WORD ADDRESSABLE READ             #
# 
* 
* DC  NON-LOCAL VARIABLES 
# 
      XREF ARRAY DB$FTMD;;         # MASTER DIRECTORY FIT              #
# 
* DC  DESCRIPTION 
* 
* 
*     THE VERSION DIRECTORY TABLE (VDT) IN THE MASTER DIRECTORY 
*     CONTAINS A LIST OF VALID VERSION NAMES.  THE FUNCTION OF
*     DB$VERL IS TO SEARCH THE VDT FOR A SPECIFIED VERSION NAME (VENAM).
*     IF VENAM IS FOUND, ITS SUBSCRIPT (VERSUB) IN THE VDT IS SET. IF 
*     NOT FOUND, VERSUB IS ZERO.  FOR READING THE VDT, A CMM BLOCK
*     CALLED THE VERSION NAME LIST (VNL) IS ALLOCATED AND LINKED TO THE 
*     SAL.  IF THE SIZE OF THE VNL IS SMALLER THAN THE VDT, THEN THE
*     VDT IS READ INTO THE VNL IN BLOCKS.  THE CURRENT CMM BLOCK IS 
*     SEARCHED BEFORE THE MD IS READ AGAIN.  THE SIZE OF THE VNL
*     IS DETERMINED BY VNLSIZE IN THE COMDECK, VENLDCLS.  VNLSIZE IS
*     SET AT INITIALIZATION TIME.  THIS ALLOWS EACH PRODUCT THAT USES 
*     DB$VERL (CDCS, DBQRFA, DBRCN, DBRST) TO CHOOSE AN APPROPRIATE 
*     SIZE FOR THE VNL. 
* 
* 
*     IF VERSION IS MASTER
*     THEN
*       RETURN WITH VERSION SUBSCRIPT = 1.
*     IF SCHEMA HAS ONE VERSION ONLY
*     THEN
*       RETURN WITH VERSION INVALID.
*       (VERSUB = 0 INDICATES AN INVALID VERSION.)
*     IF THERE IS NO VERSION NAME LIST
*     THEN
*       ALLOCATE MEMORY FOR VNL 
*     ELSE
*       SEARCH THE EXISTING VNL.
*     WHILE VERSION NAME IS NOT FOUND AND THERE ARE MORE VERSIONS IN THE
*           VERSION DIRECTORY TABLE 
*       READ NEXT BLOCK OF VERSIONS INTO THE VNL. 
*       SEARCH THE VNL. 
*     RETURN. 
*     (UPON RETURN, VERSUB = 0 IF VERSION IS INVALID.)
* 
 #
# 
*     LOCAL VARIABLES 
# 
      ITEM I           I;          # LOOP INDUCTION                    #
      ITEM J           I;          # LOOP INDUCTION                    #
      ITEM SEARCHCNT   I;          # COUNT OF VDT ENTRIES SEARCHED     #
      ITEM TEMPLEN     I;          # LENGTH IN WORDS OF VNL, INCLUDING #
                                   # HEADER WORD                       #
      BASED ARRAY WSA;;            # DUMMY ARRAY                       #
      CONTROL EJECT;
      PROC SEARCHVNL; 
      BEGIN 
 #
* *   DB$VEMD                                    PAGE  1
* *   SEARCHVNL - SEARCH VERSION NAME LIST (FOR DB$VERL)
* *   A W ALLEN                                  DATE  11/01/80 
* 
* DC  PURPOSE 
* 
*     SEARCH VERSION NAME LIST CURRENTLY IN CMM FOR A SPECIFIED VERSION 
*     NAME. 
* 
* DC  ENTRY CONDITIONS
* 
*     ASSUMPTIONS 
* 
*     VENAM IS SET TO SPECIFIED VERSION NAME. 
*     VNL POINTER IS SET TO A VNL THAT CONTAINS AT LEAST ONE VERSION
*     NAME. 
*     VERSUB (VERSION SUBSCRIPT) = 0. 
* 
* DC  EXIT CONDITIONS 
* 
*     VERSUB IS SET TO THE SUBSCRIPT OF VENAM IN THE MASTER DIRECTORY 
*     VERSION DIRECTORY TABLE (VDT).  SUBSCRIPTS START AT 1, NOT ZERO.
*     IF VERSUB = 0, THEN VENAM WAS NOT FOUND IN THE CURRENT VNL. 
*     SEARCHCNT INDICATES THE NUMBER OF VDT ENTRIES SEARCHED SO FAR.
* 
* DC  CALLING ROUTINES
* 
*     DB$VERL                      VERSION NAME LOOK-UP (INTERNAL PROC) 
* 
* DC  CALLED ROUTINES 
* 
*     NONE
* 
* DC  NON-LOCAL VARIABLES 
* 
*     CDCS COMMON 
* 
* DC  DESCRIPTION 
* 
*     LOOP THROUGH ALL VERSION NAMES IN THE CURRENT VNL.
* 
 #
#     START OF SEARCHVNL EXECUTABLE CODE                               #
  
  
      FOR J = 1 STEP DFMDVDEN      # LOOP FOR EACH VDT ENTRY IN THE    #
                                   # CURRENT LOAD OF THE VNL.          #
        WHILE J LQ VNLNOVER[0]*DFMDVDEN 
      DO
        BEGIN 
        IF VENAM EQ MDVDTNAME[J]   # IF VERSION NAME IS FOUND...       #
        THEN
          BEGIN 
          VERSUB = VNLSTART[0] + (J - 1)/DFMDVDEN;
                                   # SET VERSION SUBSCRIPT.            #
          RETURN;                  # RETURN TO DB$VERL                 #
  
          END 
        END 
      SEARCHCNT = SEARCHCNT + VNLNOVER[0];
      RETURN;                      # VERSION NAME NOT IN VNL.          #
  
      END                          # END OF SEARCHVNL                  #
      CONTROL EJECT;
  
  
#     S T A R T   O F   D B $ V E R L   E X E C U T A B L E   C O D E  #
  
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("VERL   ");        # GENERATE A FLOW POINT.            #
      CONTROL ENDIF;
  
      VERSUB = 0; 
      IF VENAM EQ DFMASTER         # IF VERSION IS MASTER...           #
      THEN
        BEGIN 
        VERSUB = DFMASTSUB;        # SET DEFAULT SUBSCRIPT AND RETURN. #
        RETURN; 
  
        END 
      IF SASCNOVER[SALX] EQ 1      # IF THERE IS ONLY ONE VERSION IN   #
      THEN                         # SCHEMA...                         #
        BEGIN                      # THEN VERSION NAME IS INVALID IF   #
        RETURN;                    # IT IS NOT MASTER.                 #
  
        END 
      SEARCHCNT = 0;               # NO VERSIONS SEARCHED YET.         #
      IF SAVNLPTR[SALX] EQ 0       # IF VERSION NAME LIST IS NOT YET   #
      THEN                         # ALLOCATED...                      #
        BEGIN                      # ALLOCATE THE CMM BLOCK.           #
        TEMPLEN = SASCNOVER[SALX]*DFMDVDEN + 1; 
                                   # FIND LENGTH OF VDT IN MD (PLUS 1) #
        IF TEMPLEN GR VNLSIZE      # IF VDT IS TOO LARGE FOR VNL...    #
        THEN
          BEGIN 
          TEMPLEN = VNLSIZE;
          END 
        DB$MFA(TEMPLEN,P<VNL>);    # GET CMM BLOCK FOR VNL.            #
        VNLNOVER[0] = 0;           # INDICATES THAT VNL IS EMPTY.      #
        VNLLENGTH[0] = TEMPLEN;    # SET HEADER WORD IN VNL.           #
        VNLSTART[0] = 1;
        SAVNLPTR[SALX] = P<VNL>;
        END 
      ELSE                         # VNL ALREADY ALLOCATED             #
        BEGIN 
        P<VNL> = SAVNLPTR[SALX];
        SEARCHVNL;                 # SEARCH EXISTING VNL.              #
        END 
  
      FOR I = I 
        WHILE VERSUB EQ 0 AND SEARCHCNT LS SASCNOVER[SALX]
      DO
        BEGIN                      # READ NEXT BLOCK OF VDT INTO VNL   #
        P<WSA> = P<VNL> + 1;       # SET CMM ADDRESS                   #
  
#     FIND STARTING SUBSCRIPT OF NEXT BLOCK OF VDT ENTRIES.            #
  
        VNLSTART[0] = VNLSTART[0] + VNLNOVER[0];
        IF VNLSTART[0] GR SASCNOVER[SALX] 
        THEN                       # IF END OF VDT HAS BEEN REACHED... #
          BEGIN 
          VNLSTART[0] = 1;         # REPOSITION AT BEGINNING.          #
          END 
  
#     FIND NUMBER OF VERSION ENTRIES TO READ.                          #
  
        VNLNOVER[0] = (VNLLENGTH[0] - 1)/DFMDVDEN;
        IF (VNLSTART[0] + VNLNOVER[0] - 1) GR SASCNOVER[SALX] 
        THEN
          BEGIN 
          VNLNOVER[0] = SASCNOVER[SALX] - VNLSTART[0] + 1;
          END 
  
#     READ VERSION DIRECTORY TABLE FROM MASTER DIRECTORY.              #
  
        DB$WGET(DB$FTMD,           # MASTER DIRECTORY FIT              #
                WSA,               # VNL AFTER HEADER WORD             #
                VNLNOVER[0]*DFMDVDEN, # NUMBER OF WORDS TO READ        #
                SASCWAVD[SALX] + (VNLSTART[0] - 1)*DFMDVDEN,
                                   # WORD ADDRESS IN VDT               #
                DB$MDER);          # ADDRESS OF ERROR ROUTINE          #
  
#     SEARCH THE VERSION NAMES NOW IN THE VNL.                         #
  
        SEARCHVNL;
        END 
      RETURN; 
      END                          # END OF DB$VERL                    #
      END                          # END OF DB$VEMD                    #
      TERM
