*DECK DB$RSEL 
USETEXT JLDEFTX 
USETEXT CDCSCTX 
      PROC DB$RSEL; 
      BEGIN 
 #
* *   DB$RSEL                                    PAGE  1
* *   SELECT LOG FILE RECORDS FOR RECOVERY/RESTORE
* *   J E ESLER                                  DATE  06/28/76 
* *   A W ALLEN - DATABASE VERSIONS              DATE  09/19/80 
* 
* DC  PURPOSE 
* 
*     READ THE INPUT LOG FILE AND SELECT RECORDS THAT MEET THE DEFINED
*     SELECTION CRITERIA. 
* 
* DC  ENTRY CONDITIONS
* 
*     DB$RCOM PARAMETERS ARE INITIALIZED. 
*     SCHEMA TABLE (SAL) ENTRY ZERO SET IN CDCS COMMON. 
*     CRITERIA TABLE HAS BEEN BUILT.
*     VERSION NAME LIST (VNL) IS LINKED TO SAL IF ANY VERSION CRITERIA. 
* 
* DC  EXIT CONDITIONS 
* 
*     A SELECTION FILE HAS BEEN GENERATED, CONTAINING ALL LOG RECORDS 
*     THAT MET THE DEFINED SELECTION CRITERIA.
* 
* DC  CALLING ROUTINES
* 
*     DB$RVRS - RECOVER/RESTORE CONTROL ROUTINE 
* 
* DC  CALLED ROUTINES 
* 
# 
      XREF PROC DB$ABRT;           #ABORT RUN#
      XREF FUNC DB$CBIN;           #CONVERT DISPLAY CODE TO BINARY# 
      XREF FUNC DB$CDEB C(10);     #INTEGER TO DECIMAL W/BLANK FILL    #
      XREF FUNC DB$CDEC C(10);     #INTEGER TO DECIMAL W/ZERO FILL     #
      XREF FUNC DB$COCT C(10);     #INTEGER TO OCTAL W/ZERO FILL       #
      XREF FUNC DB$CRCK B;         #CHECK LOG RECORD AGAINST CRITERIA#
      XREF PROC DB$CRDL;           #DELETE A CRITERIA TABLE ENTRY,MM# 
      XREF FUNC DB$CREV B;         #CHECK FOR END OF SELECTION PHASE# 
      XREF PROC DB$EPRT;           #WRITE A LINE TO OUTPUT FILE#
      XREF PROC DB$JLST;           #LIST A JOURNAL LOG RECORD#
      XREF FUNC DB$LNK;            # CREATE ENTRY IN LINKED CHAIN      #
      XREF PROC DB$LNKD;           # DELETE ENTRY IN LINKED CHAIN      #
      XREF PROC DB$MDER;           # MASTER DIRECTORY ERROR ROUTINE    #
      XREF PROC DB$MFA;            #ALLOCATE A MANAGED MEMORY BLOCK#
      XREF PROC DB$MFF;            #RELEASE A MM BLOCK# 
      XREF PROC DB$MSG;            #ISSUE DAYFILE MESSAGE#
      XREF PROC DB$UCLF;           #CLOSE INPUT AND OUTPUT FILES# 
      XREF PROC DB$VEPN;           # FIND PRIMARY VERSION NAME         #
      XREF PROC DB$VERL;           # VERSION NAME LOOK-UP              #
      XREF PROC CLOSEM;            #CLOSE FILE# 
      XREF PROC GET;               #READ FILE#
      XREF PROC OPENM;             #OPEN FILE#
      XREF PROC PUT;               #CRM WRITE MODULE# 
# 
* DC  NON-LOCAL VARIABLES 
* 
# 
      XREF ARRAY DB$JFIT;          #MODEL FIT FOR JOURNAL LOG#
        BEGIN 
        ITEM LOGFITWD;
        END 
      XREF ARRAY DB$RA0;;          #ARRAY AT RA+0#
