mirror of https://gitee.com/openkylin/libvirt.git
XML-RPC errors checks
This commit is contained in:
parent
0d8e15fa75
commit
fd6d06b49d
|
@ -1,3 +1,8 @@
|
||||||
|
Wed May 10 15:50:32 CEST 2006 Karel Zak <kzak@redhat.com>
|
||||||
|
|
||||||
|
* src/virterror.c include/virterror.h: added VIR_FROM_RPC
|
||||||
|
* src/xmlrpc.c: added checks and _virRaiseError()
|
||||||
|
|
||||||
Wed May 10 13:17:00 CEST 2006 Karel Zak <kzak@redhat.com>
|
Wed May 10 13:17:00 CEST 2006 Karel Zak <kzak@redhat.com>
|
||||||
|
|
||||||
* src/xml.c src/xml.h: added virBufferNew() and virBufferStrcat()
|
* src/xml.c src/xml.h: added virBufferNew() and virBufferStrcat()
|
||||||
|
|
|
@ -44,6 +44,7 @@ typedef enum {
|
||||||
VIR_FROM_SEXPR, /* Error in the S-Epression code */
|
VIR_FROM_SEXPR, /* Error in the S-Epression code */
|
||||||
VIR_FROM_XML, /* Error in the XML code */
|
VIR_FROM_XML, /* Error in the XML code */
|
||||||
VIR_FROM_DOM, /* Error when operating on a domain */
|
VIR_FROM_DOM, /* Error when operating on a domain */
|
||||||
|
VIR_FROM_RPC /* Error in the XML-RPC code */
|
||||||
} virErrorDomain;
|
} virErrorDomain;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ typedef enum {
|
||||||
VIR_FROM_SEXPR, /* Error in the S-Epression code */
|
VIR_FROM_SEXPR, /* Error in the S-Epression code */
|
||||||
VIR_FROM_XML, /* Error in the XML code */
|
VIR_FROM_XML, /* Error in the XML code */
|
||||||
VIR_FROM_DOM, /* Error when operating on a domain */
|
VIR_FROM_DOM, /* Error when operating on a domain */
|
||||||
|
VIR_FROM_RPC /* Error in the XML-RPC code */
|
||||||
} virErrorDomain;
|
} virErrorDomain;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -262,6 +262,9 @@ virDefaultErrorFunc(virErrorPtr err)
|
||||||
case VIR_FROM_DOM:
|
case VIR_FROM_DOM:
|
||||||
dom = "Domain ";
|
dom = "Domain ";
|
||||||
break;
|
break;
|
||||||
|
case VIR_FROM_RPC:
|
||||||
|
dom = "XML-RPC ";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if ((err->dom != NULL) && (err->code != VIR_ERR_INVALID_DOMAIN)) {
|
if ((err->dom != NULL) && (err->code != VIR_ERR_INVALID_DOMAIN)) {
|
||||||
domain = err->dom->name;
|
domain = err->dom->name;
|
||||||
|
|
|
@ -23,14 +23,6 @@
|
||||||
#include "sexpr.h"
|
#include "sexpr.h"
|
||||||
#include "xml.h"
|
#include "xml.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* virXenError:
|
|
||||||
* @conn: the connection if available
|
|
||||||
* @error: the error number
|
|
||||||
* @info: extra information string
|
|
||||||
*
|
|
||||||
* Handle an error at the xend daemon interface
|
|
||||||
*/
|
|
||||||
static void
|
static void
|
||||||
virXMLError(virErrorNumber error, const char *info, int value)
|
virXMLError(virErrorNumber error, const char *info, int value)
|
||||||
{
|
{
|
||||||
|
|
173
src/xmlrpc.c
173
src/xmlrpc.c
|
@ -9,6 +9,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xmlrpc.h"
|
#include "xmlrpc.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
#include <libxml/nanohttp.h>
|
#include <libxml/nanohttp.h>
|
||||||
|
|
||||||
|
@ -20,8 +21,6 @@
|
||||||
2) xmlRpcValueToSexpr
|
2) xmlRpcValueToSexpr
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define TODO do { } while (0)
|
|
||||||
|
|
||||||
static xmlNodePtr xmlFirstElement(xmlNodePtr node);
|
static xmlNodePtr xmlFirstElement(xmlNodePtr node);
|
||||||
static xmlNodePtr xmlNextElement(xmlNodePtr node);
|
static xmlNodePtr xmlNextElement(xmlNodePtr node);
|
||||||
|
|
||||||
|
@ -32,19 +31,39 @@ struct _xmlRpcContext
|
||||||
char *faultMessage;
|
char *faultMessage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void xmlRpcError(virErrorNumber error, const char *info, int value)
|
||||||
|
{
|
||||||
|
const char *errmsg;
|
||||||
|
|
||||||
|
if (error == VIR_ERR_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
errmsg = __virErrorMsg(error, info);
|
||||||
|
__virRaiseError(NULL, NULL, VIR_FROM_RPC, error, VIR_ERR_ERROR,
|
||||||
|
errmsg, info, NULL, value, 0, errmsg, info, value);
|
||||||
|
}
|
||||||
|
|
||||||
static xmlRpcValuePtr xmlRpcValueNew(xmlRpcValueType type)
|
static xmlRpcValuePtr xmlRpcValueNew(xmlRpcValueType type)
|
||||||
{
|
{
|
||||||
xmlRpcValuePtr ret = malloc(sizeof(*ret));
|
xmlRpcValuePtr ret = malloc(sizeof(*ret));
|
||||||
if (ret)
|
|
||||||
ret->kind = type;
|
if (!ret)
|
||||||
|
xmlRpcError(VIR_ERR_NO_MEMORY, "allocate value", sizeof(*ret));
|
||||||
|
else
|
||||||
|
ret->kind = type;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *xmlGetText(xmlNodePtr node)
|
static char *xmlGetText(xmlNodePtr node)
|
||||||
{
|
{
|
||||||
for (node = node->children; node; node = node->next)
|
for (node = node->children; node; node = node->next)
|
||||||
if (node->type == XML_TEXT_NODE)
|
if (node->type == XML_TEXT_NODE) {
|
||||||
return strdup((const char *)node->content);
|
char *x = strdup((const char *)node->content);
|
||||||
|
if (!x)
|
||||||
|
xmlRpcError(VIR_ERR_NO_MEMORY, "copying node content",
|
||||||
|
strlen((const char *)node->content));
|
||||||
|
return x;
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,21 +86,23 @@ static xmlNodePtr xmlNextElement(xmlNodePtr node)
|
||||||
static xmlRpcValuePtr xmlRpcValueUnmarshalDateTime(xmlNodePtr node ATTRIBUTE_UNUSED)
|
static xmlRpcValuePtr xmlRpcValueUnmarshalDateTime(xmlNodePtr node ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
/* we don't need this */
|
/* we don't need this */
|
||||||
TODO;
|
TODO
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static xmlRpcValuePtr xmlRpcValueUnmarshalString(xmlNodePtr node)
|
static xmlRpcValuePtr xmlRpcValueUnmarshalString(xmlNodePtr node)
|
||||||
{
|
{
|
||||||
xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_STRING);
|
xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_STRING);
|
||||||
ret->value.string = xmlGetText(node);
|
|
||||||
|
if (ret)
|
||||||
|
ret->value.string = xmlGetText(node);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static xmlRpcValuePtr xmlRpcValueUnmarshalBase64(xmlNodePtr node ATTRIBUTE_UNUSED)
|
static xmlRpcValuePtr xmlRpcValueUnmarshalBase64(xmlNodePtr node ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
/* we don't need this */
|
/* we don't need this */
|
||||||
TODO;
|
TODO
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,11 +110,11 @@ static xmlRpcValuePtr xmlRpcValueUnmarshalInteger(xmlNodePtr node)
|
||||||
{
|
{
|
||||||
xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_INTEGER);
|
xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_INTEGER);
|
||||||
char *value = xmlGetText(node);
|
char *value = xmlGetText(node);
|
||||||
|
|
||||||
ret->value.integer = atoi(value);
|
if (ret && value)
|
||||||
|
ret->value.integer = atoi(value);
|
||||||
free(value);
|
if (value)
|
||||||
|
free(value);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,13 +123,14 @@ static xmlRpcValuePtr xmlRpcValueUnmarshalBoolean(xmlNodePtr node)
|
||||||
xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_BOOLEAN);
|
xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_BOOLEAN);
|
||||||
char *value = xmlGetText(node);
|
char *value = xmlGetText(node);
|
||||||
|
|
||||||
if (atoi(value))
|
if (!ret)
|
||||||
|
return NULL;
|
||||||
|
if (value && atoi(value))
|
||||||
ret->value.boolean = true;
|
ret->value.boolean = true;
|
||||||
else
|
else
|
||||||
ret->value.boolean = false;
|
ret->value.boolean = false;
|
||||||
|
if (value)
|
||||||
free(value);
|
free(value);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,10 +139,10 @@ static xmlRpcValuePtr xmlRpcValueUnmarshalDouble(xmlNodePtr node)
|
||||||
xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_DOUBLE);
|
xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_DOUBLE);
|
||||||
char *value = xmlGetText(node);
|
char *value = xmlGetText(node);
|
||||||
|
|
||||||
ret->value.real = atof(value);
|
if (ret && value)
|
||||||
|
ret->value.real = atof(value);
|
||||||
free(value);
|
if (value)
|
||||||
|
free(value);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,11 +152,19 @@ static xmlRpcValuePtr xmlRpcValueUnmarshalArray(xmlNodePtr node)
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
int n_elements = 0;
|
int n_elements = 0;
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
for (cur = xmlFirstElement(node); cur; cur = xmlNextElement(cur))
|
for (cur = xmlFirstElement(node); cur; cur = xmlNextElement(cur))
|
||||||
n_elements += 1;
|
n_elements += 1;
|
||||||
|
|
||||||
ret->value.array.elements = malloc(n_elements * sizeof(xmlRpcValue));
|
ret->value.array.elements = malloc(n_elements * sizeof(xmlRpcValue));
|
||||||
|
if (!ret->value.array.elements) {
|
||||||
|
xmlRpcError(VIR_ERR_NO_MEMORY, "allocate value array",
|
||||||
|
n_elements * sizeof(xmlRpcValue));
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
n_elements = 0;
|
n_elements = 0;
|
||||||
for (cur = xmlFirstElement(node); cur; cur = xmlNextElement(cur)) {
|
for (cur = xmlFirstElement(node); cur; cur = xmlNextElement(cur)) {
|
||||||
ret->value.array.elements[n_elements] = xmlRpcValueUnmarshal(cur);
|
ret->value.array.elements[n_elements] = xmlRpcValueUnmarshal(cur);
|
||||||
|
@ -151,6 +181,10 @@ static xmlRpcValueDictElementPtr xmlRpcValueUnmarshalDictElement(xmlNodePtr node
|
||||||
xmlRpcValueDictElementPtr ret = malloc(sizeof(*ret));
|
xmlRpcValueDictElementPtr ret = malloc(sizeof(*ret));
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
|
xmlRpcError(VIR_ERR_NO_MEMORY, "allocate dict", sizeof(*ret));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
memset(ret, 0, sizeof(*ret));
|
memset(ret, 0, sizeof(*ret));
|
||||||
|
|
||||||
for (cur = xmlFirstElement(node); cur; cur = xmlNextElement(cur)) {
|
for (cur = xmlFirstElement(node); cur; cur = xmlNextElement(cur)) {
|
||||||
|
@ -159,7 +193,13 @@ static xmlRpcValueDictElementPtr xmlRpcValueUnmarshalDictElement(xmlNodePtr node
|
||||||
} else if (xmlStrEqual(cur->name, BAD_CAST "value")) {
|
} else if (xmlStrEqual(cur->name, BAD_CAST "value")) {
|
||||||
ret->value = xmlRpcValueUnmarshal(cur);
|
ret->value = xmlRpcValueUnmarshal(cur);
|
||||||
} else {
|
} else {
|
||||||
/* What? */
|
xmlRpcError(VIR_ERR_XML_ERROR, "unexpected dict node", 0);
|
||||||
|
if (ret->name)
|
||||||
|
free(ret->name);
|
||||||
|
if (ret->value)
|
||||||
|
xmlRpcValueFree(ret->value);
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,13 +214,20 @@ static xmlRpcValuePtr xmlRpcValueUnmarshalDict(xmlNodePtr node)
|
||||||
xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_STRUCT);
|
xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_STRUCT);
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ret->value.dict.root = root;
|
||||||
|
|
||||||
for (cur = xmlFirstElement(node); cur; cur = xmlNextElement(cur)) {
|
for (cur = xmlFirstElement(node); cur; cur = xmlNextElement(cur)) {
|
||||||
*elem = xmlRpcValueUnmarshalDictElement(cur);
|
*elem = xmlRpcValueUnmarshalDictElement(cur);
|
||||||
|
if (*elem==NULL) {
|
||||||
|
xmlRpcValueFree(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
elem = &(*elem)->next;
|
elem = &(*elem)->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret->value.dict.root = root;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +265,7 @@ xmlRpcValuePtr xmlRpcValueUnmarshal(xmlNodePtr node)
|
||||||
} else if (xmlStrEqual(node->name, BAD_CAST "nil")) {
|
} else if (xmlStrEqual(node->name, BAD_CAST "nil")) {
|
||||||
ret = xmlRpcValueNew(XML_RPC_NIL);
|
ret = xmlRpcValueNew(XML_RPC_NIL);
|
||||||
} else {
|
} else {
|
||||||
/* bug */
|
xmlRpcError(VIR_ERR_XML_ERROR, "unexpected value node", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -299,11 +346,11 @@ void xmlRpcValueMarshal(xmlRpcValuePtr value, virBufferPtr buf, int indent)
|
||||||
break;
|
break;
|
||||||
case XML_RPC_DATE_TIME:
|
case XML_RPC_DATE_TIME:
|
||||||
/* FIXME */
|
/* FIXME */
|
||||||
TODO;
|
TODO
|
||||||
break;
|
break;
|
||||||
case XML_RPC_BASE64:
|
case XML_RPC_BASE64:
|
||||||
/* FIXME */
|
/* FIXME */
|
||||||
TODO;
|
TODO
|
||||||
break;
|
break;
|
||||||
case XML_RPC_STRING:
|
case XML_RPC_STRING:
|
||||||
virBufferStrcat(buf,
|
virBufferStrcat(buf,
|
||||||
|
@ -344,6 +391,9 @@ virBufferPtr xmlRpcMarshalRequest(const char *request,
|
||||||
|
|
||||||
xmlRpcValuePtr xmlRpcUnmarshalResponse(xmlNodePtr node, bool *is_fault)
|
xmlRpcValuePtr xmlRpcUnmarshalResponse(xmlNodePtr node, bool *is_fault)
|
||||||
{
|
{
|
||||||
|
if (!node)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (!xmlStrEqual(node->name, BAD_CAST "methodResponse"))
|
if (!xmlStrEqual(node->name, BAD_CAST "methodResponse"))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -361,7 +411,6 @@ xmlRpcValuePtr xmlRpcUnmarshalResponse(xmlNodePtr node, bool *is_fault)
|
||||||
return xmlRpcValueUnmarshal(xmlFirstElement(node));
|
return xmlRpcValueUnmarshal(xmlFirstElement(node));
|
||||||
} else
|
} else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *xmlRpcCallRaw(const char *url, const char *request)
|
static char *xmlRpcCallRaw(const char *url, const char *request)
|
||||||
|
@ -378,24 +427,29 @@ static char *xmlRpcCallRaw(const char *url, const char *request)
|
||||||
NULL,
|
NULL,
|
||||||
strlen(request));
|
strlen(request));
|
||||||
|
|
||||||
if (cxt == NULL)
|
if (cxt == NULL) {
|
||||||
|
xmlRpcError(VIR_ERR_POST_FAILED, "send request", 0);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (contentType && strcmp(contentType, "text/xml") != 0) {
|
if (contentType && strcmp(contentType, "text/xml") != 0) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
|
xmlRpcError(VIR_ERR_POST_FAILED, "unexpected mime type", 0);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = xmlNanoHTTPContentLength(cxt);
|
len = xmlNanoHTTPContentLength(cxt);
|
||||||
response = malloc(len + 1);
|
response = malloc(len + 1);
|
||||||
if (response == NULL)
|
if (response == NULL) {
|
||||||
|
xmlRpcError(VIR_ERR_NO_MEMORY, "allocate response", len);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
ret = xmlNanoHTTPRead(cxt, response, len);
|
ret = xmlNanoHTTPRead(cxt, response, len);
|
||||||
if (ret != len) {
|
if (ret != len) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
free(response);
|
free(response);
|
||||||
response = NULL;
|
response = NULL;
|
||||||
|
xmlRpcError(VIR_ERR_POST_FAILED, "read response", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
response[len] = 0;
|
response[len] = 0;
|
||||||
|
@ -426,8 +480,10 @@ static char **xmlRpcStringArray(xmlRpcValuePtr value)
|
||||||
if (value->value.array.elements[i]->kind == XML_RPC_STRING)
|
if (value->value.array.elements[i]->kind == XML_RPC_STRING)
|
||||||
size += strlen(value->value.array.elements[i]->value.string) + 1;
|
size += strlen(value->value.array.elements[i]->value.string) + 1;
|
||||||
|
|
||||||
ptr = malloc(size);
|
if (!(ptr = malloc(size))) {
|
||||||
|
xmlRpcError(VIR_ERR_NO_MEMORY, "allocate string array", size);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
ret = (char **)ptr;
|
ret = (char **)ptr;
|
||||||
ptr += sizeof(char *) * (value->value.array.n_elements + 1);
|
ptr += sizeof(char *) * (value->value.array.n_elements + 1);
|
||||||
|
|
||||||
|
@ -454,29 +510,35 @@ xmlRpcArgvNew(const char *fmt, va_list ap, int *argc)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
*argc = strlen(fmt);
|
*argc = strlen(fmt);
|
||||||
argv = malloc(sizeof(*argv) * *argc);
|
if (!(argv = malloc(sizeof(*argv) * *argc))) {
|
||||||
|
xmlRpcError(VIR_ERR_NO_MEMORY, "read response", sizeof(*argv) * *argc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
for (ptr = fmt; *ptr; ptr++) {
|
for (ptr = fmt; *ptr; ptr++) {
|
||||||
switch (*ptr) {
|
switch (*ptr) {
|
||||||
case 'i':
|
case 'i':
|
||||||
argv[i] = xmlRpcValueNew(XML_RPC_INTEGER);
|
if ((argv[i] = xmlRpcValueNew(XML_RPC_INTEGER)))
|
||||||
argv[i]->value.integer = va_arg(ap, int32_t);
|
argv[i]->value.integer = va_arg(ap, int32_t);
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
argv[i] = xmlRpcValueNew(XML_RPC_DOUBLE);
|
if ((argv[i] = xmlRpcValueNew(XML_RPC_DOUBLE)))
|
||||||
argv[i]->value.real = va_arg(ap, double);
|
argv[i]->value.real = va_arg(ap, double);
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
argv[i] = xmlRpcValueNew(XML_RPC_BOOLEAN);
|
if ((argv[i] = xmlRpcValueNew(XML_RPC_BOOLEAN)))
|
||||||
argv[i]->value.boolean = va_arg(ap, int);
|
argv[i]->value.boolean = va_arg(ap, int);
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
argv[i] = xmlRpcValueNew(XML_RPC_STRING);
|
if ((argv[i] = xmlRpcValueNew(XML_RPC_STRING)))
|
||||||
argv[i]->value.string = strdup(va_arg(ap, const char *));
|
argv[i]->value.string = strdup(va_arg(ap, const char *));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
xmlRpcArgvFree(i, argv);
|
argv[i] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (argv[i]==NULL) {
|
||||||
|
xmlRpcArgvFree(i, argv);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
@ -488,6 +550,8 @@ void
|
||||||
xmlRpcArgvFree(int argc, xmlRpcValuePtr *argv)
|
xmlRpcArgvFree(int argc, xmlRpcValuePtr *argv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
if (!argv)
|
||||||
|
return;
|
||||||
for (i = 0; i < argc; i++)
|
for (i = 0; i < argc; i++)
|
||||||
xmlRpcValueFree(argv[i]);
|
xmlRpcValueFree(argv[i]);
|
||||||
|
|
||||||
|
@ -513,7 +577,8 @@ int xmlRpcCall(xmlRpcContextPtr context, const char *method,
|
||||||
if (retfmt && *retfmt)
|
if (retfmt && *retfmt)
|
||||||
retval = va_arg(ap, void *);
|
retval = va_arg(ap, void *);
|
||||||
|
|
||||||
argv = xmlRpcArgvNew(fmt, ap, &argc);
|
if (!(argv = xmlRpcArgvNew(fmt, ap, &argc)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
|
@ -521,10 +586,16 @@ int xmlRpcCall(xmlRpcContextPtr context, const char *method,
|
||||||
|
|
||||||
xmlRpcArgvFree(argc, argv);
|
xmlRpcArgvFree(argc, argv);
|
||||||
|
|
||||||
|
if (!buf)
|
||||||
|
return -1;
|
||||||
|
|
||||||
ret = xmlRpcCallRaw(context->uri, buf->content);
|
ret = xmlRpcCallRaw(context->uri, buf->content);
|
||||||
|
|
||||||
virBufferFree(buf);
|
virBufferFree(buf);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
return -1;
|
||||||
|
|
||||||
xml = xmlReadDoc((const xmlChar *)ret, "response.xml", NULL,
|
xml = xmlReadDoc((const xmlChar *)ret, "response.xml", NULL,
|
||||||
XML_PARSE_NOENT | XML_PARSE_NONET |
|
XML_PARSE_NOENT | XML_PARSE_NONET |
|
||||||
XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
|
XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
|
||||||
|
@ -532,6 +603,7 @@ int xmlRpcCall(xmlRpcContextPtr context, const char *method,
|
||||||
|
|
||||||
if (xml == NULL) {
|
if (xml == NULL) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
|
xmlRpcError(VIR_ERR_XML_ERROR, "parse server response failed", 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,7 +644,9 @@ int xmlRpcCall(xmlRpcContextPtr context, const char *method,
|
||||||
|
|
||||||
xmlFreeDoc(xml);
|
xmlFreeDoc(xml);
|
||||||
|
|
||||||
if (fault) { /* FIXME we need generic dict routines */
|
if (fault) {
|
||||||
|
/* FIXME we need generic dict routines */
|
||||||
|
/* FIXME we need faultMessage propagate to libvirt error API */
|
||||||
context->faultCode = value->value.dict.root->value->value.integer;
|
context->faultCode = value->value.dict.root->value->value.integer;
|
||||||
context->faultMessage = strdup(value->value.dict.root->next->value->value.string);
|
context->faultMessage = strdup(value->value.dict.root->next->value->value.string);
|
||||||
xmlRpcValueFree(value);
|
xmlRpcValueFree(value);
|
||||||
|
@ -592,7 +666,8 @@ xmlRpcContextPtr xmlRpcContextNew(const char *uri)
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret->uri = strdup(uri);
|
ret->uri = strdup(uri);
|
||||||
ret->faultMessage = NULL;
|
ret->faultMessage = NULL;
|
||||||
}
|
} else
|
||||||
|
xmlRpcError(VIR_ERR_NO_MEMORY, "allocate new context", sizeof(*ret));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue