xmlrpc_server_validatee.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. /* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
  2. **
  3. ** Redistribution and use in source and binary forms, with or without
  4. ** modification, are permitted provided that the following conditions
  5. ** are met:
  6. ** 1. Redistributions of source code must retain the above copyright
  7. ** notice, this list of conditions and the following disclaimer.
  8. ** 2. Redistributions in binary form must reproduce the above copyright
  9. ** notice, this list of conditions and the following disclaimer in the
  10. ** documentation and/or other materials provided with the distribution.
  11. ** 3. The name of the author may not be used to endorse or promote products
  12. ** derived from this software without specific prior written permission.
  13. **
  14. ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  15. ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16. ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  17. ** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  18. ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  19. ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  20. ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  21. ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  22. ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  23. ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  24. ** SUCH DAMAGE. */
  25. /*============================================================================
  26. xmlrpc_server_validatee
  27. ==============================================================================
  28. This program runs an XMLRPC server, using the Xmlrpc-c libraries.
  29. The server implements the methods that the Userland Validator1 test suite
  30. invokes, which are supposed to exercise a broad range of XMLRPC server
  31. function.
  32. Coments here used to say you could get information about Validator1
  33. from <http://validator.xmlrpc.com/>, but as of 2004.09.25, there's nothing
  34. there (there's a web server, but it is not configured to serve that
  35. particular URL).
  36. ============================================================================*/
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <xmlrpc-c/base.h>
  41. #include <xmlrpc-c/server.h>
  42. #include <xmlrpc-c/server_abyss.h>
  43. #include "config.h" /* information about this build environment */
  44. #define RETURN_IF_FAULT(envP) \
  45. do { \
  46. if ((envP)->fault_occurred) \
  47. return NULL; \
  48. } while (0)
  49. /*=========================================================================
  50. ** validator1.arrayOfStructsTest
  51. **=========================================================================
  52. */
  53. static xmlrpc_value *
  54. array_of_structs(xmlrpc_env * const envP,
  55. xmlrpc_value * const paramArrayP,
  56. void * const user_data) {
  57. xmlrpc_value * arrayP;
  58. xmlrpc_value * retval;
  59. xmlrpc_decompose_value(envP, paramArrayP, "(A)", &arrayP);
  60. if (envP->fault_occurred)
  61. retval = NULL;
  62. else {
  63. /* Add up all the struct elements named "curly". */
  64. size_t size;
  65. size = xmlrpc_array_size(envP, arrayP);
  66. if (envP->fault_occurred)
  67. retval = NULL;
  68. else {
  69. unsigned int sum;
  70. unsigned int i;
  71. sum = 0;
  72. for (i = 0; i < size && !envP->fault_occurred; ++i) {
  73. xmlrpc_value * strctP;
  74. strctP = xmlrpc_array_get_item(envP, arrayP, i);
  75. if (!envP->fault_occurred) {
  76. xmlrpc_int32 curly;
  77. xmlrpc_decompose_value(envP, strctP, "{s:i,*}",
  78. "curly", &curly);
  79. if (!envP->fault_occurred)
  80. sum += curly;
  81. }
  82. }
  83. xmlrpc_DECREF(arrayP);
  84. if (envP->fault_occurred)
  85. retval = NULL;
  86. else
  87. retval = xmlrpc_build_value(envP, "i", sum);
  88. }
  89. }
  90. return retval;
  91. }
  92. /*=========================================================================
  93. ** validator1.countTheEntities
  94. **=========================================================================
  95. */
  96. static xmlrpc_value *
  97. count_entities(xmlrpc_env * const envP,
  98. xmlrpc_value * const paramArrayP,
  99. void * const user_data) {
  100. const char * str;
  101. size_t len, i;
  102. xmlrpc_int32 left, right, amp, apos, quote;
  103. xmlrpc_decompose_value(envP, paramArrayP, "(s#)", &str, &len);
  104. RETURN_IF_FAULT(envP);
  105. left = right = amp = apos = quote = 0;
  106. for (i = 0; i < len; ++i) {
  107. switch (str[i]) {
  108. case '<': ++left; break;
  109. case '>': ++right; break;
  110. case '&': ++amp; break;
  111. case '\'': ++apos; break;
  112. case '\"': ++quote; break;
  113. default: break;
  114. }
  115. }
  116. free((void*)str);
  117. return xmlrpc_build_value(envP, "{s:i,s:i,s:i,s:i,s:i}",
  118. "ctLeftAngleBrackets", left,
  119. "ctRightAngleBrackets", right,
  120. "ctAmpersands", amp,
  121. "ctApostrophes", apos,
  122. "ctQuotes", quote);
  123. }
  124. /*=========================================================================
  125. ** validator1.easyStructTest
  126. **=========================================================================
  127. */
  128. static xmlrpc_value *
  129. easy_struct(xmlrpc_env * const envP,
  130. xmlrpc_value * const paramArrayP,
  131. void * const user_data) {
  132. xmlrpc_int32 larry, moe, curly;
  133. /* Parse our argument array and get the stooges. */
  134. xmlrpc_decompose_value(envP, paramArrayP, "({s:i,s:i,s:i,*})",
  135. "larry", &larry,
  136. "moe", &moe,
  137. "curly", &curly);
  138. RETURN_IF_FAULT(envP);
  139. /* Return our result. */
  140. return xmlrpc_build_value(envP, "i", larry + moe + curly);
  141. }
  142. /*=========================================================================
  143. ** validator1.echoStructTest
  144. **=========================================================================
  145. */
  146. static xmlrpc_value *
  147. echo_struct(xmlrpc_env * const envP,
  148. xmlrpc_value * const paramArrayP,
  149. void * const user_data) {
  150. xmlrpc_value * sP;
  151. /* Parse our argument array. */
  152. xmlrpc_decompose_value(envP, paramArrayP, "(S)", &sP);
  153. RETURN_IF_FAULT(envP);
  154. return sP; /* We transfer our reference on '*sP' to Caller */
  155. }
  156. /*=========================================================================
  157. ** validator1.manyTypesTest
  158. **=========================================================================
  159. */
  160. static xmlrpc_value *
  161. many_types(xmlrpc_env * const env,
  162. xmlrpc_value * const param_array,
  163. void * const user_data) {
  164. /* Create another reference to our argument array and return it as is. */
  165. xmlrpc_INCREF(param_array);
  166. return param_array;
  167. }
  168. /*=========================================================================
  169. ** validator1.moderateSizeArrayCheck
  170. **=========================================================================
  171. */
  172. static void
  173. concatenate(xmlrpc_env * const envP,
  174. const char * const str1,
  175. size_t const str1_len,
  176. const char * const str2,
  177. size_t const str2_len,
  178. xmlrpc_value ** const resultPP) {
  179. /* Concatenate the two strings. */
  180. char * buffer;
  181. buffer = (char*) malloc(str1_len + str2_len);
  182. if (!buffer) {
  183. xmlrpc_env_set_fault(envP, 1,
  184. "Couldn't allocate concatenated string");
  185. } else {
  186. memcpy(buffer, str1, str1_len);
  187. memcpy(&buffer[str1_len], str2, str2_len);
  188. *resultPP = xmlrpc_build_value(envP, "s#",
  189. buffer, str1_len + str2_len);
  190. free(buffer);
  191. }
  192. }
  193. static xmlrpc_value *
  194. moderate_array(xmlrpc_env * const envP,
  195. xmlrpc_value * const paramArrayP,
  196. void * const user_data) {
  197. xmlrpc_value * retval;
  198. xmlrpc_value * arrayP;
  199. /* Parse our argument array. */
  200. xmlrpc_decompose_value(envP, paramArrayP, "(A)", &arrayP);
  201. if (!envP->fault_occurred) {
  202. int const size = xmlrpc_array_size(envP, arrayP);
  203. if (!envP->fault_occurred) {
  204. /* Get our first string. */
  205. xmlrpc_value * const firstItemP =
  206. xmlrpc_array_get_item(envP, arrayP, 0);
  207. if (!envP->fault_occurred) {
  208. const char * str1;
  209. size_t str1_len;
  210. xmlrpc_read_string_lp(envP, firstItemP, &str1_len, &str1);
  211. if (!envP->fault_occurred) {
  212. /* Get our last string. */
  213. xmlrpc_value * const lastItemP =
  214. xmlrpc_array_get_item(envP, arrayP, size - 1);
  215. if (!envP->fault_occurred) {
  216. const char * str2;
  217. size_t str2_len;
  218. xmlrpc_read_string_lp(envP, lastItemP,
  219. &str2_len, &str2);
  220. if (!envP->fault_occurred) {
  221. concatenate(envP, str1, str1_len, str2, str2_len,
  222. &retval);
  223. free((char*)str2);
  224. }
  225. }
  226. free((char*)str1);
  227. }
  228. }
  229. }
  230. xmlrpc_DECREF(arrayP);
  231. }
  232. return retval;
  233. }
  234. /*=========================================================================
  235. ** validator1.nestedStructTest
  236. **=========================================================================
  237. */
  238. static xmlrpc_value *
  239. nested_struct(xmlrpc_env * const envP,
  240. xmlrpc_value * const paramArrayP,
  241. void * const user_data) {
  242. xmlrpc_value * yearsP;
  243. xmlrpc_value * retval;
  244. /* Parse our argument array. */
  245. xmlrpc_decompose_value(envP, paramArrayP, "(S)", &yearsP);
  246. if (envP->fault_occurred)
  247. retval = NULL;
  248. else {
  249. /* Get values of larry, moe and curly for 2000-04-01. */
  250. xmlrpc_int32 larry, moe, curly;
  251. xmlrpc_decompose_value(envP, yearsP,
  252. "{s:{s:{s:{s:i,s:i,s:i,*},*},*},*}",
  253. "2000", "04", "01",
  254. "larry", &larry,
  255. "moe", &moe,
  256. "curly", &curly);
  257. if (envP->fault_occurred)
  258. retval = NULL;
  259. else
  260. retval = xmlrpc_build_value(envP, "i", larry + moe + curly);
  261. xmlrpc_DECREF(yearsP);
  262. }
  263. return retval;
  264. }
  265. /*=========================================================================
  266. ** validator1.simpleStructReturnTest
  267. **=========================================================================
  268. */
  269. static xmlrpc_value *
  270. struct_return(xmlrpc_env * const envP,
  271. xmlrpc_value * const paramArrayP,
  272. void * const user_data) {
  273. xmlrpc_int32 i;
  274. xmlrpc_decompose_value(envP, paramArrayP, "(i)", &i);
  275. RETURN_IF_FAULT(envP);
  276. return xmlrpc_build_value(envP, "{s:i,s:i,s:i}",
  277. "times10", (xmlrpc_int32) i * 10,
  278. "times100", (xmlrpc_int32) i * 100,
  279. "times1000", (xmlrpc_int32) i * 1000);
  280. }
  281. /*=========================================================================
  282. ** main
  283. **=========================================================================
  284. */
  285. int main(int const argc,
  286. const char ** const argv) {
  287. xmlrpc_server_abyss_parms serverparm;
  288. xmlrpc_registry * registryP;
  289. xmlrpc_env env;
  290. if (argc-1 != 1) {
  291. fprintf(stderr, "You must specify 1 argument: The TCP port "
  292. "number on which the server will accept connections "
  293. "for RPCs. You specified %d arguments.\n", argc-1);
  294. exit(1);
  295. }
  296. xmlrpc_env_init(&env);
  297. registryP = xmlrpc_registry_new(&env);
  298. xmlrpc_registry_add_method(
  299. &env, registryP, NULL, "validator1.arrayOfStructsTest",
  300. &array_of_structs, NULL);
  301. xmlrpc_registry_add_method(
  302. &env, registryP, NULL, "validator1.countTheEntities",
  303. &count_entities, NULL);
  304. xmlrpc_registry_add_method(
  305. &env, registryP, NULL, "validator1.easyStructTest",
  306. &easy_struct, NULL);
  307. xmlrpc_registry_add_method(
  308. &env, registryP, NULL, "validator1.echoStructTest",
  309. &echo_struct, NULL);
  310. xmlrpc_registry_add_method(
  311. &env, registryP, NULL, "validator1.manyTypesTest",
  312. &many_types, NULL);
  313. xmlrpc_registry_add_method(
  314. &env, registryP, NULL, "validator1.moderateSizeArrayCheck",
  315. &moderate_array, NULL);
  316. xmlrpc_registry_add_method(
  317. &env, registryP, NULL, "validator1.nestedStructTest",
  318. &nested_struct, NULL);
  319. xmlrpc_registry_add_method(
  320. &env, registryP, NULL, "validator1.simpleStructReturnTest",
  321. &struct_return, NULL);
  322. serverparm.config_file_name = NULL;
  323. serverparm.registryP = registryP;
  324. serverparm.port_number = atoi(argv[1]);
  325. serverparm.log_file_name = NULL;
  326. printf("Running XML-RPC server...\n");
  327. xmlrpc_server_abyss(&env, &serverparm, XMLRPC_APSIZE(log_file_name));
  328. /* This never gets executed. */
  329. return 0;
  330. }