|
Packit |
a07778 |
/*
|
|
Packit |
a07778 |
* libvirt-gconfig-helpers.c: libvirt configuration helpers
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Copyright (C) 2010, 2011 Red Hat, Inc.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* This library is free software; you can redistribute it and/or
|
|
Packit |
a07778 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
a07778 |
* License as published by the Free Software Foundation; either
|
|
Packit |
a07778 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
a07778 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
a07778 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
a07778 |
* Lesser General Public License for more details.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
a07778 |
* License along with this library. If not, see
|
|
Packit |
a07778 |
* <http://www.gnu.org/licenses/>.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Authors: Daniel P. Berrange <berrange@redhat.com>
|
|
Packit |
a07778 |
* Christophe Fergeau <cfergeau@gmail.com>
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#include <config.h>
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#include <string.h>
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#include <libxml/xmlerror.h>
|
|
Packit |
a07778 |
#include <glib/gi18n-lib.h>
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#include "libvirt-gconfig/libvirt-gconfig.h"
|
|
Packit |
a07778 |
#include "libvirt-gconfig/libvirt-gconfig-helpers-private.h"
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
GQuark
|
|
Packit |
a07778 |
gvir_config_object_error_quark(void)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
return g_quark_from_static_string("gvir-config-object");
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static GError *gvir_config_error_new_literal(GQuark domain,
|
|
Packit |
a07778 |
gint code,
|
|
Packit |
a07778 |
const gchar *message)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlErrorPtr xerr = xmlGetLastError();
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!xerr)
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (message)
|
|
Packit |
a07778 |
return g_error_new(domain,
|
|
Packit |
a07778 |
code,
|
|
Packit |
a07778 |
"%s: %s",
|
|
Packit |
a07778 |
message,
|
|
Packit |
a07778 |
xerr->message);
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
return g_error_new(domain,
|
|
Packit |
a07778 |
code,
|
|
Packit |
a07778 |
"%s",
|
|
Packit |
a07778 |
xerr->message);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
GError *gvir_config_error_new(GQuark domain,
|
|
Packit |
a07778 |
gint code,
|
|
Packit |
a07778 |
const gchar *format,
|
|
Packit |
a07778 |
...)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GError *err;
|
|
Packit |
a07778 |
va_list args;
|
|
Packit |
a07778 |
gchar *message;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
va_start(args, format);
|
|
Packit |
a07778 |
message = g_strdup_vprintf(format, args);
|
|
Packit |
a07778 |
va_end(args);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
err = gvir_config_error_new_literal(domain, code, message);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_free(message);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return err;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
void gvir_config_set_error(GError **err,
|
|
Packit |
a07778 |
GQuark domain, gint code,
|
|
Packit |
a07778 |
const gchar *format, ...)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
va_list args;
|
|
Packit |
a07778 |
gchar *message;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!err)
|
|
Packit |
a07778 |
return;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
va_start(args, format);
|
|
Packit |
a07778 |
message = g_strdup_vprintf(format, args);
|
|
Packit |
a07778 |
va_end(args);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
*err = gvir_config_error_new_literal(domain, code, message);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_free(message);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
void gvir_config_set_error_literal(GError **err,
|
|
Packit |
a07778 |
GQuark domain, gint code,
|
|
Packit |
a07778 |
const gchar *message)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
if (!err)
|
|
Packit |
a07778 |
return;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
*err = gvir_config_error_new_literal(domain, code, message);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
void gvir_config_set_error_valist(GError **err,
|
|
Packit |
a07778 |
GQuark domain, gint code,
|
|
Packit |
a07778 |
const gchar *format,
|
|
Packit |
a07778 |
va_list args)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
gchar *message;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!err)
|
|
Packit |
a07778 |
return;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
message = g_strdup_vprintf(format, args);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
*err = gvir_config_error_new_literal(domain, code, message);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_free(message);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
xmlNodePtr
|
|
Packit |
a07778 |
gvir_config_xml_parse(const char *xml, const char *root_node, GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlDocPtr doc;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!xml) {
|
|
Packit |
a07778 |
*err = g_error_new(GVIR_CONFIG_OBJECT_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"%s",
|
|
Packit |
a07778 |
_("No XML document to parse"));
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
doc = xmlParseMemory(xml, strlen(xml));
|
|
Packit |
a07778 |
if (!doc) {
|
|
Packit |
a07778 |
gvir_config_set_error_literal(err, GVIR_CONFIG_OBJECT_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Unable to parse configuration"));
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
if ((!doc->children) ||
|
|
Packit |
a07778 |
((root_node != NULL) && g_strcmp0((char *)doc->children->name, root_node) != 0)) {
|
|
Packit |
a07778 |
g_set_error(err,
|
|
Packit |
a07778 |
GVIR_CONFIG_OBJECT_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("XML data has no '%s' node"),
|
|
Packit |
a07778 |
root_node);
|
|
Packit |
a07778 |
xmlFreeDoc(doc);
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return doc->children;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
void gvir_config_xml_foreach_child(xmlNodePtr node,
|
|
Packit |
a07778 |
GVirConfigXmlNodeIterator iter_func,
|
|
Packit |
a07778 |
gpointer opaque)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlNodePtr it;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(iter_func != NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
it = node->children;
|
|
Packit |
a07778 |
while (it != NULL) {
|
|
Packit |
a07778 |
gboolean cont;
|
|
Packit |
a07778 |
xmlNodePtr next = it->next;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!xmlIsBlankNode(it)) {
|
|
Packit |
a07778 |
cont = iter_func(it, opaque);
|
|
Packit |
a07778 |
if (!cont)
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
it = next;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/*
|
|
Packit |
a07778 |
* gvir_config_xml_get_element is
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Copyright (C) 2006, 2007 OpenedHand Ltd.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Author: Jorn Baayen <jorn@openedhand.com>
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
xmlNode *
|
|
Packit |
a07778 |
gvir_config_xml_get_element (xmlNode *node, ...)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
va_list var_args;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
va_start (var_args, node);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
while (TRUE) {
|
|
Packit |
a07778 |
const char *arg;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
arg = va_arg (var_args, const char *);
|
|
Packit |
a07778 |
if (!arg)
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
for (node = node->children; node; node = node->next)
|
|
Packit |
a07778 |
if (!g_strcmp0 (arg, (char *) node->name))
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!node)
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
va_end (var_args);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return node;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL const char *
|
|
Packit |
a07778 |
gvir_config_xml_get_child_element_content (xmlNode *node,
|
|
Packit |
a07778 |
const char *child_name)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlNode *child_node;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
child_node = gvir_config_xml_get_element(node, child_name, NULL);
|
|
Packit |
a07778 |
if (!child_node || !(child_node->children))
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return (const char *)child_node->children->content;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL const char *
|
|
Packit |
a07778 |
gvir_config_xml_get_attribute_content(xmlNodePtr node, const char *attr_name)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlAttr *attr;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
for (attr = node->properties; attr; attr = attr->next)
|
|
Packit |
a07778 |
if (g_strcmp0 (attr_name, (char *)attr->name) == 0)
|
|
Packit |
a07778 |
return (const char *)attr->children->content;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
const char *gvir_config_genum_get_nick (GType enum_type, gint value)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GEnumClass *enum_class;
|
|
Packit |
a07778 |
GEnumValue *enum_value;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
enum_class = g_type_class_ref(enum_type);
|
|
Packit |
a07778 |
enum_value = g_enum_get_value(enum_class, value);
|
|
Packit |
a07778 |
g_type_class_unref(enum_class);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (enum_value != NULL)
|
|
Packit |
a07778 |
return enum_value->value_nick;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_reached(NULL);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL int
|
|
Packit |
a07778 |
gvir_config_genum_get_value (GType enum_type, const char *nick,
|
|
Packit |
a07778 |
gint default_value)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GEnumClass *enum_class;
|
|
Packit |
a07778 |
GEnumValue *enum_value;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(G_TYPE_IS_ENUM(enum_type), default_value);
|
|
Packit |
a07778 |
g_return_val_if_fail(nick != NULL, default_value);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
enum_class = g_type_class_ref(enum_type);
|
|
Packit |
a07778 |
enum_value = g_enum_get_value_by_nick(enum_class, nick);
|
|
Packit |
a07778 |
g_type_class_unref(enum_class);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (enum_value != NULL)
|
|
Packit |
a07778 |
return enum_value->value;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_reached(default_value);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_GNUC_INTERNAL char *
|
|
Packit |
a07778 |
gvir_config_xml_node_to_string(xmlNodePtr node)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
xmlBufferPtr xmlbuf;
|
|
Packit |
a07778 |
char *xml;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (node == NULL)
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
xmlbuf = xmlBufferCreate();
|
|
Packit |
a07778 |
if (xmlNodeDump(xmlbuf, node->doc, node, 0, 1) < 0)
|
|
Packit |
a07778 |
xml = NULL;
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
xml = g_strndup((gchar *)xmlBufferContent(xmlbuf), xmlBufferLength(xmlbuf));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
xmlBufferFree(xmlbuf);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return xml;
|
|
Packit |
a07778 |
}
|