/***************************************************************************/ /* */ /* (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 the above copyright notice and disclaimer of */ /* warranty. */ /* */ /***************************************************************************/ /* */ /* Program name: sunloadmq */ /* */ /* Description: Sample C program that gets messages from */ /* a message queue (example using MQGET) */ /* by loading the WebSphere MQ shared libraries */ /* */ /***************************************************************************/ /* */ /* Function: */ /* */ /* This program is a modified version of the AMQSGET0.C program */ /* that comes with the WebSphere MQ product. It has been */ /* changed to use the dlopen and dlsym calls to dynamically */ /* load the WebSphere MQ libraries and its entry points. */ /* */ /* This program is built with the following command line: */ /* */ /* cc -o sunloadmq sunloadmq.c -mt -ldl */ /* */ /***************************************************************************/ /* */ /* For a detailed description of what this program does, please refer */ /* to the original source for AMQSGET0.C. */ /* */ /***************************************************************************/ /* */ /* sunloadmq has 2 parameters - */ /* - the name of the message queue (required) */ /* - the queue manager name (optional) */ /* */ /***************************************************************************/ #include #include #include #include /* Required for dlopen */ #include 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 OpenCode; /* MQOPEN completion code */ MQLONG Reason; /* reason code */ MQLONG CReason; /* reason code for MQCONN */ MQBYTE buffer[101]; /* message buffer */ MQLONG buflen; /* buffer length */ MQLONG messlen; /* message length received */ char QMName[50]; /* queue manager name */ /************************************************************/ /* The next set of variables will be used to get the shared */ /* library and the entry points into the shared library. */ /************************************************************/ char dlLib[50]; /* name of the WebSphere MQ library to load */ int rc; void *so1; void *so2; void *so; void (*sconn)(char *, MQHCONN *, MQLONG *, MQLONG *); void (*sopen)(MQHCONN, MQOD *, MQLONG, MQHOBJ *, MQLONG *, MQLONG *); void (*sget) (MQHCONN, MQHOBJ, MQMD *, MQGMO *, MQLONG, MQBYTE *, MQLONG *, MQLONG *, MQLONG *); void (*sclose)(MQHCONN, MQHOBJ *, MQLONG, MQLONG *, MQLONG *); void (*sdisc)(MQLONG *, MQLONG *, MQLONG *); /************************************************************/ /* End of the shared library variables. */ /************************************************************/ printf("Sample sunloadmq 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]); } /*****************************************************************/ /* The program will load the WMQ shared libraries. If there is */ /* an error, the program will indicate which library failed to */ /* load and the dlopen error. If all WebSphere MQ libraries are */ /* found, the MQ API entry points will be loaded using dlsym. */ /*****************************************************************/ strcpy(dlLib, "libmqmzse.so"); if ((so1 = dlopen(dlLib, RTLD_NOW | RTLD_GLOBAL)) == NULL) { printf("dlLib=%s failed to load.\n", dlLib); printf(" dlopen: %s\n", dlerror()); printf(" Program exiting.\n"); exit(0); } strcpy(dlLib, "libmqmcs.so"); if ((so2 = dlopen(dlLib, RTLD_NOW | RTLD_GLOBAL)) == NULL) { printf("dlLib=%s failed to load.\n", dlLib); printf(" dlopen: %s\n", dlerror()); printf(" Program exiting.\n"); exit(0); } strcpy(dlLib, "libmqm.so"); if ((so = dlopen(dlLib, RTLD_NOW | RTLD_GLOBAL)) == NULL) { printf("dlLib=%s failed to load.\n", dlLib); printf(" dlopen: %s\n", dlerror()); printf(" Program exiting.\n"); exit(0); } else { /*********************************************************************/ /* We found the WebSphere MQ libraries. Now, we will load the entry */ /* points of the functions that we are interested in. */ /* If we can't load an entry point that we are interested in, */ /* we'll print an error and exit. */ /*********************************************************************/ sconn = (void(*)(char *, MQHCONN *, MQLONG *, MQLONG *))dlsym(so, "MQCONN"); if (!sconn) { printf("sconn call failed.\n"); exit(0); } else { printf("sconn symbol resolved\n"); } sopen = (void(*)(MQHCONN, MQOD *, MQLONG, MQHOBJ *, MQLONG *, MQLONG *))dlsym(so, "MQOPEN"); if (!sopen) { printf("sopen call failed.\n"); exit(0); } else { printf("sopen symbol resolved\n"); } sget = (void(*)(MQHCONN, MQHOBJ, MQMD *, MQGMO *, MQLONG, MQBYTE *, MQLONG *, MQLONG *, MQLONG *))dlsym(so, "MQGET"); if (!sget) { printf("sget call failed.\n"); exit(0); } else { printf("sget symbol resolved\n"); } sclose = (void(*)(MQHCONN, MQHOBJ *, MQLONG, MQLONG *, MQLONG *))dlsym(so, "MQCLOSE"); if (!sclose) { printf("sclose call failed.\n"); exit(0); } else { printf("sclose symbol resolved\n"); } sdisc = (void(*)(MQLONG *, MQLONG *, MQLONG *))dlsym(so, "MQDISC"); if (!sdisc) { printf("sdisc call failed.\n"); exit(0); } else { printf("sdisc symbol resolved\n"); } } /************************************************************/ /* End of the shared library/entry point loading. */ /************************************************************/ /******************************************************************/ /* From here to the end, this program has the same logic as the */ /* original AMQSGET0.C sample. The only difference is that it */ /* will use the entry points that it loaded rather than the */ /* entry points that are normally linked into the program. */ /* In other words, sconn instead of MQCONN. */ /******************************************************************/ /******************************************************************/ /* Connect to queue manager */ /******************************************************************/ sconn(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 */ sopen(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 and */ /* CorrelID must have the default value. MQGET sets them */ /* to the values in for 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)); /****************************************************************/ /* */ /* 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; sget(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; } } } /****************************************************************/ /* Display each message received */ /****************************************************************/ if (CompCode != MQCC_FAILED) { buffer[messlen] = '\0'; /* add terminator */ printf("message <%s>\n", buffer); } } /******************************************************************/ /* Close the source queue (if it was opened) */ /******************************************************************/ if (OpenCode != MQCC_FAILED) { C_options = 0; /* no close options */ sclose(Hcon, &Hobj, C_options, &CompCode, &Reason); 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 ) { sdisc(&Hcon, &CompCode, &Reason); if (Reason != MQRC_NONE) { printf("MQDISC ended with reason code %ld\n", Reason); } } printf("Sample sunloadmq end.\n"); return(0); }