+

Search Tips | Advanced Search

PCF example

The compiled program, written in C language, in the example uses IBM MQ for Windows. It inquires of the default queue manager about a subset of the attributes for all local queues defined to it. It then produces an output file, SAVEQMGR.TST, in the directory from which it was run for use with RUNMQSC.


Inquire local queue attributes

This following section provides an example of how Programmable Command Formats can be used in a program for administration of IBM MQ queues.

The program is given as an example of using PCFs and has been limited to a simple case. This program is of most use as an example if we are considering the use of PCFs to manage the IBM MQ environment.


Program listing

/*===========================================================================*/
/*                                                                           */
/* This is a program to inquire of the default queue manager about the       */
/* local queues defined to it.                                               */
/*                                                                           */
/* The program takes this information and appends it to a file               */
/* SAVEQMGR.TST which is of a format suitable for RUNMQSC. It could,         */
/* therefore, be used to re-create or clone a queue manager.                 */
/*                                                                           */
/* It is offered as an example of using Programmable Command Formats (PCFs)  */
/* as a method for administering a queue manager.                            */
/*                                                                           */
/*===========================================================================*/

/* Include standard libraries */
#include <memory.h>
#include <stdio.h>

/* Include MQSeries headers */
#include <cmqc.h>
#include <cmqcfc.h>
#include <cmqxc.h>

typedef struct LocalQParms {
   MQCHAR48    QName;
   MQLONG      QType;
   MQCHAR64    QDesc;
   MQLONG      InhibitPut;
   MQLONG      DefPriority;
   MQLONG      DefPersistence;
   MQLONG      InhibitGet;
   MQCHAR48    ProcessName;
   MQLONG      MaxQDepth;
   MQLONG      MaxMsgLength;
   MQLONG      BackoutThreshold;
   MQCHAR48    BackoutReqQName;
   MQLONG      Shareability;
   MQLONG      DefInputOpenOption;
   MQLONG      HardenGetBackout;
   MQLONG      MsgDeliverySequence;
   MQLONG      RetentionInterval;
   MQLONG      DefinitionType;
   MQLONG      Usage;
   MQLONG      OpenInputCount;
   MQLONG      OpenOutputCount;
   MQLONG      CurrentQDepth;
   MQCHAR12    CreationDate;
   MQCHAR8     CreationTime;
   MQCHAR48    InitiationQName;
   MQLONG      TriggerControl;
   MQLONG      TriggerType;
   MQLONG      TriggerMsgPriority;
   MQLONG      TriggerDepth;
   MQCHAR64    TriggerData;
   MQLONG      Scope;
   MQLONG      QDepthHighLimit;
   MQLONG      QDepthLowLimit;
   MQLONG      QDepthMaxEvent;
   MQLONG      QDepthHighEvent;
   MQLONG      QDepthLowEvent;
   MQLONG      QServiceInterval;
   MQLONG      QServiceIntervalEvent;
} LocalQParms;

MQOD  ObjDesc = { MQOD_DEFAULT };
MQMD  md      = { MQMD_DEFAULT };
MQPMO pmo     = { MQPMO_DEFAULT };
MQGMO gmo     = { MQGMO_DEFAULT }; 
 
void ProcessStringParm( MQCFST *pPCFString, LocalQParms *DefnLQ );

void ProcessIntegerParm( MQCFIN *pPCFInteger, LocalQParms *DefnLQ );

void AddToFileQLOCAL( LocalQParms DefnLQ );

void MQParmCpy( char *target, char *source, int length );
 
void PutMsg( MQHCONN   hConn       /* Connection to queue manager            */
         , MQCHAR8   MsgFormat   /* Format of user data to be put in msg   */
         , MQHOBJ    hQName      /* handle of queue to put the message to  */
         , MQCHAR48  QName       /* name of queue to put the message to    */
         , MQBYTE   *UserMsg     /* The user data to be put in the message */
         , MQLONG    UserMsgLen  /*                                        */
           );
 
void GetMsg( MQHCONN   hConn          /* handle of queue manager            */
         , MQLONG    MQParm         /* Options to specify nature of get   */
         , MQHOBJ    hQName         /* handle of queue to read from       */
         , MQBYTE   *UserMsg        /* Input/Output buffer containing msg */
         , MQLONG    ReadBufferLen  /* Length of supplied buffer          */
           );
MQHOBJ OpenQ( MQHCONN     hConn
          , MQCHAR48    QName
          , MQLONG      OpenOpts
            );
 
