demo/c/socket/LogRedirect.c

Go to the documentation of this file.
00001 /*----------------------------------------------------------------------------
00002 Name:      xmlBlaster/demo/c/socket/LogRedirect.c
00003 Project:   xmlBlaster.org
00004 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
00005 Comment:   Tests redirect of logging
00006 Author:    "Marcel Ruff" <xmlBlaster@marcelruff.info>
00007 Compile:
00008   Linux with libxmlBlasterC.so:
00009           gcc  -D_REENTRANT -Wall -o LogRedirect LogRedirect.c -I../../../src/c
00010                 -L../../../lib -lxmlBlasterClientC -Wl,-rpath=../../../lib -lpthread
00011 See:      http://www.xmlblaster.org/xmlBlaster/doc/requirements/client.c.socket.html
00012 -----------------------------------------------------------------------------*/
00013 #include <stdio.h>
00014 #include <stdlib.h>
00015 #include <string.h>
00016 #include <stdarg.h>
00017 #include <ctype.h>
00018 #include <XmlBlasterAccessUnparsed.h>
00019 
00020 static void myLogger(void *logUserP, 
00021                      XMLBLASTER_LOG_LEVEL currLevel,
00022                      XMLBLASTER_LOG_LEVEL level,
00023                      const char *location, const char *fmt, ...);
00024 static bool myUpdate(MsgUnitArr *msgUnitArr, void *userData,
00025                      XmlBlasterException *xmlBlasterException);
00026 
00030 int main(int argc, char** argv)
00031 {
00032    int iarg;
00033    char *response = (char *)0;
00034    char connectQos[2048];
00035    XmlBlasterException xmlBlasterException;
00036    XmlBlasterAccessUnparsed *xa = 0;
00037 
00038    printf("[client] Try option '-help' if you need usage informations\n");
00039 
00040    for (iarg=0; iarg < argc; iarg++) {
00041       if (strcmp(argv[iarg], "-help") == 0 || strcmp(argv[iarg], "--help") == 0) {
00042          char usage[XMLBLASTER_MAX_USAGE_LEN];
00043          const char *pp =
00044          "\n  -logLevel            ERROR | WARN | INFO | TRACE [WARN]"
00045          "\n\nExample:"
00046          "\n  LogRedirect -logLevel TRACE"
00047                " -dispatch/connection/plugin/socket/hostname server.mars.universe";
00048          printf("Usage:\nXmlBlaster C SOCKET client %s\n%s%s\n",
00049                   getXmlBlasterVersion(), xmlBlasterAccessUnparsedUsage(usage), pp);
00050          exit(EXIT_FAILURE);
00051       }
00052    }
00053 
00054    xa = getXmlBlasterAccessUnparsed(argc, (const char* const*)argv);
00055 
00056    /* Register our own logging function */
00057    xa->log = myLogger;
00058    /* Optionally pass a pointer which we can use in myLogger again */
00059    xa->logUserP = xa;
00060 
00061    /* connect */
00062    sprintf(connectQos,
00063             "<qos>"
00064             " <securityService type='htpasswd' version='1.0'>"
00065             "  <![CDATA["
00066             "   <user>fritz</user>"
00067             "   <passwd>secret</passwd>"
00068             "  ]]>"
00069             " </securityService>"
00070             "</qos>");
00071 
00072    response = xa->connect(xa, connectQos, myUpdate, &xmlBlasterException);
00073    if (*xmlBlasterException.errorCode != 0) {
00074       printf("[client] Caught exception during connect errorCode=%s, message=%s\n",
00075                xmlBlasterException.errorCode, xmlBlasterException.message);
00076       freeXmlBlasterAccessUnparsed(xa);
00077       exit(EXIT_FAILURE);
00078    }
00079    xmlBlasterFree(response);
00080    printf("[client] Connected to xmlBlaster, do some tests ...\n");
00081 
00082    /* ping */
00083    response = xa->ping(xa, 0, &xmlBlasterException);
00084    if (response == (char *)0) {
00085       printf("[client] ERROR: Pinging a connected server failed: errorCode=%s, message=%s\n",
00086              xmlBlasterException.errorCode, xmlBlasterException.message);
00087       freeXmlBlasterAccessUnparsed(xa);
00088       exit(EXIT_FAILURE);
00089    }
00090    else {
00091       printf("[client] Pinging a connected server, response=%s\n", response);
00092       xmlBlasterFree(response);
00093    }
00094 
00095    /* disconnect */
00096    if (xa->disconnect(xa, 0, &xmlBlasterException) == false) {
00097       printf("[client] Caught exception in disconnect, errorCode=%s, message=%s\n",
00098                xmlBlasterException.errorCode, xmlBlasterException.message);
00099       freeXmlBlasterAccessUnparsed(xa);
00100       exit(EXIT_FAILURE);
00101    }
00102 
00103    freeXmlBlasterAccessUnparsed(xa);
00104    printf("[client] Good bye.\n");
00105    return 0;
00106 }
00107 
00125 static void myLogger(void *logUserP, 
00126                      XMLBLASTER_LOG_LEVEL currLevel,
00127                      XMLBLASTER_LOG_LEVEL level,
00128                      const char *location, const char *fmt, ...)
00129 {
00130    /* Guess we need no more than 200 bytes. */
00131    int n, size = 200;
00132    char *p = 0;
00133    va_list ap;
00134    /*XmlBlasterAccessUnparsed *xa = (XmlBlasterAccessUnparsed *)logUserP;*/
00135    if (logUserP) {}  /* To avoid "logUserP was never referenced" compiler warning */
00136 
00137    if (level > currLevel) { /* XMLBLASTER_LOG_ERROR, XMLBLASTER_LOG_WARN, XMLBLASTER_LOG_INFO, XMLBLASTER_LOG_TRACE */
00138       return;
00139    }
00140    if ((p = (char *)malloc (size)) == NULL)
00141       return;
00142 
00143    for (;;) {
00144       /* Try to print in the allocated space. */
00145       va_start(ap, fmt);
00146       n = VSNPRINTF(p, size, fmt, ap); /* UNIX: vsnprintf(), WINDOWS: _vsnprintf() */
00147       va_end(ap);
00148       /* If that worked, print the string to console. */
00149       if (n > -1 && n < size) {
00150          if (level == XMLBLASTER_LOG_TRACE)
00151             printf("%s %s\n", getLogLevelStr(level), p);
00152          else
00153             printf("{%s-%s-%s} [%s] %s\n",
00154                    __DATE__, __TIME__, getLogLevelStr(level), location, p);
00155          free(p);
00156          return;
00157       }
00158       /* Else try again with more space. */
00159       if (n > -1)    /* glibc 2.1 */
00160          size = n+1; /* precisely what is needed */
00161       else           /* glibc 2.0 */
00162          size *= 2;  /* twice the old size */
00163       if ((p = (char *)realloc (p, size)) == NULL) {
00164          return;
00165       }
00166    }
00167 }
00168 
00172 static bool myUpdate(MsgUnitArr *msgUnitArr, void *userData,
00173                      XmlBlasterException *xmlBlasterException)
00174 {
00175    size_t i;
00176    if (xmlBlasterException != 0) ;  /* Supress compiler warnings */
00177    if (userData != 0) ;
00178    for (i=0; i<msgUnitArr->len; i++) {
00179       char *xml = messageUnitToXml(&msgUnitArr->msgUnitArr[i]);
00180       printf("[client] CALLBACK update(): Asynchronous message update arrived:%s\n",
00181              xml);
00182       xmlBlasterFree(xml);
00183       msgUnitArr->msgUnitArr[i].responseQos =
00184              strcpyAlloc("<qos><state id='OK'/></qos>");
00185       /* Return QoS: Everything is OK */
00186    }
00187    return true;
00188 }
00189