|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define WIN32_LEAN_AND_MEAN |
|
|
|
|
|
#include <stdlib.h> |
|
|
#include <stdio.h> |
|
|
|
|
|
#include <xmlrpc-c/base.h> |
|
|
#include <xmlrpc-c/server.h> |
|
|
#include <xmlrpc-c/server_abyss.h> |
|
|
|
|
|
#include "config.h" |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
computeQuotient(xmlrpc_env * const envP, |
|
|
xmlrpc_value * const ratioP, |
|
|
xmlrpc_double * const quotientP) { |
|
|
|
|
|
xmlrpc_value * dividendP; |
|
|
|
|
|
xmlrpc_struct_find_value(envP, ratioP, "DIVIDEND", ÷ndP); |
|
|
|
|
|
if (!envP->fault_occurred) { |
|
|
if (!dividendP) |
|
|
xmlrpc_env_set_fault( |
|
|
envP, 0, "Structure is missing 'DIVIDEND' member"); |
|
|
else { |
|
|
xmlrpc_value * divisorP; |
|
|
|
|
|
xmlrpc_struct_find_value(envP, ratioP, "DIVISOR", &divisorP); |
|
|
|
|
|
if (!envP->fault_occurred) { |
|
|
if (!divisorP) |
|
|
xmlrpc_env_set_fault( |
|
|
envP, 0, "Structure is missing 'DIVISOR' member"); |
|
|
else { |
|
|
xmlrpc_double dividend; |
|
|
|
|
|
xmlrpc_read_double(envP, dividendP, ÷nd); |
|
|
|
|
|
if (!envP->fault_occurred) { |
|
|
xmlrpc_double divisor; |
|
|
|
|
|
xmlrpc_read_double(envP, divisorP, &divisor); |
|
|
|
|
|
if (!envP->fault_occurred) |
|
|
*quotientP = dividend / divisor; |
|
|
} |
|
|
xmlrpc_DECREF(divisorP); |
|
|
} |
|
|
} |
|
|
xmlrpc_DECREF(dividendP); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
computeQuotients(xmlrpc_env * const envP, |
|
|
xmlrpc_value * const ratioArrayP, |
|
|
xmlrpc_value ** const quotientArrayPP) { |
|
|
|
|
|
xmlrpc_value * quotientArrayP; |
|
|
|
|
|
quotientArrayP = xmlrpc_array_new(envP); |
|
|
if (!envP->fault_occurred) { |
|
|
|
|
|
unsigned int const ratioCt = xmlrpc_array_size(envP, ratioArrayP); |
|
|
|
|
|
unsigned int i; |
|
|
|
|
|
for (i = 0; i < ratioCt && !envP->fault_occurred; ++i) { |
|
|
xmlrpc_value * ratioP; |
|
|
|
|
|
xmlrpc_array_read_item(envP, ratioArrayP, i, &ratioP); |
|
|
|
|
|
if (!envP->fault_occurred) { |
|
|
xmlrpc_double quotient; |
|
|
|
|
|
computeQuotient(envP, ratioP, "ient); |
|
|
|
|
|
if (!envP->fault_occurred) { |
|
|
xmlrpc_value * quotientP; |
|
|
|
|
|
quotientP = xmlrpc_double_new(envP, quotient); |
|
|
|
|
|
if (!envP->fault_occurred) { |
|
|
xmlrpc_array_append_item(envP, quotientArrayP, |
|
|
quotientP); |
|
|
|
|
|
xmlrpc_DECREF(quotientP); |
|
|
} |
|
|
} |
|
|
xmlrpc_DECREF(ratioP); |
|
|
} |
|
|
} |
|
|
if (envP->fault_occurred) |
|
|
xmlrpc_DECREF(quotientArrayP); |
|
|
else |
|
|
*quotientArrayPP = quotientArrayP; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static xmlrpc_value * |
|
|
example_divide(xmlrpc_env * const envP, |
|
|
xmlrpc_value * const paramArrayP, |
|
|
void * const serverInfo, |
|
|
void * const channelInfo) { |
|
|
|
|
|
xmlrpc_value * retvalP; |
|
|
xmlrpc_int32 argVersion; |
|
|
xmlrpc_value * ratioArrayP; |
|
|
|
|
|
xmlrpc_decompose_value(envP, paramArrayP, "(iA)", |
|
|
&argVersion, &ratioArrayP); |
|
|
if (envP->fault_occurred) |
|
|
return NULL; |
|
|
|
|
|
if (argVersion != 1) { |
|
|
xmlrpc_env_set_fault(envP, 0, "Parameter list version must be 1"); |
|
|
return NULL; |
|
|
} |
|
|
|
|
|
computeQuotients(envP, ratioArrayP, &retvalP); |
|
|
|
|
|
xmlrpc_DECREF(ratioArrayP); |
|
|
|
|
|
if (envP->fault_occurred) |
|
|
return NULL; |
|
|
|
|
|
return retvalP; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
main(int const argc, |
|
|
const char ** const argv) { |
|
|
|
|
|
struct xmlrpc_method_info3 const methodInfo = { |
|
|
"example.divide", |
|
|
&example_divide, |
|
|
}; |
|
|
xmlrpc_server_abyss_parms serverparm; |
|
|
xmlrpc_registry * registryP; |
|
|
xmlrpc_env env; |
|
|
|
|
|
if (argc-1 != 1) { |
|
|
fprintf(stderr, "You must specify 1 argument: The TCP port " |
|
|
"number on which the server will accept connections " |
|
|
"for RPCs (8080 is a common choice). " |
|
|
"You specified %d arguments.\n", argc-1); |
|
|
exit(1); |
|
|
} |
|
|
|
|
|
xmlrpc_env_init(&env); |
|
|
|
|
|
registryP = xmlrpc_registry_new(&env); |
|
|
|
|
|
xmlrpc_registry_add_method3(&env, registryP, &methodInfo); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
serverparm.config_file_name = NULL; |
|
|
serverparm.registryP = registryP; |
|
|
serverparm.port_number = atoi(argv[1]); |
|
|
serverparm.log_file_name = "/tmp/xmlrpc_log"; |
|
|
|
|
|
printf("Running XML-RPC server...\n"); |
|
|
|
|
|
xmlrpc_server_abyss(&env, &serverparm, XMLRPC_APSIZE(log_file_name)); |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
} |
|
|
|