*DECK DB$OCAR 
USETEXT CDCSCTX 
      FUNC DB$OCAR( AREAID, VERSION, ERRBLKA ) B; 
      BEGIN 
 #
* *   DB$OCAR - OPEN AND CHECK AREA              PAGE  1
* *   D E TRIGLIA/W P CEAGLIO                    DATE  02/06/81 
* 
* DC  PURPOSE 
* 
*     ACTIVATE AN AREA FOR I/O AND ENSURE THAT IT IS IN *UP* STATUS.
* 
* DC  ENTRY CONDITIONS
* 
* D   PARAMETERS
* 
#     ITEM AREAID       I;         # AREA IDENTIFIER                   #
      ITEM VERSION   C(7);         # VERSION NAME                      #
      ITEM ERRBLKA      I;         # ADDRESS OF ERROR BLOCK            #
# 
* 
* D   ASSUMPTIONS 
* 
*     SALX IS SET.
*     SAL 
*       SADBPPTR POINTS TO APL. 
*     DATABASE PROCEDURE LIBRARY IS ATTACHED. 
* 
* DC  EXIT CONDITIONS 
* 
*     NORMAL   - AREA IS SUCCESSFULLY ATTACHED AND OPENED FOR I/O.
*                P<OFT> POINTS TO AREA OFT. 
*                FUNCTION RESULT SET TO *TRUE*. 
* 
*     ABNORMAL - FUNCTION RESULT SET TO *FALSE*.
* 
*                THE FOLLOWING ERRORS ARE DIAGNOSED:  
* 
*                * IF DB$ACAI DETECTED AN ERROR, DB$OCAR RETURNS A VALUE
*                  OF *FALSE*.  SEE DB$ACAI FOR THE TYPES OF ERRORS 
*                  DETECTED.
* 
*                * IF THERE WAS AN FDL ERROR DURING DATA BASE PROCEDURE 
*                  (DBP) LOADING OR IF THERE WAS A CRM FATAL ERROR
*                  OPENING THE AREA, DB$DRAR HAS BEEN CALLED TO PRINT AN
*                  ERROR MESSAGE, TO ZERO OUT THE ERROR BLOCK, TO SET 
*                  THE AREA STATUS TO *ERRDOWN*, AND TO RETURN THE AREA 
*                  AND INDEX FILES. 
* 
*                IF AN ERROR OCCURS READING THE MD FILE, DB$MDER IS 
*                CALLED TO ABORT CDCS.
* 
* DC  CALLING ROUTINES
* 
*     DB$RFOR      ROLL FORWARD FROM LAST RECOVERY POINT
*     DB$UNDO      ROLL BACK AN UNCOMMITTED TRANSACTION 
* 
* DC  CALLED ROUTINES 
* 
# 
      XREF FUNC DB$ACAI B;         # ATTACH AND CHECK AREA AND INDEX   #
      XREF FUNC DB$ADDP U;         # LOAD HASH/COMPRESS/DECOMPRESS DBP #
      XREF PROC DB$DRAR;           # DOWN AND RETURN AREA              #
      XREF PROC DB$FLOP;           # GENERATE A FLOW POINT             #
      XREF PROC DB$FTEX;           # CRM ERROR ROUTINE                 #
      XREF PROC DB$MDER;           # MD ERROR HANDLER                  #
      XREF PROC DB$POP;            # RESTORE VARIABLE FROM RCB STACK   #
      XREF PROC DB$PUSH;           # SAVE VARIABLE IN RCB STACK        #
      XREF PROC DB$WGET;           # READ ENTRY FROM MD                #
      XREF PROC OPENM;             # CRM OPEN PROCEDURE                #
