xmlrpc_socket_server.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /* A simple standalone XML-RPC server program written in C as an example of
  2. use of the Xmlrpc-c libraries.
  3. This example expects an already bound socket on Standard Input, ready to
  4. be listened on for client connections. Also see xmlrpc_sample_add_server,
  5. which is the same thing, except you tell it a TCP port number and it
  6. creates the socket itself. Also see xmlrpc_inetd_server.c, which is
  7. the same thing except you give it a socket which is already connected
  8. to a client.
  9. Example:
  10. $ socketexec -local_port=8080 ./xmlrpc_socket_server
  11. */
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #ifdef WIN32
  15. # include <windows.h>
  16. #else
  17. # include <unistd.h>
  18. #endif
  19. #include <xmlrpc-c/base.h>
  20. #include <xmlrpc-c/server.h>
  21. #include <xmlrpc-c/server_abyss.h>
  22. #include "config.h" /* information about this build environment */
  23. #ifdef WIN32
  24. #define SLEEP(seconds) SleepEx(seconds * 1000, 1);
  25. #else
  26. #define SLEEP(seconds) sleep(seconds);
  27. #endif
  28. static xmlrpc_value *
  29. sample_add(xmlrpc_env * const envP,
  30. xmlrpc_value * const paramArrayP,
  31. void * const serverInfo,
  32. void * const channelInfo) {
  33. xmlrpc_int32 x, y, z;
  34. /* Parse our argument array. */
  35. xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y);
  36. if (envP->fault_occurred)
  37. return NULL;
  38. /* Add our two numbers. */
  39. z = x + y;
  40. /* Sometimes, make it look hard (so client can see what it's like
  41. to do an RPC that takes a while).
  42. */
  43. if (y == 1)
  44. SLEEP(2);
  45. /* Return our result. */
  46. return xmlrpc_build_value(envP, "i", z);
  47. }
  48. int
  49. main(int const argc,
  50. const char ** const argv) {
  51. struct xmlrpc_method_info3 const methodInfo = {
  52. .methodName = "sample.add",
  53. .methodFunction = &sample_add,
  54. .serverInfo = NULL
  55. };
  56. xmlrpc_server_abyss_parms serverparm;
  57. xmlrpc_registry * registryP;
  58. xmlrpc_env env;
  59. if (argc-1 != 0) {
  60. fprintf(stderr, "There are no arguments. You must supply a "
  61. "bound socket on which to listen for client connections "
  62. "as Standard Input\n");
  63. if (argv) {} /* silence unused parameter warning */
  64. exit(1);
  65. }
  66. xmlrpc_env_init(&env);
  67. registryP = xmlrpc_registry_new(&env);
  68. xmlrpc_registry_add_method3(&env, registryP, &methodInfo);
  69. /* In the modern form of the Abyss API, we supply parameters in memory
  70. like a normal API. We select the modern form by setting
  71. config_file_name to NULL:
  72. */
  73. serverparm.config_file_name = NULL;
  74. serverparm.registryP = registryP;
  75. serverparm.log_file_name = "/tmp/xmlrpc_log";
  76. serverparm.keepalive_timeout = 0;
  77. serverparm.keepalive_max_conn = 0;
  78. serverparm.timeout = 0;
  79. serverparm.dont_advertise = FALSE;
  80. serverparm.socket_bound = TRUE;
  81. serverparm.socket_handle = STDIN_FILENO;
  82. printf("Running XML-RPC server...\n");
  83. xmlrpc_server_abyss(&env, &serverparm, XMLRPC_APSIZE(socket_handle));
  84. return 0;
  85. }