1 /* A simple standalone XML-RPC server based on Abyss that processes a
2 single RPC from an existing TCP connection on Standard Input.
4 A typical example of where this would be useful is with an Inetd
7 xmlrpc_sample_add_server.c is a server that does the same thing,
8 but you give it a TCP port number and it listens for TCP connecitons
9 and processes RPCs ad infinitum.
19 #include <xmlrpc-c/base.h>
20 #include <xmlrpc-c/abyss.h>
21 #include <xmlrpc-c/server.h>
22 #include <xmlrpc-c/server_abyss.h>
24 #include "config.h" /* information about this build environment */
28 setupSignalHandlers(void) {
30 /* In UNIX, when you try to write to a socket that has been closed
31 from the other end, your write fails, but you also get a SIGPIPE
32 signal. That signal will kill you before you even have a chance
33 to see the write fail unless you catch, block, or ignore it.
34 If a client should connect to us and then disconnect before we've
35 sent our response, we see this socket-closed behavior. We
36 obviously don't want to die just because a client didn't complete
37 an RPC, so we ignore SIGPIPE.
39 struct sigaction mysigaction;
41 sigemptyset(&mysigaction.sa_mask);
42 mysigaction.sa_flags = 0;
43 mysigaction.sa_handler = SIG_IGN;
44 sigaction(SIGPIPE, &mysigaction, NULL);
50 sample_add(xmlrpc_env * const envP,
51 xmlrpc_value * const paramArrayP,
52 void * const userData ATTR_UNUSED) {
56 /* Parse our argument array. */
57 xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y);
58 if (envP->fault_occurred)
61 /* Add our two numbers. */
64 /* Return our result. */
65 return xmlrpc_build_value(envP, "i", z);
72 const char ** const argv) {
75 xmlrpc_registry * registryP;
79 fprintf(stderr, "There are no arguments. You must supply a "
80 "bound socket on which to listen for client connections "
81 "as Standard Input\n");
82 if (argv) {} /* silence unused parameter warning */
85 xmlrpc_env_init(&env);
87 registryP = xmlrpc_registry_new(&env);
89 xmlrpc_registry_add_method(
90 &env, registryP, NULL, "sample.add", &sample_add, NULL);
92 ServerCreateNoAccept(&abyssServer, "XmlRpcServer", NULL, NULL);
94 xmlrpc_server_abyss_set_handlers(&abyssServer, registryP);
96 setupSignalHandlers();
98 ServerRunConn(&abyssServer, STDIN_FILENO);
99 /* This reads the HTTP POST request from Standard Input and
100 executes the indicated RPC.
103 ServerFree(&abyssServer);