int main( int argc, char *argv[] )
{
  MQCHAR48             QMgrName;         /* Name of connected queue mgr     */
  MQHCONN              hConn;            /* handle to connected queue mgr   */
  MQOD                 ObjDesc;          /*                                 */
  MQLONG               OpenOpts;         /*                                 */
  MQLONG               CompCode;         /* MQ API completion code          */
  MQLONG               Reason;           /* Reason qualifying CompCode      */
                                         /*                                 */
  MQHOBJ               hAdminQ;          /* handle to output queue          */
  MQHOBJ               hReplyQ;          /* handle to input queue           */
                                         /*                                 */
  MQLONG               AdminMsgLen;      /* Length of user message buffer   */
  MQBYTE              *pAdminMsg;        /* Ptr to outbound data buffer     */
  MQCFH               *pPCFHeader;       /* Ptr to PCF header structure     */
  MQCFST              *pPCFString;       /* Ptr to PCF string parm block    */
  MQCFIN              *pPCFInteger;      /* Ptr to PCF integer parm block   */
  MQLONG              *pPCFType;         /* Type field of PCF message parm  */
  LocalQParms          DefnLQ;           /*                                 */
                                         /*                                 */
  char                 ErrorReport[40];  /*                       */
  MQCHAR8              MsgFormat;        /* Format of inbound message       */
  short                Index;            /* Loop counter                    */

  /* Connect to default queue manager */
  QMgrName[0] =  '\0';                   /* set to null   default QM */
  if ( argc > 1 )
    strcpy(QMgrName, argv[1]);

  MQCONN(  QMgrName                      /*  use default queue manager  */
      , &hConn                         /*  queue manager handle       */
      , &CompCode                      /*  Completion code            */
      , &Reason                        /*  Reason qualifying CompCode */
        );
 
  if ( CompCode != MQCC_OK ) {
     printf( "MQCONN failed for %s, CC=%d RC=%d\n"
         , QMgrName
         , CompCode
         , Reason
           );
     exit( -1 );
  } /* endif */
 
  /* Open all the required queues */
  hAdminQ = OpenQ( hConn, "SYSTEM.ADMIN.COMMAND.QUEUE\0", MQOO_OUTPUT );
 
  hReplyQ = OpenQ( hConn, "SAVEQMGR.REPLY.QUEUE\0", MQOO_INPUT_EXCLUSIVE );
 
  /* ****************************************************************** */
  /* Put a message to the SYSTEM.ADMIN.COMMAND.QUEUE to inquire all     */
  /* the local queues defined on the queue manager.                     */
  /*                                                                    */
  /* The request consists of a Request Header and a parameter block     */
  /* used to specify the generic search. The header and the parameter   */
  /* block follow each other in a contiguous buffer which is pointed    */
  /* to by the variable pAdminMsg. This entire buffer is then put to    */
  /* the queue.                                                         */
  /*                                                                    */
  /* The command server, (use STRMQCSV to start it), processes the      */
  /* SYSTEM.ADMIN.COMMAND.QUEUE and puts a reply on the application     */
  /* ReplyToQ for each defined queue.                                   */
  /* ****************************************************************** */
 
  /* Set the length for the message buffer */
  AdminMsgLen = MQCFH_STRUC_LENGTH
              + MQCFST_STRUC_LENGTH_FIXED + MQ_Q_NAME_LENGTH
              + MQCFIN_STRUC_LENGTH
              ;
 
  /* ----------------------------------------------------------------- */
  /* Set pointers to message data buffers                              */
  /*                                                                   */
  /* pAdminMsg points to the start of the message buffer               */
  /*                                                                   */
  /* pPCFHeader also points to the start of the message buffer. It is  */
  /* used to indicate the type of command we wish to execute and the   */
  /* number of parameter blocks following in the message buffer.       */
  /*                                                                   */
  /* pPCFString points into the message buffer immediately after the   */
  /* header and is used to map the following bytes onto a PCF string   */
  /* parameter block. In this case the string is used to indicate the  */
  /* nameof the queue we want details about, * indicating all queues.  */
  /*                                                                   */
  /* pPCFInteger points into the message buffer immediately after the  */
  /* string block described above. It is used to map the following     */
  /* bytes onto a PCF integer parameter block. This block indicates    */
  /* the type of queue we wish to receive details about, thereby       */
  /* qualifying the generic search set up by passing the previous      */
  /* string parameter.                                                 */
  /*                                                                   */
  /* Note that this example is a generic search for all attributes of  */
  /* all local queues known to the queue manager. By using different,  */
  /* or more, parameter blocks in the request header it is possible    */
  /* to narrow the search.                                             */
  /* ----------------------------------------------------------------- */
 
  pAdminMsg   = (MQBYTE *)malloc( AdminMsgLen );
 
  pPCFHeader  = (MQCFH *)pAdminMsg;
 
  pPCFString  = (MQCFST *)(pAdminMsg
                          + MQCFH_STRUC_LENGTH
                          );
 
  pPCFInteger = (MQCFIN *)( pAdminMsg
                          + MQCFH_STRUC_LENGTH
                          + MQCFST_STRUC_LENGTH_FIXED + MQ_Q_NAME_LENGTH
                          );
 
 
  /* Set up request header */
  pPCFHeader->Type           = MQCFT_COMMAND;
  pPCFHeader->StrucLength    = MQCFH_STRUC_LENGTH;
  pPCFHeader->Version        = MQCFH_VERSION_1;
  pPCFHeader->Command        = MQCMD_INQUIRE_Q;
  pPCFHeader->MsgSeqNumber   = MQCFC_LAST;
  pPCFHeader->Control        = MQCFC_LAST;
  pPCFHeader->ParameterCount = 2;
 
  /* Set up parameter block */
  pPCFString->Type           = MQCFT_STRING;
  pPCFString->StrucLength    = MQCFST_STRUC_LENGTH_FIXED + MQ_Q_NAME_LENGTH;
  pPCFString->Parameter      = MQCA_Q_NAME;
  pPCFString->CodedCharSetId = MQCCSI_DEFAULT;
  pPCFString->StringLength   = 1;
  memcpy( pPCFString->String, "*", 1 );
 
  /* Set up parameter block */
  pPCFInteger->Type        = MQCFT_INTEGER;
  pPCFInteger->StrucLength = MQCFIN_STRUC_LENGTH;
  pPCFInteger->Parameter   = MQIA_Q_TYPE;
  pPCFInteger->Value       = MQQT_LOCAL;
 
  PutMsg(  hConn                    /* Queue manager handle             */
      ,  MQFMT_ADMIN              /* Format of message                */
      ,  hAdminQ                  /* Handle of command queue          */
      ,  "SAVEQMGR.REPLY.QUEUE\0" /* reply to queue                   */
      ,  (MQBYTE *)pAdminMsg      /* Data part of message to put      */
      ,  AdminMsgLen
        );
 
  free( pAdminMsg );
 
  /* ****************************************************************** */
  /* Get and process the replies received from the command server onto  */
  /* the applications ReplyToQ.                                         */
  /*                                                                    */
  /* There will be one message per defined local queue.                 */
  /*                                                                    */
  /* The last message will have the Control field of the PCF header     */
  /* set to MQCFC_LAST. All others will be MQCFC_NOT_LAST.              */
  /*                                                                    */
  /* An individual Reply message consists of a header followed by a     */
  /* number a parameters, the exact number, type and order will depend  */
  /* upon the type of request.                                          */
  /*                                                                    */
  /* ------------------------------------------------------------------ */
  /*                                                                    */
  /* The message is retrieved into a buffer pointed to by pAdminMsg.    */
  /* This buffer has been allocated enough memory to hold every         */
  /* parameter needed for a local queue definition.                     */
  /*                                                                    */
  /* pPCFHeader is then allocated to point also to the beginning of     */
  /* the buffer and is used to access the PCF header structure. The     */
  /* header contains several fields. The one we are specifically        */
  /* interested in is the ParameterCount. This tells us how many        */
  /* parameters follow the header in the message buffer. There is       */
  /* one parameter for each local queue attribute known by the          */
  /* queue manager.                                                     */
  /*                                                                    */
  /* At this point we do not know the order or type of each parameter   */
  /* block in the buffer, the first MQLONG of each block defines its    */
  /* type; they may be parameter blocks containing either strings or    */
  /* integers.                                                          */
  /*                                                                    */
  /* pPCFType is used initially to point to the first byte beyond the   */
  /* known parameter block. Initially then, it points to the first byte */
  /* after the PCF header. Subsequently it is incremented by the length */
  /* of the identified parameter block and therefore points at the      */
  /* next. Looking at the value of the data pointed to by pPCFType we   */
  /* can decide how to process the next group of bytes, either as a     */
  /* string, or an integer.                                             */
  /*                                                                    */
  /* In this way we parse the message buffer extracting the values of   */
  /* each of the parameters we are interested in.                       */
  /*                                                                    */
  /* ****************************************************************** */
 
  /* AdminMsgLen is to be set to the length of the expected reply       */
  /* message. This structure is specific to Local Queues.               */
  AdminMsgLen =   MQCFH_STRUC_LENGTH
              + ( MQCFST_STRUC_LENGTH_FIXED * 7 )
              + ( MQCFIN_STRUC_LENGTH       * 39 )
              + ( MQ_Q_NAME_LENGTH          * 6  )
              + ( MQ_Q_MGR_NAME_LENGTH      * 2  )
              +   MQ_Q_DESC_LENGTH
              +   MQ_PROCESS_NAME_LENGTH
              +   MQ_CREATION_DATE_LENGTH
              +   MQ_CREATION_TIME_LENGTH
              +   MQ_TRIGGER_DATA_LENGTH + 100
              ;
 
  /* Set pointers to message data buffers */
  pAdminMsg = (MQBYTE *)malloc( AdminMsgLen );
 
  do {
 
     GetMsg(  hConn                      /* Queue manager handle            */
         ,  MQGMO_WAIT
         ,  hReplyQ                    /* Get queue handle                */
         ,  (MQBYTE *)pAdminMsg        /* pointer to message area         */
         ,  AdminMsgLen                /* length of get buffer            */
           );
 
     /* Examine Header */
     pPCFHeader = (MQCFH *)pAdminMsg;
 
     /* Examine first parameter */
     pPCFType = (MQLONG *)(pAdminMsg + MQCFH_STRUC_LENGTH);
 
     Index = 1;
 
     while ( Index <= pPCFHeader->ParameterCount ) {
 
        /* Establish the type of each parameter and allocate  */
        /* a pointer of the correct type to reference it.     */
        switch ( *pPCFType ) {
        case MQCFT_INTEGER:
           pPCFInteger = (MQCFIN *)pPCFType;
           ProcessIntegerParm( pPCFInteger, &DefnLQ );
           Index++;
           /* Increment the pointer to the next parameter by the */
           /* length of the current parm.                        */
           pPCFType = (MQLONG *)( (MQBYTE *)pPCFType
                                + pPCFInteger->StrucLength
                                );
           break;
        case MQCFT_STRING:
           pPCFString = (MQCFST *)pPCFType;
           ProcessStringParm( pPCFString, &DefnLQ );
           Index++;
           /* Increment the pointer to the next parameter by the */
           /* length of the current parm.                        */
           pPCFType = (MQLONG *)( (MQBYTE *)pPCFType
                                + pPCFString->StrucLength
                                );
           break;
        } /* endswitch */
 
     } /* endwhile */
 
     /* ********************************************************* */
     /* Message parsed, append to output file                     */
     /* ********************************************************* */
     AddToFileQLOCAL( DefnLQ );
 
 
     /* ********************************************************* */
     /* Finished processing the current message, do the next one. */
     /* ********************************************************* */
 
  } while ( pPCFHeader->Control == MQCFC_NOT_LAST ); /* enddo */
 
  free( pAdminMsg );
 
  /* *************************************** */
  /* Processing of the local queues complete */
  /* *************************************** */
 
}

