DSN8ED8
Demonstrates how to use an application program to call DSNUTILU, the Db2 Utilities Unicode parser.
/*********************************************************************
* Module name = DSN8ED8 (sample program) *
* *
* DESCRIPTIVE NAME: Sample client for: *
* DSNTUTILU (DB2 Utilities Unicode Parser) *
* *
* LICENSED MATERIALS - PROPERTY OF IBM *
* 5650-DB2 *
* (C) COPYRIGHT 1982, 2016 IBM CORP. ALL RIGHTS RESERVED. *
* *
* STATUS = VERSION 12 *
* *
* Function: Demonstrates how to use an application program to call *
* DSNUTILU, the DB2 Utilities Unicode parser. DSN8ED8 *
* performs the following tasks: *
* - Collects the user-provided utility id, restart option, *
* and utility statement in EBCDIC format (CCSID 37) *
* * A utility statement of up to 32K can be passed via *
* the UTILSTMT DD. Input records must be RECFM=FB, *
* LRECL=80. Columns 73 - 80 of each record are *
* ignored. *
* - Calls z/OS UNICODE Services to convert these values to *
* UNICODE (CCSID 1208) *
* - Calls DSNUTILU, passing the converted values as parms *
* - Receives and processes the result set from DSNUTILU, *
* converting the data from UNICODE to EBCDIC and *
* printing the results. *
* *
* Notes: *
* Dependencies: z/OS Unicode Conversion Services *
* - Note: conversion for 37->1208 and 1208-> 37 must *
* be available. *
* SYSPROC.DSNUTILU *
* *
* Restrictions: *
* *
* Module type: C program *
* Processor: DB2 Precompiler *
* IBM C/C++ for z/OS V1R3 or higher *
* Module size: See linkedit output *
* Attributes: Reentrant and reusable *
* *
* Entry point: DSN8ED8 *
* Purpose: See Function *
* Linkage: Standard MVS program invocation, no parameters. *
* *
* Parameters: None *
* *
* Inputs: DSN8ED8 allocates these input DDs: *
* - UTILID : Specify utility ID *
* - RESTART : Specify utility RESTART option *
* - UTILSTMT: Specify utility statement *
* *
* Outputs: DSN8ED8 allocates these output DD *
* - REPORT : Results from running utility *
* - SYSPRINT: Call summary *
* *
* Normal Exit: Return Code: 0000 *
* - Message: DSNUTILU has completed with return code 0 *
* *
* Normal with Warnings Exit: Return Code: 0004 +@04*
* - Message: DSNUTILU has completed with return code 4 *
* *
* Error Exit: Return Code: 0012 *
* - Message: DSNUTILU has completed with return code <n>*
* - Message: The length of the argument specified for *
* the <parameter-name> does not fall within *
* the required bounds of <minimum-length> *
* and <maximum-length> *
* - Message: Unable to open <DD-name> *
* - Message: Unable to close <DD-name> *
* - Message: Unable to read <DD-name> *
* - Message: Unable to convert the string x<string> *
* from CCSID <sourceCCSID> *
* to CCSID <targetCCSID> *
* Conversion returned code = <code>, *
* reason = <reason> *
* - Message: <formatted SQL text from DSNTIAR> *
* *
* External References: *
* - Routines/Services: DSNTIAR: DB2 msg text formatter *
* - Data areas : None *
* - Control blocks : None *
* *
* *
* Pseudocode: *
* DSN8ED8: *
* - writeReportHeader *
* - readDSNUTILUparms *
* - readUtilityId *
* - convertEncodingScheme *
* - readRestartOption *
* - convertEncodingScheme *
* - readUtilityStatement *
* - convertEncodingScheme *
* - callDSNUTILU *
* - processDSNUTILUresultSet *
* - associateResultSetLocator *
* - allocateResultSetCursor *
* - writeDSNUTILUreport *
* - openReportDataSet *
* - while unprocessed result set records *
* - fetchFromResultSetCursor *
* - convertEncodingScheme *
* - write report line *
* - closeReportDataSet *
* - if return code from DSNUTILU was 0 or 4 *
* - processSqlCommit *
* - else *
* - processSqlRollback *
* End DSN8ED8 *
* *
* *
* Change activity = *
* 07/26/2014 Add UTILFILE DD for passing the s20128_inst1 s20128 *
* name of a data set having the *
* utility control statement. *
* 06/22/2015 Remove UTILFILE DD s25173_inst1 s25173 *
* *
*********************************************************************/
#pragma runopts(POSIX(ON),TRAP(OFF))
#define _XOPEN_SOURCE_EXTENDED 1
/********************** C library definitions ***********************/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cunhc.h> /* UNICODE services */
/**************************** Constants *****************************/
#define NULLCHAR '\0' /* Null character */
#define RETNRM 0 /* Normal return code */
#define RETWRN 4 /* Warning return code */
#define RETERR 8 /* Error return code */
#define RETSEV 12 /* Severe error return code */
#define UNIBLANK '\x20' /* UNICODE Blank character */
enum flag {No, Yes}; /* Settings for flags */
/**************** Output: DSNUTILU result set report ****************/
FILE *reportDD; /* Pointer to report DD */
char reportDDName[12]; /* For report DD name */
unsigned short reportLRECL; /* length req'd for output rec*/
/************************ Working variables *************************/
unsigned short resultSetReturned = 0;/* DSNUTILU result set status */
long int DSNUTILU_rc = -1; /* DSNUTILU return code */
long int rc = 0; /* program return code */
char utilityId[17]; /* */
char restartOption[9]; /* */
char utilityStmt[32705]; /* */
/******************** DB2 SQL Communication Area ********************/
EXEC SQL INCLUDE SQLCA;
/************************ DB2 Host Variables ************************/
EXEC SQL BEGIN DECLARE SECTION;
struct /* DSNUTILU utility ID */
{ short int length; /* length */
char data[17]; /* value */
} UTILITY_ID;
struct /* DSNUTILU restart point */
{ short int length; /* length */
char data[9]; /* value */
} RESTART;
struct /* DSNUTILU utility statement */
{ short int length; /* length */
char data[32705]; /* value */
} UTSTMT;
long int RETCODE; /* DSNUTILU return code */
struct /* DSNUTILU result set */
{ short int length; /* length */
char data[254]; /* value */
} TEXT;
long int SEQNO; /* Result set row sequence no.*/
EXEC SQL END DECLARE SECTION;
/*************** DB2 Result Set Locator Host Variables **************/
EXEC SQL BEGIN DECLARE SECTION;
static volatile SQL TYPE IS RESULT_SET_LOCATOR *DSNUTILU_rs_loc1;
EXEC SQL END DECLARE SECTION;
/********************** DSN8ED8 Function Models *********************/
int main /* DSN8ED8 driver */
( int argc, /* - Input argument count */
char *argv[] /* - Input argument vector */
);
void writeReportHeader( void ); /* Write the report header */
void readDSNUTILUparms( void ); /* Get data for DSNUTILU call */
void readUtilityId /* Read Utility ID */
( char *utilityId /* -out: utility ID */
);
void readRestartOption /* Read restart point */
( char *restartOption /* -out: restart point */
);
void readUtilityStatement /* Read utility statement */
( char *utilityStmt /* -out: utility statement */
);
void callDSNUTILU( void ); /* Run DSNUTILU */
void processDSNUTILUresultSet( void );/* Process DSNUTILU rslt set */
void associateResultSetLocator(void); /* Assoc DSNUTILU RS locator */
void allocateResultSetCursor( void ); /* Alloc DSNUTILU RS cursor */
void writeDSNUTILUreport( void ); /* Output a DSNUTILU report */
void fetchFromResultSetCursor( void );/* Read DSNTSPMP RS cursor */
void openReportDataSet( void ); /* Alloc DD for report */
void closeReportDataSet( void ); /* Dealloc DD for report */
char * trimTrailingBlanks /* Strip off trailing blanks */
( char *string /* - in: string to be trimmed */
);
void processSqlCommit( void ); /* Commit SQL changes @04*/
void processSqlRollback( void ); /* Rollback SQL changes @04*/
void issueDataSetClosingError /* Handler for ds close error */
( char *DDname, /* - in: name of errant DD */
int LEerrno /* - in: LE diagnostic errno */
);
void issueDataSetOpeningError /* Handler for ds open error */
( char *DDname, /* - in: name of errant DD */
int LEerrno /* - in: LE diagnostic errno */
);
void issueDataSetReadingError /* Handler for ds read error */
( char *DDname, /* - in: name of errant DD */
int LEerrno /* - in: LE diagnostic errno */
);
void issueInvalidParmLengthError /* Handler for parm len error */
( char *parmName, /* - in: identify of parm */
int minLength, /* - in: min valid length */
int maxLength /* - in: max valid length */
);
void issueSqlError /* Handler for SQL error */
( char *locMsg /* - in: Call location */
);
void convertEncodingScheme
( char *string, /* - in/out: string to convert*/
short int stringLength, /* - in: length of string */
unsigned long sourceCCSID, /* - in: CCSID to convert from*/
unsigned long targetCCSID /* - in: CCSID to convert to */
);
int main /* DSN8ED8 driver */
( int argc, /* - Input argument count */
char *argv[] /* - Input argument vector */
)
/*******************************************************************
* Main Driver: *
* - Reads data to be passed to DSNUTILU *
* - Calls DSNUTILU *
* - Processes the result set returned from DSNUTILU *
* *
*******************************************************************/
{ /*****************************************************************
* Write the report header *
*****************************************************************/
writeReportHeader();
/*****************************************************************
* Read data for DSNUTILU parm arguments *
*****************************************************************/
readDSNUTILUparms();
/*****************************************************************
* Call DSNUTILU *
*****************************************************************/
if( rc < RETSEV )
callDSNUTILU();
/*****************************************************************
* Process the result set, if any, from DSNUTILU *
*****************************************************************/
if( resultSetReturned )
processDSNUTILUresultSet();
/*****************************************************************
* If DSNUTILU returns either 0 (normal) or 4 (warnings), perform *
* a COMMIT; Otherwise, perform a ROLLBACK *
*****************************************************************/
if( DSNUTILU_rc == RETNRM || DSNUTILU_rc == RETWRN )
{ processSqlCommit();
if( rc < DSNUTILU_rc )
rc = DSNUTILU_rc;
}
else
{ processSqlRollback();
if( rc < RETSEV )
rc = RETSEV;
}
/*****************************************************************
* Return highest completion code *
*****************************************************************/
return( rc );
} /* end of main */
void writeReportHeader( void ) /* Write the report header */
/*******************************************************************
* Writes the report header *
*******************************************************************/
{
printf( "****************************************"
"****************************************\n" );
printf( "* DSN8ED8 is now invoking the DB2 Utilities UNICODE "
"Parser (SYSPROC.DSNUTILU)\n" );
printf( "*\n" );
} /* end of writeReportHeader */
void readDSNUTILUparms( void ) /* Get DSNUTILU parms */
/*******************************************************************
* Collects the arguments for parms to be passed to DSNUTILU *
*******************************************************************/
{
UTILITY_ID.length = 0;
memset( UTILITY_ID.data, NULLCHAR, 17 );
RESTART.length = 0;
memset( RESTART.data, NULLCHAR, 9 );
UTSTMT.length = 0;
memset( UTSTMT.data, NULLCHAR, 32704 );
readUtilityId( utilityId );
if( rc < RETSEV )
{ strcpy( UTILITY_ID.data, utilityId );
UTILITY_ID.length = strlen(utilityId);
}
if( rc < RETSEV )
{ readRestartOption( restartOption );
}
if( rc < RETSEV )
{ strcpy( RESTART.data, restartOption );
RESTART.length = strlen(restartOption);
}
if( rc < RETSEV )
{ readUtilityStatement( utilityStmt );
}
if( rc < RETSEV )
{ strcpy( UTSTMT.data, utilityStmt );
UTSTMT.length = strlen(utilityStmt);
}
} /* end of readDSNUTILUparms */
void readUtilityId /* Read Utility ID */
( char *utilityId /* -out: utility ID */
)
/*******************************************************************
* Reads a utility ID value of 1-16 bytes from the UTILID DD *
*******************************************************************/
{ FILE *utilIdFile; /* Ptr to UTILID DD */
char utilIdDD[12]; /* DD handle */
char utilIdRec[80]; /* UTILID file input record */
short int recordLength = 0; /* Length of record */
unsigned short moreRecords = Yes; /* EOF indicator */
strcpy( utilIdDD,"DD:UTILID " );
errno = 0; /* clear LE errno */
utilIdFile = fopen( utilIdDD,
"rb,lrecl=80,type=record" );
if( utilIdFile == NULL )
issueDataSetOpeningError( utilIdDD,errno );
while( moreRecords == Yes && rc < RETSEV )
{ recordLength
= fread( utilIdRec, /* Read into UTILID rec area */
1, /* ..1 record */
80, /* ..of 80 bytes */
utilIdFile ); /* ..from UTILID file */
/* Discard bytes 73-80 */
memset(&utilIdRec[72], NULLCHAR, 8);
if( ferror(utilIdFile) ) /* Handle IO errors */
issueDataSetReadingError( utilIdDD,errno );
else if( feof(utilIdFile) ) /* Handle EOF */
moreRecords = No;
/* Don't overfill return area */
else if( rc < RETSEV &&
(strlen(utilityId) +
strlen(trimTrailingBlanks( utilIdRec ))) > 16 )
issueInvalidParmLengthError( "UTILID",1,16 );
else /* Strip off trailing blanks */
strcat( utilityId, trimTrailingBlanks( utilIdRec ) );
}
if( rc < RETSEV )
if( fclose( utilIdFile ) != 0 )
issueDataSetClosingError( utilIdDD,errno );
if( rc < RETSEV )
{ printf( "* Utility ID: %s\n", utilityId );
printf( "*\n" );
convertEncodingScheme( utilityId, strlen(utilityId),
37,1208 );
}
} /* end of readUtilityId */
void readRestartOption /* Read restart point */
( char *restartOption /* -out: restart point */
)
/*******************************************************************
* Reads a restart point value of 0-8 bytes from the RESTART DD *
*******************************************************************/
{ FILE *restartOptFile; /* Ptr to RESTART DD */
char restartOptDD[12]; /* DD handle */
char restartOptRec[80]; /* RESTART file input record */
short int recordLength = 0; /* Length of record */
unsigned short moreRecords = Yes; /* EOF indicator */
strcpy( restartOptDD,"DD:RESTART " );
errno = 0; /* clear LE errno */
restartOptFile = fopen( restartOptDD,
"rb,lrecl=80,type=record" );
if( restartOptFile == NULL )
issueDataSetOpeningError( restartOptDD,errno );
while( moreRecords == Yes && rc < RETSEV )
{ recordLength
= fread( restartOptRec, /* Read into RESTART rec area */
1, /* ..1 record */
80, /* ..of 80 bytes */
restartOptFile ); /* ..from RESTART file */
/* Discard bytes 73-80 */
memset(&restartOptRec[72], NULLCHAR, 8);
if( ferror(restartOptFile) ) /* Handle IO errors */
issueDataSetReadingError( restartOptDD,errno );
else if(feof(restartOptFile)) /* Handle EOF */
moreRecords = No;
/* Don't overfill return area */
else if( rc < RETSEV &&
(strlen(restartOption) +
strlen(trimTrailingBlanks( restartOptRec ))) > 8 )
issueInvalidParmLengthError( "RESTART",0,8 );
else /* Strip off trailing blanks */
strcat( restartOption,
trimTrailingBlanks( restartOptRec ) );
}
if( rc < RETSEV )
if( fclose( restartOptFile ) != 0 )
issueDataSetClosingError( restartOptDD,errno );
if( rc < RETSEV )
{ printf( "* Restart point: %s\n", restartOption );
printf( "*\n" );
convertEncodingScheme( restartOption, strlen(restartOption),
37,1208 );
}
} /* end of readRestartOption */
void readUtilityStatement /* Read utility statement */
( char *utilityStmt /* -out: utility statement */
)
/*******************************************************************
* Reads a utility statement of 0-32704 bytes from the UTILSTMT DD *
*******************************************************************/
{ FILE *utilStmtFile; /* Ptr to UTILSTMT DD */
char utilStmtDD[12]; /* DD handle */
char utilStmtRec[80]; /* UTILSTMT file input record */
short int recordLength = 0; /* Length of record */
unsigned short moreRecords = Yes; /* EOF indicator */
memset( utilityStmt, NULLCHAR, 32705 );
strcpy( utilStmtDD,"DD:UTILSTMT" );
errno = 0; /* clear LE errno */
utilStmtFile = fopen( utilStmtDD,
"rb,lrecl=80,type=record" );
if( utilStmtFile == NULL )
issueDataSetOpeningError( utilStmtDD,errno );
while( moreRecords == Yes && rc < RETSEV )
{ recordLength
= fread( utilStmtRec, /* Read into UTILSTMT rec area*/
1, /* ..1 record */
80, /* ..of 80 bytes */
utilStmtFile ); /* ..from UTILSTMT file */
/* Discard bytes 73-80 */
memset(&utilStmtRec[72], NULLCHAR, 8);
if( ferror(utilStmtFile) ) /* Handle IO errors */
issueDataSetReadingError( utilStmtDD,errno );
else if(feof(utilStmtFile)) /* Handle EOF */
moreRecords = No;
/* Don't overfill return area */
else if( rc < RETSEV &&
(strlen(utilityStmt) +
strlen(utilStmtRec)) > 32704 )
issueInvalidParmLengthError( "UTILSTMT",1,32704 );
else
strcat( utilityStmt,utilStmtRec );
}
if( rc < RETSEV )
if( fclose( utilStmtFile ) != 0 )
issueDataSetClosingError( utilStmtDD,errno );
if( rc < RETSEV )
{ printf( "* Utility statement: %s\n", utilityStmt );
printf( "*\n" );
convertEncodingScheme( utilityStmt, strlen(utilityStmt),
37,1208 );
}
} /* end of readUtilityStatement */
void callDSNUTILU( void ) /* Run DSNUTILU */
/*******************************************************************
* Calls DSNUTILU *
*******************************************************************/
{ EXEC SQL
CALL SYSPROC.DSNUTILU( :UTILITY_ID
,:RESTART
,:UTSTMT
,:RETCODE );
/*****************************************************************
* Analyze status codes from DSNUTILU *
*****************************************************************/
printf( "* DSNUTILU has completed with return code %i\n",
RETCODE );
if( SQLCODE != 0 && SQLCODE != 466 )
{ issueSqlError( "Call to DSNUTILU failed" );
}
else
{ DSNUTILU_rc = RETCODE;
if( SQLCODE == 466 )
{ printf( "* A result set was returned\n" );
resultSetReturned = Yes;
}
else /* SQLCODE == 0 */
{ printf( "* No result sets were returned\n" );
resultSetReturned = No;
}
}
} /* end of callDSNUTILU */
void processDSNUTILUresultSet( void ) /* Handle DSNUTILU result set */
/*******************************************************************
* Outputs data from the result set returned by DSNUTILU *
*******************************************************************/
{
/*****************************************************************
* Associate a locator with the result set from DSNUTILU *
*****************************************************************/
associateResultSetLocator();
/*****************************************************************
* Allocate a cursor for the result set *
*****************************************************************/
if( rc < RETSEV )
allocateResultSetCursor();
/*****************************************************************
* Output reports returned in the result set *
*****************************************************************/
if( rc < RETSEV )
writeDSNUTILUreport();
} /* end of processDSNUTILUresultSet */
void associateResultSetLocator(void) /* Assoc DSNUTILU RS locator */
/*******************************************************************
* Associates the result set from DSNUTILU with a result set locator*
*******************************************************************/
{ EXEC SQL
ASSOCIATE
LOCATORS( :DSNUTILU_rs_loc1 )
WITH PROCEDURE SYSPROC.DSNUTILU;
if( SQLCODE != 0 )
{ issueSqlError( "Associate locator call failed" );
}
} /* end of associateResultSetLocator */
void allocateResultSetCursor( void ) /* Alloc DSNUTILU RS cursor */
/*******************************************************************
* Allocates a cursor to the locator for the DSNUTILU result set *
*******************************************************************/
{ EXEC SQL
ALLOCATE DSNUTILU_RS_CSR1
CURSOR FOR RESULT SET :DSNUTILU_rs_loc1;
if( SQLCODE != 0 )
{ issueSqlError( "Allocate result set cursor "
"call failed" );
}
} /* end of allocateResultSetCursor */
void writeDSNUTILUreport( void ) /* Print DSNUTILU report */
/*******************************************************************
* Outputs the contents of the result set from DSNUTILU *
*******************************************************************/
{ short int recordLength = 0; /* Length of record */
char recordText[256]; /* Text of record */
/*****************************************************************
* Get the first entry in the result set *
*****************************************************************/
fetchFromResultSetCursor();
/*****************************************************************
* Allocate an outout DD for the report *
*****************************************************************/
if( rc < RETSEV )
openReportDataSet();
/*****************************************************************
* Process all rows in the result set *
*****************************************************************/
while( SQLCODE == 0 && rc < RETSEV )
{ /*************************************************************
* Convert the current report line from UNICODE to EBCDIC *
*************************************************************/
convertEncodingScheme( TEXT.data, TEXT.length,
1208, 37 );
/*************************************************************
* Write the current report line *
*************************************************************/
memset( recordText,' ',256 );
memcpy( recordText,TEXT.data,TEXT.length );
if( rc < RETSEV )
{ recordLength
= fwrite( recordText, /* write from TEXT.data */
1, /* ..a record */
sizeof( recordText ),
reportDD ); /* ..into the report data set */
}
if( rc < RETSEV )
{ fetchFromResultSetCursor();
}
}
if( rc < RETSEV )
{ closeReportDataSet();
}
} /* end of writeDSNUTILUreport */
void fetchFromResultSetCursor( void ) /* Read DSNUTILU RS cursor */
/*******************************************************************
* Reads the cursor for the DSNUTILU result set *
*******************************************************************/
{ memset( TEXT.data,NULLCHAR,254 );
EXEC SQL
FETCH DSNUTILU_RS_CSR1
INTO :SEQNO,
:TEXT;
if( SQLCODE != 0 && SQLCODE != 100 && rc < RETSEV )
{ issueSqlError( "*** Fetch from "
"result set cursor failed" );
}
} /* end of fetchFromResultSetCursor */
void openReportDataSet( void ) /* Alloc DD for report */
/*******************************************************************
* Opens the DD REPORT and associates it with the file handler *
* reportDD. *
*******************************************************************/
{ char reportDDdcb[36]; /* for generated DCB */
sprintf( reportDDName, /* Generate DD name REPORT */
"DD:REPORT" );
if( TEXT.data[0] == '1' ) /* Does this look like FBA? */
sprintf( reportDDdcb, /* Yes: Specify */
"wb,recfm=FBA," /* ..record output, recfm=fba */
"lrecl=256" ); /* ..and lrecl 255 */
else
sprintf( reportDDdcb, /* No: Specify */
"wb,recfm=FB," /* ..record output, recfm=fb */
"lrecl=256" ); /* ..and lrecl 255 */
errno = 0; /* clear LE errno */
reportDD = fopen( reportDDName,reportDDdcb );
if( reportDD == NULL ) /* If unable to open data set */
issueDataSetOpeningError( reportDDName,errno );
} /* end of openReportDataSet */
void closeReportDataSet( void ) /* Dealloc DD for report */
/*******************************************************************
* Closes the DD associated with the file handler reportDD. *
*******************************************************************/
{ if( fclose(reportDD) != 0 )
issueDataSetClosingError( reportDDName,errno );
} /* end of closeReportDataSet */
char * trimTrailingBlanks /* Strip off trailing blanks */
( char *string /* - in: string to be trimmed */
)
/*******************************************************************
* Strips trailing blanks from a string *
*******************************************************************/
{ int i;
for( i = strlen(string) - 1; string[i] == ' '; i-- );
string[++i] = '\0';
return string;
} /* end of trimTrailingBlanks */
void processSqlCommit( void ) /* Commit SQL changes */
/*******************************************************************
* Commits the current unit of SQL work *
*******************************************************************/
{ EXEC SQL
COMMIT;
if( SQLCODE != 0 )
{ issueSqlError( "*** Commit failed " );
}
} /* end of processSqlCommit */
void processSqlRollback( void ) /* Rollback SQL changes */
/*******************************************************************
* Rolls back the current unit of SQL work *
*******************************************************************/
{ EXEC SQL
ROLLBACK;
if( SQLCODE != 0 )
{ issueSqlError( "*** Rollback failed " );
}
} /* end of processSqlRollback */
void issueDataSetClosingError /* Handler for ds close error */
( char *DDname, /* - in: name of errant DD */
int LEerrno /* - in: LE diagnostic errno */
)
/*******************************************************************
* Called when a TSO data set cannot be closed *
*******************************************************************/
{ printf( "ERROR: Unable to close %s\n", DDname );
printf( "%s \n",strerror(LEerrno) );
printf( "-----> Processing halted\n" );
rc = RETSEV;
} /* end of issueDataSetClosingError */
void issueDataSetOpeningError /* Handler for ds open error */
( char *DDname, /* - in: name of errant DD */
int LEerrno /* - in: LE diagnostic errno */
)
/*******************************************************************
* Called when a TSO data set cannot be opened *
*******************************************************************/
{ printf( "ERROR: Unable to open %s\n", DDname );
printf( "%s \n",strerror(LEerrno) );
printf( "-----> Processing halted\n" );
rc = RETSEV;
} /* end of issueDataSetOpeningError */
void issueDataSetReadingError /* Handler for ds read error */
( char *DDname, /* - in: name of errant DD */
int LEerrno /* - in: LE diagnostic errno */
)
/*******************************************************************
* Called when a TSO data set cannot be read *
*******************************************************************/
{ printf( "ERROR: Unable to read %s\n", DDname );
printf( "%s \n",strerror(LEerrno) );
printf( "-----> Processing halted\n" );
rc = RETSEV;
} /* end of issueDataSetReadingError */
void issueInvalidParmLengthError /* Handler for parm len error */
( char *parmName, /* - in: identify of parm */
int minLength, /* - in: min valid length */
int maxLength /* - in: max valid length */
)
/*******************************************************************
* Called when the length of an argument specified for a DSNTPSMP *
* parameter (parmName) does not fall within the valid bounds for *
* size (minLength and maxLength) for that parameter *
*******************************************************************/
{ printf( "ERROR: The length of the argument specified for the %s "
"parameter\n",parmName );
printf( " does not fall within the required bounds of %i "
"and %i\n",minLength,maxLength );
printf( "-----> Processing halted\n" );
rc = RETSEV;
} /* end of issueInvalidParmLengthError */
#pragma linkage(dsntiar, OS)
void issueSqlError /* Handler for SQL error */
( char *locMsg /* - in: Call location */
)
/*******************************************************************
* Called when an unexpected SQLCODE is returned from a DB2 call *
*******************************************************************/
{ struct error_struct { /* DSNTIAR message structure */
short int error_len;
char error_text[10][80];
} error_message = {10 * 80};
extern short int dsntiar( struct sqlca *sqlca,
struct error_struct *msg,
int *len );
short int DSNTIARrc; /* DSNTIAR Return code */
int j; /* Loop control */
static int lrecl = 80; /* Width of message lines */
/*****************************************************************
* print the locator message *
*****************************************************************/
printf( "ERROR: %-80s\n", locMsg );
printf( "-----> Processing halted\n" );
/*****************************************************************
* format and print the SQL message *
*****************************************************************/
DSNTIARrc = dsntiar( &sqlca, &error_message, &lrecl );
if( DSNTIARrc == 0 )
for( j = 0; j <= 10; j++ )
printf( " %.80s\n", error_message.error_text[j] );
else
{
printf( " *** ERROR: DSNTIAR could not format the message\n" );
printf( " *** SQLCODE is %d\n",SQLCODE );
printf( " *** SQLERRM is \n" );
for( j=0; j<sqlca.sqlerrml; j++ )
printf( "%c", sqlca.sqlerrmc[j] );
printf( "\n" );
}
/*****************************************************************
* set severe error code *
*****************************************************************/
rc = RETSEV;
} /* end of issueSqlError */
void convertEncodingScheme
( char *string, /* - in/out: string to convert*/
short int stringLength, /* - in: length of string */
unsigned long sourceCCSID, /* - in: CCSID to convert from*/
unsigned long targetCCSID /* - in: CCSID to convert to */
)
/*******************************************************************
* Call z/OS conversion services to convert string from sourceCCSID *
* to targetCCSID *
*******************************************************************/
{ char sourcebuffer[32704];
char targetbuffer[32704];
char DDA[CUNBCPRM_DDA_REQ];
char workbuffer[32704];
CUNBCPRM convParm = {CUNBCPRM_DEFAULT};
short int ii;
/*****************************************************************
* initialize work areas *
*****************************************************************/
memset( sourcebuffer,NULLCHAR,32704 );
memset( targetbuffer,NULLCHAR,32704 );
memset( workbuffer,NULLCHAR,32704 );
strncpy( sourcebuffer,string,stringLength );
/*****************************************************************
* establish work area pointers for conversion services *
*****************************************************************/
convParm.Src_Buf_Ptr = sourcebuffer;
convParm.Src_Buf_Len = stringLength;
convParm.Targ_Buf_Ptr = targetbuffer;
convParm.Targ_Buf_Len = 32704;
convParm.Src_CCSID = sourceCCSID;
convParm.Targ_CCSID = targetCCSID;
memcpy(convParm.Technique,"ER",2);
convParm.Wrk_Buf_Ptr = workbuffer;
convParm.Wrk_Buf_Len = 32704;
convParm.DDA_Buf_Ptr = DDA; /* used for service internal data */
convParm.DDA_Buf_Len = CUNBCPRM_DDA_REQ;
/*****************************************************************
* call conversion services *
*****************************************************************/
CUNLCNV ( & convParm );
if( convParm.Return_Code == CUN_RC_OK )
strcpy( string,targetbuffer );
else
{ printf( "ERROR: Unable to convert the string: x<" );
for( ii=0; ii<stringLength; ii++ )
printf( "%0x",TEXT.data[ii] );
printf( ">\n" );
printf( " from CCSID %u to CCSID %u\n",
sourceCCSID, targetCCSID );
printf( " Conversion returned code = %d, reason = %d\n",
convParm.Return_Code, convParm.Reason_Code);
printf( "-----> Processing halted\n" );
rc = RETSEV;
}
} /* end of convertEncodingScheme */