1 /* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
3 ** Redistribution and use in source and binary forms, with or without
4 ** modification, are permitted provided that the following conditions
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.
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
27 /*============================================================================
28 xmlrpc_server_validatee
29 ==============================================================================
31 This program runs an XMLRPC server, using the Xmlrpc-c libraries.
33 The server implements the methods that the Userland Validator1 test suite
34 invokes, which are supposed to exercise a broad range of XMLRPC server
37 Coments here used to say you could get information about Validator1
38 from <http://validator.xmlrpc.com/>, but as of 2004.09.25, there's nothing
39 there (there's a web server, but it is not configured to serve that
42 ============================================================================*/
48 #include <xmlrpc-c/base.h>
49 #include <xmlrpc-c/server.h>
50 #include <xmlrpc-c/server_abyss.h>
52 #include "config.h" /* information about this build environment */
54 #define RETURN_IF_FAULT(env) \
56 if ((env)->fault_occurred) \
61 /*=========================================================================
62 ** validator1.arrayOfStructsTest
63 **=========================================================================
67 array_of_structs(xmlrpc_env * const envP,
68 xmlrpc_value * const param_array,
69 void * const user_data ATTR_UNUSED) {
72 xmlrpc_value * retval;
74 xmlrpc_decompose_value(envP, param_array, "(A)", &array);
75 if (envP->fault_occurred)
78 /* Add up all the struct elements named "curly". */
80 size = xmlrpc_array_size(envP, array);
81 if (envP->fault_occurred)
87 for (i = 0; i < size && !envP->fault_occurred; ++i) {
89 strct = xmlrpc_array_get_item(envP, array, i);
90 if (!envP->fault_occurred) {
92 xmlrpc_decompose_value(envP, strct, "{s:i,*}",
94 if (!envP->fault_occurred)
99 if (envP->fault_occurred)
102 retval = xmlrpc_build_value(envP, "i", sum);
109 /*=========================================================================
110 ** validator1.countTheEntities
111 **=========================================================================
114 static xmlrpc_value *
115 count_entities(xmlrpc_env * const env,
116 xmlrpc_value * const param_array,
117 void * const user_data ATTR_UNUSED) {
120 xmlrpc_int32 left, right, amp, apos, quote;
122 xmlrpc_decompose_value(env, param_array, "(s#)", &str, &len);
123 RETURN_IF_FAULT(env);
125 left = right = amp = apos = quote = 0;
126 for (i = 0; i < len; i++) {
128 case '<': left++; break;
129 case '>': right++; break;
130 case '&': amp++; break;
131 case '\'': apos++; break;
132 case '\"': quote++; break;
138 return xmlrpc_build_value(env, "{s:i,s:i,s:i,s:i,s:i}",
139 "ctLeftAngleBrackets", left,
140 "ctRightAngleBrackets", right,
142 "ctApostrophes", apos,
148 /*=========================================================================
149 ** validator1.easyStructTest
150 **=========================================================================
153 static xmlrpc_value *
154 easy_struct(xmlrpc_env * const env,
155 xmlrpc_value * const param_array,
156 void * const user_data ATTR_UNUSED) {
158 xmlrpc_int32 larry, moe, curly;
160 /* Parse our argument array and get the stooges. */
161 xmlrpc_decompose_value(env, param_array, "({s:i,s:i,s:i,*})",
165 RETURN_IF_FAULT(env);
167 /* Return our result. */
168 return xmlrpc_build_value(env, "i", larry + moe + curly);
172 /*=========================================================================
173 ** validator1.echoStructTest
174 **=========================================================================
177 static xmlrpc_value *
178 echo_struct(xmlrpc_env * const env,
179 xmlrpc_value * const param_array,
180 void * const user_data ATTR_UNUSED) {
183 /* Parse our argument array. */
184 xmlrpc_decompose_value(env, param_array, "(S)", &s);
185 RETURN_IF_FAULT(env);
187 return s; /* We transfer our reference on 's' to Caller */
191 /*=========================================================================
192 ** validator1.manyTypesTest
193 **=========================================================================
196 static xmlrpc_value *
197 many_types(xmlrpc_env * const env ATTR_UNUSED,
198 xmlrpc_value * const param_array,
199 void * const user_data ATTR_UNUSED) {
201 /* Create another reference to our argument array and return it as is. */
202 xmlrpc_INCREF(param_array);
207 /*=========================================================================
208 ** validator1.moderateSizeArrayCheck
209 **=========================================================================
213 concatenate(xmlrpc_env * const envP,
214 const char * const str1,
215 size_t const str1_len,
216 const char * const str2,
217 size_t const str2_len,
218 xmlrpc_value ** const resultP) {
220 /* Concatenate the two strings. */
224 buffer = (char*) malloc(str1_len + str2_len);
226 xmlrpc_env_set_fault(envP, 1,
227 "Couldn't allocate concatenated string");
229 memcpy(buffer, str1, str1_len);
230 memcpy(&buffer[str1_len], str2, str2_len);
231 *resultP = xmlrpc_build_value(envP, "s#",
232 buffer, str1_len + str2_len);
239 static xmlrpc_value *
240 moderate_array(xmlrpc_env * const envP,
241 xmlrpc_value * const param_array,
242 void * const user_data ATTR_UNUSED) {
244 xmlrpc_value * retval;
245 xmlrpc_value * arrayP;
247 /* Parse our argument array. */
248 xmlrpc_decompose_value(envP, param_array, "(A)", &arrayP);
249 if (!envP->fault_occurred) {
250 int const size = xmlrpc_array_size(envP, arrayP);
251 if (!envP->fault_occurred) {
252 /* Get our first string. */
253 xmlrpc_value * const firstItemP =
254 xmlrpc_array_get_item(envP, arrayP, 0);
255 if (!envP->fault_occurred) {
258 xmlrpc_read_string_lp(envP, firstItemP, &str1_len, &str1);
259 if (!envP->fault_occurred) {
260 /* Get our last string. */
261 xmlrpc_value * const lastItemP =
262 xmlrpc_array_get_item(envP, arrayP, size - 1);
263 if (!envP->fault_occurred) {
266 xmlrpc_read_string_lp(envP, lastItemP,
268 if (!envP->fault_occurred) {
269 concatenate(envP, str1, str1_len, str2, str2_len,
278 xmlrpc_DECREF(arrayP);
284 /*=========================================================================
285 ** validator1.nestedStructTest
286 **=========================================================================
289 static xmlrpc_value *
290 nested_struct(xmlrpc_env * const envP,
291 xmlrpc_value * const param_array,
292 void * const user_data ATTR_UNUSED) {
294 xmlrpc_value * yearsP;
295 xmlrpc_value * retval;
297 /* Parse our argument array. */
298 xmlrpc_decompose_value(envP, param_array, "(S)", &yearsP);
299 if (envP->fault_occurred)
302 /* Get values of larry, moe and curly for 2000-04-01. */
303 xmlrpc_int32 larry, moe, curly;
304 xmlrpc_decompose_value(envP, yearsP,
305 "{s:{s:{s:{s:i,s:i,s:i,*},*},*},*}",
310 if (envP->fault_occurred)
313 retval = xmlrpc_build_value(envP, "i", larry + moe + curly);
315 xmlrpc_DECREF(yearsP);
321 /*=========================================================================
322 ** validator1.simpleStructReturnTest
323 **=========================================================================
326 static xmlrpc_value *
327 struct_return(xmlrpc_env * const env,
328 xmlrpc_value * const param_array,
329 void * const user_data ATTR_UNUSED) {
333 xmlrpc_decompose_value(env, param_array, "(i)", &i);
334 RETURN_IF_FAULT(env);
336 return xmlrpc_build_value(env, "{s:i,s:i,s:i}",
337 "times10", (xmlrpc_int32) i * 10,
338 "times100", (xmlrpc_int32) i * 100,
339 "times1000", (xmlrpc_int32) i * 1000);
343 /*=========================================================================
345 **=========================================================================
348 int main(int const argc,
349 const char ** const argv) {
351 xmlrpc_server_abyss_parms serverparm;
352 xmlrpc_registry * registryP;
356 fprintf(stderr, "You must specify 1 argument: The TCP port "
357 "number on which the server will accept connections "
358 "for RPCs. You specified %d arguments.\n", argc-1);
362 xmlrpc_env_init(&env);
364 registryP = xmlrpc_registry_new(&env);
366 xmlrpc_registry_add_method(
367 &env, registryP, NULL, "validator1.arrayOfStructsTest",
368 &array_of_structs, NULL);
369 xmlrpc_registry_add_method(
370 &env, registryP, NULL, "validator1.countTheEntities",
371 &count_entities, NULL);
372 xmlrpc_registry_add_method(
373 &env, registryP, NULL, "validator1.easyStructTest",
375 xmlrpc_registry_add_method(
376 &env, registryP, NULL, "validator1.echoStructTest",
378 xmlrpc_registry_add_method(
379 &env, registryP, NULL, "validator1.manyTypesTest",
381 xmlrpc_registry_add_method(
382 &env, registryP, NULL, "validator1.moderateSizeArrayCheck",
383 &moderate_array, NULL);
384 xmlrpc_registry_add_method(
385 &env, registryP, NULL, "validator1.nestedStructTest",
386 &nested_struct, NULL);
387 xmlrpc_registry_add_method(
388 &env, registryP, NULL, "validator1.simpleStructReturnTest",
389 &struct_return, NULL);
391 serverparm.config_file_name = NULL;
392 serverparm.registryP = registryP;
393 serverparm.port_number = atoi(argv[1]);
394 serverparm.log_file_name = NULL;
396 printf("Running XML-RPC server...\n");
398 xmlrpc_server_abyss(&env, &serverparm, XMLRPC_APSIZE(log_file_name));
400 /* This never gets executed. */