# 
*     CDCS COMMON, RECOVER/RESTORE COMMON 
* 
* DC  DESCRIPTION 
* 
*     BUILD FITS FOR INPUT JOURNAL LOG FILE AND FOR SELECT FILE, AND
*       OPEN THESE TWO FILES. 
*     FOR EACH RECORD ON THE INPUT JOURNAL LOG FILE 
*       BEGIN 
*       READ THE RECORD.
*       IF CRM ERROR ON READ
*       THEN
*         ISSUE ERROR MESSAGE.
*         SET SELECTION ERROR FLAG. 
*       IF THE RECORD THAT WAS READ IS FROM THE PRESET PORTION OF THE 
*         FILE
*       THEN
*         SIMULATE AN END-OF-INFORMATION. 
*       IF NO RECORD WAS READ OR IF IT WAS THE LOG FILE HEADER RECORD 
*       THEN
*         READ THE NEXT RCORD.
*       IF WRONG RECORD LENGTH
*       THEN
*         ISSUE AN ERROR MESSAGE. 
*         SET SELECTION ERROR FLAG. 
*       IF ALL CRITERIA ENTRIES ARE PAST THEIR END TIME (DB$CREV) 
*       THEN
*         STOP READING. 
*       IF SCHEMA NAME/ID MISMATCH WITH MD
*       THEN
*         ISSUE MESSAGE AND ABORT.
*       IF RECORD MEETS AT LEAST ONE CRITERION (DB$CRCK)
*       THEN
*         IF VERSION NAME IS INVALID (DB$VERL)
*         THEN
*           ISSUE MESSAGE AND ABORT RUN.
*         FIND PRIMARY VERSION NAME, FORMAT AND WRITE SELECT RECORD 
*           (SELPUT). 
*       END (OF JOURNAL LOG FILE) 
*       DELETE CRITERIA ENTRIES.
*       IF ANY SELECTION ERRORS 
*       THEN
*         ISSUE MESSAGE AND ABORT RUN.
*       CLOSE LOG FILE AND SELECT FILE. 
* 
*     INTERNAL PROCEDURES-- 
* 
*     ABTSEL - ISSUE MESSAGE AND ABORT
*     SELPUT - WRITE SELECT FILE RECORD 
*     SELPUTR - DELAY THE WRITE OF THE SELECT FILE RECORD 
 #
      CONTROL NOLIST;              # RVRSCOMMN                         #
*CALL RVRSCOMMN 
      CONTROL LIST; 
