Example: Using registration facility APIs
These ILE C programs show how to register an exit point, how to add an exit program to the exit point, and how to call the exit program based on the exit point information that is retrieved.
The first thing to do, after deciding in what program object the exit point is to be placed, is to register that exit point. It is also important to remember that the exit point format defines what the exit program data looks like. This ILE C program registers an exit point named QIBM_QXIC_TSTXPOINTA.
/********************************************************************/
/* PROGRAM: RegisterPoint */
/* */
/* LANGUAGE: ILE C */
/* */
/* DESCRIPTION: This program registers an exit point in an */
/* application. */
/* */
/* APIs USED: QusRegisterExitPoint */
/* */
/********************************************************************/
#include <string.h>
#include <qusec.h>
#include <qusrgfa1.h>
/********************************************************************/
/* Structure for the control block */
/********************************************************************/
typedef _Packed struct Control_x{
int Num_Vlen_Recs;
Qus_Vlen_Rec_4_t Vlen_Rec_1;
char Description[50];
} Control_Rec;
int main () {
Qus_EC_t Error_Code = {0};
char EPnt_Name[20] = "QIBM_QXIC_TSTXPOINTA";
char EPnt_F_Name[8] = "USUSOOOO";
int EProg_Number = -1;
Control_Rec EPnt_Controls = {0};
/*****************************************
*** INITIALIZING ALL STRUCTURES:: ***
*****************************************/
Error_Code.Bytes_Provided = sizeof(Error_Code);
EPnt_Controls.Num_Vlen_Recs = 1;
EPnt_Controls.Vlen_Rec_1.Length_Vlen_Record = 62;
EPnt_Controls.Vlen_Rec_1.Control_Key = 8;
EPnt_Controls.Vlen_Rec_1.Length_Data = 50;
memcpy( EPnt_Controls.Description , "Example Exit Point" , 17 );
QusRegisterExitPoint (EPnt_Name,
EPnt_F_Name,
&EPnt_Controls,
&Error_Code);
if ( Error_Code.Bytes_Available ) {
printf("\nEXCEPTION : %s",Error_Code.Exception_Id);
exit (1);
}
return(0);
}
After an exit point has been registered, exit programs must be added to that point, indicating the possible calls based on runtime conditions. The following ILE C program adds an exit program named TSTXITPROGQGPL to the QIBM_QXIC_TSTXPOINTA exit point that is registered in the previous example.
/********************************************************************/
/* PROGRAM: AddProgram */
/* */
/* LANGUAGE: ILE C */
/* */
/* DESCRIPTION: This program adds an exit program to a registered */
/* exit point. */
/* */
/* APIs USED: QusAddExitProgram */
/* */
/********************************************************************/
#include <qusec.h>
#include <qusrgfa1.h>
/********************************************************************/
/* Structure for the Exit Program Attributes */
/********************************************************************/
typedef _Packed struct Xit_Att{
int Num_Vlen_Recs;
Qus_Vlen_Rec_4_t ADPG_Vlen;
int CCSID;
char Reserved;
} Xit_Attributes;
int main () {
Qus_EC_t Error_Code = {0};
char EPnt_Name[20] = "QIBM_QXIC_TSTXPOINTA";
char EPnt_F_Name[8] = "USUSOOOO";
int EProg_Number = -1;
char Q_EProg_Name[20] = "TSTXITPROGQGPL ";
char EProg_Data[10] = "EXAMPLE ";
int Len_EProg_Data = sizeof(EProg_Data);
Xit_Attributes EProg_Attributes;
Error_Code.Bytes_Provided=sizeof(Error_Code);
EProg_Attributes.Num_Vlen_Recs=1;
EProg_Attributes.ADPG_Vlen.Length_Vlen_Record=16;
EProg_Attributes.ADPG_Vlen.Control_Key=3;
EProg_Attributes.ADPG_Vlen.Length_Data=4;
EProg_Attributes.CCSID = 37;
QusAddExitProgram (EPnt_Name,
EPnt_F_Name,
EProg_Number,
Q_EProg_Name,
EProg_Data,
Len_EProg_Data,
&EProg_Attributes,
&Error_Code);
if ( Error_Code.Bytes_Available ) {
printf("\nEXCEPTION : %s",Error_Code.Exception_Id);
exit (1);
}
return(0);
}
When you have registered an exit point and have added the exit programs to that exit point, you can do exit program calls from within your application. The information needed to do the calls is obtained from the Retrieve Exit Information API. In the following sample a conditional call is made based on the exit point information.
/********************************************************************/
/* PROGRAM: RetrieveAndProcess */
/* */
/* LANGUAGE: ILE C */
/* */
/* DESCRIPTION: This is an excerpt of a program that retrieves */
/* information on an exit point, and does processing */
/* based on that information. */
/* */
/* APIs USED: QusRetrieveExitInformation */
/* */
/********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <qusec.h>
#include <qusrgfa2.h>
/********************************************************************/
/* Structure for Selection Criteria on the Retrieve */
/********************************************************************/
typedef _Packed struct RTVEI_Select_C_x {
Qus_Selcrtr_t Crit;
Qus_Select_Entry_t Select_Entry;
char RTV_String[10];
} RTVEI_Select_C;
/********************************************************************/
/* Conv_Lib converts the library name to a null terminated string */
/********************************************************************/
char * Conv_Lib(char in_lib[], char *tmp) {
int x = 0;
while ( (in_lib[x] != ' ') && x!=10 ) {
*tmp=in_lib[x++];
tmp++;
}
return(tmp);
}
int main() {
Qus_EXTI0200_t *EXTI0200;
Qus_EXTI0200_Entry_t *EXTI0200_Entry;
char *Pgm_Data;
Qus_EC_t Error_Code= {0};
char EPnt_Name[20] = "QIBM_QXIC_TSTXPOINTA";
char EPnt_F_Name[8] = "USUSOOOO";
int EProg_Number = -1;
int Counter;
char *tmp_str;
char *lib;
char Handle[16] = " ";
int Length_Of_R_Var;
char RTVEI_Format_Name[8];
RTVEI_Select_C EProg_Select_C = {0};
/*****************************************
* Initializing Structures *
*****************************************/
Error_Code.Bytes_Provided = sizeof(Error_Code);
tmp_str=(char *)malloc(sizeof(char));
lib=(char *)malloc(sizeof(char));
EXTI0200=(Qus_EXTI0200_t *) malloc ( ( sizeof( Qus_EXTI0200_t ) +
sizeof( Qus_EXTI0200_Entry_t ) + MAX_PGM_DATA_SIZE ) * 2 );
EProg_Select_C.Crit.Number_Sel_Criteria = 1;
EProg_Select_C.Select_Entry.Size_Entry = 26;
EProg_Select_C.Select_Entry.Comp_Operator = 1;
EProg_Select_C.Select_Entry.Start_Pgm_Data = 0;
EProg_Select_C.Select_Entry.Length_Comp_Data = 10;
memcpy( EProg_Select_C.RTV_String , "EXAMPLE " , 10 );
Length_Of_R_Var = (sizeof( Qus_EXTI0200_t ) +
sizeof( Qus_EXTI0200_Entry_t ) +
MAX_PGM_DATA_SIZE) *2;
memcpy( RTVEI_Format_Name , "EXTI0200" , 8 );
QusRetrieveExitInformation (Handle,
EXTI0200,
Length_Of_R_Var,
RTVEI_Format_Name,
EPnt_Name,
EPnt_F_Name,
EProg_Number,
&EProg_Select_C,
&Error_Code);
if ( Error_Code.Bytes_Available ) {
printf("\nEXCEPTION : %s",Error_Code.Exception_Id);
exit (1);
}
/********************************************************
* Call all of the preprocessing exit programs returned *
********************************************************/
Counter=EXTI0200->Number_Programs_Returned;
while ( Counter-- ) {
EXTI0200_Entry = (Qus_EXTI0200_Entry_t *) EXTI0200;
EXTI0200_Entry = (Qus_EXTI0200_Entry_t *)((char *)EXTI0200 +
EXTI0200->Offset_Program_Entry);
Pgm_Data = (char *) EXTI0200_Entry;
Pgm_Data += EXTI0200_Entry->Offset_Exit_Data;
Conv_Lib(EXTI0200_Entry->Program_Library,lib);
sprintf( tmp_str , "CALL %s/%.10s %.*s" ,
lib,
EXTI0200_Entry->Program_Name,
EXTI0200_Entry->Length_Exit_Data,
Pgm_Data );
system( tmp_str );
/********************************************************
* This is where Error Handling on the exit program *
* would be done. *
********************************************************/
if ( Counter ) {
memcpy(EXTI0200->Continue_Handle,Handle,16);
QusRetrieveExitInformation(Handle,
EXTI0200,
Length_Of_R_Var,
RTVEI_Format_Name,
EPnt_Name,
EPnt_F_Name,
EProg_Number,
&EProg_Select_C,
&Error_Code);
if ( Error_Code.Bytes_Available ) {
printf("\nEXCEPTION : %s",Error_Code.Exception_Id);
exit (1);
}
}
}
return(0);
}