int wpCreatePostStruct(xmlrpc_env *env, char *username, char*password, wppost_t *post, xmlrpc_value **paramArray, int mode) { int retval = 0; xmlrpc_value *blogidP, *postidP, *usernameP, *passwordP, *titleP, *descriptionP, *dateP, *publishP, *categoryP, *contentP, *tokenP; char *token; char *categories = NULL, *catPtr; if ( mode == 0 ) { post->blogid = wpGetBlogId(username, password, post->url); if (post->blogid == NULL) { fprintf(stderr, "NULL Blog Id\n"); retval = 1; goto out; } blogidP = xmlrpc_string_new(env, post->blogid); postidP = NULL; } else { blogidP = NULL; postidP = xmlrpc_string_new(env, post->postid); } usernameP = xmlrpc_string_new(env, username); passwordP = xmlrpc_string_new(env, password); titleP = xmlrpc_string_new(env, post->subject); descriptionP = xmlrpc_string_new(env, post->body); if(!strcmp(post->status, "draft")) { publishP = xmlrpc_bool_new(env, FALSE); } else { publishP = xmlrpc_bool_new(env, TRUE); } dateP = xmlrpc_datetime_new_sec(env, time(NULL)); asprintf(&categories, "%s", post->categories); catPtr = categories; categoryP = xmlrpc_array_new(env); token = strtok(categories, ","); tokenP = xmlrpc_string_new(env, token); xmlrpc_array_append_item(env, categoryP, tokenP); while( (token = strtok( (char *) NULL, ",") ) != NULL ) { tokenP = xmlrpc_string_new(env, token); xmlrpc_array_append_item(env, categoryP, tokenP); } free(catPtr); contentP = xmlrpc_struct_new(env); xmlrpc_struct_set_value(env, contentP, "title", titleP); xmlrpc_struct_set_value(env, contentP, "description", descriptionP); xmlrpc_struct_set_value(env, contentP, "dateCreated", dateP); xmlrpc_struct_set_value(env, contentP, "categories", categoryP); /* Populate the Parameter Array */ *paramArray = xmlrpc_array_new(env); if (mode == 0) xmlrpc_array_append_item(env, *paramArray, blogidP); else xmlrpc_array_append_item(env, *paramArray, postidP); xmlrpc_array_append_item(env, *paramArray, usernameP); xmlrpc_array_append_item(env, *paramArray, passwordP); xmlrpc_array_append_item(env, *paramArray, contentP); xmlrpc_array_append_item(env, *paramArray, publishP); out: return retval; }
/* Pack the information from any client method into a generic xmlrpc struct to send to the server */ xmlrpc_value * callinfo_pack(xmlrpc_env *envP, struct call_info *cip) { xmlrpc_value *s = xmlrpc_struct_new(envP); xmlrpc_value *methargs = xmlrpc_array_new(envP); xmlrpc_value *files = xmlrpc_array_new(envP); int i; xmlrpc_struct_set_value(envP, s, "clientIP", xmlrpc_string_new(envP, nonull(cip->clientIP))); xmlrpc_struct_set_value(envP, s, "serverURL", xmlrpc_string_new(envP, nonull(cip->serverURL))); xmlrpc_struct_set_value(envP, s, "session", xmlrpc_string_new(envP, nonull(cip->session))); xmlrpc_struct_set_value(envP, s, "method", xmlrpc_string_new(envP, nonull(cip->method))); xmlrpc_struct_set_value(envP, s, "user", xmlrpc_string_new(envP, nonull(cip->user))); xmlrpc_struct_set_value(envP, s, "password", xmlrpc_string_new(envP, nonull(cip->password))); xmlrpc_struct_set_value(envP, s, "project", xmlrpc_string_new(envP, nonull(cip->project))); xmlrpc_struct_set_value(envP, s, "version", xmlrpc_string_new(envP, nonull(cip->version))); if (cip->methodargs) { for (i = 0; cip->methodargs[i]; ++i) { if (!strncmp(cip->methodargs[i], "file:", 5)) { char *file_what, *file_name; file_what = strdup(&cip->methodargs[i][5]); file_name = strchr(file_what, '='); if (file_name) { xmlrpc_value * fstruct; *file_name++ = '\0'; fstruct = file_pack(envP, file_what, file_name); xmlrpc_array_append_item(envP, files, fstruct); } else { fprintf(stderr, "oracc-client: bad -Mfile arg, expected -Mfile:WHAT=NAME\n"); exit(1); } } else xmlrpc_array_append_item(envP, methargs, xmlrpc_string_new(envP, cip->methodargs[i])); } } xmlrpc_struct_set_value(envP, s, "method-args", methargs); xmlrpc_struct_set_value(envP, s, "method-data", files); return s; }
static void test_value_array(void) { xmlrpc_value *v; xmlrpc_env env; size_t len; /* Basic array-building test. */ xmlrpc_env_init(&env); v = xmlrpc_array_new(&env); TEST_NO_FAULT(&env); TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v)); len = xmlrpc_array_size(&env, v); TEST_NO_FAULT(&env); TEST(len == 0); xmlrpc_DECREF(v); v = xmlrpc_build_value(&env, "()"); TEST_NO_FAULT(&env); TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v)); len = xmlrpc_array_size(&env, v); TEST_NO_FAULT(&env); TEST(len == 0); xmlrpc_DECREF(v); xmlrpc_env_clean(&env); }
xmlrpc_value* GetConferences(xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { MCU *mcu = (MCU *)user_data; MCU::ConferencesInfo list; //Obtenemos la referencia if(!mcu->GetConferenceList(list)) return xmlerror(env,"Could not retreive conference info list\n"); //Create array xmlrpc_value* arr = xmlrpc_array_new(env); //Process result for (MCU::ConferencesInfo::iterator it = list.begin(); it!=list.end(); ++it) { //Create array xmlrpc_value* val = xmlrpc_build_value(env,"(isi)",it->second.id,it->second.name.c_str(),it->second.numPart); //Add it xmlrpc_array_append_item(env,arr,val); //Release xmlrpc_DECREF(val); } //return return xmlok(env,arr); }
/* vxdb.mount.get(string name[, string dst]) */ xmlrpc_value *m_vxdb_mount_get(xmlrpc_env *env, xmlrpc_value *p, void *c) { xmlrpc_value *params, *response = NULL; char *name, *dst; int rc; xid_t xid; params = method_init(env, p, c, VCD_CAP_MOUNT, M_OWNER); method_return_if_fault(env); xmlrpc_decompose_value(env, params, "{s:s,s:s,*}", "name", &name, "dst", &dst); method_return_if_fault(env); method_empty_params(1, &dst); if (dst && !validate_path(dst)) method_return_faultf(env, MEINVAL, "invalid dst value: %s", dst); if (!(xid = vxdb_getxid(name))) method_return_fault(env, MENOVPS); if (dst) rc = vxdb_prepare(&dbr, "SELECT src,dst,type,opts FROM mount " "WHERE xid = %d AND dst = '%s'", xid, dst); else rc = vxdb_prepare(&dbr, "SELECT src,dst,type,opts FROM mount " "WHERE xid = %d ORDER BY dst ASC", xid); if (rc != VXDB_OK) method_return_vxdb_fault(env); response = xmlrpc_array_new(env); vxdb_foreach_step(rc, dbr) xmlrpc_array_append_item(env, response, xmlrpc_build_value(env, "{s:s,s:s,s:s,s:s}", "src", vxdb_column_text(dbr, 0), "dst", vxdb_column_text(dbr, 1), "type", vxdb_column_text(dbr, 2), "opts", vxdb_column_text(dbr, 3))); if (rc != VXDB_DONE) method_set_vxdb_fault(env); vxdb_finalize(dbr); return response; }
static void parseCallChildren(xmlrpc_env * const envP, xml_element * const callElemP, const char ** const methodNameP, xmlrpc_value ** const paramArrayPP ) { /*---------------------------------------------------------------------------- Parse the children of a <methodCall> XML element *callElemP. They should be <methodName> and <params>. -----------------------------------------------------------------------------*/ size_t const callChildCount = xml_element_children_size(callElemP); xml_element * nameElemP; XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(callElemP), "methodCall")); nameElemP = getChildByName(envP, callElemP, "methodName"); if (!envP->fault_occurred) { parseMethodNameElement(envP, nameElemP, methodNameP); if (!envP->fault_occurred) { /* Convert our parameters. */ if (callChildCount > 1) { xml_element * paramsElemP; paramsElemP = getChildByName(envP, callElemP, "params"); if (!envP->fault_occurred) *paramArrayPP = convertParams(envP, paramsElemP); } else { /* Workaround for Ruby XML-RPC and old versions of xmlrpc-epi. Future improvement: Instead of looking at child count, we should just check for existence of <params>. */ *paramArrayPP = xmlrpc_array_new(envP); } if (!envP->fault_occurred) { if (callChildCount > 2) setParseFault(envP, "<methodCall> has extraneous " "children, other than <methodName> and " "<params>. Total child count = %u", callChildCount); if (envP->fault_occurred) xmlrpc_DECREF(*paramArrayPP); } if (envP->fault_occurred) xmlrpc_strfree(*methodNameP); } } }
static xmlrpc_value * system_multicall(xmlrpc_env * const envP, xmlrpc_value * const paramArrayP, void * const serverInfo, void * const callInfo) { xmlrpc_registry * registryP; xmlrpc_value * resultsP; xmlrpc_value * methlistP; XMLRPC_ASSERT_ENV_OK(envP); XMLRPC_ASSERT_ARRAY_OK(paramArrayP); XMLRPC_ASSERT_PTR_OK(serverInfo); resultsP = NULL; /* defeat compiler warning */ /* Turn our arguments into something more useful. */ registryP = (xmlrpc_registry*) serverInfo; getMethListFromMulticallPlist(envP, paramArrayP, &methlistP); if (!envP->fault_occurred) { /* Create an initially empty result list. */ resultsP = xmlrpc_array_new(envP); if (!envP->fault_occurred) { /* Loop over our input list, calling each method in turn. */ unsigned int const methodCount = xmlrpc_array_size(envP, methlistP); unsigned int i; for (i = 0; i < methodCount && !envP->fault_occurred; ++i) { xmlrpc_value * const methinfoP = xmlrpc_array_get_item(envP, methlistP, i); xmlrpc_value * resultP; XMLRPC_ASSERT_ENV_OK(envP); callOneMethod(envP, registryP, methinfoP, callInfo, &resultP); if (!envP->fault_occurred) { /* Append this method result to our master array. */ xmlrpc_array_append_item(envP, resultsP, resultP); xmlrpc_DECREF(resultP); } } if (envP->fault_occurred) xmlrpc_DECREF(resultsP); xmlrpc_DECREF(methlistP); } } return resultsP; }
xmlrpc_value* GetParticipantStatistics(xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { MCU *mcu = (MCU *)user_data; MultiConf *conf = NULL; //Parseamos int confId; int partId; xmlrpc_parse_value(env, param_array, "(ii)", &confId, &partId); //Comprobamos si ha habido error if(env->fault_occurred) xmlerror(env,"Fault occurred\n"); //Obtenemos la referencia if(!mcu->GetConferenceRef(confId,&conf)) return xmlerror(env,"Conference does not exist"); //Get statistics MultiConf::ParticipantStatistics *partStats = conf->GetParticipantStatistic(partId); //Liberamos la referencia mcu->ReleaseConferenceRef(confId); //Salimos if(!partStats) return xmlerror(env,"Participant not found\n"); //Create array xmlrpc_value* arr = xmlrpc_array_new(env); //Process result for (MultiConf::ParticipantStatistics::iterator it = partStats->begin(); it!=partStats->end(); ++it) { //Get media std::string media = it->first; //Get stats MediaStatistics stats = it->second; //Create array xmlrpc_value* val = xmlrpc_build_value(env,"(siiiiiii)",media.c_str(),stats.isReceiving,stats.isSending,stats.lostRecvPackets,stats.numRecvPackets,stats.numSendPackets,stats.totalRecvBytes,stats.totalSendBytes); //Add it xmlrpc_array_append_item(env,arr,val); //Release xmlrpc_DECREF(val); } //return return xmlok(env,arr); }
static void parseArray(xmlrpc_env * const envP, unsigned int const maxRecursion, xml_element * const arrayElemP, xmlrpc_value ** const arrayPP) { xmlrpc_value * arrayP; XMLRPC_ASSERT_ENV_OK(envP); XMLRPC_ASSERT(arrayElemP != NULL); arrayP = xmlrpc_array_new(envP); if (!envP->fault_occurred) { unsigned int const childCount = xml_element_children_size(arrayElemP); if (childCount != 1) setParseFault(envP, "<array> element has %u children. Only one <data> " "makes sense.", childCount); else { xml_element * const dataElemP = xml_element_children(arrayElemP)[0]; const char * const elemName = xml_element_name(dataElemP); if (!xmlrpc_streq(elemName, "data")) setParseFault(envP, "<array> element has <%s> child. Only <data> " "makes sense.", elemName); else { xml_element ** const values = xml_element_children(dataElemP); unsigned int const size = xml_element_children_size(dataElemP); unsigned int i; for (i = 0; i < size && !envP->fault_occurred; ++i) parseArrayDataChild(envP, values[i], maxRecursion, arrayP); } } if (envP->fault_occurred) xmlrpc_DECREF(arrayP); else *arrayPP = arrayP; } }
static void test_value_array(void) { xmlrpc_value *v; xmlrpc_env env; size_t len; xmlrpc_value * itemP; /* Basic array-building test. */ xmlrpc_env_init(&env); TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_ARRAY), "ARRAY")); v = xmlrpc_array_new(&env); TEST_NO_FAULT(&env); TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v)); len = xmlrpc_array_size(&env, v); TEST_NO_FAULT(&env); TEST(len == 0); itemP = xmlrpc_int_new(&env, 7); TEST_NO_FAULT(&env); xmlrpc_array_append_item(&env, v, itemP); TEST_NO_FAULT(&env); len = xmlrpc_array_size(&env, v); TEST_NO_FAULT(&env); TEST(len == 1); xmlrpc_DECREF(itemP); xmlrpc_DECREF(v); v = xmlrpc_build_value(&env, "()"); TEST_NO_FAULT(&env); TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v)); len = xmlrpc_array_size(&env, v); TEST_NO_FAULT(&env); TEST(len == 0); xmlrpc_DECREF(v); xmlrpc_env_clean(&env); }
static void testSynchCall(void) { xmlrpc_env env; xmlrpc_client * clientP; xmlrpc_value * resultP; xmlrpc_value * emptyArrayP; xmlrpc_server_info * noSuchServerInfoP; xmlrpc_env_init(&env); emptyArrayP = xmlrpc_array_new(&env); TEST_NO_FAULT(&env); xmlrpc_client_setup_global_const(&env); TEST_NO_FAULT(&env); xmlrpc_client_create(&env, 0, "testprog", "1.0", NULL, 0, &clientP); TEST_NO_FAULT(&env); noSuchServerInfoP = xmlrpc_server_info_new(&env, "nosuchserver"); TEST_NO_FAULT(&env); xmlrpc_client_call2(&env, clientP, noSuchServerInfoP, "nosuchmethod", emptyArrayP, &resultP); TEST_FAULT(&env, XMLRPC_NETWORK_ERROR); /* No such server */ xmlrpc_client_call2f(&env, clientP, "nosuchserver", "nosuchmethod", &resultP, "(i)", 7); TEST_FAULT(&env, XMLRPC_NETWORK_ERROR); /* No such server */ xmlrpc_server_info_free(noSuchServerInfoP); xmlrpc_client_destroy(clientP); xmlrpc_DECREF(emptyArrayP); xmlrpc_client_teardown_global_const(); xmlrpc_env_clean(&env); }
xmlrpc_value *xmlrpccmd_core_get_log(xmlrpc_env * const envP, xmlrpc_value * const paramArrayP, void * const userData) { uint32_t last_id; xmlrpc_decompose_value(envP, paramArrayP, "(i)", &last_id); if (envP->fault_occurred) return NULL; xmlrpc_value *res = xmlrpc_array_new(envP); if (envP->fault_occurred) return NULL; pomlog_rlock(); struct pomlog_entry *log = pomlog_get_tail(); if (log->id <= last_id) { pomlog_unlock(); return res; } while (log && log->id > last_id + 1) log = log->prev; while (log) { xmlrpc_value *entry = xmlrpc_build_value(envP, "{s:i,s:i,s:s,s:s}", "id", log->id, "level", log->level, "file", log->file, "data", log->data); xmlrpc_array_append_item(envP, res, entry); xmlrpc_DECREF(entry); log = log->next; } pomlog_unlock(); return res; }
static void createMethodListArray(xmlrpc_env * const envP, xmlrpc_registry * const registryP, xmlrpc_value ** const methodListPP) { /*---------------------------------------------------------------------------- Create as an XML-RPC array value a list of names of methods registered in registry 'registryP'. This is the type of value that the system.listMethods method is supposed to return. -----------------------------------------------------------------------------*/ xmlrpc_value * methodListP; methodListP = xmlrpc_array_new(envP); if (!envP->fault_occurred) { xmlrpc_methodNode * methodNodeP; for (methodNodeP = registryP->methodListP->firstMethodP; methodNodeP && !envP->fault_occurred; methodNodeP = methodNodeP->nextP) { xmlrpc_value * methodNameVP; methodNameVP = xmlrpc_string_new(envP, methodNodeP->methodName); if (!envP->fault_occurred) { xmlrpc_array_append_item(envP, methodListP, methodNameVP); xmlrpc_DECREF(methodNameVP); } } if (envP->fault_occurred) xmlrpc_DECREF(methodListP); } *methodListPP = methodListP; }
static xmlrpc_value * calculate_modexp(xmlrpc_env * const env, xmlrpc_value * const param_array, void * const serverInfo, void * const channelInfo) { int i = 0; Task temp; xmlrpc_value * retval; xmlrpc_value * arrayP; xmlrpc_decompose_value(env, param_array, "(A)", &arrayP); size_t size = xmlrpc_array_size(env, arrayP); if (env->fault_occurred) retval = NULL; else { for (i = 0; i < size && !env->fault_occurred; ++i) { xmlrpc_value * strctP; strctP = xmlrpc_array_get_item(env, arrayP, i); if (!env->fault_occurred) { if(i == 0) { const char * str1; size_t str1_len; xmlrpc_read_string_lp(env, strctP, &str1_len, &str1); //xmlrpc_int32 curly; //xmlrpc_decompose_value(env, strctP, "(s)",&ip[0]); strcpy(temp._clientid, str1); } else { const char * str1; size_t str1_len; xmlrpc_read_string_lp(env, strctP, &str1_len, &str1); if(i == 1) strcpy(temp.p,str1); else if(i == 2) strcpy(temp.m,str1); } } } } xmlrpc_DECREF(arrayP); if (env->fault_occurred) return NULL; printf("Received: %s %s %s\n",temp._clientid,temp.p,temp.m); /* Add our two numbers. */ // z = x + y; /* Sometimes, make it look hard (so client can see what it's like to do an RPC that takes a while). */ compute_mod(&temp); xmlrpc_value *arr = xmlrpc_array_new(env); xmlrpc_value *v1 = xmlrpc_build_value(env, "s", temp.response); xmlrpc_array_append_item (env,arr,v1); /* Return our result. */ return xmlrpc_build_value(env,"(A)", arr); }
int main(int const argc, const char ** const argv) { if(argc < 2 ) { fprintf(stderr,"Usage : ./client <Semantics> <No of Servers>\n"); exit(EXIT_FAILURE); } const char const **serverUrl; int i = 0, port = 8080 ; xmlrpc_env env; xmlrpc_value * resultP; int nUrl = atoi(argv[2]); struct timeval start,end,diff; if(nUrl == 0) { fprintf(stderr,"Please enter non-zero number of servers\n"); exit(EXIT_FAILURE); } #if 0 serverUrl = (char **) malloc (nUrl * sizeof(char*)); for(i = 0 ; i < nUrl ; i++){ serverUrl[i] = (char *) malloc(50 * sizeof(char)); sprintf(serverUrl[i],"http://localhost:%d/RPC2",port++); } #endif #if 1 serverUrl = malloc(sizeof(char*) * 5); serverUrl[0] = "http://localhost:8080/RPC2"; serverUrl[1] = "http://localhost:8081/RPC2"; serverUrl[2] = "http://localhost:8082/RPC2"; serverUrl[3] = "http://localhost:8083/RPC2"; serverUrl[4] = "http://localhost:8084/RPC2"; #endif const char * const methodName = "calculate_modexp"; //const char * const serverUrl = "http://localhost:8080/RPC2"; /* Initialize our error-handling environment. */ xmlrpc_env_init(&env); /* Start up our XML-RPC client library. */ xmlrpc_client_init2(&env, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, NULL, 0); dieIfFaultOccurred(&env); // printf("Making XMLRPC call to server url '%s' method '%s' " "to request the sum " "of 5 and 7...\n", serverUrl, methodName); /* Make the remote procedure call */ // printf("Result is : %d\n",xmlrpc_validate_utf8("Hello World")); xmlrpc_value *arr = xmlrpc_array_new(&env); //resultP = xmlrpc_client_call(&env, serverUrl, methodName,"(A)", generate_request_array(&env , arr) ); gettimeofday(&start,NULL); /*Call the server*/ resultP = xmlrpc_client_call_multi_sync(atoi(argv[1]),nUrl, &env, serverUrl, methodName,"(A)", generate_request_array(&env , arr)); gettimeofday(&end,NULL); difference(&diff,end,start); printf("Time Taken With %d Server = %ld:%ld\n",nUrl,diff.tv_usec/1000000,diff.tv_usec%1000000); // printf("Check to see if killed\n"); dieIfFaultOccurred(&env); /* Get our sum and print it out. */ //xmlrpc_read_int(&env, resultP, &primeResult); // xmlrpc_env * const dummy; // printf("Extracting Results\n"); const char* result = extract_result ( &env , resultP); dieIfFaultOccurred(&env); // printf("2^p/m = %s\n", result); /*Dispose of our result value. */ xmlrpc_DECREF(resultP); /* Clean up our error-handling environment. */ xmlrpc_env_clean(&env); /* Shutdown our XML-RPC client library. */ xmlrpc_client_cleanup(); return 0; }
cWrapper() { env_wrap env; this->valueP = xmlrpc_array_new(&env.env_c); throwIfError(env); }
void getDataBlock(xmlrpc_env * envP, xmlrpc_value * DataStructP, xmlrpc_value ** OutDataStructPP) { xmlrpc_value * ID_t, * PORT_t, * DATA_t, * IP_t; xmlrpc_struct_find_value(envP, DataStructP, "ID", &ID_t); xmlrpc_struct_find_value(envP, DataStructP, "IP", &IP_t); xmlrpc_struct_find_value(envP, DataStructP, "PORT", &PORT_t); xmlrpc_struct_find_value(envP, DataStructP, "DATA", &DATA_t); xmlrpc_int ID, PORT, DATA; char* IP; xmlrpc_read_int(envP, ID_t, &ID); xmlrpc_read_string(envP, IP_t, &IP); xmlrpc_read_int(envP, PORT_t, &PORT); xmlrpc_read_int(envP, DATA_t, &DATA); xmlrpc_DECREF(ID_t); xmlrpc_DECREF(IP_t); xmlrpc_DECREF(PORT_t); xmlrpc_DECREF(DATA_t); printf("The value of ID is %d\n", ID); printf("The value of ID is %s\n", IP); printf("The value of PORT is %d\n", PORT); printf("The value of DATA is %d\n", DATA); xmlrpc_value * ID_out, * IP_out, * PORT_out, * DATA_out, *DATAP_out; xmlrpc_value * ID1_out, * IP1_out, * PORT1_out, * DATA1_out, *DATAP1_out; xmlrpc_value * ID2_out, * IP2_out, * PORT2_out, * DATA2_out, *DATAP2_out; xmlrpc_value * structArray; structArray = xmlrpc_array_new(envP); ID_out = xmlrpc_int_new(envP, 78654); IP_out = xmlrpc_string_new(envP, "127.0.0.1"); PORT_out = xmlrpc_int_new(envP, 8090); DATA_out = xmlrpc_int_new(envP, 45425); ID1_out = xmlrpc_int_new(envP, 78764); IP1_out = xmlrpc_string_new(envP, "127.0.0.1"); PORT1_out = xmlrpc_int_new(envP, 8091); DATA1_out = xmlrpc_int_new(envP, 452135); ID2_out = xmlrpc_int_new(envP, 78123); IP2_out = xmlrpc_string_new(envP, "127.0.0.1"); PORT2_out = xmlrpc_int_new(envP, 8092); DATA2_out = xmlrpc_int_new(envP, 45563); DATAP_out = xmlrpc_struct_new(envP); DATAP1_out = xmlrpc_struct_new(envP); DATAP2_out = xmlrpc_struct_new(envP); xmlrpc_struct_set_value(envP, DATAP_out, "ID", ID_out); xmlrpc_struct_set_value(envP, DATAP_out, "IP", IP_out); xmlrpc_struct_set_value(envP, DATAP_out, "PORT", PORT_out); xmlrpc_struct_set_value(envP, DATAP_out, "DATA", DATA_out); xmlrpc_struct_set_value(envP, DATAP1_out, "ID", ID1_out); xmlrpc_struct_set_value(envP, DATAP1_out, "IP", IP1_out); xmlrpc_struct_set_value(envP, DATAP1_out, "PORT", PORT1_out); xmlrpc_struct_set_value(envP, DATAP1_out, "DATA", DATA1_out); xmlrpc_struct_set_value(envP, DATAP2_out, "ID", ID2_out); xmlrpc_struct_set_value(envP, DATAP2_out, "IP", IP2_out); xmlrpc_struct_set_value(envP, DATAP2_out, "PORT", PORT2_out); xmlrpc_struct_set_value(envP, DATAP2_out, "DATA", DATA2_out); xmlrpc_array_append_item(envP, structArray, DATAP_out); xmlrpc_array_append_item(envP, structArray, DATAP1_out); xmlrpc_array_append_item(envP, structArray, DATAP2_out); xmlrpc_DECREF(ID_out); xmlrpc_DECREF(IP_out); xmlrpc_DECREF(PORT_out); xmlrpc_DECREF(DATA_out); xmlrpc_DECREF(ID1_out); xmlrpc_DECREF(IP1_out); xmlrpc_DECREF(PORT1_out); xmlrpc_DECREF(DATA1_out); xmlrpc_DECREF(ID2_out); xmlrpc_DECREF(IP2_out); xmlrpc_DECREF(PORT2_out); xmlrpc_DECREF(DATA2_out); *OutDataStructPP = structArray; }
static int unenroll_host(const char *server, const char *hostname, const char *ktname, int quiet) { int rval = 0; int ret; char *ipaserver = NULL; char *host = NULL; struct utsname uinfo; char *principal = NULL; char *realm = NULL; krb5_context krbctx = NULL; krb5_keytab keytab = NULL; krb5_ccache ccache = NULL; krb5_principal princ = NULL; krb5_error_code krberr; krb5_creds creds; krb5_get_init_creds_opt gicopts; char tgs[LINE_MAX]; xmlrpc_env env; xmlrpc_value * argArrayP = NULL; xmlrpc_value * paramArrayP = NULL; xmlrpc_value * paramP = NULL; xmlrpc_value * resultP = NULL; xmlrpc_server_info * serverInfoP = NULL; xmlrpc_value *princP = NULL; char * url = NULL; char * user_agent = NULL; if (server) { ipaserver = strdup(server); } else { char * conf_data = read_config_file(IPA_CONFIG); if ((ipaserver = getIPAserver(conf_data)) == NULL) { if (!quiet) fprintf(stderr, _("Unable to determine IPA server from %s\n"), IPA_CONFIG); exit(1); } free(conf_data); } if (NULL == hostname) { uname(&uinfo); host = strdup(uinfo.nodename); } else { host = strdup(hostname); } if (NULL == strstr(host, ".")) { if (!quiet) fprintf(stderr, _("The hostname must be fully-qualified: %s\n"), host); rval = 16; goto cleanup; } krberr = krb5_init_context(&krbctx); if (krberr) { if (!quiet) fprintf(stderr, _("Unable to join host: " "Kerberos context initialization failed\n")); rval = 1; goto cleanup; } krberr = krb5_kt_resolve(krbctx, ktname, &keytab); if (krberr != 0) { if (!quiet) fprintf(stderr, _("Error resolving keytab: %s.\n"), error_message(krberr)); rval = 7; goto cleanup; } krberr = krb5_get_default_realm(krbctx, &realm); if (krberr != 0) { if (!quiet) fprintf(stderr, _("Error getting default Kerberos realm: %s.\n"), error_message(krberr)); rval = 21; goto cleanup; } ret = asprintf(&principal, "host/%s@%s", host, realm); if (ret == -1) { if (!quiet) fprintf(stderr, _("Out of memory!\n")); rval = 3; goto cleanup; } krberr = krb5_parse_name(krbctx, principal, &princ); if (krberr != 0) { if (!quiet) fprintf(stderr, _("Error parsing \"%1$s\": %2$s.\n"), principal, error_message(krberr)); return krberr; } strcpy(tgs, KRB5_TGS_NAME); snprintf(tgs + strlen(tgs), sizeof(tgs) - strlen(tgs), "/%.*s", (krb5_princ_realm(krbctx, princ))->length, (krb5_princ_realm(krbctx, princ))->data); snprintf(tgs + strlen(tgs), sizeof(tgs) - strlen(tgs), "@%.*s", (krb5_princ_realm(krbctx, princ))->length, (krb5_princ_realm(krbctx, princ))->data); memset(&creds, 0, sizeof(creds)); krb5_get_init_creds_opt_init(&gicopts); krb5_get_init_creds_opt_set_forwardable(&gicopts, 1); krberr = krb5_get_init_creds_keytab(krbctx, &creds, princ, keytab, 0, tgs, &gicopts); if (krberr != 0) { if (!quiet) fprintf(stderr, _("Error obtaining initial credentials: %s.\n"), error_message(krberr)); return krberr; } krberr = krb5_cc_resolve(krbctx, "MEMORY:ipa-join", &ccache); if (krberr == 0) { krberr = krb5_cc_initialize(krbctx, ccache, creds.client); } else { if (!quiet) fprintf(stderr, _("Unable to generate Kerberos Credential Cache\n")); rval = 19; goto cleanup; } krberr = krb5_cc_store_cred(krbctx, ccache, &creds); if (krberr != 0) { if (!quiet) fprintf(stderr, _("Error storing creds in credential cache: %s.\n"), error_message(krberr)); return krberr; } krb5_cc_close(krbctx, ccache); ccache = NULL; putenv("KRB5CCNAME=MEMORY:ipa-join"); /* Start up our XML-RPC client library. */ xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION); xmlrpc_env_init(&env); xmlrpc_client_setup_global_const(&env); #if 1 ret = asprintf(&url, "https://%s:443/ipa/xml", ipaserver); #else ret = asprintf(&url, "http://%s:8888/", ipaserver); #endif if (ret == -1) { if (!quiet) fprintf(stderr, _("Out of memory!\n")); rval = 3; goto cleanup; } serverInfoP = xmlrpc_server_info_new(&env, url); argArrayP = xmlrpc_array_new(&env); paramArrayP = xmlrpc_array_new(&env); paramP = xmlrpc_string_new(&env, host); xmlrpc_array_append_item(&env, argArrayP, paramP); xmlrpc_array_append_item(&env, paramArrayP, argArrayP); xmlrpc_DECREF(paramP); if ((user_agent = set_user_agent(ipaserver)) == NULL) { rval = 3; goto cleanup; } callRPC(user_agent, &env, serverInfoP, "host_disable", paramArrayP, &resultP); if (handle_fault(&env)) { rval = 17; goto cleanup; } xmlrpc_struct_find_value(&env, resultP, "result", &princP); if (princP) { xmlrpc_bool result; xmlrpc_read_bool(&env, princP, &result); if (result == 1) { if (!quiet) fprintf(stderr, _("Unenrollment successful.\n")); } else { if (!quiet) fprintf(stderr, _("Unenrollment failed.\n")); } xmlrpc_DECREF(princP); } else { fprintf(stderr, _("result not found in XML-RPC response\n")); rval = 20; goto cleanup; } cleanup: free(user_agent); if (keytab) krb5_kt_close(krbctx, keytab); free((char *)principal); free((char *)ipaserver); if (princ) krb5_free_principal(krbctx, princ); if (ccache) krb5_cc_close(krbctx, ccache); if (krbctx) krb5_free_context(krbctx); free(url); xmlrpc_env_clean(&env); xmlrpc_client_cleanup(); return rval; }
/* * Write accounting information to this modules database. */ static int xmlrpc_accounting(void *instance, REQUEST * request) { rlm_xmlrpc_t *inst = instance; rlm_xmlrpc_client_t *client; VALUE_PAIR *vps = request->packet->vps; xmlrpc_value *array_param; xmlrpc_value *array_string; xmlrpc_value *resultP; char *const methodName = inst->method; int error; VALUE_PAIR *status_type_pair; if ((status_type_pair = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE)) == NULL) { radlog(L_ERR, "rlm_xmlrpc: No Accounting-Status-Type record."); return RLM_MODULE_NOOP; } client = get_client(instance); /* * Xmlrpc wants method params in an array, so we build an array * with a pointer in index 0. This pointer contains a sub array * filled whith strings each one for packet attributes. */ array_param = xmlrpc_array_new(&client->env); error = check_error(&client->env); if (error != RLM_MODULE_OK) return error; array_string = xmlrpc_array_new(&client->env); error = check_error(&client->env); if (error != RLM_MODULE_OK) return error; /* * The array of strings is built whit vp_prints */ VALUE_PAIR *vp = vps; for (; vp; vp = vp->next) { char buf[1024]; vp_prints(buf, sizeof(buf), vp); xmlrpc_array_append_item(&client->env, array_string, xmlrpc_string_new(&client->env, buf)); int error = check_error(&client->env); if (error != RLM_MODULE_OK) return error; } xmlrpc_array_append_item(&client->env, array_param, array_string); error = check_error(&client->env); if (error != RLM_MODULE_OK) return error; xmlrpc_client_call2(&client->env, client->clientP, client->serverInfoP, methodName, array_param, &resultP); error = check_error(&client->env); if (error != RLM_MODULE_OK) return error; /* * We don't check for method return value. If an accounting packet is * dispatched without errors, it should be processed by server * without any further notification. */ xmlrpc_DECREF(resultP); xmlrpc_DECREF(array_param); xmlrpc_DECREF(array_string); return RLM_MODULE_OK; }
int bugzilla_submit_bug(BugzillaData *data, const char *product, const char *component, const char *summary, const char *version, const char *description, const char *op_sys, const char *platform, const char *priority, const char *severity, const char *cc) { E_ASSERT(data != NULL); int bug_id = -1; xmlrpc_value *result; /* if given CC, add it so bugzilla assign that email as notification receiver */ if(cc) { /* as for now we only support single email address */ xmlrpc_value *cc_array, *cc_str; cc_array = xmlrpc_array_new(&data->xenv); cc_str = xmlrpc_string_new(&data->xenv, (const char *const)cc); xmlrpc_array_append_item(&data->xenv, cc_array, cc_str); xmlrpc_DECREF(cc_str); xmlrpc_client_call2f(&data->xenv, data->xcli, data->url.c_str(), "Bug.create", &result, "({s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:A})", "product", product, "component", component, "summary", summary, "version", version, "description", description, "op_sys", op_sys, "platform", platform, "priority", priority, "severity", severity, "cc", cc_array); xmlrpc_DECREF(cc_array); } else { xmlrpc_client_call2f(&data->xenv, data->xcli, data->url.c_str(), "Bug.create", &result, "({s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s})", "product", product, "component", component, "summary", summary, "version", version, "description", description, "op_sys", op_sys, "platform", platform, "priority", priority, "severity", severity); } if(data->xenv.fault_occurred) { E_WARNING(E_STRLOC ": Unable to perform submit function (%s)\n", data->xenv.fault_string); if(data->cb) (data->cb)(data->xenv.fault_string, data->cb_data); return bug_id; } xmlrpc_decompose_value(&data->xenv, result, "{s:i,*}", "id", &bug_id); xmlrpc_DECREF(result); return bug_id; }
static int join_krb5(const char *ipaserver, char *hostname, char **hostdn, const char **princ, const char **subject, int force, int quiet) { xmlrpc_env env; xmlrpc_value * argArrayP = NULL; xmlrpc_value * paramArrayP = NULL; xmlrpc_value * paramP = NULL; xmlrpc_value * optionsP = NULL; xmlrpc_value * resultP = NULL; xmlrpc_value * structP = NULL; xmlrpc_server_info * serverInfoP = NULL; struct utsname uinfo; xmlrpc_value *princP = NULL; xmlrpc_value *krblastpwdchangeP = NULL; xmlrpc_value *subjectP = NULL; xmlrpc_value *hostdnP = NULL; const char *krblastpwdchange = NULL; char * url = NULL; char * user_agent = NULL; int rval = 0; int ret; *hostdn = NULL; *subject = NULL; *princ = NULL; /* Start up our XML-RPC client library. */ xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION); uname(&uinfo); xmlrpc_env_init(&env); xmlrpc_client_setup_global_const(&env); #if 1 ret = asprintf(&url, "https://%s:443/ipa/xml", ipaserver); #else ret = asprintf(&url, "http://%s:8888/", ipaserver); #endif if (ret == -1) { if (!quiet) fprintf(stderr, _("Out of memory!\n")); rval = 3; goto cleanup; } serverInfoP = xmlrpc_server_info_new(&env, url); argArrayP = xmlrpc_array_new(&env); paramArrayP = xmlrpc_array_new(&env); if (hostname == NULL) paramP = xmlrpc_string_new(&env, uinfo.nodename); else paramP = xmlrpc_string_new(&env, hostname); xmlrpc_array_append_item(&env, argArrayP, paramP); #ifdef REALM if (!quiet) printf("Joining %s to IPA realm %s\n", uinfo.nodename, iparealm); #endif xmlrpc_array_append_item(&env, paramArrayP, argArrayP); xmlrpc_DECREF(paramP); optionsP = xmlrpc_build_value(&env, "{s:s,s:s}", "nsosversion", uinfo.release, "nshardwareplatform", uinfo.machine); xmlrpc_array_append_item(&env, paramArrayP, optionsP); xmlrpc_DECREF(optionsP); if ((user_agent = set_user_agent(ipaserver)) == NULL) { rval = 3; goto cleanup; } callRPC(user_agent, &env, serverInfoP, "join", paramArrayP, &resultP); if (handle_fault(&env)) { rval = 17; goto cleanup_xmlrpc; } /* Return value is the form of an array. The first value is the * DN, the second a struct of attribute values */ xmlrpc_array_read_item(&env, resultP, 0, &hostdnP); xmlrpc_read_string(&env, hostdnP, (const char **)hostdn); xmlrpc_DECREF(hostdnP); xmlrpc_array_read_item(&env, resultP, 1, &structP); xmlrpc_struct_find_value(&env, structP, "krbprincipalname", &princP); if (princP) { xmlrpc_value * singleprincP = NULL; /* FIXME: all values are returned as lists currently. Once this is * fixed we can read the string directly. */ xmlrpc_array_read_item(&env, princP, 0, &singleprincP); xmlrpc_read_string(&env, singleprincP, &*princ); xmlrpc_DECREF(princP); xmlrpc_DECREF(singleprincP); } else { if (!quiet) fprintf(stderr, _("principal not found in XML-RPC response\n")); rval = 12; goto cleanup; } xmlrpc_struct_find_value(&env, structP, "krblastpwdchange", &krblastpwdchangeP); if (krblastpwdchangeP && !force) { xmlrpc_value * singleprincP = NULL; /* FIXME: all values are returned as lists currently. Once this is * fixed we can read the string directly. */ xmlrpc_array_read_item(&env, krblastpwdchangeP, 0, &singleprincP); xmlrpc_read_string(&env, singleprincP, &krblastpwdchange); xmlrpc_DECREF(krblastpwdchangeP); if (!quiet) fprintf(stderr, _("Host is already joined.\n")); rval = 13; goto cleanup; } xmlrpc_struct_find_value(&env, structP, "ipacertificatesubjectbase", &subjectP); if (subjectP) { xmlrpc_value * singleprincP = NULL; /* FIXME: all values are returned as lists currently. Once this is * fixed we can read the string directly. */ xmlrpc_array_read_item(&env, subjectP, 0, &singleprincP); xmlrpc_read_string(&env, singleprincP, *&subject); xmlrpc_DECREF(subjectP); } cleanup: if (argArrayP) xmlrpc_DECREF(argArrayP); if (paramArrayP) xmlrpc_DECREF(paramArrayP); if (resultP) xmlrpc_DECREF(resultP); cleanup_xmlrpc: free(user_agent); free(url); free((char *)krblastpwdchange); xmlrpc_env_clean(&env); xmlrpc_client_cleanup(); return rval; }
/* Function: build_suppressed_msg_value * Description: Pack info of a syslog message into a xmlrpc array of structs: * Key: "msg name" * Value: Array of N items: * Index 0 Struct of 1 members: * Index 0 Key: String "para name" * Index 0 Value: Struct "para value" * * Index 1 Struct of 1 members: * Index 1 Key: String "para name" * Index 1 Value: Struct "para value" * * Parameters: env[in]: xmlrpc env struct * p_msg[in]: ptr to a msg struct * Returns: xml formatted data */ static xmlrpc_value *build_suppressed_msg_value (xmlrpc_env *const env, syslog_msg_def_t *p_msg) { xmlrpc_value *retval; xmlrpc_value *msg_value = NULL; msg_value = xmlrpc_array_new(env); if (!msg_value) { goto done; } if ((build_xml_struct(env, msg_value, "Name", p_msg->msg_name, XMLRPC_CHAR) == NULL) || (build_xml_struct(env, msg_value, "Facility", p_msg->facility->fac_name, XMLRPC_CHAR) == NULL) || (build_xml_struct(env, msg_value, "Format", p_msg->output_format, XMLRPC_CHAR) == NULL)) { return NULL; } if (p_msg->limiter) { char ts_buf[BUFFER_SIZE], string_buffer[BUFFER_SIZE]; snprintf(string_buffer, BUFFER_SIZE, "%llu", p_msg->limiter->suppressed); abs_time_t now = get_sys_time(); rel_time_t last_sup_time = TIME_SUB_A_A(now, p_msg->limiter->last_time); if ((build_xml_struct(env, msg_value, "Limit rate", &(p_msg->limiter->rate_limit), XMLRPC_UINT) == NULL) || (build_xml_struct(env, msg_value, "Suppressed last time (sec ago)", (char *)rel_time_to_str( last_sup_time, ts_buf, BUFFER_SIZE), XMLRPC_CHAR) == NULL) || (build_xml_struct(env, msg_value, "Suppressed message count", string_buffer, XMLRPC_CHAR) == NULL)) { return NULL; } } done: retval = xmlrpc_build_value(env, "{s:A}", p_msg->msg_name, msg_value); xmlrpc_DECREF(msg_value); return retval; }
static xmlrpc_value * method_get_reports(xmlrpc_env * const env, xmlrpc_value * const param_array, void * const user_data) { int has_more; xmlrpc_value *ret = 0, *item = 0; UNUSED_ARGUMENT(param_array); UNUSED_ARGUMENT(user_data); DEBUG_MSG(LOG_NOTICE, "Method get_reports called"); struct _report *report = get_reports(&has_more); ret = xmlrpc_array_new(env); /* Add information if there's more reports pending */ item = xmlrpc_int_new(env, has_more); xmlrpc_array_append_item(env, ret, item); xmlrpc_DECREF(item); while (report) { xmlrpc_value *rv = xmlrpc_build_value(env, "(" "{s:i,s:i,s:i,s:i,s:i,s:i}" /* timeval */ "{s:i,s:i,s:i,s:i}" /* bytes */ "{s:i,s:i,s:i,s:i}" /* block counts */ "{s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d}" /* RTT, IAT, Delay */ "{s:i,s:i}" /* MTU */ "{s:i,s:i,s:i,s:i,s:i}" /* TCP info */ "{s:i,s:i,s:i,s:i,s:i}" /* ... */ "{s:i,s:i,s:i,s:i,s:i}" /* ... */ "{s:i}" ")", "id", report->id, "type", report->type, "begin_tv_sec", (int)report->begin.tv_sec, "begin_tv_nsec", (int)report->begin.tv_nsec, "end_tv_sec", (int)report->end.tv_sec, "end_tv_nsec", (int)report->end.tv_nsec, "bytes_read_high", (int32_t)(report->bytes_read >> 32), "bytes_read_low", (int32_t)(report->bytes_read & 0xFFFFFFFF), "bytes_written_high", (int32_t)(report->bytes_written >> 32), "bytes_written_low", (int32_t)(report->bytes_written & 0xFFFFFFFF), "request_blocks_read", report->request_blocks_read, "request_blocks_written", report->request_blocks_written, "response_blocks_read", report->response_blocks_read, "response_blocks_written", report->response_blocks_written, "rtt_min", report->rtt_min, "rtt_max", report->rtt_max, "rtt_sum", report->rtt_sum, "iat_min", report->iat_min, "iat_max", report->iat_max, "iat_sum", report->iat_sum, "delay_min", report->delay_min, "delay_max", report->delay_max, "delay_sum", report->delay_sum, "pmtu", report->pmtu, "imtu", report->imtu, /* Currently, not all members of the TCP_INFO socket option are used by the * FreeBSD kernel. Other members will contain zeroes */ "tcpi_snd_cwnd", (int)report->tcp_info.tcpi_snd_cwnd, "tcpi_snd_ssthresh", (int)report->tcp_info.tcpi_snd_ssthresh, "tcpi_unacked", (int)report->tcp_info.tcpi_unacked, "tcpi_sacked", (int)report->tcp_info.tcpi_sacked, "tcpi_lost", (int)report->tcp_info.tcpi_lost, "tcpi_retrans", (int)report->tcp_info.tcpi_retrans, "tcpi_retransmits", (int)report->tcp_info.tcpi_retransmits, "tcpi_fackets", (int)report->tcp_info.tcpi_fackets, "tcpi_reordering", (int)report->tcp_info.tcpi_reordering, "tcpi_rtt", (int)report->tcp_info.tcpi_rtt, "tcpi_rttvar", (int)report->tcp_info.tcpi_rttvar, "tcpi_rto", (int)report->tcp_info.tcpi_rto, "tcpi_backoff", (int)report->tcp_info.tcpi_backoff, "tcpi_ca_state", (int)report->tcp_info.tcpi_ca_state, "tcpi_snd_mss", (int)report->tcp_info.tcpi_snd_mss, "status", report->status ); xmlrpc_array_append_item(env, ret, rv); xmlrpc_DECREF(rv); struct _report *next = report->next; free(report); report = next; } if (env->fault_occurred) logging_log(LOG_WARNING, "Method get_reports failed: %s", env->fault_string); else { DEBUG_MSG(LOG_WARNING, "Method get_reports successful"); } return ret; }
static void get_torrent_list(torrent_array **result) { size_t size; xmlrpc_value *xml_array, *params; params = xmlrpc_array_new(&env); xmlrpc_array_append_item(&env, params, xmlrpc_string_new(&env, "main")); xmlrpc_array_append_item(&env, params, xmlrpc_string_new(&env, "d.hash=")); xmlrpc_array_append_item(&env, params, xmlrpc_string_new(&env, "d.name=")); xmlrpc_array_append_item(&env, params, xmlrpc_string_new(&env, "d.is_active=")); xmlrpc_array_append_item(&env, params, xmlrpc_string_new(&env, "d.state=")); xmlrpc_array_append_item(&env, params, xmlrpc_string_new(&env, "d.bytes_done=")); xmlrpc_array_append_item(&env, params, xmlrpc_string_new(&env, "d.size_bytes=")); xmlrpc_array_append_item(&env, params, xmlrpc_string_new(&env, "d.up.rate=")); xmlrpc_array_append_item(&env, params, xmlrpc_string_new(&env, "d.down.rate=")); xmlrpc_array_append_item(&env, params, xmlrpc_string_new(&env, "d.down.total=")); xmlrpc_array_append_item(&env, params, xmlrpc_string_new(&env, "d.ratio=")); check_fault(); execute_proxy_method(&xml_array, "d.multicall", params); check_fault(&env); assert(xmlrpc_value_type(xml_array) == XMLRPC_TYPE_ARRAY); XMLRPC_ASSERT_ARRAY_OK(xml_array); size = xmlrpc_array_size(&env, xml_array); check_fault(&env); if (size <= 0) goto finish; *result = torrent_array_new(size); for (size_t i = 0; i < size; ++i) { size_t tarray_size; xmlrpc_value *tarray = NULL; xmlrpc_array_read_item(&env, xml_array, i, &tarray); check_fault(&env); assert(xmlrpc_value_type(tarray) == XMLRPC_TYPE_ARRAY); XMLRPC_ASSERT_ARRAY_OK(tarray); tarray_size = xmlrpc_array_size(&env, tarray); for (size_t j = 0; j < tarray_size; ++j) { xmlrpc_value *item = NULL; xmlrpc_array_read_item(&env, tarray, j, &item); check_fault(&env); switch (j) { case 0: get_string(item, &(*result)->torrents[i]->hash); break; case 1: get_string(item, &(*result)->torrents[i]->name); break; case 2: get_bool_from_int64(item, &(*result)->torrents[i]->active); break; case 3: get_bool_from_int64(item, &(*result)->torrents[i]->started); break; case 4: get_int64(item, &(*result)->torrents[i]->done_bytes); break; case 5: get_int64(item, &(*result)->torrents[i]->size_bytes); break; case 6: get_int64(item, &(*result)->torrents[i]->up_rate); break; case 7: get_int64(item, &(*result)->torrents[i]->down_rate); break; case 8: get_int64(item, &(*result)->torrents[i]->down_total); break; case 9: get_int64(item, &(*result)->torrents[i]->ratio); break; default: ; } xmlrpc_DECREF(item); } xmlrpc_DECREF(tarray); } finish: xmlrpc_DECREF(xml_array); }