# 
*     LOCAL VARIABLES 
# 
      DEF DFAVTSIZE # 3#;          # SIZE OF AVT ENTRY                 #
      BASED ARRAY AVT;             # ACTIVE VERSION TABLE              #
        BEGIN 
        ITEM AVWORD0    U(00,00,60);
        ITEM AVPRIOR    U(00,24,18);    # PRIOR AVT ENTRY              #
        ITEM AVNEXT     U(00,42,18);    # NEXT AVT ENTRY               #
  
        ITEM AVWORD1    U(01,00,60);
        ITEM AVRVENAME  C(01,00,07);    # REQUESTED VERSION NAME       #
        ITEM AVAREAID   U(01,48,12);    # AREA ID                      #
  
        ITEM AVWORD2    U(02,00,60);
        ITEM AVPVENAME  C(02,00,07);    # PRIMARY VERSION NAME         #
        ITEM AVPFOFF    U(02,42,18);    # PERMANENT FILE OFFSET        #
        END 
      ARRAY LFIT [DFFITSIZE] S;    #OLD LOG FILE FIT# 
        BEGIN 
        ITEM LFITWD (0,0,60); 
        ITEM LFITLFN C(0,0,7);     #FILE NAME#
        ITEM LFITFP  U(10,26,7);   #FILE POSITION#
        ITEM LFITRL  U(11,0,24);   #RECORD LENGTH#
        ITEM LFITMRL U(12,0,24);   #MAXIMUM RECORD LENGTH#
        ITEM LFITES  U(13,33,9);   #ERROR STATUS# 
        ITEM LFITWSA U(15,42,18);  #WORKING STORAGE AREA# 
        END 
      ARRAY SFIT [DFFITSIZE] S;    #SELECTION FILE FIT# 
        BEGIN 
        ITEM SFITWD   (0,0,60); 
        ITEM SFITLFN   C(0,0,7);   #SELECT FILE LFN#
        ITEM SFITRL  U(11,0,24);   #RECORD LENGTH#
        ITEM SFITMRL U(12,0,24);   #MAXIMUM RECORD LENGTH#
        ITEM SFITES  U(13,33,9);   #ERROR STATUS# 
        ITEM SFITHL  U(15,0,24);   #HEADER LENGTH OF A T TYPE RECORD   #
                                   #IN CHARACTERS.                     #
        ITEM SFITWSA U(15,42,18);  #WORKING STORAGE AREA# 
        ITEM SFITCP  U(17,15,24);  #TRAILER COUNT BEGINNING CHARACTER  #
                                   #POSITION OF A T TYPE RECORD.       #
        END 
      ITEM ALTWSA    I;            # ALTERNATE WORKING STORAGE AREA    #
      ITEM AREAID    U;            # AREA ID - INTEGER                 #
      ITEM AVTCHAIN  U;            # POINTER TO FIRST AVT ENTRY        #
      ITEM BUFFER    I;            # LOCATION OF WSA BUFFER            #
      ITEM CTSAVED = 0;            #COUNT OF LOG RECORDS SAVED# 
      ITEM INDEX;                  #LOOP INDEX# 
      ITEM LASTDATE C(5) = "00000"; 
      ITEM LASTTIME C(10) = DFZEROTIME; 
      ITEM MAXSEL    I;            #MAXIMUM SEL RECORD LENGTH          #
      ITEM NEXTWORD  I;            #NEXT WORD AFTER LAST RECORD        #
      ITEM NXTCRIT;                #LOOP INDEX# 
      ITEM NXTLOGREC;              #LOOP INDEX# 
      ITEM PFOFF U;                #OFFSET TO PRIMARY VERSION PF INFO  #
                                   #IN THE MD.                         #
      ITEM PRESET C(10)=DFPRESET;  #VALUE OF PRESET LOG FILE WORDS     #
      ITEM PVENAME C(07);          #PRIMARY VERSION NAME.              #
      ITEM SCHEMAID C(4);          #SCHEMA ID FOR THIS RUN# 
      ITEM SELHDTYPE C(1);         #TYPE OF JOURNAL RECORD TO SELECT# 
      ITEM SELCRMERR C(31) = "0 CRM ERROR XXX ON OLD LOG FILE"; 
      ITEM SELFCRMERR C(33) = "0 CRM ERROR XXX ON SELECTION FILE";
      ITEM SELRECLERR C(38) = "0 INVALID RECORD LENGTH FOR LOG RECORD"; 
      ITEM SUPUPDATE C(43) = " SELECTION ERRORS, UPDATE PHASE SUPPRESSED
:"; 
      ITEM SELRECMSG C(70) = "1                                      LOG
 RECORDS SELECTED FOR UPDATE";
      ITEM SEQUENCE U = 0;         #LOG RECORD SEQUENCE NUMBER# 
      ITEM SELMSG C(35) = "          RECORDS SELECTED        :";
      ITEM VERSUB    U;            # VERSION SUBSCRIPT IN MASTER       #
                                   # DIRECTORY.                        #
  
      CONTROL EJECT;
      PROC ABTSEL((ERRNUM));
 #
* *   DB$RSEL                                    PAGE  1
* *   ABTSEL - ISSUE AN ERROR MESSAGE.  CLOSE ALL FILES AND ABORT.
* *   J E ESLER                                  DATE  06/28/76 
 #
      BEGIN 
      DEF DFNUMERR #5#;            # NUMBER OF ERRORS DEFINE - 1       #
      ITEM ERRNUM;                 #REQUESTED ERROR NUMBER# 
      ARRAY ERRTEXTS [DFNUMERR] S(6); 
        BEGIN 
        ITEM TEXT C(0,0,50) = [ 
               " ERROR NUMBER XXX IN DB$RSEL.                    :" 
              ," CRM ERROR ON OPEN OF OLD LOG FILE.              :" 
              ," CRM ERROR ON OPEN OF SELECT FILE.               :" 
              ," ERRORS DETECTED DURING SELECTION.               :" 
              ," SCHEMA NAME/ID ON LOG FILE DOES NOT MATCH MD.   :" 
              ," VERSION NAME ON LOG FILE DOES NOT MATCH MD.     :" 
                          ];
        END 
  
  
  
