*DECK DB$ACAI 
USETEXT CDCSCTX 
      FUNC DB$ACAI ( (AREAID), (VERSION), (ERRBLKA) ) B;
      BEGIN 
 #
* *   DB$ACAI - ATTACH AND CHECK AREA AND INDEX  PAGE  1
* *   D E TRIGLIA/W P CEAGLIO                    DATE  02/06/81 
* 
* DC  PURPOSE 
* 
*     ATTACH AN AREA AND ITS INDEX FILE 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 
*       SAOFTLSP POINTS TO START OF OFT CHAIN.
* 
* DC  EXIT CONDITIONS 
* 
*     NORMAL   - AREA AND INDEX FILES ATTACHED.  P<OFT> IS SET. 
*                FUNCTION SET TO *TRUE*.
* 
*     ABNORMAL - FUNCTION RESULT IS SET TO *FALSE*.  THE FOLLOWING
*                ERRORS ARE DETECTED: 
* 
*                IF AN INVALID VERSION IS DETECTED, THE ERROR NUMBER AND
*                VERSION NAME ARE PUT INTO THE ERROR BLOCK, THE SCHEMA
*                STATUS IS SET TO *ERRDOWN*, AND P<OFT> IS SET TO ZERO. 
* 
*                IF AN OFT ALREADY EXISTS FOR THE AREA/VERSION AND THE
*                AREA STATUS IS NOT *UP*, *IDLING*, OR *DOWNING*, 
*                DB$DRAR IS CALLED TO PRINT THE ERROR MESSAGE AND TO
*                SET THE AREA STATUS TO *ERRDOWN*.  P<OFT> POINTS TO
*                THE OFT. 
* 
*                IF AN ERROR OCCURRED DURING THE ATTACH, DB$DRAR IS 
*                CALLED TO DOWN AND RETURN THE AREA, AND P<OFT> POINTS
*                TO THE OFT.
* 
*                IF CDCS IS NOT RUNNING IN SYSTEM RECOVERY MODE, THERE
*                SHOULD BE AN EXISTING OFT FOR THE AREA/PRIMARY-VERSION 
*                COMBINATION.  IF NO CORRESPONDING OFT IS FOUND, THEN 
*                DB$PUNT IS CALLED TO ABORT CDCS WITH AN INTERNAL ERROR.
* 
*                IF AN ERROR OCCURS READING THE MASTER DIRECTORY (MD) 
*                FILE, DB$MDER IS CALLED TO ABORT CDCS. 
* 
* DC  CALLING ROUTINES
* 
*     DB$OCAR      ATTACH AREA AND OPEN FOR I/O 
*     DB$QRFA      ATTACH AREA FOR QRF APPLICATION
* 
* DC  CALLED ROUTINES 
# 
      XREF PROC DB$ATCH;           # ATTACH AREA AND INDEX FILE        #
      XREF PROC DB$DRAR;           # DOWN AND RETURN AREA              #
      XREF PROC DB$FLOP;           # GENERATE A FLOW POINT             #
      XREF PROC DB$GOFT;           # CHECK IF AREA HAS OFT ENTRY       #
      XREF FUNC DB$LFN U;          # ASSIGN LFN FOR OFT ENTRY          #
      XREF PROC DB$MBA;            # ALLOCATE CMM BLOCK                #
      XREF PROC DB$MBF;            # RELEASE CMM BLOCK                 #
      XREF PROC DB$MDER;           # HANDLE MD I/O ERRORS              #
      XREF PROC DB$OFTC;           # LINK AND INITIALIZE AN OFT ENTRY  #
      XREF PROC DB$PUNT;           # CDCS INTERNAL ERROR PROCESSOR     #
      XREF PROC DB$QRF;            # BLOCK LOGGING PROCESSOR           #
      XREF PROC DB$VEFI;           # GET MODEL AREA FIT FROM MD        #
      XREF PROC DB$VEPF;           # GET PERMANENT FILE INFO FROM MD   #
      XREF PROC DB$VEPN;           # GET PRIMARY VERSION NAME          #
      XREF PROC DB$VERL;           # GET VERSION SUBSCRIPT FOR DB$VEPN #
      XREF PROC DB$WGET;           # READ ENTRY IN MD                  #
