DSN8ED2

Use the Instrumentation Facility Interface (IFI) to process a Db2 command which has been passed from DSN8ED1, the requester program.

 /********************************************************************  00010000
 *   Module name = DSN8ED2 (sample program)                          *  00020000
 *                                                                   *  00030000
 *   Descriptive name = Stored procedure result set server program   *  00040000
 *                                                                   *  00050000
 *     LICENSED MATERIALS - PROPERTY OF IBM                          *  00060000
 *     5675-DB2                                                      *  00070000
 *     (C) COPYRIGHT 1997, 2000 IBM CORP.  ALL RIGHTS RESERVED.      *  00080000
 *                                                                   *  00090000
 *     STATUS = VERSION 7                                            *  00100000
 *                                                                   *  00110000
 *   Function:                                                       *  00120000
 *      Use the Instrumentation Facility Interface (IFI) to process  *  00130000
 *      a DB2 command which has been passed from DSN8ED1, the        *  00140000
 *      requester program.  Load the responses to a temporary DB2    *  00150000
 *      table and return them as a result set.                       *  00160000
 *                                                                   *  00170000
 *   Notes:                                                          *  00180000
 *      Dependencies =                                               *  00190000
 *         1.  Must be linked and run under LE/370                   *  00200000
 *         2.  Requires global temporary table DSN8.DSN8ED2_RS_TBL   *  00202990
 *             (created by sample job DSNTEJ6T)                      *  00205980
 *                                                                   *  00210000
 *      Restrictions =                                               *  00220000
 *         1.  The Instrumentation Facility Communication Area       *  00230000
 *             (IFCA) contains information regarding the success     *  00240000
 *             of the call and provides feedback.                    *  00250000
 *             This area must be maintained to include any changes   *  00260000
 *             to the mapping macro DSNDIFCA.                        *  00270000
 *                                                                   *  00280000
 *         2. A command may be no more than 4096 bytes.              *  00290000
 *                                                                   *  00300000
 *   Module type  = C program                                        *  00310000
 *      Processor =                                                  *  00320000
 *         ADMF precompiler                                          *  00330000
 *         C/370                                                     *  00340000
 *      Module size = See linkedit output                            *  00350000
 *      Attributes = Not re-entrant nor re-usable                    *  00360000
 *                                                                   *  00370000
 *   Entry Point = CEESTART (LE/370)                                 *  00380000
 *      Purpose  = See function                                      *  00390000
 *      Linkage  = SIMPLE WITH NULLS                                 *  00400000
 *                 Invoked via EXEC SQL call                         *  00410000
 *      Input    = Parameters explicitly passed to this function:    *  00420000
 *         Symbolic label/name = ARGV[1] (puts inputcmd)             *  00430000
 *         Description = DB2 command to be processed by IFI.         *  00440000
 *                       Input statements from this parameter        *  00450000
 *                       will be passed to the text_or_command       *  00460000
 *                       field of the output_area of the IFI         *  00470000
 *                       utility for processing.                     *  00480000
 *                                                                   *  00490000
 *      Output   = Parameters explicitly returned:                   *  00500000
 *         Symbolic label/name = ARGV[2] (gets ifca_ret_hex)         *  00510000
 *         - IFI return code, in hex                                 *  00520000
 *         Symbolic label/name = ARGV[3] (gets ifca_res_hex)         *  00530000
 *         - IFI reason code, in hex                                 *  00540000
 *         Symbolic label/name = ARGV[4] (gets xs_bytes_hex)         *  00550000
 *         - Excess bytes not returned, in hex                       *  00560000
 *         Symbolic label/name = ARGV[5] (gets errmsg_buf)           *  00570000
 *         - Formatted SQL error messages                            *  00580000
 *         Symbolic label/name = ARGV[6] (gets indvar)               *  00590000
 *         - DB2 indicator variables                                 *  00600000
 *                                                                   *  00610000
 *      Output   = Result set returned:                              *  00620000
 *         Result set cursor name = DSN8ED2_RS_CSR                   *  00630000
 *         - Formatted responses from IFI for input command          *  00640000
 *                                                                   *  00650000
 *   Exit normal =                                                   *  00660000
 *      No errors were found in the passed DB2 command and no        *  00670000
 *      errors occurred during processing.                           *  00680000
 *                                                                   *  00690000
 *   Normal messages =                                               *  00700000
 *                                                                   *  00710000
 *   Exit-error =                                                    *  00720000
 *      Errors were found in the passed DB2 command or occurred      *  00730000
 *      during processing.                                           *  00740000
 *                                                                   *  00750000
 *      Return codes: n/a                                            *  00760000
 *                                                                   *  00770000
 *   Error messages = see under output                               *  00780000
 *                                                                   *  00790000
 *   External references =                                           *  00800000
 *      Routines/services = none                                     *  00810000
 *      Data areas        = none                                     *  00820000
 *      Control blocks    = none                                     *  00830000
 *                                                                   *  00840000
 *   Pseudocode      =                                               *  00850000
 *     DSN8ED2: Main                                                 *  00860000
 *     - get the passed DB2 command.                                 *  00870000
 *     - calculate the return area size for command requests.        *  00880000
 *     - allocate the requested return area.                         *  00890000
 *     - format the output area with the requested command.          *  00900000
 *     - issue the command request to IFI.                           *  00910000
 *     - create the temporary table to hold the result set.          *  00920000
 *       - call sql_error if an unexpected SQLCODE is encountered    *  00930000
 *     - extract the responses from the IFI return buffer and        *  00940000
 *       insert them to the result set table.                        *  00950000
 *       - call sql_error if an unexpected SQLCODE is encountered    *  00960000
 *     - open the cursor to the result set table and exit.           *  00970000
 *       - call sql_error if an unexpected SQLCODE is encountered    *  00980000
 *     End DSN8ED2                                                   *  00990000
 *                                                                   *  01000000
 *     sql_error                                                     *  01010000
 *     - invoke DSNTIAR to format the current SQL code and put the   *  01020000
 *       messages to output parameter ARGV[5].                       *  01030000
 *     - if DSNTIAR cannot detail the code, put the SQLCODE and the  *  01040000
 *       SQLERRM to output parameter ARGV[5].                        *  01050000
 *     End sql_error                                                 *  01060000
 ********************************************************************/  01070000
                                                                        01080000
                                                                        01090000
 /********************** C library definitions ***********************/ 01100000
 #pragma     runopts( plist(mvs) )                                      01110000
 #include    <stdio.h>                                                  01120000
 #include    <stdlib.h>                                                 01130000
 #include    <string.h>                                                 01140000
 #pragma     linkage( dsnwli,OS )                                       01150000
                                                                        01160000
 /**************************** Constants *****************************/ 01170000
 #define     BLANK         ' '         /* Buffer padding             */ 01180000
 #define     BUFROWLN       80         /* Length of a report line    */ 01190000
 #define     DATA_DIM       10         /* Number of message lines    */ 01200000
 #define     HYPHEN        '-'         /* Hyphen                     */ 01210000
 #define     LINEFEED     '\n'         /* Linefeed character         */ 01220000
 #define     NULLCHAR     '\0'         /* Null character             */ 01230000
 #define     RETSEV         12         /* Severe error return code   */ 01240000
 #define     RETURN_LEN   8320         /* Length of IFI return buffer*/ 01250000
                                                                        01260000
 /********************** Program Argument List ***********************/ 01270000
 struct      inp  {                    /* Arg1 (in): Command stmt    */ 01280000
   short int   incmlen;                /* - Input stmt length        */ 01290000
   char        incmtxt[4096];          /* - Input stmt text          */ 01300000
 }           inputcmd;                 /*                            */ 01310000
 struct inp  *inpptr;                  /* Pointer to input struct    */ 01320000
                                                                        01330000
 long int    ifca_ret_hex;             /* Arg2 (out): IFI return code*/ 01340000
 long int    ifca_res_hex;             /* Arg3 (out): IFI reason code*/ 01350000
                                                                        01360000
 long int    xs_bytes_hex;             /* Arg4 (out): # records lost */ 01370000
                                                                        01380000
 char        errmsg[DATA_DIM+1][BUFROWLN];                              01390000
                                       /* Arg5 (out): error messages */ 01400000
                                                                        01410000
 short int   locind[5];                /* Arg6 (out): indicator vars */ 01420000
                                                                        01430000
 /************************ Working variables *************************/ 01440000
 char        *parg1[];                 /* Pointer to argument 1      */ 01450000
 int         *parg2;                   /* Pointer to argument 2      */ 01460000
 int         *parg3;                   /* Pointer to argument 3      */ 01470000
 int         *parg4;                   /* Pointer to argument 4      */ 01480000
 char        *parg5[][BUFROWLN];       /* Pointer to argument 5      */ 01490000
 short int   *parg6;                   /* Pointer to argument 6      */ 01500000
                                                                        01510000
 long int    rc, lastrc;               /* Return codes               */ 01520000
                                                                        01530000
 /************************ DB2 Host Variables ************************/ 01540000
 EXEC SQL BEGIN DECLARE SECTION;                                        01550000
 long int    rs_sequence;              /* Result set data sequence   */ 01560000
 char        rs_data[81];              /* Result set data buffer     */ 01570000
                                       /* - length is BUFROWLN+1 for */ 01580000
                                       /*   C NUL-terminator byte)   */ 01590000
 EXEC SQL END DECLARE SECTION;                                          01600000
                                                                        01610000
 /******************** DB2 SQL Communication Area ********************/ 01620000
 EXEC SQL INCLUDE SQLCA;                                                01630000
                                                                        01640000
 /******************** DB2 SQL Cursor Declarations *******************/ 01650000
 EXEC SQL DECLARE  DSN8ED2_RS_CSR                                       01660000
           CURSOR  WITH RETURN WITH HOLD FOR                            01670000
           SELECT  RS_SEQUENCE, RS_DATA                                 01680000
             FROM  DSN8.DSN8ED2_RS_TBL /* <- Created in job DSNTEJ6T */ 01690000
         ORDER BY  RS_SEQUENCE;                                         01700000
                                                                        01710000
 /********************************************************************/ 01720000
 /*************************** main routine ***************************/ 01730000
 /********************************************************************/ 01740000
 int main( int argc, char *argv[] )    /* Argument count and list    */ 01750000
 {                                                                      01760000
   /*************************** Constants ****************************/ 01770000
                                                                        01780000
   char        eye[4]                  /* Const for IFI eye catcher  */ 01790000
               = {'I','F','C','A'};                                     01800000
   char        loc[4]                  /* Const for IFI location     */ 01810000
               = {'L','O','C','2'};                                     01820000
                                                                        01830000
   /*********************** Working variables ************************/ 01840000
                                                                        01850000
   short int   numfull;                /* No. of lines in area passed*/ 01860000
                                       /* from IFI that have BUFROWLN*/ 01870000
                                       /* or more bytes              */ 01880000
   short int   partrow;                /* No. of lines in area passed*/ 01890000
                                       /* from IFI that have less    */ 01900000
                                       /* than BUFROWLN bytes        */ 01910000
                                                                        01920000
   short int   i, j, k;                /* Loop control vars          */ 01930000
                                                                        01940000
   char        *curbyte;               /* Pointer to current byte in */ 01950000
                                       /*  return area               */ 01960000
                                                                        01970000
   short int   len_bin;                /* Length of buffer, in binary*/ 01980000
   char        lenbyt1;                /* 1st byte of length         */ 01990000
   char        lenbyt2;                /* 2nd byte of length         */ 02000000
                                                                        02010000
                                                                        02020000
   /*********************** IFI Argument List ************************/ 02030000
                                                                        02040000
   char        function[9];            /* First parm for IFI call    */ 02050000
                                                                        02060000
   /******************************************************************* 02070000
   * IFCA - (Instrumentation Facility Communication Area) contains    * 02080000
   *        information regarding the success of the call to IFI and  * 02090000
   *        provides feedback information to the application program. * 02100000
   *                                                                  * 02110000
   * WARNING: This area must be maintained to include any changes to  * 02120000
   *          the mapping macro DSNDIFCA.                             * 02130000
   *******************************************************************/ 02140000
                                                                        02150000
   typedef struct {                    /* Second parm for IFI call   */ 02160000
     short int   lngth;                /* Length of the IFCA,        */ 02170000
                                       /*  including length field    */ 02180000
     short int   unused1;              /* Reserved                   */ 02190000
     char        eye_catcher[4];       /* Valid eye catcher of IFCA  */ 02200000
                                       /*  used to verify IFCA block */ 02210000
     char        owner_id[4];          /* Used to establish ownership*/ 02220000
                                       /*  of an OPN destination     */ 02230000
     long int    ifcarc1;              /* Rtrn code for IFC API call */ 02240000
     long int    ifcarc2;              /* Reason cd for IFC API call */ 02250000
     long int    bytes_moved;          /* Bytes of recrd rtrnd by IFI*/ 02260000
     long int    excess_bytes;         /* Bytes that did not fit     */ 02270000
     long int    opn_writ_seq_num;     /* Last OPN writer sequ numbr */ 02280000
                                       /*  rtrnd for a READA function*/ 02290000
     long int    num_recds_lost;       /* Records lost indicator     */ 02300000
     char        opn_name_for_reada[4];/* OPN nm used for READA requ */ 02310000
     struct {                          /* Area with up to 8 OPN names*/ 02320000
       short int   opn_lngth;          /* Length+4 of OPN names rtrnd*/ 02330000
       short int   unused2;            /* Reserved                   */ 02340000
       char        array_opn_names[4][8];                               02350000
                                       /* Area for OPN names returned*/ 02360000
     }           opn_names_area;                                        02370000
     struct {                          /* Area with up to 8 trace nos*/ 02380000
       short int   trace_lngth;        /* Length+4 of trace nos rtrnd*/ 02390000
       short int   unused3;            /* Reserved                   */ 02400000
       char        array_trace_nos[2][8];                               02410000
                                       /* Area for trace nos returned*/ 02420000
     }           trace_nos_area;                                        02430000
     struct {                          /* Diagnosticd area           */ 02440000
       short int diagnos_lngth;        /* Diagnostics length         */ 02450000
       short int unused4;              /* Reserved                   */ 02460000
       char diagnos_data[80];          /* Diagnostics data           */ 02470000
     }           diagnos_area;                                          02480000
   }           ifca;                   /****** end IFCA typedef ******/ 02490000
                                                                        02500000
   ifca        *pi;                    /* Pointer to IFCA structure  */ 02510000
                                                                        02520000
   typedef struct {                    /* Third parm for IFI call    */ 02530000
     short int   lngth;                /* Length+4 of text or command*/ 02540000
     short int   unused;               /* Reserved                   */ 02550000
     char        text_or_command[254]; /* Actual cmd or record text  */ 02560000
     }         output_area;                                             02570000
                                                                        02580000
   output_area *po;                    /* Pointer to IFI output area */ 02590000
                                                                        02600000
   typedef struct {                    /* Fourth parm for IFI call   */ 02610000
     long int    lngth;                /* Length+4 of IFI return area*/ 02620000
     char        rtrn_buff[RETURN_LEN];/* IFI return area            */ 02630000
     }         return_area;                                             02640000
                                                                        02650000
   return_area *pr;                    /* Pointer to IFI return area */ 02660000
                                                                        02670000
   /******************************************************************* 02680000
   * initialize working variables                                     * 02690000
   *******************************************************************/ 02700000
   rc = 0;                             /* Initialize return code     */ 02710000
   lastrc = 0;                         /* Initialize return code     */ 02720000
                                                                        02730000
   for( i=0; i<DATA_DIM+1; i++ )       /* clear error message buffer */ 02740000
     for( j=0; j<BUFROWLN; j++ )                                        02750000
       errmsg[i][j] = BLANK;                                            02760000
                                                                        02770000
   /******************************************************************* 02780000
   * get input parameter (command for IFI) from caller                * 02790000
   *******************************************************************/ 02800000
   parg1[1] = argv[1];                 /* Command text from caller   */ 02810000
   curbyte = parg1[1];                 /* Get pointer to input struct*/ 02820000
                                                                        02830000
   /******************************************************************* 02840000
   * determine the length of the command text                         * 02850000
   *******************************************************************/ 02860000
   inputcmd.incmlen = 0;                                                02870000
   i = 0;                                                               02880000
   while( *(curbyte) != NULLCHAR   &&    i < 4096 )                     02890000
     {                                                                  02900000
       inputcmd.incmtxt[i] = *curbyte;                                  02910000
       i++;                                                             02920000
       curbyte++;                                                       02930000
       inputcmd.incmlen++;                                              02940000
     }                                                                  02950000
                                                                        02960000
   /******************************************************************* 02970000
   * initialize the IFI parameters                                    * 02980000
   *******************************************************************/ 02990000
   strncpy( function,"COMMAND \0",9 ); /* Set constant               */ 03000000
                                                                        03010000
   pi = malloc( sizeof(ifca) );        /* Point to IFCA structure    */ 03020000
   pi->lngth = sizeof(ifca);           /* Note length of IFCA area   */ 03030000
   for(i=0; i<4; i++ )                                                  03040000
   {                                                                    03050000
    pi->eye_catcher[i] = eye[i];       /* Initialize eye catcher     */ 03060000
    pi->owner_id[i] = loc[i];          /* DB2 Loc: 1=Local, 2=Remote */ 03070000
   }                                                                    03080000
                                                                        03090000
   pr = malloc( sizeof(return_area) ); /* Point to IFI return area   */ 03100000
   for( i=0; i<RETURN_LEN; i++ )                                        03110000
     pr->rtrn_buff[i] = BLANK;         /* Clear the return buffer    */ 03120000
   pr->lngth = RETURN_LEN;             /* Length of return buffer    */ 03130000
                                                                        03140000
   po = malloc( sizeof(output_area) ); /* Point to IFI command area  */ 03150000
   po->lngth = inputcmd.incmlen+4;     /* Note length of command text*/ 03160000
   for( i=0; i<254; i++ )              /* Copy in command            */ 03170000
     po->text_or_command[i] = inputcmd.incmtxt[i];                      03180000
                                                                        03190000
   /******************************************************************* 03200000
   * make the IFI call via the DSNWLI macro                           * 03210000
   *******************************************************************/ 03220000
   dsnwli( function,pi,pr,po );                                         03230000
                                                                        03240000
   /******************************************************************* 03250000
   * copy IFI command status codes to output parms                    * 03260000
   *******************************************************************/ 03270000
   ifca_ret_hex = pi->ifcarc1;         /* IFI Return code in binary  */ 03280000
   ifca_res_hex = pi->ifcarc2;         /* IFI Reason code in binary  */ 03290000
   xs_bytes_hex = pi->excess_bytes;    /* Bytes that did not fit     */ 03300000
                                                                        03310000
   /******************************************************************* 03320000
   * Extract records from the IFI return area and place them in a     * 03330000
   * table for transmission to the caller via a result set            * 03340000
   *******************************************************************/ 03350000
   if( pi->bytes_moved != 0 )          /* If data was returned by IFI*/ 03360000
   {                                                                    03370000
     /***************************************************************** 03380000
     * First, clear any residue from the result set table             * 03390000
     *****************************************************************/ 03400000
     EXEC SQL DELETE                                                    03439990
                FROM  DSN8.DSN8ED2_RS_TBL;                              03469980
     if( SQLCODE != 0                  /* 0 because everything is ok */ 03499970
       & SQLCODE != +88 )              /* +88 because all rows del'd */ 03529960
       sql_error( "*** SQL error when clearing temp table ..." );       03559950
                                                                        03620000
     rs_sequence = 0;                  /* Init result set sequence no*/ 03630000
     for( k=0; k<BUFROWLN; k++ )       /* Clear result set data var  */ 03640000
       rs_data[k] = BLANK;                                              03650000
                                                                        03660000
     /***************************************************************** 03670000
     * The IFI return buffer contains one or more variable length     * 03680000
     * records.  Each record consists of a 4-byte length component    * 03690000
     * followed by a text component.  The length component contains   * 03700000
     * the length of the text component plus 4 to account for its     * 03710000
     * own length.                                                    * 03720000
     ****************************************************************** 03730000
     * Extract the length of the 1st record in the buffer and sub-    * 03740000
     * tract 4 bytes to obtain the length of just the text portion.   * 03750000
     *****************************************************************/ 03760000
     curbyte = &( pr->rtrn_buff[0] );  /* Point to 1st byte in buffer*/ 03770000
     lenbyt1 = *(curbyte);             /* Set 1st byte of length     */ 03780000
     lenbyt2 = *(curbyte+1);           /* Set 2nd byte of length     */ 03790000
                                                                        03800000
     len_bin  = ( (short int)lenbyt1 ) * 10 + ( (short int)lenbyt2 );   03810000
     len_bin = len_bin - 4;            /* Discount size of length fld*/ 03820000
                                                                        03830000
     /***************************************************************** 03840000
     * For each IFI record returned, create one or more records of    * 03850000
     * length BUFROWLN and insert them to the result set table        * 03860000
     *****************************************************************/ 03870000
     while( ( rc < RETSEV ) && (pi->bytes_moved - len_bin) > 2 )        03880000
     {                                                                  03890000
       curbyte = curbyte + 4;          /* Update position in buffer  */ 03900000
                                                                        03910000
       if( ((short int)( curbyte - &(pr->rtrn_buff[0]) ) + len_bin - 1) 03920000
         > pi->bytes_moved )                                            03930000
         break;                        /* At end of buffer           */ 03940000
                                                                        03950000
       numfull = len_bin / BUFROWLN;   /* No. rows of BUFROWLN bytes */ 03960000
       partrow = len_bin % BUFROWLN;   /* No. of bytes leftover      */ 03970000
                                                                        03980000
       /*************************************************************** 03990000
       * Move all complete lines                                      * 04000000
       ***************************************************************/ 04010000
       if( numfull > 0 )                                                04020000
         for( j=0; j<numfull; j++ )                                     04030000
         {                                                              04040000
           for( i=0; i<BUFROWLN; i++ ) /* Clear result set tbl buffer*/ 04050000
             rs_data[i] = BLANK;                                        04060000
           for( i=0; i<BUFROWLN; i++ )                                  04070000
           {                                                            04080000
             rs_data[i] = *curbyte;    /* Build result set table rec */ 04090000
             curbyte++;                /* Bump ptr into IFI rtrn buff*/ 04100000
           }                                                            04110000
                                                                        04120000
           rs_sequence++;              /* Bump result set tbl sequ no*/ 04130000
           EXEC SQL INSERT             /* Insert to the table        */ 04140000
                      INTO  DSN8.DSN8ED2_RS_TBL                         04150000
                          ( RS_SEQUENCE,RS_DATA )                       04160000
                    VALUES(:rs_sequence,:rs_data );                     04170000
           if( SQLCODE != 0 )                                           04180000
             sql_error( "*** SQL error when inserting full line ..." ); 04190000
         }                                                              04200000
                                                                        04210000
       /*************************************************************** 04220000
       * Move leftover bytes to one last result set table record      * 04230000
       ***************************************************************/ 04240000
       if( rc < RETSEV && partrow > 0 )                                 04250000
       {                                                                04260000
         for( i=0; i<BUFROWLN; i++ )  /* Clear result set tbl buffer*/  04270000
           rs_data[i] = BLANK;                                          04280000
         for( i=0; i<partrow; i++ )                                     04290000
         {                                                              04300000
           rs_data[i] = *curbyte;      /* Build result set table rec */ 04310000
           curbyte++;                  /* Bump ptr into IFI rtrn buff*/ 04320000
         }                                                              04330000
         rs_data[i-1] = BLANK;         /* Discard linefeed char      */ 04340000
                                                                        04350000
         rs_sequence++;                /* Bump result set tbl sequ no*/ 04360000
                                                                        04370000
         EXEC SQL INSERT               /* Insert to the table        */ 04380000
                    INTO  DSN8.DSN8ED2_RS_TBL                           04390000
                        ( RS_SEQUENCE,RS_DATA )                         04400000
                  VALUES(:rs_sequence,:rs_data );                       04410000
         if( SQLCODE != 0 )                                             04420000
           sql_error( "*** SQL error when inserting partial line ..." );04430000
       }                               /* End-move partial line      */ 04440000
                                                                        04450000
       /*************************************************************** 04460000
       * Advance to next record in the IFI buffer, extract its length,* 04470000
       * and subtract 4 bytes to get length of text portion           * 04480000
       ***************************************************************/ 04490000
       lenbyt1 = *(curbyte);            /* Set 1st byte of length    */ 04500000
       lenbyt2 = *(curbyte+1);          /* Set 2nd byte of length    */ 04510000
                                                                        04520000
       len_bin  = ( (short int)lenbyt1) * 10 + ((short int)lenbyt2 );   04530000
       len_bin = len_bin - 4;           /* Discount for length field */ 04540000
                                                                        04550000
     } /* End of copying IFI return text to result set table */         04560000
                                                                        04570000
     /***************************************************************** 04580000
     * Open the cursor to the result set table on the way out         * 04590000
     *****************************************************************/ 04600000
     if( rc < RETSEV )                                                  04610000
     {                                                                  04620000
       EXEC SQL OPEN  DSN8ED2_RS_CSR;                                   04630000
       if( SQLCODE != 0 )                                               04640000
         sql_error( "*** SQL error when opening result set cursor ...");04650000
     }                                                                  04660000
                                                                        04670000
   } /* End of if data was returned by IFI */                           04680000
                                                                        04690000
   /******************************************************************* 04700000
   * Set output arguments and DB2 locator variables                   * 04710000
   *******************************************************************/ 04720000
   parg2 = (int *)argv[2];              /* locate and recast 2nd arg */ 04730000
   *parg2 = ifca_ret_hex;               /*  assign it ifca return cd */ 04740000
   locind[1] = 0;                       /* tell DB2 to transmit it   */ 04750000
                                                                        04760000
   parg3 = (int *)argv[3];              /* locate and recast 3rd arg */ 04770000
   *parg3 = ifca_res_hex;               /*  assign it ifca reason cd */ 04780000
   locind[2] = 0;                       /* tell DB2 to transmit it   */ 04790000
                                                                        04800000
   parg4 = (int *)argv[4];              /* locate and recast 4th arg */ 04810000
   *parg4 = xs_bytes_hex;               /*  and assign it bytes lost */ 04820000
   locind[3] = 0;                       /* tell DB2 to transmit it   */ 04830000
                                                                        04840000
   if( errmsg[0][0] == BLANK )          /* if no error message exists*/ 04850000
     locind[4] = -1;                    /* -tell DB2 not to send one */ 04860000
   else                                 /* otherwise copy it over and*/ 04870000
   {                                    /* tell DB2 to transmit it   */ 04880000
     parg5[0][0] = argv[5];             /* -locate the 5th func arg  */ 04890000
     curbyte = parg5[0][0];             /* -set helper pointer       */ 04900000
     for( i=0; i<DATA_DIM+1; i++ )      /* -parse a row, looking for */ 04910000
     {                                  /*  the end of its msg text  */ 04920000
       j = 0;                                                           04930000
       while( errmsg[i][j] != NULLCHAR  &&  j < BUFROWLN )              04940000
       {                                                                04950000
         *curbyte = errmsg[i][j++];     /* -copy nonnull bytes       */ 04960000
         curbyte++;                                                     04970000
       }                                                                04980000
       errmsg[i][j] = LINEFEED;         /* -add linefd to end of row */ 04990000
     } /* End of for( i=0; i<DATA_DIM+1; i++ ) */                       05000000
                                                                        05010000
     *curbyte = NULLCHAR;               /* -null-terminate the buffer*/ 05020000
     locind[4] = 0;                     /* -tell DB2 to transmit it  */ 05030000
   } /* End of if( errmsg[0][0] != BLANK ) */                           05040000
                                                                        05050000
   parg6 = (short int *)argv[6];        /* locate and recast 6th arg */ 05060000
   for( j=0; j<5; j++ )                 /* copy over null-ind array  */ 05070000
   {                                                                    05080000
     *parg6 = locind[j];                                                05090000
     parg6++;                                                           05100000
   }                                    /* return control to caller  */ 05110000
                                                                        05120000
 } /* end of main */                                                    05130000
                                                                        05140000
 /********************************************************************* 05150000
 * SQL error handler                                                  * 05160000
 *********************************************************************/ 05170000
 #pragma linkage(dsntiar, OS)                                           05180000
                                                                        05190000
 sql_error( char locmsg[] )                                             05200000
 {                                                                      05210000
                                                                        05220000
                                       /* DSNTIAR message structure  */ 05230000
   struct      error_struct {                                           05240000
     short int   error_len;                                             05250000
     char        error_text[DATA_DIM][BUFROWLN];                        05260000
     }         error_message = {DATA_DIM * BUFROWLN};                   05270000
                                                                        05280000
   extern short int dsntiar( struct      sqlca         *sqlca,          05290000
                             struct      error_struct  *msg,            05300000
                             int                       *len );          05310000
                                                                        05320000
   char        *curbyte;               /* Pointer to current byte in */ 05330000
                                       /*  error_message             */ 05340000
                                                                        05350000
   short int   tiar_rc;                /* DSNTIAR Return code        */ 05360000
   int         i;                      /* Loop control               */ 05370000
   static int  lrecl = BUFROWLN;       /* Width of message lines     */ 05380000
                                                                        05390000
   /******************************************************************* 05400000
   * indicate that a fatal error has occurred                         * 05410000
   *******************************************************************/ 05420000
   rc = RETSEV;                                                         05430000
                                                                        05440000
   /******************************************************************* 05450000
   * copy locator message to the error message return buffer          * 05460000
   *******************************************************************/ 05470000
   strcpy( errmsg[0],locmsg );                                          05480000
                                                                        05490000
   /******************************************************************* 05500000
   * format the SQL message and move it to the err msg rtn buffer     * 05510000
   *******************************************************************/ 05520000
   tiar_rc = dsntiar( &sqlca, &error_message, &lrecl );                 05530000
                                                                        05540000
   if( tiar_rc == 0 )                                                   05550000
     for( i=0; i<DATA_DIM; i++ )                                        05560000
     {                                                                  05570000
       strncpy( errmsg[i+1],error_message.error_text[i],BUFROWLN );     05580000
     }                                                                  05590000
   else                                                                 05600000
     {                                                                  05610000
       strcpy( errmsg[1],"DSNTIAR could not detail the SQL error" );    05620000
       strcpy( errmsg[2],"*** SQLCODE is " );                           05630000
       strcat( errmsg[3],(char *)SQLCODE );                             05640000
       strcpy( errmsg[4],"*** SQLERRM is " );                           05650000
       for( i=0; i<sqlca.sqlerrml; i++ )                                05660000
         errmsg[5][i],sqlca.sqlerrmc[i];                                05670000
     }                                                                  05680000
                                                                        05690000
} /* end of sql_error */                                                05700000