#     A B T S E L   E X E C U T A B L E   C O D E                      #
  
      IF ERRNUM GR DFNUMERR THEN
        BEGIN 
        C<14,3>TEXT[0] = DB$CDEB(ERRNUM,3); 
        ERRNUM = 0; 
        END 
      DB$MSG(TEXT[ERRNUM]);            #MESSAGE ON DAYFILE# 
      DB$EPRT(TEXT[ERRNUM],49);        #AND OUTPUT FILE#
      DB$UCLF;
      CLOSEM(LFIT,DB$RA0);
      CLOSEM(SFIT,DB$RA0);
      DB$MSG("   **PROGRAM ABORTED**:");
      DB$ABRT;
      END 
      CONTROL EJECT;
      PROC SELPUT;
      BEGIN 
 #
* *   DB$RSEL                                    PAGE  1
* *   SELPUT - WRITE A SELECT FILE RECORD 
* *   A W ALLEN - DATABASE VERSIONS              DATE  09/19/80 
* 
* DC  PURPOSE 
* 
*     FIND PRIMARY VERSION NAME, FORMAT AND WRITE THE JOURNAL LOG 
*     RECORD TO THE SELECT FILE.  SELECT FILE RECORD CONTAINS THE 
*     PRIMARY VERSION NAME. 
* 
* DC  ENTRY CONDITIONS
* 
*     ASSUMPTIONS 
* 
*     P<LOGREC> IS SET TO A JOURNAL LOG RECORD THAT HAS BEEN SELECTED 
*       FOR WRITING TO THE SELECT FILE. 
*     AVTCHAIN IS EITHER ZERO OR IT POINTS TO THE FIRST BLOCK IN THE
*       ACTIVE VERSION TABLE (AVT). 
* 
* DC  EXIT CONDITIONS 
* 
*     CRM PUT HAS BEEN ISSUED (ERROR STATUS IS RETURNED IN THE FIT).
*     AN ENTRY HAS BEEN ADDED TO THE ACTIVE VERSION TABLE WITH THE
*       PRIMARY VERSION AND PF OFFSET (IF A NEW ENTRY WAS NEEDED).
* 
* DC  CALLING ROUTINES
* 
*     DB$RSEL - SELECT LOG RECORDS, MAIN PROGRAM. 
* 
* DC  CALLED ROUTINES 
* 
*     DB$CBIN - CONVERT DISPLAY TO BINARY 
*     DB$LNK  - GET AND LINK AN AVT BLOCK.
*     DB$VEPN - FIND PRIMARY VERSION NAME.
*     DB$VERL - FIND VERSION NAME ON MASTER DIRECTORY 
*     SELPUTR - WRITE A SELECT FILE RECORD WITH A DELAY 
* 
* DC  DESCRIPTION 
* 
*     SEARCH ALL ENTRIES IN ALL ACTIVE VERSION TABLE (AVT) BLOCKS.
*     IF REQUESTED VERSION NAME AND AREA ID FROM THE LOG RECORD ARE 
*       NOT FOUND IN THE AVT
*     THEN
*       FIND PRIMARY VERSION NAME IN MASTER DIRECTORY (DB$VEPN).
*       ADD A  NEW AVT ENTRY WITH REQUESTED VERSION, AREA ID, 
*         PRIMARY VERSION, AND PF OFFSET. 
*     ADD PRIMARY VERSION AND PF OFFSET FROM THE AVT TO THE SELECT
*       FILE RECORD.
*     WRITE THE SELECT FILE RECORD. 
* 
 #
  
#     S E L P U T   E X E C U T A B L E   C O D E                     # 
  
  
      IF JLHDVENM[0] EQ DFMASTER   # IF VERSION ON LOG RECORD IS       #
      THEN                         # "MASTER"...                       #
        BEGIN 
        SELPVENAM[0] = DFMASTER;   # SET "MASTER" AS PRIMARY VERSION   #
        SELPFOFF[0] = 0;           # FOR SELECT RECORD.                #
        GOTO PUTRECORD; 
  
        END 
  
#     SEARCH AVT FOR VERSION AND AREA ID.                              #
  
      AREAID = DB$CBIN(JLHDARID[0],4,10); 
                                   # CONVERT LOG RECORD AREA ID.       #
      P<AVT> = LOC(AVTCHAIN);      # SET TO START OF CHAIN.            #
      FOR INDEX = INDEX WHILE AVNEXT[0] NQ 0
      DO
        BEGIN 
        P<AVT> = AVNEXT[0]; 
        IF AVAREAID[0] EQ AREAID           # IF AREA AND VERSION       #
          AND AVRVENAME[0] EQ JLHDVENM[0]  # ALREADY USED...           #
        THEN
          BEGIN                    # SET UP SELECT RECORD.             #
          SELPVENAM[0] = AVPVENAME[0];
          SELPFOFF[0] = AVPFOFF[0]; 
          GOTO PUTRECORD; 
  
          END 
        END                        # END OF AVT SEARCH                 #
  
