xmlrpc_sample_add_server.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /* A simple standalone XML-RPC server program written in C. */
  2. /* This server knows one RPC class (besides the system classes):
  3. "sample.add".
  4. The program takes one argument: the HTTP port number on which the server
  5. is to accept connections, in decimal.
  6. You can use the example program 'xmlrpc_sample_add_client' to send an RPC
  7. to this server.
  8. Example:
  9. $ ./xmlrpc_sample_add_server 8080&
  10. $ ./xmlrpc_sample_add_client
  11. For more fun, run client and server in separate terminals and turn on
  12. tracing for each:
  13. $ export XMLRPC_TRACE_XML=1
  14. */
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #ifdef WIN32
  18. # include <windows.h>
  19. #else
  20. # include <unistd.h>
  21. #endif
  22. #include <xmlrpc-c/base.h>
  23. #include <xmlrpc-c/server.h>
  24. #include <xmlrpc-c/server_abyss.h>
  25. #include "config.h" /* information about this build environment */
  26. #ifdef WIN32
  27. #define SLEEP(seconds) SleepEx(seconds * 1000, 1);
  28. #else
  29. #define SLEEP(seconds) sleep(seconds);
  30. #endif
  31. static xmlrpc_value *
  32. sample_add(xmlrpc_env * const envP,
  33. xmlrpc_value * const paramArrayP,
  34. void * const serverInfo,
  35. void * const channelInfo) {
  36. xmlrpc_int32 x, y, z;
  37. /* Parse our argument array. */
  38. xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y);
  39. if (envP->fault_occurred)
  40. return NULL;
  41. /* Add our two numbers. */
  42. z = x + y;
  43. /* Sometimes, make it look hard (so client can see what it's like
  44. to do an RPC that takes a while).
  45. */
  46. if (y == 1)
  47. SLEEP(3);
  48. /* Return our result. */
  49. return xmlrpc_build_value(envP, "i", z);
  50. }
  51. int
  52. main(int const argc,
  53. const char ** const argv) {
  54. struct xmlrpc_method_info3 const methodInfo = {
  55. /* .methodName = */ "sample.add",
  56. /* .methodFunction = */ &sample_add,
  57. };
  58. xmlrpc_server_abyss_parms serverparm;
  59. xmlrpc_registry * registryP;
  60. xmlrpc_env env;
  61. if (argc-1 != 1) {
  62. fprintf(stderr, "You must specify 1 argument: The TCP port "
  63. "number on which the server will accept connections "
  64. "for RPCs (8080 is a common choice). "
  65. "You specified %d arguments.\n", argc-1);
  66. exit(1);
  67. }
  68. xmlrpc_env_init(&env);
  69. registryP = xmlrpc_registry_new(&env);
  70. xmlrpc_registry_add_method3(&env, registryP, &methodInfo);
  71. /* In the modern form of the Abyss API, we supply parameters in memory
  72. like a normal API. We select the modern form by setting
  73. config_file_name to NULL:
  74. */
  75. serverparm.config_file_name = NULL;
  76. serverparm.registryP = registryP;
  77. serverparm.port_number = atoi(argv[1]);
  78. serverparm.log_file_name = "/tmp/xmlrpc_log";
  79. printf("Running XML-RPC server...\n");
  80. xmlrpc_server_abyss(&env, &serverparm, XMLRPC_APSIZE(log_file_name));
  81. /* xmlrpc_server_abyss() never returns */
  82. return 0;
  83. }