home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / tarv314.zip / EERESET.CMD next >
OS/2 REXX Batch file  |  1992-12-07  |  91KB  |  1,993 lines

  1. /******************************************************************
  2. *  MODULE NAME:      EERESET                                      *
  3. *                                                                 *
  4. *  DESCRIPTIVE NAME: Reset the Log Control File                   *
  5. *                    in EE 1.2, 1.3 level databases.              *
  6. *                                                                 *
  7. *  LPP NAME:         Standalone Tool                              *
  8. *                                                                 *
  9. *  DESCRIPTION: This routine provides a mechanism for resetting   *
  10. *               or initializing the Log Control File to a state   *
  11. *               in which it appears that the database no longer   *
  12. *               needs recovery.                                   *
  13. *                                                                 *
  14. *               Caution should be exercised in using this tool    *
  15. *               because it will prevent any committed changes     *
  16. *               which did not make it to media from being         *
  17. *               recovered in the database.  As a result, there    *
  18. *               could be index and table mismatches and           *
  19. *               referential integrity violations.                 *
  20. *                                                                 *
  21. *  DEPENDENCIES:                                                  *
  22. *    SYSTEM CONFIRUATION:                                         *
  23. *      - OS/2 EE 1.2 and OS/2 EE 1.3                              *
  24. *                                                                 *
  25. *    LANGUAGE INTERPRETER:                                        *
  26. *      - OS/2 Rexx Interpreter                                    *
  27. *                                                                 *
  28. *    PREREQUISTIES: None                                          *
  29. *                                                                 *
  30. *                                                                 *
  31. *  RESTRICTIONS: None                                             *
  32. *                                                                 *
  33. *  INPUT:  Database name                                          *
  34. *          Report File                                            *
  35. *                                                                 *
  36. *  OUTPUT: Log Control File reset.                                *
  37. *          Usable database.                                       *
  38. *                                                                 *
  39. *                                                                 *
  40. *  HOST LANGUAGE: OS/2 Rexx                                       *
  41. *                                                                 *
  42. *  LAST CHANGE DATE: Version 1.4 09/29/91                         *
  43. *                                                                 *
  44. *                                                                 *
  45. ******************************************************************/
  46.  
  47. parse upper arg  dbname rptname
  48.  
  49. '@echo off'
  50.  
  51. TRACE OFF
  52.  
  53. numeric digits 15            /* Set precision for arithmetic operations */
  54. dbpath = ''                  /* Initialize database path specification  */
  55. logpath = ''                 /* Initialize log path specification       */
  56. cr_lf = d2c(13) || d2c(10)   /* Line End characters                     */
  57. report_open = 'NO'           /* Initialize Report Open Indicator        */
  58.  
  59. /*********************************************
  60.    Check the Program Input Arguments
  61. *********************************************/
  62. if dbname = '?' then
  63.   do
  64.     call general_help
  65.     signal xit
  66.   end
  67.  
  68. else    /* No Help requested, so check the input parameters */
  69.   call chkargs
  70.  
  71. 'cls'
  72. say '     '
  73. say ,
  74.     " ╔══════════════════════════════════════════════════════════════════════╗ "
  75. say ,
  76.     " ║    **  NOTICE  **  NOTICE  **  NOTICE  **  NOTICE  **  NOTICE  **    ║ "
  77. say ,
  78.     " ║                                                                      ║ "
  79. say ,
  80.     " ║        THE LOG CONTROL FILE IS ABOUT TO BE RESET !!                  ║ "
  81. say ,
  82.     " ║                                                                      ║ "
  83. say ,
  84.     " ║        Caution:  This should only be done as a very last resort.     ║ "
  85. say ,
  86.     " ║                 It will prevent all committed changes in the         ║ "
  87. say ,
  88.     " ║                 Write-Ahead Log from being applied to the database.  ║ "
  89. say ,
  90.     " ║                                                                      ║ "
  91. say ,
  92.     " ║   **********  WARNING ===>  DATA INTEGRIT MAY BE LOST   **********   ║ "
  93. say ,
  94.     " ║                                                                      ║ "
  95. say ,
  96.     " ║        Would you like to Reset the Log Control File now? (y/n)       ║ "
  97. say ,
  98.     " ║           If so, type 'y' and press ENTER;                           ║ "
  99. say ,
  100.     " ║           Otherwise, type 'n' and press ENTER.                       ║ "
  101. say ,
  102.     " ╚══════════════════════════════════════════════════════════════════════╝ "
  103. say "      "
  104. say "      "
  105. pull reset_decision
  106.  
  107. if reset_decision = 'Y' then
  108.   do
  109.  
  110.     /*********************************************
  111.        Determine the Database Subdirectory
  112.     *********************************************/
  113.     say '....Scanning the Database Directory'
  114.     call getddir
  115.     if dbpath = '' then
  116.       call errxit 'The database was not found on the file system.'
  117.  
  118.     /*********************************************
  119.        Construct the Database Configuration File
  120.     *********************************************/
  121.     dbcon_name = dbpath || 'SQLDBCON'
  122.  
  123.     /*********************************************
  124.        Check Existence of Configuration File
  125.     *********************************************/
  126.     rc = stream(dbcon_name, 'c', 'query exist')
  127.  
  128.     if rc = '' then
  129.       do
  130.         call errxit  'The Database Configuration File could not be found.'
  131.       end
  132.  
  133.     /*********************************************
  134.        Open the Report File if specified
  135.     *********************************************/
  136.     if rptname \= '' then
  137.       do
  138.         rc = stream(rptname, 'c', 'open')
  139.  
  140.         if (rc \= 'READY:') & (rc \= 'READY') then
  141.           do
  142.             call errxit  'The Report File could not be opened.'
  143.           end
  144.  
  145.         report_open = 'YES'        /* Report is now Open Indicator */
  146.  
  147.         /*********************************************
  148.            Set the Write Cursor to Append to the Report File
  149.         *********************************************/
  150.         /* Locate the last byte in the file */
  151.         eofpos = stream(rptname, 'c', 'query size')
  152.  
  153.         /* Make sure the file is not empty before reading
  154.                the last byte */
  155.         if eofpos > 0 then
  156.           do
  157.  
  158.             /* Position the Write Cursor on the last byte
  159.                  of the file if it is an EOF control;
  160.                  otherwise leave the Write Cursor positioned
  161.                  after the last byte */
  162.             if charin(rptname, eofpos, 1) = x2c('1A') then
  163.               r = stream(rptname, 'c', 'seek -1')
  164.  
  165.           end
  166.  
  167.         /*********************************************
  168.            Write the Report File Header
  169.         *********************************************/
  170.         call rpthdr
  171.  
  172.       end
  173.  
  174.     /*********************************************
  175.        Open the Database Configuration File
  176.     *********************************************/
  177.     rc = stream(dbcon_name, 'c', 'open')
  178.  
  179.     if (rc \= 'READY:') & (rc \= 'READY') then
  180.       do
  181.         call errxit  'The Database Configuration File could not be opened.'
  182.       end
  183.  
  184.     /*********************************************
  185.        Find the Path to the Log File
  186.     *********************************************/
  187.     say '....Examining the Database Configuration'
  188.     call findlog
  189.  
  190.     /*********************************************
  191.        Close the Database Configuration File
  192.     *********************************************/
  193.     rc = stream(dbcon_name, 'c', 'close')
  194.  
  195.     /*********************************************
  196.        Construct Log Control File Name if Log Path Found
  197.     *********************************************/
  198.     if logpath = '' then
  199.       call errxit  'The Log Control File could not be found.'
  200.     else
  201.       /* Construct the Log Control File Name */
  202.       logctl_name = logpath || 'SQL00000.LOG'
  203.  
  204.     /*********************************************
  205.        Open the Log Control File
  206.     *********************************************/
  207.     rc = stream(logctl_name, 'c', 'open')
  208.  
  209.     if (rc \= 'READY:') & (rc \= 'READY') then
  210.       do
  211.         call errxit  'The Log File could not be opened.'
  212.       end
  213.  
  214.     /*********************************************
  215.        Reset the Log Control File
  216.     *********************************************/
  217.     call reset
  218.  
  219.     /*********************************************
  220.        Close the Log Control File
  221.     *********************************************/
  222.     rc = stream(logctl_name, 'c', 'close')
  223.  
  224.     /*********************************************
  225.        Successful Program Completion
  226.     *********************************************/
  227.     say '     '
  228.     say 'The Reset Log Tool completed.'
  229.  
  230.     signal finish
  231.  
  232.   end
  233.  
  234. else  /* User chose not to reset the Log Control File */
  235.  
  236.   say 'Program terminated by user  --  Log Control File not reset.'
  237.  
  238. /*  ************************************************************************  */
  239. /*   =======================  PROGRAM  EXITS  ==============================  */
  240. /*  ************************************************************************  */
  241.  
  242. /*********************************************
  243.    Final Program Clean-Up
  244. *********************************************/
  245. finish:
  246.  
  247.   /*********************************************
  248.      Close the Report File if specified
  249.   *********************************************/
  250.   if report_open = 'YES' then
  251.     rc = stream(rptname, 'c', 'close')
  252.  
  253. xit:
  254.  
  255.   /* Exit the program */
  256.   exit
  257.  
  258.  
  259. /*  ************************************************************************  */
  260. /*  ----------------------   FASTARRR Error Exit   -------------------------  */
  261. /*  ************************************************************************  */
  262. errxit:
  263.  
  264.   parse arg msg_text
  265.  
  266.   /* Display the Error Message */
  267.   say '     '
  268.   say msg_text
  269.  
  270.   /* Complete the Tool Cleanup */
  271.   signal finish
  272.  
  273.   return
  274.  
  275.  
  276.  
  277. /*********************************************
  278.    SQL (Database Manager) Error Exit
  279. *********************************************/
  280. sqlxit:
  281.  
  282.   /* Get the formatted SQL message */
  283.   call SQLDBS 'GET MESSAGE INTO :sql_msg LINEWIDTH 70'
  284.   if result = 0 then
  285.     do
  286.       /* Formatting successful - Display formatted message */
  287.       say '     '
  288.       say sql_msg
  289.     end
  290.   else
  291.     do
  292.       /* Formatting unsuccessful - Display unformatted message */
  293.       say '     '
  294.       say SQLMSG
  295.     end
  296.  
  297.   /* Complete the Tool Cleanup */
  298.   signal finish
  299.  
  300.   return
  301.  
  302.  
  303. /*  ************************************************************************  */
  304. /*  +++++++++++++++++++++++++   SUBROUTINES   ++++++++++++++++++++++++++++++  */
  305. /*  ************************************************************************  */
  306.  
  307. /******************************************************************
  308. *  SUBROUTINE:   CHKARGS                                          *
  309. *                                                                 *
  310. *  DESCRIPTIVE NAME: Check the Program Input Arguments            *
  311. *                                                                 *
  312. *  DESCRIPTION: This routine checks the validity of the input     *
  313. *               arguments for the program.  If any arguments      *
  314. *               are not specified, then the user is prompted to   *
  315. *               type the required argument.                       *
  316. *                                                                 *
  317. *  INPUT: none                                                    *
  318. *                                                                 *
  319. *                                                                 *
  320. *  OUTPUT: none                                                   *
  321. *                                                                 *
  322. ******************************************************************/
  323.  
  324. chkargs:
  325.  
  326. if dbname = '' then      /* Prompt for the Database name if not input */
  327.   do
  328.     'cls'
  329.     say "     "
  330.     say ,
  331.     " ╔══════════════════════════════════════════════════════════════════════╗ "
  332.     say ,
  333.     " ║                                                                      ║ "
  334.     say ,
  335.     " ║  Please type the input Database Name and press ENTER:                ║ "
  336.     say ,
  337.     " ║                                                                      ║ "
  338.     say ,
  339.     " ╚══════════════════════════════════════════════════════════════════════╝ "
  340.     say "      "
  341.     say "      "
  342.     pull dbname
  343.   end
  344.  
  345. return
  346.  
  347.  
  348. /******************************************************************
  349. *  SUBROUTINE:   GETDDIR                                          *
  350. *                                                                 *
  351. *  DESCRIPTIVE NAME: Get the Database Directory                   *
  352. *                                                                 *
  353. *  DESCRIPTION: This routine scans the System Database Directory  *
  354. *               to determine the Drive containing the specified   *
  355. *               database.  If it finds the database on a local    *
  356. *               volume, then it calls another routine to          *
  357. *               scan the Volume Database Directory to determine   *
  358. *               the subdirectory containing the database.         *
  359. *                                                                 *
  360. *                                                                 *
  361. *  INPUT: none                                                    *
  362. *                                                                 *
  363. *                                                                 *
  364. *  OUTPUT: none                                                   *
  365. *                                                                 *
  366. ******************************************************************/
  367.  
  368. getddir:
  369.  
  370. /*********************************************
  371.    Register SQLDBS with REXX
  372. *********************************************/
  373. /* Check if SQLDBS function is currently registered */
  374. if Rxfuncquery('SQLDBS') \= 0 then
  375.    do
  376.      /* Register SQLDBS function */
  377.      rcy = Rxfuncadd('SQLDBS','SQLAR','SQLDBS')
  378.  
  379.      if rcy \= 0 then
  380.         call errxit 'Database Manager registration error'
  381.    end  /* end if */
  382.  
  383. /*********************************************
  384.    Register SQLEXEC with REXX
  385. *********************************************/
  386. /* Check if SQLEXEC function is currently registered */
  387. if Rxfuncquery('SQLEXEC') \= 0 then
  388.    do
  389.      /* Register SQLEXEC function */
  390.      rcy = Rxfuncadd('SQLEXEC','SQLAR','SQLEXEC')
  391.  
  392.      if rcy \= 0 then
  393.         call errxit 'Database Manager registration error'
  394.    end  /* end if */
  395.  
  396. /*********************************************
  397.    Scan System Directory for Database Name
  398. *********************************************/
  399. call SQLDBS 'open database directory on 0 using :dhandle'
  400. if sqlca.sqlcode < 0 then
  401.   signal sqlxit
  402.  
  403. do while sqlca.sqlcode = 0
  404.    call SQLDBS 'get database directory entry :dhandle.1'
  405.    if sqlca.sqlcode = 0 then
  406.      do
  407.        if SQLDINFO.1 = dbname then
  408.          do
  409.            db_drive = SQLDINFO.3
  410.            dbname = strip(dbname)
  411.            call scanvol
  412.            leave
  413.          end
  414.      end
  415. end
  416.  
  417. call SQLDBS 'close database directory :dhandle.1'
  418.  
  419. return
  420.  
  421. /******************************************************************
  422. *  SUBROUTINE:   SCANVOL                                          *
  423. *                                                                 *
  424. *  DESCRIPTIVE NAME: Scan the Volume Database Directory           *
  425. *                                                                 *
  426. *  DESCRIPTION: This routine scans the Volume Database Directory  *
  427. *               to determine the Subdirectory containing the      *
  428. *               specified database.                               *
  429. *                                                                 *
  430. *                                                                 *
  431. *  INPUT: none                                                    *
  432. *                                                                 *
  433. *  OUTPUT: none                                                   *
  434. *                                                                 *
  435. ******************************************************************/
  436.  
  437. scanvol:
  438.  
  439. /* Scan volume directory for name */
  440.  
  441. dbpath = ''
  442.  
  443. call SQLDBS 'open database directory on 'left(db_drive,1)' using :vhandle'
  444. if sqlca.sqlcode = 0 then
  445.  do
  446.  
  447.    do forever
  448.      call SQLDBS 'get database directory entry :vhandle.1'
  449.      if SQLCA.SQLCODE = 1014 then
  450.       do
  451.         say 'No entry found in volume directory for drive 'db_drive'...'
  452.         leave
  453.       end
  454.      if SQLDINFO.1 = dbname then
  455.       do
  456.         dbdir = SQLDINFO.4
  457.         leave
  458.       end
  459.    end
  460.  
  461.    call SQLDBS 'close database directory :vhandle.1'
  462.  
  463.    dbpath = db_drive'\'dbdir'\'
  464.  end
  465.  
  466. return
  467.  
  468. /******************************************************************
  469. *  SUBROUTINE:   RPTHDR                                           *
  470. *                                                                 *
  471. *  DESCRIPTIVE NAME: Write the Report File Header                 *
  472. *                                                                 *
  473. *  DESCRIPTION: This routine writes the information that appears  *
  474. *               at the beginning of the Report for a given        *
  475. *               execution of RESETLOG.                            *
  476. *                                                                 *
  477. *               Note: The Report File must already be opened.     *
  478. *                                                                 *
  479. *  INPUT: none                                                    *
  480. *                                                                 *
  481. *                                                                 *
  482. *  OUTPUT: none                                                   *
  483. *                                                                 *
  484. ******************************************************************/
  485.  
  486. rpthdr:
  487.  
  488.   /* Define Various text lines for the Report */
  489.   eqlines = '==================================================' || ,
  490.             '============================'
  491.   ttline = '       EERESET (V 3.1)  Report   -   ' || date('N') || '   ' || ,
  492.                                                   time('C')
  493.   dbline  = '                     Database:  ' || dbname
  494.   dbpline = '                Database Path:  ' || dbpath
  495.   seplines = '--------------------------------------------------' || ,
  496.              '----------------------------'
  497.  
  498.   /* Construct the Report Header text */
  499.   rpthdr_text = '     '  || cr_lf || ,
  500.                 '     '  || cr_lf || ,
  501.                 eqlines  || cr_lf || ,
  502.                 eqlines  || cr_lf || ,
  503.                 eqlines  || cr_lf || ,
  504.                 eqlines  || cr_lf || ,
  505.                 '     '  || cr_lf || ,
  506.                 '     '  || cr_lf || ,
  507.                 ttline   || cr_lf || ,
  508.                 '     '  || cr_lf || ,
  509.                 '     '  || cr_lf || ,
  510.                 dbline   || cr_lf || ,
  511.                 '     '  || cr_lf || ,
  512.                 '     '  || cr_lf || ,
  513.                 seplines || cr_lf || ,
  514.                 seplines || cr_lf || ,
  515.                 '     '  || cr_lf || ,
  516.                 '     '  || cr_lf
  517.  
  518.  
  519.   /* Write the Report Header to the Report File */
  520.   call wrt2rpt  rpthdr_text
  521.  
  522. return
  523.  
  524. /******************************************************************
  525. *  SUBROUTINE:   WRT2RPT                                          *
  526. *                                                                 *
  527. *  DESCRIPTIVE NAME: Write to the Report File                     *
  528. *                                                                 *
  529. *  DESCRIPTION: This routine provides a common routine for        *
  530. *               writing information to the Report File.  This     *
  531. *               routine checks to verify that the Report File     *
  532. *               was specified as input to the tool and was        *
  533. *               subsequently opened before writing the data.      *
  534. *                                                                 *
  535. *  INPUT:  Text to be written to the Report File                  *
  536. *                                                                 *
  537. *                                                                 *
  538. *  OUTPUT: none                                                   *
  539. *                                                                 *
  540. ******************************************************************/
  541.  
  542. wrt2rpt:
  543.  
  544.   parse arg report_text
  545.  
  546.   if report_open = 'YES' then
  547.     do
  548.       rc = lineout(rptname, report_text)
  549.     end
  550.  
  551. return
  552.  
  553. /******************************************************************
  554. *  SUBROUTINE:   FINDLOG                                          *
  555. *                                                                 *
  556. *  DESCRIPTIVE NAME: Find the Path to the Log Files               *
  557. *                                                                 *
  558. *  DESCRIPTION: This routine determines the path containing the   *
  559. *               Log files for the database.                       *
  560. *                                                                 *
  561. *                                                                 *
  562. *  INPUT: none                                                    *
  563. *                                                                 *
  564. *                                                                 *
  565. *  OUTPUT: none                                                   *
  566. *                                                                 *
  567. ******************************************************************/
  568.  
  569. findlog:
  570.  
  571. /*********************************************
  572.    Define Offsets to Fields in the Database
  573.            Configuration File
  574. *********************************************/
  575. call defoff_dbcon
  576.  
  577. /*********************************************
  578.    Get Data in the Database Configuration File
  579. *********************************************/
  580. call getdata_dbcon
  581.  
  582. /*********************************************
  583.    Determine the Path to the Log Files
  584. *********************************************/
  585. say '....Determining Log File Location'
  586. call getlogpath
  587.  
  588. return
  589.  
  590. /******************************************************************
  591. *  SUBROUTINE:   DEFOFF_DBCON                                     *
  592. *                                                                 *
  593. *  DESCRIPTIVE NAME: Define Offsets to Fields in Database Config  *
  594. *                                                                 *
  595. *  DESCRIPTION: This routine defines the offsets for the fields   *
  596. *               in the Database Configuration File.               *
  597. *                                                                 *
  598. *  INPUT: none                                                    *
  599. *                                                                 *
  600. *  OUTPUT: none                                                   *
  601. *                                                                 *
  602. ******************************************************************/
  603.  
  604. defoff_dbcon:
  605.  
  606. /*********************************************
  607.    Define Page Offset Constants
  608.       (Note: These offsets are 1-origin from the Start of the Page)
  609.       (Note: The length values are in terms of character bytes.)
  610. *********************************************/
  611. dbcon  =  1            /* Offset to the Database Configuration */
  612.  
  613. /*********************************************
  614.    Define Offsets within the Database Configuration Description
  615.       (Note: These offsets are 0-origin from the Start of the
  616.                     Database Configuration File.)
  617. *********************************************/
  618. dbc_chksumo =  0               /* Checksum field offset                      */
  619. dbc_chksuml =  4               /*                length                      */
  620.  
  621. dbc_titleo =  4                /* Title field offset                         */
  622. dbc_titlel =  12               /*             length                         */
  623.  
  624. dbc_relo  =  16                /* Release field offset                       */
  625. dbc_rell  =  2                 /*               length                       */
  626.  
  627. dbc_pad1o =  18                /* Pad for Long Boundary field offset         */
  628. dbc_pad1l =  2                 /*                             length         */
  629.  
  630. dbc_logsizo =  20              /* Log File Size (4K Pages) field offset      */
  631. dbc_logsizl =  4               /*                                length      */
  632.  
  633. dbc_logexto =  24              /* Log File Extent Size field offset          */
  634. dbc_logextl =  4               /*                            length          */
  635.  
  636. dbc_maxexto =  28              /* Max Extents field offset                   */
  637. dbc_maxextl =  4               /*                   length                   */
  638.  
  639. dbc_dlchko =  32               /* Deadlock Check Interval field offset       */
  640. dbc_dlchkl =  4                /*                               length       */
  641.  
  642. dbc_mseedo =  36               /* Database Seed (masked) field offset        */
  643. dbc_mseedl =  4                /*                              length        */
  644.  
  645. dbc_pad2o =  40                /* Pad field offset                           */
  646. dbc_pad2l =  4                 /*           length                           */
  647.  
  648. dbc_unseedo =  44              /* Unmasked Database Seed field offset        */
  649. dbc_unseedl =  4               /*                              length        */
  650.  
  651. dbc_stmpo =  48                /* Timestamp field offset                     */
  652. dbc_stmpl =  10                /*                 length                     */
  653.  
  654. dbc_lcklsto =  58              /* Maximum Storage for LockList offset        */
  655. dbc_lcklstl =  2               /*                              length        */
  656.  
  657. dbc_buffo =  60                /* Size of buffer pool offset                 */
  658. dbc_buffl =  2                 /*                     length                 */
  659.  
  660. dbc_maxfilo =  62              /* Max Db Files Open per appl offset          */
  661. dbc_maxfill =  2               /*                            length          */
  662.  
  663. dbc_softo =  64                /* No. records before Soft Chkpt offset       */
  664. dbc_softl =  2                 /*                               length       */
  665.  
  666. dbc_maxappo =  66              /* Max active applications offset             */
  667. dbc_maxappl =  2               /*                         length             */
  668.  
  669. dbc_apheapo =  68              /* Application Heap Size offset               */
  670. dbc_apheapl =  2               /*                       length               */
  671.  
  672. dbc_dbheapo =  70              /* Database Heap Size offset                  */
  673. dbc_dbheapl =  2               /*                    length                  */
  674.  
  675. dbc_cntryo =  72               /* Country Code of Application offset         */
  676. dbc_cntryl =  2                /*                             length         */
  677.  
  678. dbc_cpago =  74                /* Code Page of Application offset            */
  679. dbc_cpagl =  2                 /*                          length            */
  680.  
  681. dbc_agheapo =  76              /* Application Agent Heap Size offset         */
  682. dbc_agheapl =  2               /*                             length         */
  683.  
  684. dbc_maxtoto =  78              /* Max Total Files Open offset                */
  685. dbc_maxtotl =  2               /*                      length                */
  686.  
  687. dbc_slheapo =  80              /* Sort List Heap Size offset                 */
  688. dbc_slheapl =  2               /*                     length                 */
  689.  
  690. dbc_rdso  =  82                /* RDS Version Indicator offset               */
  691. dbc_rdsl  =  2                 /*                       length               */
  692.  
  693. dbc_pctlckso =  84             /* % of Total LockList per appl offset        */
  694. dbc_pctlcksl =  2              /*                              length        */
  695.  
  696. dbc_stheapo =  86              /* Statement Heap Size offset                 */
  697. dbc_stheapl =  2               /*                     length                 */
  698.  
  699. dbc_plogo =  88                /* Number of Primary Log Files offset         */
  700. dbc_plogl =  2                 /*                             length         */
  701.  
  702. dbc_slogo =  90                /* Number of Secondary Log Files offset       */
  703. dbc_slogl =  2                 /*                               length       */
  704.  
  705. dbc_lfsizo =  92               /* Log File Size offset                       */
  706. dbc_lfsizl =  2                /*               length                       */
  707.  
  708. dbc_logpatho =  94             /* Log File Path offset                       */
  709. dbc_logpathl =  248            /*               length                       */
  710.  
  711. dbc_newpatho =  342            /* Path to the Log File offset                */
  712. dbc_newpathl =  248            /*                      length                */
  713.  
  714. dbc_inflgo =  590              /* Internal Indicator/Status Flag offset      */
  715. dbc_inflgl =  2                /*                                length      */
  716.  
  717. dbc_exflgo =  592              /* External Indicator/Status Flag offset      */
  718. dbc_exflgl =  2                /*                                length      */
  719.  
  720. dbc_pad3o =  594               /* Pad for Spare Bytes offset                 */
  721. dbc_pad3l =  8                 /*                     length                 */
  722.  
  723. return
  724.  
  725.  
  726. /******************************************************************
  727. *  SUBROUTINE:   GETDATA_DBCON                                    *
  728. *                                                                 *
  729. *  DESCRIPTIVE NAME: Get Data from the Db Config File             *
  730. *                                                                 *
  731. *  DESCRIPTION: This routine retrieves the data from the          *
  732. *               Database Configuration File and stores the        *
  733. *               Database Configuration fields in variables.       *
  734. *                                                                 *
  735. *  INPUT: none                                                    *
  736. *                                                                 *
  737. *                                                                 *
  738. *  OUTPUT: none                                                   *
  739. *                                                                 *
  740. ******************************************************************/
  741.  
  742. getdata_dbcon:
  743.  
  744. /*********************************************
  745.    Read the Database Configuration File
  746. *********************************************/
  747.  
  748.                                  /* Checksum                */
  749. dbc_chksum = c2d(reverse(charin(dbcon_name, dbcon+dbc_chksumo+2, 2)) || ,
  750.               reverse(charin(dbcon_name, dbcon+dbc_chksumo, 2)), 5)
  751.  
  752.                                  /* Title                   */
  753. dbc_title = charin(dbcon_name, dbcon+dbc_titleo, dbc_titlel)
  754.  
  755.                                  /* Release                 */
  756. dbc_rel = c2x(reverse(charin(dbcon_name, dbcon+dbc_relo, dbc_rell)))
  757.  
  758.                                  /* Log File Size           */
  759. dbc_logsiz = c2d(reverse(charin(dbcon_name, dbcon+dbc_logsizo+2, 2)) || ,
  760.               reverse(charin(dbcon_name, dbcon+dbc_logsizo, 2)), 5)
  761.  
  762.                                  /* Log File Extent Size    */
  763. dbc_logext = c2d(reverse(charin(dbcon_name, dbcon+dbc_logexto+2, 2)) || ,
  764.               reverse(charin(dbcon_name, dbcon+dbc_logexto, 2)), 5)
  765.  
  766.                                  /* Max No. of Extents      */
  767. dbc_maxext = c2d(reverse(charin(dbcon_name, dbcon+dbc_maxexto+2, 2)) || ,
  768.               reverse(charin(dbcon_name, dbcon+dbc_maxexto, 2)), 5)
  769.  
  770.                                  /* Deadlock Check Interval */
  771. dbc_dlchk = c2d(reverse(charin(dbcon_name, dbcon+dbc_dlchko+2, 2)) || ,
  772.               reverse(charin(dbcon_name, dbcon+dbc_dlchko, 2)), 5)
  773.  
  774.                                  /* Masked Database Seed    */
  775. dbc_mseed = c2d(reverse(charin(dbcon_name, dbcon+dbc_mseedo+2, 2)) || ,
  776.               reverse(charin(dbcon_name, dbcon+dbc_mseedo, 2)), 5)
  777.  
  778.                                  /* UnMasked Database Seed  */
  779. dbc_unseed = c2d(reverse(charin(dbcon_name, dbcon+dbc_unseedo+2, 2)) || ,
  780.               reverse(charin(dbcon_name, dbcon+dbc_unseedo, 2)), 5)
  781.  
  782.                                  /* Timestamp               */
  783. dbc_stmp = c2x(charin(dbcon_name, dbcon+dbc_stmpo, dbc_stmpl))
  784.  
  785.                                  /* Maximum Storage for Lock List  */
  786. dbc_lcklst = c2d(reverse(charin(dbcon_name, dbcon+dbc_lcklsto, dbc_lcklstl)))
  787.  
  788.                                  /* Size of Buffer Pool     */
  789. dbc_buff = c2d(reverse(charin(dbcon_name, dbcon+dbc_buffo, dbc_buffl)))
  790.  
  791.                                  /* Max Db Files Open per Appl     */
  792. dbc_maxfil = c2d(reverse(charin(dbcon_name, dbcon+dbc_maxfilo, dbc_maxfill)))
  793.  
  794.                                  /* No. Records before Soft Chkpt  */
  795. dbc_soft = c2d(reverse(charin(dbcon_name, dbcon+dbc_softo, dbc_softl)))
  796.  
  797.                                  /* Max Active Applications        */
  798. dbc_maxapp = c2d(reverse(charin(dbcon_name, dbcon+dbc_maxappo, dbc_maxappl)))
  799.  
  800.                                  /* Application Heap Size          */
  801. dbc_apheap = c2d(reverse(charin(dbcon_name, dbcon+dbc_apheapo, dbc_apheapl)))
  802.  
  803.                                  /* Database Heap Size             */
  804. dbc_dbheap = c2d(reverse(charin(dbcon_name, dbcon+dbc_dbheapo, dbc_dbheapl)))
  805.  
  806.                                  /* Country Code                   */
  807. dbc_cntry = c2d(reverse(charin(dbcon_name, dbcon+dbc_cntryo, dbc_cntryl)))
  808.  
  809.                                  /* Code Page                      */
  810. dbc_cpag = c2d(reverse(charin(dbcon_name, dbcon+dbc_cpago, dbc_cpagl)))
  811.  
  812.                                  /* Application Agent Heap Size    */
  813. dbc_agheap = c2d(reverse(charin(dbcon_name, dbcon+dbc_agheapo, dbc_agheapl)))
  814.  
  815.                                  /* Max Total Files Open           */
  816. dbc_maxtot = c2d(reverse(charin(dbcon_name, dbcon+dbc_maxtoto, dbc_maxtotl)))
  817.  
  818.                                  /* Sort List Heap Size            */
  819. dbc_slheap = c2d(reverse(charin(dbcon_name, dbcon+dbc_slheapo, dbc_slheapl)))
  820.  
  821.                                  /* RDS Version Indicator          */
  822. dbc_rds  = c2d(reverse(charin(dbcon_name, dbcon+dbc_rdso, dbc_rdsl)))
  823.  
  824.                                  /* %  of Total LockList per Appl  */
  825. dbc_pctlcks = c2d(reverse(charin(dbcon_name, dbcon+dbc_pctlckso, dbc_pctlcksl)))
  826.  
  827.                                  /* Statement Heap Size            */
  828. dbc_stheap = c2d(reverse(charin(dbcon_name, dbcon+dbc_stheapo, dbc_stheapl)))
  829.  
  830.                                  /* Number of Primary Log Files    */
  831. dbc_plog = c2d(reverse(charin(dbcon_name, dbcon+dbc_plogo, dbc_plogl)))
  832.  
  833.                                  /* Number of Secondary Log Files  */
  834. dbc_slog = c2d(reverse(charin(dbcon_name, dbcon+dbc_slogo, dbc_slogl)))
  835.  
  836.                                  /* Log File Size                  */
  837. dbc_lfsiz = c2d(reverse(charin(dbcon_name, dbcon+dbc_lfsizo, dbc_lfsizl)))
  838.  
  839.                                  /* Log File Path           */
  840. dbc_logpath = charin(dbcon_name, dbcon+dbc_logpatho, dbc_logpathl)
  841.  
  842.                                  /* New Log File Path       */
  843. dbc_newpath = charin(dbcon_name, dbcon+dbc_newpatho, dbc_newpathl)
  844.  
  845.                                  /* Internal Indicator/Status Flag */
  846. dbc_inflg = c2x(reverse(charin(dbcon_name, dbcon+dbc_inflgo, dbc_inflgl)))
  847.  
  848.                                  /* External Indicator/Status Flag */
  849. dbc_exflg = c2x(reverse(charin(dbcon_name, dbcon+dbc_exflgo, dbc_exflgl)))
  850.  
  851. /*********************************************
  852.    Report the Contents of the Database
  853.      Configuration File
  854. *********************************************/
  855.  
  856. dbcon_text = ,
  857.    '     ' || cr_lf || ,
  858.    '                     Database Configuration File  ' || cr_lf || ,
  859.    '     ' || cr_lf || ,
  860.    '     ' || cr_lf || ,
  861.    '                        Checksum:  ' || dbc_chksum  || cr_lf || ,
  862.    '                           Title:  ' || dbc_title   || cr_lf || ,
  863.    '                         Release:  ' || dbc_rel     || cr_lf || ,
  864.    '           RDS Version Indicator:  ' || dbc_rds     || cr_lf || ,
  865.    '            Masked Database Seed:  ' || dbc_mseed   || cr_lf || ,
  866.    '          UnMasked Database Seed:  ' || dbc_unseed  || cr_lf || ,
  867.    '     Database Creation Timestamp:  ' || substr(dbc_stmp,1,4) || '-' || ,
  868.                                             substr(dbc_stmp,5,2) || '-' || ,
  869.                                             substr(dbc_stmp,7,2) || '-' || ,
  870.                                             substr(dbc_stmp,9,2) || '.' || ,
  871.                                             substr(dbc_stmp,11,2) || '.' || ,
  872.                                             substr(dbc_stmp,13,2) || '.' || ,
  873.                                             substr(dbc_stmp,15,6) || ,
  874.                                             cr_lf || ,
  875.    '     ' || cr_lf || ,
  876.    '      Log File Size (Linear Log):  ' || dbc_logsiz || cr_lf || ,
  877.    '        Extent Size (Linear Log):  ' || dbc_logext || cr_lf || ,
  878.    ' Max No. of Extents (Linear Log):  ' || dbc_maxext || cr_lf || ,
  879.    '     Number of Primary Log Files:  ' || dbc_plog   || cr_lf || ,
  880.    '   Number of Secondary Log Files:  ' || dbc_slog   || cr_lf || ,
  881.    '           Size of Each Log File:  ' || dbc_lfsiz  || cr_lf || ,
  882.    '                   Log File Path:  ' || ,
  883.                          strip(translate(dbc_logpath, ' ', '00'x )) || ,
  884.                          cr_lf || ,
  885.    '               New Log File Path:  ' || ,
  886.                          strip(translate(dbc_newpath, ' ', '00'x )) || ,
  887.                          cr_lf || ,
  888.    '     ' || cr_lf || ,
  889.    ' Interval for DeadLock Detection:  ' || dbc_dlchk   || cr_lf || ,
  890.    '   Maximum Storage for Lock List:  ' || dbc_lcklst  || cr_lf || ,
  891.    '   % of Total Lock List per Appl:  ' || dbc_pctlcks || cr_lf || ,
  892.    '     Maximum Active Applications:  ' || dbc_maxapp  || cr_lf || ,
  893.    '  Maximum Db Files Open per Appl:  ' || dbc_maxfil  || cr_lf || ,
  894.    '     Max Tot Files Open per Appl:  ' || dbc_maxtot  || cr_lf || ,
  895.    'Records Written before SoftChkpt:  ' || dbc_soft    || cr_lf || ,
  896.    '             Size of Buffer Pool:  ' || dbc_buff    || cr_lf || ,
  897.    '     '  || cr_lf || ,
  898.    '           Application Heap Size:  ' || dbc_apheap  || cr_lf || ,
  899.    '     Application Agent Heap Size:  ' || dbc_agheap  || cr_lf || ,
  900.    '              Database Heap Size:  ' || dbc_dbheap  || cr_lf || ,
  901.    '             Statement Heap Size:  ' || dbc_stheap  || cr_lf || ,
  902.    '             Sort List Heap Size:  ' || dbc_slheap  || cr_lf || ,
  903.    '     '  || cr_lf || ,
  904.    '                    Country Code:  ' || dbc_cntry   || cr_lf || ,
  905.    '                       Code Page:  ' || dbc_cpag    || cr_lf || ,
  906.    '     ' || cr_lf || ,
  907.    '     ' || cr_lf || ,
  908.    '     ' || cr_lf || ,
  909.    '                  -----Internal Indicators----- '  || cr_lf || ,
  910.    '     ' || cr_lf || ,
  911.    '         Log File Move Indicator:  ' || bitand(dbc_inflg, '0001'x) || ,
  912.                                          cr_lf || ,
  913.    '    Linear to Circular Log Xlate:  ' || bitand(dbc_inflg, '0002'x) || ,
  914.                                          cr_lf || ,
  915.    '    Circular to Linear Log Xlate:  ' || bitand(dbc_inflg, '0004'x) || ,
  916.                                          cr_lf || ,
  917.    '     ' || cr_lf || ,
  918.    '     ' || cr_lf || ,
  919.    '                  -----External Indicators----- ' || cr_lf || ,
  920.    '     ' || cr_lf || ,
  921.    '          Copy Protect Indicator:  ' || bitand(dbc_exflg, '0001'x) || ,
  922.                                          cr_lf
  923. call wrt2rpt  dbcon_text
  924.  
  925. return
  926.  
  927.  
  928. /******************************************************************
  929. *  SUBROUTINE:   GETLOGPATH                                       *
  930. *                                                                 *
  931. *  DESCRIPTIVE NAME: Get the Path Containing Log Files            *
  932. *                                                                 *
  933. *  DESCRIPTION: This routine determines the SubDirectory that     *
  934. *               contains the Log Files from the LOGPATH and       *
  935. *               NEWPATH fields in the Db Config file.  If both    *
  936. *               fields are NULL, then the Log Files are           *
  937. *               supposed to be in the Database Subdirectory.      *
  938. *               The subdirectory supposedly containing the Log    *
  939. *               Files is checked to see if the Log Control File   *
  940. *               really exists in the subdirectory.  Upon exit     *
  941. *               from this routine, the shared variable LOGPATH    *
  942. *               should contain the log file subdirectory.  If     *
  943. *               no subdirectory is found to contain the Log File, *
  944. *               then LOGPATH remains a NULL value.                *
  945. *                                                                 *
  946. *  INPUT: LOGPATH = NULL                                          *
  947. *                                                                 *
  948. *                                                                 *
  949. *  OUTPUT: LOGPATH = Log File Subdirectory                        *
  950. *                 or                                              *
  951. *          LOGPATH = NULL                                         *
  952. *                                                                 *
  953. ******************************************************************/
  954.  
  955. getlogpath:
  956.  
  957. /* Construct normalized LogPath character string */
  958. norm_logpath = strip(translate(dbc_logpath, ' ', '00'x ))
  959.  
  960. /* Construct normalized NewLogPath character string */
  961. norm_newpath = strip(translate(dbc_newpath, ' ', '00'x ))
  962.  
  963. if norm_logpath = '' & norm_newpath = '' then
  964.   do
  965.     /* Log Files are supposedly in the database subdirectory */
  966.     if stream(dbpath || 'SQL00000.LOG', 'c', 'query exist') \= '' then
  967.        logpath = dbpath      /* Log File in database subdirectory */
  968.   end
  969. else   /* Log Path is specified in the Db Configuration */
  970.   do
  971.     /* Check if Log Control File is specified and found in LOGPATH */
  972.     if norm_logpath \= '' & ,
  973.        stream(norm_logpath || 'SQL00000.LOG', 'c', 'query exist') \= '' then
  974.        /* Log Control File found in LOGPATH */
  975.       logpath = norm_logpath
  976.     else
  977.       do
  978.         if norm_newpath \= '' & ,
  979.           stream(norm_newpath || 'SQL00000.LOG', 'c', 'query exist') \= '' then
  980.           /* Log Control File found in NEWPATH */
  981.           logpath = norm_newpath
  982.       end
  983.   end
  984.  
  985. return
  986.  
  987. /******************************************************************
  988. *  SUBROUTINE:   RESET                                            *
  989. *                                                                 *
  990. *  DESCRIPTIVE NAME: Reset the Log Control File                   *
  991. *                                                                 *
  992. *  DESCRIPTION: This routine controls the resetting of the Log    *
  993. *               Control File.  It calls a routine to set up the   *
  994. *               offsets to fields in the Log Control File and     *
  995. *               then it calls the routine to update the Base      *
  996. *               LSN in the file.                                  *
  997. *                                                                 *
  998. *                                                                 *
  999. *  INPUT: none                                                    *
  1000. *                                                                 *
  1001. *                                                                 *
  1002. *  OUTPUT: none                                                   *
  1003. *                                                                 *
  1004. ******************************************************************/
  1005.  
  1006. reset:
  1007.  
  1008. say '....Examining the Log Control File'
  1009.  
  1010. /*********************************************
  1011.    Define Offsets to Fields in the Log Control File
  1012. *********************************************/
  1013. call defoff_log
  1014.  
  1015.  
  1016. /*********************************************
  1017.    Write Report File Separator Lines
  1018. *********************************************/
  1019. rptsep_text = '     '  || cr_lf || ,
  1020.               '     '  || cr_lf || ,
  1021.               seplines || cr_lf || ,
  1022.               seplines || cr_lf || ,
  1023.               '     '  || cr_lf || ,
  1024.               '     '  || cr_lf
  1025.  
  1026. call wrt2rpt  rptsep_text
  1027.  
  1028. /*********************************************
  1029.    Get Data in the Log Control File
  1030. *********************************************/
  1031. call getdata_logctl
  1032.  
  1033. /*********************************************
  1034.    Write Report File Separator Lines
  1035. *********************************************/
  1036. call wrt2rpt  rptsep_text
  1037.  
  1038. /*********************************************
  1039.    Get Data in the LOGFILEHEAD Log File
  1040. *********************************************/
  1041. say '....Examining the LOGFILEHEAD'
  1042. call getdata_logfilehead
  1043.  
  1044. /*********************************************
  1045.    Write Report File Separator Lines
  1046. *********************************************/
  1047. call wrt2rpt  rptsep_text
  1048.  
  1049. /*********************************************
  1050.    Get Data in the LOGFILETAIL Log File
  1051. *********************************************/
  1052. say '....Examining the LOGFILETAIL'
  1053. call getdata_logfiletail
  1054.  
  1055. /*********************************************
  1056.    Write Report File Separator Lines
  1057. *********************************************/
  1058. call wrt2rpt  rptsep_text
  1059.  
  1060. /*********************************************
  1061.    Update the Base LSN
  1062. *********************************************/
  1063. say '....Comparing LSN Values'
  1064. call updlsn
  1065.  
  1066. /*********************************************
  1067.    Write the Report File Tail
  1068. *********************************************/
  1069. rptail_text = '     '  || cr_lf || ,
  1070.               '     '  || cr_lf || ,
  1071.               eqlines  || cr_lf || ,
  1072.               eqlines  || cr_lf || ,
  1073.               '     '  || cr_lf || ,
  1074.               '     '  || cr_lf
  1075.  
  1076. call wrt2rpt  rptail_text
  1077.  
  1078. return
  1079.  
  1080. /******************************************************************
  1081. *  SUBROUTINE:   DEFOFF_LOG                                       *
  1082. *                                                                 *
  1083. *  DESCRIPTIVE NAME: Define Offsets to Fields in Log Control File *
  1084. *                                                                 *
  1085. *  DESCRIPTION: This routine defines the offsets for the fields   *
  1086. *               in the Log Control File.                          *
  1087. *                                                                 *
  1088. *  INPUT: none                                                    *
  1089. *                                                                 *
  1090. *                                                                 *
  1091. *  OUTPUT: none                                                   *
  1092. *                                                                 *
  1093. ******************************************************************/
  1094.  
  1095. defoff_log:
  1096.  
  1097. /*********************************************
  1098.    Define Page Offset Constants
  1099.       (Note: These offsets are 1-origin from the Start of the Page)
  1100.       (Note: The length values are in terms of character bytes.)
  1101. *********************************************/
  1102. lfhdr1  =  1            /* Offset to the Primary Log File Header */
  1103. lfhdr2  =  2049         /* Offset to the Secondary Log File Header */
  1104.  
  1105. lfalt1  =  4097         /* Offset to Partial Page 1 (ALTERNATE1) */
  1106. lfalt2  =  8193         /* Offset to Partial Page 2 (ALTERNATE2) */
  1107.  
  1108. /*********************************************
  1109.    Define Offsets for Log File Header in Log Control File
  1110.       (Note: These offsets are 0-origin from the Start of LFH)
  1111. *********************************************/
  1112. lfh_cnt1o =  0               /* Consistency Counter 1 field offset           */
  1113. lfh_cnt1l =  2               /*                       field length           */
  1114.  
  1115. lfh_sizeo  =  2              /* Number of Bytes in Log File Hdr offset       */
  1116. lfh_sizel  =  2              /*                           field length       */
  1117.  
  1118. lfh_logtypo  =  4            /* Log File Type field offset                   */
  1119. lfh_logtypl  =  2            /*               field length                   */
  1120.  
  1121. lfh_logacto  =  6            /* Number of Primary Log Files field offset     */
  1122. lfh_logactl  =  2            /*                             field length     */
  1123.  
  1124. lfh_loginao  =  8            /* Number of Secondary Log Files field offset   */
  1125. lfh_loginal  =  2            /*                               field length   */
  1126.  
  1127. lfh_logtoto  =  10           /* Total number of files field offset           */
  1128. lfh_logtotl  =  2            /*                       field length           */
  1129.  
  1130. lfh_totpago  =  12           /* Total Pages field offset                     */
  1131. lfh_totpagl  =  4            /*             field length                     */
  1132.  
  1133. lfh_totsizo  =  16           /* Total Bytes field offset                     */
  1134. lfh_totsizl  =  4            /*             field length                     */
  1135.  
  1136. lfh_logsizo  =  20           /* Number of Pages in each Log field offset     */
  1137. lfh_logsizl  =  2            /*                             field length     */
  1138.  
  1139. lfh_ttblsizo =  22           /* Transaction Table Size field offset          */
  1140. lfh_ttblsizl =  4            /*                        field length          */
  1141.  
  1142. lfh_frstpago =  26           /* First Log Page field offset                  */
  1143. lfh_frstpagl =  4            /*                field length                  */
  1144.  
  1145. lfh_lastpago =  30           /* Last Log Page field offset                   */
  1146. lfh_lastpagl =  4            /*               field length                   */
  1147.  
  1148. lfh_softcnto =  34           /* Soft Checkpoints field offset                */
  1149. lfh_softcntl =  4            /*                  field length                */
  1150.  
  1151. lfh_lfheado  =  38           /* File containing Log Head field offset        */
  1152. lfh_lfheadl  =  2            /*                          field length        */
  1153.  
  1154. lfh_lfhoffo  =  40           /* First Page Number of Log File Head field off */
  1155. lfh_lfhoffl  =  4            /*                                    field len */
  1156.  
  1157. lfh_lftailo  =  44           /* File containing Log Tail field offset        */
  1158. lfh_lftaill  =  2            /*                          field length        */
  1159.  
  1160. lfh_lftoffo  =  46           /* Last Page Number of Log File Tail field off  */
  1161. lfh_lftoffl  =  4            /*                                   field len  */
  1162.  
  1163. lfh_softmaxo =  50           /* Log Records written before Soft Chkpt   off  */
  1164. lfh_softmaxl =  2            /*                                   field len  */
  1165.  
  1166. lfh_baselsno =  52           /* First LSN after final Stop Using field off   */
  1167. lfh_baselsnl =  6            /*                                  field len   */
  1168.  
  1169. lfh_nextlsno =  58           /* Next LSN prior to final Stop Using field off */
  1170. lfh_nextlsnl =  6            /*                                    field len */
  1171.  
  1172. lfh_lastlsno =  64           /* LSN of Last Log on Disk field offset         */
  1173. lfh_lastlsnl =  6            /*                         field length         */
  1174.  
  1175. lfh_lowlsno  =  70           /* First LSN of Oldest In-Flight Trans field off*/
  1176. lfh_lowlsnl  =  6            /*                                     field len*/
  1177.  
  1178. lfh_minblsno =  76           /* First LSN of Oldest Pg in Buff Pool field off*/
  1179. lfh_minblsnl =  6            /*                                     field len*/
  1180.  
  1181. lfh_basetido =  82           /* First Transaction ID field offset            */
  1182. lfh_basetidl =  6            /*                      field length            */
  1183.  
  1184. lfh_headlsno =  88           /* LSN at Head of Log File field offset         */
  1185. lfh_headlsnl =  6            /*                         field length         */
  1186.  
  1187. lfh_taillsno =  94           /* Last LSN of Log File field offset            */
  1188. lfh_taillsnl =  6            /*                      field length            */
  1189.  
  1190. lfh_logpatho =  100          /* Log File Path field offset                   */
  1191. lfh_logpathl =  260          /*               field length                   */
  1192.  
  1193. lfh_newpatho =  360          /* New Log File Path field offset               */
  1194. lfh_newpathl =  260          /*                   field length               */
  1195.  
  1196. lfh_dbseedo  =  620          /* Database Seed field offset                   */
  1197. lfh_dbseedl  =  4            /*               field length                   */
  1198.  
  1199. lfh_bkpflgo  =  624          /* Backup Flag field offset                     */
  1200. lfh_bkpflgl  =  2            /*             field length                     */
  1201.  
  1202. lfh_resvo =  626             /* Reserved field offset                        */
  1203. lfh_resvl =  2               /*          field length                        */
  1204.  
  1205. lfh_handleo =  628           /* File Handle Array field offset               */
  1206. lfh_handlel =  256           /*                   field length               */
  1207.  
  1208. lfh_headcnto =  884          /* Counter incremented before soft checkpoint   */
  1209. lfh_headcntl =  4            /*                                              */
  1210.  
  1211. lfh_pado  =  888             /* Pad offset                                   */
  1212. lfh_padl  =  1158            /*     length                                   */
  1213.  
  1214. lfh_cnt2o =  2046            /* Consistency counter offset                   */
  1215. lfh_cnt2l =  2               /*                     length                   */
  1216.  
  1217. /*********************************************
  1218.    Define Offsets for Log Page Header and Log Page Tail
  1219.       in Log Pages
  1220.       (Note: These offsets are 0-origin from the Start
  1221.                 of the Log Page.)
  1222. *********************************************/
  1223.  
  1224. lph_pglsno = 0               /* Page Header LSN  offset                      */
  1225. lph_pglsnl = 6               /*                  length                      */
  1226.  
  1227. lph_pgnumo = 6               /* Page Number  offset                          */
  1228. lph_pgnuml = 4               /*              length                          */
  1229.  
  1230. lph_frstidxo = 10            /* Index to First Log Record  offset            */
  1231. lph_frstidxl = 2             /*                            length            */
  1232.  
  1233. lph_nxtidxo = 12             /* Index to Next Available Record Space  offset */
  1234. lph_nxttidxl = 2             /*                                       length */
  1235.  
  1236. lph_resvo = 14               /* Reserved Space  offset                       */
  1237. lph_resvl = 6                /*                 length                       */
  1238.  
  1239. lpd_recordo = 20             /* Log Record Data Area  offset                 */
  1240. lpd_recordl = 4070           /*                       length                 */
  1241.  
  1242. lpt_tailsno = 4090           /* Log Page Tail LSN  offset                    */
  1243. lpt_tailsnl = 6              /*                    length                    */
  1244.  
  1245. return
  1246.  
  1247. /******************************************************************
  1248. *  SUBROUTINE:   GETDATA_LOGCTL                                   *
  1249. *                                                                 *
  1250. *  DESCRIPTIVE NAME: Get Data from the Log Control File           *
  1251. *                                                                 *
  1252. *  DESCRIPTION: This routine determines the most recent Log File  *
  1253. *               Header (either the Primary or the Secondary) and  *
  1254. *               retrieves the data from the Log Control File      *
  1255. *               and stores the Log File Header fields in          *
  1256. *               variables.                                        *
  1257. *                                                                 *
  1258. *  INPUT: none                                                    *
  1259. *                                                                 *
  1260. *                                                                 *
  1261. *  OUTPUT: none                                                   *
  1262. *                                                                 *
  1263. ******************************************************************/
  1264.  
  1265. getdata_logctl:
  1266.  
  1267. /*********************************************
  1268.    Determine the Current Log File Header
  1269. *********************************************/
  1270. /* Get the Head Count field from both Log File Headers */
  1271. lfh_headcnt1 = c2d(reverse(charin(logctl_name, lfhdr1+lfh_headcnto+2, 2)) || ,
  1272.                reverse(charin(logctl_name, lfhdr1+lfh_headcnto, 2)), 5)
  1273. lfh_headcnt2 = c2d(reverse(charin(logctl_name, lfhdr2+lfh_headcnto+2, 2)) || ,
  1274.                reverse(charin(logctl_name, lfhdr2+lfh_headcnto, 2)), 5)
  1275.  
  1276. /* Compare the Head Count fields from both headers */
  1277. if lfh_headcnt1 >= lfh_headcnt2 then     /* Primary LFH is most recent */
  1278.   lfhdr = lfhdr1        /* Set offset for using Primary Log File Header */
  1279. else                             /* Secondary LFH is most recent */
  1280.   lfhdr = lfhdr2        /* Set offset for using Secondary Log File Header */
  1281.  
  1282. /*********************************************
  1283.    Read the Log Control File
  1284. *********************************************/
  1285.  
  1286.                                  /* Number of Bytes in Log File Header */
  1287. lfh_size = c2d(reverse(charin(logctl_name, lfhdr+lfh_sizeo, lfh_sizel)))
  1288.                                  /* Log File Type */
  1289. lfh_logtyp = c2d(reverse(charin(logctl_name, lfhdr+lfh_logtypo, lfh_logtypl)))
  1290.                                  /* Number of Primary Log Files */
  1291. lfh_logact = c2d(reverse(charin(logctl_name, lfhdr+lfh_logacto, lfh_logactl)))
  1292.                                  /* Number of Secondary Log Files */
  1293. lfh_logina = c2d(reverse(charin(logctl_name, lfhdr+lfh_loginao, lfh_loginal)))
  1294.                                  /* Total active/inactive Log Files */
  1295. lfh_logtot = c2d(reverse(charin(logctl_name, lfhdr+lfh_logtoto, lfh_logtotl)))
  1296.                                  /* Total Pages in Log File */
  1297. lfh_totpag = c2d(reverse(charin(logctl_name, lfhdr+lfh_totpago+2, 2)) || ,
  1298.                  reverse(charin(logctl_name, lfhdr+lfh_totpago, 2)), 5)
  1299.                                  /* Total Bytes in Log File */
  1300. lfh_totsiz = c2d(reverse(charin(logctl_name, lfhdr+lfh_totsizo+2, 2)) || ,
  1301.                  reverse(charin(logctl_name, lfhdr+lfh_totsizo, 2)), 5)
  1302.                                  /* Number of pages in each Log File */
  1303. lfh_logsiz = c2d(reverse(charin(logctl_name, lfhdr+lfh_logsizo, lfh_logsizl)))
  1304.                                  /* Current size of Transaction Table */
  1305. lfh_ttblsiz = c2d(reverse(charin(logctl_name, lfhdr+lfh_ttblsizo+2, 2)) || ,
  1306.                   reverse(charin(logctl_name, lfhdr+lfh_ttblsizo, 2)), 5)
  1307.                                  /* First Log Page for this header */
  1308. lfh_frstpag = c2d(reverse(charin(logctl_name, lfhdr+lfh_frstpago+2, 2)) || ,
  1309.                   reverse(charin(logctl_name, lfhdr+lfh_frstpago, 2)), 5)
  1310.                                  /* Last Log Page containing records */
  1311. lfh_lastpag = c2d(reverse(charin(logctl_name, lfhdr+lfh_lastpago+2, 2)) || ,
  1312.                   reverse(charin(logctl_name, lfhdr+lfh_lastpago, 2)), 5)
  1313.                                  /* Soft Checkpoints since initialization */
  1314. lfh_softcnt = c2d(reverse(charin(logctl_name, lfhdr+lfh_softcnto+2, 2)) || ,
  1315.                   reverse(charin(logctl_name, lfhdr+lfh_softcnto, 2)), 5)
  1316.                                  /* File containing Beginning of Log */
  1317. lfh_lfhead = c2d(reverse(charin(logctl_name, lfhdr+lfh_lfheado, lfh_lfheadl)))
  1318.                                  /* LOGFILEHEAD Offset               */
  1319. lfh_lfhoff = c2d(reverse(charin(logctl_name, lfhdr+lfh_lfhoffo+2, 2)) || ,
  1320.                  reverse(charin(logctl_name, lfhdr+lfh_lfhoffo, 2)), 5)
  1321.                                  /* File containing End of Log */
  1322. lfh_lftail = c2d(reverse(charin(logctl_name, lfhdr+lfh_lftailo, lfh_lftaill)))
  1323.                                  /* LOGFILETAIL Offset               */
  1324. lfh_lftoff = c2d(reverse(charin(logctl_name, lfhdr+lfh_lftoffo+2, 2)) || ,
  1325.                  reverse(charin(logctl_name, lfhdr+lfh_lftoffo, 2)), 5)
  1326.                                  /* # of Log Recs written before soft chkpt */
  1327. lfh_softmax = c2d(reverse(charin(logctl_name, lfhdr+lfh_softmaxo, lfh_softmaxl)))
  1328.                                  /* First LSN after final Stop Using */
  1329. lfh_baselsn = c2x(charin(logctl_name, lfhdr+lfh_baselsno, lfh_baselsnl))
  1330.                                  /* Next LSN prior to final Stop Using */
  1331. lfh_nextlsn = c2x(charin(logctl_name, lfhdr+lfh_nextlsno, lfh_nextlsnl))
  1332.                                  /* LSN of last Log Rec written to disk */
  1333. lfh_lastlsn = c2x(charin(logctl_name, lfhdr+lfh_lastlsno, lfh_lastlsnl))
  1334.                                  /* First LSN of oldest in-flight trans */
  1335. lfh_lowlsn = c2x(charin(logctl_name, lfhdr+lfh_lowlsno, lfh_lowlsnl))
  1336.                                  /* First LSN of oldest page in buff pool */
  1337. lfh_minblsn = c2x(charin(logctl_name, lfhdr+lfh_minblsno, lfh_minblsnl))
  1338.                                  /* First TID after hard checkpoint */
  1339. lfh_basetid = c2x(charin(logctl_name, lfhdr+lfh_basetido, lfh_basetidl))
  1340.                                  /* LSN of Head of the Log File */
  1341. lfh_headlsn = c2x(charin(logctl_name, lfhdr+lfh_headlsno, lfh_headlsnl))
  1342.                                  /* Last LSN of the Log File */
  1343. lfh_taillsn = c2x(charin(logctl_name, lfhdr+lfh_taillsno, lfh_taillsnl))
  1344.                                  /* Log File Path */
  1345. lfh_logpath = charin(logctl_name, lfhdr+lfh_logpatho, lfh_logpathl)
  1346.                                  /* New Log File Path */
  1347. lfh_newpath = charin(logctl_name, lfhdr+lfh_newpatho, lfh_newpathl)
  1348.                                  /* Database Seed */
  1349. lfh_dbseed = c2d(reverse(charin(logctl_name, lfhdr+lfh_dbseedo+2, 2)) || ,
  1350.              reverse(charin(logctl_name, lfhdr+lfh_dbseedo, 2)), 5)
  1351.                                  /* Backup Flag */
  1352. lfh_bkpflg = c2d(reverse(charin(logctl_name, lfhdr+lfh_bkpflgo, lfh_bkpflgl)))
  1353.                                  /* Head Counter */
  1354. lfh_headcnt = c2d(reverse(charin(logctl_name, lfhdr+lfh_headcnto+2, 2)) || ,
  1355.               reverse(charin(logctl_name, lfhdr+lfh_headcnto, 2)), 5)
  1356.  
  1357. /*********************************************
  1358.    Report the Contents of the Log File Header
  1359.      in the Log Control File
  1360. *********************************************/
  1361.  
  1362. lfh_text = ,
  1363.     '     ' || cr_lf || ,
  1364.     '                        Log Control File ' || cr_lf || ,
  1365.     '                    Current Log File Header:' || cr_lf || ,
  1366.     '     ' || cr_lf || ,
  1367.     '     ' || cr_lf || ,
  1368.     ' Size of Log File Header (bytes):  ' || lfh_size || cr_lf || ,
  1369.     '                   Log File Type:  ' || lfh_logtyp || cr_lf || ,
  1370.     '     ' || cr_lf || ,
  1371.     '                   Log File Path:  ' || ,
  1372.                            strip(translate(lfh_logpath, ' ', '00'x )) || ,
  1373.                            cr_lf || ,
  1374.     '               New Log File Path:  ' || ,
  1375.                            strip(translate(lfh_newpath, ' ', '00'x )) || ,
  1376.                            cr_lf || ,
  1377.     '     ' || cr_lf || ,
  1378.     '     ' || cr_lf || ,
  1379.     '     ' || cr_lf || ,
  1380.     '     Number of Primary Log Files:  ' || lfh_logact  || cr_lf || ,
  1381.     '   Number of Secondary Log Files:  ' || lfh_logina  || cr_lf || ,
  1382.     '     Total Active/Inactive Files:  ' || lfh_logtot  || cr_lf || ,
  1383.     '     Total Pages in the Log File:  ' || lfh_totpag  || cr_lf || ,
  1384.     'Number of Pages in each Log File:  ' || lfh_logsiz  || cr_lf || ,
  1385.     '     Total Bytes in the Log File:  ' || lfh_totsiz  || cr_lf || ,
  1386.     '     ' || cr_lf || ,
  1387.     '     ' || cr_lf || ,
  1388.     '     ' || cr_lf || ,
  1389.     '                  First Log Page:  ' || lfh_frstpag  || cr_lf || ,
  1390.     '                   Last Log Page:  ' || lfh_lastpag  || cr_lf || ,
  1391.     '                   Log File Head:  ' || lfh_lfhead   || cr_lf || ,
  1392.     '            Log File Head Offset:  ' || lfh_lfhoff   || cr_lf || ,
  1393.     '                   Log File Tail:  ' || lfh_lftail   || cr_lf || ,
  1394.     '            Log File Tail Offset:  ' || lfh_lftoff   || cr_lf || ,
  1395.     '     ' || cr_lf || ,
  1396.     '     ' || cr_lf || ,
  1397.     '     ' || cr_lf || ,
  1398.     '                        Base LSN:  ' || lfh_baselsn  || cr_lf || ,
  1399.     '                        Next LSN:  ' || lfh_nextlsn  || cr_lf || ,
  1400.     '                   Last Disk LSN:  ' || lfh_lastlsn  || cr_lf || ,
  1401.     '             Low Transaction LSN:  ' || lfh_lowlsn   || cr_lf || ,
  1402.     '              Minimum Buffer LSN:  ' || lfh_minblsn  || cr_lf || ,
  1403.     '                        Head LSN:  ' || lfh_headlsn  || cr_lf || ,
  1404.     '                        Tail LSN:  ' || lfh_taillsn  || cr_lf || ,
  1405.     '     ' || cr_lf || ,
  1406.     '     ' || cr_lf || ,
  1407.     '     ' || cr_lf || ,
  1408.     '            First Transaction ID:  ' || lfh_basetid  || cr_lf || ,
  1409.     '       Size of Transaction Table:  ' || lfh_ttblsiz  || cr_lf || ,
  1410.     'Soft Chkpts since Initialization:  ' || lfh_softcnt  || cr_lf || ,
  1411.     '    Log Recs prior to Soft Chkpt:  ' || lfh_softmax  || cr_lf || ,
  1412.     '                   Database Seed:  ' || lfh_dbseed   || cr_lf || ,
  1413.     '                     Backup Flag:  ' || lfh_bkpflg   || cr_lf || ,
  1414.     '     '  || cr_lf || ,
  1415.     '     '  || cr_lf
  1416.  
  1417. call wrt2rpt  lfh_text
  1418.  
  1419. /*********************************************
  1420.    Read Partial Page 1 in the Log Control File
  1421. *********************************************/
  1422.  
  1423.                                  /* Page Header LSN  */
  1424. alt1_pglsn = c2x(charin(logctl_name, lfalt1+lph_pglsno, lph_pglsnl))
  1425.                                  /* Page Number  */
  1426. alt1_pgnum = c2d(reverse(charin(logctl_name, lfalt1+lph_pgnumo+2, 2)) || ,
  1427.              reverse(charin(logctl_name, lfalt1+lph_pgnumo, 2)), 5)
  1428.                                  /* Page Tail LSN  */
  1429. alt1_tailsn = c2x(charin(logctl_name, lfalt1+lpt_tailsno, lpt_tailsnl))
  1430.  
  1431. /*********************************************
  1432.    Report the Contents of Partial Page 1
  1433.      in the Log Control File
  1434. *********************************************/
  1435.  
  1436. alt1_text = ,
  1437.         '     ' || cr_lf || ,
  1438.         '                        Log Control File ' || cr_lf || ,
  1439.         '     ' || cr_lf || ,
  1440.         '                         Partial Page 1:'  || cr_lf || ,
  1441.         '     ' || cr_lf || ,
  1442.         '     ' || cr_lf || ,
  1443.         '                     Page Number:  ' || alt1_pgnum  || cr_lf || ,
  1444.         '                 Page Header LSN:  ' || alt1_pglsn  || cr_lf || ,
  1445.         '                   Page Tail LSN:  ' || alt1_tailsn || cr_lf || ,
  1446.         '     ' || cr_lf
  1447.  
  1448. call wrt2rpt  alt1_text
  1449.  
  1450. /*********************************************
  1451.    Read Partial Page 2 in the Log Control File
  1452. *********************************************/
  1453.  
  1454.                                  /* Page Header LSN  */
  1455. alt2_pglsn = c2x(charin(logctl_name, lfalt2+lph_pglsno, lph_pglsnl))
  1456.                                  /* Page Number  */
  1457. alt2_pgnum = c2d(reverse(charin(logctl_name, lfalt2+lph_pgnumo+2, 2)) || ,
  1458.              reverse(charin(logctl_name, lfalt2+lph_pgnumo, 2)), 5)
  1459.                                  /* Page Tail LSN  */
  1460. alt2_tailsn = c2x(charin(logctl_name, lfalt2+lpt_tailsno, lpt_tailsnl))
  1461.  
  1462. /*********************************************
  1463.    Report the Contents of Partial Page 2
  1464.      in the Log Control File
  1465. *********************************************/
  1466.  
  1467. alt2_text = ,
  1468.         '     ' || cr_lf || ,
  1469.         '                        Log Control File ' || cr_lf || ,
  1470.         '     ' || cr_lf || ,
  1471.         '                         Partial Page 2:'  || cr_lf || ,
  1472.         '     ' || cr_lf || ,
  1473.         '     ' || cr_lf || ,
  1474.         '                     Page Number:  ' || alt2_pgnum  || cr_lf || ,
  1475.         '                 Page Header LSN:  ' || alt2_pglsn  || cr_lf || ,
  1476.         '                   Page Tail LSN:  ' || alt2_tailsn || cr_lf || ,
  1477.         '     ' || cr_lf
  1478.  
  1479. call wrt2rpt  alt2_text
  1480.  
  1481. return
  1482.  
  1483. /******************************************************************
  1484. *  SUBROUTINE:   GETDATA_LOGFILEHEAD                              *
  1485. *                                                                 *
  1486. *  DESCRIPTIVE NAME: Get Data from the LOGFILEHEAD Log File       *
  1487. *                                                                 *
  1488. *  DESCRIPTION: This routine determines file name of the          *
  1489. *               LOGFILEHEAD Log File, opens that Log File and     *
  1490. *               retrieves the data from the Log File              *
  1491. *               and stores the Page Header fields in variables.   *
  1492. *                                                                 *
  1493. *  INPUT: none                                                    *
  1494. *                                                                 *
  1495. *                                                                 *
  1496. *  OUTPUT: none                                                   *
  1497. *                                                                 *
  1498. ******************************************************************/
  1499.  
  1500. getdata_logfilehead:
  1501.  
  1502. /*********************************************
  1503.    Construct the LOGFILEHEAD Log File Name
  1504. *********************************************/
  1505. lfhead_name = logpath || 'SQL'
  1506.  
  1507. if length(lfh_lfhead) < 5 then     /* File token less than 5 characters */
  1508.   /* Concatenate leading 0s to the File Token */
  1509.   lfhead_name = lfhead_name || copies('0', 5 - length(lfh_lfhead) )
  1510.  
  1511. lfhead_name = lfhead_name || lfh_lfhead || '.LOG'
  1512.  
  1513. /*********************************************
  1514.    Initialize the LOGFILEHEAD Log File Page LSN
  1515. *********************************************/
  1516. lfhead_pglsn = 0
  1517.  
  1518. /*********************************************
  1519.    Check Existence of LOGFILEHEAD Log File
  1520. *********************************************/
  1521. rc = stream(lfhead_name, 'c', 'query exist')
  1522.  
  1523. if rc = '' then
  1524.   do
  1525.     say 'The LOGFILEHEAD Log File could not be found.'
  1526.     error_text = '     ' || cr_lf || ,
  1527.                  'The LOGFILEHEAD Log File could not be found.' || cr_lf || ,
  1528.                  '     ' || cr_lf
  1529.     call wrt2rpt  error_text
  1530.   end
  1531.  
  1532. else       /* LOGFILEHEAD Log File does exists */
  1533.   do
  1534.  
  1535.     /*********************************************
  1536.        Open the LOGFILEHEAD Log File
  1537.     *********************************************/
  1538.     rc = stream(lfhead_name, 'c', 'open')
  1539.  
  1540.     if (rc = 'READY:') | (rc = 'READY') then
  1541.       do
  1542.         /*********************************************
  1543.            Calculate REXX offset to Start of LOGFILEHEAD
  1544.         *********************************************/
  1545.         lfhead_off = lfh_lfhoff + 1
  1546.  
  1547.         /*********************************************
  1548.            Read the Page Header from the LOGFILEHEAD
  1549.         *********************************************/
  1550.                                  /* Page Header LSN  */
  1551.         lfhead_pglsn = ,
  1552.            c2x(charin(lfhead_name, lfhead_off+lph_pglsno, lph_pglsnl))
  1553.                                  /* Page Number  */
  1554.         lfhead_pgnum = ,
  1555.            c2d(reverse(charin(lfhead_name, lfhead_off+lph_pgnumo+2, 2)) || ,
  1556.                reverse(charin(lfhead_name, lfhead_off+lph_pgnumo, 2)), 5)
  1557.                                  /* Page Tail LSN  */
  1558.         lfhead_tailsn = ,
  1559.            c2x(charin(lfhead_name, lfhead_off+lpt_tailsno, lpt_tailsnl))
  1560.  
  1561.         /*********************************************
  1562.            Report the Contents of the Page Header
  1563.              from LOGFILEHEAD.
  1564.         *********************************************/
  1565.  
  1566.         lfhead_text = ,
  1567.                 '     ' || cr_lf || ,
  1568.                 '                       LOGFILEHEAD Log File' || cr_lf || ,
  1569.                 '     ' || cr_lf || ,
  1570.                 '                       ' || lfhead_name || cr_lf || ,
  1571.                 '                       Log File Page: ' || ,
  1572.                                              (lfh_lfhoff % 4096) || ,
  1573.                                                            cr_lf || ,
  1574.                 '     ' || cr_lf || ,
  1575.                 '     ' || cr_lf || ,
  1576.                 '                     Page Number:  ' || lfhead_pgnum  || ,
  1577.                                                          cr_lf || ,
  1578.                 '                 Page Header LSN:  ' || lfhead_pglsn  || ,
  1579.                                                          cr_lf || ,
  1580.                 '                   Page Tail LSN:  ' || lfhead_tailsn || ,
  1581.                                                          cr_lf || ,
  1582.                 '     ' || cr_lf
  1583.  
  1584.         call wrt2rpt  lfhead_text
  1585.  
  1586.         /*********************************************
  1587.            Close the LOGFILEHEAD Log File
  1588.         *********************************************/
  1589.         rc = stream(lfhead_name, 'c', 'close')
  1590.  
  1591.       end
  1592.   end
  1593.  
  1594. return
  1595.  
  1596. /******************************************************************
  1597. *  SUBROUTINE:   GETDATA_LOGFILETAIL                              *
  1598. *                                                                 *
  1599. *  DESCRIPTIVE NAME: Get Data from the LOGFILETAIL Log File       *
  1600. *                                                                 *
  1601. *  DESCRIPTION: This routine determines file name of the          *
  1602. *               LOGFILETAIL Log File, opens that Log File and     *
  1603. *               retrieves the data from the Log File              *
  1604. *               and stores the Page Header fields in variables.   *
  1605. *                                                                 *
  1606. *  INPUT: none                                                    *
  1607. *                                                                 *
  1608. *                                                                 *
  1609. *  OUTPUT: none                                                   *
  1610. *                                                                 *
  1611. ******************************************************************/
  1612.  
  1613. getdata_logfiletail:
  1614.  
  1615. /*********************************************
  1616.    Construct the LOGFILETAIL Log File Name
  1617. *********************************************/
  1618. lftail_name = logpath || 'SQL'
  1619.  
  1620. if length(lfh_lftail) < 5 then     /* File token less than 5 characters */
  1621.   /* Concatenate leading 0s to the File Token */
  1622.   lftail_name = lftail_name || copies('0', 5 - length(lfh_lftail) )
  1623.  
  1624. lftail_name = lftail_name || lfh_lftail || '.LOG'
  1625.  
  1626. /*********************************************
  1627.    Initialize the LOGFILETAIL Log File Page LSN
  1628. *********************************************/
  1629. lftail_pglsn = 0
  1630.  
  1631. /*********************************************
  1632.    Check Existence of LOGFILETAIL Log File
  1633. *********************************************/
  1634. rc = stream(lftail_name, 'c', 'query exist')
  1635.  
  1636. if rc = '' then
  1637.   do
  1638.     say 'The LOGFILETAIL Log File could not be found.'
  1639.     error_text = '     ' || cr_lf || ,
  1640.                  'The LOGFILETAIL Log File could not be found.' || cr_lf || ,
  1641.                  '     ' || cr_lf
  1642.     call wrt2rpt  error_text
  1643.   end
  1644.  
  1645. else       /* LOGFILETAIL Log File does exists */
  1646.   do
  1647.  
  1648.     /*********************************************
  1649.        Open the LOGFILETAIL Log File
  1650.     *********************************************/
  1651.     rc = stream(lftail_name, 'c', 'open')
  1652.  
  1653.     if (rc = 'READY:') | (rc = 'READY') then
  1654.       do
  1655.  
  1656.         /*********************************************
  1657.            Calculate offset to Last Page of LOGFILETAIL
  1658.         *********************************************/
  1659.         lftail_off = lfh_lftoff + 1
  1660.  
  1661.         /*********************************************
  1662.            Read the Page Header from the LOGFILETAIL
  1663.         *********************************************/
  1664.                                  /* Page Header LSN  */
  1665.         lftail_pglsn = ,
  1666.            c2x(charin(lftail_name, lftail_off+lph_pglsno, lph_pglsnl))
  1667.                                  /* Page Number  */
  1668.         lftail_pgnum = ,
  1669.            c2d(reverse(charin(lftail_name, lftail_off+lph_pgnumo+2, 2)) || ,
  1670.                reverse(charin(lftail_name, lftail_off+lph_pgnumo, 2)), 5)
  1671.                                  /* Page Tail LSN  */
  1672.         lftail_tailsn = ,
  1673.            c2x(charin(lftail_name, lftail_off+lpt_tailsno, lpt_tailsnl))
  1674.  
  1675.         /*********************************************
  1676.            Report the Contents of the Page Header
  1677.              from LOGFILETAIL.
  1678.         *********************************************/
  1679.  
  1680.         lftail_text = ,
  1681.                 '     ' || cr_lf || ,
  1682.                 '                       LOGFILETAIL Log File' || cr_lf || ,
  1683.                 '     ' || cr_lf || ,
  1684.                 '                       ' || lftail_name || cr_lf || ,
  1685.                 '                       Log File Page: ' || ,
  1686.                                               (lfh_lftoff % 4096) || ,
  1687.                                                             cr_lf || ,
  1688.                 '     ' || cr_lf || ,
  1689.                 '     ' || cr_lf || ,
  1690.                 '                     Page Number:  ' || lftail_pgnum || ,
  1691.                                                          cr_lf || ,
  1692.                 '                 Page Header LSN:  ' || lftail_pglsn || ,
  1693.                                                          cr_lf || ,
  1694.                 '                   Page Tail LSN:  ' || lftail_tailsn || ,
  1695.                                                          cr_lf || ,
  1696.                 '     ' || cr_lf
  1697.  
  1698.         call wrt2rpt  lftail_text
  1699.  
  1700.         /*********************************************
  1701.            Close the LOGFILETAIL Log File
  1702.         *********************************************/
  1703.         rc = stream(lftail_name, 'c', 'close')
  1704.  
  1705.       end
  1706.   end
  1707.  
  1708. return
  1709.  
  1710. /******************************************************************
  1711. *  SUBROUTINE:   UPDLSN                                           *
  1712. *                                                                 *
  1713. *  DESCRIPTIVE NAME: Update Base LSN                              *
  1714. *                                                                 *
  1715. *  DESCRIPTION: This routine updates the Base LSN fields in the   *
  1716. *               Log Control File to effectively reset the Log.    *
  1717. *               It sets the Base LSN to the highest LSN value     *
  1718. *               between the Base LSN itself, and the Page LSNs    *
  1719. *               from the Partial Page 1 of the Log Control File,  *
  1720. *               the Partial Page 2 of the Log Control File,       *
  1721. *               the LOGFILEHEAD, and the LOGFILETAIL.             *
  1722. *                                                                 *
  1723. *  INPUT: none                                                    *
  1724. *                                                                 *
  1725. *                                                                 *
  1726. *  OUTPUT: none                                                   *
  1727. *                                                                 *
  1728. ******************************************************************/
  1729. updlsn:
  1730.  
  1731. baselsn_reset = 'NO'      /* Initialize Base LSN reset indicator */
  1732.  
  1733. updlsn_text = ,
  1734.         '     ' || cr_lf || ,
  1735.         '     ' || cr_lf || ,
  1736.         'Base LSN Comparison: ' || cr_lf || ,
  1737.         '     ' || cr_lf || ,
  1738.         '....Base LSN from Log Control File Header:  ' || lfh_baselsn || ,
  1739.                                                           cr_lf || ,
  1740.         '....Page LSN from Log Control File Page 1:  ' || alt1_pglsn  || ,
  1741.                                                           cr_lf || ,
  1742.         '....Page LSN from Log Control File Page 2:  ' || alt2_pglsn  || ,
  1743.                                                           cr_lf || ,
  1744.         '................Page LSN from LOGFILEHEAD:  ' || lfhead_pglsn || ,
  1745.                                                           cr_lf || ,
  1746.         '................Page LSN from LOGFILETAIL:  ' || lftail_pglsn || ,
  1747.                                                           cr_lf || ,
  1748.         '     ' || cr_lf || ,
  1749.         '     ' || cr_lf
  1750.  
  1751. call wrt2rpt  updlsn_text
  1752.  
  1753. /* Reset Base LSN to Partial Page 1 Page LSN if larger */
  1754. if lfh_baselsn < alt1_pglsn then
  1755.   do
  1756.     lfh_baselsn = alt1_pglsn
  1757.     baselsn_reset = 'YES'
  1758.   end
  1759.  
  1760. /* Reset Base LSN to Partial Page 2 Page LSN if larger */
  1761. if lfh_baselsn < alt2_pglsn then
  1762.   do
  1763.     lfh_baselsn = alt2_pglsn
  1764.     baselsn_reset = 'YES'
  1765.   end
  1766.  
  1767. /* Reset Base LSN to LOGFILEHEAD Page LSN if larger */
  1768. if lfh_baselsn < lfhead_pglsn then
  1769.   do
  1770.     lfh_baselsn = lfhead_pglsn
  1771.     baselsn_reset = 'YES'
  1772.   end
  1773.  
  1774. /* Reset Base LSN to LOGFILETAIL Page LSN if larger */
  1775. if lfh_baselsn < lftail_pglsn then
  1776.   do
  1777.     lfh_baselsn = lftail_pglsn
  1778.     baselsn_reset = 'YES'
  1779.   end
  1780.  
  1781. if baselsn_reset = 'NO' then
  1782.   do
  1783.     /* Increment Base LSN by Log File Size Factor if desired */
  1784.     /* Note: This routine may cause the Base LSN to be reset */
  1785.     /*         even though it has not been reset yet.        */
  1786.     call quantum_leap
  1787.   end
  1788.  
  1789. if baselsn_reset = 'NO' then
  1790.   do
  1791.     say 'The Log appears to be in a reset state and has not been changed.'
  1792.     error_text = '     ' || cr_lf || ,
  1793.                  'The Log appears to be in a reset state ' || ,
  1794.                  'and has not been changed.' || cr_lf || ,
  1795.                  '     ' || cr_lf
  1796.     call wrt2rpt  error_text
  1797.   end
  1798. else
  1799.   do
  1800.     /* Write the new Base LSN to the Log Control File */
  1801.     rc = charout(logctl_name, x2c(lfh_baselsn), lfhdr+lfh_baselsno)
  1802.  
  1803.     rst_text = '     ' || cr_lf || ,
  1804.                'The Log has been reset with a new Base LSN of:  ' || ,
  1805.                        lfh_baselsn  || cr_lf || ,
  1806.                '     ' || cr_lf
  1807.     say rst_text
  1808.     call wrt2rpt  rst_text
  1809.   end
  1810.  
  1811. return
  1812.  
  1813. /******************************************************************
  1814. *  SUBROUTINE:   QUANTUM_LEAP                                     *
  1815. *                                                                 *
  1816. *  DESCRIPTIVE NAME: Increment the Base LSN by Log File Size      *
  1817. *                                                                 *
  1818. *  DESCRIPTION: This routine prompts the user to determine        *
  1819. *               if they would like to make a Quantum Leap by      *
  1820. *               incrementing the Base LSN by the size of a single *
  1821. *               Log File.  This may be necessary in some cases    *
  1822. *               (in which there has not been a previous soft      *
  1823. *               checkpoint) because the Log Control File will     *
  1824. *               not have the most current LSN information.        *
  1825. *                                                                 *
  1826. *               By incrementing the Base LSN by the size of a     *
  1827. *               single Log File, it is fairly certain that the    *
  1828. *               Base LSN will be incremented to a value which     *
  1829. *               will truly put it in a reset state.               *
  1830. *                                                                 *
  1831. *                                                                 *
  1832. *  INPUT: none                                                    *
  1833. *                                                                 *
  1834. *                                                                 *
  1835. *  OUTPUT: none                                                   *
  1836. *                                                                 *
  1837. ******************************************************************/
  1838.  
  1839. quantum_leap:
  1840.  
  1841. say "     "
  1842. say ,
  1843.     " ╔══════════════════════════════════════════════════════════════════════╗ "
  1844. say ,
  1845.     " ║                                                                      ║ "
  1846. say ,
  1847.     " ║  From the information in the Log Control File, the Log already       ║ "
  1848. say ,
  1849.     " ║     appears to be in a Reset State.  In certain cases, this may      ║ "
  1850. say ,
  1851.     " ║     be misleading.                                                   ║ "
  1852. say ,
  1853.     " ║  Therefore, would you like to increase the Base LSN in order to      ║ "
  1854. say ,
  1855.     " ║     enhance the probability that the Log has actually been           ║ "
  1856. say ,
  1857.     " ║     reset?  (y/n)                                                    ║ "
  1858. say ,
  1859.     " ║           If so, type 'y' and press ENTER;                           ║ "
  1860. say ,
  1861.     " ║           Otherwise, type 'n' and press ENTER.                       ║ "
  1862. say ,
  1863.     " ║                                                                      ║ "
  1864. say ,
  1865.     " ╚══════════════════════════════════════════════════════════════════════╝ "
  1866. say "      "
  1867. say "      "
  1868. pull quantum_leap_answer
  1869.  
  1870. if quantum_leap_answer = 'Y' then
  1871.   do
  1872.  
  1873.     /* Increase the Base LSN by a factor equal to the size of a Log File */
  1874.     lfh_baselsn = d2x(x2d(lfh_baselsn) + (dbc_logsiz * 4096), (lfh_baselsnl*2))
  1875.  
  1876.     /* Report the Quantum Leap in the Report File */
  1877.     leap_text = '     ' || cr_lf || ,
  1878.                'A Quantum Leap of the Base LSN was requested.  ' || ,
  1879.                '     ' || cr_lf || ,
  1880.                '     ' || cr_lf
  1881.     call wrt2rpt  leap_text
  1882.  
  1883.     /* Set this flag so the new Base LSN will be written to the Log */
  1884.     baselsn_reset = 'YES'
  1885.  
  1886.   end
  1887.  
  1888. return
  1889.  
  1890.  
  1891. /******************************************************************
  1892. *  SUBROUTINE:   GENERAL_HELP                                     *
  1893. *                                                                 *
  1894. *  DESCRIPTIVE NAME: RESETLOG General Help                        *
  1895. *                                                                 *
  1896. *  DESCRIPTION: This routine displays the Help panels for the     *
  1897. *               Reset Log Control File tool.  This routine        *
  1898. *               receives control when the input parameter is      *
  1899. *               a "?" instead of the database name.  A brief      *
  1900. *               description of the RESETLOG Tool and its          *
  1901. *               syntax is included in the Help panels.            *
  1902. *                                                                 *
  1903. *  INPUT: none                                                    *
  1904. *                                                                 *
  1905. *                                                                 *
  1906. *  OUTPUT: none                                                   *
  1907. *                                                                 *
  1908. ******************************************************************/
  1909.  
  1910. general_help:
  1911.  
  1912.   /* Display help panel */
  1913.   say "      "
  1914.   say ,
  1915.   "     ┌────────────────────────────────────────────────────────────┐       "
  1916.   say ,
  1917.   "     │         ┌────────────────────────────────────────┐         │       "
  1918.   say ,
  1919.   "     │         │       *****  E E R E S E T  *****      │         │       "
  1920.   say ,
  1921.   "     │         │        Reset the Log Control File      │         │       "
  1922.   say ,
  1923.   "     │         │               Version 3.1              │         │       "
  1924.   say ,
  1925.   "     │         └────────────────────────────────────────┘         │       "
  1926.   say ,
  1927.   "     │      ▀▀▀▀▀▀▀▀▀▀      ▀▀▀▀▀▀▀▀▀▀       ▀▀▀▀▀     ▀▀▀▀▀      │       "
  1928.   say ,
  1929.   "     │      ▀▀▀▀▀▀▀▀▀▀      ▀▀▀▀▀▀▀▀▀▀▀      ▀▀▀▀▀     ▀▀▀▀▀      │       "
  1930.   say ,
  1931.   "     │         ▀▀▀▀          ▀▀▀   ▀▀▀▀       ▀▀▀▀▀   ▀▀▀▀▀       │       "
  1932.   say ,
  1933.   "     │         ▀▀▀▀          ▀▀▀▀▀▀▀▀▀        ▀▀▀▀▀▀ ▀▀▀▀▀▀       │       "
  1934.   say ,
  1935.   "     │         ▀▀▀▀          ▀▀▀▀▀▀▀▀▀        ▀▀▀ ▀▀▀▀▀ ▀▀▀       │       "
  1936.   say ,
  1937.   "     │         ▀▀▀▀          ▀▀▀   ▀▀▀▀       ▀▀▀  ▀▀▀  ▀▀▀       │       "
  1938.   say ,
  1939.   "     │      ▀▀▀▀▀▀▀▀▀▀      ▀▀▀▀▀▀▀▀▀▀▀      ▀▀▀▀   ▀   ▀▀▀▀      │       "
  1940.   say ,
  1941.   "     │      ▀▀▀▀▀▀▀▀▀▀      ▀▀▀▀▀▀▀▀▀▀       ▀▀▀▀       ▀▀▀▀      │       "
  1942.   say ,
  1943.   "     └────────────────────────────────────────────────────────────┘       "
  1944.   say ,
  1945.   " ╔══════════════════════════════════════════════════════════════════════╗ "
  1946.   say ,
  1947.   " ║  The EERESET Tool is a mechanism for resetting the Log Control       ║ "
  1948.   say ,
  1949.   " ║  File which governs the recovery of the database from the            ║ "
  1950.   say ,
  1951.   " ║  Write-Ahead Log.  By reseting  the Log Control File,  the database  ║ "
  1952.   say ,
  1953.   " ║  will appear to be usable and not need recovery.                     ║ "
  1954.   say ,
  1955.   " ║  CAUTION:  The use of this tool will prevent committed changes       ║ "
  1956.   say ,
  1957.   " ║  which did not make it to media from being recovered and data        ║ "
  1958.   say ,
  1959.   " ║  integrity could be lost.                                            ║ "
  1960.   say ,
  1961.   " ╚══════════════════════════════════════════════════════════════════════╝ "
  1962.   say "      "
  1963.   'pause'
  1964.   say "      "
  1965.   say "      "
  1966.   say "      "
  1967.   say "      "
  1968.   say ,
  1969.   "      Syntax:   EERESET   [dbname]  [rptname]                             "
  1970.   say "      "
  1971.   say "      "
  1972.   say ,
  1973.   "       where:   [dbname]   is the alias name of the database.             "
  1974.   say "                       If no database name is specified , the user    "
  1975.   say "                          will be prompted for the database name.     "
  1976.   say "      "
  1977.   say "      "
  1978.   say ,
  1979.   "                [rptname]  is the report file name.                       "
  1980.   say "                       If no report file name is specified, then no   "
  1981.   say "                          report will be generated.                   "
  1982.   say "      "
  1983.   say "      "
  1984.   say "      "
  1985.   say "      "
  1986.   say "      "
  1987.   say "      "
  1988.   say "      "
  1989.   say "      "
  1990.  
  1991.  
  1992.   return
  1993.