# 
* DC  NON-LOCAL VARIABLES MODIFIED
* 
*     P<OFT>
*     OFT (ALL FIELDS)
* 
*     AUTO RECOVERY ERROR BLOCK (ALL FIELDS)
* 
* DC  DESCRIPTION 
* 
*     -  CHECK IF AN OFT ENTRY ALREADY EXISTS FOR THE AREA AND VERSION. 
*        IF AN OFT ENTRY WAS NOT FOUND, DO THE FOLLOWING: 
*           *  IF THE REQUESTED VERSION NAME IS NOT *MASTER*, OBTAIN THE
*              PRIMARY VERSION NAME FROM THE MD.  (IF THE VERSION IS NOT
*              IN THE MD, SET P<OFT> TO ZERO, SET THE ERROR NUMBER AND
*              VERSION NAME IN THE ERROR BLOCK, SET THE SCHEMA STATUS TO
*              *ERRDOWN*, AND SET THE FUNCTION RESULT TO *FALSE*.)
*           *  CHECK IF THE AREA/PRIMARY VERSION COMBINATION HAS AN OFT.
* 
*     -  IF AN OFT ENTRY EXISTS, RETURN FUNCTION RESULT OF *TRUE* IF THE
*        AREA STATUS IS *UP*, *IDLING*, OR *DOWNING*, AND *FALSE* 
*        OTHERWISE.  IN THE LATTER CASE, CALL DB$DRAR TO PRINT THE ERROR
*        MESSAGE AND TO SET THE AREA STATUS TO *ERRDOWN*. 
* 
*     -  OFT ENTRY NOT FOUND.  CALL DB$PUNT IF CDCS IS NOT IN SYSTEM
*        RECOVERY MODE.  OTHERWISE, ALLOCATE AN OFT ENTRY AND LINK IT 
*        INTO THE SAL OFT CHAIN.
* 
*     -  READ THE AREA/VERSION ATTACH AND FIT INFORMATION FROM THE MD.
*        INITIALIZE THE MODEL FIT IN THE OFT ENTRY FROM THE MD FIT. 
*        PERFORM THE ATTACH OF THE AREA AND INDEX FILES.  IF AN ATTACH
*        ERROR OCCURS, CALL DB$DRAR TO SET THE AREA STATUS TO *ERRDOWN*,
*        AND RETURN A FUNCTION RESULT OF *FALSE*.  OTHERWISE, RETURN A
*        FUNCTION RESULT OF *TRUE*. 
* 
 #
  
  
#     NON-LOCAL VARIABLES REFERENCED                                   #
  
  
      XREF ARRAY DB$FTMD;;         # FIT FOR READING MD                #
  
#     LOCAL VARIABLES                                                  #
  
      ITEM FOUND        B;         # RESULT OF TABLE SEARCHES          #
      ITEM INDEX        I;         # FOR LOOPS                         #
      ITEM MDWA         I;         # FOR COMPUTING LOCATION IN MD      #
      ITEM PFOFF        U;         # PRIMARY VERSION OFFSET IN MD      #
      ITEM PVERSNAM  C(7);         # PRIMARY VERSION NAME FOR AN AREA  #
      ITEM VERSUB       I;         # VERSION SUBSCRIPT IN MD           #
  
  
      BASED ARRAY DUMMY;;          # FOR ATTACH REQUESTS               #
      BASED ARRAY FIT;;            # FOR AREA MODEL FIT FROM MD        #
  
  
      BASED ARRAY MDAINFO;         # MD AREA INFORMATION ENTRY         #
        BEGIN 
*CALL MDARIDCLS 
        END 
  
*CALL SRERRDCLS 
  
  
  
  
  
  
# S T A R T   O F   D B $ A C A I   E X E C U T A B L E   C O D E      #
  
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("ACAI");               # GENERATE A FLOW POINT         #
      CONTROL ENDIF;
  
