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