void ProcessStringParm( MQCFST *pPCFString, LocalQParms *DefnLQ )
{
   switch ( pPCFString->Parameter ) {
   case MQCA_Q_NAME:
      MQParmCpy( DefnLQ->QName, pPCFString->String, 48 );
      break;
   case MQCA_Q_DESC:
      MQParmCpy( DefnLQ->QDesc, pPCFString->String, 64 );
      break;
   case MQCA_PROCESS_NAME:
      MQParmCpy( DefnLQ->ProcessName, pPCFString->String, 48 );
      break;
   case MQCA_BACKOUT_REQ_Q_NAME:
      MQParmCpy( DefnLQ->BackoutReqQName, pPCFString->String, 48 );
      break;
   case MQCA_CREATION_DATE:
      MQParmCpy( DefnLQ->CreationDate, pPCFString->String, 12 );
      break;
   case MQCA_CREATION_TIME:
      MQParmCpy( DefnLQ->CreationTime, pPCFString->String, 8 );
      break;
   case MQCA_INITIATION_Q_NAME:
      MQParmCpy( DefnLQ->InitiationQName, pPCFString->String, 48 );
      break;
   case MQCA_TRIGGER_DATA:
      MQParmCpy( DefnLQ->TriggerData, pPCFString->String, 64 );
      break;
   } /* endswitch */
}