#**********************************************************************#
#                                                                      #
#     CHECK IF AN OFT ENTRY ALREADY EXISTS FOR THE AREA AND VERSION.   #
#     IF AN OFT ENTRY WAS NOT FOUND, DO THE FOLLOWING:                 #
#        *  IF THE REQUESTED VERSION IS NOT *MASTER*, GET THE PRIMARY  #
#           VERSION FROM THE MD.                                       #
#        *  CHECK IF THE AREA/PRIMARY VERSION COMBINATION HAS AN OFT.  #
#                                                                      #
#**********************************************************************#
  
      P<SRERRBLK> = ERRBLKA;
  
      DB$GOFT(AREAID,VERSION,FOUND);
      IF NOT FOUND
      THEN
        BEGIN 
        IF VERSION EQ DFMASTER         # IF VERSION NAME IS MASTER     #
        THEN
          BEGIN 
          PVERSNAM = DFMASTER;         # PRIMARY VERSION NAME = MASTER #
          END 
        ELSE
          BEGIN 
          DB$VERL(VERSION,VERSUB);     # VERIFY VERSION NAME IN MD     #
  
          IF VERSUB EQ 0               # IF INVALID VERSION, ERROR     #
          THEN
            BEGIN 
            P<OFT> = 0; 
            SRENUMB[0] = DFSRENVER;    # ERROR NUMBER - INVALID VERSION#
            SREVRNM[0] = VERSION;      # VERSION NAME                  #
                                       # NOTE - FILE TYPE MUST BE SET  #
                                       # IN SREFTYP[0] BY CALLER       #
            SASCHST[SALX] = S"ERRDOWN"; 
            DB$ACAI = FALSE;
            RETURN; 
  
            END 
          IF VERSUB EQ DFMASTSUB
          THEN
            BEGIN 
            PVERSNAM = DFMASTER;       # PRIMARY VERSION NAME = MASTER #
            END 
          ELSE
            BEGIN                      # GET PRIMARY VERSION NAME AND  #
                                       # OFFSET TO PF INFO             #
            DB$VEPN(VERSUB,AREAID,PVERSNAM,PFOFF);
            END 
          DB$GOFT(AREAID,PVERSNAM,FOUND);  # CHECK FOR PRIMARY VERS    #
          END 
        END 
  
#**********************************************************************#
#                                                                      #
#     IF AN OFT ENTRY EXISTS, RETURN A FUNCTION RESULT OF *FALSE* IF   #
#     THE AREA IS IN *ERRDOWN* STATUS, OTHERWISE RETURN *TRUE*.        #
#                                                                      #
#**********************************************************************#
  
      IF FOUND
      THEN
        BEGIN 
        IF OFSTATUS[0] EQ S"ERRDOWN"
        THEN
          BEGIN 
          SRENUMB[0] = DFSRENDWN;      # AREA NOT UP                   #
          SREARID[0] = AREAID;         # AREA ID                       #
          SREVRNM[0] = VERSION;        # VERSION NAME                  #
          DB$DRAR(ERRBLKA);            # PRINT ERROR MESSAGE AND SET   #
                                       # AREA STATUS TO *ERRDOWN*      #
  
          DB$ACAI = FALSE;
  
          END 
        ELSE
          BEGIN 
          DB$ACAI = TRUE; 
          END 
  
        RETURN; 
  
  
        END 
  
#**********************************************************************#
#                                                                      #
#     NO OFT ENTRY EXISTS.  IF CDCS IS NOT IN SYSTEM RECOVERY MODE,    #
#     THERE IS AN INTERNAL ERROR SINCE THE AREA SHOULD ALREADY HAVE    #
#     BEEN ATTACHED.  THE FOLLOWING CODE CANNOT BE EXECUTED OUTSIDE OF #
#     SYSTEM RECOVERY MODE, BECAUSE IT WOULD BE INTERRUPTIBLE IN SUCH  #
#     AN ENVIRONMENT.                                                  #
#     IF CDCS IS IN SYSTEM RECOVERY MODE, ALLOCATE A NEW OFT ENTRY AND #
#     LINK IT INTO THE SAL CHAIN.  COMPLETE APPLICABLE OFT FIELDS.     #
#                                                                      #
#**********************************************************************#
  
      IF NOT SYSRECOVERY
      THEN
        BEGIN 
        DB$PUNT("DB$ACAI  1");         # ABORT CDCS - NO RETURN        #
  
        END 
  
      DB$OFTC;
      OFVENAME[0] = PVERSNAM;          # PRIMARY VERSION NAME          #
      OFARID[0] = AREAID; 
  
