/*******************************************************************************
**
** Source File Name = db2mon.c
**
** Licensed Materials - Property of IBM
**
** (C) COPYRIGHT International Business Machines Corp. 1995, 2000
** All Rights Reserved.
**
** US Government Users Restricted Rights - Use, duplication or
** disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
**
**
** PURPOSE: This sample program demonstrates how to use the Database
**          System Monitor APIs, and how to process the output data
**          buffer returned from the Snapshot API.
**          It is a menu-driven program that allows the user to
**          access the functionality of the Database System
**          Monitor APIs:
**            - Turn ON/OFF any of the monitoring groups
**            - Reset data areas for specific databases or all
**              active databases
**            - Monitor DB2 activity in a wide variety of
**              object combinations.
**
** STRUCTURES USED :
**   sqlma
**   sqlm_collected
**   sqlm_recording_group
**   sqlca
**
** MONOTOR APIs USED:
**        GET/UPDATE MONITOR SWITCHES               sqlmon()
**        GET SNAPSHOT                              sqlmonss()
**        ESTIMATE SIZE REQUIRED FOR
**              sqlmonss() OUTPUT BUFFER            sqlmonsz()
**        RESET MONOTOR                             sqlmrset()                 
**        
**
** OTHER APIs USED:
**        INSTANCE ATTACH                           sqleatin()
**
** RUN:   To run this sample, just enter "db2mon" and follow the
**        on-screen menus. Ensure that DB2 has been started
**        before attempting to monitor any activity.
**
**    EXTERNAL DEPENDENCIES :
**       - Ensure existence of database for precompile purposes.
**       - Compile and link with the IBM Cset++ compiler (AIX and OS/2)
**         or the Microsoft Visual C++ compiler (Windows)
**         or the compiler supported on your platform.
**
**
** For more information about these samples see the README file.
**
** For more information on programming in C, see the:
**   -  "Programming in C and C++" section of the Application Development Guide
** For more information on Building C Applications, see the:
**   -  "Building C Applications" section of the Application Building Guide.
**
** For more information on the SQL language see the SQL Reference.
**
*******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "sqlenv.h"
#include "sqlmon.h"
#include "sqlca.h"
#include "sqlutil.h"

#if (defined(DB2AIX) || defined(DB2SCO) || defined(DB2SUN) || defined(DB2HP) || defined(DB2SNI) || defined(DB2IRIX) || defined(DB2LINUX))
   #define CLEARSCR      "clear"
   #define min(a, b) ((a < b) ? a : b)
#else
   #define CLEARSCR      "cls"
#endif


/*****************************************************************************/
/* Constants definitions                                                     */
/*****************************************************************************/
#define SCREEN_OUTPUT   1                   /* output data to screen         */
#define FILE_OUTPUT     2                   /* output data to user file      */

/*****************************************************************************/
/* Internal Function Prototypes                                              */
/*****************************************************************************/
int dbmon_switch();
int dbmon_reset();
int dbmon_snapshot();
void pause();
void clrscrn();
void pr_sqlca(struct sqlca *);
void process_db2();
void process_dbase();
void process_appl();
void process_applinfo();
void process_dcs_applinfo();
void process_table();
void process_lock();
void process_tablespace();
void process_dcs_app();
void cleanup(struct sqlma *ma_ptr);

/*****************************************************************************/
/*  Global Variables                                                         */
/*****************************************************************************/

FILE                  *outstream;       /* output stream if directed to file */
unsigned int          output_opt = SCREEN_OUTPUT; /* output to screen or file*/

struct sqlm_collected collected;        /* returned sqlm_collected structure */
char                  *buffer_ptr = NULL; /* buffer returned from snapshot   */
char                  *buffer_index;    /* current position in buffer        */
sqluint32              buffer_sz;       /* Estimated buffer size             */

/*****************************************************************************/
/* MAIN routine.                                                             */
/*****************************************************************************/

int main( int argc, char *argv[], char *envp[])
{

   int                   ssout= 0;            /* exit flag                  */
   int                   ssrc= 0;             /* program return code        */
   unsigned int          numsel = 999;        /* numeric input selection    */
   struct sqlca          sqlca;

   char userid[9];
   char passwd[19];
   char nodename[9];

   if (argc == 4) {
      strcpy (userid, argv[1]);
      strcpy (passwd, argv[2]);
      strcpy (nodename, argv[3]);

      /*************************/
      /* ATTACH API called     */
      /*************************/
      sqleatin (nodename, userid, passwd, &sqlca);
   }

   else if (argc != 1) {
      printf ("\nUSAGE: db2mon [userid passwd remote_nodename]\n");
      return 1;
   }

   /*************************************************************************/
   /* initialize outstream for screen output                                */
   /*************************************************************************/
   outstream = stdout;

   /*************************************************************************/
   /* Perform main loop until users wants to exit.                          */
   /*************************************************************************/

   while (!ssout)
   {
      clrscrn();
      printf("******************************************************************************\n");
      printf("****                                                                      ****\n");
      printf("****                 DB2 DATABASE MONITOR SAMPLE PROGRAM                  ****\n");
      printf("****                                                                      ****\n");
      printf("******************************************************************************\n");

      while (numsel < 0 || numsel > 3)
      {
         printf("\nPlease choose one of the following options:\n\n");
         printf("    1 - Turn ON/OFF monitoring switches\n");
         printf("    2 - Reset data areas\n");
         printf("    3 - Get a Snapshot\n");
         printf("    0 - Exit the Database Monitor sample program\n");

         fflush(stdin);
         scanf("%u", &numsel);
         if (numsel < 0 || numsel > 3)
            printf("\nInvalid selection. Please choose again.\n");

      }  /* while */

      /**********************************************************************/
      /* Process user selection                                             */
      /**********************************************************************/
      switch (numsel)
      {
         case 0:
              ssout = 1;
              break;

         case 1:
              ssrc = dbmon_switch();
              if (ssrc != 0)
              {
                 printf("\nreturn code from dbmon_switch : %i\n", ssrc);
                 pause();
              }
              break;

         case 2:
              ssrc = dbmon_reset();
              if (ssrc != 0)
              {
                 printf("\nreturn code from dbmon_reset : %i\n", ssrc);
                 pause();
              }
              break;

         case 3:
              ssrc = dbmon_snapshot();
              if (ssrc != 0)
              {
                 printf("\nreturn code from dbmon_snapshot : %i\n", ssrc);
                 pause();
              }
              break;

         default:
              break;

      }  /* switch numsel */

      numsel = 999;

   }  /* while !ssout */

   return 0;
}


/*****************************************************************************/
/* dbmon_switch.                                                             */
/* This function is called when the user wants to turn ON or OFF any of      */
/* the Database Monitor groups.                                              */
/*****************************************************************************/

int dbmon_switch()
{

   unsigned int          numsel = 999;        /* numeric input selection    */
   unsigned int          numsel2 = 999;       /* numeric input selection    */
   unsigned int          i;                   /* loop counter               */
   int                   rc = 0;              /* return code                */
   struct sqlca          sqlca;
   struct sqlm_recording_group states[SQLM_NUM_GROUPS];

   clrscrn();
   printf("******************************************************************************\n");
   printf("*                         Database Monitor Switch                            *\n");
   printf("******************************************************************************\n");

   /********************************************************/
   /* Query the current state of the switches              */
   /********************************************************/
   for (i = 0; i < SQLM_NUM_GROUPS; i++)
   {
      states[i].input_state = SQLM_HOLD;
   }

   rc = sqlmon(SQLM_DBMON_VERSION5_2, NULL, states, &sqlca);
   if (rc != 0)
   {
      printf("\nReturn code from SQLMON is %d \n", rc);
      return(rc);
   }

   if (sqlca.sqlcode != 0L)
   {
      printf("\nSqlcode from SQLMON is not 0. \n");
      pr_sqlca(&sqlca);
   }

   /********************************************************/
   /* Display the current state of the switches            */
   /********************************************************/
   printf("\nCurrent Switch settings:\n");

   printf("1 - UOW Switch state       : %s %24.24s\n", (states[0].output_state) ? "ON , start time :" : "OFF",
                                     (states[0].start_time.seconds) ? ctime((time_t *)&states[0].start_time.seconds) : "");
   printf("2 - STMT Switch state      : %s %24.24s\n", (states[1].output_state) ? "ON , start time :" : "OFF",
                                     (states[1].start_time.seconds) ? ctime((time_t *)&states[1].start_time.seconds) : "");
   printf("3 - TABLE Switch state     : %s %24.24s\n", (states[2].output_state) ? "ON , start time :" : "OFF",
                                     (states[2].start_time.seconds) ? ctime((time_t *)&states[2].start_time.seconds) : "");
   printf("4 - BUFF POOL Switch state : %s %24.24s\n", (states[3].output_state) ? "ON , start time :" : "OFF",
                                     (states[3].start_time.seconds) ? ctime((time_t *)&states[3].start_time.seconds) : "");
   printf("5 - LOCK Switch state      : %s %24.24s\n", (states[4].output_state) ? "ON , start time :" : "OFF",
                                     (states[4].start_time.seconds) ? ctime((time_t *)&states[4].start_time.seconds) : "");
   printf("6 - SORT Switch state      : %s %24.24s\n", (states[5].output_state) ? "ON , start time :" : "OFF",
                                     (states[5].start_time.seconds) ? ctime((time_t *)&states[5].start_time.seconds) : "");


   for (i = 0; i < SQLM_NUM_GROUPS; i++)
   {
      states[i].input_state = SQLM_HOLD;
   }

   /**************************************************************/
   /* loop to let user select switches to be turned ON or OFF    */
   /**************************************************************/
   do
   {
      printf("\nPlease enter the switch number you wish to set:\n");
      printf("This function toggles the switch state ON/OFF.\n");
      printf("   Enter 0 when you are done with your selections.\n");

      fflush(stdin);
      scanf("%u", &numsel);
      if (numsel < 0 || numsel > 6)
         printf("\nInvalid selection. Please try again.\n");
      else
         if (numsel != 0)
         {
            if (states[numsel-1].output_state == SQLM_ON)
                states[numsel-1].input_state = SQLM_OFF;
            else
                states[numsel-1].input_state = SQLM_ON;

         } /* if */

   } while (numsel != 0);

   /********************************************************/
   /* Set new switch states                                */
   /********************************************************/
   rc = sqlmon(SQLM_DBMON_VERSION5_2, NULL, states, &sqlca);
   if (rc != 0)
   {
      printf("\nReturn code from SQLMON is %d \n", rc);
      return(rc);
   }

   if (sqlca.sqlcode != 0L)
   {
      printf("\nSqlcode from SQLMON is not 0. \n");
      pr_sqlca(&sqlca);
      if (sqlca.sqlcode < 0L)             /* negative sqlcodes are errors    */
      {
         printf("Negative sqlcode... exiting\n");
         return((int)sqlca.sqlcode);
      }
      pause();
   }

   /********************************************************/
   /* Display new switch states                            */
   /********************************************************/
   printf("\nNew states:\n");
   printf("1 - UOW Switch state       : %s %24.24s\n", (states[0].output_state) ? "ON , start time :" : "OFF",
                                     (states[0].start_time.seconds) ? ctime((time_t *)&states[0].start_time.seconds) : "");
   printf("2 - STMT Switch state      : %s %24.24s\n", (states[1].output_state) ? "ON , start time :" : "OFF",
                                     (states[1].start_time.seconds) ? ctime((time_t *)&states[1].start_time.seconds) : "");
   printf("3 - TABLE Switch state     : %s %24.24s\n", (states[2].output_state) ? "ON , start time :" : "OFF",
                                     (states[2].start_time.seconds) ? ctime((time_t *)&states[2].start_time.seconds) : "");
   printf("4 - BUFF POOL Switch state : %s %24.24s\n", (states[3].output_state) ? "ON , start time :" : "OFF",
                                     (states[3].start_time.seconds) ? ctime((time_t *)&states[3].start_time.seconds) : "");
   printf("5 - LOCK Switch state      : %s %24.24s\n", (states[4].output_state) ? "ON , start time :" : "OFF",
                                     (states[4].start_time.seconds) ? ctime((time_t *)&states[4].start_time.seconds) : "");
   printf("6 - SORT Switch state      : %s %24.24s\n", (states[5].output_state) ? "ON , start time :" : "OFF",
                                     (states[5].start_time.seconds) ? ctime((time_t *)&states[5].start_time.seconds) : "");

   pause();

   return(0);

}  /* dbmon_switch() */

/*****************************************************************************/
/* dbmon_reset.                                                              */
/* This function is called when the user wants to reset Database Monitor     */
/* data areas.                                                               */
/*****************************************************************************/

int dbmon_reset()
{

   unsigned int          numsel = 999;                  /* numeric input selection    */
   sqluint32             reset_all;                     /* reset indicator            */
   int                   rc = 0;                        /* return code                */
   struct sqlca          sqlca;
   char                  db_alias[SQLM_IDENT_SZ];       /* input database alias       */

   clrscrn();
   printf("******************************************************************************\n");
   printf("*                         Database Monitor Reset                             *\n");
   printf("******************************************************************************\n");

   do
   {
      printf("\nDo you wish to reset data areas for :\n");
      printf("   1 - a specifc database, or\n");
      printf("   2 - all active databases ?\n");
      printf("   (Press 0 to exit to return to the previous menu)\n");

      fflush(stdin);
      scanf("%u", &numsel);
      if (numsel < 0 || numsel > 2)
         printf ("\nInvalid selection. Please try again.\n");
   } while (numsel < 0 || numsel > 2);

   switch (numsel)
   {
      case 0:
          return(0);
          break;
      case 1:
          reset_all = SQLM_OFF;
          printf("\nPlease enter the database alias of the database you wish to reset:\n");

          fflush(stdin);
          scanf("%s", db_alias);
          break;
      case 2:
          reset_all = SQLM_ON;
          break;
      default:
          printf("\nError in Reset... should not happen... exiting...\n");
          exit(99);
          break;
   }  /* switch numsel */

   /***************************************************************/
   /* Reset the Database Monitor data areas                       */
   /***************************************************************/
   rc = sqlmrset(SQLM_DBMON_VERSION5_2, NULL, reset_all, db_alias, &sqlca);

   if (rc != 0)
   {
      printf("\nReturn code from SQLMONRSET is %d \n", rc);
      return(rc);
   }

   if (sqlca.sqlcode != 0L)
   {
      printf("\nSqlcode from SQLMRSET is not 0. \n");
      pr_sqlca(&sqlca);
      if (sqlca.sqlcode < 0L)             /* negative sqlcodes are errors    */
      {
         printf("Negative sqlcode... exiting\n");
         return((int)sqlca.sqlcode);
      }
   }
   else
      printf("\nReset was successful. \n");

   pause();

   return(0);

}  /* dbmon_reset() */

/*****************************************************************************/
/* dbmon_snapshot                                                            */
/* This function is called when the user wishes to perform a Database        */
/* Monitor Snapshot.                                                         */
/* The user will select the types of information the snapshot will collect   */
/* and return in the buffer.                                                 */
/*****************************************************************************/

int dbmon_snapshot()
{

   time_t                ltime;
   unsigned int          ma_sz;               /* size of sqlma structure    */
   unsigned int          input_opt;
   unsigned int          obj_num = 0;         /* # of objects to monitor    */
   unsigned int          numstruct = 0;       /* # of structures returned   */
   unsigned int          i;                   /* loop counter               */
   int                   rc = 0;              /* return code                */
   int                   ssrc= 0;             /* driver return code         */
   char                  outfilename[81];     /* name for data output file  */
   struct sqlca          sqlca;
   struct sqlma          *ma_ptr = NULL;      /* sqlma structure pointer    */

   struct ma_unit                             /* working sqlma element      */
   {
      sqluint32          agent_id;
      sqluint32          obj_type;
      char               object[SQLM_OBJECT_SZ];
      struct ma_unit     *next;
   };

   struct ma_unit        ma_unit_head;
   struct ma_unit        *ma_unit_ptr;
   struct ma_unit        *free_ptr;


   /**************************************************************************/
   /* Initialize various character arrays to nulls                           */
   /**************************************************************************/

   memset(&collected, '\0', sizeof(struct sqlm_collected));
   memset(outfilename, '\0', sizeof(outfilename));

   /**************************************************************************/
   /* Prompt the user for the tpyes of objects to monitor                    */
   /**************************************************************************/

   do {

      clrscrn();
      printf("******************************************************************************\n");
      printf("*                         Database Monitor Snapshot                          *\n");
      printf("******************************************************************************\n");

      printf("\nPlease choose the type of object to monitor.\n");
      printf("You can choose as many as you want, one at a time\n");
      printf("\n  Enter 0 when done with your selections\n");
      printf("   1 --- General information for DB2\n");
      printf("   2 --- Information for a specific DATABASE\n");
      printf("   3 --- Information for a specific APPLICATION (by APPL-ID)\n");
      printf("   4 --- Information for a specific APPLICATION (by AGENT-ID)\n");
      printf("   5 --- TABLE information for a specific database\n");
      printf("   6 --- APPLICATION information for a SPECIFIC DATABASE\n");
      printf("   7 --- SUMMARY APPLICATION information for a SPECIFIC DATABASE\n");
      printf("   8 --- LOCK information for a specific database\n");
      printf("   9 --- Information for ALL ACTIVE DATABASES\n");
      printf("  10 --- Information for ALL ACTIVE APPLICATIONS\n");
      printf("  11 --- SUMMARY information for ALL ACTIVE APPLICATIONS\n");
      printf("  12 --- Information for ALL ACTIVE DCS APPLICATIONS\n");
      printf("  13 --- TABLESPACE information for a SPECIFIC DATABASE\n");
      printf("  14 --- Information about a specific DCS application (by APPL. HANDLE)\n");
      printf("Please enter the number of your choice==> ");

      fflush(stdin);
      scanf("%u", &input_opt);

      /*******************************************************/
      /* If the user entered a vaild number, allocate        */
      /* memory for working temporary sqlma information      */
      /*******************************************************/
      if (input_opt > 0 && input_opt <= 14)
      {
         obj_num++;     /* increment # of objects to monitor */
         if (obj_num == 1)
         {
            ma_unit_ptr = &ma_unit_head;
         }
         else
         {
            ma_unit_ptr->next =
               (struct ma_unit *) malloc(sizeof(struct ma_unit));
            if (ma_unit_ptr->next != NULL)
            {
               ma_unit_ptr = ma_unit_ptr->next;
               memset(ma_unit_ptr, '\0', sizeof(struct ma_unit));
            }
            else
            {
               printf("error allocating ma_unit memory. Exiting\n");
               return(99);
            }
         } /* else */
      } /* if */

      /********************************************************/
      /* Fill in temporary sqlma info with user choice        */
      /********************************************************/
      switch (input_opt)
      {
        case 0:

          break;
        case 1:
          ma_unit_ptr->obj_type = SQLMA_DB2;
          ma_unit_ptr->agent_id = 0L;
          break;
        case 2:
          ma_unit_ptr->obj_type = SQLMA_DBASE;
          printf("\nPlease enter the database alias name ==> ");

          fflush(stdin);
          scanf("%s", ma_unit_ptr->object);
          ma_unit_ptr->agent_id = 0L;
          break;
        case 3 :
          ma_unit_ptr->obj_type = SQLMA_APPL;
          printf("\nPlease enter the application ID ==> ");

          fflush(stdin);
          scanf("%s", ma_unit_ptr->object);
          ma_unit_ptr->agent_id = 0L;
          break;
        case 4 :
          ma_unit_ptr->obj_type = SQLMA_AGENT_ID;
          printf("\nPlease enter the agent ID ==> ");

          fflush(stdin);
          scanf("%ul", &(ma_unit_ptr->agent_id));
          break;
        case 5:
          ma_unit_ptr->obj_type = SQLMA_DBASE_TABLES;
          printf("\nPlease enter the database alias name ==> ");

          fflush(stdin);
          scanf("%s", ma_unit_ptr->object);
          ma_unit_ptr->agent_id = 0L;
          break;
        case 6:
          ma_unit_ptr->obj_type = SQLMA_DBASE_APPLS;
          printf("\nPlease enter the database alias name ==> ");

          fflush(stdin);
          scanf("%s", ma_unit_ptr->object);
          ma_unit_ptr->agent_id = 0L;
          break;
        case 7:
          ma_unit_ptr->obj_type = SQLMA_DBASE_APPLINFO;
          printf("\nPlease enter the database alias name ==> ");

          fflush(stdin);
          scanf("%s", ma_unit_ptr->object);
          ma_unit_ptr->agent_id = 0L;
          break;
        case 8:
          ma_unit_ptr->obj_type = SQLMA_DBASE_LOCKS;
          printf("\nPlease enter the database alias name ==> ");

          fflush(stdin);
          scanf("%s", ma_unit_ptr->object);
          ma_unit_ptr->agent_id = 0L;
          break;
        case 9:
          ma_unit_ptr->obj_type = SQLMA_DBASE_ALL;
          ma_unit_ptr->agent_id = 0L;
          break;
        case 10:
          ma_unit_ptr->obj_type = SQLMA_APPL_ALL;
          ma_unit_ptr->agent_id = 0L;
          break;
        case 11:
          ma_unit_ptr->obj_type = SQLMA_APPLINFO_ALL;
          ma_unit_ptr->agent_id = 0L;
          break;
        case 12:
          ma_unit_ptr->obj_type = SQLMA_DCS_APPLINFO_ALL;
          ma_unit_ptr->agent_id = 0L;
          break;
        case 13:
          ma_unit_ptr->obj_type = SQLMA_DBASE_TABLESPACES;
          printf("\nPlease enter the database alias name ==> ");

          fflush(stdin);
          scanf("%s", ma_unit_ptr->object);
          ma_unit_ptr->agent_id = 0L;
          break;
        case 14 :
          ma_unit_ptr->obj_type = SQLMA_DCS_APPL_HANDLE;
          printf("\nPlease enter the DCS application handle ==> ");

          fflush(stdin);
          scanf("%ul", &(ma_unit_ptr->agent_id));
          break;
        default:
          printf("\n\nThe input selection is not valid. Please try again.\n");
          pause();
          break;
      } /* end switch */

   } while ( input_opt != 0 ); /* enddo */

   /********************************************************************/
   /* transfer user selections to sqlma structure                      */
   /********************************************************************/

   if (obj_num == 0)
      return(0);

   /* Determine required size for sqlma structure */
   ma_sz = SQLMASIZE(obj_num);
   ma_ptr = (struct sqlma *) malloc(ma_sz);
   if ( ma_ptr == NULL)
   {
      printf("error allocating sqlma. Exiting.\n");
      return(99);
   }

   /* Initialize sqlma structure to nulls  */
   memset(ma_ptr, '\0', ma_sz);
   ma_ptr->obj_num = obj_num;

   ma_unit_ptr = &ma_unit_head;
   for (i = 0; i < obj_num; i++)
   {
      ma_ptr->obj_var[i].agent_id = ma_unit_ptr->agent_id;
      ma_ptr->obj_var[i].obj_type = ma_unit_ptr->obj_type;
      strncpy((char *)ma_ptr->obj_var[i].object,
              (char *)ma_unit_ptr->object,
               SQLM_OBJECT_SZ);
      free_ptr = ma_unit_ptr;        /* remember pointer before going to next */
      ma_unit_ptr = ma_unit_ptr->next;
      if (i != 0)
         free(free_ptr);                             /* free memory when done */
   }

   /***************************************************************************/
   /* Selection of output destination. The user can have the snapshot         */
   /* output sent either to the screen or to an output file of their choice.  */
   /* All output will be written out using "fprintf". This code will either   */
   /* assign stdout to outstream for screen output or open the appropriate    */
   /* file.                                                                   */
   /***************************************************************************/

   clrscrn();
   do
   {
     printf("\n\nPlease select output destination (0 to exit now):\n");
     printf("           %u : screen\n", SCREEN_OUTPUT);
     printf("           %u : file\n", FILE_OUTPUT);
     printf("           ==>");

     fflush(stdin);
     scanf("%u", &output_opt);
     switch (output_opt)
     {
       case SCREEN_OUTPUT :
               outstream = stdout;
               break;
       case FILE_OUTPUT :
               printf("\nNew results will be appended to existing file, if any.\n");
               printf("Please enter filename of the output file (80 chars max): ");

               fflush(stdin);
               scanf("%s", &outfilename);
               outstream = fopen(outfilename, "a");
               if (outstream == NULL)
               {
                 printf("\nERROR opening output file. Output defaults to SCREEN.\n");
                 output_opt = SCREEN_OUTPUT;
                 outstream = stdout;
                 pause();
               }
               break;
       case 0 :
               printf("Exiting...\n");
               return(0);
               break;
       default :
               printf("\nInvalid selection. Please try again.\n");
               break;
     } /* end switch(output_opt) */

   } while (output_opt < 1 | output_opt > 2);

   /**************************************************************************/
   /* Call the Database Monitor Estimate Buffer Size API to determine the    */
   /* size of the buffer required to store the Snapshot Monitor data.        */
   /**************************************************************************/

   rc = sqlmonsz(SQLM_DBMON_VERSION5_2, NULL, ma_ptr, &buffer_sz, &sqlca);

   if (rc != 0)
   {
      printf("\nReturn code from SQLMONSZ is %d \n", rc);
      return(rc);
   }
   if (sqlca.sqlcode != 0L)
   {
      printf("\nSqlcode from SQLMONSZ is not 0. \n");
      pr_sqlca(&sqlca);
      if (sqlca.sqlcode < 0L)             /* negative sqlcodes are errors    */
      {
         printf("Negative sqlcode... exiting\n");
         cleanup(ma_ptr);
         return((int)sqlca.sqlcode);
      }
      pause();
   }

   if (buffer_sz == 0)
   {
      return(0);
   }

   buffer_ptr = (char *) malloc(buffer_sz);    /* allocate buffer           */
   if (buffer_ptr == NULL)
   {
       printf("Error allocating memory for buffer area... exiting\n");
       cleanup(ma_ptr);
       return(99);
   }
   memset(buffer_ptr, '\0', buffer_sz);   /* set contents to nulls          */

   /**************************************************************************/
   /* Call Snapshot Monitor and verify the return codes.                     */
   /* If rc return code from call to the Snapshot Monitor api is non-zero,   */
   /* exit the sample program.                                               */
   /* A non-zero sqlcode is not necessarily an error. If the sqlcode is      */
   /* negative, than it is an error and db2mon exits. If the sqlcode is      */
   /* positive, than processing continues. In both cases, the contents of    */
   /* the sqlca are displayed on the screen.                                 */
   /* Note that in version2 snapshots, agent_id (application handle) is the  */
   /* id of the agent on the server. In version 5 and later this value is    */
   /* no longer the agent id. If you wish to use the agent_id field to take  */
   /* snapshots for a version 5 server, you must take a version 5 level      */
   /* snapshot.                                                              */
   /**************************************************************************/

   rc = sqlmonss(SQLM_DBMON_VERSION5_2, NULL, ma_ptr, buffer_sz, buffer_ptr,
                 &collected, &sqlca);

   if (rc != 0)
   {
      printf("\nReturn code from SQLMONSS is %d \n", rc);
      cleanup(ma_ptr);
      return(rc);
   }

   if (sqlca.sqlcode != 0L)
   {
      printf("\nSqlcode from SQLMONSS is not 0. \n");
      pr_sqlca(&sqlca);
      if (sqlca.sqlcode < 0L)             /* negative sqlcodes are errors    */
      {
         printf("Negative sqlcode... exiting\n");
         cleanup(ma_ptr);
         return((int)sqlca.sqlcode);
      }
      pause();
   }


   /**************************************************************************/
   /* Print out some general information about the results.                  */
   /* This information is contained in the sqlm_collected data structure     */
   /* returned from the call to sqlmonss. It is not part of the output       */
   /* buffer.                                                                */
   /**************************************************************************/

   if (output_opt == SCREEN_OUTPUT)
      clrscrn();

   fprintf(outstream, "**********************************************************************\n");
   fprintf(outstream, "*                         GENERAL INFORMATION                        *\n");
   fprintf(outstream, "**********************************************************************\n");


  ltime  = collected.time_stamp.seconds;
  fprintf(outstream, "Time Stamp of the Snapshot call          ===> %24.24s\n", (ltime) ? ctime(<ime) : "");

  switch (collected.server_db2_type)
  {
     case SQLF_NT_SERVER:
          fprintf(outstream, "Server Type                              ===> Server with Local and Remote Clients\n");
          break;
     case SQLF_NT_STAND_REQ:
          fprintf(outstream, "Server Type                              ===> Server with Local Clients \n");
          break;
     case SQLF_NT_SATELLITE:
          fprintf(outstream, "Server Type                              ===> Satellite Server with Local Clients \n");
          break;
     case SQLF_NT_MPP:
          fprintf(outstream, "Server Type                              ===> Partitioned Server with Local and Remote Clients \n");
          break;
     default:
          fprintf(outstream, "Server Type                              ===> UNKNOWN(%lu)\n", collected.server_db2_type);
          break;
  }  /* switch */

  fprintf(outstream, "Product Signature (prdid)                ===> %0.*s\n", SQLM_IDENT_SZ, collected.server_prdid);
  fprintf(outstream, "Server Instance Name                     ===> %0.*s\n", SQLM_IDENT_SZ, collected.server_instance_name);

  fprintf(outstream, "\nMonitor Switch settings:\n");

  fprintf(outstream, "1 - UOW Switch state       : %s %24.24s\n", (collected.group_states[0].output_state) ? "ON , start time :" : "OFF",
                     (collected.group_states[0].start_time.seconds) ? ctime((time_t *)&collected.group_states[0].start_time.seconds) : "");
  fprintf(outstream, "2 - STMT Switch state      : %s %24.24s\n", (collected.group_states[1].output_state) ? "ON , start time :" : "OFF",
                     (collected.group_states[1].start_time.seconds) ? ctime((time_t *)&collected.group_states[1].start_time.seconds) : "");
  fprintf(outstream, "3 - TABLE Switch state     : %s %24.24s\n", (collected.group_states[2].output_state) ? "ON , start time :" : "OFF",
                     (collected.group_states[2].start_time.seconds) ? ctime((time_t *)&collected.group_states[2].start_time.seconds) : "");
  fprintf(outstream, "4 - BUFF POOL Switch state : %s %24.24s\n", (collected.group_states[3].output_state) ? "ON , start time :" : "OFF",
                     (collected.group_states[3].start_time.seconds) ? ctime((time_t *)&collected.group_states[3].start_time.seconds) : "");
  fprintf(outstream, "5 - LOCK Switch state      : %s %24.24s\n", (collected.group_states[4].output_state) ? "ON , start time :" : "OFF",
                     (collected.group_states[4].start_time.seconds) ? ctime((time_t *)&collected.group_states[4].start_time.seconds) : "");
  fprintf(outstream, "6 - SORT Switch state      : %s %24.24s\n", (collected.group_states[5].output_state) ? "ON , start time :" : "OFF",
                     (collected.group_states[5].start_time.seconds) ? ctime((time_t *)&collected.group_states[5].start_time.seconds) : "");


  if (output_opt == SCREEN_OUTPUT)
     pause();

   /**************************************************************************/
   /* Process the buffer returned from Snapshot Monitor API.                 */
   /* The buffer will contain the data structures of the objects that were   */
   /* monitored. The first 4 bytes of each structure indicates its size and  */
   /* the next character identifies the type of information returned.        */
   /* The program goes through the whole buffer, processing each structure as*/
   /* it encounters it. It first determines what type of information it      */
   /* currently points to, then processes it accordingly. After processing   */
   /* a structure, it advances in the buffer to the next one, until it       */
   /* has processed the whole buffer.                                        */
   /* Processing is complete when all returned structures have been          */
   /* processed, as indicated by the numbers in the sqlm_collected data      */
   /* structure.                                                             */
   /**************************************************************************/

   /* add up all the structures returned in the buffer */
   numstruct = collected.num_top_level_structs;

   buffer_index = buffer_ptr;

   /* loop until all data structures have been processed */
   while (numstruct > 0)
   {
     /* Determine the type of structure at current position in the buffer    */
     switch ((unsigned char)*(buffer_index + 4))
     {
       case SQLM_DB2_SS:                  /* DB2 information                 */
         process_db2();
         break;
       case SQLM_DBASE_SS:                /* Database information            */
         process_dbase();
         break;
       case SQLM_APPL_SS:                 /* Application information         */
         process_appl();
         break;
       case SQLM_TABLE_HEADER_SS:         /* Table information               */
         process_table();
         break;
       case SQLM_DBASE_LOCK_SS:           /* Lock information                */
         process_lock();
         break;
       case SQLM_APPLINFO_SS:             /* Summary application information */
         process_applinfo();
         break;
       case SQLM_DCS_APPLINFO_SS:         /* List DCS applications info      */
         process_dcs_applinfo();
         break;
       case SQLM_TABLESPACE_HEADER_SS:    /* Tablespace information          */
         process_tablespace();
         break;
       case SQLM_DCS_APPL_SS:             /* DCS application information     */
         process_dcs_app();
         break;
       default:                           /* Unexpected data in buffer       */
         printf("\n\n***************************************************************\n");
         printf("*    ERROR processing output buffer from snapshot monitor.    *\n");
         printf("*    Expecting start of new structure. First chars: %10c *\n",(unsigned char)*buffer_index);
         printf("*    buffer offset where error occurred: %10u             *\n",(ptrdiff_t)(buffer_index - buffer_ptr));
         printf("*    Exiting db2mon.                                          *\n\n");
         printf("\n***************************************************************\n");
         cleanup(ma_ptr);
         exit(99);
         break;
     }  /* end switch (*buffer_index) */
     --numstruct;
   }  /* end while (buffer_index < ...) */

   cleanup(ma_ptr);   /* cleanup before exiting */

   return(ssrc);

}  /* snapshot */


