3 #include "xmlrpc_config.h"
7 #include <xmlrpc-c/base.h>
8 #include <xmlrpc-c/client.h>
9 #include <xmlrpc-c/client_int.h>
10 #include <xmlrpc-c/client_global.h>
12 /*=========================================================================
14 =========================================================================*/
16 static struct xmlrpc_client * globalClientP;
17 static bool globalClientExists = false;
21 xmlrpc_client_init2(xmlrpc_env * const envP,
23 const char * const appname,
24 const char * const appversion,
25 const struct xmlrpc_clientparms * const clientparmsP,
26 unsigned int const parmSize) {
27 /*----------------------------------------------------------------------------
28 This function is not thread-safe.
29 -----------------------------------------------------------------------------*/
30 if (globalClientExists)
33 "Xmlrpc-c global client instance has already been created "
34 "(need to call xmlrpc_client_cleanup() before you can "
37 /* The following call is not thread-safe */
38 xmlrpc_client_setup_global_const(envP);
39 if (!envP->fault_occurred) {
40 xmlrpc_client_create(envP, flags, appname, appversion,
41 clientparmsP, parmSize, &globalClientP);
42 if (!envP->fault_occurred)
43 globalClientExists = true;
45 if (envP->fault_occurred)
46 xmlrpc_client_teardown_global_const();
54 xmlrpc_client_init(int const flags,
55 const char * const appname,
56 const char * const appversion) {
57 /*----------------------------------------------------------------------------
58 This function is not thread-safe.
59 -----------------------------------------------------------------------------*/
60 struct xmlrpc_clientparms clientparms;
62 /* As our interface does not allow for failure, we just fail silently ! */
65 xmlrpc_env_init(&env);
67 clientparms.transport = NULL;
69 /* The following call is not thread-safe */
70 xmlrpc_client_init2(&env, flags,
72 &clientparms, XMLRPC_CPSIZE(transport));
74 xmlrpc_env_clean(&env);
80 xmlrpc_client_cleanup() {
81 /*----------------------------------------------------------------------------
82 This function is not thread-safe
83 -----------------------------------------------------------------------------*/
84 XMLRPC_ASSERT(globalClientExists);
86 xmlrpc_client_destroy(globalClientP);
88 globalClientExists = false;
90 /* The following call is not thread-safe */
91 xmlrpc_client_teardown_global_const();
97 validateGlobalClientExists(xmlrpc_env * const envP) {
99 if (!globalClientExists)
101 "Xmlrpc-c global client instance "
102 "has not been created "
103 "(need to call xmlrpc_client_init2()).");
109 xmlrpc_client_transport_call(
110 xmlrpc_env * const envP,
111 void * const reserved ATTR_UNUSED,
112 /* for client handle */
113 const xmlrpc_server_info * const serverP,
114 xmlrpc_mem_block * const callXmlP,
115 xmlrpc_mem_block ** const respXmlPP) {
117 validateGlobalClientExists(envP);
118 if (!envP->fault_occurred)
119 xmlrpc_client_transport_call2(envP, globalClientP, serverP,
120 callXmlP, respXmlPP);
126 clientCall_va(xmlrpc_env * const envP,
127 const xmlrpc_server_info * const serverInfoP,
128 const char * const methodName,
129 const char * const format,
131 xmlrpc_value ** const resultPP) {
133 validateGlobalClientExists(envP);
134 if (!envP->fault_occurred) {
135 xmlrpc_value * paramArrayP;
138 xmlrpc_build_value_va(envP, format, args, ¶mArrayP, &suffix);
140 if (!envP->fault_occurred) {
142 xmlrpc_faultf(envP, "Junk after the argument "
144 "There must be exactly one arument.",
147 xmlrpc_client_call2(envP, globalClientP, serverInfoP,
148 methodName, paramArrayP, resultPP);
150 xmlrpc_DECREF(paramArrayP);
158 xmlrpc_client_call(xmlrpc_env * const envP,
159 const char * const serverUrl,
160 const char * const methodName,
161 const char * const format,
164 xmlrpc_value * resultP;
166 xmlrpc_server_info * serverInfoP;
168 serverInfoP = xmlrpc_server_info_new(envP, serverUrl);
170 if (!envP->fault_occurred) {
172 va_start(args, format);
174 clientCall_va(envP, serverInfoP, methodName, format, args, &resultP);
177 xmlrpc_server_info_free(serverInfoP);
186 xmlrpc_client_call_server(xmlrpc_env * const envP,
187 const xmlrpc_server_info * const serverP,
188 const char * const methodName,
189 const char * const format,
193 xmlrpc_value * resultP;
195 va_start(args, format);
196 clientCall_va(envP, serverP, methodName, format, args, &resultP);
205 xmlrpc_client_call_server_params(
206 xmlrpc_env * const envP,
207 const xmlrpc_server_info * const serverInfoP,
208 const char * const methodName,
209 xmlrpc_value * const paramArrayP) {
211 xmlrpc_value * resultP;
213 validateGlobalClientExists(envP);
215 if (!envP->fault_occurred)
216 xmlrpc_client_call2(envP, globalClientP,
217 serverInfoP, methodName, paramArrayP,
226 xmlrpc_client_call_params(xmlrpc_env * const envP,
227 const char * const serverUrl,
228 const char * const methodName,
229 xmlrpc_value * const paramArrayP) {
231 xmlrpc_value * resultP;
233 validateGlobalClientExists(envP);
235 if (!envP->fault_occurred) {
236 xmlrpc_server_info * serverInfoP;
238 serverInfoP = xmlrpc_server_info_new(envP, serverUrl);
240 if (!envP->fault_occurred) {
241 xmlrpc_client_call2(envP, globalClientP,
242 serverInfoP, methodName, paramArrayP,
245 xmlrpc_server_info_free(serverInfoP);
254 xmlrpc_client_call_server_asynch_params(
255 xmlrpc_server_info * const serverInfoP,
256 const char * const methodName,
257 xmlrpc_response_handler responseHandler,
258 void * const userData,
259 xmlrpc_value * const paramArrayP) {
263 xmlrpc_env_init(&env);
265 validateGlobalClientExists(&env);
267 if (!env.fault_occurred)
268 xmlrpc_client_start_rpc(&env, globalClientP,
269 serverInfoP, methodName, paramArrayP,
270 responseHandler, userData);
272 if (env.fault_occurred) {
273 /* Unfortunately, we have no way to return an error and the
274 regular callback for a failed RPC is designed to have the
275 parameter array passed to it. This was probably an oversight
276 of the original asynch design, but now we have to be as
277 backward compatible as possible, so we do this:
279 (*responseHandler)(serverInfoP->_server_url,
280 methodName, paramArrayP, userData,
283 xmlrpc_env_clean(&env);
289 xmlrpc_client_call_asynch(const char * const serverUrl,
290 const char * const methodName,
291 xmlrpc_response_handler responseHandler,
292 void * const userData,
293 const char * const format,
298 xmlrpc_env_init(&env);
300 validateGlobalClientExists(&env);
302 if (!env.fault_occurred) {
303 xmlrpc_value * paramArrayP;
307 va_start(args, format);
308 xmlrpc_build_value_va(&env, format, args, ¶mArrayP, &suffix);
311 if (!env.fault_occurred) {
313 xmlrpc_faultf(&env, "Junk after the argument "
315 "There must be exactly one arument.",
318 xmlrpc_client_call_asynch_params(
319 serverUrl, methodName, responseHandler, userData,
323 if (env.fault_occurred)
324 (*responseHandler)(serverUrl, methodName, NULL, userData, &env, NULL);
326 xmlrpc_env_clean(&env);
332 xmlrpc_client_call_asynch_params(const char * const serverUrl,
333 const char * const methodName,
334 xmlrpc_response_handler responseHandler,
335 void * const userData,
336 xmlrpc_value * const paramArrayP) {
338 xmlrpc_server_info * serverInfoP;
340 xmlrpc_env_init(&env);
342 serverInfoP = xmlrpc_server_info_new(&env, serverUrl);
344 if (!env.fault_occurred) {
345 xmlrpc_client_call_server_asynch_params(
346 serverInfoP, methodName, responseHandler, userData, paramArrayP);
348 xmlrpc_server_info_free(serverInfoP);
350 if (env.fault_occurred)
351 (*responseHandler)(serverUrl, methodName, paramArrayP, userData,
353 xmlrpc_env_clean(&env);
359 xmlrpc_client_call_server_asynch(xmlrpc_server_info * const serverInfoP,
360 const char * const methodName,
361 xmlrpc_response_handler responseHandler,
362 void * const userData,
363 const char * const format,
367 xmlrpc_value * paramArrayP;
371 xmlrpc_env_init(&env);
373 va_start(args, format);
374 xmlrpc_build_value_va(&env, format, args, ¶mArrayP, &suffix);
377 if (!env.fault_occurred) {
379 xmlrpc_faultf(&env, "Junk after the argument "
381 "There must be exactly one arument.",
384 xmlrpc_client_call_server_asynch_params(
385 serverInfoP, methodName, responseHandler, userData,
388 xmlrpc_DECREF(paramArrayP);
390 if (env.fault_occurred)
391 (*responseHandler)(serverInfoP->_server_url, methodName, NULL,
392 userData, &env, NULL);
394 xmlrpc_env_clean(&env);
400 xmlrpc_client_event_loop_finish_asynch(void) {
402 XMLRPC_ASSERT(globalClientExists);
403 xmlrpc_client_event_loop_finish(globalClientP);
409 xmlrpc_client_event_loop_finish_asynch_timeout(
410 unsigned long const milliseconds) {
412 XMLRPC_ASSERT(globalClientExists);
413 xmlrpc_client_event_loop_finish_timeout(globalClientP, milliseconds);