+++ /dev/null
-/*
- * xmlrpc.c: XML-RPC protocol handler for libvir library
- *
- * Copyright (C) 2006 IBM, Corp.
- *
- * See COPYING.LIB for the License of this software
- *
- * Anthony Liguori <aliguori@us.ibm.com>
- */
-
-#include <config.h>
-
-#include "xmlrpc.h"
-#include "virterror_internal.h"
-#include "memory.h"
-
-#include <libxml/nanohttp.h>
-
-#include <string.h>
-#include <errno.h>
-
-/* TODO
- 1) Lots of error checking
- 2) xmlRpcValueToSexpr
-*/
-
-static xmlNodePtr xmlFirstElement(xmlNodePtr node);
-static xmlNodePtr xmlNextElement(xmlNodePtr node);
-
-struct _xmlRpcContext
-{
- char *uri;
- int faultCode;
- 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, NULL, VIR_FROM_RPC, error, VIR_ERR_ERROR,
- errmsg, info, NULL, value, 0, errmsg, info, value);
-}
-
-static xmlRpcValuePtr xmlRpcValueNew(xmlRpcValueType type)
-{
- xmlRpcValuePtr ret = NULL;
- if (VIR_ALLOC(ret) < 0)
- xmlRpcError(VIR_ERR_NO_MEMORY, _("allocate value"), sizeof(*ret));
- else
- ret->kind = type;
- return ret;
-}
-
-static char *xmlGetText(xmlNodePtr node)
-{
- for (node = node->children; node; node = node->next)
- if (node->type == XML_TEXT_NODE) {
- 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;
-}
-
-static xmlNodePtr xmlFirstElement(xmlNodePtr node)
-{
- for (node = node->children; node; node = node->next)
- if (node->type == XML_ELEMENT_NODE)
- break;
- return node;
-}
-
-static xmlNodePtr xmlNextElement(xmlNodePtr node)
-{
- for (node = node->next; node; node = node->next)
- if (node->type == XML_ELEMENT_NODE)
- break;
- return node;
-}
-
-static xmlRpcValuePtr xmlRpcValueUnmarshalDateTime(xmlNodePtr node ATTRIBUTE_UNUSED)
-{
- /* we don't need this */
- TODO
- return NULL;
-}
-
-static xmlRpcValuePtr xmlRpcValueUnmarshalString(xmlNodePtr node)
-{
- xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_STRING);
-
- if (ret)
- ret->value.string = xmlGetText(node);
- return ret;
-}
-
-static xmlRpcValuePtr xmlRpcValueUnmarshalBase64(xmlNodePtr node ATTRIBUTE_UNUSED)
-{
- /* we don't need this */
- TODO
- return NULL;
-}
-
-static xmlRpcValuePtr xmlRpcValueUnmarshalInteger(xmlNodePtr node)
-{
- xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_INTEGER);
- char *value = xmlGetText(node);
-
- if (ret && value)
- ret->value.integer = atoi(value);
- VIR_FREE(value);
- return ret;
-}
-
-static xmlRpcValuePtr xmlRpcValueUnmarshalBoolean(xmlNodePtr node)
-{
- xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_BOOLEAN);
- char *value = xmlGetText(node);
-
- if (!ret)
- return NULL;
- if (value && atoi(value))
- ret->value.boolean = true;
- else
- ret->value.boolean = false;
- VIR_FREE(value);
- return ret;
-}
-
-static xmlRpcValuePtr xmlRpcValueUnmarshalDouble(xmlNodePtr node)
-{
- xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_DOUBLE);
- char *value = xmlGetText(node);
-
- if (ret && value)
- ret->value.real = atof(value);
- VIR_FREE(value);
- return ret;
-}
-
-static xmlRpcValuePtr xmlRpcValueUnmarshalArray(xmlNodePtr node)
-{
- xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_ARRAY);
- xmlNodePtr cur;
- int n_elements = 0;
- xmlRpcValuePtr *elems;
-
- if (!ret)
- return NULL;
-
- for (cur = xmlFirstElement(node); cur; cur = xmlNextElement(cur))
- n_elements += 1;
-
- if (VIR_ALLOC_N(elems, n_elements) < 0) {
- xmlRpcError(VIR_ERR_NO_MEMORY, _("allocate value array"),
- n_elements * sizeof(*elems));
- VIR_FREE(ret);
- return NULL;
- }
- n_elements = 0;
- for (cur = xmlFirstElement(node); cur; cur = xmlNextElement(cur)) {
- elems[n_elements] = xmlRpcValueUnmarshal(cur);
- n_elements += 1;
- }
-
- ret->value.array.elements = elems;
- ret->value.array.n_elements = n_elements;
-
- return ret;
-}
-
-static xmlRpcValueDictElementPtr xmlRpcValueUnmarshalDictElement(xmlNodePtr node)
-{
- xmlRpcValueDictElementPtr ret;
- xmlNodePtr cur;
-
- if (VIR_ALLOC(ret) < 0) {
- xmlRpcError(VIR_ERR_NO_MEMORY, _("allocate dict"), sizeof(*ret));
- return NULL;
- }
- memset(ret, 0, sizeof(*ret));
-
- for (cur = xmlFirstElement(node); cur; cur = xmlNextElement(cur)) {
- if (xmlStrEqual(cur->name, BAD_CAST "name")) {
- ret->name = xmlGetText(cur);
- } else if (xmlStrEqual(cur->name, BAD_CAST "value")) {
- ret->value = xmlRpcValueUnmarshal(cur);
- } else {
- xmlRpcError(VIR_ERR_XML_ERROR, _("unexpected dict node"), 0);
- VIR_FREE(ret->name);
- if (ret->value)
- xmlRpcValueFree(ret->value);
- VIR_FREE(ret);
- return NULL;
- }
- }
-
- ret->next = NULL;
-
- return ret;
-}
-
-static xmlRpcValuePtr xmlRpcValueUnmarshalDict(xmlNodePtr node)
-{
- xmlRpcValueDictElementPtr root = NULL, *elem = &root;
- xmlRpcValuePtr ret = xmlRpcValueNew(XML_RPC_STRUCT);
- xmlNodePtr cur;
-
- if (!ret)
- return NULL;
-
- ret->value.dict.root = root;
-
- for (cur = xmlFirstElement(node); cur; cur = xmlNextElement(cur)) {
- *elem = xmlRpcValueUnmarshalDictElement(cur);
- if (*elem==NULL) {
- xmlRpcValueFree(ret);
- return NULL;
- }
- elem = &(*elem)->next;
- }
-
- return ret;
-}
-
-xmlRpcValuePtr xmlRpcValueUnmarshal(xmlNodePtr node)
-{
- xmlNodePtr n;
- xmlRpcValuePtr ret = NULL;
-
- if (xmlStrEqual(node->name, BAD_CAST "value")) {
- n = xmlFirstElement(node);
- if (n == NULL) {
- ret = xmlRpcValueUnmarshalString(node);
- } else {
- ret = xmlRpcValueUnmarshal(n);
- }
- } else if (xmlStrEqual(node->name, BAD_CAST "dateTime.iso8601")) {
- ret = xmlRpcValueUnmarshalDateTime(node);
- } else if (xmlStrEqual(node->name, BAD_CAST "string")) {
- ret = xmlRpcValueUnmarshalString(node);
- } else if (xmlStrEqual(node->name, BAD_CAST "base64")) {
- ret = xmlRpcValueUnmarshalBase64(node);
- } else if (xmlStrEqual(node->name, BAD_CAST "i4") ||
- xmlStrEqual(node->name, BAD_CAST "int")) {
- ret = xmlRpcValueUnmarshalInteger(node);
- } else if (xmlStrEqual(node->name, BAD_CAST "boolean")) {
- ret = xmlRpcValueUnmarshalBoolean(node);
- } else if (xmlStrEqual(node->name, BAD_CAST "double")) {
- ret = xmlRpcValueUnmarshalDouble(node);
- } else if (xmlStrEqual(node->name, BAD_CAST "array")) {
- ret = xmlRpcValueUnmarshal(xmlFirstElement(node));
- } else if (xmlStrEqual(node->name, BAD_CAST "data")) {
- ret = xmlRpcValueUnmarshalArray(node);
- } else if (xmlStrEqual(node->name, BAD_CAST "struct")) {
- ret = xmlRpcValueUnmarshalDict(node);
- } else if (xmlStrEqual(node->name, BAD_CAST "nil")) {
- ret = xmlRpcValueNew(XML_RPC_NIL);
- } else {
- xmlRpcError(VIR_ERR_XML_ERROR, _("unexpected value node"), 0);
- }
-
- return ret;
-}
-
-void xmlRpcValueFree(xmlRpcValuePtr value)
-{
- int i;
- xmlRpcValueDictElementPtr cur, next;
-
- if (value == NULL)
- return;
-
- switch (value->kind) {
- case XML_RPC_ARRAY:
- for (i = 0; i < value->value.array.n_elements; i++)
- xmlRpcValueFree(value->value.array.elements[i]);
- VIR_FREE(value->value.array.elements);
- break;
- case XML_RPC_STRUCT:
- next = value->value.dict.root;
- while (next) {
- cur = next;
- next = next->next;
- VIR_FREE(cur->name);
- xmlRpcValueFree(cur->value);
- VIR_FREE(cur);
- }
- break;
- case XML_RPC_STRING:
- VIR_FREE(value->value.string);
- break;
- default:
- break;
- }
-
- VIR_FREE(value);
-}
-
-void xmlRpcValueMarshal(xmlRpcValuePtr value, virBufferPtr buf, int indent)
-{
- int i;
- xmlRpcValueDictElement *elem;
-
- virBufferVSprintf(buf, "%*s<value>", indent, "");
- switch (value->kind) {
- case XML_RPC_ARRAY:
- virBufferStrcat(buf, "<array><data>\n", NULL);
- for (i = 0; i < value->value.array.n_elements; i++)
- xmlRpcValueMarshal(value->value.array.elements[i], buf, indent+2);
- virBufferVSprintf(buf, "%*s</data></array>", indent, "");
- break;
- case XML_RPC_STRUCT:
- virBufferStrcat(buf, "<struct>\n", NULL);
- indent += 2;
- for (elem = value->value.dict.root; elem; elem = elem->next) {
- virBufferVSprintf(buf, "%*s<member>\n", indent, "");
- virBufferVSprintf(buf, "%*s<name>%s</name>\n",
- indent + 2, "", elem->name);
- xmlRpcValueMarshal(elem->value, buf, indent + 2);
- virBufferVSprintf(buf, "%*s</member>\n", indent, "");
- }
- indent -= 2;
- virBufferVSprintf(buf, "%*s</struct>", indent, "");
- break;
- case XML_RPC_INTEGER:
- virBufferVSprintf(buf, "<int>%d</int>", value->value.integer);
- break;
- case XML_RPC_DOUBLE:
- virBufferVSprintf(buf, "<double>%f</double>", value->value.real);
- break;
- case XML_RPC_BOOLEAN:
- if (value->value.boolean)
- i = 1;
- else
- i = 0;
- virBufferVSprintf(buf, "<boolean>%d</boolean>", i);
- break;
- case XML_RPC_DATE_TIME:
- /* FIXME */
- TODO
- break;
- case XML_RPC_BASE64:
- /* FIXME */
- TODO
- break;
- case XML_RPC_STRING:
- virBufferStrcat(buf,
- "<string>", value->value.string, "</string>", NULL);
- break;
- case XML_RPC_NIL:
- virBufferStrcat(buf, "<nil> </nil>", NULL);
- break;
- }
- virBufferStrcat(buf, "</value>\n", NULL);
-}
-
-void xmlRpcMarshalRequest(const char *request,
- virBufferPtr buf,
- int argc, xmlRpcValuePtr *argv)
-{
- int i;
-
- virBufferStrcat(buf,
- "<?xml version=\"1.0\"?>\n"
- "<methodCall>\n"
- " <methodName>", request, "</methodName>\n"
- " <params>\n", NULL);
- for (i = 0; i < argc; i++) {
- virBufferStrcat(buf,
- " <param>\n", NULL);
- xmlRpcValueMarshal(argv[i], buf, 6);
- virBufferStrcat(buf,
- " </param>\n", NULL);
- }
- virBufferStrcat(buf,
- " </params>\n"
- "</methodCall>\n", NULL);
-}
-
-xmlRpcValuePtr xmlRpcUnmarshalResponse(xmlNodePtr node, bool *is_fault)
-{
- if (!node)
- return NULL;
-
- if (!xmlStrEqual(node->name, BAD_CAST "methodResponse"))
- return NULL;
-
- node = xmlFirstElement(node);
- if (xmlStrEqual(node->name, BAD_CAST "params")) {
- node = xmlFirstElement(node);
-
- if (!xmlStrEqual(node->name, BAD_CAST "param"))
- return NULL;
-
- *is_fault = false;
- return xmlRpcValueUnmarshal(xmlFirstElement(node));
- } else if (xmlStrEqual(node->name, BAD_CAST "fault")) {
- *is_fault = true;
- return xmlRpcValueUnmarshal(xmlFirstElement(node));
- } else
- return NULL;
-}
-
-static char *xmlRpcCallRaw(const char *url, const char *request)
-{
- void *cxt;
- char *contentType = (char *) "text/xml";
- int len, ret, serrno;
- char *response = NULL;
-
- cxt = xmlNanoHTTPMethod(url,
- "POST",
- request,
- &contentType,
- NULL,
- strlen(request));
-
- if (cxt == NULL) {
- xmlRpcError(VIR_ERR_POST_FAILED, _("send request"), 0);
- goto error;
- }
-
- if (contentType && STRNEQ(contentType, "text/xml")) {
- errno = EINVAL;
- xmlRpcError(VIR_ERR_POST_FAILED, _("unexpected mime type"), 0);
- goto error;
- }
-
- len = xmlNanoHTTPContentLength(cxt);
- if (VIR_ALLOC_N(response, len + 1) < 0) {
- xmlRpcError(VIR_ERR_NO_MEMORY, _("allocate response"), len);
- goto error;
- }
- ret = xmlNanoHTTPRead(cxt, response, len);
- if (ret != len) {
- errno = EINVAL;
- VIR_FREE(response);
- xmlRpcError(VIR_ERR_POST_FAILED, _("read response"), 0);
- }
-
- response[len] = 0;
-
- error:
- serrno = errno;
- if (cxt) {
- xmlNanoHTTPClose(cxt);
- VIR_FREE(contentType);
- }
- errno = serrno;
-
- return response;
-}
-
-static char **xmlRpcStringArray(xmlRpcValuePtr value)
-{
- char **ret, *ptr;
- int i;
- size_t size = 0;
-
- if (value->kind != XML_RPC_ARRAY)
- return NULL;
-
- size = sizeof(char *) * (value->value.array.n_elements + 1);
-
- for (i = 0; i < value->value.array.n_elements; i++)
- if (value->value.array.elements[i]->kind == XML_RPC_STRING)
- size += strlen(value->value.array.elements[i]->value.string) + 1;
-
- if (VIR_ALLOC_N(ptr, size) < 0) {
- xmlRpcError(VIR_ERR_NO_MEMORY, _("allocate string array"), size);
- return NULL;
- }
- ret = (char **)ptr;
- ptr += sizeof(char *) * (value->value.array.n_elements + 1);
-
- for (i = 0; i < value->value.array.n_elements; i++) {
- if (value->value.array.elements[i]->kind == XML_RPC_STRING) {
- char *s = value->value.array.elements[i]->value.string;
- strcpy(ptr, s);
- ret[i] = ptr;
- ptr += strlen(s) + 1;
- } else
- ret[i] = (char *) "";
- }
-
- ret[i] = NULL;
-
- return ret;
-}
-
-xmlRpcValuePtr *
-xmlRpcArgvNew(const char *fmt, va_list ap, int *argc)
-{
- xmlRpcValuePtr *argv;
- const char *ptr;
- int i;
-
- *argc = strlen(fmt);
- if (VIR_ALLOC_N(argv, *argc) < 0) {
- xmlRpcError(VIR_ERR_NO_MEMORY, _("read response"), sizeof(*argv) * *argc);
- return NULL;
- }
- i = 0;
- for (ptr = fmt; *ptr; ptr++) {
- switch (*ptr) {
- case 'i':
- if ((argv[i] = xmlRpcValueNew(XML_RPC_INTEGER)))
- argv[i]->value.integer = va_arg(ap, int32_t);
- break;
- case 'f':
- if ((argv[i] = xmlRpcValueNew(XML_RPC_DOUBLE)))
- argv[i]->value.real = va_arg(ap, double);
- break;
- case 'b':
- if ((argv[i] = xmlRpcValueNew(XML_RPC_BOOLEAN)))
- argv[i]->value.boolean = va_arg(ap, int);
- break;
- case 's':
- if ((argv[i] = xmlRpcValueNew(XML_RPC_STRING)))
- argv[i]->value.string = strdup(va_arg(ap, const char *));
- break;
- default:
- argv[i] = NULL;
- break;
- }
- if (argv[i]==NULL) {
- xmlRpcArgvFree(i, argv);
- return NULL;
- }
- i++;
- }
- return argv;
-}
-
-void
-xmlRpcArgvFree(int argc, xmlRpcValuePtr *argv)
-{
- int i;
- if (!argv)
- return;
- for (i = 0; i < argc; i++)
- xmlRpcValueFree(argv[i]);
-
- VIR_FREE(argv);
-}
-
-int xmlRpcCall(xmlRpcContextPtr context, const char *method,
- const char *retfmt, const char *fmt, ...)
-{
- va_list ap;
- int argc;
- xmlRpcValuePtr *argv;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- char *ret;
- xmlDocPtr xml;
- xmlNodePtr node;
- bool fault;
- xmlRpcValuePtr value;
- void *retval = NULL;
- char *content;
-
- va_start(ap, fmt);
-
- if (retfmt && *retfmt)
- retval = va_arg(ap, void *);
-
- if (!(argv = xmlRpcArgvNew(fmt, ap, &argc)))
- return -1;
-
- va_end(ap);
-
- xmlRpcMarshalRequest(method, &buf, argc, argv);
-
- xmlRpcArgvFree(argc, argv);
-
- if (virBufferError(&buf))
- return -1;
-
- content = virBufferContentAndReset(&buf);
- ret = xmlRpcCallRaw(context->uri, content);
- VIR_FREE(content);
-
- if (!ret)
- return -1;
-
- xml = xmlReadDoc((const xmlChar *)ret, "response.xml", NULL,
- XML_PARSE_NOENT | XML_PARSE_NONET |
- XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
- VIR_FREE(ret);
-
- if (xml == NULL) {
- errno = EINVAL;
- xmlRpcError(VIR_ERR_XML_ERROR, _("parse server response failed"), 0);
- return -1;
- }
-
- node = xmlDocGetRootElement(xml);
-
- value = xmlRpcUnmarshalResponse(node, &fault);
-
- if (!fault) {
- switch (*retfmt) {
- case 'i':
- if (value->kind == XML_RPC_INTEGER)
- *(int32_t *)retval = value->value.integer;
- break;
- case 'b':
- if (value->kind == XML_RPC_BOOLEAN)
- *(bool *)retval = value->value.boolean;
- break;
- case 'f':
- if (value->kind == XML_RPC_DOUBLE)
- *(double *)retval = value->value.real;
- break;
- case 's':
- if (value->kind == XML_RPC_STRING)
- *(char **)retval = strdup(value->value.string);
- break;
- case 'S':
- *(char ***)retval = xmlRpcStringArray(value);
- break;
- case 'V':
- *(xmlRpcValuePtr *)retval = value;
- value = NULL;
- break;
- default:
- printf("not supported yet\n");
- break;
- }
- }
-
- xmlFreeDoc(xml);
-
- 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->faultMessage = strdup(value->value.dict.root->next->value->value.string);
- xmlRpcValueFree(value);
- errno = EFAULT;
- return -1;
- }
-
- xmlRpcValueFree(value);
-
- return 0;
-}
-
-xmlRpcContextPtr xmlRpcContextNew(const char *uri)
-{
- xmlRpcContextPtr ret;
-
- if (VIR_ALLOC(ret) < 0) {
- xmlRpcError(VIR_ERR_NO_MEMORY, _("allocate new context"), sizeof(*ret));
- } else {
- ret->uri = strdup(uri);
- ret->faultMessage = NULL;
- }
-
- return ret;
-}
-
-void xmlRpcContextFree(xmlRpcContextPtr context)
-{
- if (context) {
- VIR_FREE(context->uri);
- VIR_FREE(context->faultMessage);
- VIR_FREE(context);
- }
-}
-
-int xmlRpcContextFaultCode(xmlRpcContextPtr context)
-{
- return context->faultCode;
-}
-
-const char *xmlRpcContextFaultMessage(xmlRpcContextPtr context)
-{
- return context->faultMessage;
-}
+++ /dev/null
-/*
- * xmlrpctest.c: simple client for XML-RPC tests
- *
- * Copyright (C) 2005, 2008 Red Hat, Inc.
- *
- * See COPYING.LIB for the License of this software
- *
- * Karel Zak <kzak@redhat.com>
- *
- * $Id$
- */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <limits.h>
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxml/xpath.h>
-
-#include "internal.h"
-#include "buf.h"
-#include "xmlrpc.h"
-
-#include "testutils.h"
-
-
-#define NLOOPS 100 /* default number of loops per test */
-
-static char *progname;
-
-
-static int
-testMethodPlusINT(const void *data)
-{
- int retval = 0;
- xmlRpcContextPtr cxt = (xmlRpcContextPtr) data;
-
- if (xmlRpcCall(cxt, "plus", "i", "ii",
- (const char *) &retval, 10, 10) < 0)
- return -1;
-
- return retval==(10+10) ? 0 : -1;
-}
-
-static int
-testMethodPlusDOUBLE(const void *data)
-{
- double retval = 0;
- xmlRpcContextPtr cxt = (xmlRpcContextPtr) data;
-
- if (xmlRpcCall(cxt, "plus", "f", "ff",
- (const char *) &retval, 10.1234, 10.1234) < 0)
- return -1;
-
- return retval==(10.1234+10.1234) ? 0 : -1;
-}
-
-static void
-marshalRequest(virBufferPtr buf, const char *fmt, ...)
-{
- int argc;
- xmlRpcValuePtr *argv;
- va_list ap;
-
- va_start(ap, fmt);
- argv = xmlRpcArgvNew(fmt, ap, &argc);
- va_end(ap);
-
- xmlRpcMarshalRequest("test", buf, argc, argv);
-
- xmlRpcArgvFree(argc, argv);
-}
-
-static int
-checkRequestValue(const char *xmlstr, const char *xpath, int type, void *expected)
-{
- xmlDocPtr xml = NULL;
- xmlXPathContextPtr ctxt = NULL;
- xmlXPathObjectPtr obj = NULL;
- int ret = -1;
-
- xml = xmlReadDoc((const xmlChar *) xmlstr, "xmlrpctest.xml", NULL,
- XML_PARSE_NOENT | XML_PARSE_NONET |
- XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
- if (!xml)
- goto error;
-
- if (!(ctxt = xmlXPathNewContext(xml)))
- goto error;
-
- if (!(obj = xmlXPathEval(BAD_CAST xpath, ctxt)))
- goto error;
-
- switch(type) {
- case XML_RPC_INTEGER:
- if ((obj->type != XPATH_NUMBER) ||
- ((int) obj->floatval != *((int *)expected)))
- goto error;
- break;
- case XML_RPC_DOUBLE:
- if ((obj->type != XPATH_NUMBER) ||
- ((double) obj->floatval != *((double *)expected)))
- goto error;
- break;
- case XML_RPC_STRING:
- if ((obj->type != XPATH_STRING) ||
- (STRNEQ((const char *)obj->stringval, (const char *)expected)))
- goto error;
- break;
- default:
- goto error;
- }
- ret = 0;
-
-error:
- xmlXPathFreeObject(obj);
- xmlXPathFreeContext(ctxt);
- if (xml)
- xmlFreeDoc(xml);
- return ret;
-}
-
-static int
-testMarshalRequestINT(const void *data)
-{
- int num = INT_MAX;
- int ret = 0;
- int check = data ? *((int *)data) : 0;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- marshalRequest(&buf, "i", num);
- char *content;
-
- if (virBufferError(&buf))
- return -1;
-
- content = virBufferContentAndReset(&buf);
-
- if (check)
- ret = checkRequestValue(content,
- "number(/methodCall/params/param[1]/value/int)",
- XML_RPC_INTEGER, (void *) &num);
-
- free(content);
- return ret;
-}
-
-static int
-testMarshalRequestSTRING(const void *data ATTRIBUTE_UNUSED)
-{
- const char *str = "This library will be really sexy.";
- int ret = 0;
- int check = data ? *((int *)data) : 0;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- char *content;
-
- marshalRequest(&buf, "s", str);
-
- if (virBufferError(&buf))
- return -1;
-
- content = virBufferContentAndReset(&buf);
- if (check)
- ret = checkRequestValue(content,
- "string(/methodCall/params/param[1]/value/string)",
- XML_RPC_STRING, (void *) str);
-
- free(content);
- return ret;
-}
-
-static int
-testMarshalRequestDOUBLE(const void *data)
-{
- double num = 123456789.123;
- int ret = 0;
- int check = data ? *((int *)data) : 0;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- char *content;
-
- marshalRequest(&buf, "f", num);
-
- if (virBufferError(&buf))
- return -1;
-
- content = virBufferContentAndReset(&buf);
- if (check)
- ret = checkRequestValue(content,
- "number(/methodCall/params/param[1]/value/double)",
- XML_RPC_DOUBLE, (void *) &num);
-
- free(content);
- return ret;
-}
-
-
-int
-main(int argc, char **argv)
-{
- xmlRpcContextPtr cxt = NULL;
- int check = 1;
- int ret = 0;
- const char *url = "http://localhost:8000";
-
- progname = argv[0];
-
- if (argc > 2)
- {
- fprintf(stderr, "Usage: %s [url]\n", progname);
- exit(EXIT_FAILURE);
- }
- if (argc == 2)
- url = argv[1];
-
- /*
- * client-server tests
- */
- if (!(cxt = xmlRpcContextNew(url)))
- {
- fprintf(stderr, "%s: failed create new RPC context\n", progname);
- exit(EXIT_FAILURE);
- }
-
- if (virtTestRun("XML-RPC methodCall INT+INT",
- NLOOPS, testMethodPlusINT, (const void *) cxt) != 0)
- ret = -1;
-
- if (virtTestRun("XML-RPC methodCall DOUBLE+DOUBLE",
- NLOOPS, testMethodPlusDOUBLE, (const void *) cxt) != 0)
- ret = -1;
-
- xmlRpcContextFree(cxt);
-
- /*
- * regression / performance tests
- */
- if (virtTestRun("XML-RPC request marshalling: INT (check)",
- 1, testMarshalRequestINT, (const void *) &check) != 0)
- ret = -1;
- if (virtTestRun("XML-RPC request marshalling: INT",
- NLOOPS, testMarshalRequestINT, NULL) != 0)
- ret = -1;
-
- if (virtTestRun("XML-RPC request marshalling: DOUBLE (check)",
- 1, testMarshalRequestDOUBLE, (const void *) &check) != 0)
- ret = -1;
- if (virtTestRun("XML-RPC request marshalling: DOUBLE",
- NLOOPS, testMarshalRequestDOUBLE, NULL) != 0)
- ret = -1;
-
- if (virtTestRun("XML-RPC request marshalling: STRING (check)",
- 1, testMarshalRequestSTRING, (void *) &check) != 0)
- ret = -1;
- if (virtTestRun("XML-RPC request marshalling: STRING",
- NLOOPS, testMarshalRequestSTRING, NULL) != 0)
- ret = -1;
-
- exit(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
-}
-
-
-/*
- * vim: set tabstop=4:
- * vim: set shiftwidth=4:
- * vim: set expandtab:
- */