Main Page   Modules   Data Structures   File List   Data Fields   Related Pages  

config-loader-libxml.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */
00002 /* config-loader-libxml.c  libxml2 XML loader
00003  *
00004  * Copyright (C) 2003 Red Hat, Inc.
00005  *
00006  * Licensed under the Academic Free License version 1.2
00007  * 
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  * 
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  */
00023 
00024 #include "config-parser.h"
00025 #include <dbus/dbus-internals.h>
00026 #include <libxml/xmlreader.h>
00027 #include <libxml/parser.h>
00028 #include <libxml/globals.h>
00029 #include <libxml/xmlmemory.h>
00030 #include <errno.h>
00031 #include <string.h>
00032 
00033 static void*
00034 libxml_malloc (size_t size)
00035 {
00036   return dbus_malloc (size);
00037 }
00038 
00039 static void*
00040 libxml_realloc (void *ptr, size_t size)
00041 {
00042   return dbus_realloc (ptr, size);
00043 }
00044 
00045 static void
00046 libxml_free (void *ptr)
00047 {
00048   dbus_free (ptr);
00049 }
00050 
00051 static char*
00052 libxml_strdup (const char *str)
00053 {
00054   return _dbus_strdup (str);
00055 }
00056 
00057 static void
00058 xml_text_reader_error (void                   *arg,
00059                        const char             *msg,
00060                        xmlParserSeverities     severity,
00061                        xmlTextReaderLocatorPtr locator)
00062 {
00063   DBusError *error = arg;
00064   
00065   if (!dbus_error_is_set (error))
00066     {
00067       dbus_set_error (error, DBUS_ERROR_FAILED,
00068                       "Error loading config file: %s",
00069                       msg);
00070     }
00071 }
00072 
00073 BusConfigParser*
00074 bus_config_load (const DBusString *file,
00075                  DBusError        *error)
00076 {
00077   xmlTextReader *reader;
00078   const char *filename;
00079   BusConfigParser *parser;
00080   DBusError tmp_error;
00081   int ret;
00082   
00083   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00084   
00085   _dbus_string_get_const_data (file, &filename);
00086   parser = NULL;
00087   reader = NULL;
00088   dbus_error_init (&tmp_error);
00089 
00090   if (xmlMemSetup (libxml_free,
00091                    libxml_malloc,
00092                    libxml_realloc,
00093                    libxml_strdup) != 0)
00094     {
00095       /* Current libxml can't possibly fail here, but just being
00096        * paranoid; don't really know why xmlMemSetup() returns an
00097        * error code, assuming some version of libxml had a reason.
00098        */
00099       dbus_set_error (error, DBUS_ERROR_FAILED,
00100                       "xmlMemSetup() didn't work for some reason\n");
00101       return NULL;
00102     }
00103   
00104   parser = bus_config_parser_new ();
00105   if (parser == NULL)
00106     {
00107       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00108       return NULL;
00109     }
00110   
00111   errno = 0;
00112   reader = xmlNewTextReaderFilename (filename);
00113 
00114   if (reader == NULL)
00115     {
00116       dbus_set_error (error, DBUS_ERROR_FAILED,
00117                       "Failed to load configuration file %s: %s\n",
00118                       filename,
00119                       errno != 0 ? strerror (errno) : "Unknown error");
00120         
00121       goto failed;
00122     }
00123 
00124   xmlTextReaderSetErrorHandler (reader, xml_text_reader_error, &tmp_error);
00125 
00126   while ((ret = xmlTextReaderRead (reader)) == 1)
00127     {
00128       int type;
00129       
00130       if (dbus_error_is_set (&tmp_error))
00131         goto reader_out;
00132       
00133       /* "enum" anyone? http://dotgnu.org/pnetlib-doc/System/Xml/XmlNodeType.html for
00134        * the magic numbers
00135        */
00136       type = xmlTextReaderNodeType (reader);
00137       if (dbus_error_is_set (&tmp_error))
00138         goto reader_out;
00139 
00140       /* FIXME I don't really know exactly what I need to do to
00141        * resolve all entities and so on to get the full content of a
00142        * node or attribute value. I'm worried about whether I need to
00143        * manually handle stuff like &lt;
00144        */
00145     }
00146 
00147   if (ret == -1)
00148     {
00149       if (!dbus_error_is_set (&tmp_error))
00150         dbus_set_error (&tmp_error,
00151                         DBUS_ERROR_FAILED,
00152                         "Unknown failure loading configuration file");
00153     }
00154   
00155  reader_out:
00156   xmlFreeTextReader (reader);
00157   reader = NULL;
00158   if (dbus_error_is_set (&tmp_error))
00159     {
00160       dbus_move_error (&tmp_error, error);
00161       goto failed;
00162     }
00163   
00164   if (!bus_config_parser_finished (parser, error))
00165     goto failed;
00166 
00167   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00168   return parser;
00169   
00170  failed:
00171   _DBUS_ASSERT_ERROR_IS_SET (error);
00172   if (parser)
00173     bus_config_parser_unref (parser);
00174   _dbus_assert (reader == NULL); /* must go to reader_out first */
00175   return NULL;
00176 }

Generated on Mon Sep 29 21:30:59 2003 for D-BUS by doxygen1.2.15