1 /*------------------------------------------------------------------------------
2 Name: client.c
3
4 Project: xmlBlaster.org
5
6 Comment: Example how to access xmlBlaster with C and XmlRpc
7 See http://xmlrpc-c.sourceforge.net/
8 Usually you start first the callbackServer to receive
9 asynchronous update from xmlBlaster as well (see README)
10
11 Author: xmlBlaster@marcelruff.info
12
13 Compile: Read xmlrpc-c/doc/overview.txt
14 CLIENT_CFLAGS=`xmlrpc-c-config libwww-client --cflags`
15 CLIENT_LIBS=`xmlrpc-c-config libwww-client --libs`
16 gcc $CLIENT_CFLAGS -o client client.c $CLIENT_LIBS -Wall
17
18 Invoke: See usage text below
19 ------------------------------------------------------------------------------*/
20 #include <stdio.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <sys/types.h> // for file-read only
24 #include <sys/stat.h> // for file-read only
25 #include <fcntl.h> // for file-read only
26 #include <malloc.h> // for file-read only
27 #include <xmlrpc.h>
28 #include <xmlrpc_client.h>
29 #define NAME "XMLRPC xmlBlaster.org C Client"
30 #define VERSION "0.79d"
31
32 char *readFile(const char *const fileName);
33 void usage();
34 void die_if_fault_occurred (xmlrpc_env *env);
35
36
37 int main (int argc, char** argv)
38 {
39 xmlrpc_env env;
40 xmlrpc_value *result;
41 char sessionId[256], *tmpP;
42 char key[256], *content, qos[256], *retVal, *loginName, *passwd, loginQos[256], *cbUrl;
43 char *keyOid = "PIB_REQUEST";
44 char *serverUrl = NULL; // "http://localhost:8080/"
45 char *msgFile = NULL, *data = NULL;
46 char *destination = NULL;
47 char serverHostName[256];
48 char tmp[256];
49 int iarg;
50
51 for (iarg=0; iarg < argc-1; iarg++) {
52 if (strcmp(argv[iarg], "-xmlrpc.serverUrl") == 0)
53 serverUrl = argv[++iarg];
54 else if (strcmp(argv[iarg], "-xmlrpc.cbUrl") == 0) // URL of our here instantiated callback server
55 cbUrl = argv[++iarg];
56 else if (strcmp(argv[iarg], "-dest") == 0)
57 destination = argv[++iarg];
58 else if (strcmp(argv[iarg], "-msgFile") == 0)
59 msgFile = argv[++iarg];
60 else if (strcmp(argv[iarg], "-loginName") == 0)
61 loginName = argv[++iarg];
62 else if (strcmp(argv[iarg], "-passwd") == 0)
63 passwd = argv[++iarg];
64 else if (strcmp(argv[iarg], "--help") == 0 || strcmp(argv[iarg], "-help") == 0 || strcmp(argv[iarg], "-?") == 0) {
65 usage();
66 exit(0);
67 }
68 }
69
70 if (destination == NULL) // as default, we send messages to ourself (-> our callbackServer)
71 destination = loginName;
72
73 data = readFile(msgFile); // get the data we want to send
74
75 if (destination == NULL || data == NULL) {
76 printf("Missing arguments\n");
77 usage();
78 exit(0);
79 }
80
81 if (serverUrl == NULL) {
82 gethostname(serverHostName, 125);
83 sprintf(tmp, "http://%.255s:8080/", serverHostName);
84 serverUrl = tmp;
85 }
86
87 printf("\n\n-------------------------------------------\n"
88 "Hello as C XmlRpc client for xmlBlaster ...\n\n");
89
90 /* Start up our XMLRPC client library. */
91 xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION);
92 xmlrpc_env_init(&env);
93
94
95 /* Login to xmlBlaster XMLRPC server. */
96 {
97 printf("Login to %s as user %s ...\n", serverUrl, loginName);
98 sprintf(loginQos, "<qos><callback type='XMLRPC'>%.100s</callback></qos>", cbUrl);
99 result = xmlrpc_client_call(&env, serverUrl,
100 "authenticate.login", "(ssss)",
101 loginName, passwd, loginQos, "");
102 die_if_fault_occurred(&env);
103
104 /* Parse our result value. */
105 xmlrpc_parse_value(&env, result, "s", &tmpP);
106 die_if_fault_occurred(&env);
107 strncpy(sessionId, tmpP, 255); // remember sessionId, tmpP is empty after xmlrpc_DECREF(result)
108 printf("Login success, got sessionId=%s\n", sessionId);
109
110 /* Dispose of our result value. */
111 xmlrpc_DECREF(result);
112 }
113
114 /* Send message to destination. */
115 {
116 printf("publish %s to %s ...\n", keyOid, destination);
117 sprintf(key, "<key oid='%.100s' contentMime='text/xml'/>", keyOid);
118 sprintf(qos, "<qos><destination queryType='EXACT'>%.100s</destination></qos>", destination);
119 content = data;
120 printf("Key=%s Qos=%s\n", key, qos);
121 result = xmlrpc_client_call(&env, serverUrl,
122 "xmlBlaster.publish", "(ssss)",
123 sessionId, key, content, qos);
124 die_if_fault_occurred(&env);
125
126 /* Parse our result value. */
127 xmlrpc_parse_value(&env, result, "s", &retVal);
128 die_if_fault_occurred(&env);
129 printf("Publish success, return value is %s\n", retVal);
130
131 /* Dispose of our result value. */
132 xmlrpc_DECREF(result);
133 }
134
135 printf("\nWait until callbackServer has received the response!\n");
136 printf("Than hit a key to logout ...\n");
137 getc(stdin);
138
139 /* Logout from xmlBlaster XMLRPC server. */
140 {
141 printf("Logout from %s as user %s, sessionId=%s ...\n", serverUrl, loginName, sessionId);
142 strcpy(loginQos, "<qos></qos>");
143 result = xmlrpc_client_call(&env, serverUrl, "authenticate.logout", "(s)", sessionId);
144 die_if_fault_occurred(&env);
145
146 /* Parse our result value. */
147 xmlrpc_parse_value(&env, result, "s", &retVal);
148 die_if_fault_occurred(&env);
149 printf("Logout success, got '%s'\n", retVal);
150
151 /* Dispose of our result value. */
152 xmlrpc_DECREF(result);
153 }
154
155 /* Shutdown our XMLRPC client library. */
156 xmlrpc_env_clean(&env);
157 xmlrpc_client_cleanup();
158
159 free(data);
160
161 printf("\nSuccessful communicated with xmlBlaster.\n"
162 "-------------------------------------------\n");
163
164 return 0;
165 }
166
167
168 /*
169 * Some default error handling
170 */
171 void die_if_fault_occurred (xmlrpc_env *env)
172 {
173 /* Check our error-handling environment for an XMLRPC fault. */
174 if (env->fault_occurred) {
175 fprintf(stderr, "XMLRPC Fault: %s (%d)\n",
176 env->fault_string, env->fault_code);
177 usage();
178 exit(1);
179 }
180 }
181
182
183 /*
184 * @return data from file, you need to call free() on this pointer!
185 */
186 char *readFile(const char *const fileName)
187 {
188 int n, fd;
189 const int BUFFSIZE=8192;
190 char buf[BUFFSIZE];
191 char *data;
192 struct stat statbuf;
193
194 if (fileName == NULL)
195 return NULL;
196
197 // get size of file ...
198 if (stat(fileName, &statbuf)) {
199 fprintf(stderr, "File %s not found\n", fileName);
200 return NULL;
201 }
202
203 // read file ...
204 data = malloc((statbuf.st_size+1)*sizeof(char));
205 *data = 0;
206 fd = open(fileName, O_RDONLY);
207 if (fd < 0) {
208 fprintf(stderr, "Can't read file %s\n", fileName);
209 return NULL;
210 }
211 while((n=read(fd, buf, BUFFSIZE)) > 0) {
212 buf[n] = NULL;
213 strcat(data, buf);
214 }
215 *(data + statbuf.st_size) = 0;
216 close(fd);
217 return data;
218 }
219
220 void usage()
221 {
222 fprintf(stderr,
223 "--------------------------------------------------\n"
224 "Usage:\n"
225 " client -xmlrpc.serverUrl <serverURL> -xmlrpc.cbUrl <myCallbackServerURL> -loginName <loginName> -passwd <Password> -dest <loginName> -msgFile <xmlFile>\n"
226 "Example:\n"
227 " client -xmlrpc.serverUrl http://anotherHost:8080/ -xmlrpc.cbUrl http://myHost:8080/RPC2 -loginName gesa -passwd secret -dest gesa -msgFile hello.xml\n"
228 " This sends a message to myself, we have to start the callbackServer first\n"
229 "--------------------------------------------------\n");
230 }
syntax highlighted by Code2HTML, v. 0.9.1