00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 #include <libxml/xmlmemory.h>
00069 #include <libxml/tree.h>
00070 #include <libxml/debugXML.h>
00071 #include <libxml/encoding.h>
00072
00073 #include "gwlib/gwlib.h"
00074 #include "gwlib/xmlrpc.h"
00075
00076 #define XR_ENABLE_EMPTY_STRING_VALUES
00077
00078 #define OPTIMAL_STRUCT_SIZE 7
00079
00080 typedef struct xmlrpc_methodresponse XMLRPCMethodResponse;
00081 typedef struct xmlrpc_member XMLRPCMember;
00082 typedef struct xmlrpc_methodcall XMLRPCMethodCall;
00083 typedef struct xmlrpc_fault XMLRPCFault;
00084
00085 typedef struct xmlrpc_table_t xmlrpc_table_t;
00086 typedef struct xmlrpc_2table_t xmlrpc_2table_t;
00087
00088
00089 struct xmlrpc_methodcall {
00090 Octstr *method_name;
00091 List *params;
00092 };
00093
00094 struct xmlrpc_methodresponse {
00095 XMLRPCValue *param;
00096 XMLRPCFault *fault;
00097 };
00098
00099 struct xmlrpc_fault {
00100 long f_code;
00101 Octstr *f_string;
00102 };
00103
00104 struct xmlrpc_document {
00105 int d_type;
00106 int parse_status;
00107 Octstr *parse_error;
00108 XMLRPCMethodCall *methodcall;
00109 XMLRPCMethodResponse *methodresponse;
00110 };
00111
00112 struct xmlrpc_value {
00113 int v_type;
00114 XMLRPCScalar *v_scalar;
00115 List *v_array;
00116 Dict *v_struct;
00117 };
00118
00119 struct xmlrpc_member {
00120 Octstr *name;
00121 XMLRPCValue *value;
00122 };
00123
00124 struct xmlrpc_scalar {
00125 int s_type;
00126 Octstr *s_str;
00127 long s_int;
00128 int s_bool;
00129 double s_double;
00130 Octstr *s_date;
00131 Octstr *s_base64;
00132 };
00133
00134 struct xmlrpc_table_t {
00135 char *name;
00136 };
00137
00138 struct xmlrpc_2table_t {
00139 char *name;
00140 int s_type;
00141 };
00142
00143 static xmlrpc_table_t methodcall_elements[] = {
00144 { "METHODNAME" },
00145 { "PARAMS" }
00146 };
00147
00148 static xmlrpc_table_t methodresponse_elements[] = {
00149 { "FAULT" },
00150 { "PARAMS" }
00151 };
00152
00153 static xmlrpc_table_t params_elements[] = {
00154 { "PARAM" }
00155 };
00156
00157 static xmlrpc_table_t param_elements[] = {
00158 { "VALUE" }
00159 };
00160
00161 static xmlrpc_2table_t value_elements[] = {
00162 { "I4", xr_int },
00163 { "INT", xr_int },
00164 { "BOOLEAN", xr_bool },
00165 { "STRING", xr_string },
00166 { "DOUBLE", xr_double },
00167 { "DATETIME.ISO8601", xr_date },
00168 { "BASE64", xr_base64 },
00169 { "STRUCT", xr_struct },
00170 { "ARRAY", xr_array }
00171 };
00172
00173 static xmlrpc_table_t struct_elements[] = {
00174 { "MEMBER" }
00175 };
00176
00177 static xmlrpc_table_t member_elements[] = {
00178 { "NAME" },
00179 { "VALUE" }
00180 };
00181
00182 static xmlrpc_table_t array_elements[] = {
00183 { "DATA" }
00184 };
00185
00186 static xmlrpc_table_t data_elements[] = {
00187 { "VALUE" }
00188 };
00189
00190 static xmlrpc_table_t fault_elements[] = {
00191 { "VALUE" }
00192 };
00193
00194 #define NUMBER_OF_METHODCALL_ELEMENTS \
00195 sizeof(methodcall_elements)/sizeof(methodcall_elements[0])
00196 #define NUMBER_OF_METHODRESPONSE_ELEMENTS \
00197 sizeof(methodresponse_elements)/sizeof(methodresponse_elements[0])
00198 #define NUMBER_OF_PARAMS_ELEMENTS \
00199 sizeof(params_elements)/sizeof(params_elements[0])
00200 #define NUMBER_OF_PARAM_ELEMENTS \
00201 sizeof(param_elements)/sizeof(param_elements[0])
00202 #define NUMBER_OF_VALUE_ELEMENTS \
00203 sizeof(value_elements)/sizeof(value_elements[0])
00204 #define NUMBER_OF_STRUCT_ELEMENTS \
00205 sizeof(struct_elements)/sizeof(struct_elements[0])
00206 #define NUMBER_OF_MEMBER_ELEMENTS \
00207 sizeof(member_elements)/sizeof(member_elements[0])
00208 #define NUMBER_OF_ARRAY_ELEMENTS \
00209 sizeof(array_elements)/sizeof(array_elements[0])
00210 #define NUMBER_OF_DATA_ELEMENTS \
00211 sizeof(data_elements)/sizeof(data_elements[0])
00212 #define NUMBER_OF_FAULT_ELEMENTS \
00213 sizeof(fault_elements)/sizeof(fault_elements[0])
00214
00215
00216
00217
00218
00219
00220 static int parse_document(xmlDocPtr document, XMLRPCDocument *xrdoc);
00221 static int parse_methodcall(xmlDocPtr doc, xmlNodePtr node,
00222 XMLRPCDocument *xrdoc, XMLRPCMethodCall *methodcall);
00223 static int parse_methodcall_element(xmlDocPtr doc, xmlNodePtr node,
00224 XMLRPCDocument *xrdoc, XMLRPCMethodCall *methodcall);
00225 static int parse_methodresponse(xmlDocPtr doc, xmlNodePtr node,
00226 XMLRPCDocument *xrdoc, XMLRPCMethodResponse *methodresponse,
00227 int* n);
00228 static int parse_methodresponse_element(xmlDocPtr doc, xmlNodePtr node,
00229 XMLRPCDocument *xrdoc, XMLRPCMethodResponse *methodresponse);
00230 static int parse_params(xmlDocPtr doc, xmlNodePtr node, XMLRPCDocument *xrdoc,
00231 List *params);
00232 static int parse_params_element(xmlDocPtr doc, xmlNodePtr node,
00233 XMLRPCDocument *xrdoc, List *params);
00234 static int parse_param(xmlDocPtr doc, xmlNodePtr node, XMLRPCDocument *xrdoc,
00235 List *params, int *n);
00236 static int parse_param_element(xmlDocPtr doc, xmlNodePtr node,
00237 XMLRPCDocument *xrdoc, List *params);
00238 static int parse_value(xmlDocPtr doc, xmlNodePtr node, XMLRPCDocument *xrdoc,
00239 XMLRPCValue *value);
00240 static int parse_value_element(xmlDocPtr doc, xmlNodePtr node,
00241 XMLRPCDocument *xrdoc, XMLRPCValue *xrvalue);
00242 static int parse_struct(xmlDocPtr doc, xmlNodePtr node, XMLRPCDocument *xrdoc,
00243 Dict *members);
00244 static int parse_struct_element(xmlDocPtr doc, xmlNodePtr node,
00245 XMLRPCDocument *xrdoc, Dict *members);
00246 static int parse_member(xmlDocPtr doc, xmlNodePtr node, XMLRPCDocument *xrdoc,
00247 XMLRPCMember *member);
00248 static int parse_member_element(xmlDocPtr doc, xmlNodePtr node,
00249 XMLRPCDocument *xrdoc, XMLRPCMember *member);
00250 static int parse_array(xmlDocPtr doc, xmlNodePtr node, XMLRPCDocument *xrdoc,
00251 List *elements);
00252 static int parse_array_element(xmlDocPtr doc, xmlNodePtr node,
00253 XMLRPCDocument *xrdoc, List *elements);
00254 static int parse_data(xmlDocPtr doc, xmlNodePtr node, XMLRPCDocument *xrdoc,
00255 List *elements);
00256 static int parse_data_element(xmlDocPtr doc, xmlNodePtr node,
00257 XMLRPCDocument *xrdoc, List *elements);
00258 static int parse_fault(xmlDocPtr doc, xmlNodePtr node, XMLRPCDocument *xrdoc,
00259 XMLRPCFault *fault);
00260 static int parse_fault_element(xmlDocPtr doc, xmlNodePtr node,
00261 XMLRPCDocument *xrdoc, XMLRPCFault *fault);
00262
00263
00264
00265
00266
00267
00268 static XMLRPCMethodCall *xmlrpc_call_create(Octstr *name)
00269 {
00270 XMLRPCMethodCall *nmsg = gw_malloc(sizeof(XMLRPCMethodCall));
00271
00272 nmsg->method_name = octstr_duplicate(name);
00273 nmsg->params = gwlist_create();
00274
00275 return nmsg;
00276 }
00277
00278 static void xmlrpc_call_destroy(XMLRPCMethodCall *call)
00279 {
00280 if (call == NULL)
00281 return;
00282
00283 octstr_destroy(call->method_name);
00284 gwlist_destroy(call->params, xmlrpc_value_destroy_item);
00285
00286 gw_free(call);
00287 }
00288
00289 static Octstr *xmlrpc_call_get_name(XMLRPCMethodCall *call)
00290 {
00291 return call->method_name;
00292 }
00293
00294 static int xmlrpc_call_add_param(XMLRPCMethodCall *method, XMLRPCValue *value)
00295 {
00296 if (method == NULL || value == NULL)
00297 return -1;
00298
00299 gwlist_produce(method->params, value);
00300 return 0;
00301 }
00302
00303 static Octstr *xmlrpc_call_print(XMLRPCMethodCall *call, int level)
00304 {
00305 Octstr *body, *os_value;
00306 XMLRPCValue *val;
00307 long i;
00308
00309 if (call == NULL || call->method_name == NULL)
00310 return NULL;
00311
00312 body = octstr_format("%*s<methodCall>\n"
00313 "%*s<methodName>%S</methodName>\n",
00314 level, "", level + 2, "", call->method_name);
00315
00316 gwlist_lock(call->params);
00317 if (gwlist_len(call->params) > 0) {
00318 octstr_format_append(body, "%*s<params>\n", level + 2, "");
00319 for (i = 0; i < gwlist_len(call->params); i++) {
00320 val = gwlist_get(call->params, i);
00321 os_value = xmlrpc_value_print(val, level + 6);
00322
00323 if (os_value == NULL) {
00324 error(0, "XMLRPC: Could not print method call, param %ld malformed", i);
00325 octstr_destroy(body);
00326 return NULL;
00327 }
00328 octstr_format_append(body, "%*s<param>\n%S%*s</param>\n",
00329 level + 4, "", os_value, level + 4, "");
00330 octstr_destroy(os_value);
00331 }
00332 octstr_format_append(body, "%*s</params>\n", level + 2, "");
00333 }
00334 gwlist_unlock(call->params);
00335 octstr_format_append(body, "%*s</methodCall>\n", level, "");
00336
00337 return body;
00338 }
00339
00340
00341
00342
00343
00344
00345 static XMLRPCFault *xmlrpc_fault_create(long fcode, Octstr *fstring)
00346 {
00347 XMLRPCFault *fault = gw_malloc(sizeof(XMLRPCFault));
00348
00349 fault->f_code = fcode;
00350 fault->f_string = octstr_duplicate(fstring);
00351
00352 return fault;
00353 }
00354
00355 static void xmlrpc_fault_destroy(XMLRPCFault *fault)
00356 {
00357 if (fault == NULL) return;
00358
00359 octstr_destroy(fault->f_string);
00360 gw_free(fault);
00361 }
00362
00363 static long xmlrpc_fault_get_code(XMLRPCFault *fault)
00364 {
00365 if (fault == NULL) return -1;
00366
00367 return fault->f_code;
00368 }
00369
00370 static Octstr *xmlrpc_fault_get_string(XMLRPCFault *fault)
00371 {
00372 if (fault == NULL) return NULL;
00373
00374 return fault->f_string;
00375 }
00376
00377 static Octstr *xmlrpc_fault_print(XMLRPCFault *fault, int level)
00378 {
00379 Octstr *os;
00380
00381 if (fault == NULL) return NULL;
00382
00383 os = octstr_format("%*s<fault>\n%*s<value>\n"
00384 "%*s<struct>\n"
00385 "%*s<member>\n"
00386 "%*s<name>faultCode</name>\n"
00387 "%*s<value><int>%ld</int></value>\n"
00388 "%*s</member>\n"
00389 "%*s<member>\n"
00390 "%*s<name>faultString</name>\n"
00391 "%*s<value><string>%S</string></value>\n"
00392 "%*s</member>\n"
00393 "%*s</struct>\n"
00394 "%*s</value>\n%*s</fault>\n",
00395 level, "", level+2, "", level+4, "", level+6, "",
00396 level+8, "", level+8, "",
00397 fault->f_code,
00398 level+6, "", level+6, "", level+8, "", level+8, "",
00399 (fault->f_string == NULL ? octstr_imm("/") : fault->f_string),
00400 level+6, "", level+4, "", level+2, "", level, "");
00401
00402 return os;
00403 }
00404
00405
00406
00407
00408
00409
00410
00411 static XMLRPCMethodResponse *xmlrpc_response_create(void)
00412 {
00413 XMLRPCMethodResponse *nmsg = gw_malloc(sizeof(XMLRPCMethodResponse));
00414
00415 nmsg->param = NULL;
00416 nmsg->fault = NULL;
00417
00418 return nmsg;
00419 }
00420
00421 static void xmlrpc_response_destroy(XMLRPCMethodResponse *response)
00422 {
00423 if (response == NULL)
00424 return;
00425
00426 xmlrpc_value_destroy(response->param);
00427 xmlrpc_fault_destroy(response->fault);
00428
00429 gw_free(response);
00430 }
00431
00432 static int xmlrpc_response_add_param(XMLRPCMethodResponse *response, XMLRPCValue *value)
00433 {
00434 if (response == NULL || value == NULL)
00435 return -1;
00436
00437 if (response->param != NULL) {
00438 error(0, "XMLRPC: Method Response may contain only one param.");
00439 return -1;
00440 }
00441 if (response->fault != NULL) {
00442 error(0, "XMLRPC: Fault Response may not contain any param.");
00443 return -1;
00444 }
00445
00446 response->param = value;
00447 return 0;
00448 }
00449
00450 static int xmlrpc_response_is_fault(XMLRPCMethodResponse *response)
00451 {
00452 if (response == NULL || response->fault == NULL)
00453 return 0;
00454
00455 return 1;
00456 }
00457
00458 static long xmlrpc_response_get_faultcode(XMLRPCMethodResponse *faultresponse)
00459 {
00460 if (! xmlrpc_response_is_fault(faultresponse)) {
00461 error(0, "XMLRPC response is not fault response.");
00462 return -1;
00463 }
00464
00465 return xmlrpc_fault_get_code(faultresponse->fault);
00466 }
00467
00468 static Octstr *xmlrpc_response_get_faultstring(XMLRPCMethodResponse *faultresponse)
00469 {
00470 if (! xmlrpc_response_is_fault(faultresponse)) {
00471 error(0, "XMLRPC response is not fault response.");
00472 return NULL;
00473 }
00474
00475 return xmlrpc_fault_get_string(faultresponse->fault);
00476 }
00477
00478
00479 static Octstr *xmlrpc_response_print(XMLRPCMethodResponse *response, int level)
00480 {
00481 Octstr *body = NULL, *os_value = NULL;
00482
00483 if (response->fault == NULL && response->param != NULL) {
00484 os_value = xmlrpc_value_print(response->param, level + 6);
00485
00486 body = octstr_format("%*s<methodResponse>\n"
00487 "%*s<params>\n%*s<param>\n"
00488 "%S"
00489 "%*s</param>\n%*s</params>\n"
00490 "%*s</methodResponse>\n",
00491 level, "", level+2, "", level+4, "", os_value,
00492 level+4, "", level+2, "", level, "");
00493 }
00494 else if (response->fault != NULL && response->param == NULL) {
00495 os_value = xmlrpc_fault_print(response->fault, level + 2);
00496
00497 body = octstr_format("%*s<methodResponse>\n"
00498 "%S"
00499 "%*s</methodResponse>\n",
00500 level, "", os_value, level, "");
00501 }
00502
00503 octstr_destroy(os_value);
00504 return body;
00505 }
00506
00507
00508
00509
00510
00511
00512 XMLRPCDocument *xmlrpc_doc_create(void)
00513 {
00514 XMLRPCDocument *xrdoc = gw_malloc(sizeof(XMLRPCDocument));
00515
00516 xrdoc->d_type = xr_undefined;
00517 xrdoc->parse_status = XMLRPC_COMPILE_OK;
00518 xrdoc->parse_error = NULL;
00519 xrdoc->methodcall = NULL;
00520 xrdoc->methodresponse = NULL;
00521
00522 return xrdoc;
00523 }
00524
00525 XMLRPCDocument *xmlrpc_doc_create_call(Octstr *name)
00526 {
00527 XMLRPCDocument *xrdoc;
00528
00529 xrdoc = xmlrpc_doc_create();
00530 xrdoc->d_type = xr_methodcall;
00531 xrdoc->methodcall = xmlrpc_call_create(name);
00532
00533 return xrdoc;
00534 }
00535
00536 XMLRPCDocument *xmlrpc_doc_create_response(void)
00537 {
00538 XMLRPCDocument *xrdoc;
00539
00540 xrdoc = xmlrpc_doc_create();
00541 xrdoc->d_type = xr_methodresponse;
00542 xrdoc->methodresponse = xmlrpc_response_create();
00543
00544 return xrdoc;
00545 }
00546
00547 XMLRPCDocument *xmlrpc_doc_create_faultresponse(long faultcode, Octstr *faultstring)
00548 {
00549 XMLRPCDocument *xrdoc;
00550 XMLRPCMethodResponse *response;
00551
00552 xrdoc = xmlrpc_doc_create_response();
00553
00554 response = xrdoc->methodresponse;
00555 response->fault = xmlrpc_fault_create(faultcode, faultstring);
00556
00557 return xrdoc;
00558 }
00559
00560 XMLRPCDocument *xmlrpc_doc_parse(Octstr *post_body, int d_type)
00561 {
00562 XMLRPCDocument *xrdoc = xmlrpc_doc_create();
00563 xmlDocPtr pDoc;
00564 size_t size;
00565 char *body;
00566
00567 if (post_body == NULL) {
00568 xrdoc->parse_status = XMLRPC_XMLPARSE_FAILED;
00569 xrdoc->parse_error = octstr_create("XMLRPC: (null) XML document given.");
00570 return xrdoc;
00571 }
00572 xrdoc->d_type = d_type;
00573
00574 octstr_strip_blanks(post_body);
00575 octstr_shrink_blanks(post_body);
00576 size = octstr_len(post_body);
00577 body = octstr_get_cstr(post_body);
00578
00579
00580 pDoc = xmlParseMemory(body, size);
00581 if (!pDoc) {
00582 xrdoc->parse_status = XMLRPC_XMLPARSE_FAILED;
00583 xrdoc->parse_error = octstr_create("XMLRPC: not valid XML document given.");
00584 return xrdoc;
00585 }
00586 parse_document(pDoc, xrdoc);
00587 xmlFreeDoc(pDoc);
00588
00589 return xrdoc;
00590 }
00591
00592
00593 void xmlrpc_doc_destroy(XMLRPCDocument *xrdoc, int d_type)
00594 {
00595 if (xrdoc == NULL)
00596 return;
00597
00598 if (xrdoc->d_type != d_type)
00599 warning(0, "Destroying document with different type then given.");
00600
00601 xmlrpc_call_destroy(xrdoc->methodcall);
00602 xmlrpc_response_destroy(xrdoc->methodresponse);
00603 octstr_destroy(xrdoc->parse_error);
00604
00605 gw_free(xrdoc);
00606 }
00607
00608
00609
00610
00611 int xmlrpc_doc_add_value(XMLRPCDocument *xrdoc, int d_type, XMLRPCValue *value)
00612 {
00613 if (xrdoc == NULL)
00614 return -1;
00615
00616 if (xrdoc->d_type != d_type && d_type != xr_undefined) {
00617 error(0, "Wrong xmlrpc document type. Param not added.");
00618 return -1;
00619 }
00620 if (xrdoc->d_type == xr_methodresponse) {
00621 if (xmlrpc_response_add_param(xrdoc->methodresponse, value) < 0)
00622 return -1;
00623 }
00624 else if (xrdoc->d_type == xr_methodcall) {
00625 if (xmlrpc_call_add_param(xrdoc->methodcall, value) < 0)
00626 return -1;
00627 }
00628 else {
00629 error(0, "Unknown xmlrpc document type. Param not added.");
00630 return -1;
00631 }
00632 return 0;
00633 }
00634
00635
00636
00637
00638 int xmlrpc_doc_add_scalar(XMLRPCDocument *xrdoc, int d_type, int type, void *arg)
00639 {
00640 XMLRPCValue *param;
00641
00642 param = xmlrpc_create_scalar_value(type, arg);
00643 if (xmlrpc_doc_add_value(xrdoc, d_type, param) < 0) {
00644 xmlrpc_value_destroy(param);
00645 return -1;
00646 }
00647 return 0;
00648 }
00649
00650
00651
00652
00653 Octstr *xmlrpc_doc_print(XMLRPCDocument *xrdoc, int d_type, int level)
00654 {
00655 Octstr *body = NULL, *pref = NULL;
00656
00657 if (xrdoc == NULL)
00658 return NULL;
00659
00660 if (xrdoc->d_type != d_type) {
00661 error(0, "Wrong xmlrpc document type.");
00662 return NULL;
00663 }
00664 if (xrdoc->d_type == xr_methodresponse) {
00665 body = xmlrpc_response_print(xrdoc->methodresponse, level);
00666 }
00667 else if (xrdoc->d_type == xr_methodcall) {
00668 body = xmlrpc_call_print(xrdoc->methodcall, level);
00669 }
00670 else {
00671 error(0, "Unknown xmlrpc document type.");
00672 }
00673
00674 if (body != NULL) {
00675 pref = octstr_format("%*s<?xml version=\"1.0\"?>\n", level, "");
00676 octstr_insert(body, pref, 0);
00677 octstr_destroy(pref);
00678 }
00679 return body;
00680 }
00681
00682
00683
00684
00685 int xmlrpc_doc_send(XMLRPCDocument *xrdoc, int d_type, HTTPCaller *http_ref,
00686 Octstr *url, List *headers, void *ref)
00687 {
00688 Octstr *body;
00689 if (http_ref == NULL || xrdoc == NULL)
00690 return -1;
00691
00692 if (xrdoc->d_type != d_type) {
00693 error(0, "Wrong xmlrpc document type.");
00694 return -1;
00695 }
00696
00697 if (headers == NULL)
00698 headers = gwlist_create();
00699
00700 http_header_remove_all(headers, "Content-Type");
00701 http_header_add(headers, "Content-Type", "text/xml");
00702
00703
00704
00705
00706
00707
00708 body = xmlrpc_doc_print(xrdoc, d_type, 0);
00709
00710 http_start_request(http_ref, HTTP_METHOD_POST,
00711 url, headers, body, 0, ref, NULL);
00712
00713 octstr_destroy(body);
00714
00715
00716 return 0;
00717 }
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 XMLRPCValue *xmlrpc_value_create(void)
00729 {
00730 XMLRPCValue *val = gw_malloc(sizeof(XMLRPCValue));
00731
00732 val->v_type = xr_undefined;
00733 val->v_scalar = NULL;
00734 val->v_array = NULL;
00735 val->v_struct = NULL;
00736 return val;
00737 }
00738
00739
00740 void xmlrpc_value_destroy(XMLRPCValue *val)
00741 {
00742 if (val == NULL)
00743 return;
00744
00745 switch(val->v_type) {
00746 case xr_scalar:
00747 xmlrpc_scalar_destroy(val->v_scalar);
00748 break;
00749 case xr_array:
00750 gwlist_destroy(val->v_array, xmlrpc_value_destroy_item);
00751 break;
00752 case xr_struct:
00753 dict_destroy(val->v_struct);
00754 break;
00755 }
00756 gw_free(val);
00757 }
00758
00759
00760 void xmlrpc_value_destroy_item(void *val)
00761 {
00762 xmlrpc_value_destroy(val);
00763 }
00764
00765 int xmlrpc_value_set_type(XMLRPCValue *val, int v_type)
00766 {
00767 if (val == NULL)
00768 return -1;
00769
00770 switch(v_type) {
00771 case xr_scalar:
00772 case xr_array:
00773 case xr_struct:
00774 val->v_type = v_type;
00775 break;
00776 default:
00777 error(0, "XMLRPC: value type not supported.");
00778 return -1;
00779 }
00780
00781 return 0;
00782 }
00783
00784 int xmlrpc_value_set_content(XMLRPCValue *val, void *content)
00785 {
00786 if (val == NULL)
00787 return -1;
00788
00789 switch(val->v_type) {
00790 case xr_scalar:
00791 val->v_scalar = (XMLRPCScalar *)content;
00792 break;
00793 case xr_array:
00794 val->v_array = (List *)content;
00795 break;
00796 case xr_struct:
00797 val->v_struct = (Dict *)content;
00798 break;
00799 default:
00800 error(0, "XMLRPC: value type not supported.");
00801 return -1;
00802 }
00803
00804 return 0;
00805 }
00806
00807 int xmlrpc_value_get_type(XMLRPCValue *val)
00808 {
00809 if (val == NULL)
00810 return -1;
00811
00812 return val->v_type;
00813 }
00814
00815 int xmlrpc_value_get_type_smart(XMLRPCValue *val)
00816 {
00817 int type = xmlrpc_value_get_type(val);
00818 if (type == xr_scalar)
00819 return xmlrpc_get_scalar_value_type(val);
00820
00821 return type;
00822 }
00823
00824 void *xmlrpc_value_get_content(XMLRPCValue *val)
00825 {
00826 if (val == NULL)
00827 return NULL;
00828
00829 switch(val->v_type) {
00830 case xr_scalar:
00831 return val->v_scalar;
00832 case xr_array:
00833 return val->v_array;
00834 case xr_struct:
00835 return val->v_struct;
00836 default:
00837 error(0, "XMLRPC: value type not supported.");
00838 return NULL;
00839 }
00840 }
00841
00842 Octstr *xmlrpc_value_print(XMLRPCValue *val, int level)
00843 {
00844 Octstr *body = NULL, *os = NULL;
00845
00846 if (val == NULL)
00847 return NULL;
00848
00849 switch(val->v_type) {
00850 case xr_scalar:
00851 os = xmlrpc_scalar_print(val->v_scalar, level+2);
00852 break;
00853 case xr_struct:
00854 os = xmlrpc_print_struct(val->v_struct, level+2);
00855 break;
00856 case xr_array:
00857 os = xmlrpc_print_array(val->v_array, level+2);
00858 break;
00859 default:
00860 return NULL;
00861 }
00862
00863 if (os != NULL) {
00864 body = octstr_format("%*s<value>\n%S%*s</value>\n",
00865 level, "", os, level, "");
00866 octstr_destroy(os);
00867 }
00868
00869 return body;
00870 }
00871
00872
00873
00874
00875
00876
00877
00878
00879 XMLRPCScalar *xmlrpc_scalar_create(int type, void *arg)
00880 {
00881 XMLRPCScalar *scalar = gw_malloc(sizeof(XMLRPCScalar));
00882
00883 scalar->s_type = type;
00884 scalar->s_int = 0;
00885 scalar->s_bool = 0;
00886 scalar->s_double = 0.0;
00887 scalar->s_str = NULL;
00888 scalar->s_date = NULL;
00889 scalar->s_base64 = NULL;
00890
00891 if (arg == NULL) {
00892 #ifdef XR_ENABLE_EMPTY_STRING_VALUES
00893 if (scalar->s_type != xr_string) {
00894 #endif
00895 error(0,"XML-RPC: scalar value may not be null!");
00896 xmlrpc_scalar_destroy(scalar);
00897 return NULL;
00898 #ifdef XR_ENABLE_EMPTY_STRING_VALUES
00899 }
00900 #endif
00901 }
00902 switch (type) {
00903 case xr_int:
00904 if (arg != NULL)
00905 scalar->s_int = *(long*)arg;
00906 break;
00907 case xr_bool:
00908 if (arg != NULL)
00909 scalar->s_bool = *(int*)arg;
00910 break;
00911 case xr_double:
00912 if (arg != NULL)
00913 scalar->s_double = *(double*)arg;
00914 break;
00915 case xr_string:
00916 scalar->s_str = octstr_duplicate((Octstr *)arg);
00917 break;
00918 case xr_date:
00919 scalar->s_date = octstr_duplicate((Octstr *)arg);
00920 break;
00921 case xr_base64:
00922 scalar->s_base64 = octstr_duplicate((Octstr *)arg);
00923 break;
00924 default:
00925 error(0,"XML-RPC: scalar type not supported!");
00926 xmlrpc_scalar_destroy(scalar);
00927 return NULL;
00928 }
00929 return scalar;
00930 }
00931
00932
00933
00934 void xmlrpc_scalar_destroy(XMLRPCScalar *scalar)
00935 {
00936 if (scalar == NULL)
00937 return;
00938
00939 octstr_destroy(scalar->s_str);
00940 octstr_destroy(scalar->s_date);
00941 octstr_destroy(scalar->s_base64);
00942
00943 gw_free(scalar);
00944 }
00945
00946 int xmlrpc_scalar_get_type(XMLRPCScalar *scalar)
00947 {
00948 if (scalar == NULL)
00949 return -1;
00950 return scalar->s_type;
00951 }
00952
00953 void *xmlrpc_scalar_get_content(XMLRPCScalar *scalar, int s_type)
00954 {
00955 if (scalar == NULL)
00956 return NULL;
00957 if (scalar->s_type != s_type) {
00958 error(0, "XMLRPC: Scalar content request with bogus type");
00959 return NULL;
00960 }
00961 switch (scalar->s_type) {
00962 case xr_int: return &(scalar->s_int);
00963 case xr_bool: return &(scalar->s_bool);
00964 case xr_double: return &(scalar->s_double);
00965 case xr_string: return scalar->s_str;
00966 case xr_date: return scalar->s_date;
00967 case xr_base64: return scalar->s_base64;
00968 default:
00969 error(0,"XML-RPC: scalar type not supported!");
00970 return NULL;
00971 }
00972 }
00973
00974 Octstr *xmlrpc_scalar_print(XMLRPCScalar *scalar, int level)
00975 {
00976 Octstr *os = NULL;
00977
00978 if (scalar == NULL)
00979 return NULL;
00980
00981 switch (scalar->s_type) {
00982 case xr_int:
00983 os = octstr_format("%*s<int>%ld</int>\n",
00984 level, "", scalar->s_int);
00985 break;
00986 case xr_bool:
00987 os = octstr_format("%*s<bool>%d</bool>\n",
00988 level, "", scalar->s_bool);
00989 break;
00990 case xr_double:
00991 os = octstr_format("%*s<double>%d</double>\n",
00992 level, "", scalar->s_double);
00993 break;
00994 case xr_string:
00995 if (scalar->s_str == NULL) {
00996 #ifdef XR_ENABLE_EMPTY_STRING_VALUES
00997 os = octstr_format("%*s<string></string>\n",
00998 level, "");
00999 #endif
01000 } else {
01001 Octstr *tmp = octstr_duplicate(scalar->s_str);
01002 octstr_convert_to_html_entities(tmp);
01003 os = octstr_format("%*s<string>%S</string>\n",
01004 level, "", tmp);
01005 octstr_destroy(tmp);
01006 }
01007 break;
01008 case xr_date:
01009 os = octstr_format("%*s<datetime.iso8601>%S</datetime.iso8601>\n",
01010 level, "", scalar->s_date);
01011 break;
01012 case xr_base64:
01013 os = octstr_format("%*s<base64>%S</base64>\n",
01014 level, "", scalar->s_base64);
01015 break;
01016 }
01017 return os;
01018 }
01019
01020
01021
01022
01023
01024
01025
01026 static XMLRPCMember *xmlrpc_member_create(void)
01027 {
01028 XMLRPCMember *member = gw_malloc(sizeof(XMLRPCMember));
01029
01030 member->name = NULL;
01031 member->value = NULL;
01032
01033 return member;
01034 }
01035
01036
01037 static void xmlrpc_member_destroy(XMLRPCMember *member, int destroy_value)
01038 {
01039 if (member == NULL)
01040 return;
01041
01042 octstr_destroy(member->name);
01043 if (destroy_value == 1)
01044 xmlrpc_value_destroy(member->value);
01045
01046 gw_free(member);
01047 }
01048
01049
01050
01051
01052
01053
01054
01055 Octstr *xmlrpc_get_call_name(XMLRPCDocument *call)
01056 {
01057 if (call == NULL || call->methodcall == NULL)
01058 return NULL;
01059 return xmlrpc_call_get_name(call->methodcall);
01060 }
01061
01062
01063 int xmlrpc_count_params(XMLRPCDocument *xrdoc)
01064 {
01065 if (xrdoc == NULL)
01066 return -1;
01067 if (xrdoc->d_type == xr_methodcall && xrdoc->methodcall != NULL)
01068 return gwlist_len(xrdoc->methodcall->params);
01069 else if (xrdoc->d_type == xr_methodresponse && xrdoc->methodresponse != NULL)
01070 return (xrdoc->methodresponse->param != NULL ? 1 : 0);
01071
01072 return -1;
01073 }
01074
01075 XMLRPCValue *xmlrpc_get_param(XMLRPCDocument *xrdoc, int i)
01076 {
01077 if (xrdoc == NULL)
01078 return NULL;
01079 if (xrdoc->d_type == xr_methodcall && xrdoc->methodcall != NULL)
01080 return gwlist_len(xrdoc->methodcall->params) > i ? gwlist_get(xrdoc->methodcall->params, i) : NULL;
01081 else if (xrdoc->d_type == xr_methodresponse && xrdoc->methodresponse != NULL
01082 && i == 0)
01083 return xrdoc->methodresponse->param;
01084
01085 return NULL;
01086 }
01087
01088 int xmlrpc_get_type_param(XMLRPCDocument *xrdoc, int i)
01089 {
01090 XMLRPCValue *param = xmlrpc_get_param(xrdoc, i);
01091
01092 return xmlrpc_value_get_type(param);
01093 }
01094
01095 void *xmlrpc_get_content_param(XMLRPCDocument *xrdoc, int i)
01096 {
01097 XMLRPCValue *param = xmlrpc_get_param(xrdoc, i);
01098
01099 return xmlrpc_value_get_content(param);
01100 }
01101
01102
01103 XMLRPCValue *xmlrpc_create_struct_value(int count_members)
01104 {
01105 XMLRPCValue *value = xmlrpc_value_create();
01106 int len = (count_members > 0 ? count_members : OPTIMAL_STRUCT_SIZE);
01107 value->v_type = xr_struct;
01108 value->v_struct = dict_create(len, xmlrpc_value_destroy_item);
01109
01110 return value;
01111 }
01112
01113 long xmlrpc_count_members(XMLRPCValue *xrstruct)
01114 {
01115 if (xrstruct == NULL || xrstruct->v_type != xr_struct)
01116 return -1;
01117 return dict_key_count(xrstruct->v_struct);
01118 }
01119
01120 int xmlrpc_add_member(XMLRPCValue *xrstruct, Octstr *name, XMLRPCValue *value)
01121 {
01122 if (xrstruct == NULL || xrstruct->v_type != xr_struct
01123 || name == NULL || value == NULL)
01124 return -1;
01125
01126 return dict_put_once(xrstruct->v_struct, name, value);
01127 }
01128
01129 int xmlrpc_add_member_scalar(XMLRPCValue *xrstruct, Octstr *name, int type, void *arg)
01130 {
01131 XMLRPCValue *value = xmlrpc_create_scalar_value(type, arg);
01132 int status;
01133
01134 status = xmlrpc_add_member(xrstruct, name, value);
01135 if (status < 0)
01136 xmlrpc_value_destroy(value);
01137
01138 return status;
01139 }
01140
01141 XMLRPCValue *xmlrpc_get_member(XMLRPCValue *xrstruct, Octstr *name)
01142 {
01143 if (xrstruct == NULL || xrstruct->v_type != xr_struct || name == NULL)
01144 return NULL;
01145
01146 return dict_get(xrstruct->v_struct, name);
01147 }
01148
01149 int xmlrpc_get_member_type(XMLRPCValue *xrstruct, Octstr *name)
01150 {
01151 XMLRPCValue *value = xmlrpc_get_member(xrstruct, name);
01152
01153 return xmlrpc_value_get_type(value);
01154 }
01155
01156 void *xmlrpc_get_member_content(XMLRPCValue *xrstruct, Octstr *name)
01157 {
01158 XMLRPCValue *value = xmlrpc_get_member(xrstruct, name);
01159
01160 return xmlrpc_value_get_content(value);
01161 }
01162
01163 Octstr *xmlrpc_print_struct(Dict *v_struct, int level)
01164 {
01165 Octstr *body, *os_val, *key;
01166 List *keys;
01167 XMLRPCValue *member_val;
01168
01169 if (v_struct == NULL || dict_key_count(v_struct) == 0)
01170 return NULL;
01171
01172 keys = dict_keys(v_struct);
01173 body = octstr_format("%*s<struct>\n", level, "");
01174
01175 while ((key = gwlist_consume(keys)) != NULL) {
01176 member_val = dict_get(v_struct, key);
01177 os_val = xmlrpc_value_print(member_val, level+4);
01178 if (os_val == NULL) {
01179 gwlist_destroy(keys, octstr_destroy_item);
01180 octstr_destroy(key);
01181 octstr_destroy(body);
01182 return NULL;
01183 }
01184 octstr_format_append(body, "%*s<member>\n"
01185 "%*s<name>%S</name>\n%S"
01186 "%*s</member>\n",
01187 level+2, "", level+4, "",
01188 key, os_val,
01189 level+2, "");
01190 octstr_destroy(key);
01191 octstr_destroy(os_val);
01192 }
01193 gwlist_destroy(keys, octstr_destroy_item);
01194 octstr_format_append(body, "%*s</struct>\n", level, "");
01195
01196 return body;
01197 }
01198
01199
01200 XMLRPCValue *xmlrpc_create_array_value(void)
01201 {
01202 XMLRPCValue *value = xmlrpc_value_create();
01203 value->v_type = xr_array;
01204 value->v_array = gwlist_create();
01205
01206 return value;
01207 }
01208
01209 int xmlrpc_count_elements(XMLRPCValue *xrarray)
01210 {
01211 if (xrarray == NULL || xrarray->v_type != xr_array)
01212 return -1;
01213
01214 return gwlist_len(xrarray->v_array);
01215 }
01216
01217 int xmlrpc_add_element(XMLRPCValue *xrarray, XMLRPCValue *value)
01218 {
01219 if (xrarray == NULL || xrarray->v_type != xr_array || value == NULL)
01220 return -1;
01221
01222 gwlist_produce(xrarray->v_array, value);
01223 return 1;
01224 }
01225
01226 int xmlrpc_add_element_scalar(XMLRPCValue *xrarray, int type, void *arg)
01227 {
01228 XMLRPCValue *value = xmlrpc_create_scalar_value(type, arg);
01229 int status;
01230
01231 status = xmlrpc_add_element(xrarray, value);
01232 if (status < 0)
01233 xmlrpc_value_destroy(value);
01234
01235 return status;
01236 }
01237
01238 XMLRPCValue *xmlrpc_get_element(XMLRPCValue *xrarray, int i)
01239 {
01240 if (xrarray == NULL || xrarray->v_type != xr_array || i < 0)
01241 return NULL;
01242
01243 return gwlist_get(xrarray->v_array, i);
01244 }
01245
01246 int xmlrpc_get_element_type(XMLRPCValue *xrarray, int i)
01247 {
01248 XMLRPCValue *value = xmlrpc_get_element(xrarray, i);
01249
01250 return xmlrpc_value_get_type(value);
01251 }
01252
01253 void *xmlrpc_get_element_content(XMLRPCValue *xrarray, int i)
01254 {
01255 XMLRPCValue *value = xmlrpc_get_element(xrarray, i);
01256
01257 return xmlrpc_value_get_content(value);
01258 }
01259
01260 Octstr *xmlrpc_print_array(List *v_array, int level)
01261 {
01262 Octstr *body, *os_element;
01263 XMLRPCValue *element = NULL;
01264 int i;
01265
01266 if (v_array == NULL)
01267 return NULL;
01268
01269 body = octstr_format("%*s<array>\n%*s<data>\n", level, "", level+2, "");
01270
01271 for(i = 0; i < gwlist_len(v_array); i++) {
01272 element = gwlist_get(v_array, i);
01273 os_element = xmlrpc_value_print(element, level+4);
01274 if (os_element == NULL) {
01275 octstr_destroy(body);
01276 return NULL;
01277 }
01278
01279 octstr_append(body, os_element);
01280 octstr_destroy(os_element);
01281 }
01282 octstr_format_append(body, "%*s</data>\n%*s</array>\n",
01283 level+2, "", level, "");
01284
01285 return body;
01286 }
01287
01288
01289
01290 XMLRPCValue *xmlrpc_create_scalar_value(int type, void *arg)
01291 {
01292 XMLRPCValue *value = xmlrpc_value_create();
01293 value->v_type = xr_scalar;
01294 value->v_scalar = xmlrpc_scalar_create(type, arg);
01295
01296 return value;
01297 }
01298
01299 XMLRPCValue *xmlrpc_create_double_value(double val)
01300 {
01301 return xmlrpc_create_scalar_value(xr_double, &val);
01302 }
01303
01304 XMLRPCValue *xmlrpc_create_int_value(long val)
01305 {
01306 return xmlrpc_create_scalar_value(xr_int, &val);
01307 }
01308
01309 XMLRPCValue *xmlrpc_create_string_value(Octstr *val)
01310 {
01311 return xmlrpc_create_scalar_value(xr_string, val);
01312 }
01313
01314
01315
01316 int xmlrpc_is_fault(XMLRPCDocument *response)
01317 {
01318 if (response == NULL || response->d_type != xr_methodresponse)
01319 return 0;
01320
01321 return xmlrpc_response_is_fault(response->methodresponse);
01322 }
01323
01324 long xmlrpc_get_faultcode(XMLRPCDocument *faultresponse)
01325 {
01326 if (! xmlrpc_is_fault(faultresponse)) {
01327 error(0, "XMLRPC object is not fault response.");
01328 return -1;
01329 }
01330
01331 return xmlrpc_response_get_faultcode(faultresponse->methodresponse);
01332 }
01333
01334 Octstr *xmlrpc_get_faultstring(XMLRPCDocument *faultresponse)
01335 {
01336 if (! xmlrpc_is_fault(faultresponse)) {
01337 error(0, "XMLRPC object is not fault response.");
01338 return NULL;
01339 }
01340
01341 return xmlrpc_response_get_faultstring(faultresponse->methodresponse);
01342 }
01343
01344
01345
01346
01347 int xmlrpc_parse_status(XMLRPCDocument *xrdoc)
01348 {
01349 if (xrdoc == NULL)
01350 return -1;
01351
01352 return xrdoc->parse_status;
01353 }
01354
01355 Octstr *xmlrpc_parse_error(XMLRPCDocument *xrdoc)
01356 {
01357 if (xrdoc == NULL)
01358 return NULL;
01359
01360 return octstr_duplicate(xrdoc->parse_error);
01361 }
01362
01363
01364
01365
01366
01367
01368 static int parse_document(xmlDocPtr document, XMLRPCDocument *xrdoc)
01369 {
01370 xmlNodePtr node;
01371 Octstr *name;
01372 int n = 0, status = 0;
01373
01374 node = xmlDocGetRootElement(document);
01375
01376
01377
01378
01379 if (node == NULL || node->name == NULL) {
01380 error(0, "XMLRPC: XML document - not valid root node!");
01381 xrdoc->parse_status = XMLRPC_XMLPARSE_FAILED;
01382 xrdoc->parse_error = octstr_format("XML-RPC compiler: bad XML");
01383 return -1;
01384 }
01385
01386 name = octstr_create(node->name);
01387 if (octstr_len(name) == 0) {
01388 octstr_destroy(name);
01389 return -1;
01390 }
01391 if ((xrdoc->d_type == xr_methodcall || xrdoc->d_type == xr_undefined)
01392 && octstr_case_compare(name, octstr_imm("METHODCALL")) == 0) {
01393
01394 xrdoc->d_type = xr_methodcall;
01395 xrdoc->methodcall = xmlrpc_call_create(NULL);
01396 octstr_destroy(name);
01397
01398 status = parse_methodcall(document, node->xmlChildrenNode, xrdoc, xrdoc->methodcall);
01399 if (status < 0) {
01400 xmlrpc_call_destroy(xrdoc->methodcall);
01401 xrdoc->methodcall = NULL;
01402 if (xrdoc->parse_status == XMLRPC_COMPILE_OK) {
01403 xrdoc->parse_status = XMLRPC_XMLPARSE_FAILED;
01404 xrdoc->parse_error = octstr_format("XML-RPC compiler: bad XML");
01405 }
01406 }
01407 else if ((xrdoc->methodcall->method_name) == NULL) {
01408 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01409 xrdoc->parse_error = octstr_format("XML-RPC compiler: <methodName> tag expected!");
01410 status = -1;
01411 }
01412 return status;
01413 } else if ((xrdoc->d_type == xr_methodresponse || xrdoc->d_type == xr_undefined)
01414 && octstr_case_compare(name, octstr_imm("METHODRESPONSE")) == 0) {
01415
01416 xrdoc->d_type = xr_methodresponse;
01417 xrdoc->methodresponse = xmlrpc_response_create();
01418 octstr_destroy(name);
01419
01420 status = parse_methodresponse(document, node->xmlChildrenNode,
01421 xrdoc, xrdoc->methodresponse, &n);
01422 if (status < 0) {
01423 xmlrpc_response_destroy(xrdoc->methodresponse);
01424 xrdoc->methodresponse = NULL;
01425 }
01426 return status;
01427 } else {
01428 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01429 xrdoc->parse_error = octstr_format("XML-RPC compiler: wrong root element <%s>, "
01430 "<%s> expected!",
01431 octstr_get_cstr(name),
01432 (xrdoc->d_type == xr_methodcall ?
01433 "methodCall" : "methodResponse"));
01434 octstr_destroy(name);
01435 return -1;
01436 }
01437 }
01438
01439 static int parse_methodcall(xmlDocPtr doc, xmlNodePtr node, XMLRPCDocument *xrdoc,
01440 XMLRPCMethodCall *methodcall)
01441 {
01442 int status = 0;
01443
01444
01445 switch (node->type) {
01446
01447 case XML_ELEMENT_NODE:
01448
01449 status = parse_methodcall_element(doc, node, xrdoc, methodcall);
01450 break;
01451
01452 case XML_TEXT_NODE:
01453 case XML_COMMENT_NODE:
01454 case XML_PI_NODE:
01455
01456 break;
01457
01458
01459
01460
01461 default:
01462 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01463 xrdoc->parse_error = octstr_format("XML-RPC compiler: unknown XML node "
01464 "in the XML-RPC source.");
01465 return -1;
01466 break;
01467 }
01468
01469 if (node->next != NULL)
01470 return parse_methodcall(doc, node->next, xrdoc, methodcall);
01471
01472 return status;
01473 }
01474
01475 static int parse_methodcall_element(xmlDocPtr doc, xmlNodePtr node,
01476 XMLRPCDocument *xrdoc, XMLRPCMethodCall *methodcall)
01477 {
01478 Octstr *name;
01479 xmlChar *content_buff;
01480 size_t i;
01481
01482
01483
01484
01485 if (node->name == NULL) {
01486 error(0, "XMLRPC: XML methodcall element nodes without name!");
01487 xrdoc->parse_status = XMLRPC_XMLPARSE_FAILED;
01488 xrdoc->parse_error = octstr_format("XML-RPC compiler: bad XML");
01489 return -1;
01490 }
01491
01492 name = octstr_create(node->name);
01493 if (octstr_len(name) == 0) {
01494 octstr_destroy(name);
01495 return -1;
01496 }
01497
01498 i = 0;
01499 while (i < NUMBER_OF_METHODCALL_ELEMENTS) {
01500 if (octstr_case_compare(name, octstr_imm(methodcall_elements[i].name)) == 0)
01501 break;
01502 ++i;
01503 }
01504 if (i == NUMBER_OF_METHODCALL_ELEMENTS) {
01505 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01506 xrdoc->parse_error = octstr_format("XML-RPC compiler: unknown tag '%s' in XML source "
01507 "at level <methodCall>", octstr_get_cstr(name));
01508 octstr_destroy(name);
01509 return -1;
01510 }
01511 octstr_destroy(name);
01512
01513
01514
01515
01516
01517
01518
01519
01520 if (i == 0) {
01521
01522 if (methodcall->method_name == NULL) {
01523
01524 content_buff = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
01525 if (content_buff != NULL) {
01526 methodcall->method_name = octstr_create(content_buff);
01527 xmlFree(content_buff);
01528 } else {
01529 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01530 xrdoc->parse_error = octstr_format("XML-RPC compiler: empty tag <methodName> in XML source "
01531 "at level <methodCall>");
01532 return -1;
01533 }
01534 } else {
01535 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01536 xrdoc->parse_error = octstr_format("XML-RPC compiler: duplicated tag <methodName> in XML source "
01537 "at level <methodCall>");
01538 octstr_destroy(name);
01539 return -1;
01540 }
01541 } else {
01542
01543
01544
01545
01546 return parse_params(doc, node->xmlChildrenNode, xrdoc, methodcall->params);
01547 }
01548 return 0;
01549 }
01550
01551 static int parse_methodresponse(xmlDocPtr doc, xmlNodePtr node,
01552 XMLRPCDocument *xrdoc, XMLRPCMethodResponse *methodresponse, int* n)
01553 {
01554 int status = 0;
01555
01556
01557 switch (node->type) {
01558
01559 case XML_ELEMENT_NODE:
01560 if (*n > 0) {
01561 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01562 xrdoc->parse_error = octstr_format("XML-RPC compiler: unexpected XML node <%s> "
01563 "in the XML-RPC source.", node->name);
01564 return -1;
01565 }
01566 status = parse_methodresponse_element(doc, node, xrdoc, methodresponse);
01567 (*n)++;
01568 break;
01569
01570 case XML_TEXT_NODE:
01571 case XML_COMMENT_NODE:
01572 case XML_PI_NODE:
01573
01574 break;
01575
01576
01577
01578
01579 default:
01580 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01581 xrdoc->parse_error = octstr_format("XML-RPC compiler: unknown XML node "
01582 "in the XML-RPC source.");
01583 return -1;
01584 break;
01585 }
01586
01587 if (node->next != NULL) {
01588 if (parse_methodresponse(doc, node->next, xrdoc, methodresponse, n) == -1) {
01589 return -1;
01590 }
01591 }
01592
01593 return status;
01594 }
01595
01596 static int parse_methodresponse_element(xmlDocPtr doc, xmlNodePtr node,
01597 XMLRPCDocument *xrdoc, XMLRPCMethodResponse *methodresponse)
01598 {
01599 Octstr *name;
01600 size_t i;
01601 int status;
01602
01603
01604
01605
01606 if (node->name == NULL) {
01607 error(0, "XMLRPC: XML methodResponse element nodes without name!");
01608 xrdoc->parse_status = XMLRPC_XMLPARSE_FAILED;
01609 xrdoc->parse_error = octstr_format("XML-RPC compiler: bad XML");
01610 return -1;
01611 }
01612
01613 name = octstr_create(node->name);
01614 if (octstr_len(name) == 0) {
01615 octstr_destroy(name);
01616 return -1;
01617 }
01618
01619 i = 0;
01620 while (i < NUMBER_OF_METHODRESPONSE_ELEMENTS) {
01621 if (octstr_case_compare(name, octstr_imm(methodresponse_elements[i].name)) == 0)
01622 break;
01623 ++i;
01624 }
01625 if (i == NUMBER_OF_METHODRESPONSE_ELEMENTS) {
01626 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01627 xrdoc->parse_error = octstr_format("XML-RPC compiler: unknown tag '%s' in XML source "
01628 "at level <methodResponse>", octstr_get_cstr(name));
01629 octstr_destroy(name);
01630 return -1;
01631 }
01632 octstr_destroy(name);
01633
01634
01635
01636
01637
01638
01639
01640
01641 if (i == 0) {
01642
01643 methodresponse->fault = xmlrpc_fault_create(0, NULL);
01644 return parse_fault(doc, node->xmlChildrenNode, xrdoc, methodresponse->fault);
01645 } else {
01646
01647
01648
01649
01650 List *params = gwlist_create();;
01651 status = parse_params(doc, node->xmlChildrenNode, xrdoc, params);
01652 if (status < 0) return -1;
01653 if (gwlist_len(params) != 1) {
01654 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01655 xrdoc->parse_error = octstr_format("XML-RPC compiler:wrong number of params "
01656 "at level <methodResponse>");
01657 gwlist_destroy(params, xmlrpc_value_destroy_item);
01658 return -1;
01659 }
01660 methodresponse->param = gwlist_consume(params);
01661 gwlist_destroy(params, xmlrpc_value_destroy_item);
01662 return status;
01663 }
01664
01665 }
01666
01667 static int parse_params(xmlDocPtr doc, xmlNodePtr node,
01668 XMLRPCDocument *xrdoc, List *params)
01669 {
01670 int status = 0;
01671
01672
01673 switch (node->type) {
01674
01675 case XML_ELEMENT_NODE:
01676 status = parse_params_element(doc, node, xrdoc, params);
01677 break;
01678
01679 case XML_TEXT_NODE:
01680 case XML_COMMENT_NODE:
01681 case XML_PI_NODE:
01682
01683 break;
01684
01685
01686
01687
01688 default:
01689 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01690 xrdoc->parse_error = octstr_format("XML-RPC compiler: unknown XML node in XML-RPC source.");
01691 return -1;
01692 break;
01693 }
01694
01695 if (node->next != NULL)
01696 if (parse_params(doc, node->next, xrdoc, params) == -1)
01697 return -1;
01698
01699 return status;
01700 }
01701
01702 static int parse_params_element(xmlDocPtr doc, xmlNodePtr node,
01703 XMLRPCDocument *xrdoc, List *params)
01704 {
01705 Octstr *name;
01706 size_t i;
01707 int n = 0;
01708
01709
01710
01711
01712
01713 if (node->name == NULL) {
01714 error(0, "XMLRPC: XML params element nodes without name!");
01715 xrdoc->parse_status = XMLRPC_XMLPARSE_FAILED;
01716 xrdoc->parse_error = octstr_format("XML-RPC compiler: bad XML");
01717 return -1;
01718 }
01719
01720 name = octstr_create(node->name);
01721 if (octstr_len(name) == 0) {
01722 octstr_destroy(name);
01723 return -1;
01724 }
01725
01726 i = 0;
01727 while (i < NUMBER_OF_PARAMS_ELEMENTS) {
01728 if (octstr_case_compare(name, octstr_imm(params_elements[i].name)) == 0)
01729 break;
01730 ++i;
01731 }
01732 if (i == NUMBER_OF_PARAMS_ELEMENTS) {
01733 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01734 xrdoc->parse_error = octstr_format("XML-RPC compiler: unknown tag '%s' "
01735 "in XML source at level <params>",
01736 octstr_get_cstr(name));
01737 octstr_destroy(name);
01738 return -1;
01739 }
01740 octstr_destroy(name);
01741
01742
01743
01744
01745
01746
01747
01748 if (i == 0) {
01749
01750 if (parse_param(doc, node->xmlChildrenNode, xrdoc, params, &n) == -1)
01751 return -1;
01752 } else {
01753
01754 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01755 xrdoc->parse_error = octstr_format("XML-RPC compiler: bogus parsing exception in parse_params!");
01756 return -1;
01757 }
01758 return 0;
01759 }
01760
01761 static int parse_param(xmlDocPtr doc, xmlNodePtr node,
01762 XMLRPCDocument *xrdoc, List *params, int *n)
01763 {
01764 int status = 0;
01765
01766
01767 switch (node->type) {
01768
01769 case XML_ELEMENT_NODE:
01770
01771
01772 if ((*n) > 0) {
01773 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01774 xrdoc->parse_error = octstr_format("XML-RPC compiler: param may only have one value!");
01775 return -1;
01776 }
01777
01778 status = parse_param_element(doc, node, xrdoc, params);
01779 (*n)++;
01780 break;
01781
01782 case XML_TEXT_NODE:
01783 case XML_COMMENT_NODE:
01784 case XML_PI_NODE:
01785
01786 break;
01787
01788
01789
01790
01791 default:
01792 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01793 xrdoc->parse_error = octstr_format("XML-RPC compiler: Unknown XML node in the XML-RPC source.");
01794 return -1;
01795 break;
01796 }
01797
01798 if (node->next != NULL)
01799 if (parse_param(doc, node->next, xrdoc, params, n) == -1)
01800 return -1;
01801
01802 return status;
01803 }
01804
01805 static int parse_param_element(xmlDocPtr doc, xmlNodePtr node,
01806 XMLRPCDocument *xrdoc, List *params)
01807 {
01808 Octstr *name;
01809 size_t i;
01810 XMLRPCValue *value;
01811
01812
01813
01814
01815 if (node->name == NULL) {
01816 error(0, "XMLRPC: XML param element nodes without name!");
01817 xrdoc->parse_status = XMLRPC_XMLPARSE_FAILED;
01818 xrdoc->parse_error = octstr_format("XML-RPC compiler: bad XML");
01819 return -1;
01820 }
01821
01822 name = octstr_create(node->name);
01823 if (octstr_len(name) == 0) {
01824 octstr_destroy(name);
01825 return -1;
01826 }
01827
01828 i = 0;
01829 while (i < NUMBER_OF_PARAM_ELEMENTS) {
01830 if (octstr_case_compare(name, octstr_imm(param_elements[i].name)) == 0)
01831 break;
01832 ++i;
01833 }
01834 if (i == NUMBER_OF_PARAM_ELEMENTS) {
01835 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01836 xrdoc->parse_error = octstr_format("XML-RPC compiler: unknown tag '%s' "
01837 "in XML source at level <param>",
01838 octstr_get_cstr(name));
01839 octstr_destroy(name);
01840 return -1;
01841 }
01842 octstr_destroy(name);
01843
01844
01845
01846
01847
01848
01849
01850 if (i == 0) {
01851
01852 value = xmlrpc_value_create();
01853 if (parse_value(doc, node->xmlChildrenNode, xrdoc, value) == -1) {
01854 xmlrpc_value_destroy(value);
01855 return -1;
01856 }
01857 gwlist_append(params, value);
01858 } else {
01859
01860 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01861 xrdoc->parse_error = octstr_format("XML-RPC compiler: bogus parsing exception in parse_param!");
01862 return -1;
01863 }
01864 return 0;
01865 }
01866
01867 static int parse_value(xmlDocPtr doc, xmlNodePtr node,
01868 XMLRPCDocument *xrdoc, XMLRPCValue *value)
01869 {
01870 int status = 0;
01871
01872
01873 switch (node->type) {
01874
01875 case XML_ELEMENT_NODE:
01876 status = parse_value_element(doc, node, xrdoc, value);
01877 break;
01878
01879 case XML_TEXT_NODE:
01880 case XML_COMMENT_NODE:
01881 case XML_PI_NODE:
01882
01883 break;
01884
01885
01886
01887
01888 default:
01889 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01890 xrdoc->parse_error = octstr_format("XML-RPC compiler: Unknown XML node in the XML-RPC source.");
01891 return -1;
01892 break;
01893 }
01894
01895 if (node->next != NULL)
01896 if (parse_value(doc, node->next, xrdoc, value) == -1)
01897 return -1;
01898
01899 return status;
01900 }
01901
01902 static int parse_value_element(xmlDocPtr doc, xmlNodePtr node,
01903 XMLRPCDocument *xrdoc, XMLRPCValue *xrvalue)
01904 {
01905 Octstr *name;
01906 Octstr *value = NULL;
01907 xmlChar *content_buff;
01908 long lval = 0;
01909 double dval = 0.0;
01910 size_t i;
01911
01912
01913
01914
01915 if (node->name == NULL) {
01916 error(0, "XMLRPC: XML value element nodes without name!");
01917 xrdoc->parse_status = XMLRPC_XMLPARSE_FAILED;
01918 xrdoc->parse_error = octstr_format("XML-RPC compiler: bad XML");
01919 return -1;
01920 }
01921
01922 name = octstr_create(node->name);
01923 if (octstr_len(name) == 0) {
01924 octstr_destroy(name);
01925 return -1;
01926 }
01927
01928 i = 0;
01929 while (i < NUMBER_OF_VALUE_ELEMENTS) {
01930 if (octstr_case_compare(name, octstr_imm(value_elements[i].name)) == 0)
01931 break;
01932 ++i;
01933 }
01934 if (i == NUMBER_OF_VALUE_ELEMENTS) {
01935 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01936 xrdoc->parse_error = octstr_format("XML-RPC compiler: unknown tag '%s' "
01937 "in XML source at level <value>",
01938 octstr_get_cstr(name));
01939 octstr_destroy(name);
01940 return -1;
01941 }
01942 octstr_destroy(name);
01943
01944
01945 content_buff = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
01946 if (content_buff != NULL) {
01947 value = octstr_create(content_buff);
01948 xmlFree(content_buff);
01949 }
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964 switch (value_elements[i].s_type) {
01965
01966
01967
01968 case xr_int: case xr_bool:
01969 case xr_double:
01970 case xr_date: case xr_base64:
01971 #ifndef XR_ENABLE_EMPTY_STRING_VALUES
01972 case xr_string:
01973 #endif
01974 if (value == NULL) {
01975 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01976 xrdoc->parse_error = octstr_format("XML-RPC compiler: no value for '%s'",
01977 node->name);
01978 return -1;
01979 }
01980 break;
01981 }
01982
01983 switch (value_elements[i].s_type) {
01984
01985
01986
01987
01988 case xr_int:
01989 if (value != NULL && octstr_parse_long(&lval, value, 0, 10) < 0) {
01990 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
01991 xrdoc->parse_error = octstr_format("XML-RPC compiler: could not parse int value '%s'",
01992 octstr_get_cstr(value));
01993 octstr_destroy(value);
01994 return -1;
01995 }
01996 xrvalue->v_type = xr_scalar;
01997 xrvalue->v_scalar = xmlrpc_scalar_create(xr_int, (void *) &lval);
01998 break;
01999
02000 case xr_bool:
02001 if (value != NULL && octstr_parse_long(&lval, value, 0, 10) < 0) {
02002 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02003 xrdoc->parse_error = octstr_format("XML-RPC compiler: could not parse boolean value '%s'",
02004 octstr_get_cstr(value));
02005 octstr_destroy(value);
02006 return -1;
02007 }
02008 xrvalue->v_type = xr_scalar;
02009 xrvalue->v_scalar = xmlrpc_scalar_create(xr_bool, (void *) &lval);
02010 break;
02011
02012 case xr_double:
02013 if (value != NULL && octstr_parse_double(&dval, value, 0) < 0) {
02014 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02015 xrdoc->parse_error = octstr_format("XML-RPC compiler: could not parse double value '%s'",
02016 octstr_get_cstr(value));
02017 octstr_destroy(value);
02018 return -1;
02019 }
02020 xrvalue->v_type = xr_scalar;
02021 xrvalue->v_scalar = xmlrpc_scalar_create(xr_double, (void *) &dval);
02022 break;
02023
02024 case xr_string:
02025 xrvalue->v_type = xr_scalar;
02026 xrvalue->v_scalar = xmlrpc_scalar_create(xr_string, (void *) value);
02027 break;
02028
02029 case xr_date:
02030 xrvalue->v_type = xr_scalar;
02031 xrvalue->v_scalar = xmlrpc_scalar_create(xr_date, (void *) value);
02032 break;
02033
02034 case xr_base64:
02035 xrvalue->v_type = xr_scalar;
02036 xrvalue->v_scalar = xmlrpc_scalar_create(xr_base64, (void *) value);
02037 break;
02038
02039 case xr_struct:
02040 xrvalue->v_type = xr_struct;
02041 xrvalue->v_struct = dict_create(OPTIMAL_STRUCT_SIZE, xmlrpc_value_destroy_item);
02042
02043 if (parse_struct(doc, node->xmlChildrenNode, xrdoc, xrvalue->v_struct) == -1) {
02044 octstr_destroy(value);
02045 return -1;
02046 }
02047 break;
02048
02049 case xr_array:
02050 xrvalue->v_type = xr_array;
02051 xrvalue->v_array = gwlist_create();
02052
02053 if (parse_array(doc, node->xmlChildrenNode, xrdoc, xrvalue->v_array) == -1) {
02054 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02055 xrdoc->parse_error = octstr_format("XML-RPC compiler: could not parse array");
02056 octstr_destroy(value);
02057 return -1;
02058 }
02059 break;
02060
02061 default:
02062 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02063 xrdoc->parse_error = octstr_format("XML-RPC compiler: bogus parsing exception in parse_value!");
02064 return -1;
02065 }
02066
02067 octstr_destroy(value);
02068 return 0;
02069 }
02070
02071 static int parse_struct(xmlDocPtr doc, xmlNodePtr node,
02072 XMLRPCDocument *xrdoc, Dict *members)
02073 {
02074 int status = 0;
02075
02076
02077 switch (node->type) {
02078
02079 case XML_ELEMENT_NODE:
02080 status = parse_struct_element(doc, node, xrdoc, members);
02081 break;
02082
02083 case XML_TEXT_NODE:
02084 case XML_COMMENT_NODE:
02085 case XML_PI_NODE:
02086
02087 break;
02088
02089
02090
02091
02092 default:
02093 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02094 xrdoc->parse_error = octstr_format("XML-RPC compiler: Unknown XML node in the XML-RPC source.");
02095 return -1;
02096 break;
02097 }
02098
02099 if (node->next != NULL)
02100 if (parse_struct(doc, node->next, xrdoc, members) == -1)
02101 return -1;
02102
02103 return status;
02104 }
02105
02106 static int parse_struct_element(xmlDocPtr doc, xmlNodePtr node,
02107 XMLRPCDocument *xrdoc, Dict *members)
02108 {
02109 Octstr *name;
02110 size_t i;
02111 XMLRPCMember *member;
02112
02113
02114
02115
02116 if (node->name == NULL) {
02117 error(0, "XMLRPC: XML struct element nodes without name!");
02118 xrdoc->parse_status = XMLRPC_XMLPARSE_FAILED;
02119 xrdoc->parse_error = octstr_format("XML-RPC compiler: bad XML");
02120 return -1;
02121 }
02122
02123 name = octstr_create(node->name);
02124 if (octstr_len(name) == 0) {
02125 octstr_destroy(name);
02126 return -1;
02127 }
02128
02129 i = 0;
02130 while (i < NUMBER_OF_STRUCT_ELEMENTS) {
02131 if (octstr_case_compare(name, octstr_imm(struct_elements[i].name)) == 0)
02132 break;
02133 ++i;
02134 }
02135 if (i == NUMBER_OF_STRUCT_ELEMENTS) {
02136 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02137 xrdoc->parse_error = octstr_format("XML-RPC compiler: unknown tag '%s' "
02138 "in XML source at level <struct>",
02139 octstr_get_cstr(name));
02140 octstr_destroy(name);
02141 return -1;
02142 }
02143 octstr_destroy(name);
02144
02145
02146
02147
02148
02149
02150
02151 if (i == 0) {
02152
02153 member = xmlrpc_member_create();
02154 if (parse_member(doc, node->xmlChildrenNode, xrdoc, member) == -1) {
02155 xmlrpc_member_destroy(member, 1);
02156 return -1;
02157 }
02158 if (! dict_put_once(members, member->name, member->value)) {
02159 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02160 xrdoc->parse_error = octstr_format("XML-RPC compiler: at least two members have same name.");
02161 xmlrpc_member_destroy(member, 1);
02162 return -1;
02163 }
02164 xmlrpc_member_destroy(member, 0);
02165 } else {
02166
02167 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02168 xrdoc->parse_error = octstr_format("XML-RPC compiler: bogus parsing exception in parse_struct!");
02169 return -1;
02170 }
02171 return 0;
02172 }
02173
02174 static int parse_member(xmlDocPtr doc, xmlNodePtr node,
02175 XMLRPCDocument *xrdoc, XMLRPCMember *member)
02176 {
02177 int status = 0;
02178
02179
02180 switch (node->type) {
02181
02182 case XML_ELEMENT_NODE:
02183 status = parse_member_element(doc, node, xrdoc, member);
02184 break;
02185
02186 case XML_TEXT_NODE:
02187 case XML_COMMENT_NODE:
02188 case XML_PI_NODE:
02189
02190 break;
02191
02192
02193
02194
02195 default:
02196 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02197 xrdoc->parse_error = octstr_format("XML-RPC compiler: Unknown XML node in the XML-RPC source.");
02198 return -1;
02199 break;
02200 }
02201
02202 if (node->next != NULL)
02203 if (parse_member(doc, node->next, xrdoc, member) == -1)
02204 return -1;
02205
02206 return status;
02207 }
02208
02209 static int parse_member_element(xmlDocPtr doc, xmlNodePtr node,
02210 XMLRPCDocument *xrdoc, XMLRPCMember *member)
02211 {
02212 Octstr *name;
02213 xmlChar *content_buff;
02214 size_t i;
02215
02216
02217
02218
02219 if (node->name == NULL) {
02220 error(0, "XMLRPC: XML member element nodes without name!");
02221 xrdoc->parse_status = XMLRPC_XMLPARSE_FAILED;
02222 xrdoc->parse_error = octstr_format("XML-RPC compiler: bad XML");
02223 return -1;
02224 }
02225
02226 name = octstr_create(node->name);
02227 if (octstr_len(name) == 0) {
02228 octstr_destroy(name);
02229 return -1;
02230 }
02231
02232 i = 0;
02233 while (i < NUMBER_OF_MEMBER_ELEMENTS) {
02234 if (octstr_case_compare(name, octstr_imm(member_elements[i].name)) == 0)
02235 break;
02236 ++i;
02237 }
02238 if (i == NUMBER_OF_MEMBER_ELEMENTS) {
02239 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02240 xrdoc->parse_error = octstr_format("XML-RPC compiler: unknown tag '%s' "
02241 "in XML source at level <member>",
02242 octstr_get_cstr(name));
02243 octstr_destroy(name);
02244 return -1;
02245 }
02246 octstr_destroy(name);
02247
02248
02249
02250
02251
02252
02253
02254
02255 if (i == 0) {
02256
02257 if (member->name != NULL) {
02258 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02259 xrdoc->parse_error = octstr_format("XML-RPC compiler: duplicated tag '<name>' "
02260 "in XML source at level <member>");
02261 return -1;
02262 }
02263 content_buff = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
02264 if (content_buff != NULL) {
02265 member->name = octstr_create(content_buff);
02266 xmlFree(content_buff);
02267 } else {
02268 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02269 xrdoc->parse_error = octstr_format("XML-RPC compiler: empty tag <name> in XML source "
02270 "at level <member>");
02271 return -1;
02272 }
02273 } else {
02274 member->value = xmlrpc_value_create();
02275 if (parse_value(doc, node->xmlChildrenNode, xrdoc, member->value) == -1) {
02276 xmlrpc_value_destroy(member->value);
02277 member->value = NULL;
02278 return -1;
02279 }
02280 }
02281 return 0;
02282 }
02283
02284 static int parse_array(xmlDocPtr doc, xmlNodePtr node,
02285 XMLRPCDocument *xrdoc, List *elements)
02286 {
02287 int status = 0;
02288
02289
02290 switch (node->type) {
02291
02292 case XML_ELEMENT_NODE:
02293 status = parse_array_element(doc, node, xrdoc, elements);
02294 break;
02295
02296 case XML_TEXT_NODE:
02297 case XML_COMMENT_NODE:
02298 case XML_PI_NODE:
02299
02300 break;
02301
02302
02303
02304
02305 default:
02306 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02307 xrdoc->parse_error = octstr_format("XML-RPC compiler: Unknown XML node in the XML-RPC source.");
02308 return -1;
02309 break;
02310 }
02311
02312 if (node->next != NULL)
02313 if (parse_array(doc, node->next, xrdoc, elements) == -1)
02314 return -1;
02315
02316 return status;
02317 }
02318
02319 static int parse_array_element(xmlDocPtr doc, xmlNodePtr node,
02320 XMLRPCDocument *xrdoc, List *elements)
02321 {
02322 Octstr *name;
02323 size_t i;
02324
02325
02326
02327
02328 if (node->name == NULL) {
02329 error(0, "XMLRPC: XML array element nodes without name!");
02330 xrdoc->parse_status = XMLRPC_XMLPARSE_FAILED;
02331 xrdoc->parse_error = octstr_format("XML-RPC compiler: bad XML");
02332 return -1;
02333 }
02334
02335 name = octstr_create(node->name);
02336 if (octstr_len(name) == 0) {
02337 octstr_destroy(name);
02338 return -1;
02339 }
02340
02341 i = 0;
02342 while (i < NUMBER_OF_ARRAY_ELEMENTS) {
02343 if (octstr_case_compare(name, octstr_imm(array_elements[i].name)) == 0)
02344 break;
02345 ++i;
02346 }
02347 if (i == NUMBER_OF_ARRAY_ELEMENTS) {
02348 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02349 xrdoc->parse_error = octstr_format("XML-RPC compiler: unknown tag '%s' "
02350 "in XML source at level <array>",
02351 octstr_get_cstr(name));
02352 octstr_destroy(name);
02353 return -1;
02354 }
02355 octstr_destroy(name);
02356
02357
02358
02359
02360
02361
02362
02363 if (i == 0) {
02364
02365 if (parse_data(doc, node->xmlChildrenNode, xrdoc, elements) == -1)
02366 return -1;
02367
02368 } else {
02369
02370 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02371 xrdoc->parse_error = octstr_format("XML-RPC compiler: bogus parsing exception in parse_array!");
02372 return -1;
02373 }
02374 return 0;
02375 }
02376
02377 static int parse_data(xmlDocPtr doc, xmlNodePtr node,
02378 XMLRPCDocument *xrdoc, List *elements)
02379 {
02380 int status = 0;
02381
02382
02383 switch (node->type) {
02384
02385 case XML_ELEMENT_NODE:
02386 status = parse_data_element(doc, node, xrdoc, elements);
02387 break;
02388
02389 case XML_TEXT_NODE:
02390 case XML_COMMENT_NODE:
02391 case XML_PI_NODE:
02392
02393 break;
02394
02395
02396
02397
02398 default:
02399 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02400 xrdoc->parse_error = octstr_format("XML-RPC compiler: Unknown XML node in the XML-RPC source.");
02401 return -1;
02402 break;
02403 }
02404
02405 if (node->next != NULL)
02406 if (parse_data(doc, node->next, xrdoc, elements) == -1)
02407 return -1;
02408
02409 return status;
02410 }
02411
02412 static int parse_data_element(xmlDocPtr doc, xmlNodePtr node,
02413 XMLRPCDocument *xrdoc, List *elements)
02414 {
02415 Octstr *name;
02416 XMLRPCValue *value;
02417 size_t i;
02418
02419
02420
02421
02422 if (node->name == NULL) {
02423 error(0, "XMLRPC: XML data element nodes without name!");
02424 xrdoc->parse_status = XMLRPC_XMLPARSE_FAILED;
02425 xrdoc->parse_error = octstr_format("XML-RPC compiler: bad XML");
02426 return -1;
02427 }
02428
02429 name = octstr_create(node->name);
02430 if (octstr_len(name) == 0) {
02431 octstr_destroy(name);
02432 return -1;
02433 }
02434
02435 i = 0;
02436 while (i < NUMBER_OF_DATA_ELEMENTS) {
02437 if (octstr_case_compare(name, octstr_imm(data_elements[i].name)) == 0)
02438 break;
02439 ++i;
02440 }
02441 if (i == NUMBER_OF_DATA_ELEMENTS) {
02442 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02443 xrdoc->parse_error = octstr_format("XML-RPC compiler: unknown tag '%s' "
02444 "in XML source at level <data>",
02445 octstr_get_cstr(name));
02446 octstr_destroy(name);
02447 return -1;
02448 }
02449 octstr_destroy(name);
02450
02451
02452
02453
02454
02455
02456
02457 if (i == 0) {
02458
02459 value = xmlrpc_value_create();
02460 if (parse_value(doc, node->xmlChildrenNode, xrdoc, value) == -1) {
02461 xmlrpc_value_destroy(value);
02462 return -1;
02463 }
02464 gwlist_append(elements, value);
02465
02466 } else {
02467
02468 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02469 xrdoc->parse_error = octstr_format("XML-RPC compiler: bogus parsing exception in parse_array!");
02470 return -1;
02471 }
02472 return 0;
02473 }
02474
02475 static int parse_fault(xmlDocPtr doc, xmlNodePtr node,
02476 XMLRPCDocument *xrdoc, XMLRPCFault *fault)
02477 {
02478 int status = 0;
02479
02480
02481 switch (node->type) {
02482
02483 case XML_ELEMENT_NODE:
02484 status = parse_fault_element(doc, node, xrdoc, fault);
02485 break;
02486
02487 case XML_TEXT_NODE:
02488 case XML_COMMENT_NODE:
02489 case XML_PI_NODE:
02490
02491 break;
02492
02493
02494
02495
02496 default:
02497 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02498 xrdoc->parse_error = octstr_format("XML-RPC compiler: Unknown XML node in the XML-RPC source.");
02499 return -1;
02500 break;
02501 }
02502
02503 if (node->next != NULL)
02504 if (parse_fault(doc, node->next, xrdoc, fault) == -1)
02505 return -1;
02506
02507 return status;
02508 }
02509
02510 static int parse_fault_element(xmlDocPtr doc, xmlNodePtr node,
02511 XMLRPCDocument *xrdoc, XMLRPCFault *fault)
02512 {
02513 Octstr *name;
02514 XMLRPCValue *value, *v_code, *v_string;
02515 size_t i;
02516
02517
02518
02519
02520 if (node->name == NULL) {
02521 error(0, "XMLRPC: XML fault element nodes without name!");
02522 xrdoc->parse_status = XMLRPC_XMLPARSE_FAILED;
02523 xrdoc->parse_error = octstr_format("XML-RPC compiler: bad XML");
02524 return -1;
02525 }
02526
02527 name = octstr_create(node->name);
02528 if (octstr_len(name) == 0) {
02529 octstr_destroy(name);
02530 return -1;
02531 }
02532
02533 i = 0;
02534 while (i < NUMBER_OF_FAULT_ELEMENTS) {
02535 if (octstr_case_compare(name, octstr_imm(fault_elements[i].name)) == 0)
02536 break;
02537 ++i;
02538 }
02539 if (i == NUMBER_OF_FAULT_ELEMENTS) {
02540 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02541 xrdoc->parse_error = octstr_format("XML-RPC compiler: unknown tag '%s' "
02542 "in XML source at level <fault>",
02543 octstr_get_cstr(name));
02544 octstr_destroy(name);
02545 return -1;
02546 }
02547 octstr_destroy(name);
02548
02549
02550
02551
02552
02553
02554
02555 if (i == 0) {
02556
02557 value = xmlrpc_value_create();
02558 if (parse_value(doc, node->xmlChildrenNode, xrdoc, value) == -1) {
02559 xmlrpc_value_destroy(value);
02560 return -1;
02561 }
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574 if (xmlrpc_value_get_type(value) != xr_struct ||
02575 (v_code = xmlrpc_get_member(value, octstr_imm("faultCode"))) == NULL ||
02576 xmlrpc_value_get_type_smart(v_code) != xr_int ||
02577 (v_string = xmlrpc_get_member(value, octstr_imm("faultString"))) == NULL ||
02578 xmlrpc_value_get_type_smart(v_string) != xr_string ||
02579 xmlrpc_count_members(value) != 2) {
02580
02581 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02582 xrdoc->parse_error = octstr_format("XML-RPC compiler: bogus value "
02583 "in XML source at level <fault>");
02584 xmlrpc_value_destroy(value);
02585 return -1;
02586 }
02587
02588 fault->f_code = xmlrpc_scalar_get_int((XMLRPCScalar *) xmlrpc_value_get_content(v_code));
02589 fault->f_string = xmlrpc_scalar_get_string((XMLRPCScalar *) xmlrpc_value_get_content(v_string));
02590
02591 xmlrpc_value_destroy(value);
02592 } else {
02593 xrdoc->parse_status = XMLRPC_PARSING_FAILED;
02594 xrdoc->parse_error = octstr_format("XML-RPC compiler: duplicated tag '<name>' "
02595 "in XML source at level <member>");
02596 return -1;
02597 }
02598 return 0;
02599 }
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.