1 /*----------------------------------------------------------------------------
  2 Name:      xmlBlaster/demo/c/socket/LogRedirect.c
  3 Project:   xmlBlaster.org
  4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
  5 Comment:   Tests redirect of logging
  6 Author:    "Marcel Ruff" <xmlBlaster@marcelruff.info>
  7 Compile:
  8   Linux with libxmlBlasterC.so:
  9           gcc  -D_REENTRANT -Wall -o LogRedirect LogRedirect.c -I../../../src/c
 10                 -L../../../lib -lxmlBlasterClientC -Wl,-rpath=../../../lib -lpthread
 11 See:      http://www.xmlblaster.org/xmlBlaster/doc/requirements/client.c.socket.html
 12 -----------------------------------------------------------------------------*/
 13 #include <stdio.h>
 14 #include <stdlib.h>
 15 #include <string.h>
 16 #include <stdarg.h>
 17 #include <ctype.h>
 18 #include <XmlBlasterAccessUnparsed.h>
 19 
 20 static void myLogger(void *logUserP, 
 21                      XMLBLASTER_LOG_LEVEL currLevel,
 22                      XMLBLASTER_LOG_LEVEL level,
 23                      const char *location, const char *fmt, ...);
 24 static bool myUpdate(MsgUnitArr *msgUnitArr, void *userData,
 25                      XmlBlasterException *xmlBlasterException);
 26 
 27 /**
 28  * Invoke: LogRedirect -logLevel TRACE
 29  */
 30 int main(int argc, char** argv)
 31 {
 32    int iarg;
 33    char *response = (char *)0;
 34    char connectQos[2048];
 35    XmlBlasterException xmlBlasterException;
 36    XmlBlasterAccessUnparsed *xa = 0;
 37 
 38    printf("[client] Try option '-help' if you need usage informations\n");
 39 
 40    for (iarg=0; iarg < argc; iarg++) {
 41       if (strcmp(argv[iarg], "-help") == 0 || strcmp(argv[iarg], "--help") == 0) {
 42          char usage[XMLBLASTER_MAX_USAGE_LEN];
 43          const char *pp =
 44          "\n  -logLevel            ERROR | WARN | INFO | TRACE [WARN]"
 45          "\n\nExample:"
 46          "\n  LogRedirect -logLevel TRACE"
 47                " -dispatch/connection/plugin/socket/hostname server.mars.universe";
 48          printf("Usage:\nXmlBlaster C SOCKET client %s\n%s%s\n",
 49                   getXmlBlasterVersion(), xmlBlasterAccessUnparsedUsage(usage), pp);
 50          exit(EXIT_FAILURE);
 51       }
 52    }
 53 
 54    xa = getXmlBlasterAccessUnparsed(argc, (const char* const*)argv);
 55 
 56    /* Register our own logging function */
 57    xa->log = myLogger;
 58    /* Optionally pass a pointer which we can use in myLogger again */
 59    xa->logUserP = xa;
 60 
 61    /* connect */
 62    sprintf(connectQos,
 63             "<qos>"
 64             " <securityService type='htpasswd' version='1.0'>"
 65             "  <![CDATA["
 66             "   <user>fritz</user>"
 67             "   <passwd>secret</passwd>"
 68             "  ]]>"
 69             " </securityService>"
 70             "</qos>");
 71 
 72    response = xa->connect(xa, connectQos, myUpdate, &xmlBlasterException);
 73    if (*xmlBlasterException.errorCode != 0) {
 74       printf("[client] Caught exception during connect errorCode=%s, message=%s\n",
 75                xmlBlasterException.errorCode, xmlBlasterException.message);
 76       freeXmlBlasterAccessUnparsed(xa);
 77       exit(EXIT_FAILURE);
 78    }
 79    xmlBlasterFree(response);
 80    printf("[client] Connected to xmlBlaster, do some tests ...\n");
 81 
 82    /* ping */
 83    response = xa->ping(xa, 0, &xmlBlasterException);
 84    if (response == (char *)0) {
 85       printf("[client] ERROR: Pinging a connected server failed: errorCode=%s, message=%s\n",
 86              xmlBlasterException.errorCode, xmlBlasterException.message);
 87       freeXmlBlasterAccessUnparsed(xa);
 88       exit(EXIT_FAILURE);
 89    }
 90    else {
 91       printf("[client] Pinging a connected server, response=%s\n", response);
 92       xmlBlasterFree(response);
 93    }
 94 
 95    /* disconnect */
 96    if (xa->disconnect(xa, 0, &xmlBlasterException) == false) {
 97       printf("[client] Caught exception in disconnect, errorCode=%s, message=%s\n",
 98                xmlBlasterException.errorCode, xmlBlasterException.message);
 99       freeXmlBlasterAccessUnparsed(xa);
100       exit(EXIT_FAILURE);
101    }
102 
103    freeXmlBlasterAccessUnparsed(xa);
104    printf("[client] Good bye.\n");
105    return 0;
106 }
107 
108 /**
109  * Customized logging output is handled by this method. 
110  * <p>
111  * We register this function with 
112  * </p>
113  * <pre>
114  * xa->log = myLogger;
115  * </pre>
116  * @param logUserP 0 or pointing to one of your supplied data struct
117  * @param currLevel The actual log level of the client
118  * @param level The level of this log entry
119  * @param location A string describing the code place
120  * @param fmt The formatting string
121  * @param ... Other variables to log, corresponds to 'fmt'
122  * @see xmlBlaster/src/c/msgUtil.c: xmlBlasterDefaultLogging() is the default
123  *      implementation
124  */
125 static void myLogger(void *logUserP, 
126                      XMLBLASTER_LOG_LEVEL currLevel,
127                      XMLBLASTER_LOG_LEVEL level,
128                      const char *location, const char *fmt, ...)
129 {
130    /* Guess we need no more than 200 bytes. */
131    int n, size = 200;
132    char *p = 0;
133    va_list ap;
134    /*XmlBlasterAccessUnparsed *xa = (XmlBlasterAccessUnparsed *)logUserP;*/
135    if (logUserP) {}  /* To avoid "logUserP was never referenced" compiler warning */
136 
137    if (level > currLevel) { /* XMLBLASTER_LOG_ERROR, XMLBLASTER_LOG_WARN, XMLBLASTER_LOG_INFO, XMLBLASTER_LOG_TRACE */
138       return;
139    }
140    if ((p = (char *)malloc (size)) == NULL)
141       return;
142 
143    for (;;) {
144       /* Try to print in the allocated space. */
145       va_start(ap, fmt);
146       n = VSNPRINTF(p, size, fmt, ap); /* UNIX: vsnprintf(), WINDOWS: _vsnprintf() */
147       va_end(ap);
148       /* If that worked, print the string to console. */
149       if (n > -1 && n < size) {
150          if (level == XMLBLASTER_LOG_TRACE)
151             printf("%s %s\n", getLogLevelStr(level), p);
152          else
153             printf("{%s-%s-%s} [%s] %s\n",
154                    __DATE__, __TIME__, getLogLevelStr(level), location, p);
155          free(p);
156          return;
157       }
158       /* Else try again with more space. */
159       if (n > -1)    /* glibc 2.1 */
160          size = n+1; /* precisely what is needed */
161       else           /* glibc 2.0 */
162          size *= 2;  /* twice the old size */
163       if ((p = (char *)realloc (p, size)) == NULL) {
164          return;
165       }
166    }
167 }
168 
169 /**
170  * Here we receive the callback messages from xmlBlaster
171  */
172 static bool myUpdate(MsgUnitArr *msgUnitArr, void *userData,
173                      XmlBlasterException *xmlBlasterException)
174 {
175    size_t i;
176    if (xmlBlasterException != 0) ;  /* Supress compiler warnings */
177    if (userData != 0) ;
178    for (i=0; i<msgUnitArr->len; i++) {
179       char *xml = messageUnitToXml(&msgUnitArr->msgUnitArr[i]);
180       printf("[client] CALLBACK update(): Asynchronous message update arrived:%s\n",
181              xml);
182       xmlBlasterFree(xml);
183       msgUnitArr->msgUnitArr[i].responseQos =
184              strcpyAlloc("<qos><state id='OK'/></qos>");
185       /* Return QoS: Everything is OK */
186    }
187    return true;
188 }


syntax highlighted by Code2HTML, v. 0.9.1