/*****************************************************************************/
/* process_db2                                                               */
/* This function processes DB2 level information. The information is in      */
/* an sqlm_db2 data structure.                                               */
/*****************************************************************************/

void process_db2()
{

   time_t                ltime;
   struct sqlm_db2      *db2_ptr;

   if (output_opt == SCREEN_OUTPUT)
      clrscrn();

   fprintf(outstream, "**********************************************************************\n");
   fprintf(outstream, "*                       DB2 GENERAL INFORMATION                      *\n");
   fprintf(outstream, "**********************************************************************\n");

   /* cast buffer contents to an sqlm_db2 structure */
   db2_ptr = (struct sqlm_db2 *)buffer_index;

   switch (db2_ptr->db2_status)
   {
      case SQLM_DB2_ACTIVE:
         fprintf(outstream, "\nDatabase manager status                   ===> %s",  "Active");
         break;
      case SQLM_DB2_QUIESCE_PEND:
         fprintf(outstream, "\nDatabase manager status                   ===> %s",  "Quiesce Pending");
         break;
      case SQLM_DB2_QUIESCED:
         fprintf(outstream, "\nDatabase manager status                   ===> %s",  "Quiesced");
         break;
   } /* end switch on database manager status */

   fprintf(outstream, "\n\nSorting Information:");
   fprintf(outstream, "\n  Sort heap currently allocated           ===> %lu", db2_ptr->sort_heap_allocated);
   fprintf(outstream, "\n  Post Threshold sorts                    ===> %lu", db2_ptr->post_threshold_sorts);
   fprintf(outstream, "\n  Piped sorts requested                   ===> %lu", db2_ptr->piped_sorts_requested);
   fprintf(outstream, "\n  Piped sorts accepted                    ===> %lu", db2_ptr->piped_sorts_accepted);

   fprintf(outstream, "\n\nConnection Information:");
   fprintf(outstream, "\n  Remote connects to the target DB2       ===> %lu", db2_ptr->rem_cons_in);
   fprintf(outstream, "\n  Remote connects to target exec in DB2   ===> %lu", db2_ptr->rem_cons_in_exec);
   fprintf(outstream, "\n  Local connections                       ===> %lu", db2_ptr->local_cons);
   fprintf(outstream, "\n  Local connections exec in DB2           ===> %lu", db2_ptr->local_cons_in_exec);
   fprintf(outstream, "\n  Local active databases                  ===> %lu", db2_ptr->con_local_dbases);
   fprintf(outstream, "\n  Number of agents registered             ===> %lu", db2_ptr->agents_registered);
   fprintf(outstream, "\n  Number of agents waiting on a token     ===> %lu", db2_ptr->agents_waiting_on_token);
   fprintf(outstream, "\n  High water mark of agents registered    ===> %lu", db2_ptr->agents_registered_top);
   fprintf(outstream, "\n  High water mark of agents waiting       ===> %lu", db2_ptr->agents_waiting_top);
   fprintf(outstream, "\n  Number of idle agents                   ===> %lu", db2_ptr->idle_agents);

   fprintf(outstream, "\n\nMemory Usage Information:");
   fprintf(outstream, "\n  Committed Private Memory (bytes)        ===> %lu", db2_ptr->comm_private_mem);

   fprintf(outstream, "\n\nTimestamps:");
   ltime = db2_ptr->db2start_time.seconds;
   fprintf(outstream, "\n  Db2start time                           ===> %24.24s",
                                                     (ltime) ? ctime(<ime) : "");
   ltime = db2_ptr->last_reset.seconds;
   fprintf(outstream, "\n  Last Reset time                         ===> %24.24s\n",
                                                     (ltime) ? ctime(<ime) : "");

   buffer_index += db2_ptr->size;          /* move pointer to next structure */
                                           /* in output buffer               */
   if (output_opt == SCREEN_OUTPUT)        /* pause only if output is screen */
      pause();

} /* process_db2 */


/*****************************************************************************/
/* process_dbase                                                             */
/* This function processes database information. The information is in an    */
/* sqlm_dbase data structure                                                 */
/*****************************************************************************/
void process_dbase()
{

   time_t                ltime;
   unsigned int          i, j;              /* counters                      */
   int                   rc = 0;
   struct sqlm_dbase     *dbase_ptr;

   if (output_opt == SCREEN_OUTPUT)
      clrscrn();

   fprintf(outstream, "**********************************************************************\n");
   fprintf(outstream, "*                       DATABASE INFORMATION                         *\n");
   fprintf(outstream, "**********************************************************************\n");

   /* cast buffer contents to an sqlm_dbase structure */
   dbase_ptr = (struct sqlm_dbase *)(buffer_index);

   fprintf(outstream, "\nDatabase Identification:");
   fprintf(outstream, "\n  Input Database Alias                   ===> %0.*s", SQLM_IDENT_SZ, dbase_ptr->input_db_alias);
   fprintf(outstream, "\n  Database Name                          ===> %0.*s", SQLM_IDENT_SZ, dbase_ptr->db_name);
   fprintf(outstream, "\n  Database Path (truncated to 70 chars)\n    ===> %0.70s", dbase_ptr->db_path);

   switch (dbase_ptr->db_status)
   {
      case SQLM_DB_ACTIVE:
         fprintf(outstream, "\n  Database status                        ===> %s",  "Active");
         break;
      case SQLM_DB_QUIESCE_PEND:
         fprintf(outstream, "\n  Database status                        ===> %s",  "Quiesce Pending");
         break;
      case SQLM_DB_QUIESCED:
         fprintf(outstream, "\n  Database status                        ===> %s",  "Quiesced");
         break;
   } /* end switch on database manager status */

   fprintf(outstream, "\n\nLocking Identification:");
   fprintf(outstream, "\n  Locks currently held                    ===> %lu", dbase_ptr->locks_held);
   fprintf(outstream, "\n  No. of waits on lock since 1st connect  ===> %lu", dbase_ptr->lock_waits);
   fprintf(outstream, "\n  Total time waited on locks since connect===> %lu milliseconds", dbase_ptr->lock_wait_time);
   fprintf(outstream, "\n  Total Lock list memory in use           ===> %lu", dbase_ptr->lock_list_in_use);
   fprintf(outstream, "\n  Deadlocks since 1st connect             ===> %lu", dbase_ptr->deadlocks);
   fprintf(outstream, "\n  Lock escalations since 1st connect      ===> %lu", dbase_ptr->lock_escals);
   fprintf(outstream, "\n  X lock escalations since 1st connect    ===> %lu", dbase_ptr->x_lock_escals);
   fprintf(outstream, "\n  Lock timeouts since 1st connect         ===> %lu", dbase_ptr->lock_timeouts);
   fprintf(outstream, "\n  Applications waiting on locks           ===> %lu", dbase_ptr->locks_waiting);


   fprintf(outstream, "\n\nSorting Identification:");
   fprintf(outstream, "\n  Sort Heap currently allocated           ===> %lu", dbase_ptr->sort_heap_allocated);
   fprintf(outstream, "\n  Total number of sorts                   ===> %lu", dbase_ptr->total_sorts);
   fprintf(outstream, "\n  Total sort time                         ===> %lu milliseconds", dbase_ptr->total_sort_time);
   fprintf(outstream, "\n  Number of sort overflows                ===> %lu", dbase_ptr->sort_overflows);
   fprintf(outstream, "\n  Number of sorts currently active        ===> %lu", dbase_ptr->active_sorts);

   fprintf(outstream, "\n\nBuffer Pool Information:");
   fprintf(outstream, "\n  Buffer pool logical data page reads     ===> %lu", dbase_ptr->pool_data_l_reads);
   fprintf(outstream, "\n  Buffer pool physical data page reads    ===> %lu", dbase_ptr->pool_data_p_reads);
   fprintf(outstream, "\n  Buffer pool data page writes            ===> %lu", dbase_ptr->pool_data_writes);
   fprintf(outstream, "\n  Buffer pool logical index page reads    ===> %lu", dbase_ptr->pool_index_l_reads);
   fprintf(outstream, "\n  Buffer pool physical index page reads   ===> %lu", dbase_ptr->pool_index_p_reads);
   fprintf(outstream, "\n  Buffer pool index page writes           ===> %lu", dbase_ptr->pool_index_writes);
   fprintf(outstream, "\n  Buffer pool read time since 1st connect ===> %lu milliseconds", dbase_ptr->pool_read_time);
   fprintf(outstream, "\n  Buffer pool write time since 1st connect===> %lu milliseconds", dbase_ptr->pool_write_time);
   fprintf(outstream, "\n  Files closed since 1st connect          ===> %lu", dbase_ptr->files_closed);

   fprintf(outstream, "\n  Buffer pool asynch data page reads      ===> %lu", dbase_ptr->pool_async_data_reads);
   fprintf(outstream, "\n  Buffer pool asynch data page reads reqs ===> %lu", dbase_ptr->pool_async_data_read_reqs);
   fprintf(outstream, "\n  Buffer pool asynch data page writes     ===> %lu", dbase_ptr->pool_async_data_writes);
   fprintf(outstream, "\n  Buffer pool asynch index page reads     ===> %lu", dbase_ptr->pool_async_index_reads);
   fprintf(outstream, "\n  Buffer pool asynch index page writes    ===> %lu", dbase_ptr->pool_async_index_writes);
   fprintf(outstream, "\n  Buffer pool asynch read time            ===> %lu milliseconds", dbase_ptr->pool_async_read_time);
   fprintf(outstream, "\n  Buffer pool asynch write time           ===> %lu milliseconds", dbase_ptr->pool_async_write_time);

   fprintf(outstream, "\n  Buffer pool LSN gap cleans              ===> %lu", dbase_ptr->pool_lsn_gap_clns);
   fprintf(outstream, "\n  Buffer pool dirty page steal cleans     ===> %lu", dbase_ptr->pool_drty_pg_steal_clns);
   fprintf(outstream, "\n  Buffer pool dirty page threshold cleans ===> %lu", dbase_ptr->pool_drty_pg_thrsh_clns);

   if (output_opt == SCREEN_OUTPUT)
      pause();

   fprintf(outstream, "\n\nDirect I/O Information:");
   fprintf(outstream, "\n  Sectors read directly                   ===> %lu", dbase_ptr->direct_reads);
   fprintf(outstream, "\n  Sectors written directly                ===> %lu", dbase_ptr->direct_writes);
   fprintf(outstream, "\n  Number of direct read requests          ===> %lu", dbase_ptr->direct_read_reqs);
   fprintf(outstream, "\n  Number of direct write requests         ===> %lu", dbase_ptr->direct_write_reqs);
   fprintf(outstream, "\n  Direct read time                        ===> %lu milliseconds", dbase_ptr->direct_read_time);
   fprintf(outstream, "\n  Direct write time                       ===> %lu milliseconds", dbase_ptr->direct_write_time);

   fprintf(outstream, "\n\nSQL Statement counts");
   fprintf(outstream, "\n  Number of Commit SQL statements         ===> %lu", dbase_ptr->commit_sql_stmts);
   fprintf(outstream, "\n  Number of Rollback SQL statements       ===> %lu", dbase_ptr->rollback_sql_stmts);
   fprintf(outstream, "\n  Number of Dynamic SQL statements        ===> %lu", dbase_ptr->dynamic_sql_stmts);
   fprintf(outstream, "\n  Number of Static SQL statements         ===> %lu", dbase_ptr->static_sql_stmts);
   fprintf(outstream, "\n  Number of Failed SQL statements         ===> %lu", dbase_ptr->failed_sql_stmts);
   fprintf(outstream, "\n  Number of Select SQL statements         ===> %lu", dbase_ptr->select_sql_stmts);
   fprintf(outstream, "\n  Number of Data Def. Language SQL stmts  ===> %lu", dbase_ptr->ddl_sql_stmts);
   fprintf(outstream, "\n  Number of Update/Insert/Delete SQL stmts===> %lu", dbase_ptr->uid_sql_stmts);

   fprintf(outstream, "\n\nInternal counts");
   fprintf(outstream, "\n  Number of auto rebinds                  ===> %lu", dbase_ptr->int_auto_rebinds);
   fprintf(outstream, "\n  Number of internal row deletions        ===> %lu", dbase_ptr->int_rows_deleted);
   fprintf(outstream, "\n  Number of internal row updates          ===> %lu", dbase_ptr->int_rows_updated);
   fprintf(outstream, "\n  Number of internal row inserts          ===> %lu", dbase_ptr->int_rows_inserted);
   fprintf(outstream, "\n  Number of internal commits              ===> %lu", dbase_ptr->int_commits);
   fprintf(outstream, "\n  Number of internal rollbacks            ===> %lu", dbase_ptr->int_rollbacks);
   fprintf(outstream, "\n  Number of rollbacks due to deadlocks    ===> %lu", dbase_ptr->int_deadlock_rollbacks);

   if (output_opt == SCREEN_OUTPUT)
      pause();

   fprintf(outstream, "\n\nRow counts");
   fprintf(outstream, "\n  Number of row deletions                 ===> %lu", dbase_ptr->rows_deleted);
   fprintf(outstream, "\n  Number of row insertions                ===> %lu", dbase_ptr->rows_inserted);
   fprintf(outstream, "\n  Number of row updates                   ===> %lu", dbase_ptr->rows_updated);
   fprintf(outstream, "\n  Number of row selections                ===> %lu", dbase_ptr->rows_selected);

   fprintf(outstream, "\n\n  Number of binds/precompiles             ===> %lu", dbase_ptr->binds_precompiles);

   fprintf(outstream, "\n\nTimestamps");
   ltime = dbase_ptr->db_conn_time.seconds;
   fprintf(outstream, "\n  First database connect time             ===> %24.24s",
                                                   (ltime) ? ctime(<ime) : "");
   ltime = dbase_ptr->last_reset.seconds;
   fprintf(outstream, "\n  Last Database Monitor reset time        ===> %24.24s",
                                                   (ltime) ? ctime(<ime) : "");
   ltime = dbase_ptr->last_backup.seconds;
   fprintf(outstream, "\n  Last backup time                        ===> %24.24s",
                                                   (ltime) ? ctime(<ime) : "");

   fprintf(outstream, "\n\nConnection information");
   fprintf(outstream, "\n  Connections since 1st connect           ===> %lu", dbase_ptr->total_cons);
   fprintf(outstream, "\n  No. of applications currently connected ===> %lu", dbase_ptr->appls_cur_cons);
   fprintf(outstream, "\n  Applications executing in DB2           ===> %lu", dbase_ptr->appls_in_db2);
   fprintf(outstream, "\n  Maximum number of connections           ===> %lu", dbase_ptr->connections_top);

   fprintf(outstream, "\n\nDatabase heap information");
   fprintf(outstream, "\n  Maximum amount of database heap used    ===> %lu", dbase_ptr->db_heap_top);

   fprintf(outstream, "\n\nLogging information");
   fprintf(outstream, "\n  Maximum Secondary Log space used        ===> %lu", dbase_ptr->sec_log_used_top);
   fprintf(outstream, "\n  Maximum Total Log space used            ===> %lu", dbase_ptr->tot_log_used_top);
   fprintf(outstream, "\n  Number of secondary Logs allocated      ===> %lu", dbase_ptr->sec_logs_allocated);
   fprintf(outstream, "\n  Log pages read                          ===> %lu", dbase_ptr->log_reads);
   fprintf(outstream, "\n  Log pages written                       ===> %lu", dbase_ptr->log_writes);

   fprintf(outstream, "\n\nPackage Cache information");
   fprintf(outstream, "\n  Package Cache Lookups                   ===> %lu", dbase_ptr->pkg_cache_lookups);
   fprintf(outstream, "\n  Package Cache Inserts                   ===> %lu", dbase_ptr->pkg_cache_inserts);

   fprintf(outstream, "\n\nCatalog Cache information");
   fprintf(outstream, "\n  Catalog Cache Lookups                   ===> %lu", dbase_ptr->cat_cache_lookups);
   fprintf(outstream, "\n  Catalog Cache Inserts                   ===> %lu", dbase_ptr->cat_cache_inserts);
   fprintf(outstream, "\n  Catalog Cache Overflows                 ===> %lu", dbase_ptr->cat_cache_overflows);
   fprintf(outstream, "\n  Catalog Cache Heap Full                 ===> %lu\n", dbase_ptr->cat_cache_heap_full);

   buffer_index += dbase_ptr->size;   /* move pointer to the next structure */

   if (output_opt == SCREEN_OUTPUT)
      pause();

}  /* process_dbase */