void ProcessIntegerParm( MQCFIN *pPCFInteger, LocalQParms *DefnLQ )
{
   switch ( pPCFInteger->Parameter ) {
   case MQIA_Q_TYPE:
      DefnLQ->QType = pPCFInteger->Value;
      break;
   case MQIA_INHIBIT_PUT:
      DefnLQ->InhibitPut = pPCFInteger->Value;
      break;
   case MQIA_DEF_PRIORITY:
      DefnLQ->DefPriority = pPCFInteger->Value;
      break;
   case MQIA_DEF_PERSISTENCE:
      DefnLQ->DefPersistence = pPCFInteger->Value;
      break;
   case MQIA_INHIBIT_GET:
      DefnLQ->InhibitGet = pPCFInteger->Value;
      break;
   case MQIA_SCOPE:
      DefnLQ->Scope = pPCFInteger->Value;
      break;
   case MQIA_MAX_Q_DEPTH:
      DefnLQ->MaxQDepth = pPCFInteger->Value;
      break;
   case MQIA_MAX_MSG_LENGTH:
      DefnLQ->MaxMsgLength = pPCFInteger->Value;
      break;
   case MQIA_BACKOUT_THRESHOLD:
      DefnLQ->BackoutThreshold = pPCFInteger->Value;
      break;
   case MQIA_SHAREABILITY:
      DefnLQ->Shareability = pPCFInteger->Value;
      break;
   case MQIA_DEF_INPUT_OPEN_OPTION:
      DefnLQ->DefInputOpenOption = pPCFInteger->Value;
      break;
   case MQIA_HARDEN_GET_BACKOUT:
      DefnLQ->HardenGetBackout = pPCFInteger->Value;
      break;
   case MQIA_MSG_DELIVERY_SEQUENCE:
      DefnLQ->MsgDeliverySequence = pPCFInteger->Value;
      break;
   case MQIA_RETENTION_INTERVAL:
      DefnLQ->RetentionInterval = pPCFInteger->Value;
      break;
   case MQIA_DEFINITION_TYPE:
      DefnLQ->DefinitionType = pPCFInteger->Value;
      break;
   case MQIA_USAGE:
      DefnLQ->Usage = pPCFInteger->Value;
      break;
   case MQIA_OPEN_INPUT_COUNT:
      DefnLQ->OpenInputCount = pPCFInteger->Value;
      break;
   case MQIA_OPEN_OUTPUT_COUNT:
      DefnLQ->OpenOutputCount = pPCFInteger->Value;
      break;
   case MQIA_CURRENT_Q_DEPTH:
      DefnLQ->CurrentQDepth = pPCFInteger->Value;
      break;
   case MQIA_TRIGGER_CONTROL:
      DefnLQ->TriggerControl = pPCFInteger->Value;
      break;
   case MQIA_TRIGGER_TYPE:
      DefnLQ->TriggerType = pPCFInteger->Value;
      break;
   case MQIA_TRIGGER_MSG_PRIORITY:
      DefnLQ->TriggerMsgPriority = pPCFInteger->Value;
      break;
   case MQIA_TRIGGER_DEPTH:
      DefnLQ->TriggerDepth = pPCFInteger->Value;
      break;
   case MQIA_Q_DEPTH_HIGH_LIMIT:
      DefnLQ->QDepthHighLimit = pPCFInteger->Value;
      break;
   case MQIA_Q_DEPTH_LOW_LIMIT:
      DefnLQ->QDepthLowLimit = pPCFInteger->Value;
      break;
   case MQIA_Q_DEPTH_MAX_EVENT:
      DefnLQ->QDepthMaxEvent = pPCFInteger->Value;
      break;
   case MQIA_Q_DEPTH_HIGH_EVENT:
      DefnLQ->QDepthHighEvent = pPCFInteger->Value;
      break;
   case MQIA_Q_DEPTH_LOW_EVENT:
      DefnLQ->QDepthLowEvent = pPCFInteger->Value;
      break;
   case MQIA_Q_SERVICE_INTERVAL:
      DefnLQ->QServiceInterval = pPCFInteger->Value;
      break;
   case MQIA_Q_SERVICE_INTERVAL_EVENT:
      DefnLQ->QServiceIntervalEvent = pPCFInteger->Value;
      break;
   } /* endswitch */
}

