/* * LICENSE AND DISCLAIMER * ---------------------- * THIS MATERIAL CONTAINS IBM COPYRIGHTED SAMPLE PROGRAMMING SOURCE * CODE ('SAMPLE CODE'). * IBM GRANTS YOU A NONEXCLUSIVE LICENSE TO COMPILE, LINK, EXECUTE, * DISPLAY, REPRODUCE, DISTRIBUTE AND PREPARE DERIVATIVE WORKS OF * THIS SAMPLE CODE. THE SAMPLE CODE HAS NOT BEEN THOROUGHLY * TESTED UNDER ALL CONDITIONS. IBM, THEREFORE, DOES NOT GUARANTEE * OR IMPLY ITS RELIABILITY, SERVICEABILITY, OR FUNCTION. IBM * PROVIDES NO PROGRAM SERVICES FOR THE SAMPLE CODE. * * ALL SAMPLE CODE CONTAINED HEREIN IS PROVIDED TO YOU "AS IS" WITHOUT * ANY WARRANTIES OF ANY KIND. THE IMPLIED WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGMENT ARE EXPRESSLY * DISCLAIMED. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED * WARRANTIES, SO THE ABOVE EXCLUSIONS MAY NOT APPLY TO YOU. IN NO * EVENT WILL IBM BE LIABLE TO ANY PARTY FOR ANY DIRECT, INDIRECT, * SPECIAL OR OTHER CONSEQUENTIAL DAMAGES FOR ANY USE OF THE SAMPLE CODE * INCLUDING, WITHOUT LIMITATION, ANY LOST PROFITS, BUSINESS * INTERRUPTION, LOSS OF PROGRAMS OR OTHER DATA ON YOUR INFORMATION * HANDLING SYSTEM OR OTHERWISE, EVEN IF WE ARE EXPRESSLY ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. * * (C) COPYRIGHT IBM CORP. 2006 * ALL RIGHTS RESERVED. * US GOVERNMENT USERS RESTRICTED RIGHTS - * USE, DUPLICATION OR DISCLOSURE RESTRICTED * BY GSA ADP SCHEDULE CONTRACT WITH IBM CORP. * LICENSED MATERIAL - PROPERTY OF IBM */ /***************************************************************************/ /* COMPILE STATEMENT */ /* CRTSQLCI OBJ(JOLAB00/HRTMONITOR) SRCFILE(JOLAB00/HRTMONITOR */ /* COMMIT(*NONE) OBJTYPE(*PGM) OUTPUT(*PRINT) */ /***************************************************************************/ /***************************************************************************/ /* */ /* Program name: HRTMONITOR */ /* Function: Remote Journal Monitor */ /* */ /* Parameters: argv[1] - char [10] - Journal Name */ /* argv[2] - char [10] - Library Name */ /* argv[3] - char [10] - Target Journal Name */ /* argv[4] - char [10] - Target Library Name */ /* argv[5] - char [10] - Table to Create Name */ /* argv[6] - char [10] - MSGQ Name */ /* argv[7] - char [10] - User Profile */ /* */ /***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include /***************************************************************************/ /* Constants used by this program */ /***************************************************************************/ #define DELAY_CHECK 3 #define MAX_REMOTE 32 /***************************************************************************/ /* Function prototypes */ /***************************************************************************/ void my_exception(_INTRPT_Hndlr_Parms_T * __ptr128 parms); void endChildPgm(char* MSGQ, char* LibName, char* profile); /***************************************************************************/ /* SQL Error Handling and SQL Descriptor areas in C and C++ */ /***************************************************************************/ EXEC sql include SQLCA; EXEC sql include SQLDA; /***************************************************************************/ /* Global variables */ /***************************************************************************/ int jump = 0; int length; char pgm[400]; decimal(15,5) packed_length; /***************************************************************************/ /* M A I N F U N C T I O N */ /***************************************************************************/ int main(int argc, char *argv[]) { /***************************************************************************/ /* SQL Variables */ /***************************************************************************/ EXEC SQL BEGIN DECLARE SECTION; char createTable[1024]; char stmt[1024]; char status[9]; char notified[1]; char srcLib[10]; char srcJrn[10]; char tgtLib[10]; char tgtJrn[10]; char rdb[18]; char msgid[7]; char ts[22]; long ID; long rjTime; char RJ[7]; char FAIL[7]; long countFail; long rsncode; EXEC SQL END DECLARE SECTION; /***************************************************************************/ /* Variables to store Command Line Arguments */ /***************************************************************************/ char journal[10]; char library[10]; char inTgtLib[10]; char inTgtJrn[10]; char msgq[10]; char table[10]; char userProfile[10]; /***************************************************************************/ /* Flag for Status Update */ /***************************************************************************/ int noStatus = 1; /***************************************************************************/ /* Variables for Exception Handling */ /***************************************************************************/ volatile _INTRPT_Hndlr_Parms_T ca; volatile int com = 0; /***************************************************************************/ /* Variables for User Input */ /***************************************************************************/ int x = 0; char answer[10]; int char_count = 0; char ch; printf("\n\n\n\n\n\n\n\n\n\nRemote Journal Heart Monitor\n"); /*************************************************************************/ /* Check parameters & if JRN & LIB Names are valid & exit if not */ /*************************************************************************/ if(argc != 8) { printf("Incorrect number of Parameters\n"); printf("\t1) SRCJRN (string) - Name of Source Journal\n"); printf("\t2) SRCLIB (string) - Library of SRCJRN\n"); printf("\t3) TGTJRN (string) - Name of Target Journal\n"); printf("\t4) TGTLIB (string) - Library of TGTJRN\n"); printf("\t5) Table (string) - Name of SQL Table to Create\n"); printf("\t6) MSGQ (string) - Name of MSGQ\n"); printf("\t7) USRPRF (string) - Lab User Profile\n"); return; } sprintf(journal,"%s",argv[1]); sprintf(library,"%s",argv[2]); sprintf(inTgtJrn,"%s",argv[3]); sprintf(inTgtLib,"%s",argv[4]); sprintf(table,"%s",argv[5]); sprintf(msgq,"%s",argv[6]); sprintf(userProfile,"%s",argv[7]); if(strlen(journal) != 6 || strlen(library) != 6 || strlen(inTgtJrn) != 6 || strlen(inTgtLib) != 9 || strlen(msgq) != 4 || strlen(userProfile) != 7) { printf("HRTMONITOR paramaters entered incorrectly.\n"); printf("One or more of your paramaters contains "); printf("the incorrect number of characters.\n"); return; } if(!isdigit(userProfile[5]) || !isdigit(userProfile[6])) { printf("User Profile Incorrect. Must be in Format JOLABXX\n"); printf("Where XX represents your team number\n"); return; } if(!isdigit(library[4]) || !isdigit(library[5])) { printf("Source library is incorrect. Must be in Format JOHAXX\n"); printf("Where XX represents your team number\n"); return; } if(!isdigit(inTgtLib[7]) || !isdigit(inTgtLib[8])) { printf("Target library is incorrect. Must be in Format JORMTHAXX\n"); printf("Where XX represents your team number\n"); return; } if(strlen(journal) > 10 || strlen(library) > 10) { printf("Parameters can not exceed 10 characters in length\n"); return; } /*************************************************************************/ /* Create SQL Table using argv[3] */ /*************************************************************************/ sprintf(createTable,"CREATE TABLE %s/%s (RJ_ID",library,table); sprintf(createTable,"%s INT GENERATED ALWAYS AS IDENTITY",createTable); sprintf(createTable,"%s (START WITH 1000 INCREMENT BY 1),",createTable); sprintf(createTable,"%s STATUS char(8),",createTable); sprintf(createTable,"%s NOTIFIED char(1),",createTable); sprintf(createTable,"%s SRCLIB char(10), SRCJRN char(10),",createTable); sprintf(createTable,"%s TGTLIB char(10), TGTJRN char(10),",createTable); sprintf(createTable,"%s RDB char(10), MSGID char(7), RSNCODE INT,", createTable); sprintf(createTable,"%s TS TIMESTAMP,TIMES_INACTIVE INT,FAILED INT)", createTable); EXEC SQL EXECUTE IMMEDIATE :createTable; if(sqlca.sqlcode < 0) { printf("Could not create the table %s SQL ERROR CODE %d\nReason: ", table,sqlca.sqlcode); if(sqlca.sqlcode == -601) { printf("Table %s in Library %s already exists\n",table,library); } //return; } /*************************************************************************/ /* Run HRTBeat PGM To Monitor For RJ MSGs */ /*************************************************************************/ sprintf(pgm,"SBMJOB CMD(CALL PGM(%s/HRTBEAT) PARM(",userProfile); sprintf(pgm,"%s '%s' '%s' '%s' '%s' '%s' '%s'))", pgm,msgq,library, inTgtJrn,inTgtLib,table,userProfile); length = strlen(pgm); cpynv(NUM_DESCR(_T_PACKED,15,5), &packed_length, NUM_DESCR(_T_SIGNED,4,0), &length); QCMDEXC(pgm, packed_length); /*************************************************************************/ /* Prepare SQL STMT to retrieve a ROW from RJSTATUS */ /*************************************************************************/ sprintf(stmt,"SELECT RTRIM(RJ_ID), RTRIM(STATUS), RTRIM(NOTIFIED),"); sprintf(stmt,"%s RTRIM(SRCLIB), RTRIM(SRCJRN), RTRIM(TGTLIB),",stmt); sprintf(stmt,"%s RTRIM(TGTJRN), RTRIM(RDB), RTRIM(MSGID), RSNCODE, TS,",stmt); sprintf(stmt,"%s TIMESTAMPDIFF(2, char(CURRENT TIMESTAMP - TS)) FROM %s/%s", stmt,library,table); EXEC SQL PREPARE RJ FROM :stmt; EXEC SQL DECLARE NEXT_RJ CURSOR FOR RJ; /*************************************************************************/ /* Continue checking RJ status until prompted not to by user */ /*************************************************************************/ while(1) { EXEC SQL OPEN NEXT_RJ USING :RJ; EXEC SQL WHENEVER NOT FOUND GOTO close_cursor; while(1) { EXEC SQL FETCH NEXT_RJ INTO :ID, :status, :notified, :srcLib, :srcJrn, :tgtLib, :tgtJrn, :rdb, :msgid, :rsncode, :ts, :rjTime; if(sqlca.sqlcode < 0) { printf(" SQL ERROR CODE %d\nReason: ",sqlca.sqlcode); } /*************************************************************************/ /* RJ has become inactive and user has yet to be Notified */ /*************************************************************************/ if( strcmp( status, "INACTIVE" ) == 0 && notified[0] == 'N' ) { noStatus = 0; printf("Remote Journal %s in Library %s on ",srcJrn,srcLib); printf("Target Machine %s\n Has been Inactive for %i seconds\n", rdb,rjTime); ts[22] = 0x00; printf("This RJ connection became Inactive at %s\n",ts); printf(" Because of MSG %s",msgid); if(rsncode != -1) { printf(" and reason code %i",rsncode); } printf("\n"); printf("Would you like to reactivate? (Y,N)\n"); char_count = 0; ch = getchar(); while(ch != '\n' ) { if (char_count < 10) answer[char_count++] = ch; ch = getchar(); } /*************************************************************************/ /* Error Handler: Checking for all Exceptions */ /*************************************************************************/ #pragma exception_handler (my_exception, com, _C1_ALL, _C2_ALL,_CTLA_HANDLE) if(tolower(answer[0]) == 'y') { /**********************************************************************/ /* Change Remote Journal Status back to Active. If fails enter */ /* exception_handler method my_exception */ /**********************************************************************/ jump = 0; sprintf(pgm,"CHGRMTJRN RDB(%s) SRCJRN(%s/%s)",rdb,srcLib,srcJrn); sprintf(pgm,"%s TGTJRN(%s/%s) JRNSTATE(*ACTIVE)",pgm,tgtLib,tgtJrn); length = strlen(pgm); cpynv(NUM_DESCR(_T_PACKED,15,5), &packed_length, NUM_DESCR(_T_SIGNED,4,0), &length); QCMDEXC(pgm, packed_length); pgm[0] = 0x00; /**********************************************************************/ /* Reactivation of Remote Journal Succeeded. Update times INACTIVE */ /**********************************************************************/ if(jump == 0) { stmt[0] = 0x00; sprintf(stmt,"UPDATE %s/%s SET STATUS = 'ACTIVE',",library,table); sprintf(stmt,"%s NOTIFIED = 'Y', MSGID = 'MANUAL',",stmt); sprintf(stmt,"%s TS = CURRENT TIMESTAMP WHERE RJ_ID = %i",stmt,ID); EXEC SQL EXECUTE IMMEDIATE :stmt; } /**********************************************************************/ /* Reactivation of Remote Journal failed. Update Failed Attempts */ /**********************************************************************/ else if(jump == 1) { sprintf(stmt,"SELECT TIMES_INACTIVE FROM %s/%s WHERE RJ_ID = %i", argv[2],argv[9],ID); EXEC SQL PREPARE FAIL FROM :stmt; EXEC SQL DECLARE COUNT_FAILED CURSOR FOR FAIL; EXEC SQL OPEN COUNT_FAILED USING :FAIL; EXEC SQL FETCH COUNT_FAILED INTO: countFail; EXEC SQL CLOSE COUNT_FAILED; stmt[0] = 0x00; sprintf(stmt,"UPDATE %s/%s SET FAILED = %i WHERE RJ_ID = %i ", library,table,countFail+1,ID); EXEC SQL EXECUTE IMMEDIATE :stmt; } } else { stmt[0] = 0x00; sprintf(stmt,"UPDATE %s/%s SET NOTIFIED = 'Y'",library,table); EXEC SQL EXECUTE IMMEDIATE :stmt; } printf("\nWould you like to continue monitoring RJ status? (Y,N)\n"); char_count = 0; ch = getchar(); while(ch != '\n' ) { if (char_count < 10) answer[char_count++] = ch; ch = getchar(); } if(tolower(answer[0]) != 'y') { endChildPgm(msgq,library,userProfile); return; } } else if(strcmp( status, "INACTIVE" ) == 0 && notified[0] == 'Y' ) { printf("Remote Journal %s in Library %s on ",srcJrn,srcLib); printf("Target Machine %s\n status has been Inactive for %i seconds.\n", rdb,rjTime); if(rjTime > 60) { stmt[0] = 0x00; sprintf(stmt,"UPDATE %s/%s SET NOTIFIED = 'N'",library,table); EXEC SQL EXECUTE IMMEDIATE :stmt; } } /*************************************************************************/ /* Remote Journal monitoring is Active */ /*************************************************************************/ else if(strcmp( status, "ACTIVE" ) == 0) { noStatus = 0; printf("Remote Journal %s in Library %s on ",srcJrn,srcLib); printf("Target Machine %s\n status has been Active for %i seconds.\n", rdb,rjTime); } } close_cursor: EXEC SQL CLOSE NEXT_RJ; if(noStatus) { printf("Remote Journal %s in Library %s on ",journal,library); printf("Target Machine %s\n status is active.\n", rdb,rjTime); } for(x = 0;xCompare_Data, (unsigned) exp_info->Exception_Id);*/ printf("Message ID is %s\n",exp_info->Msg_Id); printf("Exception Data is %s\n",exp_info->Ex_Data); if(strncmp(exp_info->Msg_Id,"CPF697A",6) == 0 ) { printf("The Remote Journal was already Active\n"); jump = 0; } } /***************************************************************************/ /* */ /* Function: endChildPgm */ /* */ /* Description: Sends ENDPGM message to a message queue monitored by */ /* HRTMONITOR */ /* */ /* Parameters: MSGQ - 10 byte Message Queue Name */ /* LibName - 10 byte Message Queue Library Name */ /* profile - 10 byte User Profile */ /***************************************************************************/ void endChildPgm(char* MSGQ, char* libName, char* profile) { sprintf(pgm,"SBMJOB CMD(CALL PGM(%s/ENDPGM) PARM('%s' '%s' '%s'))", profile,MSGQ,libName,profile); length = strlen(pgm); cpynv(NUM_DESCR(_T_PACKED,15,5), &packed_length, NUM_DESCR(_T_SIGNED,4,0), &length); QCMDEXC(pgm, packed_length); }