/*****************************************************************************/
/* process_appl                                                              */
/* This function processes application information. The information is       */
/* contained in an sqlm_appl data structure.                                 */
/*****************************************************************************/
void process_appl()
{

   time_t                ltime;
   struct sqlm_appl      *appl_ptr;
   char                  *stmt_text_ptr;   /* Dynamic SQL Statement Text ptr */

   if (output_opt == SCREEN_OUTPUT)
      clrscrn();

   fprintf(outstream, "**********************************************************************\n");
   fprintf(outstream, "*                       APPLICATION INFORMATION                      *\n");
   fprintf(outstream, "**********************************************************************\n");

   /* cast the buffer contents to an sqlm_appl data structure */
   appl_ptr = (struct sqlm_appl *)(buffer_index);

   fprintf(outstream, "\nApplication Identification Information:");
   fprintf(outstream, "\n  Application agent id                   ===> %lu\n", appl_ptr->id_info.agent_id);
   switch (appl_ptr->id_info.appl_status)
   {
      case SQLM_CONNECTPEND:
         fprintf(outstream, "\n  Application Status                     ===> Connect Pending");
         break;
      case SQLM_CONNECTED:
         fprintf(outstream, "\n  Application Status                     ===> Connected");
         break;
      case SQLM_UOWEXEC:
         fprintf(outstream, "\n  Application Status                     ===> UOW Executing");
         break;
      case SQLM_UOWWAIT:
         fprintf(outstream, "\n  Application Status                     ===> UOW Waiting in the application");
         break;
      case SQLM_LOCKWAIT:
         fprintf(outstream, "\n  Application Status                     ===> Lock Waiting");
         break;
      case SQLM_COMMIT_ACT:
         fprintf(outstream, "\n  Application Status                     ===> Commit Active");
         break;
      case SQLM_ROLLBACK_ACT:
         fprintf(outstream, "\n  Application Status                     ===> Rollback Active");
         break;
      case SQLM_RECOMP:
         fprintf(outstream, "\n  Application Status                     ===> Recompiling Plan");
         break;
      case SQLM_COMP:
         fprintf(outstream, "\n  Application Status                     ===> Compiling SQL Stmt");
         break;
      case SQLM_INTR:
         fprintf(outstream, "\n  Application Status                     ===> Request Interupted");
         break;
      case SQLM_DISCONNECTPEND:
         fprintf(outstream, "\n  Application Status                     ===> Disconnect Pending");
         break;
      case SQLM_TPREP:
         fprintf(outstream, "\n  Application Status                     ===> Prepared Transaction");
         break;
      case SQLM_THCOMT:
         fprintf(outstream, "\n  Application Status                     ===> Trans. heuristically committed");
         break;
      case SQLM_THABRT:
         fprintf(outstream, "\n  Application Status                     ===> Trans. heuristically aborted");
         break;
      case SQLM_TEND:
         fprintf(outstream, "\n  Application Status                     ===> Transaction ended");
         break;
      case SQLM_CREATE_DB:
         fprintf(outstream, "\n  Application Status                     ===> Creating Database");
         break;
      case SQLM_RESTART:
         fprintf(outstream, "\n  Application Status                     ===> Restarting Database");
         break;
      case SQLM_RESTORE:
         fprintf(outstream, "\n  Application Status                     ===> Restoring Database");
         break;
      case SQLM_BACKUP:
         fprintf(outstream, "\n  Application Status                     ===> Backing Up Database");
         break;
      case SQLM_LOAD:
         fprintf(outstream, "\n  Application Status                     ===> Loading Database");
         break;
      case SQLM_UNLOAD:
         fprintf(outstream, "\n  Application Status                     ===> Unloading Database");
         break;
      case SQLM_IOERROR_WAIT:
         fprintf(outstream, "\n  Application Status                     ===> I/O Error Waiting");
         break;
      case SQLM_QUIESCE_TABLESPACE:
         fprintf(outstream, "\n  Application Status                     ===> Quiescing a Tablespace");
         break;
      default:
         fprintf(outstream, "\n  Application Status                     ===> Unknown (%lu)", appl_ptr->id_info.appl_status);
         break;
   } /* endswitch */

   fprintf(outstream, "\n  Application codepage id                ===> %lu", appl_ptr->id_info.codepage_id);
   fprintf(outstream, "\n  Application country code               ===> %lu", appl_ptr->country_code);

   ltime  = appl_ptr->id_info.status_change_time.seconds;
   fprintf(outstream, "\n  Application Status change time         ===> %24.24s", (ltime) ? ctime(<ime) : "");
   fprintf(outstream, "\n  Application Name                       ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->id_info.appl_name);
   fprintf(outstream, "\n  Application Id                         ===> %0.*s", SQLM_APPLID_SZ, appl_ptr->id_info.appl_id);
   fprintf(outstream, "\n  Application Id Sequence number         ===> %0.*s", SQLM_SEQ_SZ, appl_ptr->id_info.sequence_no);
   fprintf(outstream, "\n  DRDA AS Correlation Token              ===> %0.*s", SQLM_APPLID_SZ, appl_ptr->corr_token);
   fprintf(outstream, "\n  Application Authorization Id           ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->id_info.auth_id);
   fprintf(outstream, "\n  Application Execution Id               ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->execution_id);
   fprintf(outstream, "\n  Application client NNAME               ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->id_info.client_nname);
   fprintf(outstream, "\n  Application client Product name        ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->id_info.client_prdid);
   fprintf(outstream, "\n  Application client Process Id          ===> %lu", appl_ptr->client_pid);

   switch (appl_ptr->client_platform)
   {
      case SQLM_PLATFORM_OS2:
         fprintf(outstream, "\n  Application client platform            ===> OS/2");
         break;
      case SQLM_PLATFORM_DOS:
         fprintf(outstream, "\n  Application client platform            ===> DOS");
         break;
      case SQLM_PLATFORM_WINDOWS:
         fprintf(outstream, "\n  Application client platform            ===> WINDOWS");
         break;
      case SQLM_PLATFORM_AIX:
         fprintf(outstream, "\n  Application client platform            ===> AIX");
         break;
      case SQLM_PLATFORM_HP:
         fprintf(outstream, "\n  Application client platform            ===> HP");
         break;
      case SQLM_PLATFORM_SUN:
         fprintf(outstream, "\n  Application client platform            ===> SUN");
         break;
      case SQLM_PLATFORM_SNI:                                /*@db41773ygs*/
         fprintf(outstream, "\n  Application client platform            ===> SINIX");
         break;
      case SQLM_PLATFORM_MAC:
         fprintf(outstream, "\n  Application client platform            ===> MacIntosh");
         break;
      case SQLM_PLATFORM_WINDOWS95:
         fprintf(outstream, "\n  Application client platform            ===> Windows95");
         break;
      case SQLM_PLATFORM_VSE_DRDA:
         fprintf(outstream, "\n  Application client platform            ===> VSE via DRDA");
         break;                                               /*@de41773ygs*/
      case SQLM_PLATFORM_MVS_DRDA:
         fprintf(outstream, "\n  Application client platform            ===> MVS via DRDA");
         break;
      case SQLM_PLATFORM_AS400_DRDA:
         fprintf(outstream, "\n  Application client platform            ===> AS400 via DRDA");
         break;
      case SQLM_PLATFORM_VM_DRDA:
         fprintf(outstream, "\n  Application client platform            ===> VM via DRDA");
         break;
      case SQLM_PLATFORM_UNKNOWN_DRDA:
         fprintf(outstream, "\n  Application client platform            ===> Unknown via DRDA");
         break;
      case SQLM_PLATFORM_UNKNOWN:
         fprintf(outstream, "\n  Application client platform            ===> Unknown");
         break;
      default:
         fprintf(outstream, "\n  Application client platform            ===> Unknown (%lu)", appl_ptr->client_platform);
         break;
   } /* endswitch */

   switch (appl_ptr->client_protocol)
   {
      case SQLM_PROT_APPC:
         fprintf(outstream, "\n  Application client comms protocol      ===> APPC");
         break;
      case SQLM_PROT_NETBIOS:
         fprintf(outstream, "\n  Application client comms protocol      ===> Netbios");
         break;
      case SQLM_PROT_APPN:
         fprintf(outstream, "\n  Application client comms protocol      ===> APPN");
         break;
      case SQLM_PROT_TCPIP:
         fprintf(outstream, "\n  Application client comms protocol      ===> TCPIP");
         break;
      case SQLM_PROT_CPIC:
         fprintf(outstream, "\n  Application client comms protocol      ===> CPIC");
         break;
      case SQLM_PROT_IPXSPX:
         fprintf(outstream, "\n  Application client comms protocol      ===> IPX/SPX");
         break;
      case SQLM_PROT_LOCAL:
         fprintf(outstream, "\n  Application client comms protocol      ===> Local");
         break;
      case SQLM_PROT_NPIPE:
         fprintf(outstream, "\n  Application client comms protocol      ===> Named Pipe");
         break;
      default:
         fprintf(outstream, "\n  Application client comms protocol      ===> Unknown (%lu)", appl_ptr->client_protocol);
         break;
   } /* endswitch */


   fprintf(outstream, "\n  Input Database Alias                   ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->id_info.input_db_alias);
   fprintf(outstream, "\n  Client Database Alias                  ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->id_info.client_db_alias);
   fprintf(outstream, "\n  Database Name                          ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->id_info.db_name);
   fprintf(outstream, "\n  Database path (truncated to 70 chars)\n     ===> %0.70s", appl_ptr->id_info.db_path);

   if (output_opt == SCREEN_OUTPUT)
      pause();

   fprintf(outstream, "\n\nLock Information:");
   fprintf(outstream, "\n  Locks currently held by the application ===> %lu", appl_ptr->locks_held);
   fprintf(outstream, "\n  Number of waits on lock since connect   ===> %lu", appl_ptr->lock_waits);
   fprintf(outstream, "\n  Total time waited on locks since connect===> %lu milliseconds", appl_ptr->lock_wait_time);
   fprintf(outstream, "\n  Lock escalations since appl connect     ===> %lu", appl_ptr->lock_escals);
   fprintf(outstream, "\n  X lock escalations since appl connect   ===> %lu", appl_ptr->x_lock_escals);
   fprintf(outstream, "\n  Deadlocks since appl connect            ===> %lu", appl_ptr->deadlocks);
   fprintf(outstream, "\n  Lock timeouts since appl connect        ===> %lu", appl_ptr->lock_timeouts);
   fprintf(outstream, "\n  Time UOW waited on locks                ===> %lu milliseconds", appl_ptr->uow_lock_wait_time);

   fprintf(outstream, "\n\nSorting Information:");
   fprintf(outstream, "\n  Total number of sorts                   ===> %lu", appl_ptr->total_sorts);
   fprintf(outstream, "\n  Total Sort time                         ===> %lu milliseconds", appl_ptr->total_sort_time);
   fprintf(outstream, "\n  Number of sort overflows                ===> %lu", appl_ptr->sort_overflows);

   if (output_opt == SCREEN_OUTPUT)
      pause();

   fprintf(outstream, "\n\nBuffer Pool Information:");
   fprintf(outstream, "\n  Buffer pool data logical reads          ===> %lu", appl_ptr->pool_data_l_reads);
   fprintf(outstream, "\n  Buffer pool data physical reads         ===> %lu", appl_ptr->pool_data_p_reads);
   fprintf(outstream, "\n  Buffer pool data writes                 ===> %lu", appl_ptr->pool_data_writes);
   fprintf(outstream, "\n  Buffer pool index logical reads         ===> %lu", appl_ptr->pool_index_l_reads);
   fprintf(outstream, "\n  Buffer pool index physical reads        ===> %lu", appl_ptr->pool_index_p_reads);
   fprintf(outstream, "\n  Buffer pool index writes                ===> %lu", appl_ptr->pool_index_writes);
   fprintf(outstream, "\n  Buffer pool read time since 1st connect ===> %lu milliseconds", appl_ptr->pool_read_time);
   fprintf(outstream, "\n  Buffer pool write time since 1st connect===> %lu milliseconds", appl_ptr->pool_write_time);

   fprintf(outstream, "\n\nDirect I/O Information:");
   fprintf(outstream, "\n  Sectors read directly                   ===> %lu", appl_ptr->direct_reads);
   fprintf(outstream, "\n  Sectors written directly                ===> %lu", appl_ptr->direct_writes);
   fprintf(outstream, "\n  Number of direct read requests          ===> %lu", appl_ptr->direct_read_reqs);
   fprintf(outstream, "\n  Number of direct write requests         ===> %lu", appl_ptr->direct_write_reqs);
   fprintf(outstream, "\n  Direct read time                        ===> %lu milliseconds", appl_ptr->direct_read_time);
   fprintf(outstream, "\n  Direct write time                       ===> %lu milliseconds", appl_ptr->direct_write_time);

   fprintf(outstream, "\n\nSQL Statement counts");
   fprintf(outstream, "\n  Number of Commit SQL statements         ===> %lu", appl_ptr->commit_sql_stmts);
   fprintf(outstream, "\n  Number of Rollback SQL statements       ===> %lu", appl_ptr->rollback_sql_stmts);
   fprintf(outstream, "\n  Number of Dynamic SQL statements        ===> %lu", appl_ptr->dynamic_sql_stmts);
   fprintf(outstream, "\n  Number of Static SQL statements         ===> %lu", appl_ptr->static_sql_stmts);
   fprintf(outstream, "\n  Number of Failed SQL statements         ===> %lu", appl_ptr->failed_sql_stmts);
   fprintf(outstream, "\n  Number of Select SQL statements         ===> %lu", appl_ptr->select_sql_stmts);
   fprintf(outstream, "\n  Number of Data Def. Language SQL stmts  ===> %lu", appl_ptr->ddl_sql_stmts);
   fprintf(outstream, "\n  Number of Update/Insert/Delete SQL stmts===> %lu", appl_ptr->uid_sql_stmts);

   if (output_opt == SCREEN_OUTPUT)
      pause();

   fprintf(outstream, "\n\nInternal counts");
   fprintf(outstream, "\n  Number of auto rebinds                  ===> %lu", appl_ptr->int_auto_rebinds);
   fprintf(outstream, "\n  Number of internal row deletions        ===> %lu", appl_ptr->int_rows_deleted);
   fprintf(outstream, "\n  Number of internal row updates          ===> %lu", appl_ptr->int_rows_updated);
   fprintf(outstream, "\n  Number of internal row inserts          ===> %lu", appl_ptr->int_rows_inserted);
   fprintf(outstream, "\n  Number of internal commits              ===> %lu", appl_ptr->int_commits);
   fprintf(outstream, "\n  Number of internal rollbacks            ===> %lu", appl_ptr->int_rollbacks);
   fprintf(outstream, "\n  Number of rollbacks due to deadlocks    ===> %lu", appl_ptr->int_deadlock_rollbacks);

   fprintf(outstream, "\n\nRow counts");
   fprintf(outstream, "\n  Number of row deletions                 ===> %lu", appl_ptr->rows_deleted);
   fprintf(outstream, "\n  Number of row insertions                ===> %lu", appl_ptr->rows_inserted);
   fprintf(outstream, "\n  Number of row updates                   ===> %lu", appl_ptr->rows_updated);
   fprintf(outstream, "\n  Number of row selections                ===> %lu", appl_ptr->rows_selected);
   fprintf(outstream, "\n  Number of rows read                     ===> %lu", appl_ptr->rows_read);
   fprintf(outstream, "\n  Number of rows written                  ===> %lu", appl_ptr->rows_written);

   fprintf(outstream, "\n\n  Number of binds/precompiles             ===> %lu", appl_ptr->binds_precompiles);

   if (output_opt == SCREEN_OUTPUT)
      pause();

   fprintf(outstream, "\n\nStatement Information:");
   switch (appl_ptr->stmt_type)
   {
      case SQLM_STATIC:
           fprintf(outstream, "\n  Statement Type                          ===> STATIC");
           break;
      case SQLM_DYNAMIC:
           fprintf(outstream, "\n  Statement Type                          ===> DYNAMIC");
           break;
      case SQLM_NON_STMT:
           fprintf(outstream, "\n  Statement Type                          ===> NON-STATEMENT OPERATION");
           break;
      case 0:
           fprintf(outstream, "\n  Statement Type                          ===> ");
           break;
      default:
           fprintf(outstream, "\n  Statement Type                          ===> UNKNOWN (%lu)", appl_ptr->stmt_type);
           break;
   }

   switch (appl_ptr->stmt_operation)
   {
      case SQLM_PREPARE:
           fprintf(outstream, "\n  Statement Operation                     ===> PREPARE");
           break;
      case SQLM_EXECUTE:
           fprintf(outstream, "\n  Statement Operation                     ===> EXECUTE");
           break;
      case SQLM_EXECUTE_IMMEDIATE:
           fprintf(outstream, "\n  Statement Operation                     ===> EXECUTE IMMEDIATE");
           break;
      case SQLM_OPEN:
           fprintf(outstream, "\n  Statement Operation                     ===> OPEN");
           break;
      case SQLM_FETCH:
           fprintf(outstream, "\n  Statement Operation                     ===> FETCH");
           break;
      case SQLM_CLOSE:
           fprintf(outstream, "\n  Statement Operation                     ===> CLOSE");
           break;
      case SQLM_DESCRIBE:
           fprintf(outstream, "\n  Statement Operation                     ===> DESCRIBE");
           break;
      case SQLM_STATIC_COMMIT:
           fprintf(outstream, "\n  Statement Operation                     ===> STATIC COMMIT");
           break;
      case SQLM_STATIC_ROLLBACK:
           fprintf(outstream, "\n  Statement Operation                     ===> STATIC ROLLBACK");
           break;
      case 0:
           fprintf(outstream, "\n  Statement Operation                     ===>");
           break;
      default:
           fprintf(outstream, "\n  Statement Operation                     ===>UNKNOWN (%lu", appl_ptr->stmt_operation);
           break;
   }  /* switch (appl_ptr->stmt_operation) */

   fprintf(outstream, "\n  Section Number                          ===> %lu", appl_ptr->section_number);

   ltime  = appl_ptr->stmt_start.seconds;
   fprintf(outstream, "\n  Statement Operation Start Time          ===> %24.24s", (ltime) ? ctime(<ime) : "");
   ltime  = appl_ptr->stmt_stop.seconds;
   fprintf(outstream, "\n  Statement Operation Stop Time           ===> %24.24s", (ltime) ? ctime(<ime) : "");


   fprintf(outstream, "\n  Cursor Name                             ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->cursor_name);
   fprintf(outstream, "\n  Application Creator                     ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->creator);
   fprintf(outstream, "\n  Package Name                            ===> %0.*s", SQLM_IDENT_SZ, appl_ptr->package_name);


   fprintf(outstream, "\n\nUOW Information:");
   fprintf(outstream, "\n  Log space used in current UOW           ===> %lu", appl_ptr->uow_log_space_used);

   switch (appl_ptr->uow_comp_status)
   {
      case SQLM_UOWCOMMIT:
         fprintf(outstream, "\n  UOW Completion Status                   ===> UOW Commit");
         break;
      case SQLM_UOWROLLBACK:
         fprintf(outstream, "\n  UOW Completion Status                   ===> UOW Rolled Back");
         break;
      case SQLM_UOWDEADLOCK:
         fprintf(outstream, "\n  UOW Completion Status                   ===> UOW RB due to Deadlock");
         break;
      case SQLM_UOWABEND:
         fprintf(outstream, "\n  UOW Completion Status                   ===> UOW RB due to Abend");
         break;
      case SQLM_APPL_END:
         fprintf(outstream, "\n  UOW Completion Status                   ===> Appl Normal Termination");
         break;
      case SQLM_UOWLOCKTIMEOUT:
         fprintf(outstream, "\n  UOW Completion Status                   ===> UOW RB - Lock Timeout");
         break;
      case 0:
         fprintf(outstream, "\n  UOW Completion Status                   ===> ");
         break;
      default:
         fprintf(outstream, "\n  UOW Completion Status                   ===> Unknown (%lu)", appl_ptr->uow_comp_status);
         break;
   } /* endswitch */

   ltime  = appl_ptr->prev_uow_stop_time.seconds;
   fprintf(outstream, "\n  Previous UOW stop time                  ===> %24.24s", (ltime) ? ctime(<ime) : "");
   ltime  = appl_ptr->uow_start_time.seconds;
   fprintf(outstream, "\n  UOW start time                          ===> %24.24s", (ltime) ? ctime(<ime) : "");
   ltime  = appl_ptr->uow_stop_time.seconds;
   fprintf(outstream, "\n  UOW stop time                           ===> %24.24s", (ltime) ? ctime(<ime) : "");

   if (output_opt == SCREEN_OUTPUT)
      pause();

   fprintf(outstream, "\n\nCursor Information:");
   fprintf(outstream, "\n  Currently open remote cursors           ===> %lu", appl_ptr->open_rem_curs);
   fprintf(outstream, "\n  Currently open remote blocked cursors   ===> %lu", appl_ptr->open_rem_curs_blk);
   fprintf(outstream, "\n  Currently open local cursors            ===> %lu", appl_ptr->open_loc_curs);
   fprintf(outstream, "\n  Currently open local blocked cursors    ===> %lu", appl_ptr->open_loc_curs_blk);
   fprintf(outstream, "\n  Rejected block cursor requests          ===> %lu", appl_ptr->rej_curs_blk);
   fprintf(outstream, "\n  Accepted block cursor requests          ===> %lu", appl_ptr->acc_curs_blk);

   fprintf(outstream, "\n\nApplication Times/Timestamps:");
   ltime = appl_ptr->appl_con_time.seconds;
   fprintf(outstream, "\n  Application connect start time          ===> %24.24s",
                                       (ltime) ? ctime(<ime) : "");
   ltime = appl_ptr->conn_complete_time.seconds;
   fprintf(outstream, "\n  Connect completion time                 ===> %24.24s",
                                       (ltime) ? ctime(<ime) : "");
   ltime = appl_ptr->last_reset.seconds;
   fprintf(outstream, "\n  Last reset time                         ===> %24.24s",
                                       (ltime) ? ctime(<ime) : "");
   fprintf(outstream, "\n  Application User CPU time               ===> %lu.%0.6lu seconds",
           appl_ptr->agent_usr_cpu_time.seconds,
           appl_ptr->agent_usr_cpu_time.microsec);
   fprintf(outstream, "\n  Application System CPU time             ===> %lu.%0.6lu seconds",
           appl_ptr->agent_sys_cpu_time.seconds,
           appl_ptr->agent_sys_cpu_time.microsec);

   fprintf(outstream, "\n  Application Idle CPU time               ===> %lu seconds",
           appl_ptr->appl_idle_time);

   fprintf(outstream, "\n\nPackage Cache Information:");
   fprintf(outstream, "\n  Package Cache Lookups                   ===> %lu", appl_ptr->pkg_cache_lookups);
   fprintf(outstream, "\n  Package Cache Inserts                   ===> %lu", appl_ptr->pkg_cache_inserts);

   fprintf(outstream, "\n\nCatalog Cache Information:");
   fprintf(outstream, "\n  Catalog Cache Overflows                 ===> %lu", appl_ptr->cat_cache_overflows);
   fprintf(outstream, "\n  Catalog Cache Heap Full                 ===> %lu", appl_ptr->cat_cache_heap_full);

   /* advance buffer_index to next structure in the output buffer */
   buffer_index += appl_ptr->size;

   if (output_opt == SCREEN_OUTPUT)
      pause();

} /* process_appl */


/*****************************************************************************/
/* process_applinfo                                                          */
/* This function processes summary application information. The information  */
/* is in an sqlm_applinfo data structure                                     */
/*****************************************************************************/

void process_applinfo()
{

   time_t                ltime;
   struct sqlm_applinfo  *applinfo_ptr;

   if (output_opt == SCREEN_OUTPUT)
      clrscrn();

   fprintf(outstream, "**********************************************************************\n");
   fprintf(outstream, "*                   SUMMARY APPLICATION INFORMATION                  *\n");
   fprintf(outstream, "**********************************************************************\n");

   /* cast buffer contents to an sqlm_applinfo data structure */
   applinfo_ptr = (struct sqlm_applinfo *)(buffer_index);

   fprintf(outstream, "\n  Application agent id                   ===> %lu\n", applinfo_ptr->id_info.agent_id);
   switch (applinfo_ptr->id_info.appl_status)
   {
      case SQLM_CONNECTPEND:
         fprintf(outstream, "\n  Application Status                     ===> Connect Pending");
         break;
      case SQLM_CONNECTED:
         fprintf(outstream, "\n  Application Status                     ===> Connected");
         break;
      case SQLM_UOWEXEC:
         fprintf(outstream, "\n  Application Status                     ===> UOW Executing");
         break;
      case SQLM_UOWWAIT:
         fprintf(outstream, "\n  Application Status                     ===> UOW Waiting in the application");
         break;
      case SQLM_LOCKWAIT:
         fprintf(outstream, "\n  Application Status                     ===> Lock Waiting");
         break;
      case SQLM_COMMIT_ACT:
         fprintf(outstream, "\n  Application Status                     ===> Commit Active");
         break;
      case SQLM_ROLLBACK_ACT:
         fprintf(outstream, "\n  Application Status                     ===> Rollback Active");
         break;
      case SQLM_RECOMP:
         fprintf(outstream, "\n  Application Status                     ===> Recompiling Plan");
         break;
      case SQLM_COMP:
         fprintf(outstream, "\n  Application Status                     ===> Compiling SQL Stmt");
         break;
      case SQLM_INTR:
         fprintf(outstream, "\n  Application Status                     ===> Request Interupted");
         break;
      case SQLM_DISCONNECTPEND:
         fprintf(outstream, "\n  Application Status                     ===> Disconnect Pending");
         break;
      case SQLM_TPREP:
         fprintf(outstream, "\n  Application Status                     ===> Prepared Transaction");
         break;
      case SQLM_THCOMT:
         fprintf(outstream, "\n  Application Status                     ===> Trans. heuristically committed");
         break;
      case SQLM_THABRT:
         fprintf(outstream, "\n  Application Status                     ===> Trans. heuristically aborted");
         break;
      case SQLM_TEND:
         fprintf(outstream, "\n  Application Status                     ===> Transaction ended");
         break;
      case SQLM_CREATE_DB:
         fprintf(outstream, "\n  Application Status                     ===> Creating Database");
         break;
      case SQLM_RESTART:
         fprintf(outstream, "\n  Application Status                     ===> Restarting Database");
         break;
      case SQLM_RESTORE:
         fprintf(outstream, "\n  Application Status                     ===> Restoring Database");
         break;
      case SQLM_BACKUP:
         fprintf(outstream, "\n  Application Status                     ===> Backing Up Database");
         break;
      case SQLM_LOAD:
         fprintf(outstream, "\n  Application Status                     ===> Loading Database");
         break;
      case SQLM_UNLOAD:
         fprintf(outstream, "\n  Application Status                     ===> Unloading Database");
         break;
      case SQLM_IOERROR_WAIT:
         fprintf(outstream, "\n  Application Status                     ===> I/O Error Waiting");
         break;
      case SQLM_QUIESCE_TABLESPACE:
         fprintf(outstream, "\n  Application Status                     ===> Quiescing a Tablespace");
         break;
      default:
         fprintf(outstream, "\n  Application Status                     ===> Unknown (%lu)", applinfo_ptr->id_info.appl_status );
         break;
   } /* endswitch */

   fprintf(outstream, "\n  Application codepage id                ===> %lu", applinfo_ptr->id_info.codepage_id);
   fprintf(outstream, "\n  Application country code               ===> %lu", applinfo_ptr->country_code);

   ltime  = applinfo_ptr->id_info.status_change_time.seconds;
   fprintf(outstream, "\n  Application Status change time         ===> %24.24s", (ltime) ? ctime(<ime) : "");
   fprintf(outstream, "\n  Application Name                       ===> %0.*s", SQLM_IDENT_SZ, applinfo_ptr->id_info.appl_name);
   fprintf(outstream, "\n  Application Id                         ===> %0.*s", SQLM_APPLID_SZ, applinfo_ptr->id_info.appl_id);
   fprintf(outstream, "\n  Application Id Sequence number         ===> %0.*s", SQLM_SEQ_SZ, applinfo_ptr->id_info.sequence_no);
   fprintf(outstream, "\n  DRDA AS Correlation Token              ===> %0.*s", SQLM_APPLID_SZ, applinfo_ptr->corr_token);
   fprintf(outstream, "\n  Application Authorization Id           ===> %0.*s", SQLM_IDENT_SZ, applinfo_ptr->id_info.auth_id);
   fprintf(outstream, "\n  Application Execution Id               ===> %0.*s", SQLM_IDENT_SZ, applinfo_ptr->execution_id);
   fprintf(outstream, "\n  Application client NNAME               ===> %0.*s", SQLM_IDENT_SZ, applinfo_ptr->id_info.client_nname);
   fprintf(outstream, "\n  Application client Product name        ===> %0.*s", SQLM_IDENT_SZ, applinfo_ptr->id_info.client_prdid);
   fprintf(outstream, "\n  Application client Process Id          ===> %lu", applinfo_ptr->client_pid);

   switch (applinfo_ptr->client_platform)
   {
      case SQLM_PLATFORM_OS2:
         fprintf(outstream, "\n  Application client platform            ===> OS/2");
         break;
      case SQLM_PLATFORM_DOS:
         fprintf(outstream, "\n  Application client platform            ===> DOS");
         break;
      case SQLM_PLATFORM_WINDOWS:
         fprintf(outstream, "\n  Application client platform            ===> WINDOWS");
         break;
      case SQLM_PLATFORM_AIX:
         fprintf(outstream, "\n  Application client platform            ===> AIX");
         break;
      case SQLM_PLATFORM_HP:
         fprintf(outstream, "\n  Application client platform            ===> HP");
         break;
      case SQLM_PLATFORM_SUN:
         fprintf(outstream, "\n  Application client platform            ===> SUN");
         break;
      case SQLM_PLATFORM_MVS_DRDA:
         fprintf(outstream, "\n  Application client platform            ===> MVS via DRDA");
         break;
      case SQLM_PLATFORM_AS400_DRDA:
         fprintf(outstream, "\n  Application client platform            ===> AS400 via DRDA");
         break;
      case SQLM_PLATFORM_VM_DRDA:
         fprintf(outstream, "\n  Application client platform            ===> VM via DRDA");
         break;
      case SQLM_PLATFORM_UNKNOWN_DRDA:
         fprintf(outstream, "\n  Application client platform            ===> Unknown via DRDA");
         break;
      case SQLM_PLATFORM_UNKNOWN:
         fprintf(outstream, "\n  Application client platform            ===> Unknown");
         break;
      default:
         fprintf(outstream, "\n  Application client platform            ===> Unknown (%lu)", applinfo_ptr->client_platform);
         break;
   } /* endswitch */

   switch (applinfo_ptr->client_protocol)
   {
      case SQLM_PROT_APPC:
         fprintf(outstream, "\n  Application client comms protocol      ===> APPC");
         break;
      case SQLM_PROT_NETBIOS:
         fprintf(outstream, "\n  Application client comms protocol      ===> Netbios");
         break;
      case SQLM_PROT_APPN:
         fprintf(outstream, "\n  Application client comms protocol      ===> APPN");
         break;
      case SQLM_PROT_TCPIP:
         fprintf(outstream, "\n  Application client comms protocol      ===> TCPIP");
         break;
      case SQLM_PROT_CPIC:
         fprintf(outstream, "\n  Application client comms protocol      ===> CPIC");
         break;
      case SQLM_PROT_IPXSPX:
         fprintf(outstream, "\n  Application client comms protocol      ===> IPX/SPX");
         break;
      case SQLM_PROT_LOCAL:
         fprintf(outstream, "\n  Application client comms protocol      ===> Local");
         break;
      case SQLM_PROT_NPIPE:
         fprintf(outstream, "\n  Application client comms protocol      ===> Named Pipe");
         break;
      default:
         fprintf(outstream, "\n  Application client comms protocol      ===> Unknown (%lu)", applinfo_ptr->client_protocol);
         break;
   } /* endswitch */


   fprintf(outstream, "\n  Input Database Alias                   ===> %0.*s", SQLM_IDENT_SZ, applinfo_ptr->id_info.input_db_alias);
   fprintf(outstream, "\n  Client Database Alias                  ===> %0.*s", SQLM_IDENT_SZ, applinfo_ptr->id_info.client_db_alias);
   fprintf(outstream, "\n  Database Name                          ===> %0.*s", SQLM_IDENT_SZ, applinfo_ptr->id_info.db_name);
   fprintf(outstream, "\n  Database path (truncated to 70 chars)\n     ===> %0.70s\n", applinfo_ptr->id_info.db_path);

   buffer_index += (unsigned int) applinfo_ptr->size; /* move to next struct */

   if (output_opt == SCREEN_OUTPUT)
      pause();

}  /* process_applinfo */

/********************************************************************************/
/* process_dcs_applinfo                                                         */
/* This function processes DB2 Connect application information. The information */
/* is in an sqlm_dcs_applid_info data structure .                               */
/* This information is only available from a DB2 Connect server (gateway).      */
/********************************************************************************/

void process_dcs_applinfo()
{

   time_t                ltime;
   struct sqlm_dcs_applinfo     *dcs_appl1;        /* work pointer              */
   struct sqlm_dcs_applid_info  *dcs_appl;         /* work pointer              */

   if (output_opt == SCREEN_OUTPUT)
      clrscrn();

   fprintf(outstream, "**********************************************************************\n");
   fprintf(outstream, "*                     DB2 Connect APPLICATION INFORMATION                   *\n");
   fprintf(outstream, "**********************************************************************\n");

   /* Cast the buffer contents to an sqlm_dcs_applinfo data structure */
   dcs_appl1 = (struct sqlm_dcs_applinfo *)(buffer_index);

   /* Skip the structure sqlm_dcs_applinfo and point to the secondary          */
   /* structure sqlm_dcs_applid_info:                                          */
   buffer_index += dcs_appl1->size;
   dcs_appl = (sqlm_dcs_applid_info *) buffer_index;

   fprintf(outstream, "\n  Application handle (agent ID)          ===> %lu", dcs_appl->agent_id);
   fprintf(outstream, "\n  Application codepage ID                ===> %lu", dcs_appl->codepage_id);
   fprintf(outstream, "\n  Application name                       ===> %0.*s", SQLM_IDENT_SZ, dcs_appl->appl_name);
   fprintf(outstream, "\n  Client application ID                  ===> %0.*s", SQLM_APPLID_SZ,
         dcs_appl->appl_id);
   fprintf(outstream, "\n  Application ID Sequence number         ===> %0.*s", SQLM_SEQ_SZ, dcs_appl->sequence_no);
   fprintf(outstream, "\n  Application Authorization Id           ===> %0.*s", SQLM_IDENT_SZ, dcs_appl->auth_id);
   fprintf(outstream, "\n  Application client execution ID        ===> %0.*s", SQLM_IDENT_SZ, dcs_appl->execution_id);
   fprintf(outstream, "\n  Application client NNAME               ===> %0.*s", SQLM_IDENT_SZ, dcs_appl->client_nname);
   fprintf(outstream, "\n  Application client Product name        ===> %0.*s", SQLM_IDENT_SZ, dcs_appl->client_prdid);

   switch (dcs_appl->dcs_appl_status)
   {
      case SQLM_DCS_CONNECTPEND_OUTBOUND:
         fprintf(outstream, "\n  Application status                     ===> %s",
                            "connect pending - outbound");
         break;
      case SQLM_DCS_UOWWAIT_OUTBOUND:
         fprintf(outstream, "\n  Application status                     ===> %s",
                            "waiting for host reply");
         break;
      case SQLM_DCS_UOWWAIT_INBOUND:
         fprintf(outstream, "\n  Application status                     ===> %s",
                            "waiting for client request");
         break;
   } /* end switch on DCS application status */

   ltime = dcs_appl->status_change_time.seconds;
   fprintf(outstream, "\n  Status change time                     ===> %24.24s",
                                    (ltime) ? ctime(<ime) : "");
   fprintf(outstream, "\n  Gateway Database Alias                 ===> %0.*s", SQLM_IDENT_SZ, dcs_appl->gw_db_alias);
   fprintf(outstream, "\n  DCS Database Name                      ===> %0.*s", SQLM_IDENT_SZ, dcs_appl->dcs_db_name);
   fprintf(outstream, "\n  Host Database Name                     ===> %0.*s", SQLM_IDENT_SZ, dcs_appl->host_db_name);
   fprintf(outstream, "\n  Host Product Id                        ===> %0.*s", SQLM_IDENT_SZ, dcs_appl->host_prdid);
   fprintf(outstream, "\n  Host Application Id                    ===> %0.*s", SQLM_APPLID_SZ, dcs_appl->outbound_appl_id);
   fprintf(outstream, "\n  Outbound Sequence number               ===> %0.*s\n", SQLM_SEQ_SZ, dcs_appl->outbound_sequence_no);

   buffer_index += (unsigned int) dcs_appl->size; /* move to next struct */

   if (output_opt == SCREEN_OUTPUT)
      pause();

}  /* process_dcs_applinfo */

/*****************************************************************************/
/* process_table                                                             */
/* This function processes table information. This information is stored in  */
/* sqlm_table_header and sqlm_table data structures. First, we find an       */
/* sqlm_table_header structure, which provides general information, and the  */
/* number of sqlm_table structures following in the buffer.                  */
/*****************************************************************************/

void process_table()
{

   time_t                   ltime;
   unsigned int             i;              /* counter                       */
   struct sqlm_table        *table_ptr;
   struct sqlm_table_header *table_header_ptr;
   char                     table_type[21];
   char                     *c;

   if (output_opt == SCREEN_OUTPUT)
      clrscrn();

   fprintf(outstream, "**********************************************************************\n");
   fprintf(outstream, "*                          TABLE INFORMATION                         *\n");
   fprintf(outstream, "**********************************************************************\n");

   /* cast buffer contents to an sqlm_table_header data structure */
   table_header_ptr = (struct sqlm_table_header *) (buffer_index);

   fprintf(outstream, "\nTable Header Information:");
   fprintf(outstream, "\n  Number of tables collected              ===> %lu", table_header_ptr->num_tables);
   ltime = table_header_ptr->db_conn_time.seconds;
   fprintf(outstream, "\n  First database connect time             ===> %24.24s",
                                    (ltime) ? ctime(<ime) : "");
   ltime = table_header_ptr->last_reset.seconds;
   fprintf(outstream, "\n  Last reset time                         ===> %24.24s",
                                    (ltime) ? ctime(<ime) : "");

   fprintf(outstream, "\n  Input Database Alias                    ===> %0.*s", SQLM_IDENT_SZ, table_header_ptr->input_db_alias);
   fprintf(outstream, "\n  Database Name                           ===> %0.*s", SQLM_IDENT_SZ, table_header_ptr->db_name);
   fprintf(outstream, "\n  Database path (truncated to 70 chars)\n     ===> %0.70s", table_header_ptr->db_path);

   if (output_opt == SCREEN_OUTPUT)
      pause();

   /* advance pointer to first sqlm_table structure */
   buffer_index += table_header_ptr->size;

   /* process each sqlm_table structure returned */
   for (i = 0; i < table_header_ptr->num_tables; ++i)
   {

      /* cast buffer contents to an sqlm_table data structure */
      table_ptr = (struct sqlm_table *)(buffer_index);

      if (table_ptr->info_type != SQLM_TABLE_SS)
      {
         printf("\n\n***************************************************************\n");
         printf("*    ERROR processing output buffer from snapshot monitor.    *\n");
         printf("*    Expecting sqlm_table structure. First chars: %10c   *\n",(unsigned char)*buffer_index);
         printf("*    buffer offset where error occurred: %10u             *\n",(ptrdiff_t)(buffer_index - buffer_ptr));
         printf("*    Exiting ssdriver.                                        *\n\n");
         printf("\n***************************************************************\n");
         cleanup(NULL);
         exit(99);
      }

      /***************************************************************/
      /* Print the headers before the first table's info             */
      /***************************************************************/

      if (i == 0)
      {
         fprintf(outstream, "Individual Table Information:\n");
         fprintf(outstream, "Table Name                   Table Type    Rows Written  Rows Read   Overflows\n");
         fprintf(outstream, "---------------------------  ------------  ------------  ----------  ----------\n");
      }

      switch(table_ptr->table_type)
      {
         case SQLM_USER_TABLE:
              strcpy(table_type, "User");
              break;
         case SQLM_DROPPED_TABLE:
              strcpy(table_type, "Dropped User");
              break;
         case SQLM_TEMP_TABLE:
              strcpy(table_type, "Temporary");
              break;
         case SQLM_CATALOG_TABLE:
              strcpy(table_type, "Catalog");
              break;
         case SQLM_REORG_TABLE:
              strcpy(table_type, "Reorg");
              break;
         default:
              strcpy(table_type, "Unknown");
              break;
      }

      /***********************************************************************/
      /* Null terminate the table_schema                                     */
      /***********************************************************************/
      for (c = table_ptr->table_schema; *c != ' '; ++c);
      *c = '\0';

      /***********************************************************************/
      /* Display information about each table in a tabular format similar    */
      /* to the one provided by the CLP command.                             */
      /***********************************************************************/
      fprintf(outstream, "%s.%-.*s  %-*s    %*lu  %*lu  %*lu\n",
                             table_ptr->table_schema,
                         18 + 8 - strlen(table_ptr->table_schema),
                             table_ptr->table_name,
                         12, table_type,
                         10, table_ptr->rows_written,
                         10, table_ptr->rows_read,
                         10, table_ptr->overflow_accesses);

      /* move pointer to next structure */
      buffer_index += table_ptr->size;

   } /* end of for loop */

   if ((output_opt == SCREEN_OUTPUT) && (table_header_ptr->num_tables > 0))
      pause();

} /* process_table */


/*****************************************************************************/
/* process_lock                                                              */
/* This function processes lock information. This information is contained   */
/* in sqlm_dbase_lock, sqlm_appl_lock, and sqlm_lock data structures.        */
/* First, an sqlm_dbase_lock structure with information on the database, and */
/* the number of sqlm_appl_lock structures returned. Each sqlm_appl_lock     */
/* structure contains application info, and the number of sqlm_lock          */
/* structures following in the buffer.                                       */
/*****************************************************************************/

void process_lock()
{

   time_t                 ltime;
   unsigned int           i, j;              /* counters                      */
   struct sqlm_dbase_lock *dbase_lock_ptr;   /* local ptr to sqlm_dbase_lock  */
   struct sqlm_appl_lock  *appl_lock_ptr;    /* local ptr to sqlm_appl_lock   */
   struct sqlm_lock       *lock_ptr;         /* local ptr to sqlm_lock        */
   char                   lock_type[15];     /* string for lock object type   */
   char                   lock_mode[5];      /* string for lock mode          */
   char                   lock_status[11];   /* string for lock status        */
   char                   lock_obj_name[41]; /* string for lock object name   */
   char                   *c;


   if (output_opt == SCREEN_OUTPUT)
      clrscrn();

   fprintf(outstream, "**********************************************************************\n");
   fprintf(outstream, "*                          LOCK INFORMATION                          *\n");
   fprintf(outstream, "**********************************************************************\n");

   /* cast the buffer contents to an sqlm_dbase_lock data structure */
   dbase_lock_ptr = (struct sqlm_dbase_lock *)(buffer_index);

   fprintf(outstream, "\nDatabase Lock Information:");
   fprintf(outstream, "\n  Locks currently held                    ===> %lu", dbase_lock_ptr->locks_held);
   fprintf(outstream, "\n  No. of applications currently connected ===> %lu", dbase_lock_ptr->appls_cur_cons);
   fprintf(outstream, "\n  Applications waiting on locks           ===> %lu", dbase_lock_ptr->locks_waiting);
   fprintf(outstream, "\n  Input Database Alias                    ===> %0.*s", SQLM_IDENT_SZ, dbase_lock_ptr->input_db_alias);
   fprintf(outstream, "\n  Database Name                           ===> %0.*s", SQLM_IDENT_SZ, dbase_lock_ptr->db_name);
   fprintf(outstream, "\n  Database path (truncated to 70 chars)\n     ===> %0.70s", dbase_lock_ptr->db_path);

   fprintf(outstream, "\n  Number of sqlm_appl_lock returned       ===> %lu\n", dbase_lock_ptr->num_appls);

   /* advance buffer_index to the next structure in the buffer */
   buffer_index += dbase_lock_ptr->size;

   if (output_opt == SCREEN_OUTPUT)
      pause();

   /*******************************************************************************/
   /* Loop until all sqlm_appl_lock structures are processed                      */
   /*******************************************************************************/

   for (i = 0; i < dbase_lock_ptr->num_appls; i++)
   {
      /* cast the buffer contents to an sqlm_appl_lock data structure */
      appl_lock_ptr = (struct sqlm_appl_lock *)(buffer_index);

      if (appl_lock_ptr->info_type != SQLM_APPL_LOCK_SS)
      {
         printf("\n\n***************************************************************\n");
         printf("*    ERROR processing output buffer from snapshot monitor.    *\n");
         printf("*    Expecting sqlm_appl_lock structure. First chars: %10c *\n",(unsigned char)*buffer_index);
         printf("*    buffer offset where error occurred: %10u             *\n",(ptrdiff_t)(buffer_index - buffer_ptr));
         printf("*    Exiting ssdriver.                                        *\n\n");
         printf("\n***************************************************************\n");
         cleanup(NULL);
         exit(99);
      }

      fprintf(outstream, "\n\nApplication Lock Information:");
      fprintf(outstream, "\n      Agent ID                            ===> %lu", appl_lock_ptr->agent_id);
      switch (appl_lock_ptr->appl_status)
      {
         case SQLM_CONNECTPEND:
            fprintf(outstream, "\n      Application Status                  ===> Connect Pending");
            break;
         case SQLM_CONNECTED:
            fprintf(outstream, "\n      Application Status                  ===> Connected");
            break;
         case SQLM_UOWEXEC:
            fprintf(outstream, "\n      Application Status                  ===> UOW Executing");
            break;
         case SQLM_UOWWAIT:
            fprintf(outstream, "\n      Application Status                  ===> UOW Waiting in the application");
            break;
         case SQLM_LOCKWAIT:
            fprintf(outstream, "\n      Application Status                  ===> Lock Waiting");
            break;
         case SQLM_COMMIT_ACT:
            fprintf(outstream, "\n      Application Status                  ===> Commit Active");
            break;
         case SQLM_ROLLBACK_ACT:
            fprintf(outstream, "\n      Application Status                  ===> Rollback Active");
            break;
         case SQLM_RECOMP:
            fprintf(outstream, "\n      Application Status                  ===> Recompiling Plan");
            break;
         case SQLM_COMP:
            fprintf(outstream, "\n      Application Status                  ===> Compiling SQL Stmt");
            break;
         case SQLM_INTR:
            fprintf(outstream, "\n      Application Status                  ===> Request Interupted");
            break;
         case SQLM_DISCONNECTPEND:
            fprintf(outstream, "\n      Application Status                  ===> Disconnect Pending");
            break;
         case SQLM_TPREP:
            fprintf(outstream, "\n      Application Status                  ===> Prepared Transaction");
            break;
         case SQLM_THCOMT:
            fprintf(outstream, "\n      Application Status                  ===> Trans. heuristically committed");
            break;
         case SQLM_THABRT:
            fprintf(outstream, "\n      Application Status                  ===> Trans. heuristically aborted");
            break;
         case SQLM_TEND:
            fprintf(outstream, "\n      Application Status                  ===> Transaction ended");
            break;
         case SQLM_CREATE_DB:
            fprintf(outstream, "\n      Application Status                  ===> Creating Database");
            break;
         case SQLM_RESTART:
            fprintf(outstream, "\n      Application Status                  ===> Restarting Database");
            break;
         case SQLM_RESTORE:
            fprintf(outstream, "\n      Application Status                  ===> Restoring Database");
            break;
         case SQLM_BACKUP:
            fprintf(outstream, "\n      Application Status                  ===> Backing Up Database");
            break;
         case SQLM_LOAD:
            fprintf(outstream, "\n      Application Status                  ===> Loading Database");
            break;
         case SQLM_UNLOAD:
            fprintf(outstream, "\n      Application Status                  ===> Unloading Database");
            break;
         case SQLM_IOERROR_WAIT:
            fprintf(outstream, "\n      Application Status                  ===> I/O Error Waiting");
            break;
         case SQLM_QUIESCE_TABLESPACE:
            fprintf(outstream, "\n      Application Status                  ===> Quiescing a Tablespace");
            break;
         default:
            fprintf(outstream, "\n      Application Status                  ===> Unknown (%lu)", appl_lock_ptr->appl_status);
            break;
      } /* endswitch */
      fprintf(outstream, "\n      Application Codepage Id             ===> %lu", appl_lock_ptr->codepage_id);
      fprintf(outstream, "\n      Locks currently held by application ===> %lu", appl_lock_ptr->locks_held);
      ltime = appl_lock_ptr->status_change_time.seconds;
      fprintf(outstream, "\n      Application status change time      ===> %24.24s",
                                  (ltime) ? ctime(<ime) : "");

      fprintf(outstream, "\n      Application Id                      ===> %0.*s", SQLM_APPLID_SZ, appl_lock_ptr->appl_id);
      fprintf(outstream, "\n      Application Id sequence number      ===> %0.*s", SQLM_SEQ_SZ, appl_lock_ptr->sequence_no);
      fprintf(outstream, "\n      Application name                    ===> %0.*s", SQLM_IDENT_SZ, appl_lock_ptr->appl_name);
      fprintf(outstream, "\n      Authorization ID                    ===> %0.*s", SQLM_IDENT_SZ, appl_lock_ptr->auth_id);
      fprintf(outstream, "\n      Client database alias               ===> %0.*s", SQLM_IDENT_SZ, appl_lock_ptr->client_db_alias);

      fprintf(outstream, "\n    Lock waited on information:");

      fprintf(outstream, "\n      number of locks returned            ===> %lu\n", appl_lock_ptr->num_locks);

      /* advance to next structure in the buffer */
      buffer_index += appl_lock_ptr->size;

      if (output_opt == SCREEN_OUTPUT)
         pause();


      /*********************************************************************/
      /* Display information for each of the locks held by the application */
      /*********************************************************************/

      for (j = 0; j < appl_lock_ptr->num_locks; j++)
      {
         /* cast the buffer contents to an sqlm_lock data structure */
         lock_ptr = (struct sqlm_lock *)(buffer_index);

         if (lock_ptr->info_type != SQLM_LOCK_SS)
         {
            printf("\n\n***************************************************************\n");
            printf("*    ERROR processing output buffer from snapshot monitor.    *\n");
            printf("*    Expecting sqlm_lock structure. First chars: %10c   *\n",(unsigned char)*buffer_index);
            printf("*    buffer offset where error occurred: %10u             *\n",(ptrdiff_t)(buffer_index - buffer_ptr));
            printf("*    Exiting ssdriver.                                        *\n\n");
            printf("\n***************************************************************\n");
            cleanup(NULL);
            exit(99);
         }


         /*****************************************************************/
         /* Print headers before first lock information                   */
         /*****************************************************************/

         if (j == 0)
         {
            fprintf(outstream, "\nIndividual Lock Information:");
            fprintf(outstream, "\nObject Name                                Object Type        Mode   Status\n");
            fprintf(outstream, "----------------------------------------   ---------------    ----   ----------\n");
         }

         /* Null terminate table schema */
         for (c = lock_ptr->table_schema; *c != ' '; ++c);
         *c = '\0';
         switch (lock_ptr->lock_object_type)
         {
            case SQLM_ROW_LOCK:
                 strcpy(lock_type, "Row");
                 sprintf(lock_obj_name, "%s.%-.*s (%ld)",
                         lock_ptr->table_schema,
                         18 + 8 - strlen(lock_ptr->table_schema),
                         lock_ptr->table_name, lock_ptr->lock_object_name);
                 break;
            case SQLM_TABLE_LOCK:
                 strcpy(lock_type, "Table");
                 sprintf(lock_obj_name, "%s.%-.*s",
                         lock_ptr->table_schema,
                         18 + 8 - strlen(lock_ptr->table_schema),
                         lock_ptr->table_name);
                 break;
            case SQLM_INTERNAL_LOCK:
                 strcpy(lock_type, "Internal");
                 lock_obj_name[0] = '\0';
                 break;
            case SQLM_TABLESPACE_LOCK:
                 strcpy(lock_type, "Tablespace");
                 sprintf(lock_obj_name, "%.*s", 18, lock_ptr->tablespace_name);
                 break;
            default:
                 strcpy(lock_type, "Unknown");
                 break;
         }  /* switch */

         switch (lock_ptr->lock_mode)
         {
            case SQLM_LNON:
                 strcpy(lock_mode, "NO");
                 break;
            case SQLM_LOIS:
                 strcpy(lock_mode, "IS");
                 break;
            case SQLM_LOIX:
                 strcpy(lock_mode, "IX");
                 break;
            case SQLM_LOOS:
                 strcpy(lock_mode, "S");
                 break;
            case SQLM_LSIX:
                 strcpy(lock_mode, "SIX");
                 break;
            case SQLM_LOOX:
                 strcpy(lock_mode, "X");
                 break;
            case SQLM_LOIN:
                 strcpy(lock_mode, "IN");
                 break;
            case SQLM_LOOZ:
                 strcpy(lock_mode, "Z");
                 break;
            case SQLM_LOOU:
                 strcpy(lock_mode, "U");
                 break;
            default:
                 strcpy(lock_mode, "????");
                 break;
         } /* endswitch */

         switch (lock_ptr->lock_status)
         {
            case SQLM_LRBGRNT:
                 strcpy(lock_status, "Granted");
                 break;
            case SQLM_LRBCONV:
                 strcpy(lock_status, "Converting");
                 break;
            default:
                 strcpy(lock_status, "Unknown");
                 break;
         }  /* switch */

         /*******************************************************************/
         /* Display information about each lock in a tabular format similar */
         /* to the one returned by the CLP Get Snapshot command.            */
         /*******************************************************************/
         fprintf(outstream, " %-*s  %-*s     %-*s  %-*s\n",
                            40, lock_obj_name,
                            15, lock_type,
                            4,  lock_mode,
                            10, lock_status);

         /* advance to next structure in the buffer */
         buffer_index += lock_ptr->size;
         } /* endfor */

      if (output_opt == SCREEN_OUTPUT)
         pause();

      } /* end of for loop */

} /* process_lock */

/*****************************************************************************/
/* process_tablespace                                                        */
/* This function processes tablespace information. This information is       */
/* contained in sqlm_tablespace_header and sqlm_tablespace data structures.  */
/* First, an sqlm_tablespace_header structure with information on the        */
/* database, and the number of sqlm_tablespace structures returned.          */
/*****************************************************************************/

void process_tablespace()
{

   time_t                 ltime;
   unsigned int           i, j;              /* counters                      */
   sqlm_tablespace_header   *ts_header_ptr;  /* local ptr to tablespace header*/
   sqlm_tablespace          *ts_ptr;         /* local ptr to tablespace info  */

   if (output_opt == SCREEN_OUTPUT)
      clrscrn();

   fprintf(outstream, "**********************************************************************\n");
   fprintf(outstream, "*                        TABLESPACE INFORMATION                      *\n");
   fprintf(outstream, "**********************************************************************\n");

   /* cast the buffer contents to an sqlm_tablespace_header data structure */
   ts_header_ptr = (sqlm_tablespace_header *)(buffer_index);

   fprintf(outstream, "\nDatabase Information:");
   fprintf(outstream, "\n  Number of tablespaces collected         ===> %lu", ts_header_ptr->num_tablespaces);
   ltime = ts_header_ptr->db_conn_time.seconds;
   fprintf(outstream, "\n  First database connect time             ===> %24.24s",
                                    (ltime) ? ctime(<ime) : "");
   ltime = ts_header_ptr->last_reset.seconds;
   fprintf(outstream, "\n  Last reset time                         ===> %24.24s",
                                    (ltime) ? ctime(<ime) : "");

   fprintf(outstream, "\n  Input Database Alias                    ===> %0.*s", SQLM_IDENT_SZ, ts_header_ptr->input_db_alias);
   fprintf(outstream, "\n  Database Name                           ===> %0.*s", SQLM_IDENT_SZ, ts_header_ptr->db_name);
   fprintf(outstream, "\n  Database path (truncated to 70 chars)\n     ===> %0.70s", ts_header_ptr->db_path);

   /* advance buffer_index to the next structure in the buffer */
   buffer_index += ts_header_ptr->size;

   if (output_opt == SCREEN_OUTPUT)
      pause();

   /*******************************************************************************/
   /* Loop until all sqlm_tablespace structures are processed                     */
   /*******************************************************************************/

   for (i = 0; i < ts_header_ptr->num_tablespaces; i++)
   {
      /* cast the buffer contents to an sqlm_tablespace data structure */
      ts_ptr = (struct sqlm_tablespace *)(buffer_index);

      if (ts_ptr->info_type != SQLM_TABLESPACE_SS)
      {
         printf("\n\n***************************************************************\n");
         printf("*    ERROR processing output buffer from snapshot monitor.    *\n");
         printf("*    Expecting sqlm_tablespace structure. First chars: %10c*\n",(unsigned char)*buffer_index);
         printf("*    buffer offset where error occurred: %10u             *\n",(ptrdiff_t)(buffer_index - buffer_ptr));
         printf("*    Exiting ssdriver.                                        *\n\n");
         printf("\n***************************************************************\n");
         cleanup(NULL);
         exit(99);
      }

      fprintf(outstream, "\n\nTablespace Information:");
      fprintf(outstream, "\n  Tablespace Name                         ===> %0.*s", SQLM_IDENT_SZ, ts_ptr->tablespace_name);

      fprintf(outstream, "\n\nBuffer Pool Information:");
      fprintf(outstream, "\n  Buffer pool logical data page reads     ===> %lu", ts_ptr->pool_data_l_reads);
      fprintf(outstream, "\n  Buffer pool physical data page reads    ===> %lu", ts_ptr->pool_data_p_reads);
      fprintf(outstream, "\n  Buffer pool data page writes            ===> %lu", ts_ptr->pool_data_writes);
      fprintf(outstream, "\n  Buffer pool logical index page reads    ===> %lu", ts_ptr->pool_index_l_reads);
      fprintf(outstream, "\n  Buffer pool physical index page reads   ===> %lu", ts_ptr->pool_index_p_reads);
      fprintf(outstream, "\n  Buffer pool index page writes           ===> %lu", ts_ptr->pool_index_writes);
      fprintf(outstream, "\n  Buffer pool read time since 1st connect ===> %lu milliseconds", ts_ptr->pool_read_time);
      fprintf(outstream, "\n  Buffer pool write time since 1st connect===> %lu milliseconds", ts_ptr->pool_write_time);
      fprintf(outstream, "\n  Files closed since 1st connect          ===> %lu", ts_ptr->files_closed);

      fprintf(outstream, "\n  Buffer pool asynch data page reads      ===> %lu", ts_ptr->pool_async_data_reads);
      fprintf(outstream, "\n  Buffer pool asynch data page reads reqs ===> %lu", ts_ptr->pool_async_data_read_reqs);
      fprintf(outstream, "\n  Buffer pool asynch data page writes     ===> %lu", ts_ptr->pool_async_data_writes);
      fprintf(outstream, "\n  Buffer pool asynch index page reads     ===> %lu", ts_ptr->pool_async_index_reads);
      fprintf(outstream, "\n  Buffer pool asynch index page writes    ===> %lu", ts_ptr->pool_async_index_writes);
      fprintf(outstream, "\n  Buffer pool asynch read time            ===> %lu milliseconds", ts_ptr->pool_async_read_time);
      fprintf(outstream, "\n  Buffer pool asynch write time           ===> %lu milliseconds", ts_ptr->pool_async_write_time);

      if (output_opt == SCREEN_OUTPUT)
         pause();

      fprintf(outstream, "\n\nDirect I/O Information:");
      fprintf(outstream, "\n  Sectors read directly                   ===> %lu", ts_ptr->direct_reads);
      fprintf(outstream, "\n  Sectors written directly                ===> %lu", ts_ptr->direct_writes);
      fprintf(outstream, "\n  Number of direct read requests          ===> %lu", ts_ptr->direct_read_reqs);
      fprintf(outstream, "\n  Number of direct write requests         ===> %lu", ts_ptr->direct_write_reqs);
      fprintf(outstream, "\n  Direct read time                        ===> %lu milliseconds", ts_ptr->direct_read_time);
      fprintf(outstream, "\n  Direct write time                       ===> %lu milliseconds", ts_ptr->direct_write_time);


      if (output_opt == SCREEN_OUTPUT)
         pause();

      buffer_index += ts_ptr->size;

   } /* end of for loop */

} /* process_tablespace */


/*****************************************************************************/
/* process_dcs_app                                                           */
/* This function processes DCS application information. This information is  */
/* contained in structure sqlm_dcs_appl . Secondary structures of different  */
/* types may follow this structure in the buffer. This code assumes that     */
/* only the statement structure (sqlm_dcs_stmt) may follow it.               */
/*****************************************************************************/

void process_dcs_app()
{

   time_t                   ltime;
   sqlm_dcs_appl            *appl;             /* work pointer                */
   sqlm_dcs_applid_info     *applid;           /* work pointer                */
   sqlm_dcs_appl_snap_stats *stats;            /* work pointer                */
   sqlm_dcs_stmt            *stmt;             /* work pointer                */
   char          curr_sqlm_structure;          /* work variable               */
   char          statement[32001];             /* work variable - stmt text   */


   /* Cast the buffer contents to an sqlm_dcs_appl data structure */
   appl = (sqlm_dcs_appl *)(buffer_index);
   /******************************************************************/
   /* Get the pointers to secondary structures sqlm_dcs_applid_info  */
   /* and sqlm_dcs_appl_snap_stats that immediately follow the main  */
   /* structure sqlm_dcs_appl.                                       */
   /******************************************************************/
   buffer_index += appl->size;
   applid = (sqlm_dcs_applid_info *) buffer_index;
   buffer_index += applid->size;
   stats = (sqlm_dcs_appl_snap_stats *) buffer_index;


   if (output_opt == SCREEN_OUTPUT)
      clrscrn();

   fprintf(outstream, "**********************************************************************\n");
   fprintf(outstream, "*                       DCS APPLICATION SNAPSHOT INFO                *\n");
   fprintf(outstream, "**********************************************************************\n");
   fprintf(outstream, "\n(a) Application ID info - examples of data elements retrieved from \n");
   fprintf(outstream, "    secondary structure sqlm_dcs_applid_info:\n");

   fprintf(outstream, "\n  Application handle (agent ID)          ===> %lu", applid->agent_id);
   fprintf(outstream, "\n  Client application ID                  ===> %0.*s", SQLM_APPLID_SZ,
         applid->appl_id);

   switch (applid->dcs_appl_status)
   {
      case SQLM_DCS_CONNECTPEND_OUTBOUND:
         fprintf(outstream, "\n  Application status                     ===> %s",
                            "connect pending - outbound");
         break;
      case SQLM_DCS_UOWWAIT_OUTBOUND:
         fprintf(outstream, "\n  Application status                     ===> %s",
                            "waiting for host reply");
         break;
      case SQLM_DCS_UOWWAIT_INBOUND:
         fprintf(outstream, "\n  Application status                     ===> %s",
                            "waiting for client request");
         break;
   } /* end switch on DCS application status */

   ltime = applid->status_change_time.seconds;
   fprintf(outstream, "\n  Status change time                     ===> %24.24s",
                                    (ltime) ? ctime(<ime) : "");
   fprintf(outstream, "\n  Host Database Name                     ===> %0.*s", SQLM_IDENT_SZ,
         applid->host_db_name);
   fprintf(outstream, "\n  Host Product Id                        ===> %0.*s", SQLM_IDENT_SZ,
         applid->host_prdid);
   fprintf(outstream, "\n  Host Application Id                    ===> %0.*s", SQLM_APPLID_SZ,
         applid->outbound_appl_id);

   fprintf(outstream, "\n\n(b) Application stats - examples of data elements retrieved from \n");
   fprintf(outstream, "    the main structure sqlm_dcs_appl:\n");
   fprintf(outstream, "\n  Open cursors                           ===> %lu",
         appl->open_cursors);
   fprintf(outstream, "\n  Application idle time                  ===> %lu",
         appl->appl_idle_time);

   fprintf(outstream, "\n\n(c) Application stats - examples of data elements retrieved from \n");
   fprintf(outstream, "    the secondary structure sqlm_appl_snap_stats:\n");

   /* Time spent on gateway processing */
   if (collected.group_states[SQLM_STATEMENT_SW].output_state == SQLM_ON)
   {
     fprintf(outstream, "\n  Time spent on gateway processing       ===> %lu.%0.6lu",
             stats->appl_stats.gw_exec_time.seconds,
             stats->appl_stats.gw_exec_time.microsec);
   }

   /* Number of SQL statements attempted */
   fprintf(outstream, "\n  Number of SQL statements attempted     ===> %lu",
         stats->appl_stats.sql_stmts);

   if (collected.group_states[SQLM_UOW_SW].output_state == SQLM_ON)
   {
     /* UOW start timestamp */
     ltime = appl->uow_start_time.seconds;
     fprintf(outstream, "\n  UOW start timestamp                    ===> %24.24s",
                                   (ltime) ? ctime(<ime) : "");
     /* UOW stop timestamp */
     ltime = appl->uow_stop_time.seconds;
     fprintf(outstream, "\n  UOW stop timestamp                     ===> %24.24s",
                                   (ltime) ? ctime(<ime) : "");
   }

   /* advance buffer_index to the next structure in the buffer */
   buffer_index += stats->size;
   curr_sqlm_structure = *(buffer_index + 4);
   switch(curr_sqlm_structure)
   {
     case SQLM_DCS_STMT_SS:  /* This is statement secondary str. */
       stmt = (struct sqlm_dcs_stmt *) buffer_index;

       fprintf(outstream, "\n\n(d) Application stats - examples of data elements retrieved from \n");
       fprintf(outstream, "    the secondary structure sqlm_dcs_stmt (statement-level information):\n");

       switch (stmt->stmt_operation)
       {
          case SQLM_PREPARE:
             fprintf(outstream, "\n  Statement operation                    ===> %s",
                                "Prepare");
             break;
          case SQLM_EXECUTE:
             fprintf(outstream, "\n  Statement operation                    ===> %s",
                                "Execute");
             break;
          case SQLM_EXECUTE_IMMEDIATE:
             fprintf(outstream, "\n  Statement operation                    ===> %s",
                                "Execute immediate");
             break;
          case SQLM_OPEN:
             fprintf(outstream, "\n  Statement operation                    ===> %s",
                                "Open");
             break;
          case SQLM_FETCH:
             fprintf(outstream, "\n  Statement operation                    ===> %s",
                                "Fetch");
             break;
          case SQLM_CLOSE:
             fprintf(outstream, "\n  Statement operation                    ===> %s",
                                "Close");
             break;
          case SQLM_DESCRIBE:
             fprintf(outstream, "\n  Statement operation                    ===> %s",
                                "Describe");
             break;
          case SQLM_STATIC_COMMIT:
             fprintf(outstream, "\n  Statement operation                    ===> %s",
                                "Static COMMIT");
             break;
          case SQLM_STATIC_ROLLBACK:
             fprintf(outstream, "\n  Statement operation                    ===> %s",
                                "Static ROLLBACK");
             break;
          case SQLM_FREE_LOCATOR:
             fprintf(outstream, "\n  Statement operation                    ===> %s",
                                "Free locator");
             break;
          case SQLM_PREP_COMMIT:
             fprintf(outstream, "\n  Statement operation                    ===> %s",
                                "Prepare to commit");
             break;
          case SQLM_CALL:
             fprintf(outstream, "\n  Statement operation                    ===> %s",
                                "Call stored procedure");
             break;
          case SQLM_SELECT:
             fprintf(outstream, "\n  Statement operation                    ===> %s",
                                "Select");
             break;
          case SQLM_PREP_OPEN:
             fprintf(outstream, "\n  Statement operation                    ===> %s",
                                "Prepare and open");
             break;
          case SQLM_PREP_EXEC:
             fprintf(outstream, "\n  Statement operation                    ===> %s",
                                "Prepare and execute");
             break;
          case SQLM_COMPILE:
             fprintf(outstream, "\n  Statement operation                    ===> %s",
                                "Compile");
             break;
          default :
             fprintf(outstream, "\n  Statement operation                    ===> %s",
                                "Non-SQL operation");
             break;
       } /* end switch on statement operation */

       fprintf(outstream, "\n  Section number                         ===> %lu",
                            stmt->section_number);
       fprintf(outstream, "\n  Application creator                    ===> %0.*s",
                            SQLM_IDENT_SZ, stmt->creator );
       fprintf(outstream, "\n  Package name                           ===> %0.*s",
                            SQLM_IDENT_SZ, stmt->package_name);

       /* Statement start timestamp */
       ltime = stmt->stmt_start.seconds;
       fprintf(outstream, "\n  Statement start timestamp              ===> %24.24s",
                                     (ltime) ? ctime(<ime) : "");
       /* Statement stop timestamp */
       ltime = stmt->stmt_stop.seconds;
       fprintf(outstream, "\n  Statement stop timestamp               ===> %24.24s",
                                     (ltime) ? ctime(<ime) : "");
       /* Time spent on gateway processing for the statement: */
       fprintf(outstream, "\n  Time spent on gateway processing       ===> %lu.%0.6lu",
                          stmt->gw_exec_time.seconds,
                          stmt->gw_exec_time.microsec);

       /* Statement text (if present) */
       if (stmt->stmt_length > 0)           /* Print only if there is some text   */
       {
          /* Copy the statement text to a local char array and null-terminate     */

          char *stmt_text= (char*) stmt + stmt->stmt_text_offset;
          memcpy(statement, stmt_text, stmt->stmt_length);
          statement[stmt->stmt_length] = '\0';
          fprintf(outstream, "\n  Statement text:\n    %s", statement);
       }

       buffer_index += stmt->size;   /* Point to the next structure in buffer */
       break;
     case SQLM_APPL_XID_SS: /* This is xid sec. structure        */

       /* ===> Add code here to process the xid structure ...    */

       /* ===> Add code here to point to the next structure in buffer:  */
       /* ===> buffer_index += ...->size;                               */
       break;
     case SQLM_TPMON_INFO_SS: /* This is tpmon secondary struct. */

       /* ===> Add code here to process the tpmon structure ...  */

       /* ===> Add code here to point to the next structure in buffer:  */
       /* ===> buffer_index += ...->size;                               */
       break;
     default:
       goto exit;
   }
exit:
   if (output_opt == SCREEN_OUTPUT)
      pause();


} /* process_dcs_app */


/*****************************************************************************/
/* pr_sqlca                                                                  */
/* This function prints the contents of the sqlca error information          */
/* structure.                                                                */
/*****************************************************************************/
void pr_sqlca(struct sqlca *ca)
{

  char           buffer[200];
  unsigned short i;

  /*Print out header for DUMP*/
  fprintf(outstream, "*************************************\n");
  fprintf(outstream, "*         CONTENTS OF SQLCA         *\n");
  fprintf(outstream, "*************************************\n\n");

  /*Print out contents of SQLCA variables*/
  fprintf(outstream, "SQLCABC  = %ld\n", ca->sqlcabc);
  fprintf(outstream, "SQLCODE  = %ld\n", ca->sqlcode);
  fprintf(outstream, "SQLERRMC = %0.70s\n", ca->sqlerrmc);
  fprintf(outstream, "SQLERRP  =  %0.8s\n", ca->sqlerrp);

  sqlaintp(buffer, sizeof(buffer), 80, ca);
  fprintf(outstream, "%0.200s\n", buffer);

  for (i = 0; i < 6; i++)
  {
    fprintf(outstream, "sqlerrd[%d] = %lu \n", i, ca->sqlerrd[i]);
  }

  fprintf(outstream, "SQLWARN  = %0.11s\n", ca->sqlwarn);
  fprintf(outstream, "SQLSTATE = %0.5s\n", ca->sqlstate);
}  /* pr_sqlca */

/*****************************************************************************/
/* cleanup                                                                   */
/* General cleanup routine to close open files and release memory buffers.   */
/*****************************************************************************/
void cleanup(struct sqlma *ma_ptr)

{

   int                   rc = 0;

  if (output_opt == FILE_OUTPUT)
  {                                                     /* close output file */
    rc = fclose(outstream);
    if (rc != 0)
    {
      fprintf(outstream, "error closing output file at cleanup. rc= %d\n", rc);
    }
  }
  if (buffer_ptr != NULL)
     free(buffer_ptr);                                 /* free output buffer */

  if (ma_ptr != NULL)                                  /* free sqlma         */
     free(ma_ptr);


}  /* cleanup */

/*****************************************************************************/
/* pause.                                                                    */
/* Waits for user input before proceeding                                    */
/*****************************************************************************/
void pause()
{
   printf("\nPress Enter to continue!\n");
   fflush(stdin);
   getchar();
}  /* pause */

/*****************************************************************************/
/* clrscrn.                                                                  */
/* Clears the user's screen                                                  */
/*****************************************************************************/
void clrscrn()
{
   system(CLEARSCR);
}  /* clrscrn */