#     NO EXISTING AVT.  READ MASTER DIRECTORY AND CREATE AVT.          #
  
      DB$VERL(JLHDVENM[0],VERSUB); # FIND VERSION NAME ON MD.          #
      IF VERSUB EQ 0
      THEN
        ABTSEL(5);                 # ABORT - VERSION IS NOT ON MD.     #
  
      P<AVT> = DB$LNK(LOC(AVTCHAIN),DFAVTSIZE); 
                                   # GET ANOTHER AVT ENTRY             #
      AVRVENAME[0] = JLHDVENM[0]; 
      AVAREAID[0] = AREAID; 
      DB$VEPN(VERSUB,AREAID,PVENAME,PFOFF); 
                                   # FIND PRIMARY VERSION NAME ON MD.  #
      AVPVENAME[0] = PVENAME; 
      AVPFOFF[0] = PFOFF; 
      SELPVENAM[0] = AVPVENAME[0];  # SET UP SELECT RECORD.            #
      SELPFOFF[0] = AVPFOFF[0]; 
  
#     WRITE SELECT FILE RECORD.    #
  
PUTRECORD:  
      SELPUTR;
      END                          # END OF SELPUT PROCEDURE           #
      CONTROL EJECT;
      PROC SELPUTR; 
      BEGIN 
 #
* *   DB$RSEL                                    PAGE  1
* *   SELPUTR - PUT SELECTED RECORD OUT (DELAYED) 
* *   BOB MCALLESTER                             DATE  04/18/83 
* 
* DC  PURPOSE 
* 
*     WRITE THE SELECTED RECORD OUT AFTER A DELAY.
*     THE DELAY PERMITS A RECORD FRAGMENT TO BE IDENTIFIED. 
* 
* DC  ENTRY CONDITIONS
* 
* D   ASSUMPTIONS 
* 
*     THE VARIABLE, ALTWSA, POINTS TO THE OLD LOG RECORD THAT WAS 
*     PASSED TO SELPUTR ON THE PREVIOUS CALL. 
*     THE BASED ARRAY POINTERS, SELREC AND LOGREC, POINT TO THE 
*     RECORD BEING PASSED ON THIS CALL. 
*     IF THE VARIABLE, CTSAVED, IS ZERO THEN THERE IS NO OLD LOG
*     RECORD. 
* 
* DC  EXIT CONDITIONS 
* 
*     THE OLD RECORD HAS BEEN WRITTEN TO THE SELECT FILE. 
*     ALTWSA POINTS TO THE RECORD PASSED IN ON THIS CALL. 
*     SELREC AND LOGREC POINT TO A WSA THAT IS TO BE USED TO GET
*     THE NEXT RECORD FROM THE LOG FILE.
* 
* DC  CALLING ROUTINES
* 
*     SELPUT  - WRITE A SELECT FILE RECORD
*     DB$RSEL - SELECT LOG RECORDS, MAIN PROGRAM
* 
* DC  CALLED ROUTINES 
* 
*     DB$COCT  - CONVERT INTEGER TO OCTAL 
*     DB$EPRT  - WRITE A LINE TO THE OUTPUT FILE
*     DB$JLST  - LIST A JOURNAL LOG RECORD
*     PUT      - WRITE A RECORD 
* 
* DC  NON-LOCAL VARIABLES MODIFIED
* 
*     ALTWSA                     - ALTERNATE WSA POINTER
*     P<SELREC> AND P<LOGREC>    - JOURNAL LOG RECORD POINTERS
*     LFITWSA[0] AND SFITWSA[0]  - FIT WORKING STORAGE AREA POINTERS
* 
* DC  DESCRIPTION 
* 
*     EXCHANGE THE POINTERS TO THE OLD RECORD AND THE NEW RECORD. 
*     SET THE FIT POINTERS TO THE WORKING STORAGE AREAS.
*     IF THERE IS AN OLD RECORD, WRITE IT TO THE SELECT FILE. 
 #
  
  
