mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2025-12-30 11:50:11 +01:00
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>
This commit is contained in:
parent
d361874ef6
commit
bc86794f23
15 changed files with 995 additions and 123 deletions
25
ChangeLog
25
ChangeLog
|
|
@ -1,3 +1,28 @@
|
|||
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>
|
||||
|
||||
2003-03-28 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* dbus/dbus-string.c (_dbus_string_copy_data_len)
|
||||
(_dbus_string_copy_data): new functions
|
||||
|
||||
2003-03-28 Anders Carlsson <andersca@codefactory.se>
|
||||
|
||||
* dbus/dbus-bus.c: (bus_data_free), (dbus_bus_get):
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,36 +28,31 @@
|
|||
|
||||
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;
|
||||
|
|
@ -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,23 +124,81 @@ 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;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ _dbus_test_oom_handling (const char *description,
|
|||
|
||||
if (!(* func) (data))
|
||||
return FALSE;
|
||||
|
||||
|
||||
approx_mallocs = _DBUS_INT_MAX - _dbus_get_fail_alloc_counter ();
|
||||
|
||||
_dbus_verbose ("=================\n%s: about %d mallocs total\n=================\n",
|
||||
|
|
|
|||
|
|
@ -212,7 +212,8 @@ _DBUS_DECLARE_GLOBAL_LOCK (atomic);
|
|||
_DBUS_DECLARE_GLOBAL_LOCK (message_handler);
|
||||
_DBUS_DECLARE_GLOBAL_LOCK (user_info);
|
||||
_DBUS_DECLARE_GLOBAL_LOCK (bus);
|
||||
#define _DBUS_N_GLOBAL_LOCKS (7)
|
||||
_DBUS_DECLARE_GLOBAL_LOCK (shutdown_funcs);
|
||||
#define _DBUS_N_GLOBAL_LOCKS (8)
|
||||
|
||||
DBUS_END_DECLS;
|
||||
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ alloc_link (void *data)
|
|||
|
||||
if (!_DBUS_LOCK (list))
|
||||
return NULL;
|
||||
|
||||
if (!list_pool)
|
||||
|
||||
if (list_pool == NULL)
|
||||
{
|
||||
list_pool = _dbus_mem_pool_new (sizeof (DBusList), TRUE);
|
||||
|
||||
|
|
@ -67,9 +67,21 @@ alloc_link (void *data)
|
|||
_DBUS_UNLOCK (list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
link = _dbus_mem_pool_alloc (list_pool);
|
||||
if (link == NULL)
|
||||
{
|
||||
_dbus_mem_pool_free (list_pool);
|
||||
list_pool = NULL;
|
||||
_DBUS_UNLOCK (list);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
link = _dbus_mem_pool_alloc (list_pool);
|
||||
else
|
||||
{
|
||||
link = _dbus_mem_pool_alloc (list_pool);
|
||||
}
|
||||
|
||||
if (link)
|
||||
link->data = data;
|
||||
|
||||
|
|
@ -80,13 +92,14 @@ alloc_link (void *data)
|
|||
|
||||
static void
|
||||
free_link (DBusList *link)
|
||||
{
|
||||
{
|
||||
_DBUS_LOCK (list);
|
||||
if (_dbus_mem_pool_dealloc (list_pool, link))
|
||||
{
|
||||
_dbus_mem_pool_free (list_pool);
|
||||
list_pool = NULL;
|
||||
}
|
||||
|
||||
_DBUS_UNLOCK (list);
|
||||
}
|
||||
|
||||
|
|
@ -607,6 +620,27 @@ _dbus_list_pop_last (DBusList **list)
|
|||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the last link in the list and returns it. This is a
|
||||
* constant-time operation.
|
||||
*
|
||||
* @param list address of the list head.
|
||||
* @returns the last link in the list, or #NULL for an empty list.
|
||||
*/
|
||||
DBusList*
|
||||
_dbus_list_pop_last_link (DBusList **list)
|
||||
{
|
||||
DBusList *link;
|
||||
|
||||
link = _dbus_list_get_last_link (list);
|
||||
if (link == NULL)
|
||||
return NULL;
|
||||
|
||||
_dbus_list_unlink (list, link);
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a list. This is a linear-time operation. If there isn't
|
||||
* enough memory to copy the entire list, the destination list will be
|
||||
|
|
@ -952,6 +986,58 @@ _dbus_list_test (void)
|
|||
_dbus_assert (list1 == NULL);
|
||||
_dbus_assert (list2 == NULL);
|
||||
|
||||
/* Test get_first_link, get_last_link, pop_first_link, pop_last_link */
|
||||
|
||||
i = 0;
|
||||
while (i < 10)
|
||||
{
|
||||
_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i));
|
||||
_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i));
|
||||
++i;
|
||||
}
|
||||
|
||||
--i;
|
||||
while (i >= 0)
|
||||
{
|
||||
DBusList *got_link1;
|
||||
DBusList *got_link2;
|
||||
|
||||
DBusList *link1;
|
||||
DBusList *link2;
|
||||
|
||||
void *data1;
|
||||
void *data2;
|
||||
|
||||
got_link1 = _dbus_list_get_last_link (&list1);
|
||||
got_link2 = _dbus_list_get_first_link (&list2);
|
||||
|
||||
link1 = _dbus_list_pop_last_link (&list1);
|
||||
link2 = _dbus_list_pop_first_link (&list2);
|
||||
|
||||
_dbus_assert (got_link1 == link1);
|
||||
_dbus_assert (got_link2 == link2);
|
||||
|
||||
data1 = link1->data;
|
||||
data2 = link2->data;
|
||||
|
||||
_dbus_list_free_link (link1);
|
||||
_dbus_list_free_link (link2);
|
||||
|
||||
_dbus_assert (_DBUS_POINTER_TO_INT (data1) == i);
|
||||
_dbus_assert (_DBUS_POINTER_TO_INT (data2) == i);
|
||||
|
||||
verify_list (&list1);
|
||||
verify_list (&list2);
|
||||
|
||||
_dbus_assert (is_ascending_sequence (&list1));
|
||||
_dbus_assert (is_descending_sequence (&list2));
|
||||
|
||||
--i;
|
||||
}
|
||||
|
||||
_dbus_assert (list1 == NULL);
|
||||
_dbus_assert (list2 == NULL);
|
||||
|
||||
/* Test iteration */
|
||||
|
||||
i = 0;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||
/* dbus-list.h Generic linked list utility (internal to D-BUS implementation)
|
||||
*
|
||||
* Copyright (C) 2002 Red Hat, Inc.
|
||||
* Copyright (C) 2002, 2003 Red Hat, Inc.
|
||||
*
|
||||
* Licensed under the Academic Free License version 1.2
|
||||
*
|
||||
|
|
@ -63,6 +63,7 @@ void* _dbus_list_get_first (DBusList **list);
|
|||
void* _dbus_list_pop_first (DBusList **list);
|
||||
void* _dbus_list_pop_last (DBusList **list);
|
||||
DBusList* _dbus_list_pop_first_link (DBusList **list);
|
||||
DBusList* _dbus_list_pop_last_link (DBusList **list);
|
||||
dbus_bool_t _dbus_list_copy (DBusList **list,
|
||||
DBusList **dest);
|
||||
int _dbus_list_get_length (DBusList **list);
|
||||
|
|
|
|||
|
|
@ -633,13 +633,17 @@ dbus_free_string_array (char **str_array)
|
|||
*/
|
||||
int _dbus_current_generation = 1;
|
||||
|
||||
static DBusList *registered_globals = NULL;
|
||||
typedef struct ShutdownClosure ShutdownClosure;
|
||||
|
||||
typedef struct
|
||||
struct ShutdownClosure
|
||||
{
|
||||
ShutdownClosure *next;
|
||||
DBusShutdownFunction func;
|
||||
void *data;
|
||||
} ShutdownClosure;
|
||||
};
|
||||
|
||||
_DBUS_DEFINE_GLOBAL_LOCK (shutdown_funcs);
|
||||
static ShutdownClosure *registered_globals = NULL;
|
||||
|
||||
/**
|
||||
* The D-BUS library keeps some internal global variables, for example
|
||||
|
|
@ -656,22 +660,18 @@ typedef struct
|
|||
void
|
||||
dbus_shutdown (void)
|
||||
{
|
||||
DBusList *link;
|
||||
|
||||
link = _dbus_list_get_first_link (®istered_globals);
|
||||
while (link != NULL)
|
||||
while (registered_globals != NULL)
|
||||
{
|
||||
ShutdownClosure *c = link->data;
|
||||
ShutdownClosure *c;
|
||||
|
||||
(* c->func) (c->data);
|
||||
|
||||
dbus_free (c);
|
||||
c = registered_globals;
|
||||
registered_globals = c->next;
|
||||
|
||||
link = _dbus_list_get_next_link (®istered_globals, link);
|
||||
(* c->func) (c->data);
|
||||
|
||||
dbus_free (c);
|
||||
}
|
||||
|
||||
_dbus_list_clear (®istered_globals);
|
||||
|
||||
_dbus_current_generation += 1;
|
||||
}
|
||||
|
||||
|
|
@ -693,20 +693,17 @@ _dbus_register_shutdown_func (DBusShutdownFunction func,
|
|||
|
||||
if (c == NULL)
|
||||
return FALSE;
|
||||
|
||||
|
||||
c->func = func;
|
||||
c->data = data;
|
||||
|
||||
/* We prepend, then shutdown the list in order, so
|
||||
* we shutdown last-registered stuff first which
|
||||
* is right.
|
||||
*/
|
||||
if (!_dbus_list_prepend (®istered_globals, c))
|
||||
{
|
||||
dbus_free (c);
|
||||
return FALSE;
|
||||
}
|
||||
_DBUS_LOCK (shutdown_funcs);
|
||||
|
||||
c->next = registered_globals;
|
||||
registered_globals = c;
|
||||
|
||||
_DBUS_UNLOCK (shutdown_funcs);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,7 +84,8 @@ struct DBusMemBlock
|
|||
* when we free the mem pool.
|
||||
*/
|
||||
|
||||
int used_so_far; /**< bytes of this block already allocated as elements. */
|
||||
/* this is a long so that "elements" is aligned */
|
||||
long used_so_far; /**< bytes of this block already allocated as elements. */
|
||||
|
||||
unsigned char elements[ELEMENT_PADDING]; /**< the block data, actually allocated to required size */
|
||||
};
|
||||
|
|
@ -254,7 +255,7 @@ _dbus_mem_pool_alloc (DBusMemPool *pool)
|
|||
memset (element, '\0', pool->element_size);
|
||||
|
||||
pool->allocated_elements += 1;
|
||||
|
||||
|
||||
return element;
|
||||
}
|
||||
else
|
||||
|
|
@ -311,11 +312,11 @@ _dbus_mem_pool_alloc (DBusMemPool *pool)
|
|||
}
|
||||
|
||||
element = &pool->blocks->elements[pool->blocks->used_so_far];
|
||||
|
||||
|
||||
pool->blocks->used_so_far += pool->element_size;
|
||||
|
||||
pool->allocated_elements += 1;
|
||||
|
||||
|
||||
return element;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -633,7 +633,74 @@ _dbus_string_steal_data_len (DBusString *str,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
_dbus_warn ("Broken code in _dbus_string_steal_data_len(), FIXME\n");
|
||||
_dbus_warn ("Broken code in _dbus_string_steal_data_len(), see @todo, FIXME\n");
|
||||
if (!_dbus_string_steal_data (&dest, data_return))
|
||||
{
|
||||
_dbus_string_free (&dest);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_dbus_string_free (&dest);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copies the data from the string into a char*
|
||||
*
|
||||
* @param str the string
|
||||
* @param data_return place to return the data
|
||||
* @returns #TRUE on success, #FALSE on no memory
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_string_copy_data (const DBusString *str,
|
||||
char **data_return)
|
||||
{
|
||||
DBUS_CONST_STRING_PREAMBLE (str);
|
||||
_dbus_assert (data_return != NULL);
|
||||
|
||||
*data_return = dbus_malloc (real->len + 1);
|
||||
if (*data_return == NULL)
|
||||
return FALSE;
|
||||
|
||||
memcpy (*data_return, real->str, real->len + 1);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a segment of the string into a char*
|
||||
*
|
||||
* @param str the string
|
||||
* @param data_return place to return the data
|
||||
* @param start start index
|
||||
* @param len length to copy
|
||||
* @returns #FALSE if no memory
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_string_copy_data_len (const DBusString *str,
|
||||
char **data_return,
|
||||
int start,
|
||||
int len)
|
||||
{
|
||||
DBusString dest;
|
||||
|
||||
DBUS_CONST_STRING_PREAMBLE (str);
|
||||
_dbus_assert (data_return != NULL);
|
||||
_dbus_assert (start >= 0);
|
||||
_dbus_assert (len >= 0);
|
||||
_dbus_assert (start <= real->len);
|
||||
_dbus_assert (len <= real->len - start);
|
||||
|
||||
if (!_dbus_string_init (&dest, real->max_length))
|
||||
return FALSE;
|
||||
|
||||
if (!_dbus_string_copy_len (str, start, len, &dest, 0))
|
||||
{
|
||||
_dbus_string_free (&dest);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_dbus_string_steal_data (&dest, data_return))
|
||||
{
|
||||
_dbus_string_free (&dest);
|
||||
|
|
@ -1235,8 +1302,9 @@ _dbus_string_replace_len (const DBusString *source,
|
|||
*/
|
||||
#define UNICODE_VALID(Char) \
|
||||
((Char) < 0x110000 && \
|
||||
((Char) < 0xD800 || (Char) >= 0xE000) && \
|
||||
(Char) != 0xFFFE && (Char) != 0xFFFF)
|
||||
(((Char) & 0xFFFFF800) != 0xD800) && \
|
||||
((Char) < 0xFDD0 || (Char) > 0xFDEF) && \
|
||||
((Char) & 0xFFFF) != 0xFFFF)
|
||||
|
||||
/**
|
||||
* Gets a unicode character from a UTF-8 string. Does no validation;
|
||||
|
|
@ -1426,6 +1494,7 @@ _dbus_string_find_blank (const DBusString *str,
|
|||
|
||||
/**
|
||||
* Skips blanks from start, storing the first non-blank in *end
|
||||
* (blank is space or tab).
|
||||
*
|
||||
* @param str the string
|
||||
* @param start where to start
|
||||
|
|
@ -1458,6 +1527,43 @@ _dbus_string_skip_blank (const DBusString *str,
|
|||
*end = i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips whitespace from start, storing the first non-whitespace in *end.
|
||||
* (whitespace is space, tab, newline, CR).
|
||||
*
|
||||
* @param str the string
|
||||
* @param start where to start
|
||||
* @param end where to store the first non-whitespace byte index
|
||||
*/
|
||||
void
|
||||
_dbus_string_skip_white (const DBusString *str,
|
||||
int start,
|
||||
int *end)
|
||||
{
|
||||
int i;
|
||||
DBUS_CONST_STRING_PREAMBLE (str);
|
||||
_dbus_assert (start <= real->len);
|
||||
_dbus_assert (start >= 0);
|
||||
|
||||
i = start;
|
||||
while (i < real->len)
|
||||
{
|
||||
if (!(real->str[i] == ' ' ||
|
||||
real->str[i] == '\n' ||
|
||||
real->str[i] == '\r' ||
|
||||
real->str[i] == '\t'))
|
||||
break;
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
_dbus_assert (i == real->len || !(real->str[i] == ' ' ||
|
||||
real->str[i] == '\t'));
|
||||
|
||||
if (end)
|
||||
*end = i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a newline-terminated or \r\n-terminated line from the front
|
||||
* of the string to the given dest string. The dest string's previous
|
||||
|
|
|
|||
|
|
@ -81,6 +81,12 @@ dbus_bool_t _dbus_string_steal_data_len (DBusString *str,
|
|||
char **data_return,
|
||||
int start,
|
||||
int len);
|
||||
dbus_bool_t _dbus_string_copy_data (const DBusString *str,
|
||||
char **data_return);
|
||||
dbus_bool_t _dbus_string_copy_data_len (const DBusString *str,
|
||||
char **data_return,
|
||||
int start,
|
||||
int len);
|
||||
|
||||
int _dbus_string_get_length (const DBusString *str);
|
||||
|
||||
|
|
@ -175,6 +181,10 @@ void _dbus_string_skip_blank (const DBusString *str,
|
|||
int start,
|
||||
int *end);
|
||||
|
||||
void _dbus_string_skip_white (const DBusString *str,
|
||||
int start,
|
||||
int *end);
|
||||
|
||||
dbus_bool_t _dbus_string_equal (const DBusString *a,
|
||||
const DBusString *b);
|
||||
|
||||
|
|
|
|||
|
|
@ -245,7 +245,8 @@ init_global_locks (void)
|
|||
LOCK_ADDR (atomic),
|
||||
LOCK_ADDR (message_handler),
|
||||
LOCK_ADDR (user_info),
|
||||
LOCK_ADDR (bus)
|
||||
LOCK_ADDR (bus),
|
||||
LOCK_ADDR (shutdown_funcs)
|
||||
#undef LOCK_ADDR
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,18 @@ Elements:
|
|||
|
||||
Include a file <include>filename.conf</include> at this point.
|
||||
|
||||
<includedir>
|
||||
|
||||
Include all files in <includedir>foo.d</includedir> at this
|
||||
point. Files in the directory are included in undefined order.
|
||||
Only files ending in ".conf" are included.
|
||||
|
||||
This is intended to allow extension of the system bus by
|
||||
particular packages. For example, if CUPS wants to be able to send
|
||||
out notification of printer queue changes, it could install a file
|
||||
to /etc/dbus/system.d that allowed all apps to receive this
|
||||
message and allowed the printer daemon user to send it.
|
||||
|
||||
<user>
|
||||
|
||||
The user account the daemon should run as, as either a username or
|
||||
|
|
@ -42,13 +54,12 @@ Elements:
|
|||
The last <user> entry in the file "wins", the others are ignored.
|
||||
|
||||
<listen>
|
||||
address="name" mandatory attribute
|
||||
|
||||
Add an address that the bus should listen on. The
|
||||
address is in the standard D-BUS format that contains
|
||||
a transport name plus possible parameters/options.
|
||||
|
||||
Example: <listen address="unix:path=/tmp/foo"/>
|
||||
Example: <listen>unix:path=/tmp/foo</listen>
|
||||
|
||||
If there are multiple <listen> elements, then the bus listens
|
||||
on multiple addresses.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||
<busconfig>
|
||||
<user>mybususer</user>
|
||||
<listen>unix:path=/foo/bar</listen>
|
||||
<listen>tcp:port=1234</listen>
|
||||
<include ignore_missing="yes">nonexistent.conf</include>
|
||||
<policy context="default">
|
||||
<allow user="*"/>
|
||||
</policy>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue