static void interpretFaultValue(xmlrpc_env * const envP, xmlrpc_value * const faultVP, int * const faultCodeP, const char ** const faultStringP) { if (faultVP->_type != XMLRPC_TYPE_STRUCT) setParseFault(envP, "<value> element of <fault> response is not " "of structure type"); else { xmlrpc_value * faultCodeVP; xmlrpc_env fvEnv; xmlrpc_env_init(&fvEnv); xmlrpc_struct_read_value(&fvEnv, faultVP, "faultCode", &faultCodeVP); if (!fvEnv.fault_occurred) { interpretFaultCode(&fvEnv, faultCodeVP, faultCodeP); if (!fvEnv.fault_occurred) { xmlrpc_value * faultStringVP; xmlrpc_struct_read_value(&fvEnv, faultVP, "faultString", &faultStringVP); if (!fvEnv.fault_occurred) { interpretFaultString(&fvEnv, faultStringVP, faultStringP); xmlrpc_DECREF(faultStringVP); } } xmlrpc_DECREF(faultCodeVP); } if (fvEnv.fault_occurred) setParseFault(envP, "Invalid struct for <fault> value. %s", fvEnv.fault_string); xmlrpc_env_clean(&fvEnv); } }
char * wpGetBlogId(char *username, char *password, char *url) { char *blogid; int i; int noOfBlogs; xmlrpc_env env; xmlrpc_client *clientP; char *methodName = "wp.getUsersBlogs"; xmlrpc_value *result, *result2; wp_env_init(&env, &clientP); /* Make the remote procedure call */ xmlrpc_client_call2f(&env, clientP, url, methodName, &result, "(ss)", username, password); die_if_fault_occurred(&env); noOfBlogs = xmlrpc_array_size(&env, result); if ( noOfBlogs > 1 ) { fprintf(stderr, "Currently only single blog wp accounts are supported\n"); blogid = NULL; goto out; } for(i = 0; i < noOfBlogs; i++) { xmlrpc_value *blog_id_xml; xmlrpc_array_read_item(&env, result, i, &result2); xmlrpc_struct_read_value(&env, result2, "blogid", &blog_id_xml); xmlrpc_read_string(&env, blog_id_xml,(const char **) &blogid); xmlrpc_DECREF(blog_id_xml); } /* Dispose of our result value. */ xmlrpc_DECREF(result2); out: xmlrpc_DECREF(result); /* Clean up our error-handling environment. */ wp_env_clean(&env, &clientP); return blogid; }
static void parsestruct(xmlrpc_env *const envP, xmlrpc_value *const structP, struct structDecomp const structDecomp, bool const oldstyleMemMgmt) { unsigned int doneCount; doneCount = 0; /* No members done yet */ while (doneCount < structDecomp.mbrCnt && !envP->fault_occurred) { const char *const key = structDecomp.mbrArray[doneCount].key; xmlrpc_value *valueP; xmlrpc_struct_read_value(envP, structP, key, &valueP); if (!envP->fault_occurred) { decomposeValueWithTree( envP, valueP, oldstyleMemMgmt, structDecomp.mbrArray[doneCount].decompTreeP); if (!envP->fault_occurred) ++doneCount; xmlrpc_DECREF(valueP); } } if (envP->fault_occurred) { if (!oldstyleMemMgmt) { /* Release the items we completed before we failed. */ unsigned int i; for (i = 0; i < doneCount; ++i) releaseDecomposition(structDecomp.mbrArray[i].decompTreeP); } } }
static xmlrpc_value * add_flow_destination(xmlrpc_env * const env, xmlrpc_value * const param_array, void * const user_data) { UNUSED_ARGUMENT(user_data); int rc, i; xmlrpc_value *ret = 0; char* cc_alg = 0; char* bind_address = 0; xmlrpc_value* extra_options = 0; struct _flow_settings settings; struct _request_add_flow_destination* request = 0; DEBUG_MSG(LOG_WARNING, "Method add_flow_destination called"); /* Parse our argument array. */ xmlrpc_decompose_value(env, param_array, "(" "{s:s,*}" "{s:d,s:d,s:d,s:d,s:d,*}" "{s:i,s:i,*}" "{s:i,*}" "{s:b,s:b,s:b,s:b,s:b,*}" "{s:i,s:i,*}" "{s:i,s:d,s:d,*}" /* request */ "{s:i,s:d,s:d,*}" /* response */ "{s:i,s:d,s:d,*}" /* interpacket_gap */ "{s:b,s:b,s:i,s:i,*}" "{s:s,*}" "{s:i,s:i,s:i,s:i,s:i,*}" #ifdef HAVE_LIBPCAP "{s:s,*}" #endif /* HAVE_LIBPCAP */ "{s:i,s:A,*}" ")", /* general settings */ "bind_address", &bind_address, "write_delay", &settings.delay[WRITE], "write_duration", &settings.duration[WRITE], "read_delay", &settings.delay[READ], "read_duration", &settings.duration[READ], "reporting_interval", &settings.reporting_interval, "requested_send_buffer_size", &settings.requested_send_buffer_size, "requested_read_buffer_size", &settings.requested_read_buffer_size, "maximum_block_size", &settings.maximum_block_size, "traffic_dump", &settings.traffic_dump, "so_debug", &settings.so_debug, "route_record", &settings.route_record, "pushy", &settings.pushy, "shutdown", &settings.shutdown, "write_rate", &settings.write_rate, "random_seed",&settings.random_seed, "traffic_generation_request_distribution", &settings.request_trafgen_options.distribution, "traffic_generation_request_param_one", &settings.request_trafgen_options.param_one, "traffic_generation_request_param_two", &settings.request_trafgen_options.param_two, "traffic_generation_response_distribution", &settings.response_trafgen_options.distribution, "traffic_generation_response_param_one", &settings.response_trafgen_options.param_one, "traffic_generation_response_param_two", &settings.response_trafgen_options.param_two, "traffic_generation_gap_distribution", &settings.interpacket_gap_trafgen_options.distribution, "traffic_generation_gap_param_one", &settings.interpacket_gap_trafgen_options.param_one, "traffic_generation_gap_param_two", &settings.interpacket_gap_trafgen_options.param_two, "flow_control", &settings.flow_control, "byte_counting", &settings.byte_counting, "cork", &settings.cork, "nonagle", &settings.nonagle, "cc_alg", &cc_alg, "elcn", &settings.elcn, "lcd", &settings.lcd, "mtcp", &settings.mtcp, "dscp", &settings.dscp, "ipmtudiscover", &settings.ipmtudiscover, #ifdef HAVE_LIBPCAP "dump_prefix", &dump_prefix, #endif /* HAVE_LIBPCAP */ "num_extra_socket_options", &settings.num_extra_socket_options, "extra_socket_options", &extra_options); if (env->fault_occurred) goto cleanup; /* Check for sanity */ if (strlen(bind_address) >= sizeof(settings.bind_address) - 1 || settings.delay[WRITE] < 0 || settings.duration[WRITE] < 0 || settings.delay[READ] < 0 || settings.duration[READ] < 0 || settings.requested_send_buffer_size < 0 || settings.requested_read_buffer_size < 0 || settings.maximum_block_size < MIN_BLOCK_SIZE || settings.write_rate < 0 || strlen(cc_alg) > TCP_CA_NAME_MAX || settings.num_extra_socket_options < 0 || settings.num_extra_socket_options > MAX_EXTRA_SOCKET_OPTIONS || xmlrpc_array_size(env, extra_options) != settings.num_extra_socket_options) { XMLRPC_FAIL(env, XMLRPC_TYPE_ERROR, "Flow settings incorrect"); } /* Parse extra socket options */ for (i = 0; i < settings.num_extra_socket_options; i++) { const unsigned char* buffer = 0; size_t len; xmlrpc_value *option, *level = 0, *optname = 0, *value = 0; xmlrpc_array_read_item(env, extra_options, i, &option); if (!env->fault_occurred) xmlrpc_struct_read_value(env, option, "level", &level); if (!env->fault_occurred) xmlrpc_struct_read_value(env, option, "optname", &optname); if (!env->fault_occurred) xmlrpc_struct_read_value(env, option, "value", &value); if (!env->fault_occurred) xmlrpc_read_int(env, level, &settings.extra_socket_options[i].level); if (!env->fault_occurred) xmlrpc_read_int(env, optname, &settings.extra_socket_options[i].optname); if (!env->fault_occurred) xmlrpc_read_base64(env, value, &len, &buffer); if (level) xmlrpc_DECREF(level); if (optname) xmlrpc_DECREF(optname); if (value) xmlrpc_DECREF(value); if (!env->fault_occurred) { if (len > MAX_EXTRA_SOCKET_OPTION_VALUE_LENGTH) { free((void *)buffer); XMLRPC_FAIL(env, XMLRPC_TYPE_ERROR, "Too long extra socket option length"); } settings.extra_socket_options[i].optlen = len; memcpy(settings.extra_socket_options[i].optval, buffer, len); free((void *)buffer); } if (env->fault_occurred) goto cleanup; } strcpy(settings.cc_alg, cc_alg); strcpy(settings.bind_address, bind_address); DEBUG_MSG(LOG_WARNING, "bind_address=%s", bind_address); request = malloc(sizeof(struct _request_add_flow_destination)); request->settings = settings; rc = dispatch_request((struct _request*)request, REQUEST_ADD_DESTINATION); if (rc == -1) { XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR, request->r.error); /* goto cleanup on failure */ } /* Return our result. */ ret = xmlrpc_build_value(env, "{s:i,s:i,s:i,s:i}", "flow_id", request->flow_id, "listen_data_port", request->listen_data_port, "real_listen_send_buffer_size", request->real_listen_send_buffer_size, "real_listen_read_buffer_size", request->real_listen_read_buffer_size); cleanup: if (request) free_all(request->r.error, request); free_all(cc_alg, bind_address); if (extra_options) xmlrpc_DECREF(extra_options); if (env->fault_occurred) logging_log(LOG_WARNING, "Method add_flow_destination failed: %s", env->fault_string); else { DEBUG_MSG(LOG_WARNING, "Method add_flow_destination successful"); } return ret; }
static void test_struct (void) { xmlrpc_env env; xmlrpc_value * value1P; xmlrpc_value *s, *i, *i1, *i2, *i3, *key, *value; size_t size; int present; xmlrpc_bool bval; char const weirdKey[] = {'f', 'o', 'o', '\0', 'b', 'a', 'r'}; xmlrpc_env_init(&env); /* Create a struct. */ s = xmlrpc_struct_new(&env); TEST_NO_FAULT(&env); TEST(s != NULL); TEST(XMLRPC_TYPE_STRUCT == xmlrpc_value_type(s)); size = xmlrpc_struct_size(&env, s); TEST_NO_FAULT(&env); TEST(size == 0); /* Create some elements to insert into our struct. */ i1 = xmlrpc_build_value(&env, "s", "Item #1"); TEST_NO_FAULT(&env); i2 = xmlrpc_build_value(&env, "s", "Item #2"); TEST_NO_FAULT(&env); i3 = xmlrpc_build_value(&env, "s", "Item #3"); TEST_NO_FAULT(&env); /* Insert a single item. */ xmlrpc_struct_set_value(&env, s, "foo", i1); TEST_NO_FAULT(&env); size = xmlrpc_struct_size(&env, s); TEST_NO_FAULT(&env); TEST(size == 1); /* Insert an item whose key has the same hash value as "foo". */ xmlrpc_struct_set_value(&env, s, "qmdebdw", i2); TEST_NO_FAULT(&env); size = xmlrpc_struct_size(&env, s); TEST_NO_FAULT(&env); TEST(size == 2); i = xmlrpc_struct_get_value(&env, s, "foo"); TEST_NO_FAULT(&env); TEST(i == i1); i = xmlrpc_struct_get_value(&env, s, "qmdebdw"); TEST_NO_FAULT(&env); TEST(i == i2); /* Replace an existing element with a different element. */ xmlrpc_struct_set_value(&env, s, "foo", i3); TEST_NO_FAULT(&env); size = xmlrpc_struct_size(&env, s); TEST_NO_FAULT(&env); TEST(size == 2); i = xmlrpc_struct_get_value(&env, s, "foo"); TEST_NO_FAULT(&env); TEST(i == i3); /* Insert an item with a NUL in the key */ xmlrpc_struct_set_value_n(&env, s, weirdKey, sizeof(weirdKey), i2); TEST_NO_FAULT(&env); size = xmlrpc_struct_size(&env, s); TEST_NO_FAULT(&env); TEST(size == 3); test_struct_get_element(s, i3, i2, weirdKey, sizeof(weirdKey)); /* Replace an existing element with the same element (tricky). */ xmlrpc_struct_set_value(&env, s, "foo", i3); TEST_NO_FAULT(&env); size = xmlrpc_struct_size(&env, s); TEST_NO_FAULT(&env); TEST(size == 3); i = xmlrpc_struct_get_value(&env, s, "foo"); TEST_NO_FAULT(&env); TEST(i == i3); /* Test for the presence and absence of elements. */ present = xmlrpc_struct_has_key(&env, s, "foo"); TEST_NO_FAULT(&env); TEST(present); present = xmlrpc_struct_has_key(&env, s, "qmdebdw"); TEST_NO_FAULT(&env); TEST(present); present = xmlrpc_struct_has_key(&env, s, "bogus"); TEST_NO_FAULT(&env); TEST(!present); /* Make sure our typechecks work correctly. */ xmlrpc_struct_size(&env, i1); TEST_FAULT(&env, XMLRPC_TYPE_ERROR); xmlrpc_struct_has_key(&env, i1, "foo"); TEST_FAULT(&env, XMLRPC_TYPE_ERROR); xmlrpc_struct_set_value(&env, i1, "foo", i2); TEST_FAULT(&env, XMLRPC_TYPE_ERROR); xmlrpc_struct_set_value_v(&env, s, s, i2); TEST_FAULT(&env, XMLRPC_TYPE_ERROR); /* Test cleanup code (w/memprof). */ xmlrpc_DECREF(s); s = xmlrpc_build_value(&env, "{s:s,s:i,s:b}", "foo", "Hello!", "bar", (xmlrpc_int32) 1, "baz", (xmlrpc_bool) 0); TEST_NO_FAULT(&env); TEST(s != NULL); TEST(xmlrpc_value_type(s) == XMLRPC_TYPE_STRUCT); size = xmlrpc_struct_size(&env, s); TEST_NO_FAULT(&env); TEST(size == 3); present = xmlrpc_struct_has_key(&env, s, "foo"); TEST_NO_FAULT(&env); TEST(present); present = xmlrpc_struct_has_key(&env, s, "bar"); TEST_NO_FAULT(&env); TEST(present); present = xmlrpc_struct_has_key(&env, s, "baz"); TEST_NO_FAULT(&env); TEST(present); xmlrpc_struct_read_value(&env, s, "baz", &value1P); TEST_NO_FAULT(&env); xmlrpc_read_bool(&env, value1P, &bval); TEST_NO_FAULT(&env); TEST(!bval); xmlrpc_DECREF(value1P); testStructReadout(s, 3); test_struct_decompose(s); /* Test type check. */ xmlrpc_struct_get_key_and_value(&env, i1, 0, &key, &value); TEST_FAULT(&env, XMLRPC_TYPE_ERROR); TEST(key == NULL && value == NULL); /* Test bounds checks. */ xmlrpc_struct_get_key_and_value(&env, s, -1, &key, &value); TEST_FAULT(&env, XMLRPC_INDEX_ERROR); TEST(key == NULL && value == NULL); xmlrpc_struct_get_key_and_value(&env, s, 3, &key, &value); TEST_FAULT(&env, XMLRPC_INDEX_ERROR); TEST(key == NULL && value == NULL); /* Test cleanup code (w/memprof). */ xmlrpc_DECREF(s); xmlrpc_DECREF(i1); xmlrpc_DECREF(i2); xmlrpc_DECREF(i3); xmlrpc_env_clean(&env); }
static void test_struct_get_element(xmlrpc_value * const structP, xmlrpc_value * const fooValueP, xmlrpc_value * const weirdValueP, const char * const weirdKey, unsigned int const weirdKeyLen) { xmlrpc_env env; xmlrpc_value * valueP; xmlrpc_value * fooStringP; xmlrpc_value * bogusKeyStringP; xmlrpc_env_init(&env); /* build test tools */ fooStringP = xmlrpc_build_value(&env, "s", "foo"); TEST_NO_FAULT(&env); bogusKeyStringP = xmlrpc_build_value(&env, "s", "doesn't_exist"); TEST_NO_FAULT(&env); /* "find" interface */ xmlrpc_struct_find_value(&env, structP, "foo", &valueP); TEST_NO_FAULT(&env); TEST(valueP == fooValueP); xmlrpc_DECREF(valueP); xmlrpc_struct_find_value(&env, structP, "doesn't_exist", &valueP); TEST_NO_FAULT(&env); TEST(valueP == NULL); xmlrpc_struct_find_value_v(&env, structP, fooStringP, &valueP); TEST_NO_FAULT(&env); TEST(valueP == fooValueP); xmlrpc_DECREF(valueP); xmlrpc_struct_find_value_v(&env, structP, bogusKeyStringP, &valueP); TEST_NO_FAULT(&env); TEST(valueP == NULL); xmlrpc_struct_find_value(&env, fooValueP, "foo", &valueP); TEST_FAULT(&env, XMLRPC_TYPE_ERROR); /* "read" interface */ xmlrpc_struct_read_value(&env, structP, "foo", &valueP); TEST_NO_FAULT(&env); TEST(valueP == fooValueP); xmlrpc_DECREF(valueP); xmlrpc_struct_read_value(&env, structP, "doesn't_exist", &valueP); TEST_FAULT(&env, XMLRPC_INDEX_ERROR); xmlrpc_struct_read_value_v(&env, structP, fooStringP, &valueP); TEST_NO_FAULT(&env); TEST(valueP == fooValueP); xmlrpc_DECREF(valueP); xmlrpc_struct_read_value_v(&env, structP, bogusKeyStringP, &valueP); TEST_FAULT(&env, XMLRPC_INDEX_ERROR); xmlrpc_struct_read_value(&env, fooValueP, "foo", &valueP); TEST_FAULT(&env, XMLRPC_TYPE_ERROR); /* obsolete "get" interface. Note that it does not update the reference count of the xmlrpc_value it returns. */ valueP = xmlrpc_struct_get_value(&env, structP, "foo"); TEST_NO_FAULT(&env); TEST(valueP == fooValueP); valueP = xmlrpc_struct_get_value(&env, structP, "doesn't_exist"); TEST_FAULT(&env, XMLRPC_INDEX_ERROR); valueP = xmlrpc_struct_get_value(&env, fooValueP, "foo"); TEST_FAULT(&env, XMLRPC_TYPE_ERROR); valueP = xmlrpc_struct_get_value_n(&env, structP, weirdKey, weirdKeyLen); TEST_NO_FAULT(&env); TEST(valueP == weirdValueP); /* Clean up */ xmlrpc_DECREF(fooStringP); xmlrpc_DECREF(bogusKeyStringP); xmlrpc_env_clean(&env); }