#     S E L P U T R   E X E C U T A B L E   C O D E                    #
  
      ALTWSA == P<SELREC>;         # EXCHANGE POINTERS                 #
      P<LOGREC> = P<SELREC> + DFSELWORDS; 
      LFITWSA[0] = LOC(LOGREC); 
      SFITWSA[0] = LOC(SELREC); 
# 
*     IF THIS IS THE FIRST CALL TO SELPUTR, THERE IS NO OLD RECORD
*     TO BE WRITTEN.  EXIT. 
# 
      IF CTSAVED EQ 0 
      THEN
        BEGIN 
        RETURN; 
  
        END 
# 
*     WRITE THE SELECT FILE RECORD. 
# 
      PUT(SFIT,DB$RA0); 
      IF SFITES[0] NQ 0 
      THEN
        BEGIN 
        SELECTERRS = TRUE;
        C<12,3>SELFCRMERR = DB$COCT(SFITES[0],3); 
        DB$EPRT(SELFCRMERR,33); 
        DB$JLST;
        SFITES[0] = 0;
        END 
      IF NOT SUPOUTPUT             # IF OUTPUT LIST IS NOT SUPPRESSED  #
      THEN
        BEGIN 
        DB$JLST;                   # LIST SELECTED OUTPUT RECORD       #
        END 
      RETURN; 
      END                          # END OF SELPUTR PROCEDURE          #
      CONTROL EJECT;
  
  
#     S T A R T   O F   D B $ R S E L   E X E C U T A B L E   C O D E  #
  
  
# 
*     BUILD FITS FOR INPUT LOG FILE AND SELECT FILE, AND OPEN THEM. 
# 
      AVTCHAIN = 0;                # ACTIVE VERSION TABLE IS EMPTY.    #
      FOR INDEX = DFFITSIZE-1 STEP -1 UNTIL 0 DO
        BEGIN 
        LFITWD[INDEX] = LOGFITWD[INDEX];
        SFITWD[INDEX] = LOGFITWD[INDEX];
        END 
      LFITLFN[0] = C<0,7>OLDLOG;
      IF SORTREQD THEN
        SFITLFN[0] = DFPRESORTLFN;
      ELSE
        SFITLFN[0] = C<0,7>SELLFN;
      LFITMRL[0] = SASCMAXLOG[0]; 
      SFITMRL[0] = SASCMAXLOG[0] + DFSELCHARS;
                                   # SELECT RECORD HAS ONE EXTRA WORD  #
      SFITHL[0] = SFITHL[0] + DFSELCHARS; 
      SFITCP[0] = SFITCP[0] + DFSELCHARS; 
                                   # INCREASE THE HEADER LENGTH AND THE#
                                   # BEGINNING CHARACTER POSITION OF   #
                                   # THE TRAILER COUNT TO ACCOMMODATE  #
                                   # THE ADDED WORD.                   #
      MAXSEL = (SASCMAXLOG[0] +9) /10 + DFSELWORDS; 
                                   # SIZE OF MAXIMUM SELECT FILE RECORD#
      DB$MFA(MAXSEL *2, BUFFER);   # RESERVE TWO WSA AREAS             #
      ALTWSA = BUFFER + MAXSEL;    # SAVE THE ALTERNATE WSA ADDRESS    #
      P<SELREC> = BUFFER; 
      P<LOGREC> = P<SELREC> + DFSELWORDS; 
                                   # SELECT RECORD IS LOG RECORD PLUS  #
                                   # HEADER WORD.                      #
      LFITWSA[0] = P<LOGREC>; 
      SFITWSA[0] = P<SELREC>; 
      OPENM(SFIT,DFOUTPUT,DB$RA0);
      OPENM(LFIT,DFINPUT,DB$RA0); 
      IF LFITES[0] NQ 0 THEN       #ERROR ON LOG FILE#
        ABTSEL(1);
      IF SFITES[0] NQ 0 THEN       #ERROR ON SELECT FILE# 
        ABTSEL(2);
      SCHEMAID = DB$CDEC(SASCHID[0],4); 
      SELECTERRS = FALSE; 
      IF NOT SUPOUTPUT THEN 
        DB$EPRT(SELRECMSG,70);         #PRINT HEADER FOR SELECTED RECS# 
  
