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