Sample C program for inquiring about channel objects (amqsaicl.c)
The sample C program amqsaicl.c inquires channel objects using the MQAI.
/******************************************************************************/ /* */ /* Program name: AMQSAICL.C */ /* */ /* Description: Sample C program to inquire channel objects */ /* using the IBM MQ Administration Interface (MQAI) */ /* */ /* <N_OCO_COPYRIGHT> */ /* */ /* 63H9336 */ /* (c) Copyright IBM Corp. 2008, 2020. All Rights Reserved. */ /* */ /* disclosure restricted by GSA ADP Schedule Contract with */ /* IBM Corp. */ /* <NOC_COPYRIGHT> */ /******************************************************************************/ /* */ /* Function: */ /* AMQSAICL is a sample C program that demonstrates how to inquire */ /* attributes of the local queue manager using the MQAI interface. In */ /* particular, it inquires all channels and their types. */ /* */ /* - A PCF command is built from items placed into an MQAI administration */ /* bag. */ /* These are:- */ /* - The generic channel name "*" */ /* - The attributes to be inquired. In this sample we just want */ /* name and type attributes */ /* */ /* - The mqExecute MQCMD_INQUIRE_CHANNEL call is executed. */ /* The call generates the correct PCF structure. */ /* The default options to the call are used so that the command is sent */ /* to the SYSTEM.ADMIN.COMMAND.QUEUE. */ /* The reply from the command server is placed on a temporary dynamic */ /* queue. */ /* The reply from the MQCMD_INQUIRE_CHANNEL is read from the */ /* temporary queue and formatted into the response bag. */ /* */ /* - The completion code from the mqExecute call is checked and if there */ /* is a failure from the command server, then the code returned by the */ /* command server is retrieved from the system bag that has been */ /* embedded in the response bag to the mqExecute call. */ /* */ /* Note: The command server must be running. */ /* */ /******************************************************************************/ /* */ /* AMQSAICL has 2 parameter - the queue manager name (optional) */ /* - output file (optional) default varies */ /******************************************************************************/ /******************************************************************************/ /* Includes */ /******************************************************************************/ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #if (MQAT_DEFAULT == MQAT_OS400) #include <recio.h> #endif #include <cmqc.h> /* MQI */ #include <cmqcfc.h> /* PCF */ #include <cmqbc.h> /* MQAI */ #include <cmqxc.h> /* MQCD */ /******************************************************************************/ /* Function prototypes */ /******************************************************************************/ void CheckCallResult(MQCHAR *, MQLONG, MQLONG); /******************************************************************************/ /* DataTypes */ /******************************************************************************/ #if (MQAT_DEFAULT == MQAT_OS400) typedef _RFILE OUTFILEHDL; #else typedef FILE OUTFILEHDL; #endif /******************************************************************************/ /* Constants */ /******************************************************************************/ #if (MQAT_DEFAULT == MQAT_OS400) const struct { char name[9]; } ChlTypeMap[9] = { "*SDR ", /* MQCHT_SENDER */ "*SVR ", /* MQCHT_SERVER */ "*RCVR ", /* MQCHT_RECEIVER */ "*RQSTR ", /* MQCHT_REQUESTER */ "*ALL ", /* MQCHT_ALL */ "*CLTCN ", /* MQCHT_CLNTCONN */ "*SVRCONN ", /* MQCHT_SVRCONN */ "*CLUSRCVR", /* MQCHT_CLUSRCVR */ "*CLUSSDR " /* MQCHT_CLUSSDR */ }; #else const struct { char name[9]; } ChlTypeMap[9] = { "sdr ", /* MQCHT_SENDER */ "svr ", /* MQCHT_SERVER */ "rcvr ", /* MQCHT_RECEIVER */ "rqstr ", /* MQCHT_REQUESTER */ "all ", /* MQCHT_ALL */ "cltconn ", /* MQCHT_CLNTCONN */ "svrcn ", /* MQCHT_SVRCONN */ "clusrcvr ", /* MQCHT_CLUSRCVR */ "clussdr " /* MQCHT_CLUSSDR */ }; #endif /******************************************************************************/ /* Macros */ /******************************************************************************/ #if (MQAT_DEFAULT == MQAT_OS400) #define OUTFILE "QTEMP/AMQSAICL(AMQSAICL)" #define OPENOUTFILE(hdl, fname) \ (hdl) = _Ropen((fname),"wr, rtncode=Y"); #define CLOSEOUTFILE(hdl) \ _Rclose((hdl)); #define WRITEOUTFILE(hdl, buf, buflen) \ _Rwrite((hdl),(buf),(buflen)); #elif (MQAT_DEFAULT == MQAT_UNIX) #define OUTFILE "/tmp/amqsaicl.txt" #define OPENOUTFILE(hdl, fname) \ (hdl) = fopen((fname),"w"); #define CLOSEOUTFILE(hdl) \ fclose((hdl)); #define WRITEOUTFILE(hdl, buf, buflen) \ fwrite((buf),(buflen),1,(hdl)); fflush((hdl)); #else #define OUTFILE "amqsaicl.txt" #define OPENOUTFILE(fname) \ fopen((fname),"w"); #define CLOSEOUTFILE(hdl) \ fclose((hdl)); #define WRITEOUTFILE(hdl, buf, buflen) \ fwrite((buf),(buflen),1,(hdl)); fflush((hdl)); #endif #define ChlType2String(t) ChlTypeMap[(t)-1].name /******************************************************************************/ /* Function: main */ /******************************************************************************/ int main(int argc, char *argv[]) { /***************************************************************************/ /* MQAI variables */ /***************************************************************************/ MQHCONN hConn; /* handle to MQ connection */ MQCHAR qmName[MQ_Q_MGR_NAME_LENGTH+1]=""; /* default QMgr name */ MQLONG reason; /* reason code */ MQLONG connReason; /* MQCONN reason code */ MQLONG compCode; /* completion code */ MQHBAG adminBag = MQHB_UNUSABLE_HBAG; /* admin bag for mqExecute */ MQHBAG responseBag = MQHB_UNUSABLE_HBAG;/* response bag for mqExecute */ MQHBAG cAttrsBag; /* bag containing chl attributes */ MQHBAG errorBag; /* bag containing cmd server error */ MQLONG mqExecuteCC; /* mqExecute completion code */ MQLONG mqExecuteRC; /* mqExecute reason code */ MQLONG chlNameLength; /* Actual length of chl name */ MQLONG chlType; /* Channel type */ MQLONG i; /* loop counter */ MQLONG numberOfBags; /* number of bags in response bag */ MQCHAR chlName[MQ_OBJECT_NAME_LENGTH+1];/* name of chl extracted from bag */ MQCHAR OutputBuffer[100]; /* output data buffer */ OUTFILEHDL *outfp = NULL; /* output file handle */ /***************************************************************************/ /* Connect to the queue manager */ /***************************************************************************/ if (argc > 1) strncpy(qmName, argv[1], (size_t)MQ_Q_MGR_NAME_LENGTH); MQCONN(qmName, &hConn;, &compCode;, &connReason;); /***************************************************************************/ /* Report the reason and stop if the connection failed. */ /***************************************************************************/ if (compCode == MQCC_FAILED) { CheckCallResult("Queue Manager connection", compCode, connReason); exit( (int)connReason); } /***************************************************************************/ /* Open the output file */ /***************************************************************************/ if (argc > 2) { OPENOUTFILE(outfp, argv[2]); } else { OPENOUTFILE(outfp, OUTFILE); } if(outfp == NULL) { printf("Could not open output file.\n"); goto MOD_EXIT; } /***************************************************************************/ /* Create an admin bag for the mqExecute call */ /***************************************************************************/ mqCreateBag(MQCBO_ADMIN_BAG, &adminBag;, &compCode;, &reason;); CheckCallResult("Create admin bag", compCode, reason); /***************************************************************************/ /* Create a response bag for the mqExecute call */ /***************************************************************************/ mqCreateBag(MQCBO_ADMIN_BAG, &responseBag;, &compCode;, &reason;); CheckCallResult("Create response bag", compCode, reason); /***************************************************************************/ /* Put the generic channel name into the admin bag */ /***************************************************************************/ mqAddString(adminBag, MQCACH_CHANNEL_NAME, MQBL_NULL_TERMINATED, "*", &compCode;, &reason;); CheckCallResult("Add channel name", compCode, reason); /***************************************************************************/ /* Put the channel type into the admin bag */ /***************************************************************************/ mqAddInteger(adminBag, MQIACH_CHANNEL_TYPE, MQCHT_ALL, &compCode;, &reason;); CheckCallResult("Add channel type", compCode, reason); /***************************************************************************/ /* Add an inquiry for various attributes */ /***************************************************************************/ mqAddInquiry(adminBag, MQIACH_CHANNEL_TYPE, &compCode;, &reason;); CheckCallResult("Add inquiry", compCode, reason); /***************************************************************************/ /* Send the command to find all the channel names and channel types. */ /* The mqExecute call creates the PCF structure required, sends it to */ /* the command server, and receives the reply from the command server into */ /* the response bag. The attributes are contained in system bags that are */ /* embedded in the response bag, one set of attributes per bag. */ /***************************************************************************/ mqExecute(hConn, /* MQ connection handle */ MQCMD_INQUIRE_CHANNEL, /* Command to be executed */ MQHB_NONE, /* No options bag */ adminBag, /* Handle to bag containing commands */ responseBag, /* Handle to bag to receive the response*/ MQHO_NONE, /* Put msg on SYSTEM.ADMIN.COMMAND.QUEUE*/ MQHO_NONE, /* Create a dynamic q for the response */ &compCode;, /* Completion code from the mqexecute */ &reason;); /* Reason code from mqexecute call */ /***************************************************************************/ /* Check the command server is started. If not exit. */ /***************************************************************************/ if (reason == MQRC_CMD_SERVER_NOT_AVAILABLE) { printf("Please start the command server: <strmqcsv QMgrName="">\n"); goto MOD_EXIT; } /***************************************************************************/ /* Check the result from mqExecute call. If successful find the channel */ /* types for all the channels. If failed find the error. */ /***************************************************************************/ if ( compCode == MQCC_OK ) /* Successful mqExecute */ { /*************************************************************************/ /* Count the number of system bags embedded in the response bag from the */ /* mqExecute call. The attributes for each channel are in separate bags. */ /*************************************************************************/ mqCountItems(responseBag, MQHA_BAG_HANDLE, &numberOfBags;, &compCode;, &reason;); CheckCallResult("Count number of bag handles", compCode, reason); for ( i=0; i<numberOfbags; i++) { /***********************************************************************/ /* Get the next system bag handle out of the mqExecute response bag. */ /* This bag contains the channel attributes */ /***********************************************************************/ mqInquireBag(responseBag, MQHA_BAG_HANDLE, i, &cAttrsbag, &compCode, &reason); CheckCallResult("Get the result bag handle", compCode, reason); /***********************************************************************/ /* Get the channel name out of the channel attributes bag */ /***********************************************************************/ mqInquireString(cAttrsBag, MQCACH_CHANNEL_NAME, 0, MQ_OBJECT_NAME_LENGTH, chlName, &chlNameLength, NULL, &compCode, &reason); CheckCallResult("Get channel name", compCode, reason); /***********************************************************************/ /* Get the channel type out of the channel attributes bag */ /***********************************************************************/ mqInquireInteger(cAttrsBag, MQIACH_CHANNEL_TYPE, MQIND_NONE, &chlType, &compCode, &reason); CheckCallResult("Get type", compCode, reason); /***********************************************************************/ /* Use mqTrim to prepare the channel name for printing. */ /* Print the result. */ /***********************************************************************/ mqTrim(MQ_CHANNEL_NAME_LENGTH, chlName, chlName, &compCode, &reason); sprintf(OutputBuffer, "%-20s%-9s", chlName, ChlType2String(chlType)); WRITEOUTFILE(outfp,OutputBuffer,29) } else /* Failed mqExecute */ { printf("Call to get channel attributes failed: Cc = %ld : Rc = %ld\n", compCode, reason); /*************************************************************************/ /* If the command fails get the system bag handle out of the mqexecute */ /* response bag.This bag contains the reason from the command server */ /* why the command failed. */ /*************************************************************************/ if (reason == MQRCCF_COMMAND_FAILED) { mqInquireBag(responseBag, MQHA_BAG_HANDLE, 0, &errorBag, &compCode, &reason); CheckCallResult("Get the result bag handle", compCode, reason); /***********************************************************************/ /* Get the completion code and reason code, returned by the command */ /* server, from the embedded error bag. */ /***********************************************************************/ mqInquireInteger(errorBag, MQIASY_COMP_CODE, MQIND_NONE, &mqExecuteCC, &compCode, &reason ); CheckCallResult("Get the completion code from the result bag", compCode, reason); mqInquireInteger(errorBag, MQIASY_REASON, MQIND_NONE, &mqExecuteRC, &compCode, &reason); CheckCallResult("Get the reason code from the result bag", compCode, reason); printf("Error returned by the command server: Cc = %ld : Rc = %ld\n", mqExecuteCC, mqExecuteRC); } MOD_EXIT: /***************************************************************************/ /* Delete the admin bag if successfully created. */ /***************************************************************************/ if (adminBag != MQHB_UNUSABLE_HBAG) { mqDeleteBag(&adminBag, &compCode, &reason); CheckCallResult("Delete the admin bag", compCode, reason); } /***************************************************************************/ /* Delete the response bag if successfully created. */ /***************************************************************************/ if (responseBag != MQHB_UNUSABLE_HBAG) { mqDeleteBag(&responseBag, &compCode, &reason); CheckCallResult("Delete the response bag", compCode, reason); } /***************************************************************************/ /* Disconnect from the queue manager if not already connected */ /***************************************************************************/ if (connReason != MQRC_ALREADY_CONNECTED) { MQDISC(&hConn, &compCode, &reason); CheckCallResult("Disconnect from Queue Manager", compCode, reason); } /***************************************************************************/ /* Close the output file if open */ /***************************************************************************/ if(outfp != NULL) CLOSEOUTFILE(outfp); return 0; } /******************************************************************************/ /* */ /* Function: CheckCallResult */ /* */ /******************************************************************************/ /* */ /* Input Parameters: Description of call */ /* Completion code */ /* Reason code */ /* */ /* Output Parameters: None */ /* */ /* Logic: Display the description of the call, the completion code and the */ /* reason code if the completion code is not successful */ /* */ /******************************************************************************/ void CheckCallResult(char *callText, MQLONG cc, MQLONG rc) { if (cc != MQCC_OK) printf("%s failed: Completion Code = %ld : Reason = %ld\n", callText, cc, rc); }Parent topic: Use the MQAI to simplify the use of PCFs