1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2014 Kannel Group
5  * Copyright (c) 1998-2001 WapIT Ltd.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  *    if any, must include the following acknowledgment:
22  *       "This product includes software developed by the
23  *        Kannel Group (http://www.kannel.org/)."
24  *    Alternately, this acknowledgment may appear in the software itself,
25  *    if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Kannel" and "Kannel Group" must not be used to
28  *    endorse or promote products derived from this software without
29  *    prior written permission. For written permission, please
30  *    contact org@kannel.org.
31  *
32  * 5. Products derived from this software may not be called "Kannel",
33  *    nor may "Kannel" appear in their name, without prior written
34  *    permission of the Kannel Group.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS
40  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
41  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
42  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
46  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Kannel Group.  For more information on
51  * the Kannel Group, please see <http://www.kannel.org/>.
52  *
53  * Portions of this software are based upon software originally written at
54  * WapIT Ltd., Helsinki, Finland for the Kannel project.
55  */
56 
57 /*
58  * xmlrpc.h - XML-RPC functions
59  *
60  * Functions to handle XML-RPC structure - building and parsing
61  *
62  * XML-RPC is HTTP-based XML defination to handle remote procedure calls,
63  * and is defined in http://www.xml-rpc.org
64  *
65  * The current implementation is not yet ready (it does not, for example,
66  *  do any parsing nor building the tree), and is not used for any real use,
67  * yet, but probably future interfaces might be able to use this, too
68  *
69  *
70  * Kalle Marjola 2001 for project Kannel
71  * Robert Ga�ach <robert.galach@my.tenbit.pl>
72  */
73 
74 #ifndef __XMLRPC_H
75 #define __XMLRPC_H
76 
77 #include "gwlib/gwlib.h"
78 
79 /*
80  * types and structures defined by www.xml-rpc.com
81  */
82 typedef struct xmlrpc_document XMLRPCDocument;
83 typedef struct xmlrpc_value XMLRPCValue;
84 typedef struct xmlrpc_scalar XMLRPCScalar;
85 
86 enum {
87     xr_undefined, xr_scalar, xr_array, xr_struct,
88     xr_string, xr_int, xr_bool, xr_double, xr_date, xr_base64,
89     xr_methodcall, xr_methodresponse
90 };
91 
92 /*
93  * status codes while parsing
94  */
95 enum {
96     XMLRPC_COMPILE_OK,
97     XMLRPC_XMLPARSE_FAILED,
98     XMLRPC_PARSING_FAILED
99 };
100 
101 
102 
103 /*** DOCUMENTS ***/
104 
105 /* Create new XMLRPCDocument object of undefined_type  */
106 XMLRPCDocument *xmlrpc_doc_create(void);
107 /* Create new MethodCall with given name */
108 XMLRPCDocument *xmlrpc_doc_create_call(Octstr *name);
109 /* Create new MethodResponse */
110 XMLRPCDocument *xmlrpc_doc_create_response(void);
111 /* Create new fault MethodResponse with given code and fault string */
112 XMLRPCDocument *xmlrpc_doc_create_faultresponse(long faultcode, Octstr *faultstring);
113 
114 /* Create new XMLRPCDocument object from given body of text/xml,
115  * d_type is expected document type: xr_methodcall, xr_methodresponse
116    or xr_undefined if any
117  */
118 XMLRPCDocument *xmlrpc_doc_parse(Octstr *post_body, int d_type);
119 
120 /* Destroy XMLRPCDocument object */
121 void xmlrpc_doc_destroy(XMLRPCDocument *xrdoc, int d_type);
122 
123 /* Add a scalar param to XMLRPCDocument object.
124  * d_type is expected document type: xr_methodcall or xr_methodresponse.
125  * Return 0 if ok or -1 if something wrong (e.g. xrdoc is null or faultresponse)
126  */
127 int xmlrpc_doc_add_scalar(XMLRPCDocument *xrdoc, int d_type, int type, void *arg);
128 
129 /* Add given XMLRPCValue param to XMLRPCDocument object.
130  * d_type is expected document type: xr_methodcall or xr_methodresponse.
131  * Return 0 if ok or -1 if something wrong.
132  * NOTE that value is NOT duplicated
133  */
134 int xmlrpc_doc_add_value(XMLRPCDocument *xrdoc, int d_type, XMLRPCValue *value);
135 
136 /* Create Octstr (text/xml string) out of given XMLRPCDocument.
137  * d_type is expected document type.
138  * level is the indent width.
139  * Caller must free returned Octstr.
140  */
141 Octstr *xmlrpc_doc_print(XMLRPCDocument *xrdoc, int d_type, int level);
142 
143 /* Send XMLRPCDocument to given url with given headers.
144  * d_type is expected document type.
145  * Note: adds XML-RPC specified headers into given list if needed.
146  *       and if NULL when this function called, automatically generated
147  *
148  * Return 0 if all went fine, -1 if failure. As user reference, uses *void
149  */
150 int xmlrpc_doc_send(XMLRPCDocument *xrdoc, int d_type, HTTPCaller *http_ref,
151 		    Octstr *url, List *headers, void *ref);
152 
153 
154 /*** METHOD CALLS ***/
155 
156 /* Create new MethodCall with given name and no params */
157 #define xmlrpc_create_call(method) \
158             xmlrpc_doc_create_call(method)
159 
160 /* Create new MethodCall from given body of text/xml */
161 #define xmlrpc_parse_call(post_body) \
162             xmlrpc_doc_parse(post_body, xr_methodcall)
163 
164 /* Destroy MethodCall */
165 #define xmlrpc_destroy_call(call) \
166             xmlrpc_doc_destroy(call, xr_methodcall)
167 
168 /* Add a scalar param to MethodCall.
169  * type is scalar type: xr_string, xr_int, xr_bool, xr_double, xr_date or xr_base64
170  * arg is pointer to value of given type: Octstr*, long*, int*, double*, Octstr* or Octstr*
171  * respectively
172  * Return 0 if ok or -1 if something wrong.
173  */
174 #define xmlrpc_add_call_scalar(call, type, arg) \
175             xmlrpc_doc_add_scalar(call, xr_methodcall, type, arg)
176 
177 /* Add given XMLRPCValue param to MethodCall.
178  * Return 0 if ok or -1 if something wrong.
179  * NOTE: value is NOT duplicated
180  */
181 #define xmlrpc_add_call_value(call, value) \
182             xmlrpc_doc_add_value(call, xr_methodcall, value)
183 
184 /* Create Octstr (text/xml string) out of given MethodCall. Caller
185  * must free returned Octstr
186  */
187 #define xmlrpc_print_call(call) \
188             xmlrpc_doc_print(call, xr_methodcall, 0)
189 
190 /* Send MethodCall to given url with given headers.
191  * d_type is expected document type.
192  * Note: adds XML-RPC specified headers into given list if needed.
193  *       and if NULL when this function called, automatically generated
194  *
195  * Return 0 if all went fine, -1 if failure. As user reference, uses *void
196  */
197 #define xmlrpc_send_call(call,http_ref, url, headers, ref) \
198             xmlrpc_doc_send(call, xr_methodcall, http_ref, url, headers, ref)
199 
200 /* Return the name of the method requested or NULL if document is not method call */
201 Octstr *xmlrpc_get_call_name(XMLRPCDocument *call);
202 
203 
204 
205 /*** METHOD RESPONSES ***/
206 
207 /* Create a new MethodResponse with no param value */
208 #define xmlrpc_create_response() \
209             xmlrpc_doc_create_response()
210 
211 /* Create a new fault MethodResponse with given faultcode and faultstring */
212 #define xmlrpc_create_faultresponse(faultcode, faultstring) \
213             xmlrpc_doc_create_faultresponse(faultcode, faultstring)
214 
215 /* Create a new MethodResponse from given text/xml string */
216 #define xmlrpc_parse_response(post_body) \
217             xmlrpc_doc_parse(post_body, xr_methodresponse)
218 
219 /* Destroy MethodResponse */
220 #define xmlrpc_destroy_response(response) \
221             xmlrpc_doc_destroy(response, xr_methodresponse)
222 
223 /* Add a scalar param to MethodResponse.
224  * type is scalar type: xr_string, xr_int, xr_bool, xr_double, xr_date or xr_base64
225  * arg is pointer to value of given type: Octstr*, long*, int*, double*, Octstr* or Octstr*
226  * respectively
227  * Return 0 if ok or -1 if something wrong.
228  */
229 #define xmlrpc_add_response_scalar(response, type, arg) \
230             xmlrpc_doc_add_scalar(response, xr_methodresponse, type, arg)
231 
232 /* Add given XMLRPCValue param to MethodResponse.
233  * Return 0 if ok or -1 if something wrong.
234  * NOTE: value is NOT duplicated
235  */
236 #define xmlrpc_add_response_value(response, value) \
237             xmlrpc_doc_add_value(response, xr_methodresponse, value)
238 
239 /* Create Octstr (text/xml string) out of given MethodCall. Caller
240  * must free returned Octstr
241  */
242 #define xmlrpc_print_response(response) \
243             xmlrpc_doc_print(response, xr_methodresponse, 0)
244 
245 /* Send MethodResponse to given url with given headers.
246  * d_type is expected document type.
247  * Note: adds XML-RPC specified headers into given list if needed.
248  *       and if NULL when this function called, automatically generated
249  *
250  * Return 0 if all went fine, -1 if failure. As user reference, uses *void
251  */
252 #define xmlrpc_send_response(response, http_ref, url, headers, ref) \
253             xmlrpc_doc_send(call, xr_methodresponse, http_ref, url, headers, ref)
254 
255 
256 
257 /*** PARAMS HANDLING ***/
258 
259 /* Return -1 if XMLRPCDocument can't have params or number of params */
260 int xmlrpc_count_params(XMLRPCDocument *xrdoc);
261 
262 /* Return i'th MethodCall/MethodResponse param
263  * or NULL if something wrong
264  */
265 XMLRPCValue *xmlrpc_get_param(XMLRPCDocument *xrdoc, int i);
266 
267 /* Return type of i'th MethodCall/MethodResponse param: xr_scalar, xr_array or xr_struct
268  * or -1 if no param
269  */
270 int xmlrpc_get_type_param(XMLRPCDocument *xrdoc, int i);
271 
272 /* Return content of i'th MethodCall/MethodResponse param:
273  * XMLRPCScalar if xr_scalar, List of XMLRPCValues if xr_array
274  * or Dict of XMLRPCValues if xr_struct (member names as keys)
275  * or NULL if no param
276  */
277 void *xmlrpc_get_content_param(XMLRPCDocument *xrdoc, int i);
278 
279 /* Identify d_type of given XMLRPCDocument and add a scalar param.
280  * type is scalar type: xr_string, xr_int, xr_bool, xr_double, xr_date or xr_base64
281  * arg is pointer to value of given type: Octstr*, long*, int*, double*, Octstr* or Octstr*
282  * respectively
283  * Return 0 if ok or -1 if something wrong.
284  */
285 #define xmlrpc_add_scalar_param(xrdoc, type, arg) \
286             xmlrpc_doc_add_scalar(xrdoc, xr_undefined, type, arg)
287 
288 /* Identify d_type of given XMLRPCDocument and add XMLRPCValue param.
289  * Return 0 if ok or -1 if something wrong.
290  * NOTE: value is NOT duplicated
291  */
292 #define xmlrpc_add_param(xrdoc, value) \
293             xmlrpc_doc_add_value(xrdoc, xr_undefined, value)
294 
295 
296 
297 /*** VALUES HANDLING ***/
298 
299 /* Create a new XMLRPCValue object of undefined type */
300 XMLRPCValue *xmlrpc_value_create(void);
301 
302 /* Destroy given XMLRPCValue object */
303 void xmlrpc_value_destroy(XMLRPCValue *val);
304 
305 /* Wrapper for destroy */
306 void xmlrpc_value_destroy_item(void *val);
307 
308 /* Set type of XMLRPCValue: xr_scalar, xr_array or xr_struct
309  * Return 0 if ok or -1 if something wrong.
310  */
311 int xmlrpc_value_set_type(XMLRPCValue *val, int v_type);
312 
313 /* Set XMLRPCValue content:
314  * XMLRPCScalar if xr_scalar, List of XMLRPCValues if xr_array
315  * or Dict of XMLRPCValues if xr_struct (member names as keys)
316  * Return 0 if ok or -1 if something wrong.
317  */
318 int xmlrpc_value_set_content(XMLRPCValue *val, void *content);
319 
320 /* Return type of XMLRPCValue: xr_scalar, xr_array or xr_struct */
321 int xmlrpc_value_get_type(XMLRPCValue *val);
322 
323 /* Return leaf type of XMLRPCValue:
324  * as above, but if value is xr_scalar return type of scalar
325  */
326 int xmlrpc_value_get_type_smart(XMLRPCValue *val);
327 
328 /* Return XMLRPCValue content:
329  * XMLRPCScalar if xr_scalar, List of XMLRPCValues if xr_array
330  * or Dict of XMLRPCValues if xr_struct (member names as keys)
331  * or NULL if something wrong.
332  */
333 void *xmlrpc_value_get_content(XMLRPCValue *val);
334 
335 /* Create Octstr (text/xml string) out of given XMLRPCValue. Caller
336  * must free returned Octstr
337  */
338 Octstr *xmlrpc_value_print(XMLRPCValue *val, int level);
339 
340 
341 /*** STRUCT VALUE HANDLING ***/
342 
343 /* Create a new XMLRPCValue object of xr_struct type.
344  * size is expected number of struct members
345  */
346 XMLRPCValue *xmlrpc_create_struct_value(int size);
347 
348 /* Return -1 if not a struct or number of members */
349 long xmlrpc_count_members(XMLRPCValue *xrstruct);
350 
351 /* Add member with given name and value to the struct */
352 int xmlrpc_add_member(XMLRPCValue *xrstruct, Octstr *name, XMLRPCValue *value);
353 
354 /* Add member with given name and scalar value built with type and arg to the struct */
355 int xmlrpc_add_member_scalar(XMLRPCValue *xrstruct, Octstr *name, int type, void *arg);
356 
357 /* Return value of member with given name or NULL if not found */
358 XMLRPCValue *xmlrpc_get_member(XMLRPCValue *xrstruct, Octstr *name);
359 
360 /* Return type of member with given name (xr_scalar, xr_array or xr_struct)
361  * or -1 if not found
362  */
363 int xmlrpc_get_member_type(XMLRPCValue *xrstruct, Octstr *name);
364 
365 /* Return content of member with given name:
366  * XMLRPCScalar if xr_scalar, List of XMLRPCValues if xr_array
367  * or Dict of XMLRPCValues if xr_struct (member names as keys)
368  * or NULL if not found.
369  */
370 void *xmlrpc_get_member_content(XMLRPCValue *xrstruct, Octstr *name);
371 
372 
373 /* Create Octstr (text/xml string) out of struct. Caller
374  * must free returned Octstr.
375  */
376 Octstr *xmlrpc_print_struct(Dict *members,  int level);
377 
378 
379 /*** ARRAY VALUE HANDLING ***/
380 
381 /* Create a new XMLRPCValue object of xr_array type. */
382 XMLRPCValue *xmlrpc_create_array_value(void);
383 
384 /* Return -1 if not an array or number of elements */
385 int xmlrpc_count_elements(XMLRPCValue *xrarray);
386 
387 /* Add XMLRPCValue element to the end of array */
388 int xmlrpc_add_element(XMLRPCValue *xrarray, XMLRPCValue *value);
389 
390 /* Build scalar XMLRPCValue with type and arg,
391  *and add this element to the end of array
392  */
393 int xmlrpc_add_element_scalar(XMLRPCValue *xrarray, int type, void *arg);
394 
395 /* Return value of i'th element in array or NULL if something wrong*/
396 XMLRPCValue *xmlrpc_get_element(XMLRPCValue *xrarray, int i);
397 
398 /* Return type of i'th element in array (xr_scalar, xr_array or xr_struct)
399  * or -1 if not found
400  */
401 int xmlrpc_get_element_type(XMLRPCValue *xrarray, int i);
402 
403 /* Return content of i'th element:
404  * XMLRPCScalar if xr_scalar, List of XMLRPCValues if xr_array
405  * or Dict of XMLRPCValues if xr_struct (member names as keys)
406  * or NULL if not found.
407  */
408 void *xmlrpc_get_element_content(XMLRPCValue *xrarray, int i);
409 
410 /* Create Octstr (text/xml string) out of array. Caller
411  * must free returned Octstr.
412  */
413 Octstr *xmlrpc_print_array(List *elements,  int level);
414 
415 
416 /*** SCALAR HANDLING ***/
417 
418 /* Create a new scalar of given type and value
419  * (which must be in right format)
420  * type is scalar type: xr_string, xr_int, xr_bool, xr_double, xr_date or xr_base64
421  * arg is pointer to value of given type: Octstr*, long*, int*, double*, Octstr* or Octstr*
422  * respectively
423  * Return NULL if something wrong.
424  */
425 XMLRPCScalar *xmlrpc_scalar_create(int type, void *arg);
426 
427 /* Destroy XMLRPCScalar */
428 void xmlrpc_scalar_destroy(XMLRPCScalar *scalar);
429 
430 /* Return type of scalar or -1 if scalar is NULL */
431 int xmlrpc_scalar_get_type(XMLRPCScalar *scalar);
432 
433 /* Return content of scalar
434  * s_type is expected type of scalar
435  */
436 void *xmlrpc_scalar_get_content(XMLRPCScalar *scalar, int s_type);
437 
438 /* Create Octstr (text/xml string) out of scalar. Caller
439  * must free returned Octstr.
440  */
441 Octstr *xmlrpc_scalar_print(XMLRPCScalar *scalar, int level);
442 
443 /* Wrappers to get scalar content of proper type
444  * NOTE: returned values are copies, caller must free returned Octstr
445  */
446 #define xmlrpc_scalar_get_double(scalar) \
447             *(double *)xmlrpc_scalar_get_content(scalar, xr_double)
448 
449 #define xmlrpc_scalar_get_int(scalar) \
450             *(long *)xmlrpc_scalar_get_content(scalar, xr_int)
451 
452 #define xmlrpc_scalar_get_bool(scalar) \
453             *(int *)xmlrpc_scalar_get_content(scalar, xr_bool)
454 
455 #define xmlrpc_scalar_get_date(scalar) \
456             octstr_duplicate((Octstr *)xmlrpc_scalar_get_content(scalar, xr_date))
457 
458 #define xmlrpc_scalar_get_string(scalar) \
459             octstr_duplicate((Octstr *)xmlrpc_scalar_get_content(scalar, xr_string))
460 
461 #define xmlrpc_scalar_get_base64(scalar) \
462             octstr_duplicate((Octstr *)xmlrpc_scalar_get_content(scalar, xr_base64))
463 
464 
465 /*** SCALAR VALUE HANDLING ***/
466 
467 /* Create XMLRPCScalar with type and arg,
468  * and then create XMLRPCValue with xr_scalar type and
469  * created XMLRPCScalar as content
470  */
471 XMLRPCValue *xmlrpc_create_scalar_value(int type, void *arg);
472 
473 /* As above, but scalar is xr_double type */
474 XMLRPCValue *xmlrpc_create_double_value(double val);
475 
476 /* As above, but scalar is xr_int type */
477 XMLRPCValue *xmlrpc_create_int_value(long val);
478 
479 /* As above, but scalar is xr_string type */
480 XMLRPCValue *xmlrpc_create_string_value(Octstr *val);
481 
482 /* Return type of scalar in given XMLRPCValue */
483 #define xmlrpc_get_scalar_value_type(value) \
484             xmlrpc_scalar_get_type(xmlrpc_value_get_content(value))
485 
486 /* Wrappers to get scalar content of proper type from XMLRPCValue */
487 #define xmlrpc_get_double_value(value) \
488             xmlrpc_scalar_get_double(xmlrpc_value_get_content(value))
489 #define xmlrpc_get_int_value(value) \
490             xmlrpc_scalar_get_int(xmlrpc_value_get_content(value))
491 #define xmlrpc_get_string_value(value) \
492             xmlrpc_scalar_get_string(xmlrpc_value_get_content(value))
493 #define xmlrpc_get_base64_value(value) \
494             xmlrpc_scalar_get_base64(xmlrpc_value_get_content(value))
495 
496 
497 /*** FAULT HANDLING ***/
498 
499 /* Return 1 if XMLRPCDocument is fault MethodResponse */
500 int xmlrpc_is_fault(XMLRPCDocument *response);
501 
502 /* Return faultcode from fault MethodResponse
503  * or -1 if XMLRPCDocument is not valid fault MethodResponse
504  */
505 long xmlrpc_get_faultcode(XMLRPCDocument *faultresponse);
506 
507 /* Return faultstring from fault MethodResponse
508  * or NULL if XMLRPCDocument is not valid fault MethodResponse
509  */
510 Octstr *xmlrpc_get_faultstring(XMLRPCDocument *faultresponse);
511 
512 
513 
514 /*** PARSE STATUS HANDLING***/
515 
516 /*
517  * Check if parsing had any errors, return status code of parsing by
518  * returning one of the following:
519  *   XMLRPC_COMPILE_OK,
520  *   XMLRPC_XMLPARSE_FAILED,
521  *   XMLRPC_PARSING_FAILED
522  *   -1 if call has been NULL
523  */
524 int xmlrpc_parse_status(XMLRPCDocument *xrdoc);
525 
526 /* Return parser error string if parse_status != XMLRPC_COMPILE_OK */
527 /* return NULL if no error occured or no error string was available */
528 Octstr *xmlrpc_parse_error(XMLRPCDocument *xrdoc);
529 
530 #endif
531