/***************************************************************************/ /* */ /* (c) Copyright IBM Corp. 2004 All rights reserved. */ /* */ /* This sample program is owned by International Business Machines */ /* Corporation or one of its subsidiaries ("IBM") and is copyrighted */ /* and licensed, not sold. */ /* */ /* You may copy, modify, and distribute this sample program in any */ /* form without payment to IBM, for any purpose including developing, */ /* using, marketing or distributing programs that include or are */ /* derivative works of the sample program. */ /* */ /* The sample program is provided to you on an "AS IS" basis, without */ /* warranty of any kind. IBM HEREBY EXPRESSLY DISCLAIMS ALL WARRANTIES, */ /* EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ /* Some jurisdictions do not allow for the exclusion or limitation of */ /* implied warranties, so the above limitations or exclusions may not */ /* apply to you. IBM shall not be liable for any damages you suffer as */ /* a result of using, modifying or distributing the sample program or */ /* its derivatives. */ /* */ /* Each copy of any portion of this sample program or any derivative */ /* work, must include a the above copyright notice and disclaimer of */ /* warranty. */ /* */ /***************************************************************************/ /* */ /* Program name: getgroup */ /* */ /* Description: Sample C program that gets messages in a group */ /* from a message queue using MQGET */ /* */ /***************************************************************************/ /* */ /* Function: */ /* */ /* This program is a modified version of the AMQSGET0.C program. */ /* It has been changed to check for messages being part of a group. */ /* If they are, the program will get all messages in a group before */ /* getting any more messages. */ /* */ /***************************************************************************/ /* */ /* For a detailed description of what this program does, please refer */ /* to the original source for AMQSGET0.C. */ /* */ /***************************************************************************/ /* */ /* getgroup has 2 parameters - */ /* - the name of the message queue (required) */ /* - the queue manager name (optional) */ /* */ /***************************************************************************/ #include #include #include #include /* includes for MQI */ int main(int argc, char **argv) { /* Declare MQI structures needed */ MQOD od = {MQOD_DEFAULT}; /* Object Descriptor */ MQMD md = {MQMD_DEFAULT}; /* Message Descriptor */ MQGMO gmo = {MQGMO_DEFAULT}; /* get message options */ /** note, sample uses defaults where it can **/ MQHCONN Hcon; /* connection handle */ MQHOBJ Hobj; /* object handle */ MQLONG O_options; /* MQOPEN options */ MQLONG C_options; /* MQCLOSE options */ MQLONG CompCode; /* completion code */ MQLONG CC2; /* completion code for groups */ MQLONG OpenCode; /* MQOPEN completion code */ MQLONG Reason; /* reason code */ MQLONG CReason; /* reason code for MQCONN */ MQBYTE buffer[1001]; /* message buffer */ MQLONG buflen; /* buffer length */ MQLONG messlen; /* message length received */ char QMName[50]; /* queue manager name */ printf("Sample GETGROUP start\n"); if (argc < 2) { printf("Required parameter missing - queue name\n"); exit(99); } /******************************************************************/ /* Create object descriptor for subject queue */ /******************************************************************/ strcpy(od.ObjectName, argv[1]); QMName[0] = 0; /* default */ if (argc > 2) { strcpy(QMName, argv[2]); } /******************************************************************/ /* Connect to queue manager */ /******************************************************************/ MQCONN(QMName, &Hcon, &CompCode, &CReason); /* report reason and stop if it failed */ if (CompCode == MQCC_FAILED) { printf("MQCONN ended with reason code %ld\n", CReason); exit( (int)CReason ); } /******************************************************************/ /* Open the named message queue for input; exclusive or shared */ /* use of the queue is controlled by the queue definition here */ /******************************************************************/ O_options = MQOO_INPUT_AS_Q_DEF /* open queue for input */ + MQOO_FAIL_IF_QUIESCING; /* but not if MQM stopping */ MQOPEN(Hcon, &od, O_options, &Hobj, &OpenCode, &Reason); /* report reason, if any; stop if failed */ if (Reason != MQRC_NONE) { printf("MQOPEN ended with reason code %ld\n", Reason); } if (OpenCode == MQCC_FAILED) { printf("unable to open queue for input\n"); } /******************************************************************/ /* Get messages from the message queue */ /* Loop until there is a failure */ /******************************************************************/ CompCode = OpenCode; /* use MQOPEN result for initial test */ while (CompCode != MQCC_FAILED) { buflen = sizeof(buffer) - 1; /* buffer size available for GET */ gmo.Options = MQGMO_WAIT /* wait for new messages */ + MQGMO_CONVERT;/* convert if necessary */ gmo.WaitInterval = 15000; /* 15 second limit for waiting */ /**************************************************************/ /* In order to read the messages in sequence, MsgId, CorrelId,*/ /* and GroupId must have the default value. MQGET sets them */ /* to the values in the message it returns, so re-initialise */ /* them before every call. */ /**************************************************************/ memcpy(md.MsgId, MQMI_NONE, sizeof(md.MsgId)); memcpy(md.CorrelId, MQCI_NONE, sizeof(md.CorrelId)); memcpy(md.GroupId, MQCI_NONE, sizeof(md.GroupId)); /**************************************************************/ /* MQGET sets Encoding and CodedCharSetId to the values in */ /* the message returned, so these fields should be reset to */ /* the default values before every call, as MQGMO_CONVERT is */ /* specified. */ /**************************************************************/ md.Encoding = MQENC_NATIVE; md.CodedCharSetId = MQCCSI_Q_MGR; md.Version = MQMD_VERSION_2; gmo.Version = MQGMO_VERSION_2; gmo.MatchOptions = MQMO_NONE; MQGET(Hcon, Hobj, &md, &gmo, buflen, buffer, &messlen, &CompCode, &Reason); /* report reason, if any */ if (Reason != MQRC_NONE) { if (Reason == MQRC_NO_MSG_AVAILABLE) { printf("no more messages\n"); } else { printf("MQGET ended with reason code %ld\n", Reason); if (Reason == MQRC_TRUNCATED_MSG_FAILED) { CompCode = MQCC_FAILED; } } } if (CompCode != MQCC_FAILED) { buffer[messlen] = '\0'; /* add terminator */ /************************************************************/ /* Got message successfully. Test the MsgFlags to see if */ /* the message is part of a group. If it is, go into */ /* another MQGET loop to get all of the group's messages. */ /* If it is not part of a group, display the message. */ /************************************************************/ if (md.MsgFlags && MQMF_MSG_IN_GROUP) { /******************************************************/ /* To check message, display the GroupId (not 100% */ /* displayable), GroupStatus, MsgSeqNumber, MsgFlags, */ /* and message data. */ /******************************************************/ printf("GroupId <%-24.24s> ", md.GroupId); printf(" gmo.GroupStatus <%c>\n", gmo.GroupStatus); printf(" 1st msg seq <%d> MsgFlags <%08x> size<%2d> <%s>\n", md.MsgSeqNumber, md.MsgFlags, messlen, buffer); /**********************************************************/ /* Go through the message queue looking for the rest of */ /* the messages with this GroupId by setting the correct */ /* MatchOptions. */ /**********************************************************/ CC2 = MQCC_OK; while (CC2 != MQCC_FAILED) { gmo.MatchOptions = MQMO_MATCH_GROUP_ID; gmo.WaitInterval = 1000; /* 1 second, message should be here */ MQGET(Hcon, Hobj, &md, &gmo, buflen, buffer, &messlen, &CC2, &Reason); /* report reason, if any */ if (Reason != MQRC_NONE) { if (Reason == MQRC_NO_MSG_AVAILABLE) { printf(" no more messages in group\n"); } else { printf("MQGET ended with reason code %ld\n", Reason); if (Reason == MQRC_TRUNCATED_MSG_FAILED) { CC2 = MQCC_FAILED; } } } if (CC2 != MQCC_FAILED) { buffer[messlen] = '\0'; /* add terminator */ printf(" Next msg seq <%d> MsgFlags <%08x> size<%2d> <%s>\n", md.MsgSeqNumber, md.MsgFlags, messlen, buffer); } } /* end of getting msgs in group */ } else { /* Message was not part of a group */ printf("Message not in Group "); printf(" gmo.GroupStatus <%c>\n", gmo.GroupStatus); printf(" Message Data <%d> MsgFlags <%08x> size<%2d> <%s>\n", md.MsgSeqNumber, md.MsgFlags, messlen, buffer); } /* end of test for a group message */ } /* end of test for MQGET failing */ } /* end of loop for MQGETing any message */ /******************************************************************/ /* Close the source queue (if it was opened) */ /******************************************************************/ if (OpenCode != MQCC_FAILED) { C_options = 0; /* no close options */ MQCLOSE(Hcon, &Hobj, C_options, &CompCode, &Reason); /* report reason, if any */ if (Reason != MQRC_NONE) { printf("MQCLOSE ended with reason code %ld\n", Reason); } } /******************************************************************/ /* Disconnect from MQM if not already connected */ /******************************************************************/ if (CReason != MQRC_ALREADY_CONNECTED ) { MQDISC(&Hcon, &CompCode, &Reason); /* report reason, if any */ if (Reason != MQRC_NONE) { printf("MQDISC ended with reason code %ld\n", Reason); } } /******************************************************************/ /* END OF GETGROUP */ /******************************************************************/ printf("Sample GETGROUP end\n"); return(0); }