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