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