2005-12-13 16:22:05 +00:00
|
|
|
/*
|
|
|
|
* xml.c: XML based interfaces for the libvir library
|
|
|
|
*
|
2011-01-13 22:09:18 +00:00
|
|
|
* Copyright (C) 2005, 2007-2011 Red Hat, Inc.
|
2005-12-13 16:22:05 +00:00
|
|
|
*
|
|
|
|
* See COPYING.LIB for the License of this software
|
|
|
|
*
|
|
|
|
* Daniel Veillard <veillard@redhat.com>
|
|
|
|
*/
|
|
|
|
|
2008-01-29 18:15:54 +00:00
|
|
|
#include <config.h>
|
2007-11-26 11:40:28 +00:00
|
|
|
|
2005-12-13 16:22:05 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdarg.h>
|
2007-11-26 11:40:28 +00:00
|
|
|
#include <limits.h>
|
2007-10-24 14:22:25 +00:00
|
|
|
#include <math.h> /* for isnan() */
|
2008-11-04 22:30:33 +00:00
|
|
|
|
|
|
|
#include "virterror_internal.h"
|
2006-02-16 22:50:52 +00:00
|
|
|
#include "xml.h"
|
2007-06-26 22:33:22 +00:00
|
|
|
#include "buf.h"
|
2008-02-27 04:35:08 +00:00
|
|
|
#include "util.h"
|
2008-05-29 19:20:22 +00:00
|
|
|
#include "memory.h"
|
2008-07-25 13:17:27 +00:00
|
|
|
|
2009-01-29 12:10:32 +00:00
|
|
|
#define VIR_FROM_THIS VIR_FROM_XML
|
|
|
|
|
2010-02-24 20:44:47 +00:00
|
|
|
#define virGenericReportError(from, code, ...) \
|
2011-04-16 08:30:22 +00:00
|
|
|
virReportErrorHelper(from, code, __FILE__, \
|
2010-03-01 23:38:28 +00:00
|
|
|
__FUNCTION__, __LINE__, __VA_ARGS__)
|
2006-02-27 22:32:54 +00:00
|
|
|
|
2010-02-24 20:44:47 +00:00
|
|
|
#define virXMLError(code, ...) \
|
|
|
|
virGenericReportError(VIR_FROM_XML, code, __VA_ARGS__)
|
|
|
|
|
|
|
|
|
|
|
|
/* Internal data to be passed to SAX parser and used by error handler. */
|
|
|
|
struct virParserData {
|
|
|
|
int domcode;
|
|
|
|
};
|
|
|
|
|
2007-10-22 20:28:55 +00:00
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* *
|
|
|
|
* Wrappers around libxml2 XPath specific functions *
|
|
|
|
* *
|
|
|
|
************************************************************************/
|
|
|
|
|
2007-04-06 12:28:24 +00:00
|
|
|
/**
|
|
|
|
* virXPathString:
|
|
|
|
* @xpath: the XPath string to evaluate
|
|
|
|
* @ctxt: an XPath context
|
|
|
|
*
|
|
|
|
* Convenience function to evaluate an XPath string
|
|
|
|
*
|
|
|
|
* Returns a new string which must be deallocated by the caller or NULL
|
|
|
|
* if the evaluation failed.
|
|
|
|
*/
|
|
|
|
char *
|
2010-02-04 21:52:34 +00:00
|
|
|
virXPathString(const char *xpath,
|
2008-07-25 14:27:25 +00:00
|
|
|
xmlXPathContextPtr ctxt)
|
2007-10-24 14:22:25 +00:00
|
|
|
{
|
2007-04-06 12:28:24 +00:00
|
|
|
xmlXPathObjectPtr obj;
|
2008-07-09 08:35:09 +00:00
|
|
|
xmlNodePtr relnode;
|
2007-04-06 12:28:24 +00:00
|
|
|
char *ret;
|
|
|
|
|
|
|
|
if ((ctxt == NULL) || (xpath == NULL)) {
|
2010-02-04 21:52:34 +00:00
|
|
|
virXMLError(VIR_ERR_INTERNAL_ERROR,
|
avoid many format string warnings
Building with --disable-nls exposed many new warnings like these:
virsh.c:4952: warning: format not a string literal and no format ...
util.c:163: warning: format not a string literal and no format arguments
All but one of the following changes add a "%s" argument before
the offending _(...) argument.
This was the only manual change:
* src/lxc_driver.c (lxcVersion): Use %s and strerror(errno)
rather than %m, to avoid a warning from gcc -Wformat-security.
Add "%s" before each warned about format-string-with-no-%-directive:
* src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML)
(virDomainDefParseString, virDomainDefParseFile):
* src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain)
(__virGetNetwork, virReleaseNetwork, __virGetStoragePool)
(virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol):
* src/lxc_container.c (lxcContainerChild):
* src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine)
(lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML)
(lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart)
(lxcVersion, lxcGetSchedulerParameters):
* src/network_conf.c (virNetworkDefParseString)
(virNetworkDefParseFile):
* src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains):
* src/openvz_driver.c (openvzDomainDefineCmd)
(openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown)
(openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML)
(openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine)
(openvzDomainSetAutostart, openvzDomainGetAutostart)
(openvzDomainSetVcpus):
* src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek):
* src/remote_internal.c (remoteDomainBlockPeek)
(remoteDomainMemoryPeek, remoteAuthPolkit):
* src/sexpr.c (sexpr_new, _string2sexpr):
* src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol)
(virStorageBackendDiskCreateVol):
* src/storage_backend_fs.c
(virStorageBackendFileSystemNetFindPoolSources):
* src/storage_backend_logical.c (virStorageBackendLogicalFindLVs)
(virStorageBackendLogicalFindPoolSources):
* src/test.c (testOpenDefault, testOpenFromFile, testOpen)
(testGetDomainInfo, testDomainRestore)
(testNodeGetCellsFreeMemory):
* src/util.c (virExec):
* src/virsh.c (cmdAttachDevice, cmdDetachDevice)
(cmdAttachInterface, cmdDetachInterface, cmdAttachDisk)
(cmdDetachDisk, cmdEdit):
* src/xend_internal.c (do_connect, wr_sync, xend_op_ext)
(urlencode, xenDaemonDomainCreateXML)
(xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID)
(xenDaemonParseSxprOS, xend_parse_sexp_desc_char)
(xenDaemonParseSxprChar, xenDaemonParseSxprDisks)
(xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain)
(xenDaemonDomainFetch, xenDaemonDomainGetAutostart)
(xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform)
(xenDaemonDomainDefineXML, xenDaemonGetSchedulerType)
(xenDaemonGetSchedulerParameters)
(xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek)
(xenDaemonFormatSxprChr, virDomainXMLDevID):
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu)
(xenXMDomainCreate, xenXMDomainDefineXML)
(xenXMDomainAttachDevice, xenXMDomainDetachDevice):
* src/xml.c (virXPathString, virXPathNumber, virXPathLong)
(virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet):
* src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
|
|
|
"%s", _("Invalid parameter to virXPathString()"));
|
2007-10-24 14:22:25 +00:00
|
|
|
return (NULL);
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
2008-07-09 08:35:09 +00:00
|
|
|
relnode = ctxt->node;
|
2007-04-06 12:28:24 +00:00
|
|
|
obj = xmlXPathEval(BAD_CAST xpath, ctxt);
|
2009-09-29 09:07:01 +00:00
|
|
|
ctxt->node = relnode;
|
2007-04-06 12:28:24 +00:00
|
|
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
2007-07-31 14:27:12 +00:00
|
|
|
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
2008-02-07 16:49:29 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2007-10-24 14:22:25 +00:00
|
|
|
return (NULL);
|
2007-07-31 14:27:12 +00:00
|
|
|
}
|
2007-04-06 12:28:24 +00:00
|
|
|
ret = strdup((char *) obj->stringval);
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
if (ret == NULL) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
2007-10-24 14:22:25 +00:00
|
|
|
return (ret);
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
|
|
|
|
2009-03-03 09:44:41 +00:00
|
|
|
/**
|
|
|
|
* virXPathStringLimit:
|
|
|
|
* @xpath: the XPath string to evaluate
|
|
|
|
* @maxlen: maximum length permittred string
|
|
|
|
* @ctxt: an XPath context
|
|
|
|
*
|
|
|
|
* Wrapper for virXPathString, which validates the length of the returned
|
|
|
|
* string.
|
|
|
|
*
|
|
|
|
* Returns a new string which must be deallocated by the caller or NULL if
|
|
|
|
* the evaluation failed.
|
|
|
|
*/
|
|
|
|
char *
|
2010-02-04 21:52:34 +00:00
|
|
|
virXPathStringLimit(const char *xpath,
|
2009-03-03 09:44:41 +00:00
|
|
|
size_t maxlen,
|
|
|
|
xmlXPathContextPtr ctxt)
|
|
|
|
{
|
2010-02-04 21:52:34 +00:00
|
|
|
char *tmp = virXPathString(xpath, ctxt);
|
2009-03-03 09:44:41 +00:00
|
|
|
|
|
|
|
if (tmp != NULL && strlen(tmp) >= maxlen) {
|
2010-02-04 21:52:34 +00:00
|
|
|
virXMLError(VIR_ERR_INTERNAL_ERROR,
|
2011-03-04 16:52:12 +00:00
|
|
|
_("\'%s\' value longer than %zd bytes"),
|
2009-03-03 09:44:41 +00:00
|
|
|
xpath, maxlen);
|
2011-03-04 16:52:12 +00:00
|
|
|
VIR_FREE(tmp);
|
|
|
|
return NULL;
|
2009-03-03 09:44:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
2007-04-06 12:28:24 +00:00
|
|
|
/**
|
|
|
|
* virXPathNumber:
|
|
|
|
* @xpath: the XPath string to evaluate
|
|
|
|
* @ctxt: an XPath context
|
|
|
|
* @value: the returned double value
|
|
|
|
*
|
|
|
|
* Convenience function to evaluate an XPath number
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success in which case @value is set,
|
|
|
|
* or -1 if the evaluation failed.
|
|
|
|
*/
|
|
|
|
int
|
2010-02-04 21:52:34 +00:00
|
|
|
virXPathNumber(const char *xpath,
|
2008-07-25 14:27:25 +00:00
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
double *value)
|
2007-10-24 14:22:25 +00:00
|
|
|
{
|
2007-04-06 12:28:24 +00:00
|
|
|
xmlXPathObjectPtr obj;
|
2008-07-09 08:35:09 +00:00
|
|
|
xmlNodePtr relnode;
|
2007-04-06 12:28:24 +00:00
|
|
|
|
|
|
|
if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
|
2010-02-04 21:52:34 +00:00
|
|
|
virXMLError(VIR_ERR_INTERNAL_ERROR,
|
avoid many format string warnings
Building with --disable-nls exposed many new warnings like these:
virsh.c:4952: warning: format not a string literal and no format ...
util.c:163: warning: format not a string literal and no format arguments
All but one of the following changes add a "%s" argument before
the offending _(...) argument.
This was the only manual change:
* src/lxc_driver.c (lxcVersion): Use %s and strerror(errno)
rather than %m, to avoid a warning from gcc -Wformat-security.
Add "%s" before each warned about format-string-with-no-%-directive:
* src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML)
(virDomainDefParseString, virDomainDefParseFile):
* src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain)
(__virGetNetwork, virReleaseNetwork, __virGetStoragePool)
(virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol):
* src/lxc_container.c (lxcContainerChild):
* src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine)
(lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML)
(lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart)
(lxcVersion, lxcGetSchedulerParameters):
* src/network_conf.c (virNetworkDefParseString)
(virNetworkDefParseFile):
* src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains):
* src/openvz_driver.c (openvzDomainDefineCmd)
(openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown)
(openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML)
(openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine)
(openvzDomainSetAutostart, openvzDomainGetAutostart)
(openvzDomainSetVcpus):
* src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek):
* src/remote_internal.c (remoteDomainBlockPeek)
(remoteDomainMemoryPeek, remoteAuthPolkit):
* src/sexpr.c (sexpr_new, _string2sexpr):
* src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol)
(virStorageBackendDiskCreateVol):
* src/storage_backend_fs.c
(virStorageBackendFileSystemNetFindPoolSources):
* src/storage_backend_logical.c (virStorageBackendLogicalFindLVs)
(virStorageBackendLogicalFindPoolSources):
* src/test.c (testOpenDefault, testOpenFromFile, testOpen)
(testGetDomainInfo, testDomainRestore)
(testNodeGetCellsFreeMemory):
* src/util.c (virExec):
* src/virsh.c (cmdAttachDevice, cmdDetachDevice)
(cmdAttachInterface, cmdDetachInterface, cmdAttachDisk)
(cmdDetachDisk, cmdEdit):
* src/xend_internal.c (do_connect, wr_sync, xend_op_ext)
(urlencode, xenDaemonDomainCreateXML)
(xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID)
(xenDaemonParseSxprOS, xend_parse_sexp_desc_char)
(xenDaemonParseSxprChar, xenDaemonParseSxprDisks)
(xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain)
(xenDaemonDomainFetch, xenDaemonDomainGetAutostart)
(xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform)
(xenDaemonDomainDefineXML, xenDaemonGetSchedulerType)
(xenDaemonGetSchedulerParameters)
(xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek)
(xenDaemonFormatSxprChr, virDomainXMLDevID):
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu)
(xenXMDomainCreate, xenXMDomainDefineXML)
(xenXMDomainAttachDevice, xenXMDomainDetachDevice):
* src/xml.c (virXPathString, virXPathNumber, virXPathLong)
(virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet):
* src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
|
|
|
"%s", _("Invalid parameter to virXPathNumber()"));
|
2007-10-24 14:22:25 +00:00
|
|
|
return (-1);
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
2008-07-09 08:35:09 +00:00
|
|
|
relnode = ctxt->node;
|
2007-04-06 12:28:24 +00:00
|
|
|
obj = xmlXPathEval(BAD_CAST xpath, ctxt);
|
2009-09-29 09:07:01 +00:00
|
|
|
ctxt->node = relnode;
|
2007-04-06 12:28:24 +00:00
|
|
|
if ((obj == NULL) || (obj->type != XPATH_NUMBER) ||
|
|
|
|
(isnan(obj->floatval))) {
|
2007-10-24 14:22:25 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
return (-1);
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
2007-10-24 14:22:25 +00:00
|
|
|
|
2007-04-06 12:28:24 +00:00
|
|
|
*value = obj->floatval;
|
|
|
|
xmlXPathFreeObject(obj);
|
2007-10-24 14:22:25 +00:00
|
|
|
return (0);
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
|
|
|
|
2009-02-24 14:53:30 +00:00
|
|
|
static int
|
2010-02-04 21:52:34 +00:00
|
|
|
virXPathLongBase(const char *xpath,
|
2009-02-24 14:53:30 +00:00
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
int base,
|
|
|
|
long *value)
|
2007-10-24 14:22:25 +00:00
|
|
|
{
|
2007-04-06 12:28:24 +00:00
|
|
|
xmlXPathObjectPtr obj;
|
2008-07-09 08:35:09 +00:00
|
|
|
xmlNodePtr relnode;
|
2007-04-06 12:28:24 +00:00
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
|
2010-02-04 21:52:34 +00:00
|
|
|
virXMLError(VIR_ERR_INTERNAL_ERROR,
|
2009-02-13 19:12:45 +00:00
|
|
|
"%s", _("Invalid parameter to virXPathLong()"));
|
2007-10-24 14:22:25 +00:00
|
|
|
return (-1);
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
2008-07-09 08:35:09 +00:00
|
|
|
relnode = ctxt->node;
|
2007-04-06 12:28:24 +00:00
|
|
|
obj = xmlXPathEval(BAD_CAST xpath, ctxt);
|
2009-09-29 09:07:01 +00:00
|
|
|
ctxt->node = relnode;
|
2007-04-06 12:28:24 +00:00
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
char *conv = NULL;
|
2007-10-24 14:22:25 +00:00
|
|
|
long val;
|
2007-04-06 12:28:24 +00:00
|
|
|
|
2009-02-24 14:53:30 +00:00
|
|
|
val = strtol((const char *) obj->stringval, &conv, base);
|
2007-10-24 14:22:25 +00:00
|
|
|
if (conv == (const char *) obj->stringval) {
|
2007-04-06 12:28:24 +00:00
|
|
|
ret = -2;
|
|
|
|
} else {
|
2007-10-24 14:22:25 +00:00
|
|
|
*value = val;
|
|
|
|
}
|
2007-04-06 12:28:24 +00:00
|
|
|
} else if ((obj != NULL) && (obj->type == XPATH_NUMBER) &&
|
|
|
|
(!(isnan(obj->floatval)))) {
|
2007-10-24 14:22:25 +00:00
|
|
|
*value = (long) obj->floatval;
|
|
|
|
if (*value != obj->floatval) {
|
|
|
|
ret = -2;
|
|
|
|
}
|
2007-04-06 12:28:24 +00:00
|
|
|
} else {
|
2007-10-24 14:22:25 +00:00
|
|
|
ret = -1;
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
2007-10-24 14:22:25 +00:00
|
|
|
|
2007-04-06 12:28:24 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2007-10-24 14:22:25 +00:00
|
|
|
return (ret);
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
|
|
|
|
2011-01-13 22:09:18 +00:00
|
|
|
/**
|
|
|
|
* virXPathInt:
|
|
|
|
* @xpath: the XPath string to evaluate
|
|
|
|
* @ctxt: an XPath context
|
|
|
|
* @value: the returned int value
|
|
|
|
*
|
|
|
|
* Convenience function to evaluate an XPath number
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success in which case @value is set,
|
|
|
|
* or -1 if the XPath evaluation failed or -2 if the
|
|
|
|
* value doesn't have an int format.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
virXPathInt(const char *xpath,
|
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
int *value)
|
|
|
|
{
|
|
|
|
long tmp;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = virXPathLongBase(xpath, ctxt, 10, &tmp);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
if ((int) tmp != tmp)
|
|
|
|
return -2;
|
|
|
|
*value = tmp;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-07-11 10:48:34 +00:00
|
|
|
/**
|
2009-02-24 14:53:30 +00:00
|
|
|
* virXPathLong:
|
2008-07-11 10:48:34 +00:00
|
|
|
* @xpath: the XPath string to evaluate
|
|
|
|
* @ctxt: an XPath context
|
|
|
|
* @value: the returned long value
|
|
|
|
*
|
|
|
|
* Convenience function to evaluate an XPath number
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success in which case @value is set,
|
|
|
|
* or -1 if the XPath evaluation failed or -2 if the
|
|
|
|
* value doesn't have a long format.
|
|
|
|
*/
|
|
|
|
int
|
2010-02-04 21:52:34 +00:00
|
|
|
virXPathLong(const char *xpath,
|
2009-02-24 14:53:30 +00:00
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
long *value)
|
|
|
|
{
|
2010-02-04 21:52:34 +00:00
|
|
|
return virXPathLongBase(xpath, ctxt, 10, value);
|
2009-02-24 14:53:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virXPathLongHex:
|
|
|
|
* @xpath: the XPath string to evaluate
|
|
|
|
* @ctxt: an XPath context
|
|
|
|
* @value: the returned long value
|
|
|
|
*
|
|
|
|
* Convenience function to evaluate an XPath number
|
|
|
|
* according to a base of 16
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success in which case @value is set,
|
|
|
|
* or -1 if the XPath evaluation failed or -2 if the
|
|
|
|
* value doesn't have a long format.
|
|
|
|
*/
|
|
|
|
int
|
2010-02-04 21:52:34 +00:00
|
|
|
virXPathLongHex(const char *xpath,
|
2009-02-24 14:53:30 +00:00
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
long *value)
|
|
|
|
{
|
2010-02-04 21:52:34 +00:00
|
|
|
return virXPathLongBase(xpath, ctxt, 16, value);
|
2009-02-24 14:53:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2010-02-04 21:52:34 +00:00
|
|
|
virXPathULongBase(const char *xpath,
|
2009-02-24 14:53:30 +00:00
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
int base,
|
|
|
|
unsigned long *value)
|
2008-07-11 10:48:34 +00:00
|
|
|
{
|
|
|
|
xmlXPathObjectPtr obj;
|
|
|
|
xmlNodePtr relnode;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
|
2010-02-04 21:52:34 +00:00
|
|
|
virXMLError(VIR_ERR_INTERNAL_ERROR,
|
2009-02-13 19:12:45 +00:00
|
|
|
"%s", _("Invalid parameter to virXPathULong()"));
|
2008-07-11 10:48:34 +00:00
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
relnode = ctxt->node;
|
|
|
|
obj = xmlXPathEval(BAD_CAST xpath, ctxt);
|
2009-09-29 09:07:01 +00:00
|
|
|
ctxt->node = relnode;
|
2008-07-11 10:48:34 +00:00
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
char *conv = NULL;
|
|
|
|
long val;
|
|
|
|
|
2009-02-24 14:53:30 +00:00
|
|
|
val = strtoul((const char *) obj->stringval, &conv, base);
|
2008-07-11 10:48:34 +00:00
|
|
|
if (conv == (const char *) obj->stringval) {
|
|
|
|
ret = -2;
|
|
|
|
} else {
|
|
|
|
*value = val;
|
|
|
|
}
|
|
|
|
} else if ((obj != NULL) && (obj->type == XPATH_NUMBER) &&
|
|
|
|
(!(isnan(obj->floatval)))) {
|
|
|
|
*value = (unsigned long) obj->floatval;
|
|
|
|
if (*value != obj->floatval) {
|
|
|
|
ret = -2;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ret = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
return (ret);
|
|
|
|
}
|
|
|
|
|
2011-01-13 22:09:18 +00:00
|
|
|
/**
|
|
|
|
* virXPathUInt:
|
|
|
|
* @xpath: the XPath string to evaluate
|
|
|
|
* @ctxt: an XPath context
|
|
|
|
* @value: the returned int value
|
|
|
|
*
|
|
|
|
* Convenience function to evaluate an XPath number
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success in which case @value is set,
|
|
|
|
* or -1 if the XPath evaluation failed or -2 if the
|
|
|
|
* value doesn't have an int format.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
virXPathUInt(const char *xpath,
|
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
unsigned int *value)
|
|
|
|
{
|
|
|
|
unsigned long tmp;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = virXPathULongBase(xpath, ctxt, 10, &tmp);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
if ((unsigned int) tmp != tmp)
|
|
|
|
return -2;
|
|
|
|
*value = tmp;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-02-24 14:53:30 +00:00
|
|
|
/**
|
|
|
|
* virXPathULong:
|
|
|
|
* @xpath: the XPath string to evaluate
|
|
|
|
* @ctxt: an XPath context
|
|
|
|
* @value: the returned long value
|
|
|
|
*
|
|
|
|
* Convenience function to evaluate an XPath number
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success in which case @value is set,
|
|
|
|
* or -1 if the XPath evaluation failed or -2 if the
|
|
|
|
* value doesn't have a long format.
|
|
|
|
*/
|
|
|
|
int
|
2010-02-04 21:52:34 +00:00
|
|
|
virXPathULong(const char *xpath,
|
2009-02-24 14:53:30 +00:00
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
unsigned long *value)
|
|
|
|
{
|
2010-02-04 21:52:34 +00:00
|
|
|
return virXPathULongBase(xpath, ctxt, 10, value);
|
2009-02-24 14:53:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virXPathUHex:
|
|
|
|
* @xpath: the XPath string to evaluate
|
|
|
|
* @ctxt: an XPath context
|
|
|
|
* @value: the returned long value
|
|
|
|
*
|
|
|
|
* Convenience function to evaluate an XPath number
|
|
|
|
* according to base of 16
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success in which case @value is set,
|
|
|
|
* or -1 if the XPath evaluation failed or -2 if the
|
|
|
|
* value doesn't have a long format.
|
|
|
|
*/
|
|
|
|
int
|
2010-02-04 21:52:34 +00:00
|
|
|
virXPathULongHex(const char *xpath,
|
2009-02-24 14:53:30 +00:00
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
unsigned long *value)
|
|
|
|
{
|
2010-02-04 21:52:34 +00:00
|
|
|
return virXPathULongBase(xpath, ctxt, 16, value);
|
2009-02-24 14:53:30 +00:00
|
|
|
}
|
|
|
|
|
2009-02-24 14:54:30 +00:00
|
|
|
/**
|
|
|
|
* virXPathULongLong:
|
|
|
|
* @xpath: the XPath string to evaluate
|
|
|
|
* @ctxt: an XPath context
|
|
|
|
* @value: the returned long long value
|
|
|
|
*
|
|
|
|
* Convenience function to evaluate an XPath number
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success in which case @value is set,
|
|
|
|
* or -1 if the XPath evaluation failed or -2 if the
|
|
|
|
* value doesn't have a long format.
|
|
|
|
*/
|
|
|
|
int
|
2010-02-04 21:52:34 +00:00
|
|
|
virXPathULongLong(const char *xpath,
|
2009-02-24 14:54:30 +00:00
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
unsigned long long *value)
|
|
|
|
{
|
|
|
|
xmlXPathObjectPtr obj;
|
|
|
|
xmlNodePtr relnode;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
|
2010-02-04 21:52:34 +00:00
|
|
|
virXMLError(VIR_ERR_INTERNAL_ERROR,
|
2009-02-24 14:54:30 +00:00
|
|
|
"%s", _("Invalid parameter to virXPathULong()"));
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
relnode = ctxt->node;
|
|
|
|
obj = xmlXPathEval(BAD_CAST xpath, ctxt);
|
2009-09-29 09:07:01 +00:00
|
|
|
ctxt->node = relnode;
|
2009-02-24 14:54:30 +00:00
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
char *conv = NULL;
|
|
|
|
unsigned long long val;
|
|
|
|
|
|
|
|
val = strtoull((const char *) obj->stringval, &conv, 10);
|
|
|
|
if (conv == (const char *) obj->stringval) {
|
|
|
|
ret = -2;
|
|
|
|
} else {
|
|
|
|
*value = val;
|
|
|
|
}
|
|
|
|
} else if ((obj != NULL) && (obj->type == XPATH_NUMBER) &&
|
|
|
|
(!(isnan(obj->floatval)))) {
|
|
|
|
*value = (unsigned long long) obj->floatval;
|
|
|
|
if (*value != obj->floatval) {
|
|
|
|
ret = -2;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ret = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
return (ret);
|
|
|
|
}
|
|
|
|
|
2010-02-02 17:49:09 +00:00
|
|
|
/**
|
|
|
|
* virXPathULongLong:
|
|
|
|
* @xpath: the XPath string to evaluate
|
|
|
|
* @ctxt: an XPath context
|
|
|
|
* @value: the returned long long value
|
|
|
|
*
|
|
|
|
* Convenience function to evaluate an XPath number
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success in which case @value is set,
|
|
|
|
* or -1 if the XPath evaluation failed or -2 if the
|
|
|
|
* value doesn't have a long format.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
virXPathLongLong(const char *xpath,
|
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
long long *value)
|
|
|
|
{
|
|
|
|
xmlXPathObjectPtr obj;
|
|
|
|
xmlNodePtr relnode;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
|
|
|
|
virXMLError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("Invalid parameter to virXPathLongLong()"));
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
relnode = ctxt->node;
|
|
|
|
obj = xmlXPathEval(BAD_CAST xpath, ctxt);
|
|
|
|
ctxt->node = relnode;
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
char *conv = NULL;
|
|
|
|
unsigned long long val;
|
|
|
|
|
|
|
|
val = strtoll((const char *) obj->stringval, &conv, 10);
|
|
|
|
if (conv == (const char *) obj->stringval) {
|
|
|
|
ret = -2;
|
|
|
|
} else {
|
|
|
|
*value = val;
|
|
|
|
}
|
|
|
|
} else if ((obj != NULL) && (obj->type == XPATH_NUMBER) &&
|
|
|
|
(!(isnan(obj->floatval)))) {
|
|
|
|
*value = (long long) obj->floatval;
|
|
|
|
if (*value != obj->floatval) {
|
|
|
|
ret = -2;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ret = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
return (ret);
|
|
|
|
}
|
|
|
|
|
2008-07-11 16:23:36 +00:00
|
|
|
char *
|
|
|
|
virXMLPropString(xmlNodePtr node,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
return (char *)xmlGetProp(node, BAD_CAST name);
|
|
|
|
}
|
|
|
|
|
2007-04-06 12:28:24 +00:00
|
|
|
/**
|
|
|
|
* virXPathBoolean:
|
|
|
|
* @xpath: the XPath string to evaluate
|
|
|
|
* @ctxt: an XPath context
|
|
|
|
*
|
|
|
|
* Convenience function to evaluate an XPath boolean
|
|
|
|
*
|
|
|
|
* Returns 0 if false, 1 if true, or -1 if the evaluation failed.
|
|
|
|
*/
|
|
|
|
int
|
2010-02-04 21:52:34 +00:00
|
|
|
virXPathBoolean(const char *xpath,
|
2008-07-25 14:27:25 +00:00
|
|
|
xmlXPathContextPtr ctxt)
|
2007-10-24 14:22:25 +00:00
|
|
|
{
|
2007-04-06 12:28:24 +00:00
|
|
|
xmlXPathObjectPtr obj;
|
2008-07-09 08:35:09 +00:00
|
|
|
xmlNodePtr relnode;
|
2007-04-06 12:28:24 +00:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
if ((ctxt == NULL) || (xpath == NULL)) {
|
2010-02-04 21:52:34 +00:00
|
|
|
virXMLError(VIR_ERR_INTERNAL_ERROR,
|
avoid many format string warnings
Building with --disable-nls exposed many new warnings like these:
virsh.c:4952: warning: format not a string literal and no format ...
util.c:163: warning: format not a string literal and no format arguments
All but one of the following changes add a "%s" argument before
the offending _(...) argument.
This was the only manual change:
* src/lxc_driver.c (lxcVersion): Use %s and strerror(errno)
rather than %m, to avoid a warning from gcc -Wformat-security.
Add "%s" before each warned about format-string-with-no-%-directive:
* src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML)
(virDomainDefParseString, virDomainDefParseFile):
* src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain)
(__virGetNetwork, virReleaseNetwork, __virGetStoragePool)
(virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol):
* src/lxc_container.c (lxcContainerChild):
* src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine)
(lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML)
(lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart)
(lxcVersion, lxcGetSchedulerParameters):
* src/network_conf.c (virNetworkDefParseString)
(virNetworkDefParseFile):
* src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains):
* src/openvz_driver.c (openvzDomainDefineCmd)
(openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown)
(openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML)
(openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine)
(openvzDomainSetAutostart, openvzDomainGetAutostart)
(openvzDomainSetVcpus):
* src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek):
* src/remote_internal.c (remoteDomainBlockPeek)
(remoteDomainMemoryPeek, remoteAuthPolkit):
* src/sexpr.c (sexpr_new, _string2sexpr):
* src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol)
(virStorageBackendDiskCreateVol):
* src/storage_backend_fs.c
(virStorageBackendFileSystemNetFindPoolSources):
* src/storage_backend_logical.c (virStorageBackendLogicalFindLVs)
(virStorageBackendLogicalFindPoolSources):
* src/test.c (testOpenDefault, testOpenFromFile, testOpen)
(testGetDomainInfo, testDomainRestore)
(testNodeGetCellsFreeMemory):
* src/util.c (virExec):
* src/virsh.c (cmdAttachDevice, cmdDetachDevice)
(cmdAttachInterface, cmdDetachInterface, cmdAttachDisk)
(cmdDetachDisk, cmdEdit):
* src/xend_internal.c (do_connect, wr_sync, xend_op_ext)
(urlencode, xenDaemonDomainCreateXML)
(xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID)
(xenDaemonParseSxprOS, xend_parse_sexp_desc_char)
(xenDaemonParseSxprChar, xenDaemonParseSxprDisks)
(xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain)
(xenDaemonDomainFetch, xenDaemonDomainGetAutostart)
(xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform)
(xenDaemonDomainDefineXML, xenDaemonGetSchedulerType)
(xenDaemonGetSchedulerParameters)
(xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek)
(xenDaemonFormatSxprChr, virDomainXMLDevID):
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu)
(xenXMDomainCreate, xenXMDomainDefineXML)
(xenXMDomainAttachDevice, xenXMDomainDetachDevice):
* src/xml.c (virXPathString, virXPathNumber, virXPathLong)
(virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet):
* src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
|
|
|
"%s", _("Invalid parameter to virXPathBoolean()"));
|
2007-10-24 14:22:25 +00:00
|
|
|
return (-1);
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
2008-07-09 08:35:09 +00:00
|
|
|
relnode = ctxt->node;
|
2007-04-06 12:28:24 +00:00
|
|
|
obj = xmlXPathEval(BAD_CAST xpath, ctxt);
|
2009-09-29 09:07:01 +00:00
|
|
|
ctxt->node = relnode;
|
2007-04-06 12:28:24 +00:00
|
|
|
if ((obj == NULL) || (obj->type != XPATH_BOOLEAN) ||
|
|
|
|
(obj->boolval < 0) || (obj->boolval > 1)) {
|
2007-10-24 14:22:25 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
return (-1);
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
|
|
|
ret = obj->boolval;
|
2007-10-24 14:22:25 +00:00
|
|
|
|
2007-04-06 12:28:24 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
2007-10-24 14:22:25 +00:00
|
|
|
return (ret);
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virXPathNode:
|
|
|
|
* @xpath: the XPath string to evaluate
|
|
|
|
* @ctxt: an XPath context
|
|
|
|
*
|
|
|
|
* Convenience function to evaluate an XPath node set and returning
|
|
|
|
* only one node, the first one in the set if any
|
|
|
|
*
|
|
|
|
* Returns a pointer to the node or NULL if the evaluation failed.
|
|
|
|
*/
|
|
|
|
xmlNodePtr
|
2010-02-04 21:52:34 +00:00
|
|
|
virXPathNode(const char *xpath,
|
2008-07-25 14:27:25 +00:00
|
|
|
xmlXPathContextPtr ctxt)
|
2007-10-24 14:22:25 +00:00
|
|
|
{
|
2007-04-06 12:28:24 +00:00
|
|
|
xmlXPathObjectPtr obj;
|
2008-07-09 08:35:09 +00:00
|
|
|
xmlNodePtr relnode;
|
2007-04-06 12:28:24 +00:00
|
|
|
xmlNodePtr ret;
|
|
|
|
|
|
|
|
if ((ctxt == NULL) || (xpath == NULL)) {
|
2010-02-04 21:52:34 +00:00
|
|
|
virXMLError(VIR_ERR_INTERNAL_ERROR,
|
avoid many format string warnings
Building with --disable-nls exposed many new warnings like these:
virsh.c:4952: warning: format not a string literal and no format ...
util.c:163: warning: format not a string literal and no format arguments
All but one of the following changes add a "%s" argument before
the offending _(...) argument.
This was the only manual change:
* src/lxc_driver.c (lxcVersion): Use %s and strerror(errno)
rather than %m, to avoid a warning from gcc -Wformat-security.
Add "%s" before each warned about format-string-with-no-%-directive:
* src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML)
(virDomainDefParseString, virDomainDefParseFile):
* src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain)
(__virGetNetwork, virReleaseNetwork, __virGetStoragePool)
(virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol):
* src/lxc_container.c (lxcContainerChild):
* src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine)
(lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML)
(lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart)
(lxcVersion, lxcGetSchedulerParameters):
* src/network_conf.c (virNetworkDefParseString)
(virNetworkDefParseFile):
* src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains):
* src/openvz_driver.c (openvzDomainDefineCmd)
(openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown)
(openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML)
(openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine)
(openvzDomainSetAutostart, openvzDomainGetAutostart)
(openvzDomainSetVcpus):
* src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek):
* src/remote_internal.c (remoteDomainBlockPeek)
(remoteDomainMemoryPeek, remoteAuthPolkit):
* src/sexpr.c (sexpr_new, _string2sexpr):
* src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol)
(virStorageBackendDiskCreateVol):
* src/storage_backend_fs.c
(virStorageBackendFileSystemNetFindPoolSources):
* src/storage_backend_logical.c (virStorageBackendLogicalFindLVs)
(virStorageBackendLogicalFindPoolSources):
* src/test.c (testOpenDefault, testOpenFromFile, testOpen)
(testGetDomainInfo, testDomainRestore)
(testNodeGetCellsFreeMemory):
* src/util.c (virExec):
* src/virsh.c (cmdAttachDevice, cmdDetachDevice)
(cmdAttachInterface, cmdDetachInterface, cmdAttachDisk)
(cmdDetachDisk, cmdEdit):
* src/xend_internal.c (do_connect, wr_sync, xend_op_ext)
(urlencode, xenDaemonDomainCreateXML)
(xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID)
(xenDaemonParseSxprOS, xend_parse_sexp_desc_char)
(xenDaemonParseSxprChar, xenDaemonParseSxprDisks)
(xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain)
(xenDaemonDomainFetch, xenDaemonDomainGetAutostart)
(xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform)
(xenDaemonDomainDefineXML, xenDaemonGetSchedulerType)
(xenDaemonGetSchedulerParameters)
(xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek)
(xenDaemonFormatSxprChr, virDomainXMLDevID):
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu)
(xenXMDomainCreate, xenXMDomainDefineXML)
(xenXMDomainAttachDevice, xenXMDomainDetachDevice):
* src/xml.c (virXPathString, virXPathNumber, virXPathLong)
(virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet):
* src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
|
|
|
"%s", _("Invalid parameter to virXPathNode()"));
|
2007-10-24 14:22:25 +00:00
|
|
|
return (NULL);
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
2008-07-09 08:35:09 +00:00
|
|
|
relnode = ctxt->node;
|
2007-04-06 12:28:24 +00:00
|
|
|
obj = xmlXPathEval(BAD_CAST xpath, ctxt);
|
2009-09-29 09:07:01 +00:00
|
|
|
ctxt->node = relnode;
|
2007-04-06 12:28:24 +00:00
|
|
|
if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
|
|
|
|
(obj->nodesetval == NULL) || (obj->nodesetval->nodeNr <= 0) ||
|
2007-10-24 14:22:25 +00:00
|
|
|
(obj->nodesetval->nodeTab == NULL)) {
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
return (NULL);
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
2007-10-24 14:22:25 +00:00
|
|
|
|
2007-04-06 12:28:24 +00:00
|
|
|
ret = obj->nodesetval->nodeTab[0];
|
|
|
|
xmlXPathFreeObject(obj);
|
2007-10-24 14:22:25 +00:00
|
|
|
return (ret);
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
2007-10-24 14:22:25 +00:00
|
|
|
|
2007-04-06 12:28:24 +00:00
|
|
|
/**
|
|
|
|
* virXPathNodeSet:
|
|
|
|
* @xpath: the XPath string to evaluate
|
|
|
|
* @ctxt: an XPath context
|
|
|
|
* @list: the returned list of nodes (or NULL if only count matters)
|
|
|
|
*
|
|
|
|
* Convenience function to evaluate an XPath node set
|
|
|
|
*
|
|
|
|
* Returns the number of nodes found in which case @list is set (and
|
|
|
|
* must be freed) or -1 if the evaluation failed.
|
|
|
|
*/
|
|
|
|
int
|
2010-02-04 21:52:34 +00:00
|
|
|
virXPathNodeSet(const char *xpath,
|
2008-07-25 14:27:25 +00:00
|
|
|
xmlXPathContextPtr ctxt,
|
|
|
|
xmlNodePtr **list)
|
2007-10-24 14:22:25 +00:00
|
|
|
{
|
2007-04-06 12:28:24 +00:00
|
|
|
xmlXPathObjectPtr obj;
|
2008-07-09 08:35:09 +00:00
|
|
|
xmlNodePtr relnode;
|
2007-04-06 12:28:24 +00:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
if ((ctxt == NULL) || (xpath == NULL)) {
|
2010-02-04 21:52:34 +00:00
|
|
|
virXMLError(VIR_ERR_INTERNAL_ERROR,
|
avoid many format string warnings
Building with --disable-nls exposed many new warnings like these:
virsh.c:4952: warning: format not a string literal and no format ...
util.c:163: warning: format not a string literal and no format arguments
All but one of the following changes add a "%s" argument before
the offending _(...) argument.
This was the only manual change:
* src/lxc_driver.c (lxcVersion): Use %s and strerror(errno)
rather than %m, to avoid a warning from gcc -Wformat-security.
Add "%s" before each warned about format-string-with-no-%-directive:
* src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML)
(virDomainDefParseString, virDomainDefParseFile):
* src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain)
(__virGetNetwork, virReleaseNetwork, __virGetStoragePool)
(virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol):
* src/lxc_container.c (lxcContainerChild):
* src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine)
(lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML)
(lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart)
(lxcVersion, lxcGetSchedulerParameters):
* src/network_conf.c (virNetworkDefParseString)
(virNetworkDefParseFile):
* src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains):
* src/openvz_driver.c (openvzDomainDefineCmd)
(openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown)
(openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML)
(openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine)
(openvzDomainSetAutostart, openvzDomainGetAutostart)
(openvzDomainSetVcpus):
* src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek):
* src/remote_internal.c (remoteDomainBlockPeek)
(remoteDomainMemoryPeek, remoteAuthPolkit):
* src/sexpr.c (sexpr_new, _string2sexpr):
* src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol)
(virStorageBackendDiskCreateVol):
* src/storage_backend_fs.c
(virStorageBackendFileSystemNetFindPoolSources):
* src/storage_backend_logical.c (virStorageBackendLogicalFindLVs)
(virStorageBackendLogicalFindPoolSources):
* src/test.c (testOpenDefault, testOpenFromFile, testOpen)
(testGetDomainInfo, testDomainRestore)
(testNodeGetCellsFreeMemory):
* src/util.c (virExec):
* src/virsh.c (cmdAttachDevice, cmdDetachDevice)
(cmdAttachInterface, cmdDetachInterface, cmdAttachDisk)
(cmdDetachDisk, cmdEdit):
* src/xend_internal.c (do_connect, wr_sync, xend_op_ext)
(urlencode, xenDaemonDomainCreateXML)
(xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID)
(xenDaemonParseSxprOS, xend_parse_sexp_desc_char)
(xenDaemonParseSxprChar, xenDaemonParseSxprDisks)
(xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain)
(xenDaemonDomainFetch, xenDaemonDomainGetAutostart)
(xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform)
(xenDaemonDomainDefineXML, xenDaemonGetSchedulerType)
(xenDaemonGetSchedulerParameters)
(xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek)
(xenDaemonFormatSxprChr, virDomainXMLDevID):
* src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu)
(xenXMDomainCreate, xenXMDomainDefineXML)
(xenXMDomainAttachDevice, xenXMDomainDetachDevice):
* src/xml.c (virXPathString, virXPathNumber, virXPathLong)
(virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet):
* src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
|
|
|
"%s", _("Invalid parameter to virXPathNodeSet()"));
|
2007-10-24 14:22:25 +00:00
|
|
|
return (-1);
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
2008-07-11 16:23:36 +00:00
|
|
|
|
|
|
|
if (list != NULL)
|
|
|
|
*list = NULL;
|
|
|
|
|
2008-07-09 08:35:09 +00:00
|
|
|
relnode = ctxt->node;
|
2007-04-06 12:28:24 +00:00
|
|
|
obj = xmlXPathEval(BAD_CAST xpath, ctxt);
|
2009-09-29 09:07:01 +00:00
|
|
|
ctxt->node = relnode;
|
2009-10-22 08:32:15 +00:00
|
|
|
if (obj == NULL)
|
|
|
|
return(0);
|
2011-05-12 19:45:22 +00:00
|
|
|
|
2009-10-22 08:32:15 +00:00
|
|
|
if (obj->type != XPATH_NODESET) {
|
2011-05-12 19:45:22 +00:00
|
|
|
virXMLError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Incorrect xpath '%s'"), xpath);
|
2007-10-24 14:22:25 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
return (-1);
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
2011-05-12 19:45:22 +00:00
|
|
|
|
2009-10-22 08:32:15 +00:00
|
|
|
if ((obj->nodesetval == NULL) || (obj->nodesetval->nodeNr < 0)) {
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
return (0);
|
|
|
|
}
|
2007-10-24 14:22:25 +00:00
|
|
|
|
2007-04-06 12:28:24 +00:00
|
|
|
ret = obj->nodesetval->nodeNr;
|
2008-07-11 16:23:36 +00:00
|
|
|
if (list != NULL && ret) {
|
2008-05-29 19:20:22 +00:00
|
|
|
if (VIR_ALLOC_N(*list, ret) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-05-29 19:20:22 +00:00
|
|
|
ret = -1;
|
2007-10-24 14:22:25 +00:00
|
|
|
} else {
|
|
|
|
memcpy(*list, obj->nodesetval->nodeTab,
|
|
|
|
ret * sizeof(xmlNodePtr));
|
|
|
|
}
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
|
|
|
xmlXPathFreeObject(obj);
|
2007-10-24 14:22:25 +00:00
|
|
|
return (ret);
|
2007-04-06 12:28:24 +00:00
|
|
|
}
|
2010-02-24 20:44:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* catchXMLError:
|
|
|
|
*
|
|
|
|
* Called from SAX on parsing errors in the XML.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
catchXMLError(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...)
|
|
|
|
{
|
|
|
|
int domcode = VIR_FROM_XML;
|
|
|
|
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
|
|
|
|
|
|
|
if (ctxt) {
|
|
|
|
if (ctxt->_private)
|
|
|
|
domcode = ((struct virParserData *) ctxt->_private)->domcode;
|
|
|
|
|
|
|
|
if (virGetLastError() == NULL &&
|
|
|
|
ctxt->lastError.level == XML_ERR_FATAL &&
|
|
|
|
ctxt->lastError.message != NULL) {
|
|
|
|
virGenericReportError(domcode, VIR_ERR_XML_DETAIL,
|
|
|
|
_("at line %d: %s"),
|
|
|
|
ctxt->lastError.line,
|
|
|
|
ctxt->lastError.message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virXMLParseHelper:
|
|
|
|
* @domcode: error domain of the caller, usually VIR_FROM_THIS
|
|
|
|
* @filename: file to be parsed or NULL if string parsing is requested
|
|
|
|
* @xmlStr: XML string to be parsed in case filename is NULL
|
|
|
|
* @url: URL of XML document for string parser
|
|
|
|
*
|
|
|
|
* Parse XML document provided either as a file or a string. The function
|
|
|
|
* guarantees that the XML document contains a root element.
|
|
|
|
*
|
|
|
|
* Returns parsed XML document.
|
|
|
|
*/
|
|
|
|
xmlDocPtr
|
|
|
|
virXMLParseHelper(int domcode,
|
|
|
|
const char *filename,
|
|
|
|
const char *xmlStr,
|
|
|
|
const char *url)
|
|
|
|
{
|
|
|
|
struct virParserData private;
|
|
|
|
xmlParserCtxtPtr pctxt;
|
|
|
|
xmlDocPtr xml = NULL;
|
|
|
|
|
|
|
|
/* Set up a parser context so we can catch the details of XML errors. */
|
|
|
|
pctxt = xmlNewParserCtxt();
|
|
|
|
if (!pctxt || !pctxt->sax)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
private.domcode = domcode;
|
|
|
|
pctxt->_private = &private;
|
|
|
|
pctxt->sax->error = catchXMLError;
|
|
|
|
|
|
|
|
if (filename) {
|
|
|
|
xml = xmlCtxtReadFile(pctxt, filename, NULL,
|
|
|
|
XML_PARSE_NOENT | XML_PARSE_NONET |
|
|
|
|
XML_PARSE_NOWARNING);
|
|
|
|
} else {
|
|
|
|
xml = xmlCtxtReadDoc(pctxt, BAD_CAST xmlStr, url, NULL,
|
|
|
|
XML_PARSE_NOENT | XML_PARSE_NONET |
|
|
|
|
XML_PARSE_NOWARNING);
|
|
|
|
}
|
|
|
|
if (!xml)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (xmlDocGetRootElement(xml) == NULL) {
|
|
|
|
virGenericReportError(domcode, VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("missing root element"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
xmlFreeParserCtxt(pctxt);
|
|
|
|
|
|
|
|
return xml;
|
|
|
|
|
|
|
|
error:
|
|
|
|
xmlFreeDoc(xml);
|
|
|
|
xml = NULL;
|
|
|
|
|
|
|
|
if (virGetLastError() == NULL) {
|
|
|
|
virGenericReportError(domcode, VIR_ERR_XML_ERROR,
|
|
|
|
"%s", _("failed to parse xml document"));
|
|
|
|
}
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virXMLParseStrHelper:
|
|
|
|
* @domcode: error domain of the caller, usually VIR_FROM_THIS
|
|
|
|
* @xmlStr: XML string to be parsed in case filename is NULL
|
|
|
|
* @url: URL of XML document for string parser
|
|
|
|
*
|
|
|
|
* Parse XML document provided as a string. The function guarantees that
|
|
|
|
* the XML document contains a root element.
|
|
|
|
*
|
|
|
|
* Returns parsed XML document.
|
|
|
|
*/
|
|
|
|
xmlDocPtr
|
|
|
|
virXMLParseStrHelper(int domcode,
|
|
|
|
const char *xmlStr,
|
|
|
|
const char *url)
|
|
|
|
{
|
|
|
|
return virXMLParseHelper(domcode, NULL, xmlStr, url);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virXMLParseFileHelper:
|
|
|
|
* @domcode: error domain of the caller, usually VIR_FROM_THIS
|
|
|
|
* @filename: file to be parsed
|
|
|
|
*
|
|
|
|
* Parse XML document provided as a file. The function guarantees that
|
|
|
|
* the XML document contains a root element.
|
|
|
|
*
|
|
|
|
* Returns parsed XML document.
|
|
|
|
*/
|
|
|
|
xmlDocPtr
|
|
|
|
virXMLParseFileHelper(int domcode,
|
|
|
|
const char *filename)
|
|
|
|
{
|
|
|
|
return virXMLParseHelper(domcode, filename, NULL, NULL);
|
|
|
|
}
|