#     SAVE "AFTER" IMAGES FOR DBRCN, "BEFORE" IMAGES FOR DBRST.        #
  
      IF RECOVRUN THEN
        SELHDTYPE = DFJLRQAI; 
      ELSE
        SELHDTYPE = DFJLRQBI; 
  
  
# 
*     READ THE OLD LOG FILE. COPY THE RECORDS THAT MEET THE SELECTION 
*     CRITERIA ONTO THE SELECTION FILE. 
# 
      FOR NXTLOGREC = 0 WHILE   LFITFP[0] NQ DFEOI  DO
        BEGIN 
        GET(LFIT,DB$RA0); 
        IF LFITES[0] NQ 0 THEN
          BEGIN 
          SELECTERRS = TRUE;
          C<12,3>SELCRMERR = DB$COCT(LFITES[0],3);
          DB$EPRT(SELCRMERR,31);
          DB$JLST;
          IF LFITES[0] EQ O"167" THEN 
            LFITFP[0] = DFEOI;     #CRM CANNOT SKIP BAD DATA-END INPUT #
          LFITES[0] = 0;
          TEST NXTLOGREC; 
          END 
# 
*     IF THE LAST HEADER WORD OF THE RECORD THAT HAS BEEN READ IN HAS 
*     THE VALUE TO WHICH THE WHOLE FILE WAS PRESET, THEN THIS IS THE
*     END OF THE DATA ON THE JOURNAL LOG FILE.
# 
        IF JLHDTIME[0] EQ PRESET
        THEN
          BEGIN 
          LFITFP[0] = DFEOI;       # SIMULATE END-OF-INFORMATION       #
          TEST NXTLOGREC; 
  
          END 
# 
*     IF NO DATA WAS READ (END-OF-RECORD) 
*     OR IF IT IS THE LOG FILE HEADER RECORD
*     GET THE NEXT RECORD.
# 
        IF LFITRL[0] EQ 0          # NO DATA READ                      #
          OR C<0,4>JLHDWDA[0] EQ C<0,4>PRESET  # LOG HEADER RECORD     #
        THEN
          BEGIN 
          TEST NXTLOGREC; 
  
          END 
# 
*     VERIFY LOG RECORD LENGTH. IF IT IS WRONG, ISSUE WARNING AND 
*     REJECT THE RECORD.
# 
        IF LFITRL[0] NQ DB$CBIN(JLHDTRLS[0],6,10) + DFHDRSZ THEN
          BEGIN 
          SELECTERRS = TRUE;
          DB$EPRT(SELRECLERR,38); 
          DB$JLST;
          TEST NXTLOGREC; 
          END 
# 
*     SAVE THE DATE AND TIME OF EACH VALID LOG RECORD THAT IS READ. 
*     THIS DATE AND TIME IS USED BY DB$CRDL TO ASSURE THAT ALL OF 
*     SELECTION CRITERIA HAVE BEEN MET. 
*     IT MUST BE THE TIME OF THE LAST RECORD THAT WAS READ, NOT THE 
*     LAST RECORD SELECTED. 
# 
        LASTDATE = JLHDDATE[0]; 
        LASTTIME = JLHDTIME[0]; 
  
#     CHECK ALL CRITERIA ENTRY END TIMES. DELETE ANY ENTRIES THAT HAVE #
#     EXPIRED. WHEN ALL ENTRIES ARE DELETED, END SCAN OF LOG FILE.     #
  
        IF DB$CREV THEN            #ALL CRITERIA SATISFIED# 
          BEGIN 
          LFITFP[0] = DFEOI;       #SIMULATE EOI TO END SCAN# 
          TEST NXTLOGREC; 
  
          END 
  
      IF JLHDSCID[0] NQ SCHEMAID
      THEN
        BEGIN 
        ABTSEL(4);                 # WRONG SCHEMA                      #
        END 
      IF JLHDTYPE[0] EQ DFJLRQIN
        AND JLINSCNM[0] NQ SASCNAME[0]
      THEN
        BEGIN 
        ABTSEL(4);                 # SCHEMA NAME NOT SAME AS MD        #
        END 
  
