From: "Daniel P. Berrange" <berrange(a)redhat.com>
---
cfg.mk | 2 +-
po/POTFILES.in | 2 +-
src/Makefile.am | 2 +-
src/conf/cpu_conf.h | 2 +-
src/conf/device_conf.c | 2 +-
src/conf/domain_conf.c | 2 +-
src/conf/interface_conf.c | 2 +-
src/conf/netdev_bandwidth_conf.h | 2 +-
src/conf/netdev_vlan_conf.h | 2 +-
src/conf/netdev_vport_profile_conf.h | 2 +-
src/conf/network_conf.c | 2 +-
src/conf/node_device_conf.c | 2 +-
src/conf/nwfilter_conf.h | 2 +-
src/conf/secret_conf.c | 2 +-
src/conf/snapshot_conf.c | 2 +-
src/conf/storage_conf.c | 2 +-
src/conf/storage_encryption_conf.c | 2 +-
src/cpu/cpu.c | 2 +-
src/cpu/cpu_map.h | 2 +-
src/esx/esx_vi.c | 2 +-
src/qemu/qemu_conf.c | 2 +-
src/qemu/qemu_driver.c | 2 +-
src/security/virt-aa-helper.c | 2 +-
src/storage/storage_backend_fs.c | 2 +-
src/test/test_driver.c | 2 +-
src/util/virxml.c | 890 +++++++++++++++++++++++++++++++++++
src/util/virxml.h | 148 ++++++
src/util/xml.c | 890 -----------------------------------
src/util/xml.h | 148 ------
src/xen/xen_driver.c | 2 +-
tests/cputest.c | 2 +-
tests/nwfilterxml2xmltest.c | 2 +-
tests/sexpr2xmltest.c | 2 +-
tests/virshtest.c | 2 +-
tests/xencapstest.c | 2 +-
tools/virsh-domain-monitor.c | 2 +-
tools/virsh-domain.c | 2 +-
tools/virsh-host.c | 2 +-
tools/virsh-interface.c | 2 +-
tools/virsh-network.c | 2 +-
tools/virsh-nodedev.c | 2 +-
tools/virsh-nwfilter.c | 2 +-
tools/virsh-pool.c | 2 +-
tools/virsh-secret.c | 2 +-
tools/virsh-snapshot.c | 2 +-
tools/virsh-volume.c | 2 +-
tools/virsh.c | 2 +-
47 files changed, 1081 insertions(+), 1081 deletions(-)
create mode 100644 src/util/virxml.c
create mode 100644 src/util/virxml.h
delete mode 100644 src/util/xml.c
delete mode 100644 src/util/xml.h
diff --git a/cfg.mk b/cfg.mk
index a269f77..2fcb444 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -809,7 +809,7 @@ exclude_file_name_regexp--sc_prohibit_strncpy =
^src/util/virutil\.c$$
exclude_file_name_regexp--sc_prohibit_strtol = \
^src/(util/virsexpr|(vbox|xen|xenxs)/.*)\.c$$
-exclude_file_name_regexp--sc_prohibit_xmlGetProp = ^src/util/xml\.c$$
+exclude_file_name_regexp--sc_prohibit_xmlGetProp = ^src/util/virxml\.c$$
exclude_file_name_regexp--sc_prohibit_xmlURI = ^src/util/viruri\.c$$
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 8a24fd4..1afdca5 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -180,7 +180,7 @@ src/util/virtypedparam.c
src/util/viruri.c
src/util/virusb.c
src/util/virutil.c
-src/util/xml.c
+src/util/virxml.c
src/vbox/vbox_MSCOMGlue.c
src/vbox/vbox_XPCOMCGlue.c
src/vbox/vbox_driver.c
diff --git a/src/Makefile.am b/src/Makefile.am
index dd5a1bd..dddd162 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -85,7 +85,6 @@ UTIL_SOURCES = \
util/virthreadwin32.h \
util/virthreadpool.c util/virthreadpool.h \
util/virtypedparam.c util/virtypedparam.h \
- util/xml.c util/xml.h \
util/virterror.c util/virterror_internal.h \
util/vircgroup.c util/vircgroup.h \
util/virdbus.c util/virdbus.h \
@@ -115,6 +114,7 @@ UTIL_SOURCES = \
util/viruri.h util/viruri.c \
util/virutil.c util/virutil.h \
util/viruuid.c util/viruuid.h \
+ util/virxml.c util/virxml.h \
$(NULL)
EXTRA_DIST += $(srcdir)/util/virkeymaps.h $(srcdir)/util/keymaps.csv \
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
index 7bec912..616d813 100644
--- a/src/conf/cpu_conf.h
+++ b/src/conf/cpu_conf.h
@@ -26,7 +26,7 @@
# include "virutil.h"
# include "virbuffer.h"
-# include "xml.h"
+# include "virxml.h"
# include "virbitmap.h"
# define VIR_CPU_VENDOR_ID_LENGTH 12
diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c
index ecfaf30..45ecb28 100644
--- a/src/conf/device_conf.c
+++ b/src/conf/device_conf.c
@@ -24,7 +24,7 @@
#include "virterror_internal.h"
#include "datatypes.h"
#include "viralloc.h"
-#include "xml.h"
+#include "virxml.h"
#include "viruuid.h"
#include "virutil.h"
#include "virbuffer.h"
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 2943fe3..a4f33ed 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -36,7 +36,7 @@
#include "snapshot_conf.h"
#include "viralloc.h"
#include "verify.h"
-#include "xml.h"
+#include "virxml.h"
#include "viruuid.h"
#include "virutil.h"
#include "virbuffer.h"
diff --git a/src/conf/interface_conf.c b/src/conf/interface_conf.c
index 6a53bda..3867274 100644
--- a/src/conf/interface_conf.c
+++ b/src/conf/interface_conf.c
@@ -28,7 +28,7 @@
#include "interface_conf.h"
#include "viralloc.h"
-#include "xml.h"
+#include "virxml.h"
#include "viruuid.h"
#include "virutil.h"
#include "virbuffer.h"
diff --git a/src/conf/netdev_bandwidth_conf.h b/src/conf/netdev_bandwidth_conf.h
index 216a540..23aaaf3 100644
--- a/src/conf/netdev_bandwidth_conf.h
+++ b/src/conf/netdev_bandwidth_conf.h
@@ -26,7 +26,7 @@
# include "internal.h"
# include "virnetdevbandwidth.h"
# include "virbuffer.h"
-# include "xml.h"
+# include "virxml.h"
virNetDevBandwidthPtr virNetDevBandwidthParse(xmlNodePtr node,
int net_type)
diff --git a/src/conf/netdev_vlan_conf.h b/src/conf/netdev_vlan_conf.h
index 19b50cc..480d6c6 100644
--- a/src/conf/netdev_vlan_conf.h
+++ b/src/conf/netdev_vlan_conf.h
@@ -25,7 +25,7 @@
# include "internal.h"
# include "virnetdevvlan.h"
# include "virbuffer.h"
-# include "xml.h"
+# include "virxml.h"
int virNetDevVlanParse(xmlNodePtr node, xmlXPathContextPtr ctxt, virNetDevVlanPtr def);
int virNetDevVlanFormat(virNetDevVlanPtr def, virBufferPtr buf);
diff --git a/src/conf/netdev_vport_profile_conf.h b/src/conf/netdev_vport_profile_conf.h
index 15ecbd6..a70256d 100644
--- a/src/conf/netdev_vport_profile_conf.h
+++ b/src/conf/netdev_vport_profile_conf.h
@@ -26,7 +26,7 @@
# include "internal.h"
# include "virnetdevvportprofile.h"
# include "virbuffer.h"
-# include "xml.h"
+# include "virxml.h"
typedef enum {
/* generate random defaults for interfaceID/interfaceID
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 01a6f2e..2bd04c5 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -38,7 +38,7 @@
#include "netdev_bandwidth_conf.h"
#include "netdev_vlan_conf.h"
#include "viralloc.h"
-#include "xml.h"
+#include "virxml.h"
#include "viruuid.h"
#include "virutil.h"
#include "virbuffer.h"
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index 67d743e..3c68011 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -32,7 +32,7 @@
#include "node_device_conf.h"
#include "viralloc.h"
-#include "xml.h"
+#include "virxml.h"
#include "virutil.h"
#include "virbuffer.h"
#include "viruuid.h"
diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h
index 2ca44b3..ca2c070 100644
--- a/src/conf/nwfilter_conf.h
+++ b/src/conf/nwfilter_conf.h
@@ -30,7 +30,7 @@
# include "virutil.h"
# include "virhash.h"
-# include "xml.h"
+# include "virxml.h"
# include "virbuffer.h"
# include "virsocketaddr.h"
# include "virmacaddr.h"
diff --git a/src/conf/secret_conf.c b/src/conf/secret_conf.c
index 2abb95a..46d2ae5 100644
--- a/src/conf/secret_conf.c
+++ b/src/conf/secret_conf.c
@@ -30,7 +30,7 @@
#include "secret_conf.h"
#include "virterror_internal.h"
#include "virutil.h"
-#include "xml.h"
+#include "virxml.h"
#include "viruuid.h"
#define VIR_FROM_THIS VIR_FROM_SECRET
diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c
index 3ad74d6..f7f8f63 100644
--- a/src/conf/snapshot_conf.c
+++ b/src/conf/snapshot_conf.c
@@ -46,7 +46,7 @@
#include "viruuid.h"
#include "virfile.h"
#include "virterror_internal.h"
-#include "xml.h"
+#include "virxml.h"
#define VIR_FROM_THIS VIR_FROM_DOMAIN_SNAPSHOT
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 4239e49..04b2581 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -38,7 +38,7 @@
#include "storage_conf.h"
#include "virstoragefile.h"
-#include "xml.h"
+#include "virxml.h"
#include "viruuid.h"
#include "virbuffer.h"
#include "virutil.h"
diff --git a/src/conf/storage_encryption_conf.c b/src/conf/storage_encryption_conf.c
index 8ea54fa..35e9da4 100644
--- a/src/conf/storage_encryption_conf.c
+++ b/src/conf/storage_encryption_conf.c
@@ -32,7 +32,7 @@
#include "storage_conf.h"
#include "storage_encryption_conf.h"
#include "virutil.h"
-#include "xml.h"
+#include "virxml.h"
#include "virterror_internal.h"
#include "viruuid.h"
#include "virfile.h"
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 2222a91..3e25f7d 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -25,7 +25,7 @@
#include "virlog.h"
#include "viralloc.h"
-#include "xml.h"
+#include "virxml.h"
#include "cpu.h"
#include "cpu_x86.h"
#include "cpu_powerpc.h"
diff --git a/src/cpu/cpu_map.h b/src/cpu/cpu_map.h
index 9120513..8d27bcd 100644
--- a/src/cpu/cpu_map.h
+++ b/src/cpu/cpu_map.h
@@ -24,7 +24,7 @@
#ifndef __VIR_CPU_MAP_H__
# define __VIR_CPU_MAP_H__
-# include "xml.h"
+# include "virxml.h"
enum cpuMapElement {
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 92ac8f8..99c1eb1 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -32,7 +32,7 @@
#include "virutil.h"
#include "viruuid.h"
#include "vmx.h"
-#include "xml.h"
+#include "virxml.h"
#include "esx_vi.h"
#include "esx_vi_methods.h"
#include "esx_util.h"
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 8d05b4c..56c93a8 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -46,7 +46,7 @@
#include "virutil.h"
#include "viralloc.h"
#include "datatypes.h"
-#include "xml.h"
+#include "virxml.h"
#include "nodeinfo.h"
#include "virlog.h"
#include "cpu/cpu.h"
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 3821d74..d24527b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -76,7 +76,7 @@
#include "virusb.h"
#include "virprocess.h"
#include "libvirt_internal.h"
-#include "xml.h"
+#include "virxml.h"
#include "cpu/cpu.h"
#include "virsysinfo.h"
#include "domain_nwfilter.h"
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 3c15226..ffd3f71 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -48,7 +48,7 @@
#include "security_driver.h"
#include "security_apparmor.h"
#include "domain_conf.h"
-#include "xml.h"
+#include "virxml.h"
#include "viruuid.h"
#include "virusb.h"
#include "virpci.h"
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index b744fb4..23fa0f5 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -47,7 +47,7 @@
#include "virstoragefile.h"
#include "vircommand.h"
#include "viralloc.h"
-#include "xml.h"
+#include "virxml.h"
#include "virfile.h"
#include "virlog.h"
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 1a85eb3..bd557d6 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -46,7 +46,7 @@
#include "domain_event.h"
#include "storage_conf.h"
#include "node_device_conf.h"
-#include "xml.h"
+#include "virxml.h"
#include "virthread.h"
#include "virlog.h"
#include "virfile.h"
diff --git a/src/util/virxml.c b/src/util/virxml.c
new file mode 100644
index 0000000..02f7d1a
--- /dev/null
+++ b/src/util/virxml.c
@@ -0,0 +1,890 @@
+/*
+ * xml.c: XML based interfaces for the libvir library
+ *
+ * Copyright (C) 2005, 2007-2012 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <
http://www.gnu.org/licenses/>.
+ *
+ * Daniel Veillard <veillard(a)redhat.com>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <limits.h>
+#include <math.h> /* for isnan() */
+#include <sys/stat.h>
+
+#include "virterror_internal.h"
+#include "virxml.h"
+#include "virbuffer.h"
+#include "virutil.h"
+#include "viralloc.h"
+#include "virfile.h"
+
+#define VIR_FROM_THIS VIR_FROM_XML
+
+#define virGenericReportError(from, code, ...) \
+ virReportErrorHelper(from, code, __FILE__, \
+ __FUNCTION__, __LINE__, __VA_ARGS__)
+
+/* Internal data to be passed to SAX parser and used by error handler. */
+struct virParserData {
+ int domcode;
+};
+
+
+/************************************************************************
+ * *
+ * Wrappers around libxml2 XPath specific functions *
+ * *
+ ************************************************************************/
+
+/**
+ * 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 *
+virXPathString(const char *xpath,
+ xmlXPathContextPtr ctxt)
+{
+ xmlXPathObjectPtr obj;
+ xmlNodePtr relnode;
+ char *ret;
+
+ if ((ctxt == NULL) || (xpath == NULL)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Invalid parameter to
virXPathString()"));
+ return NULL;
+ }
+ 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)) {
+ xmlXPathFreeObject(obj);
+ return NULL;
+ }
+ ret = strdup((char *) obj->stringval);
+ xmlXPathFreeObject(obj);
+ if (ret == NULL) {
+ virReportOOMError();
+ }
+ return ret;
+}
+
+/**
+ * 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 *
+virXPathStringLimit(const char *xpath,
+ size_t maxlen,
+ xmlXPathContextPtr ctxt)
+{
+ char *tmp = virXPathString(xpath, ctxt);
+
+ if (tmp != NULL && strlen(tmp) >= maxlen) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("\'%s\' value longer than %zu bytes"),
+ xpath, maxlen);
+ VIR_FREE(tmp);
+ return NULL;
+ }
+
+ return tmp;
+}
+
+/**
+ * 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
+virXPathNumber(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ double *value)
+{
+ xmlXPathObjectPtr obj;
+ xmlNodePtr relnode;
+
+ if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Invalid parameter to
virXPathNumber()"));
+ return -1;
+ }
+ relnode = ctxt->node;
+ obj = xmlXPathEval(BAD_CAST xpath, ctxt);
+ ctxt->node = relnode;
+ if ((obj == NULL) || (obj->type != XPATH_NUMBER) ||
+ (isnan(obj->floatval))) {
+ xmlXPathFreeObject(obj);
+ return -1;
+ }
+
+ *value = obj->floatval;
+ xmlXPathFreeObject(obj);
+ return 0;
+}
+
+static int
+virXPathLongBase(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ int base,
+ long *value)
+{
+ xmlXPathObjectPtr obj;
+ xmlNodePtr relnode;
+ int ret = 0;
+
+ if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Invalid parameter to
virXPathLong()"));
+ 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)) {
+ if (virStrToLong_l((char *) obj->stringval, NULL, base, value) < 0)
+ ret = -2;
+ } else if ((obj != NULL) && (obj->type == XPATH_NUMBER) &&
+ (!(isnan(obj->floatval)))) {
+ *value = (long) obj->floatval;
+ if (*value != obj->floatval) {
+ ret = -2;
+ }
+ } else {
+ ret = -1;
+ }
+
+ xmlXPathFreeObject(obj);
+ return ret;
+}
+
+/**
+ * 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;
+}
+
+/**
+ * virXPathLong:
+ * @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
+virXPathLong(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ long *value)
+{
+ return virXPathLongBase(xpath, ctxt, 10, value);
+}
+
+/**
+ * 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
+virXPathLongHex(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ long *value)
+{
+ return virXPathLongBase(xpath, ctxt, 16, value);
+}
+
+static int
+virXPathULongBase(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ int base,
+ unsigned long *value)
+{
+ xmlXPathObjectPtr obj;
+ xmlNodePtr relnode;
+ int ret = 0;
+
+ if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Invalid parameter to
virXPathULong()"));
+ 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)) {
+ if (virStrToLong_ul((char *) obj->stringval, NULL, base, value) < 0)
+ ret = -2;
+ } 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;
+}
+
+/**
+ * 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;
+}
+
+/**
+ * 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
+virXPathULong(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ unsigned long *value)
+{
+ return virXPathULongBase(xpath, ctxt, 10, value);
+}
+
+/**
+ * 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
+virXPathULongHex(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ unsigned long *value)
+{
+ return virXPathULongBase(xpath, ctxt, 16, value);
+}
+
+/**
+ * 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
+virXPathULongLong(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ unsigned long long *value)
+{
+ xmlXPathObjectPtr obj;
+ xmlNodePtr relnode;
+ int ret = 0;
+
+ if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Invalid parameter to
virXPathULong()"));
+ 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)) {
+ if (virStrToLong_ull((char *) obj->stringval, NULL, 10, value) < 0)
+ ret = -2;
+ } 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;
+}
+
+/**
+ * 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)) {
+ virReportError(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)) {
+ if (virStrToLong_ll((char *) obj->stringval, NULL, 10, value) < 0)
+ ret = -2;
+ } 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;
+}
+
+char *
+virXMLPropString(xmlNodePtr node,
+ const char *name)
+{
+ return (char *)xmlGetProp(node, BAD_CAST name);
+}
+
+/**
+ * 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
+virXPathBoolean(const char *xpath,
+ xmlXPathContextPtr ctxt)
+{
+ xmlXPathObjectPtr obj;
+ xmlNodePtr relnode;
+ int ret;
+
+ if ((ctxt == NULL) || (xpath == NULL)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Invalid parameter to
virXPathBoolean()"));
+ return -1;
+ }
+ relnode = ctxt->node;
+ obj = xmlXPathEval(BAD_CAST xpath, ctxt);
+ ctxt->node = relnode;
+ if ((obj == NULL) || (obj->type != XPATH_BOOLEAN) ||
+ (obj->boolval < 0) || (obj->boolval > 1)) {
+ xmlXPathFreeObject(obj);
+ return -1;
+ }
+ ret = obj->boolval;
+
+ xmlXPathFreeObject(obj);
+ return ret;
+}
+
+/**
+ * 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
+virXPathNode(const char *xpath,
+ xmlXPathContextPtr ctxt)
+{
+ xmlXPathObjectPtr obj;
+ xmlNodePtr relnode;
+ xmlNodePtr ret;
+
+ if ((ctxt == NULL) || (xpath == NULL)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Invalid parameter to
virXPathNode()"));
+ return NULL;
+ }
+ relnode = ctxt->node;
+ obj = xmlXPathEval(BAD_CAST xpath, ctxt);
+ ctxt->node = relnode;
+ if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
+ (obj->nodesetval == NULL) || (obj->nodesetval->nodeNr <= 0) ||
+ (obj->nodesetval->nodeTab == NULL)) {
+ xmlXPathFreeObject(obj);
+ return NULL;
+ }
+
+ ret = obj->nodesetval->nodeTab[0];
+ xmlXPathFreeObject(obj);
+ return ret;
+}
+
+/**
+ * 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
+virXPathNodeSet(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ xmlNodePtr **list)
+{
+ xmlXPathObjectPtr obj;
+ xmlNodePtr relnode;
+ int ret;
+
+ if ((ctxt == NULL) || (xpath == NULL)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Invalid parameter to
virXPathNodeSet()"));
+ return -1;
+ }
+
+ if (list != NULL)
+ *list = NULL;
+
+ relnode = ctxt->node;
+ obj = xmlXPathEval(BAD_CAST xpath, ctxt);
+ ctxt->node = relnode;
+ if (obj == NULL)
+ return 0;
+
+ if (obj->type != XPATH_NODESET) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Incorrect xpath '%s'"), xpath);
+ xmlXPathFreeObject(obj);
+ return -1;
+ }
+
+ if ((obj->nodesetval == NULL) || (obj->nodesetval->nodeNr < 0)) {
+ xmlXPathFreeObject(obj);
+ return 0;
+ }
+
+ ret = obj->nodesetval->nodeNr;
+ if (list != NULL && ret) {
+ if (VIR_ALLOC_N(*list, ret) < 0) {
+ virReportOOMError();
+ ret = -1;
+ } else {
+ memcpy(*list, obj->nodesetval->nodeTab,
+ ret * sizeof(xmlNodePtr));
+ }
+ }
+ xmlXPathFreeObject(obj);
+ return ret;
+}
+
+
+/**
+ * catchXMLError:
+ *
+ * Called from SAX on parsing errors in the XML.
+ *
+ * This version is heavily based on xmlParserPrintFileContextInternal from libxml2.
+ */
+static void
+catchXMLError(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...)
+{
+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+
+ const xmlChar *cur, *base;
+ unsigned int n, col; /* GCC warns if signed, because compared with sizeof() */
+ int domcode = VIR_FROM_XML;
+
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ char *contextstr = NULL;
+ char *pointerstr = NULL;
+
+
+ /* conditions for error printing */
+ if (!ctxt ||
+ (virGetLastError() != NULL) ||
+ ctxt->input == NULL ||
+ ctxt->lastError.level != XML_ERR_FATAL ||
+ ctxt->lastError.message == NULL)
+ return;
+
+ if (ctxt->_private)
+ domcode = ((struct virParserData *) ctxt->_private)->domcode;
+
+
+ cur = ctxt->input->cur;
+ base = ctxt->input->base;
+
+ /* skip backwards over any end-of-lines */
+ while ((cur > base) && ((*(cur) == '\n') || (*(cur) ==
'\r'))) {
+ cur--;
+ }
+
+ /* search backwards for beginning-of-line (to max buff size) */
+ while ((cur > base) && (*(cur) != '\n') && (*(cur) !=
'\r'))
+ cur--;
+ if ((*(cur) == '\n') || (*(cur) == '\r')) cur++;
+
+ /* calculate the error position in terms of the current position */
+ col = ctxt->input->cur - cur;
+
+ /* search forward for end-of-line (to max buff size) */
+ /* copy selected text to our buffer */
+ while ((*cur != 0) && (*(cur) != '\n') && (*(cur) !=
'\r')) {
+ virBufferAddChar(&buf, *cur++);
+ }
+
+ /* create blank line with problem pointer */
+ contextstr = virBufferContentAndReset(&buf);
+
+ /* (leave buffer space for pointer + line terminator) */
+ for (n = 0; (n<col) && (contextstr[n] != 0); n++) {
+ if (contextstr[n] == '\t')
+ virBufferAddChar(&buf, '\t');
+ else
+ virBufferAddChar(&buf, '-');
+ }
+
+ virBufferAddChar(&buf, '^');
+
+ pointerstr = virBufferContentAndReset(&buf);
+
+ if (ctxt->lastError.file) {
+ virGenericReportError(domcode, VIR_ERR_XML_DETAIL,
+ _("%s:%d: %s%s\n%s"),
+ ctxt->lastError.file,
+ ctxt->lastError.line,
+ ctxt->lastError.message,
+ contextstr,
+ pointerstr);
+ } else {
+ virGenericReportError(domcode, VIR_ERR_XML_DETAIL,
+ _("at line %d: %s%s\n%s"),
+ ctxt->lastError.line,
+ ctxt->lastError.message,
+ contextstr,
+ pointerstr);
+ }
+
+ VIR_FREE(contextstr);
+ VIR_FREE(pointerstr);
+}
+
+/**
+ * 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
+ * @ctxt: optional pointer to populate with new context pointer
+ *
+ * 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,
+ xmlXPathContextPtr *ctxt)
+{
+ 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) {
+ virReportOOMError();
+ 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;
+ }
+
+ if (ctxt) {
+ *ctxt = xmlXPathNewContext(xml);
+ if (!*ctxt) {
+ virReportOOMError();
+ goto error;
+ }
+ (*ctxt)->node = xmlDocGetRootElement(xml);
+ }
+
+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;
+}
+
+const char *virXMLPickShellSafeComment(const char *str1, const char *str2)
+{
+ if (str1 && !strpbrk(str1, "\r\t\n
!\"#$&'()*;<>?[\\]^`{|}~") &&
+ !strstr(str1, "--"))
+ return str1;
+ if (str2 && !strpbrk(str2, "\r\t\n
!\"#$&'()*;<>?[\\]^`{|}~") &&
+ !strstr(str2, "--"))
+ return str2;
+ return NULL;
+}
+
+static int virXMLEmitWarning(int fd,
+ const char *name,
+ const char *cmd)
+{
+ size_t len;
+ const char *prologue =
+ "<!--\n"
+ "WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO
BE\n"
+ "OVERWRITTEN AND LOST. Changes to this xml configuration should be made
using:\n"
+ " virsh ";
+ const char *epilogue =
+ "\n"
+ "or other application using the libvirt API.\n"
+ "-->\n\n";
+
+ if (fd < 0 || !cmd) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ len = strlen(prologue);
+ if (safewrite(fd, prologue, len) != len)
+ return -1;
+
+ len = strlen(cmd);
+ if (safewrite(fd, cmd, len) != len)
+ return -1;
+
+ if (name) {
+ if (safewrite(fd, " ", 1) != 1)
+ return -1;
+
+ len = strlen(name);
+ if (safewrite(fd, name, len) != len)
+ return -1;
+ }
+
+ len = strlen(epilogue);
+ if (safewrite(fd, epilogue, len) != len)
+ return -1;
+
+ return 0;
+}
+
+
+struct virXMLRewriteFileData {
+ const char *warnName;
+ const char *warnCommand;
+ const char *xml;
+};
+
+static int
+virXMLRewriteFile(int fd, void *opaque)
+{
+ struct virXMLRewriteFileData *data = opaque;
+
+ if (data->warnCommand) {
+ if (virXMLEmitWarning(fd, data->warnName, data->warnCommand) < 0)
+ return -1;
+ }
+
+ if (safewrite(fd, data->xml, strlen(data->xml)) < 0)
+ return -1;
+
+ return 0;
+}
+
+int
+virXMLSaveFile(const char *path,
+ const char *warnName,
+ const char *warnCommand,
+ const char *xml)
+{
+ struct virXMLRewriteFileData data = { warnName, warnCommand, xml };
+
+ return virFileRewrite(path, S_IRUSR | S_IWUSR, virXMLRewriteFile, &data);
+}
+
+/* Returns the number of children of node, or -1 on error. */
+long
+virXMLChildElementCount(xmlNodePtr node)
+{
+ long ret = 0;
+ xmlNodePtr cur = NULL;
+
+ /* xmlChildElementCount returns 0 on error, which isn't helpful;
+ * besides, it is not available in libxml2 2.6. */
+ if (!node || node->type != XML_ELEMENT_NODE)
+ return -1;
+ cur = node->children;
+ while (cur) {
+ if (cur->type == XML_ELEMENT_NODE)
+ ret++;
+ cur = cur->next;
+ }
+ return ret;
+}
diff --git a/src/util/virxml.h b/src/util/virxml.h
new file mode 100644
index 0000000..c3b05df
--- /dev/null
+++ b/src/util/virxml.h
@@ -0,0 +1,148 @@
+/*
+ * xml.h: internal definitions used for XML parsing routines.
+ */
+
+#ifndef __VIR_XML_H__
+# define __VIR_XML_H__
+
+# include "internal.h"
+
+# include <libxml/parser.h>
+# include <libxml/tree.h>
+# include <libxml/xpath.h>
+
+int virXPathBoolean(const char *xpath,
+ xmlXPathContextPtr ctxt);
+char * virXPathString(const char *xpath,
+ xmlXPathContextPtr ctxt);
+char * virXPathStringLimit(const char *xpath,
+ size_t maxlen,
+ xmlXPathContextPtr ctxt);
+int virXPathNumber(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ double *value);
+int virXPathInt(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ int *value);
+int virXPathUInt(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ unsigned int *value);
+int virXPathLong(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ long *value);
+int virXPathULong(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ unsigned long *value);
+int virXPathULongLong(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ unsigned long long *value);
+int virXPathLongLong(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ long long *value);
+int virXPathLongHex(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ long *value);
+int virXPathULongHex(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ unsigned long *value);
+xmlNodePtr virXPathNode(const char *xpath,
+ xmlXPathContextPtr ctxt);
+int virXPathNodeSet(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ xmlNodePtr **list);
+char * virXMLPropString(xmlNodePtr node,
+ const char *name);
+long virXMLChildElementCount(xmlNodePtr node);
+
+/* Internal function; prefer the macros below. */
+xmlDocPtr virXMLParseHelper(int domcode,
+ const char *filename,
+ const char *xmlStr,
+ const char *url,
+ xmlXPathContextPtr *pctxt);
+
+const char *virXMLPickShellSafeComment(const char *str1, const char *str2);
+/**
+ * virXMLParse:
+ * @filename: file to parse, or NULL for string parsing
+ * @xmlStr: if @filename is NULL, a string to parse
+ * @url: if @filename is NULL, an optional filename to attribute the parse to
+ *
+ * Parse xml from either a file or a string.
+ *
+ * Return the parsed document object, or NULL on failure.
+ */
+# define virXMLParse(filename, xmlStr, url) \
+ virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, NULL)
+
+/**
+ * virXMLParseString:
+ * @xmlStr: a string to parse
+ * @url: an optional filename to attribute the parse to
+ *
+ * Parse xml from a string.
+ *
+ * Return the parsed document object, or NULL on failure.
+ */
+# define virXMLParseString(xmlStr, url) \
+ virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, NULL)
+
+/**
+ * virXMLParseFile:
+ * @filename: file to parse
+ *
+ * Parse xml from a file.
+ *
+ * Return the parsed document object, or NULL on failure.
+ */
+# define virXMLParseFile(filename) \
+ virXMLParseHelper(VIR_FROM_THIS, filename, NULL, NULL, NULL)
+
+/**
+ * virXMLParseCtxt:
+ * @filename: file to parse, or NULL for string parsing
+ * @xmlStr: if @filename is NULL, a string to parse
+ * @url: if @filename is NULL, an optional filename to attribute the parse to
+ * @pctxt: if non-NULL, populate with a new context object on success,
+ * with (*pctxt)->node pre-set to the root node
+ *
+ * Parse xml from either a file or a string.
+ *
+ * Return the parsed document object, or NULL on failure.
+ */
+# define virXMLParseCtxt(filename, xmlStr, url, pctxt) \
+ virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, pctxt)
+
+/**
+ * virXMLParseStringCtxt:
+ * @xmlStr: a string to parse
+ * @url: an optional filename to attribute the parse to
+ * @pctxt: if non-NULL, populate with a new context object on success,
+ * with (*pctxt)->node pre-set to the root node
+ *
+ * Parse xml from a string.
+ *
+ * Return the parsed document object, or NULL on failure.
+ */
+# define virXMLParseStringCtxt(xmlStr, url, pctxt) \
+ virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, pctxt)
+
+/**
+ * virXMLParseFileCtxt:
+ * @filename: file to parse
+ * @pctxt: if non-NULL, populate with a new context object on success,
+ * with (*pctxt)->node pre-set to the root node
+ *
+ * Parse xml from a file.
+ *
+ * Return the parsed document object, or NULL on failure.
+ */
+# define virXMLParseFileCtxt(filename, pctxt) \
+ virXMLParseHelper(VIR_FROM_THIS, filename, NULL, NULL, pctxt)
+
+int virXMLSaveFile(const char *path,
+ const char *warnName,
+ const char *warnCommand,
+ const char *xml);
+
+#endif /* __VIR_XML_H__ */
diff --git a/src/util/xml.c b/src/util/xml.c
deleted file mode 100644
index 05c7f33..0000000
--- a/src/util/xml.c
+++ /dev/null
@@ -1,890 +0,0 @@
-/*
- * xml.c: XML based interfaces for the libvir library
- *
- * Copyright (C) 2005, 2007-2012 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see
- * <
http://www.gnu.org/licenses/>.
- *
- * Daniel Veillard <veillard(a)redhat.com>
- */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <limits.h>
-#include <math.h> /* for isnan() */
-#include <sys/stat.h>
-
-#include "virterror_internal.h"
-#include "xml.h"
-#include "virbuffer.h"
-#include "virutil.h"
-#include "viralloc.h"
-#include "virfile.h"
-
-#define VIR_FROM_THIS VIR_FROM_XML
-
-#define virGenericReportError(from, code, ...) \
- virReportErrorHelper(from, code, __FILE__, \
- __FUNCTION__, __LINE__, __VA_ARGS__)
-
-/* Internal data to be passed to SAX parser and used by error handler. */
-struct virParserData {
- int domcode;
-};
-
-
-/************************************************************************
- * *
- * Wrappers around libxml2 XPath specific functions *
- * *
- ************************************************************************/
-
-/**
- * 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 *
-virXPathString(const char *xpath,
- xmlXPathContextPtr ctxt)
-{
- xmlXPathObjectPtr obj;
- xmlNodePtr relnode;
- char *ret;
-
- if ((ctxt == NULL) || (xpath == NULL)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Invalid parameter to
virXPathString()"));
- return NULL;
- }
- 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)) {
- xmlXPathFreeObject(obj);
- return NULL;
- }
- ret = strdup((char *) obj->stringval);
- xmlXPathFreeObject(obj);
- if (ret == NULL) {
- virReportOOMError();
- }
- return ret;
-}
-
-/**
- * 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 *
-virXPathStringLimit(const char *xpath,
- size_t maxlen,
- xmlXPathContextPtr ctxt)
-{
- char *tmp = virXPathString(xpath, ctxt);
-
- if (tmp != NULL && strlen(tmp) >= maxlen) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("\'%s\' value longer than %zu bytes"),
- xpath, maxlen);
- VIR_FREE(tmp);
- return NULL;
- }
-
- return tmp;
-}
-
-/**
- * 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
-virXPathNumber(const char *xpath,
- xmlXPathContextPtr ctxt,
- double *value)
-{
- xmlXPathObjectPtr obj;
- xmlNodePtr relnode;
-
- if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Invalid parameter to
virXPathNumber()"));
- return -1;
- }
- relnode = ctxt->node;
- obj = xmlXPathEval(BAD_CAST xpath, ctxt);
- ctxt->node = relnode;
- if ((obj == NULL) || (obj->type != XPATH_NUMBER) ||
- (isnan(obj->floatval))) {
- xmlXPathFreeObject(obj);
- return -1;
- }
-
- *value = obj->floatval;
- xmlXPathFreeObject(obj);
- return 0;
-}
-
-static int
-virXPathLongBase(const char *xpath,
- xmlXPathContextPtr ctxt,
- int base,
- long *value)
-{
- xmlXPathObjectPtr obj;
- xmlNodePtr relnode;
- int ret = 0;
-
- if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Invalid parameter to
virXPathLong()"));
- 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)) {
- if (virStrToLong_l((char *) obj->stringval, NULL, base, value) < 0)
- ret = -2;
- } else if ((obj != NULL) && (obj->type == XPATH_NUMBER) &&
- (!(isnan(obj->floatval)))) {
- *value = (long) obj->floatval;
- if (*value != obj->floatval) {
- ret = -2;
- }
- } else {
- ret = -1;
- }
-
- xmlXPathFreeObject(obj);
- return ret;
-}
-
-/**
- * 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;
-}
-
-/**
- * virXPathLong:
- * @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
-virXPathLong(const char *xpath,
- xmlXPathContextPtr ctxt,
- long *value)
-{
- return virXPathLongBase(xpath, ctxt, 10, value);
-}
-
-/**
- * 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
-virXPathLongHex(const char *xpath,
- xmlXPathContextPtr ctxt,
- long *value)
-{
- return virXPathLongBase(xpath, ctxt, 16, value);
-}
-
-static int
-virXPathULongBase(const char *xpath,
- xmlXPathContextPtr ctxt,
- int base,
- unsigned long *value)
-{
- xmlXPathObjectPtr obj;
- xmlNodePtr relnode;
- int ret = 0;
-
- if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Invalid parameter to
virXPathULong()"));
- 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)) {
- if (virStrToLong_ul((char *) obj->stringval, NULL, base, value) < 0)
- ret = -2;
- } 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;
-}
-
-/**
- * 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;
-}
-
-/**
- * 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
-virXPathULong(const char *xpath,
- xmlXPathContextPtr ctxt,
- unsigned long *value)
-{
- return virXPathULongBase(xpath, ctxt, 10, value);
-}
-
-/**
- * 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
-virXPathULongHex(const char *xpath,
- xmlXPathContextPtr ctxt,
- unsigned long *value)
-{
- return virXPathULongBase(xpath, ctxt, 16, value);
-}
-
-/**
- * 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
-virXPathULongLong(const char *xpath,
- xmlXPathContextPtr ctxt,
- unsigned long long *value)
-{
- xmlXPathObjectPtr obj;
- xmlNodePtr relnode;
- int ret = 0;
-
- if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Invalid parameter to
virXPathULong()"));
- 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)) {
- if (virStrToLong_ull((char *) obj->stringval, NULL, 10, value) < 0)
- ret = -2;
- } 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;
-}
-
-/**
- * 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)) {
- virReportError(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)) {
- if (virStrToLong_ll((char *) obj->stringval, NULL, 10, value) < 0)
- ret = -2;
- } 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;
-}
-
-char *
-virXMLPropString(xmlNodePtr node,
- const char *name)
-{
- return (char *)xmlGetProp(node, BAD_CAST name);
-}
-
-/**
- * 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
-virXPathBoolean(const char *xpath,
- xmlXPathContextPtr ctxt)
-{
- xmlXPathObjectPtr obj;
- xmlNodePtr relnode;
- int ret;
-
- if ((ctxt == NULL) || (xpath == NULL)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Invalid parameter to
virXPathBoolean()"));
- return -1;
- }
- relnode = ctxt->node;
- obj = xmlXPathEval(BAD_CAST xpath, ctxt);
- ctxt->node = relnode;
- if ((obj == NULL) || (obj->type != XPATH_BOOLEAN) ||
- (obj->boolval < 0) || (obj->boolval > 1)) {
- xmlXPathFreeObject(obj);
- return -1;
- }
- ret = obj->boolval;
-
- xmlXPathFreeObject(obj);
- return ret;
-}
-
-/**
- * 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
-virXPathNode(const char *xpath,
- xmlXPathContextPtr ctxt)
-{
- xmlXPathObjectPtr obj;
- xmlNodePtr relnode;
- xmlNodePtr ret;
-
- if ((ctxt == NULL) || (xpath == NULL)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Invalid parameter to
virXPathNode()"));
- return NULL;
- }
- relnode = ctxt->node;
- obj = xmlXPathEval(BAD_CAST xpath, ctxt);
- ctxt->node = relnode;
- if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
- (obj->nodesetval == NULL) || (obj->nodesetval->nodeNr <= 0) ||
- (obj->nodesetval->nodeTab == NULL)) {
- xmlXPathFreeObject(obj);
- return NULL;
- }
-
- ret = obj->nodesetval->nodeTab[0];
- xmlXPathFreeObject(obj);
- return ret;
-}
-
-/**
- * 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
-virXPathNodeSet(const char *xpath,
- xmlXPathContextPtr ctxt,
- xmlNodePtr **list)
-{
- xmlXPathObjectPtr obj;
- xmlNodePtr relnode;
- int ret;
-
- if ((ctxt == NULL) || (xpath == NULL)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Invalid parameter to
virXPathNodeSet()"));
- return -1;
- }
-
- if (list != NULL)
- *list = NULL;
-
- relnode = ctxt->node;
- obj = xmlXPathEval(BAD_CAST xpath, ctxt);
- ctxt->node = relnode;
- if (obj == NULL)
- return 0;
-
- if (obj->type != XPATH_NODESET) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Incorrect xpath '%s'"), xpath);
- xmlXPathFreeObject(obj);
- return -1;
- }
-
- if ((obj->nodesetval == NULL) || (obj->nodesetval->nodeNr < 0)) {
- xmlXPathFreeObject(obj);
- return 0;
- }
-
- ret = obj->nodesetval->nodeNr;
- if (list != NULL && ret) {
- if (VIR_ALLOC_N(*list, ret) < 0) {
- virReportOOMError();
- ret = -1;
- } else {
- memcpy(*list, obj->nodesetval->nodeTab,
- ret * sizeof(xmlNodePtr));
- }
- }
- xmlXPathFreeObject(obj);
- return ret;
-}
-
-
-/**
- * catchXMLError:
- *
- * Called from SAX on parsing errors in the XML.
- *
- * This version is heavily based on xmlParserPrintFileContextInternal from libxml2.
- */
-static void
-catchXMLError(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-
- const xmlChar *cur, *base;
- unsigned int n, col; /* GCC warns if signed, because compared with sizeof() */
- int domcode = VIR_FROM_XML;
-
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- char *contextstr = NULL;
- char *pointerstr = NULL;
-
-
- /* conditions for error printing */
- if (!ctxt ||
- (virGetLastError() != NULL) ||
- ctxt->input == NULL ||
- ctxt->lastError.level != XML_ERR_FATAL ||
- ctxt->lastError.message == NULL)
- return;
-
- if (ctxt->_private)
- domcode = ((struct virParserData *) ctxt->_private)->domcode;
-
-
- cur = ctxt->input->cur;
- base = ctxt->input->base;
-
- /* skip backwards over any end-of-lines */
- while ((cur > base) && ((*(cur) == '\n') || (*(cur) ==
'\r'))) {
- cur--;
- }
-
- /* search backwards for beginning-of-line (to max buff size) */
- while ((cur > base) && (*(cur) != '\n') && (*(cur) !=
'\r'))
- cur--;
- if ((*(cur) == '\n') || (*(cur) == '\r')) cur++;
-
- /* calculate the error position in terms of the current position */
- col = ctxt->input->cur - cur;
-
- /* search forward for end-of-line (to max buff size) */
- /* copy selected text to our buffer */
- while ((*cur != 0) && (*(cur) != '\n') && (*(cur) !=
'\r')) {
- virBufferAddChar(&buf, *cur++);
- }
-
- /* create blank line with problem pointer */
- contextstr = virBufferContentAndReset(&buf);
-
- /* (leave buffer space for pointer + line terminator) */
- for (n = 0; (n<col) && (contextstr[n] != 0); n++) {
- if (contextstr[n] == '\t')
- virBufferAddChar(&buf, '\t');
- else
- virBufferAddChar(&buf, '-');
- }
-
- virBufferAddChar(&buf, '^');
-
- pointerstr = virBufferContentAndReset(&buf);
-
- if (ctxt->lastError.file) {
- virGenericReportError(domcode, VIR_ERR_XML_DETAIL,
- _("%s:%d: %s%s\n%s"),
- ctxt->lastError.file,
- ctxt->lastError.line,
- ctxt->lastError.message,
- contextstr,
- pointerstr);
- } else {
- virGenericReportError(domcode, VIR_ERR_XML_DETAIL,
- _("at line %d: %s%s\n%s"),
- ctxt->lastError.line,
- ctxt->lastError.message,
- contextstr,
- pointerstr);
- }
-
- VIR_FREE(contextstr);
- VIR_FREE(pointerstr);
-}
-
-/**
- * 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
- * @ctxt: optional pointer to populate with new context pointer
- *
- * 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,
- xmlXPathContextPtr *ctxt)
-{
- 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) {
- virReportOOMError();
- 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;
- }
-
- if (ctxt) {
- *ctxt = xmlXPathNewContext(xml);
- if (!*ctxt) {
- virReportOOMError();
- goto error;
- }
- (*ctxt)->node = xmlDocGetRootElement(xml);
- }
-
-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;
-}
-
-const char *virXMLPickShellSafeComment(const char *str1, const char *str2)
-{
- if (str1 && !strpbrk(str1, "\r\t\n
!\"#$&'()*;<>?[\\]^`{|}~") &&
- !strstr(str1, "--"))
- return str1;
- if (str2 && !strpbrk(str2, "\r\t\n
!\"#$&'()*;<>?[\\]^`{|}~") &&
- !strstr(str2, "--"))
- return str2;
- return NULL;
-}
-
-static int virXMLEmitWarning(int fd,
- const char *name,
- const char *cmd)
-{
- size_t len;
- const char *prologue =
- "<!--\n"
- "WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO
BE\n"
- "OVERWRITTEN AND LOST. Changes to this xml configuration should be made
using:\n"
- " virsh ";
- const char *epilogue =
- "\n"
- "or other application using the libvirt API.\n"
- "-->\n\n";
-
- if (fd < 0 || !cmd) {
- errno = EINVAL;
- return -1;
- }
-
- len = strlen(prologue);
- if (safewrite(fd, prologue, len) != len)
- return -1;
-
- len = strlen(cmd);
- if (safewrite(fd, cmd, len) != len)
- return -1;
-
- if (name) {
- if (safewrite(fd, " ", 1) != 1)
- return -1;
-
- len = strlen(name);
- if (safewrite(fd, name, len) != len)
- return -1;
- }
-
- len = strlen(epilogue);
- if (safewrite(fd, epilogue, len) != len)
- return -1;
-
- return 0;
-}
-
-
-struct virXMLRewriteFileData {
- const char *warnName;
- const char *warnCommand;
- const char *xml;
-};
-
-static int
-virXMLRewriteFile(int fd, void *opaque)
-{
- struct virXMLRewriteFileData *data = opaque;
-
- if (data->warnCommand) {
- if (virXMLEmitWarning(fd, data->warnName, data->warnCommand) < 0)
- return -1;
- }
-
- if (safewrite(fd, data->xml, strlen(data->xml)) < 0)
- return -1;
-
- return 0;
-}
-
-int
-virXMLSaveFile(const char *path,
- const char *warnName,
- const char *warnCommand,
- const char *xml)
-{
- struct virXMLRewriteFileData data = { warnName, warnCommand, xml };
-
- return virFileRewrite(path, S_IRUSR | S_IWUSR, virXMLRewriteFile, &data);
-}
-
-/* Returns the number of children of node, or -1 on error. */
-long
-virXMLChildElementCount(xmlNodePtr node)
-{
- long ret = 0;
- xmlNodePtr cur = NULL;
-
- /* xmlChildElementCount returns 0 on error, which isn't helpful;
- * besides, it is not available in libxml2 2.6. */
- if (!node || node->type != XML_ELEMENT_NODE)
- return -1;
- cur = node->children;
- while (cur) {
- if (cur->type == XML_ELEMENT_NODE)
- ret++;
- cur = cur->next;
- }
- return ret;
-}
diff --git a/src/util/xml.h b/src/util/xml.h
deleted file mode 100644
index c3b05df..0000000
--- a/src/util/xml.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * xml.h: internal definitions used for XML parsing routines.
- */
-
-#ifndef __VIR_XML_H__
-# define __VIR_XML_H__
-
-# include "internal.h"
-
-# include <libxml/parser.h>
-# include <libxml/tree.h>
-# include <libxml/xpath.h>
-
-int virXPathBoolean(const char *xpath,
- xmlXPathContextPtr ctxt);
-char * virXPathString(const char *xpath,
- xmlXPathContextPtr ctxt);
-char * virXPathStringLimit(const char *xpath,
- size_t maxlen,
- xmlXPathContextPtr ctxt);
-int virXPathNumber(const char *xpath,
- xmlXPathContextPtr ctxt,
- double *value);
-int virXPathInt(const char *xpath,
- xmlXPathContextPtr ctxt,
- int *value);
-int virXPathUInt(const char *xpath,
- xmlXPathContextPtr ctxt,
- unsigned int *value);
-int virXPathLong(const char *xpath,
- xmlXPathContextPtr ctxt,
- long *value);
-int virXPathULong(const char *xpath,
- xmlXPathContextPtr ctxt,
- unsigned long *value);
-int virXPathULongLong(const char *xpath,
- xmlXPathContextPtr ctxt,
- unsigned long long *value);
-int virXPathLongLong(const char *xpath,
- xmlXPathContextPtr ctxt,
- long long *value);
-int virXPathLongHex(const char *xpath,
- xmlXPathContextPtr ctxt,
- long *value);
-int virXPathULongHex(const char *xpath,
- xmlXPathContextPtr ctxt,
- unsigned long *value);
-xmlNodePtr virXPathNode(const char *xpath,
- xmlXPathContextPtr ctxt);
-int virXPathNodeSet(const char *xpath,
- xmlXPathContextPtr ctxt,
- xmlNodePtr **list);
-char * virXMLPropString(xmlNodePtr node,
- const char *name);
-long virXMLChildElementCount(xmlNodePtr node);
-
-/* Internal function; prefer the macros below. */
-xmlDocPtr virXMLParseHelper(int domcode,
- const char *filename,
- const char *xmlStr,
- const char *url,
- xmlXPathContextPtr *pctxt);
-
-const char *virXMLPickShellSafeComment(const char *str1, const char *str2);
-/**
- * virXMLParse:
- * @filename: file to parse, or NULL for string parsing
- * @xmlStr: if @filename is NULL, a string to parse
- * @url: if @filename is NULL, an optional filename to attribute the parse to
- *
- * Parse xml from either a file or a string.
- *
- * Return the parsed document object, or NULL on failure.
- */
-# define virXMLParse(filename, xmlStr, url) \
- virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, NULL)
-
-/**
- * virXMLParseString:
- * @xmlStr: a string to parse
- * @url: an optional filename to attribute the parse to
- *
- * Parse xml from a string.
- *
- * Return the parsed document object, or NULL on failure.
- */
-# define virXMLParseString(xmlStr, url) \
- virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, NULL)
-
-/**
- * virXMLParseFile:
- * @filename: file to parse
- *
- * Parse xml from a file.
- *
- * Return the parsed document object, or NULL on failure.
- */
-# define virXMLParseFile(filename) \
- virXMLParseHelper(VIR_FROM_THIS, filename, NULL, NULL, NULL)
-
-/**
- * virXMLParseCtxt:
- * @filename: file to parse, or NULL for string parsing
- * @xmlStr: if @filename is NULL, a string to parse
- * @url: if @filename is NULL, an optional filename to attribute the parse to
- * @pctxt: if non-NULL, populate with a new context object on success,
- * with (*pctxt)->node pre-set to the root node
- *
- * Parse xml from either a file or a string.
- *
- * Return the parsed document object, or NULL on failure.
- */
-# define virXMLParseCtxt(filename, xmlStr, url, pctxt) \
- virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, pctxt)
-
-/**
- * virXMLParseStringCtxt:
- * @xmlStr: a string to parse
- * @url: an optional filename to attribute the parse to
- * @pctxt: if non-NULL, populate with a new context object on success,
- * with (*pctxt)->node pre-set to the root node
- *
- * Parse xml from a string.
- *
- * Return the parsed document object, or NULL on failure.
- */
-# define virXMLParseStringCtxt(xmlStr, url, pctxt) \
- virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, pctxt)
-
-/**
- * virXMLParseFileCtxt:
- * @filename: file to parse
- * @pctxt: if non-NULL, populate with a new context object on success,
- * with (*pctxt)->node pre-set to the root node
- *
- * Parse xml from a file.
- *
- * Return the parsed document object, or NULL on failure.
- */
-# define virXMLParseFileCtxt(filename, pctxt) \
- virXMLParseHelper(VIR_FROM_THIS, filename, NULL, NULL, pctxt)
-
-int virXMLSaveFile(const char *path,
- const char *warnName,
- const char *warnCommand,
- const char *xml);
-
-#endif /* __VIR_XML_H__ */
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index 4cbe827..c35695a 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -53,7 +53,7 @@
#if WITH_XEN_INOTIFY
# include "xen_inotify.h"
#endif
-#include "xml.h"
+#include "virxml.h"
#include "virutil.h"
#include "viralloc.h"
#include "node_device_conf.h"
diff --git a/tests/cputest.c b/tests/cputest.c
index ee1a608..6505367 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -31,7 +31,7 @@
#include <fcntl.h>
#include "internal.h"
-#include "xml.h"
+#include "virxml.h"
#include "viralloc.h"
#include "virbuffer.h"
#include "testutils.h"
diff --git a/tests/nwfilterxml2xmltest.c b/tests/nwfilterxml2xmltest.c
index 8c29a46..a215bf8 100644
--- a/tests/nwfilterxml2xmltest.c
+++ b/tests/nwfilterxml2xmltest.c
@@ -10,7 +10,7 @@
#include "internal.h"
#include "testutils.h"
-#include "xml.h"
+#include "virxml.h"
#include "virthread.h"
#include "nwfilter_params.h"
#include "nwfilter_conf.h"
diff --git a/tests/sexpr2xmltest.c b/tests/sexpr2xmltest.c
index 9b9b09d..07f6f8e 100644
--- a/tests/sexpr2xmltest.c
+++ b/tests/sexpr2xmltest.c
@@ -5,7 +5,7 @@
#include <unistd.h>
#include "internal.h"
-#include "xml.h"
+#include "virxml.h"
#include "datatypes.h"
#include "xen/xen_driver.h"
#include "xen/xend_internal.h"
diff --git a/tests/virshtest.c b/tests/virshtest.c
index 8741d47..b82a4c4 100644
--- a/tests/virshtest.c
+++ b/tests/virshtest.c
@@ -5,7 +5,7 @@
#include <unistd.h>
#include "internal.h"
-#include "xml.h"
+#include "virxml.h"
#include "virutil.h"
#include "testutils.h"
diff --git a/tests/xencapstest.c b/tests/xencapstest.c
index 387e278..b3f7d62 100644
--- a/tests/xencapstest.c
+++ b/tests/xencapstest.c
@@ -6,7 +6,7 @@
#include <unistd.h>
#include "internal.h"
-#include "xml.h"
+#include "virxml.h"
#include "testutils.h"
#include "xen/xen_hypervisor.h"
#include "virfile.h"
diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index a443988..f4940fa 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -37,7 +37,7 @@
#include "viralloc.h"
#include "virmacaddr.h"
#include "virsh-domain.h"
-#include "xml.h"
+#include "virxml.h"
static const char *
vshDomainIOErrorToString(int error)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 244ffb8..3a9cebe 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -51,7 +51,7 @@
#include "virsh-domain-monitor.h"
#include "virterror_internal.h"
#include "virtypedparam.h"
-#include "xml.h"
+#include "virxml.h"
/* Gnulib doesn't guarantee SA_SIGINFO support. */
#ifndef SA_SIGINFO
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index 0ad4296..45b89a8 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -36,7 +36,7 @@
#include "viralloc.h"
#include "virutil.h"
#include "virsh-domain.h"
-#include "xml.h"
+#include "virxml.h"
#include "virtypedparam.h"
#include "virjson.h"
diff --git a/tools/virsh-interface.c b/tools/virsh-interface.c
index ea8a6c5..cd14e89 100644
--- a/tools/virsh-interface.c
+++ b/tools/virsh-interface.c
@@ -35,7 +35,7 @@
#include "virbuffer.h"
#include "viralloc.h"
#include "virutil.h"
-#include "xml.h"
+#include "virxml.h"
virInterfacePtr
vshCommandOptInterfaceBy(vshControl *ctl, const vshCmd *cmd,
diff --git a/tools/virsh-network.c b/tools/virsh-network.c
index 918dee6..c9cd15a 100644
--- a/tools/virsh-network.c
+++ b/tools/virsh-network.c
@@ -35,7 +35,7 @@
#include "virbuffer.h"
#include "viralloc.h"
#include "virutil.h"
-#include "xml.h"
+#include "virxml.h"
#include "conf/network_conf.h"
virNetworkPtr
diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c
index 974e495..f9517cc 100644
--- a/tools/virsh-nodedev.c
+++ b/tools/virsh-nodedev.c
@@ -35,7 +35,7 @@
#include "virbuffer.h"
#include "viralloc.h"
#include "virutil.h"
-#include "xml.h"
+#include "virxml.h"
#include "conf/node_device_conf.h"
/*
diff --git a/tools/virsh-nwfilter.c b/tools/virsh-nwfilter.c
index 1480d13..9341ea7 100644
--- a/tools/virsh-nwfilter.c
+++ b/tools/virsh-nwfilter.c
@@ -35,7 +35,7 @@
#include "virbuffer.h"
#include "viralloc.h"
#include "virutil.h"
-#include "xml.h"
+#include "virxml.h"
virNWFilterPtr
vshCommandOptNWFilterBy(vshControl *ctl, const vshCmd *cmd,
diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c
index b3177e0..adac7f1 100644
--- a/tools/virsh-pool.c
+++ b/tools/virsh-pool.c
@@ -35,7 +35,7 @@
#include "virbuffer.h"
#include "viralloc.h"
#include "virutil.h"
-#include "xml.h"
+#include "virxml.h"
#include "conf/storage_conf.h"
virStoragePoolPtr
diff --git a/tools/virsh-secret.c b/tools/virsh-secret.c
index a29454f..8297743 100644
--- a/tools/virsh-secret.c
+++ b/tools/virsh-secret.c
@@ -36,7 +36,7 @@
#include "virbuffer.h"
#include "viralloc.h"
#include "virutil.h"
-#include "xml.h"
+#include "virxml.h"
static virSecretPtr
vshCommandOptSecret(vshControl *ctl, const vshCmd *cmd, const char **name)
diff --git a/tools/virsh-snapshot.c b/tools/virsh-snapshot.c
index 8428282..3b179e2 100644
--- a/tools/virsh-snapshot.c
+++ b/tools/virsh-snapshot.c
@@ -38,7 +38,7 @@
#include "viralloc.h"
#include "virutil.h"
#include "virsh-domain.h"
-#include "xml.h"
+#include "virxml.h"
#include "conf/snapshot_conf.h"
/* Helper for snapshot-create and snapshot-create-as */
diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c
index 6f2c591..a57fc28 100644
--- a/tools/virsh-volume.c
+++ b/tools/virsh-volume.c
@@ -39,7 +39,7 @@
#include "virutil.h"
#include "virfile.h"
#include "virsh-pool.h"
-#include "xml.h"
+#include "virxml.h"
virStorageVolPtr
vshCommandOptVolBy(vshControl *ctl, const vshCmd *cmd,
diff --git a/tools/virsh.c b/tools/virsh.c
index bfeaaa1..790cf56 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -60,7 +60,7 @@
#include "console.h"
#include "virutil.h"
#include "viralloc.h"
-#include "xml.h"
+#include "virxml.h"
#include "libvirt/libvirt-qemu.h"
#include "virfile.h"
#include "configmake.h"
--
1.7.11.7