# 
* 
* DC  NON-LOCAL VARIABLES MODIFIED
* 
*     CDCSCOMMN 
*       P<UFT>
* 
*     AUTO RECOVERY ERROR BLOCK 
* 
* DC  DESCRIPTION 
* 
*     -  CALL DB$ACAI TO FIND/CREATE AN OFT ENTRY FOR THE AREA/VERSION, 
*        AND, IF NECESSARY, TO ATTACH THE AREA AND ASSOCIATED INDEX 
*        FILE.  IF DB$ACAI DETECTS AN ERROR, DB$OCAR RETURNS A FUNCTION 
*        RESULT OF *FALSE*. 
* 
*     -  IF THERE IS AN EXISTING UFT ENTRY IN THE CHAIN, GET THE FSTT 
*        ADDRESS FROM IT.  OTHERWISE, SET THE FSTT ADDRESS = 0. 
* 
*     -  IF ANY HASHING/COMPRESSION/DECOMPRESSION PROCEDURES APPLY, 
*        LOAD THEM AND SET ADDRESSES IN THE FIT.  IF AN ERROR OCCURRED
*        ON THE LOAD, CALL DB$DRAR TO PRINT AN ERROR MESSAGE, TO SET THE
*        AREA STATUS TO *ERRDOWN*, AND TO RETURN THE AREA, AND THEN 
*        RETURN A FUNCTION RESULT OF *FALSE*. 
* 
*     -  OPEN THE AREA FOR I/O.  IF A FATAL CRM ERROR OCCURRED, CALL
*        DB$DRAR TO PRINT AN ERROR MESSAGE, TO SET THE AREA STATUS TO 
*        *ERRDOWN*, AND TO RETURN THE AREA, AND THEN RETURN A FUNCTION
*        RESULT OF *FALSE*. 
* 
 #
  
  
  
#     NON-LOCAL VARIABLES REFERENCED                                   #
  
      XREF ARRAY DB$FTMD;;   # FIT FOR MD I/O                          #
      XREF ITEM DB$FTSM B;   # SUPPRESS MESSAGES FROM DB$FTEX          #
      XREF ARRAY DB$RA0;;    # PARAMETER LIST TERMINATOR               #
  
#     LOCAL VARIABLES                                                  #
  
      ITEM DBPADD       I;   # FOR OBTAINING ADDRESS OF DBP            #
      ITEM FSTT         I;   # POINTER TO (CRM) FSTT                   #
      ITEM INDEX        I;   # SCRATCH - FOR LOOPS                     #
      ITEM MDWA         I;   # WORD ADDRESS IN MD                      #
      ITEM SAVESR       B;   # SAVE SYSRECOVERY STATUS                 #
  
      BASED ARRAY FIT;;      # FOR CRM OPENM REQUEST                   #
  
      ARRAY MDARDIR (DFMDADEN);    # MD AREA DIRECTORY ENTRY           #
        BEGIN 
*CALL MDARDDCLS 
        END 
  
*CALL SRERRDCLS 
  
  
  
#**********************************************************************#
#                                                                      #
#     I N T E R N A L   P R O C E D U R E   -   L O A D E R R .        #
#                                                                      #
#**********************************************************************#
  
      PROC LOADERR; 
      BEGIN 
 #
* *   DB$OCAR - OPEN AND CHECK AREA              PAGE  1
* *   LOADERR - PROCESS DBP LOAD ERROR
* *   P L KENNY                                  DATE  05/11/81 
* 
* DC  PURPOSE 
* 
*     PROCESS AN FDL ERROR DURING LOAD OF AN AREA DBP.
* 
* DC  ENTRY CONDITIONS
* 
* D   PARAMETERS
* 
*     NONE
* 
* D   ASSUMPTIONS 
* 
*     ERRBLKA CONTAINS THE ADDRESS OF THE AUTO RECOVERY ERROR BLOCK.
*     P<SRERRBLK> POINTS TO THE ERROR BLOCK.
*     AREAID CONTAINS THE AREA IDENTIFIER.
*     VERSION CONTAINS THE VERSION NAME.
*     DBPADD CONTAINS THE NEGATIVE VALUE OF THE FDL ERROR CODE. 
* 
* DC  EXIT CONDITIONS 
* 
*     DB$DRAR HAS BEEN CALLED TO PRINT THE ERROR MESSAGE, TO SET THE
*     AREA STATUS TO *ERRDOWN*, AND TO RETURN THE AREA AND INDEX FILES. 
*     DB$DRAR HAS ZEROED OUT THE ERROR BLOCK. 
* 
* DC  CALLING ROUTINES
* 
*     DB$OCAR - MAIN PROCEDURE
* 
* DC  CALLED ROUTINES 
* 
*     DB$DRAR - DOWN AND RETURN AREA
* 
* DC  NON-LOCAL VARIABLES MODIFIED
* 
*     AUTO RECOVERY ERROR BLOCK 
* 
* DC  DESCRIPTION 
* 
*     -  FILL IN THE FIELDS OF THE ERROR BLOCK TO INDICATE THAT AN FDL
*        ERROR HAS OCCURRED.
* 
*     -  CALL DB$DRAR TO PRINT THE ERROR MESSAGE, TO ZERO OUT THE ERROR 
*        BLOCK, TO SET THE AREA STATUS TO *ERRDOWN*, AND TO RETURN THE
*        AREA AND INDEX FILES.
 #
  
  
  