#     CONSIDER BEFORE OR AFTER RECORDS FOR SELECTION.  SAVE THE ONES   #
#     THAT PASS THE SELECTION CRITERIA.                                #
  
        IF JLHDTYPE[0] EQ SELHDTYPE AND DB$CRCK THEN
            BEGIN 
                SEQUENCE = SEQUENCE + 1;
                JLHDSEQNO[0] = SEQUENCE;   #SET SEQUENCE NUMBER#
                SELPUT;            # PREPARE AND WRITE SELECT RECORD   #
                CTSAVED = CTSAVED + 1;
            END 
        END  #NXTLOGREC#
# 
*     CHECK IF THE LAST LOG RECORD IS A FRAGMENT OF A RECORD THAT WAS 
*     LEFT WHEN CDCS WAS INTERRUPTED DURING HEAVY LOGGING ACTIVITY. 
*     A RECORD IS DEFINED TO BE A FRAGMENT IF ITS LAST WORD IS A PRESET 
*     AND THE FIRST WORD OF THE FOLLOWING RECORD IS A PRESET. 
*     WRITE THE LAST RECORD TO THE SELECT FILE IF IT IS NOT A FRAGMENT. 
# 
      NEXTWORD = JLHDWDA[0];       # SAVE VALUE OF THE NEXT WORD       #
      P<LOGREC> = ALTWSA + DFSELWORDS;
      IF NEXTWORD EQ PRESET 
        AND JLHDWDA[ (DB$CBIN(JLHDTRLS[0],6,10) + DFHDRSZ -1) /10 ] 
          EQ PRESET 
      THEN                         # THERE IS A RECORD FRAGMENT        #
        BEGIN 
        CTSAVED = CTSAVED -1;      # REDUCE THE SELECT COUNT           #
        END 
      ELSE                         # THE LAST RECORD IS COMPLETE       #
        BEGIN 
        SELPUTR;                   # WRITE THE LAST RECORD             #
        P<LOGREC> = ALTWSA + DFSELWORDS;  # RESTORE POINTER TO LAST REC#
        END 
  
#     RESET LOG RECORD TIME BACK TO LAST VALID TIME READ.              #
  
      JLHDDATE[0] = LASTDATE; 
      JLHDTIME[0] = LASTTIME; 
  
#     CLOSE OLD LOG FILE AND VERIFY ALL CRITERIA SATISFIED. RETURN TO  #
#     CALLER.                                                          #
  
      P<CRITERIA> = LOC(FIRSTCRIT); 
      FOR NXTCRIT = CRNEXT[0] WHILE NXTCRIT NQ 0 DO 
        BEGIN 
        P<CRITERIA> = NXTCRIT;
        NXTCRIT = CRNEXT[0];
        DB$CRDL;                   #DELETE THE MM FOR ENTRY#
        END 
      IF CTSAVED GR 0 THEN
        C<1,8>SELMSG = DB$CDEB(CTSAVED,8);
      ELSE
        C<0,10>SELMSG = " ERROR-NO "; 
      DB$EPRT(SELMSG,34); 
      DB$MSG(SELMSG); 
      IF CTSAVED EQ 0 THEN
        ABTSEL(3);
  
#     IF ERRORS OCCURED DURING THE SELECTION PHASE, SUPPRESS THE       #
#     UPDATE PHASE.  THE SELECTION FILE CAN BE APPLIED TO THE DATABASE #
#     LATER IF THE DBA DECIDES IT IS PROPER.                           #
  
      IF SELECTERRS AND NOT SAVESORT THEN 
        ABTSEL(3);                     #QUIT-SELECTION NOT TO BE SAVED# 
      IF SELECTERRS AND UPDATERUN THEN
        BEGIN 
        UPDATERUN = FALSE;
        DB$EPRT(SUPUPDATE,42);
        DB$MSG(SUPUPDATE);
        END 
  
      CLOSEM(LFIT,DFDET,DB$RA0);
      CLOSEM(SFIT,DFDET,DB$RA0);
      DB$MFF(BUFFER);              # RELEASE WSA BUFFER                #
      P<AVT> = AVTCHAIN;
      FOR INDEX=INDEX WHILE P<AVT> NQ 0 
      DO                           # RELEASE ALL ACTIVE VERSION ENTRIES#
        DB$LNKD(P<AVT>);
      RETURN; 
      END 
      TERM