/* ------------------------------------------------------------------------ */
/*                                                                          */
/* This process takes the attributes of a single local queue and adds them  */
/* to the end of a file, SAVEQMGR.TST, which can be found in the current    */
/* directory.                                                               */
/*                                                                          */
/* The file is of a format suitable for subsequent input to RUNMQSC.        */
/*                                                                          */
/* ------------------------------------------------------------------------ */
void AddToFileQLOCAL( LocalQParms DefnLQ )
{
   char    ParmBuffer[120];   /* Temporary buffer to hold for output to file */
   FILE   *fp;                /* Pointer to a file                           */
 
   /* Append these details to the end of the current SAVEQMGR.TST file */
   fp = fopen( "SAVEQMGR.TST", "a" );
 
   sprintf( ParmBuffer, "DEFINE QLOCAL ('%s') REPLACE +\n", DefnLQ.QName );
   fputs( ParmBuffer, fp );
 
   sprintf( ParmBuffer, "       DESCR('%s') +\n", DefnLQ.QDesc );
   fputs( ParmBuffer, fp );
 
   if ( DefnLQ.InhibitPut == MQQA_PUT_ALLOWED ) {
      sprintf( ParmBuffer, "       PUT(ENABLED) +\n" );
      fputs( ParmBuffer, fp );
   } else {
      sprintf( ParmBuffer, "       PUT(DISABLED) +\n" );
      fputs( ParmBuffer, fp );
   } /* endif */
 
   sprintf( ParmBuffer, "       DEFPRTY(%d) +\n", DefnLQ.DefPriority );
   fputs( ParmBuffer, fp );
 
   if ( DefnLQ.DefPersistence == MQPER_PERSISTENT ) {
      sprintf( ParmBuffer, "       DEFPSIST(YES) +\n" );
      fputs( ParmBuffer, fp );
   } else {
      sprintf( ParmBuffer, "       DEFPSIST(NO) +\n" );
      fputs( ParmBuffer, fp );
   } /* endif */
 
   if ( DefnLQ.InhibitGet == MQQA_GET_ALLOWED ) {
      sprintf( ParmBuffer, "       GET(ENABLED) +\n" );
      fputs( ParmBuffer, fp );
   } else {
      sprintf( ParmBuffer, "       GET(DISABLED) +\n" );
      fputs( ParmBuffer, fp );
   } /* endif */
 
   sprintf( ParmBuffer, "       MAXDEPTH(%d) +\n", DefnLQ.MaxQDepth );
   fputs( ParmBuffer, fp );
 
   sprintf( ParmBuffer, "       MAXMSGL(%d) +\n", DefnLQ.MaxMsgLength );
   fputs( ParmBuffer, fp );
 
   if ( DefnLQ.Shareability == MQQA_SHAREABLE ) {
      sprintf( ParmBuffer, "       SHARE +\n" );
      fputs( ParmBuffer, fp );
   } else {
      sprintf( ParmBuffer, "       NOSHARE +\n" );
      fputs( ParmBuffer, fp );
   } /* endif */
 
   if ( DefnLQ.DefInputOpenOption == MQOO_INPUT_SHARED ) {
      sprintf( ParmBuffer, "       DEFSOPT(SHARED) +\n" );
      fputs( ParmBuffer, fp );
   } else {
      sprintf( ParmBuffer, "       DEFSOPT(EXCL) +\n" );
      fputs( ParmBuffer, fp );
   } /* endif */
 
   if ( DefnLQ.MsgDeliverySequence == MQMDS_PRIORITY ) {
      sprintf( ParmBuffer, "       MSGDLVSQ(PRIORITY) +\n" );
      fputs( ParmBuffer, fp );
   } else {
      sprintf( ParmBuffer, "       MSGDLVSQ(FIFO) +\n" );
      fputs( ParmBuffer, fp );
   } /* endif */
 
   if ( DefnLQ.HardenGetBackout == MQQA_BACKOUT_HARDENED ) {
      sprintf( ParmBuffer, "       HARDENBO +\n" );
      fputs( ParmBuffer, fp );
   } else {
      sprintf( ParmBuffer, "       NOHARDENBO +\n" );
      fputs( ParmBuffer, fp );
   } /* endif */
 
   if ( DefnLQ.Usage == MQUS_NORMAL ) {
      sprintf( ParmBuffer, "       USAGE(NORMAL) +\n" );
      fputs( ParmBuffer, fp );
   } else {
      sprintf( ParmBuffer, "       USAGE(XMIT) +\n" );
      fputs( ParmBuffer, fp );
   } /* endif */
 
   if ( DefnLQ.TriggerControl == MQTC_OFF ) {
      sprintf( ParmBuffer, "       NOTRIGGER +\n" );
      fputs( ParmBuffer, fp );
   } else {
      sprintf( ParmBuffer, "       TRIGGER +\n" );
      fputs( ParmBuffer, fp );
   } /* endif */
 
   switch ( DefnLQ.TriggerType ) {
   case MQTT_NONE:
      sprintf( ParmBuffer, "       TRIGTYPE(NONE) +\n" );
      fputs( ParmBuffer, fp );
      break;
   case MQTT_FIRST:
      sprintf( ParmBuffer, "       TRIGTYPE(FIRST) +\n" );
      fputs( ParmBuffer, fp );
      break;
   case MQTT_EVERY:
      sprintf( ParmBuffer, "       TRIGTYPE(EVERY) +\n" );
      fputs( ParmBuffer, fp );
      break;
   case MQTT_DEPTH:
      sprintf( ParmBuffer, "       TRIGTYPE(DEPTH) +\n" );
      fputs( ParmBuffer, fp );
      break;
   } /* endswitch */
 
   sprintf( ParmBuffer, "       TRIGDPTH(%d) +\n", DefnLQ.TriggerDepth );
   fputs( ParmBuffer, fp );
 
   sprintf( ParmBuffer, "       TRIGMPRI(%d) +\n", DefnLQ.TriggerMsgPriority);
   fputs( ParmBuffer, fp );
 
   sprintf( ParmBuffer, "       TRIGDATA('%s') +\n", DefnLQ.TriggerData );
   fputs( ParmBuffer, fp );
 
   sprintf( ParmBuffer, "       PROCESS('%s') +\n", DefnLQ.ProcessName );
   fputs( ParmBuffer, fp );
 
   sprintf( ParmBuffer, "       INITQ('%s') +\n", DefnLQ.InitiationQName );
   fputs( ParmBuffer, fp );
 
 
   sprintf( ParmBuffer, "       RETINTVL(%d) +\n", DefnLQ.RetentionInterval );
   fputs( ParmBuffer, fp );
 
   sprintf( ParmBuffer, "       BOTHRESH(%d) +\n", DefnLQ.BackoutThreshold );
   fputs( ParmBuffer, fp );
 
   sprintf( ParmBuffer, "       BOQNAME('%s') +\n", DefnLQ.BackoutReqQName );
   fputs( ParmBuffer, fp );
 
   if ( DefnLQ.Scope == MQSCO_Q_MGR ) {
      sprintf( ParmBuffer, "       SCOPE(QMGR) +\n" );
      fputs( ParmBuffer, fp );
   } else {
      sprintf( ParmBuffer, "       SCOPE(CELL) +\n" );
      fputs( ParmBuffer, fp );
   } /* endif */
 
   sprintf( ParmBuffer, "       QDEPTHHI(%d) +\n", DefnLQ.QDepthHighLimit );
   fputs( ParmBuffer, fp );
 
   sprintf( ParmBuffer, "       QDEPTHLO(%d) +\n", DefnLQ.QDepthLowLimit );
   fputs( ParmBuffer, fp );
 
   if ( DefnLQ.QDepthMaxEvent == MQEVR_ENABLED ) {
      sprintf( ParmBuffer, "       QDPMAXEV(ENABLED) +\n" );
      fputs( ParmBuffer, fp );
   } else {
      sprintf( ParmBuffer, "       QDPMAXEV(DISABLED) +\n" );
      fputs( ParmBuffer, fp );
   } /* endif */
 
   if ( DefnLQ.QDepthHighEvent == MQEVR_ENABLED ) {
      sprintf( ParmBuffer, "       QDPHIEV(ENABLED) +\n" );
      fputs( ParmBuffer, fp );
   } else {
      sprintf( ParmBuffer, "       QDPHIEV(DISABLED) +\n" );
      fputs( ParmBuffer, fp );
   } /* endif */
 
   if ( DefnLQ.QDepthLowEvent == MQEVR_ENABLED ) {
      sprintf( ParmBuffer, "       QDPLOEV(ENABLED) +\n" );
      fputs( ParmBuffer, fp );
   } else {
      sprintf( ParmBuffer, "       QDPLOEV(DISABLED) +\n" );
      fputs( ParmBuffer, fp );
   } /* endif */
 
   sprintf( ParmBuffer, "       QSVCINT(%d) +\n", DefnLQ.QServiceInterval );
   fputs( ParmBuffer, fp );
 
   switch ( DefnLQ.QServiceIntervalEvent ) {
   case MQQSIE_OK:
      sprintf( ParmBuffer, "       QSVCIEV(OK)\n" );
      fputs( ParmBuffer, fp );
      break;
   case MQQSIE_NONE:
      sprintf( ParmBuffer, "       QSVCIEV(NONE)\n" );
      fputs( ParmBuffer, fp );
      break;
   case MQQSIE_HIGH:
      sprintf( ParmBuffer, "       QSVCIEV(HIGH)\n" );
      fputs( ParmBuffer, fp );
      break;
   } /* endswitch */
 
   sprintf( ParmBuffer, "\n" );
   fputs( ParmBuffer, fp );
 
   fclose(fp);
 
}