#      S T A R T   O F   L O A D E R R   E X E C U T A B L E   C O D E #
  
      SRENUMB[0] = DFSRENARB;  # DATABASE AREA ERROR                   #
      SREFUNC[0] = DFSREFNLD;  # FUNCTION IS LOAD                      #
      SREFPAR[0] = -DBPADD;    # FDL ERROR NUMBER                      #
      SREARID[0] = AREAID;     # AREA ID                               #
      SREVRNM[0] = VERSION;    # VERSION NAME                          #
  
      DB$DRAR(ERRBLKA);        # DOWN/RETURN AREA                      #
  
      RETURN; 
  
      END                      # END LOADERR                           #
  
  
  
  
  
  
# S T A R T   O F   D B $ O C A R   E X E C U T A B L E   C O D E      #
  
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("OCAR");               # GENERATE FLOW POINT           #
      CONTROL ENDIF;
  
      P<SRERRBLK> = ERRBLKA;
  
#     CALL DB$ACAI TO FIND/CREATE AN OFT ENTRY AND TO ATTACH THE AREA  #
#     AND INDEX FILES IF NECESSARY.  IF ANY ERROR, RETURN A FUNCTION   #
#     RESULT OF *FALSE*.                                               #
  
      IF NOT DB$ACAI(AREAID,VERSION,ERRBLKA)
      THEN
        BEGIN 
        DB$OCAR = FALSE;
  
        RETURN; 
  
        END 
  
#     GET THE EXISTING FSTT ADDRESS IF THERE IS ONE.                   #
  
      P<UFT> = LOC(OFUFT[0]); 
      FSTT = UFFITFSTT[0];
  