#**********************************************************************#
#                                                                      #
#     READ THE AREA/VERSION ATTACH AND FIT INFORMATION FROM THE MD.    #
#     INITIALIZE THE MODEL FIT IN THE OFT ENTRY FROM THE MD FIT ENTRY. #
#     PERFORM THE ATTACH (WITHOUT QUEUING) OF THE AREA AND INDEX FILES.#
#     IF AN ATTACH ERROR OCCURS, CALL DB$DRAR TO SET THE AREA STATUS   #
#     TO *ERRDOWN*, AND RETURN A FUNCTION RESULT OF *FALSE*.           #
#     OTHERWISE, FILL IN THE LOGGING FIELDS IN THE OFT, CLEAR THE OFT  #
#     DUMMY FLAG, AND RETURN A FUNCTION RESULT OF *TRUE*.              #
#                                                                      #
#**********************************************************************#
  
      DB$MBA(DFMDAIEN,P<MDAINFO>);
      IF PVERSNAM EQ DFMASTER 
      THEN
        BEGIN 
        MDWA = SASCWAAD[SALX] + SASCADSZ[SALX] + (AREAID-1)*DFMDAIEN; 
        DB$WGET(DB$FTMD,MDAINFO,DFMDAIEN,MDWA,DB$MDER); 
        FOR INDEX=DFFITSIZE-1 STEP -1 
          UNTIL 0 
        DO
          BEGIN 
          OFFIT[INDEX] = MDAIAFIT[INDEX]; 
          END 
        END 
      ELSE
        BEGIN 
        P<FIT> = LOC(OFFIT[0]); 
        DB$VEFI(AREAID,FIT);
        DB$VEPF(PFOFF,MDAINFO); 
        END 
  
# 
*               **** TEMPORARY CODE ****
*     SET A BIT IN THE FIT TO EXEMPT THIS FILE FROM THE CRM ERROR 202 
*     THAT COULD RESULT IF THE FSMODFLG BIT IS SET IN THE FSTT WHEN 
*     THE FILE IS OPENED. 
# 
      B<0,1>OFFIT[29] = 1;
  
      OFFITLFN[0] = DB$LFN("F",LOC(OFT)); 
      IF OFFITXN[0] NQ 0
      THEN
        BEGIN 
        OFFITXN[0] = DB$LFN("X",LOC(OFT));
        END 
  
      P<DUMMY> = LOC(MDAIARPF[0]);
      DB$ATCH(OFFITLFN[0],DUMMY,FALSE); 
  
      IF ATTACHSTATUS EQ 0
      THEN
        BEGIN 
        IF OFFITXN[0] NQ 0
        THEN
          BEGIN 
          P<DUMMY> = LOC(MDAIIXPF[0]);
          DB$ATCH(OFFITXN[0],DUMMY,FALSE);
          END 
        OFLOGRECF[0]= MDAIFLAGS[0]; # AREA LOGGING FLAGS ARE EXTRACTED #
                                    # BEFORE RELEASING MDAINFO         #
        END 
  
#**********************************************************************#
#                                                                      #
#     RELEASE TEMPORARY BUFFER.                                        #
#     CHECK ATTACH STATUS.  IF NOT SUCCESSFUL, DOWN AREA AND SET THE   #
#     FUNCTION RESULT *FALSE*.  ELSE, FILL IN THE LOGGING FIELDS IN THE#
#     OFT, CLEAR THE OFT DUMMY FLAG, AND SET THE FUNCTION RESULT TO    #
#     *TRUE*.                                                          #
#                                                                      #
#**********************************************************************#
  
      DB$MBF(P<MDAINFO>); 
      IF ATTACHSTATUS NQ 0
      THEN
        BEGIN 
        SRENUMB[0] = DFSRENARB;     # DATABASE AREA ERROR              #
        SREFUNC[0] = DFSREFNAT;     # FUNCTION IS ATTACH               #
        SREFPAR[0] = ATTACHSTATUS;  # PFM ERROR                        #
        SREARID[0] = AREAID;        # AREA ID                          #
        SREVRNM[0] = VERSION;       # VERSION NAME                     #
  
        DB$DRAR(ERRBLKA);           # DOWN/RETURN AREA                 #
        DB$ACAI = FALSE;
        END 
      ELSE
        BEGIN 
        IF OFLGBB[0]
        THEN                         # QRF LOGGING DEFINED FOR AREA    #
          BEGIN 
          OFFITLGX[0] = LOC(DB$QRF);
          OFFITDFLG[0] = 1; 
          OFQFT[0] = SAQRFPTR[SALX];
          END 
  
        OFCOMP[0] = TRUE; 
        OFDUMY[0] = FALSE;
        DB$ACAI = TRUE; 
        END 
  
      RETURN; 
  
      END 
      TERM; 
