summaryrefslogtreecommitdiffstats
path: root/bus
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-03-31 04:01:00 +0000
committerHavoc Pennington <hp@redhat.com>2003-03-31 04:01:00 +0000
commitbc86794f23fa538a405813fb61b531c2eacc9ae1 (patch)
tree42f040afce0d63d312d6f43bf5f6f9bb014c586a /bus
parentd361874ef6a94a61fa3e0534d8352392edf9bbb9 (diff)
2003-03-30 Havoc Pennington <hp@pobox.com>
* bus/config-parser.c: hacking * dbus/dbus-memory.c: don't use DBusList for the list of stuff to shut down, since it could cause weirdness with the DBusList lock * dbus/dbus-list.c (_dbus_list_test): add tests for the link-oriented stack routines (alloc_link): free the mempool if the first alloc from it fails * dbus/dbus-mempool.c (struct DBusMemBlock): fix alignment issue * dbus/dbus-string.c (UNICODE_VALID): sync new version of this from GLib (_dbus_string_skip_white): new * doc/config-file.txt (Elements): add <includedir>
Diffstat (limited to 'bus')
-rw-r--r--bus/config-loader-expat.c82
-rw-r--r--bus/config-parser.c705
-rw-r--r--bus/test-main.c4
3 files changed, 710 insertions, 81 deletions
diff --git a/bus/config-loader-expat.c b/bus/config-loader-expat.c
index c7981bf4..a3740a48 100644
--- a/bus/config-loader-expat.c
+++ b/bus/config-loader-expat.c
@@ -4,7 +4,7 @@
* Copyright (C) 2003 Red Hat, Inc.
*
* Licensed under the Academic Free License version 1.2
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -14,7 +14,7 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -41,6 +41,27 @@ typedef struct
dbus_bool_t failed;
} ExpatParseContext;
+static dbus_bool_t
+process_content (ExpatParseContext *context)
+{
+ if (context->failed)
+ return FALSE;
+
+ if (_dbus_string_get_length (&context->content) > 0)
+ {
+ if (!bus_config_parser_content (context->parser,
+ &context->content,
+ context->error))
+ {
+ context->failed = TRUE;
+ return FALSE;
+ }
+ _dbus_string_set_length (&context->content, 0);
+ }
+
+ return TRUE;
+}
+
static void
expat_StartElementHandler (void *userData,
const XML_Char *name,
@@ -50,13 +71,16 @@ expat_StartElementHandler (void *userData,
int i;
char **names;
char **values;
-
+
/* Expat seems to suck and can't abort the parse if we
* throw an error. Expat 2.0 is supposed to fix this.
*/
if (context->failed)
return;
+ if (!process_content (context))
+ return;
+
/* "atts" is key, value, key, value, NULL */
for (i = 0; atts[i] != NULL; ++i)
; /* nothing */
@@ -73,17 +97,17 @@ expat_StartElementHandler (void *userData,
dbus_free (values);
return;
}
-
+
i = 0;
while (atts[i] != NULL)
{
_dbus_assert (i % 2 == 0);
- names [i / 2] = (char*) atts[i];
- values[i / 2 + 1] = (char*) atts[i+1];
-
+ names [i / 2] = (char*) atts[i];
+ values[i / 2] = (char*) atts[i+1];
+
i += 2;
}
-
+
if (!bus_config_parser_start_element (context->parser,
name,
(const char **) names,
@@ -105,20 +129,9 @@ expat_EndElementHandler (void *userData,
const XML_Char *name)
{
ExpatParseContext *context = userData;
- if (context->failed)
- return;
- if (_dbus_string_get_length (&context->content) > 0)
- {
- if (!bus_config_parser_content (context->parser,
- &context->content,
- context->error))
- {
- context->failed = TRUE;
- return;
- }
- _dbus_string_set_length (&context->content, 0);
- }
+ if (!process_content (context))
+ return;
if (!bus_config_parser_end_element (context->parser,
name,
@@ -157,22 +170,22 @@ bus_config_load (const DBusString *file,
const char *filename;
BusConfigParser *parser;
ExpatParseContext context;
-
+
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
parser = NULL;
expat = NULL;
context.error = error;
context.failed = FALSE;
-
+
_dbus_string_get_const_data (file, &filename);
-
+
if (!_dbus_string_init (&context.content, _DBUS_INT_MAX))
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
return NULL;
}
-
+
expat = XML_ParserCreate_MM ("UTF-8", &memsuite, NULL);
if (expat == NULL)
{
@@ -186,6 +199,7 @@ bus_config_load (const DBusString *file,
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
goto failed;
}
+ context.parser = parser;
XML_SetUserData (expat, &context);
XML_SetElementHandler (expat,
@@ -197,28 +211,28 @@ bus_config_load (const DBusString *file,
{
DBusString data;
const char *data_str;
-
+
if (!_dbus_string_init (&data, _DBUS_INT_MAX))
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
goto failed;
}
-
+
if (!_dbus_file_get_contents (&data, file, error))
{
_dbus_string_free (&data);
goto failed;
}
-
+
_dbus_string_get_const_data (&data, &data_str);
-
+
if (!XML_Parse (expat, data_str, _dbus_string_get_length (&data), TRUE))
{
if (context.error != NULL &&
!dbus_error_is_set (context.error))
{
enum XML_Error e;
-
+
e = XML_GetErrorCode (expat);
if (e == XML_ERROR_NO_MEMORY)
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
@@ -230,7 +244,7 @@ bus_config_load (const DBusString *file,
XML_GetCurrentColumnNumber (expat),
XML_ErrorString (e));
}
-
+
_dbus_string_free (&data);
goto failed;
}
@@ -240,7 +254,7 @@ bus_config_load (const DBusString *file,
if (context.failed)
goto failed;
}
-
+
if (!bus_config_parser_finished (parser, error))
goto failed;
@@ -249,10 +263,10 @@ bus_config_load (const DBusString *file,
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
return parser;
-
+
failed:
_DBUS_ASSERT_ERROR_IS_SET (error);
-
+
_dbus_string_free (&context.content);
if (expat)
XML_ParserFree (expat);
diff --git a/bus/config-parser.c b/bus/config-parser.c
index 2429cce5..972c05ac 100644
--- a/bus/config-parser.c
+++ b/bus/config-parser.c
@@ -4,7 +4,7 @@
* Copyright (C) 2003 Red Hat, Inc.
*
* Licensed under the Academic Free License version 1.2
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -14,7 +14,7 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -28,38 +28,33 @@
typedef enum
{
+ ELEMENT_NONE,
ELEMENT_BUSCONFIG,
ELEMENT_INCLUDE,
ELEMENT_USER,
ELEMENT_LISTEN,
ELEMENT_AUTH,
ELEMENT_POLICY,
- ELEMENT_LIMIT
+ ELEMENT_LIMIT,
+ ELEMENT_ALLOW,
+ ELEMENT_DENY
} ElementType;
typedef struct
{
ElementType type;
+ unsigned int had_content : 1;
+
union
{
struct
{
- BusConfigParser *parser;
+ unsigned int ignore_missing : 1;
} include;
struct
{
- char *username;
- } user;
-
- struct
- {
- char *address;
- } listen;
-
- struct
- {
char *mechanism;
} auth;
@@ -75,20 +70,53 @@ typedef struct
{
int foo;
} limit;
-
+
} d;
-
+
} Element;
struct BusConfigParser
{
int refcount;
- DBusList *stack; /**< stack of Element */
+ DBusList *stack; /**< stack of Element */
- char *user; /**< user to run as */
+ char *user; /**< user to run as */
+
+ DBusList *listen_on; /**< List of addresses to listen to */
};
+static const char*
+element_type_to_name (ElementType type)
+{
+ switch (type)
+ {
+ case ELEMENT_NONE:
+ return NULL;
+ case ELEMENT_BUSCONFIG:
+ return "busconfig";
+ case ELEMENT_INCLUDE:
+ return "include";
+ case ELEMENT_USER:
+ return "user";
+ case ELEMENT_LISTEN:
+ return "listen";
+ case ELEMENT_AUTH:
+ return "auth";
+ case ELEMENT_POLICY:
+ return "policy";
+ case ELEMENT_LIMIT:
+ return "limit";
+ case ELEMENT_ALLOW:
+ return "allow";
+ case ELEMENT_DENY:
+ return "deny";
+ }
+
+ _dbus_assert_not_reached ("bad element type");
+
+ return NULL;
+}
static Element*
push_element (BusConfigParser *parser,
@@ -96,9 +124,17 @@ push_element (BusConfigParser *parser,
{
Element *e;
+ _dbus_assert (type != ELEMENT_NONE);
+
e = dbus_new0 (Element, 1);
if (e == NULL)
return NULL;
+
+ if (!_dbus_list_append (&parser->stack, e))
+ {
+ dbus_free (e);
+ return NULL;
+ }
e->type = type;
@@ -106,13 +142,63 @@ push_element (BusConfigParser *parser,
}
static void
+element_free (Element *e)
+{
+
+ dbus_free (e);
+}
+
+static void
pop_element (BusConfigParser *parser)
{
Element *e;
e = _dbus_list_pop_last (&parser->stack);
+
+ element_free (e);
+}
- dbus_free (e);
+static Element*
+peek_element (BusConfigParser *parser)
+{
+ Element *e;
+
+ e = _dbus_list_get_last (&parser->stack);
+
+ return e;
+}
+
+static ElementType
+top_element_type (BusConfigParser *parser)
+{
+ Element *e;
+
+ e = _dbus_list_get_last (&parser->stack);
+
+ if (e)
+ return e->type;
+ else
+ return ELEMENT_NONE;
+}
+
+static dbus_bool_t
+merge_included (BusConfigParser *parser,
+ BusConfigParser *included,
+ DBusError *error)
+{
+ DBusList *link;
+
+ if (included->user != NULL)
+ {
+ dbus_free (parser->user);
+ parser->user = included->user;
+ included->user = NULL;
+ }
+
+ while ((link = _dbus_list_pop_first_link (&included->listen_on)))
+ _dbus_list_append_link (&parser->listen_on, link);
+
+ return TRUE;
}
BusConfigParser*
@@ -148,9 +234,15 @@ bus_config_parser_unref (BusConfigParser *parser)
{
while (parser->stack != NULL)
pop_element (parser);
-
+
dbus_free (parser->user);
+ _dbus_list_foreach (&parser->listen_on,
+ (DBusForeachFunction) dbus_free,
+ NULL);
+
+ _dbus_list_clear (&parser->listen_on);
+
dbus_free (parser);
}
}
@@ -161,12 +253,12 @@ bus_config_parser_check_doctype (BusConfigParser *parser,
DBusError *error)
{
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
+
if (strcmp (doctype, "busconfig") != 0)
{
dbus_set_error (error,
DBUS_ERROR_FAILED,
- "Document has the wrong type %s",
+ "Configuration file has the wrong document type %s",
doctype);
return FALSE;
}
@@ -174,6 +266,271 @@ bus_config_parser_check_doctype (BusConfigParser *parser,
return TRUE;
}
+typedef struct
+{
+ const char *name;
+ const char **retloc;
+} LocateAttr;
+
+static dbus_bool_t
+locate_attributes (BusConfigParser *parser,
+ const char *element_name,
+ const char **attribute_names,
+ const char **attribute_values,
+ DBusError *error,
+ const char *first_attribute_name,
+ const char **first_attribute_retloc,
+ ...)
+{
+ va_list args;
+ const char *name;
+ const char **retloc;
+ int n_attrs;
+#define MAX_ATTRS 24
+ LocateAttr attrs[MAX_ATTRS];
+ dbus_bool_t retval;
+ int i;
+
+ _dbus_assert (first_attribute_name != NULL);
+ _dbus_assert (first_attribute_retloc != NULL);
+
+ retval = TRUE;
+
+ n_attrs = 1;
+ attrs[0].name = first_attribute_name;
+ attrs[0].retloc = first_attribute_retloc;
+ *first_attribute_retloc = NULL;
+
+ va_start (args, first_attribute_retloc);
+
+ name = va_arg (args, const char*);
+ retloc = va_arg (args, const char**);
+
+ while (name != NULL)
+ {
+ _dbus_assert (retloc != NULL);
+ _dbus_assert (n_attrs < MAX_ATTRS);
+
+ attrs[n_attrs].name = name;
+ attrs[n_attrs].retloc = retloc;
+ n_attrs += 1;
+ *retloc = NULL;
+
+ name = va_arg (args, const char*);
+ retloc = va_arg (args, const char**);
+ }
+
+ va_end (args);
+
+ if (!retval)
+ return retval;
+
+ i = 0;
+ while (attribute_names[i])
+ {
+ int j;
+ dbus_bool_t found;
+
+ found = FALSE;
+ j = 0;
+ while (j < n_attrs)
+ {
+ if (strcmp (attrs[j].name, attribute_names[i]) == 0)
+ {
+ retloc = attrs[j].retloc;
+
+ if (*retloc != NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Attribute \"%s\" repeated twice on the same <%s> element",
+ attrs[j].name, element_name);
+ retval = FALSE;
+ goto out;
+ }
+
+ *retloc = attribute_values[i];
+ found = TRUE;
+ }
+
+ ++j;
+ }
+
+ if (!found)
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Attribute \"%s\" is invalid on <%s> element in this context",
+ attribute_names[i], element_name);
+ retval = FALSE;
+ goto out;
+ }
+
+ ++i;
+ }
+
+ out:
+ return retval;
+}
+
+static dbus_bool_t
+check_no_attributes (BusConfigParser *parser,
+ const char *element_name,
+ const char **attribute_names,
+ const char **attribute_values,
+ DBusError *error)
+{
+ if (attribute_names[0] != NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Attribute \"%s\" is invalid on <%s> element in this context",
+ attribute_names[0], element_name);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static dbus_bool_t
+start_busconfig_child (BusConfigParser *parser,
+ const char *element_name,
+ const char **attribute_names,
+ const char **attribute_values,
+ DBusError *error)
+{
+ if (strcmp (element_name, "user") == 0)
+ {
+ if (!check_no_attributes (parser, "user", attribute_names, attribute_values, error))
+ return FALSE;
+
+ if (push_element (parser, ELEMENT_USER) == NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+ else if (strcmp (element_name, "listen") == 0)
+ {
+ if (!check_no_attributes (parser, "listen", attribute_names, attribute_values, error))
+ return FALSE;
+
+ if (push_element (parser, ELEMENT_LISTEN) == NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+ else if (strcmp (element_name, "include") == 0)
+ {
+ Element *e;
+ const char *ignore_missing;
+
+ if ((e = push_element (parser, ELEMENT_INCLUDE)) == NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ return FALSE;
+ }
+
+ e->d.include.ignore_missing = FALSE;
+
+ if (!locate_attributes (parser, "include",
+ attribute_names,
+ attribute_values,
+ error,
+ "ignore_missing", &ignore_missing,
+ NULL))
+ return FALSE;
+
+ if (ignore_missing != NULL)
+ {
+ if (strcmp (ignore_missing, "yes") == 0)
+ e->d.include.ignore_missing = TRUE;
+ else if (strcmp (ignore_missing, "no") == 0)
+ e->d.include.ignore_missing = FALSE;
+ else
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "ignore_missing attribute must have value \"yes\" or \"no\"");
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ }
+ else if (strcmp (element_name, "policy") == 0)
+ {
+ Element *e;
+ const char *context;
+ const char *user;
+ const char *group;
+
+ if ((e = push_element (parser, ELEMENT_POLICY)) == NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ return FALSE;
+ }
+
+ if (!locate_attributes (parser, "include",
+ attribute_names,
+ attribute_values,
+ error,
+ "context", &context,
+ "user", &user,
+ "group", &group,
+ NULL))
+ return FALSE;
+
+ /* FIXME */
+
+ return TRUE;
+ }
+ else
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Element <%s> not allowed inside <%s> in configuration file",
+ element_name, "busconfig");
+ return FALSE;
+ }
+}
+
+static dbus_bool_t
+start_policy_child (BusConfigParser *parser,
+ const char *element_name,
+ const char **attribute_names,
+ const char **attribute_values,
+ DBusError *error)
+{
+ if (strcmp (element_name, "allow") == 0)
+ {
+ if (push_element (parser, ELEMENT_ALLOW) == NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+ else if (strcmp (element_name, "deny") == 0)
+ {
+ if (push_element (parser, ELEMENT_DENY) == NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+ else
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Element <%s> not allowed inside <%s> in configuration file",
+ element_name, "policy");
+ return FALSE;
+ }
+}
+
dbus_bool_t
bus_config_parser_start_element (BusConfigParser *parser,
const char *element_name,
@@ -181,9 +538,56 @@ bus_config_parser_start_element (BusConfigParser *parser,
const char **attribute_values,
DBusError *error)
{
- _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ ElementType t;
- return TRUE;
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ /* printf ("START: %s\n", element_name); */
+
+ t = top_element_type (parser);
+
+ if (t == ELEMENT_NONE)
+ {
+ if (strcmp (element_name, "busconfig") == 0)
+ {
+ if (!check_no_attributes (parser, "busconfig", attribute_names, attribute_values, error))
+ return FALSE;
+
+ if (push_element (parser, ELEMENT_BUSCONFIG) == NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+ else
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Unknown element <%s> at root of configuration file",
+ element_name);
+ return FALSE;
+ }
+ }
+ else if (t == ELEMENT_BUSCONFIG)
+ {
+ return start_busconfig_child (parser, element_name,
+ attribute_names, attribute_values,
+ error);
+ }
+ else if (t == ELEMENT_POLICY)
+ {
+ return start_policy_child (parser, element_name,
+ attribute_names, attribute_values,
+ error);
+ }
+ else
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Element <%s> is not allowed in this context",
+ element_name);
+ return FALSE;
+ }
}
dbus_bool_t
@@ -191,36 +595,247 @@ bus_config_parser_end_element (BusConfigParser *parser,
const char *element_name,
DBusError *error)
{
+ ElementType t;
+ const char *n;
+ Element *e;
+
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ /* printf ("END: %s\n", element_name); */
+
+ t = top_element_type (parser);
+
+ if (t == ELEMENT_NONE)
+ {
+ /* should probably be an assertion failure but
+ * being paranoid about XML parsers
+ */
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "XML parser ended element with no element on the stack");
+ return FALSE;
+ }
+
+ n = element_type_to_name (t);
+ _dbus_assert (n != NULL);
+ if (strcmp (n, element_name) != 0)
+ {
+ /* should probably be an assertion failure but
+ * being paranoid about XML parsers
+ */
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "XML element ended which was not the topmost element on the stack");
+ return FALSE;
+ }
+
+ e = peek_element (parser);
+ _dbus_assert (e != NULL);
+
+ switch (e->type)
+ {
+ case ELEMENT_NONE:
+ _dbus_assert_not_reached ("element in stack has no type");
+ break;
+
+ case ELEMENT_INCLUDE:
+ case ELEMENT_USER:
+ case ELEMENT_LISTEN:
+ case ELEMENT_AUTH:
+ if (!e->had_content)
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "XML element <%s> was expected to have content inside it",
+ element_type_to_name (e->type));
+ return FALSE;
+ }
+ break;
+
+ case ELEMENT_BUSCONFIG:
+ case ELEMENT_POLICY:
+ case ELEMENT_LIMIT:
+ case ELEMENT_ALLOW:
+ case ELEMENT_DENY:
+ break;
+ }
+
+ pop_element (parser);
+
return TRUE;
}
+static dbus_bool_t
+all_whitespace (const DBusString *str)
+{
+ int i;
+
+ _dbus_string_skip_white (str, 0, &i);
+
+ return i == _dbus_string_get_length (str);
+}
+
dbus_bool_t
bus_config_parser_content (BusConfigParser *parser,
const DBusString *content,
DBusError *error)
{
+ Element *e;
+
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
+#if 0
+ {
+ const char *c_str;
+
+ _dbus_string_get_const_data (content, &c_str);
+
+ printf ("CONTENT %d bytes: %s\n", _dbus_string_get_length (content), c_str);
+ }
+#endif
+
+ e = peek_element (parser);
+ if (e == NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Text content outside of any XML element in configuration file");
+ return FALSE;
+ }
+ else if (e->had_content)
+ {
+ _dbus_assert_not_reached ("Element had multiple content blocks");
+ return FALSE;
+ }
+
+ switch (top_element_type (parser))
+ {
+ case ELEMENT_NONE:
+ _dbus_assert_not_reached ("element at top of stack has no type");
+ return FALSE;
+
+ case ELEMENT_BUSCONFIG:
+ case ELEMENT_POLICY:
+ case ELEMENT_LIMIT:
+ case ELEMENT_ALLOW:
+ case ELEMENT_DENY:
+ if (all_whitespace (content))
+ return TRUE;
+ else
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "No text content expected inside XML element %s in configuration file",
+ element_type_to_name (top_element_type (parser)));
+ return FALSE;
+ }
+
+ case ELEMENT_INCLUDE:
+ {
+ /* FIXME good test case for this would load each config file in the
+ * test suite both alone, and as an include, and check
+ * that the result is the same
+ */
+ BusConfigParser *included;
+ DBusError tmp_error;
+
+ e->had_content = TRUE;
+
+ dbus_error_init (&tmp_error);
+ included = bus_config_load (content, &tmp_error);
+ if (included == NULL)
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
+ if (dbus_error_has_name (&tmp_error, DBUS_ERROR_FILE_NOT_FOUND) &&
+ e->d.include.ignore_missing)
+ {
+ dbus_error_free (&tmp_error);
+ return TRUE;
+ }
+ else
+ {
+ dbus_move_error (&tmp_error, error);
+ return FALSE;
+ }
+ }
+ else
+ {
+ _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
+
+ if (!merge_included (parser, included, error))
+ return FALSE;
+
+ bus_config_parser_unref (included);
+ return TRUE;
+ }
+ }
+ break;
+
+ case ELEMENT_USER:
+ {
+ char *s;
+
+ e->had_content = TRUE;
+
+ if (!_dbus_string_copy_data (content, &s))
+ goto nomem;
+
+ dbus_free (parser->user);
+ parser->user = s;
+ }
+ break;
+
+ case ELEMENT_LISTEN:
+ {
+ char *s;
+
+ e->had_content = TRUE;
+
+ if (!_dbus_string_copy_data (content, &s))
+ goto nomem;
+
+ if (!_dbus_list_append (&parser->listen_on,
+ s))
+ {
+ dbus_free (s);
+ goto nomem;
+ }
+ }
+ break;
+
+ case ELEMENT_AUTH:
+ {
+ e->had_content = TRUE;
+ /* FIXME */
+ }
+ break;
+ }
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
return TRUE;
+
+ nomem:
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ return FALSE;
}
dbus_bool_t
bus_config_parser_finished (BusConfigParser *parser,
DBusError *error)
{
- _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ if (parser->stack != NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Element <%s> was not closed in configuration file",
+ element_type_to_name (top_element_type (parser)));
+ return FALSE;
+ }
+
return TRUE;
}
const char*
bus_config_parser_get_user (BusConfigParser *parser)
{
-
-
- return NULL;
+ return parser->user;
}
#ifdef DBUS_BUILD_TESTS
@@ -242,12 +857,12 @@ do_load (const DBusString *full_path,
DBusError error;
dbus_error_init (&error);
-
+
parser = bus_config_load (full_path, &error);
if (parser == NULL)
{
_DBUS_ASSERT_ERROR_IS_SET (&error);
-
+
if (oom_possible &&
dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
{
@@ -256,7 +871,7 @@ do_load (const DBusString *full_path,
return TRUE;
}
else if (validity == VALID)
- {
+ {
_dbus_warn ("Failed to load valid file but still had memory: %s\n",
error.message);
@@ -272,9 +887,9 @@ do_load (const DBusString *full_path,
else
{
_DBUS_ASSERT_ERROR_IS_CLEAR (&error);
-
+
bus_config_parser_unref (parser);
-
+
if (validity == INVALID)
{
_dbus_warn ("Accepted invalid file\n");
@@ -312,17 +927,17 @@ process_test_subdir (const DBusString *test_base_dir,
retval = FALSE;
dir = NULL;
-
+
if (!_dbus_string_init (&test_directory, _DBUS_INT_MAX))
_dbus_assert_not_reached ("didn't allocate test_directory\n");
_dbus_string_init_const (&filename, subdir);
-
+
if (!_dbus_string_copy (test_base_dir, 0,
&test_directory, 0))
_dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory");
-
- if (!_dbus_concat_dir_and_file (&test_directory, &filename))
+
+ if (!_dbus_concat_dir_and_file (&test_directory, &filename))
_dbus_assert_not_reached ("couldn't allocate full path");
_dbus_string_free (&filename);
@@ -342,13 +957,13 @@ process_test_subdir (const DBusString *test_base_dir,
}
printf ("Testing:\n");
-
+
next:
while (_dbus_directory_get_next_file (dir, &filename, &error))
{
DBusString full_path;
LoaderOomData d;
-
+
if (!_dbus_string_init (&full_path, _DBUS_INT_MAX))
_dbus_assert_not_reached ("couldn't init string");
@@ -373,7 +988,7 @@ process_test_subdir (const DBusString *test_base_dir,
_dbus_string_get_const_data (&filename, &s);
printf (" %s\n", s);
}
-
+
_dbus_verbose (" expecting %s\n",
validity == VALID ? "valid" :
(validity == INVALID ? "invalid" :
@@ -383,7 +998,7 @@ process_test_subdir (const DBusString *test_base_dir,
d.validity = validity;
if (!_dbus_test_oom_handling ("config-loader", check_loader_oom_func, &d))
_dbus_assert_not_reached ("test failed");
-
+
_dbus_string_free (&full_path);
}
@@ -396,9 +1011,9 @@ process_test_subdir (const DBusString *test_base_dir,
dbus_error_free (&error);
goto failed;
}
-
+
retval = TRUE;
-
+
failed:
if (dir)
@@ -418,10 +1033,10 @@ bus_config_parser_test (const DBusString *test_data_dir)
printf ("No test data\n");
return TRUE;
}
-
+
if (!process_test_subdir (test_data_dir, "valid-config-files", VALID))
return FALSE;
-
+
return TRUE;
}
diff --git a/bus/test-main.c b/bus/test-main.c
index 3768de5f..862ba604 100644
--- a/bus/test-main.c
+++ b/bus/test-main.c
@@ -69,8 +69,8 @@ main (int argc, char **argv)
printf ("%s: Running config file parser test\n", argv[0]);
if (!bus_config_parser_test (&test_data_dir))
die ("parser");
-
- check_memleaks (argv[0]);
+
+ check_memleaks (argv[0]);
printf ("%s: Running policy test\n", argv[0]);
if (!bus_policy_test (&test_data_dir))