#     IF ANY HASHING, COMPRESSION, DECOMPRESSION DATA BASE PROCEDURES  #
#     APPLY, LOAD THEM AND RECORD ADDRESSES IN THE FIT.  IF AN ERROR   #
#     OCCURS LOADING ANY OF THESE DBPS, CALL ROUTINE LOADERR TO        #
#     PROCESS THE ERROR, AND THEN RETURN A FUNCTION RESULT OF *FALSE*. #
  
      MDWA = SASCWAAD[SALX] + (AREAID-1)*DFMDADEN + 1;
      DB$WGET(DB$FTMD,MDARDIR,DFMDADEN,MDWA,DB$MDER);  # ACCESS MD     #
      P<FIT> = LOC(UFFIT[0]);          # SETUP FIT LOCATION            #
      IF MDADHSOR[0] NQ 0              # IF HASHING DBP,...            #
      THEN
        BEGIN 
        APLX = MDADHSOR[0]; 
        DBPADD = DB$ADDP;              # LOAD HASH DBP                 #
        IF DBPADD LS 0                 # IF ERROR ON DBP LOAD,...      #
        THEN
          BEGIN 
          LOADERR;                     # PROCESS LOADER ERROR          #
          DB$OCAR = FALSE;
          RETURN; 
  
          END 
        ELSE
          BEGIN 
          UFFITHRL[0] = DBPADD;        # SET HASH ORDINAL IN FIT       #
          END 
        END 
  
      IF MDADCMOR[0] NQ 0              # IF COMPRESSION DBP,...        #
      THEN
        BEGIN 
        APLX = MDADCMOR[0]; 
        DBPADD = DB$ADDP;              # LOAD COMPRESSION DBP          #
        IF DBPADD LS 0                 # IF ERROR ON DBP LOAD,...      #
        THEN
          BEGIN 
          LOADERR;                     # PROCESS LOADER ERROR          #
          DB$OCAR = FALSE;
          RETURN; 
  
          END 
        ELSE
          BEGIN 
          UFFITCPA[0] = DBPADD;        # SET COMP ORDINAL IN FIT       #
          END 
        END 
  
      IF MDADCMOR[0] EQ MDADDEOR[0]    # IF SAME ORDINAL FOR COMP AND  #
      THEN                             # DECOMP DBP, SET IN FIT        #
        BEGIN 
        UFFITDCA[0] = UFFITCPA[0];
        END 
      ELSE                             # OTHERWISE, LOAD DECOMP DBP    #
        BEGIN 
        APLX = MDADDEOR[0]; 
        DBPADD = DB$ADDP; 
        IF DBPADD LS 0                 # IF ERROR ON DBP LOAD,...      #
        THEN
          BEGIN 
          LOADERR;                     # PROCESS LOADER ERROR          #
          DB$OCAR = FALSE;
          RETURN; 
  
          END 
        ELSE
          BEGIN 
          UFFITDCA[0] = DBPADD; 
          END 
        END 
  
#     SET *FSTT*, *PD*, *KP* FIELDS IN THE FIT.  OPEN THE FILE--IF ANY #
#     FATAL ERROR, CALL DB$DRAR TO SET THE AREA IN *ERRDOWN* STATUS,   #
#     AND THEN RETURN A FUNCTION RESULT OF *FALSE*.                    #
  
      UFFITFSTT[0] = FSTT;             # FSTT ADDRESS (MAY BE ZERO)    #
      UFFITPD[0] = DFFITPDIO;          # INPUT/OUTPUT MODE             #
      UFFITKP[0] = 0;                  # KEY LEFT-JUSTIFIED IN LOG REC #
      DB$PUSH(P<UFT>);
  
      OPENM(FIT,DB$RA0);               # ISSUE CRM OPEN REQUEST        #
  
      DB$POP(P<UFT>);                  # A CRM CALL TO DB$QRF MAY HAVE #
                                       # CAUSED SCHEDULER TO SET       #
                                       # P<UFT> INCORRECTLY            #
  
      IF UFFITES[0] NQ 0
      THEN
        BEGIN 
        SAVESR = SYSRECOVERY; 
        SYSRECOVERY = TRUE;            # SO DB$FTEX DOESNT RESET P<OFT>#
        DB$FTSM = TRUE;                # SUPPRESS MESSAGES FROM DB$FTEX#
        DB$FTEX;                       # CHECK FOR DOWN CONDITIONS     #
        SYSRECOVERY = SAVESR; 
        END 
  
      IF UFFITFNF[0]                   # IF FATAL CRM ERROR            #
        OR OFSTATUS[0] EQ S"ERRDOWN"   # OR AREA HAS BEEN DOWNED       #
      THEN
        BEGIN 
  
        SRENUMB[0] = DFSRENARB;        # DATABASE AREA ERROR           #
        SREFUNC[0] = DFSREFNCR;        # CRM FUNCTION                  #
        SREFPAR = UFFITES[0];          # CRM ERROR CODE                #
        SREARID[0] = AREAID;           # AREA ID                       #
        SREVRNM[0] = VERSION;          # VERSION NAME                  #
  
        DB$DRAR(ERRBLKA);              # DOWN/RETURN AREA              #
        DB$OCAR = FALSE;
        END 
      ELSE
        BEGIN 
        DB$OCAR = TRUE; 
        END 
  
      RETURN; 
      END 
      TERM; 