/* ------------------------------------------------------------------------ */
/*                                                                          */
/* The queue manager returns strings of the maximum length for each         */
/* specific parameter, padded with blanks.                                  */
/*                                                                          */
/* We are interested in only the nonblank characters so will extract them   */
/* from the message buffer, and terminate the string with a null, \0.       */
/*                                                                          */
/* ------------------------------------------------------------------------ */
void MQParmCpy( char *target, char *source, int length )
{
   int   counter=0;
 
   while ( counter < length && source[counter] != ' ' ) {
      target[counter] = source[counter];
      counter++;
   } /* endwhile */
 
   if ( counter < length) {
      target[counter] = '\0';
   } /* endif */
}

MQHOBJ OpenQ( MQHCONN hConn, MQCHAR48 QName, MQLONG OpenOpts)
{
   MQHOBJ Hobj;
   MQLONG CompCode, Reason;

   ObjDesc.ObjectType = MQOT_Q;
   strncpy(ObjDesc.ObjectName, QName, MQ_Q_NAME_LENGTH);
   
   MQOPEN(hConn,     /* connection handle                       */
          &ObjDesc,  /* object descriptor for queue             */
          OpenOpts,  /* open options                            */
          &Hobj,     /* object handle                           */
          &CompCode, /* MQOPEN completion code                  */
          &Reason);  /* reason code                             */

   /* report reason, if any; stop if failed                     */
   if (Reason != MQRC_NONE)
   {
     printf("MQOPEN for %s ended with Reason Code %d and Comp Code %d\n",
						QName,
						Reason,
						CompCode);
     exit( -1 );
   }

   return Hobj;
}

