2
0

xmlrpc_inetd_server.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /* A simple standalone XML-RPC server program based on Abyss that processes a
  2. single RPC from an existing TCP connection on Standard Input.
  3. A typical example of where this would be useful is with an Inetd
  4. "super server."
  5. xmlrpc_sample_add_server.c is a server that does the same thing,
  6. but you give it a TCP port number and it listens for TCP connecitons
  7. and processes RPCs ad infinitum. xmlrpc_socket_server.c is halfway
  8. in between those -- you give it an already bound and listening
  9. socket, and it lists for TCP connections and processes RPCs ad
  10. infinitum.
  11. Here is an easy way to test this program:
  12. socketexec --accept --local_port=8080 --stdin -- ./xmlrpc_inetd_server
  13. Now run the client program 'xmlrpc_sample_add_client'. Socketexec
  14. will accept the connection that the client program requests and pass it
  15. to this program on Standard Input. This program will perform the RPC,
  16. respond to the client, then exit.
  17. */
  18. #define _XOPEN_SOURCE 600
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <signal.h>
  22. #ifndef WIN32
  23. #include <unistd.h>
  24. #endif
  25. #include <xmlrpc-c/base.h>
  26. #include <xmlrpc-c/abyss.h>
  27. #include <xmlrpc-c/server.h>
  28. #include <xmlrpc-c/server_abyss.h>
  29. #include "config.h" /* information about this build environment */
  30. static void
  31. setupSignalHandlers(void) {
  32. /* In UNIX, when you try to write to a socket that has been closed
  33. from the other end, your write fails, but you also get a SIGPIPE
  34. signal. That signal will kill you before you even have a chance
  35. to see the write fail unless you catch, block, or ignore it.
  36. If a client should connect to us and then disconnect before we've
  37. sent our response, we see this socket-closed behavior. We
  38. obviously don't want to die just because a client didn't complete
  39. an RPC, so we ignore SIGPIPE.
  40. */
  41. #ifndef WIN32
  42. struct sigaction mysigaction;
  43. sigemptyset(&mysigaction.sa_mask);
  44. mysigaction.sa_flags = 0;
  45. mysigaction.sa_handler = SIG_IGN;
  46. sigaction(SIGPIPE, &mysigaction, NULL);
  47. #endif
  48. }
  49. static xmlrpc_value *
  50. sample_add(xmlrpc_env * const envP,
  51. xmlrpc_value * const paramArrayP,
  52. void * const serverInfo,
  53. void * const channelInfo) {
  54. xmlrpc_int x, y, z;
  55. /* Parse our argument array. */
  56. xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y);
  57. if (envP->fault_occurred)
  58. return NULL;
  59. /* Add our two numbers. */
  60. z = x + y;
  61. /* Return our result. */
  62. return xmlrpc_build_value(envP, "i", z);
  63. }
  64. int
  65. main(int const argc,
  66. const char ** const argv) {
  67. struct xmlrpc_method_info3 const methodInfo = {
  68. .methodName = "sample.add",
  69. .methodFunction = &sample_add,
  70. .serverInfo = NULL
  71. };
  72. TServer abyssServer;
  73. xmlrpc_registry * registryP;
  74. xmlrpc_env env;
  75. if (argc-1 != 0) {
  76. fprintf(stderr, "There are no arguments. You must supply a "
  77. "bound socket on which to listen for client connections "
  78. "as Standard Input\n");
  79. if (argv) {} /* silence unused parameter warning */
  80. exit(1);
  81. }
  82. xmlrpc_env_init(&env);
  83. registryP = xmlrpc_registry_new(&env);
  84. xmlrpc_registry_add_method3(&env, registryP, &methodInfo);
  85. ServerCreateNoAccept(&abyssServer, "XmlRpcServer", NULL, NULL);
  86. xmlrpc_server_abyss_set_handlers(&abyssServer, registryP);
  87. setupSignalHandlers();
  88. ServerRunConn(&abyssServer, STDIN_FILENO);
  89. /* This reads the HTTP POST request from Standard Input and
  90. executes the indicated RPC.
  91. */
  92. ServerFree(&abyssServer);
  93. return 0;
  94. }