void PutMsg(MQHCONN hConn,
						MQCHAR8 MsgFormat,
						MQHOBJ hQName,
						MQCHAR48 QName,
						MQBYTE *UserMsg,
						MQLONG UserMsgLen)
{
   MQLONG CompCode, Reason;

   /* set up the message descriptor prior to putting the message */
   md.Report         = MQRO_NONE;         
   md.MsgType        = MQMT_REQUEST;                        
   md.Expiry         = MQEI_UNLIMITED;
   md.Feedback       = MQFB_NONE;                          
   md.Encoding       = MQENC_NATIVE;
   md.Priority       = MQPRI_PRIORITY_AS_Q_DEF;
   md.Persistence    = MQPER_PERSISTENCE_AS_Q_DEF;
   md.MsgSeqNumber   = 1;                              
   md.Offset         = 0;                                     
   md.MsgFlags       = MQMF_NONE;                          
   md.OriginalLength = MQOL_UNDEFINED;               

   memcpy(md.GroupId,  MQGI_NONE, sizeof(md.GroupId));
   memcpy(md.Format,   MsgFormat, sizeof(md.Format) );
   memcpy(md.ReplyToQ, QName,     sizeof(md.ReplyToQ) );

   /* reset MsgId and CorrelId to get a new one                 */
   memcpy(md.MsgId,    MQMI_NONE, sizeof(md.MsgId) );
   memcpy(md.CorrelId, MQCI_NONE, sizeof(md.CorrelId) );

   MQPUT(hConn,             /* connection handle                */
         hQName,            /* object handle                    */
         &md,               /* message descriptor               */
         &pmo,              /* default options                  */
         UserMsgLen,        /* message length                   */
         (MQBYTE *)UserMsg, /* message buffer                   */
         &CompCode,         /* completion code                  */
         &Reason);          /* reason code                      */

   if (Reason != MQRC_NONE) {
      printf("MQPUT ended with with Reason Code %d and Comp Code %d\n",
							Reason, CompCode);
      exit( -1 );
   }
}

void GetMsg(MQHCONN hConn, MQLONG MQParm, MQHOBJ hQName,
						MQBYTE *UserMsg, MQLONG ReadBufferLen)
{
   MQLONG CompCode, Reason, msglen;

   gmo.Options      = MQParm;
   gmo.WaitInterval = 15000;

   /* reset MsgId and CorrelId to get a new one                 */
   memcpy(md.MsgId,    MQMI_NONE, sizeof(md.MsgId) );
   memcpy(md.CorrelId, MQCI_NONE, sizeof(md.CorrelId) );

   MQGET(hConn,             /* connection handle                */
         hQName,            /* object handle                    */
         &md,               /* message descriptor               */
         &gmo,              /* get message options              */
         ReadBufferLen,     /* Buffer length                    */
         (MQBYTE *)UserMsg, /* message buffer                   */
         &msglen,           /* message length                   */
         &CompCode,         /* completion code                  */
         &Reason);          /* reason code                      */

   if (Reason != MQRC_NONE) {
      printf("MQGET ended with Reason Code %d and Comp Code %d\n",
							Reason, CompCode);
      exit( -1 );
}
}
Parent topic: Programmable command formats reference

Last updated: 2020-10-04