Commit 5fd1e389 authored by Havoc Pennington's avatar Havoc Pennington

2003-08-30 Havoc Pennington <hp@pobox.com>

	* test/data/valid-config-files/system.d/test.conf: change to
	root for the user so warnings don't get printed

	* dbus/dbus-message.c: add dbus_message_get_path,
	dbus_message_set_path

	* dbus/dbus-object-tree.c (do_test_dispatch): add test of
	dispatching to a path

	* dbus/dbus-string.c (_dbus_string_validate_path): add

	* dbus/dbus-marshal.c (_dbus_demarshal_object_path): implement
	(_dbus_marshal_object_path): implement

	* dbus/dbus-protocol.h (DBUS_HEADER_FIELD_PATH): new header field
	to contain the path to the target object
	(DBUS_HEADER_FIELD_SENDER_SERVICE): rename
	DBUS_HEADER_FIELD_SENDER to explicitly say it's the sender service
parent 9a0e83f5
2003-08-30 Havoc Pennington <hp@pobox.com>
* test/data/valid-config-files/system.d/test.conf: change to
root for the user so warnings don't get printed
* dbus/dbus-message.c: add dbus_message_get_path,
dbus_message_set_path
* dbus/dbus-object-tree.c (do_test_dispatch): add test of
dispatching to a path
* dbus/dbus-string.c (_dbus_string_validate_path): add
* dbus/dbus-marshal.c (_dbus_demarshal_object_path): implement
(_dbus_marshal_object_path): implement
* dbus/dbus-protocol.h (DBUS_HEADER_FIELD_PATH): new header field
to contain the path to the target object
(DBUS_HEADER_FIELD_SENDER_SERVICE): rename
DBUS_HEADER_FIELD_SENDER to explicitly say it's the sender service
2003-08-30 Havoc Pennington <hp@pobox.com>
* dbus/dbus-object-tree.c: write tests and fix the discovered bugs
......
......@@ -727,9 +727,10 @@ check_hello_message (BusContext *context,
acquired = NULL;
message = NULL;
message = dbus_message_new_method_call (DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"Hello",
DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
DBUS_PATH_ORG_FREEDESKTOP_DBUS,
DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"Hello");
if (message == NULL)
return TRUE;
......@@ -958,9 +959,10 @@ check_nonexistent_service_activation (BusContext *context,
dbus_error_init (&error);
message = dbus_message_new_method_call (DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"ActivateService",
DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
DBUS_PATH_ORG_FREEDESKTOP_DBUS,
DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"ActivateService");
if (message == NULL)
return TRUE;
......@@ -1341,9 +1343,10 @@ check_send_exit_to_service (BusContext *context,
retval = FALSE;
/* Kill off the test service by sending it a quit message */
message = dbus_message_new_method_call ("org.freedesktop.TestSuite",
"Exit",
service_name);
message = dbus_message_new_method_call (service_name,
"/org/freedesktop/TestSuite",
"org.freedesktop.TestSuite",
"Exit");
if (message == NULL)
{
......@@ -1510,9 +1513,10 @@ check_existent_service_activation (BusContext *context,
dbus_error_init (&error);
message = dbus_message_new_method_call (DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"ActivateService",
DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
DBUS_PATH_ORG_FREEDESKTOP_DBUS,
DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"ActivateService");
if (message == NULL)
return TRUE;
......@@ -1720,9 +1724,10 @@ check_segfault_service_activation (BusContext *context,
dbus_error_init (&error);
message = dbus_message_new_method_call (DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"ActivateService",
DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
DBUS_PATH_ORG_FREEDESKTOP_DBUS,
DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"ActivateService");
if (message == NULL)
return TRUE;
......
......@@ -49,7 +49,8 @@ bus_driver_send_service_deleted (const char *service_name,
_dbus_verbose ("sending service deleted: %s\n", service_name);
message = dbus_message_new_signal (DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,
DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"ServiceDeleted");
if (message == NULL)
......@@ -84,7 +85,8 @@ bus_driver_send_service_created (const char *service_name,
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
message = dbus_message_new_signal (DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,
DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"ServiceCreated");
if (message == NULL)
......@@ -125,7 +127,8 @@ bus_driver_send_service_lost (DBusConnection *connection,
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
message = dbus_message_new_signal (DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,
DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"ServiceLost");
if (message == NULL)
......@@ -167,7 +170,8 @@ bus_driver_send_service_acquired (DBusConnection *connection,
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
message = dbus_message_new_signal (DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,
DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"ServiceAcquired");
if (message == NULL)
......
......@@ -403,10 +403,10 @@ dbus_bus_register (DBusConnection *connection,
return TRUE;
}
message = dbus_message_new_method_call (DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"Hello",
DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
DBUS_PATH_ORG_FREEDESKTOP_DBUS,
DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"Hello");
if (!message)
{
......@@ -522,9 +522,10 @@ dbus_bus_acquire_service (DBusConnection *connection,
_dbus_return_val_if_fail (service_name != NULL, 0);
_dbus_return_val_if_error_is_set (error, 0);
message = dbus_message_new_method_call (DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"AcquireService",
DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
DBUS_PATH_ORG_FREEDESKTOP_DBUS,
DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"AcquireService");
if (message == NULL)
{
......@@ -596,9 +597,10 @@ dbus_bus_service_exists (DBusConnection *connection,
_dbus_return_val_if_fail (service_name != NULL, FALSE);
_dbus_return_val_if_error_is_set (error, FALSE);
message = dbus_message_new_method_call (DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"ServiceExists",
DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
DBUS_PATH_ORG_FREEDESKTOP_DBUS,
DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"ServiceExists");
if (message == NULL)
{
_DBUS_SET_OOM (error);
......@@ -659,9 +661,10 @@ dbus_bus_activate_service (DBusConnection *connection,
DBusMessage *msg;
DBusMessage *reply;
msg = dbus_message_new_method_call (DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"ActivateService",
DBUS_SERVICE_ORG_FREEDESKTOP_DBUS);
msg = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
DBUS_PATH_ORG_FREEDESKTOP_DBUS,
DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
"ActivateService");
if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, service_name,
DBUS_TYPE_UINT32, flags, DBUS_TYPE_INVALID))
......
......@@ -825,7 +825,8 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
if (io_path_cond == NULL)
goto error;
disconnect_message = dbus_message_new_signal (DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
disconnect_message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_LOCAL,
DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
"Disconnected");
if (disconnect_message == NULL)
......@@ -2522,7 +2523,7 @@ dbus_connection_dispatch (DBusConnection *connection)
/* We're still protected from dispatch() reentrancy here
* since we acquired the dispatcher
*/
_dbus_verbose (" running object handler on message %p (%s)\n",
_dbus_verbose (" running object path dispatch on message %p (%s)\n",
message,
dbus_message_get_interface (message) ?
dbus_message_get_interface (message) :
......
......@@ -200,7 +200,6 @@ void dbus_connection_send_preallocated (DBusConnection
/* Object tree functionality */
typedef void (* DBusObjectPathUnregisterFunction) (DBusConnection *connection,
const char **path,
void *user_data);
typedef DBusHandlerResult (* DBusObjectPathMessageFunction) (DBusConnection *connection,
DBusMessage *message,
......
......@@ -871,8 +871,6 @@ _dbus_marshal_string_array (DBusString *str,
/**
* Marshals an object path value.
*
* @todo implement this function
*
* @param str the string to append the marshalled value to
* @param byte_order the byte order to use
......@@ -886,7 +884,41 @@ _dbus_marshal_object_path (DBusString *str,
const char **path,
int path_len)
{
int array_start, old_string_len;
int i;
old_string_len = _dbus_string_get_length (str);
/* Set the length to 0 temporarily */
if (!_dbus_marshal_uint32 (str, byte_order, 0))
goto nomem;
array_start = _dbus_string_get_length (str);
i = 0;
while (i < path_len)
{
if (!_dbus_string_append_byte (str, '/'))
goto nomem;
if (!_dbus_string_append (str, path[0]))
goto nomem;
++i;
}
/* Write the length now that we know it */
_dbus_marshal_set_uint32 (str, byte_order,
_DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
_dbus_string_get_length (str) - array_start);
return TRUE;
nomem:
/* Restore the previous length */
_dbus_string_set_length (str, old_string_len);
return FALSE;
}
static dbus_uint32_t
......@@ -1438,10 +1470,10 @@ _dbus_demarshal_string_array (const DBusString *str,
return FALSE;
}
#define VERBOSE_DECOMPOSE 0
/**
* Demarshals an object path.
*
* @todo implement this function
*
* @param str the string containing the data
* @param byte_order the byte order
......@@ -1458,7 +1490,82 @@ _dbus_demarshal_object_path (const DBusString *str,
char ***path,
int *path_len)
{
int len;
char **retval;
const char *data;
int n_components;
int i, j, comp;
len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
data = _dbus_string_get_const_data_len (str, pos, len + 1);
_dbus_assert (data != NULL);
#if VERBOSE_DECOMPOSE
_dbus_verbose ("Decomposing path \"%s\"\n",
data);
#endif
n_components = 0;
i = 0;
while (i < len)
{
if (data[i] == '/')
n_components += 1;
++i;
}
retval = dbus_new0 (char*, n_components + 1);
if (retval == NULL)
return FALSE;
comp = 0;
i = 0;
while (i < len)
{
if (data[i] == '/')
++i;
j = i;
while (j < len && data[j] != '/')
++j;
/* Now [i, j) is the path component */
_dbus_assert (i < j);
_dbus_assert (data[i] != '/');
_dbus_assert (j == len || data[j] == '/');
#if VERBOSE_DECOMPOSE
_dbus_verbose (" (component in [%d,%d))\n",
i, j);
#endif
retval[comp] = _dbus_memdup (&data[i], j - i + 1);
if (retval[comp] == NULL)
{
dbus_free_string_array (retval);
return FALSE;
}
retval[comp][j-i] = '\0';
#if VERBOSE_DECOMPOSE
_dbus_verbose (" (component %d = \"%s\")\n",
comp, retval[comp]);
#endif
++comp;
i = j;
}
_dbus_assert (i == len);
_dbus_assert (retval[0] != NULL);
*path = retval;
if (path_len)
*path_len = n_components;
if (new_pos)
*new_pos = pos + len + 1;
return TRUE;
}
/**
......@@ -1514,6 +1621,7 @@ _dbus_marshal_get_arg_end_pos (const DBusString *str,
*end_pos = _DBUS_ALIGN_VALUE (pos, 8) + 8;
break;
case DBUS_TYPE_OBJECT_PATH:
case DBUS_TYPE_STRING:
{
int len;
......@@ -1540,8 +1648,7 @@ _dbus_marshal_get_arg_end_pos (const DBusString *str,
*end_pos = pos + len;
}
break;
case DBUS_TYPE_OBJECT_PATH:
case DBUS_TYPE_ARRAY:
{
int len;
......@@ -1917,6 +2024,7 @@ _dbus_marshal_validate_arg (const DBusString *str,
}
break;
case DBUS_TYPE_OBJECT_PATH:
case DBUS_TYPE_STRING:
{
int len;
......@@ -1930,6 +2038,12 @@ _dbus_marshal_validate_arg (const DBusString *str,
if (!validate_string (str, pos, len, end_pos))
return FALSE;
if (type == DBUS_TYPE_OBJECT_PATH)
{
if (!_dbus_string_validate_path (str, pos, len))
return FALSE;
}
}
break;
......@@ -2521,7 +2635,6 @@ _dbus_marshal_test (void)
s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
_dbus_assert (strcmp (s, "Hello") == 0);
dbus_free (s);
_dbus_string_free (&str);
......
......@@ -288,6 +288,56 @@ message_type_from_string (const DBusString *str,
return -1;
}
static dbus_bool_t
append_string_field (DBusString *dest,
int endian,
const char *field_name,
int type,
const char *value)
{
int len;
if (!_dbus_string_align_length (dest, 4))
{
_dbus_warn ("could not align field name\n");
return FALSE;
}
if (!_dbus_string_append (dest, field_name))
{
_dbus_warn ("couldn't append field name\n");
return FALSE;
}
if (!_dbus_string_append_byte (dest, type))
{
_dbus_warn ("could not append typecode byte\n");
return FALSE;
}
len = strlen (value);
if (!_dbus_marshal_uint32 (dest, endian, len))
{
_dbus_warn ("couldn't append string length\n");
return FALSE;
}
if (!_dbus_string_append (dest, value))
{
_dbus_warn ("couldn't append field value\n");
return FALSE;
}
if (!_dbus_string_append_byte (dest, 0))
{
_dbus_warn ("couldn't append string nul term\n");
return FALSE;
}
return TRUE;
}
/**
* Reads the given filename, which should be in "message description
* language" (look at some examples), and builds up the message data
......@@ -298,6 +348,7 @@ message_type_from_string (const DBusString *str,
* The file format is:
* @code
* VALID_HEADER <type> normal header; byte order, type, padding, header len, body len, serial
* REQUIRED_FIELDS add required fields with placeholder values
* BIG_ENDIAN switch to big endian
* LITTLE_ENDIAN switch to little endian
* OPPOSITE_ENDIAN switch to opposite endian
......@@ -322,6 +373,7 @@ message_type_from_string (const DBusString *str,
* UINT64 <N> marshals a UINT64
* DOUBLE <N> marshals a double
* STRING 'Foo' marshals a string
* OBJECT_PATH '/foo/bar' marshals an object path
* BYTE_ARRAY { 'a', 3, 4, 5, 6} marshals a BYTE array
* BOOLEAN_ARRAY { false, true, false} marshals a BOOLEAN array
* INT32_ARRAY { 3, 4, 5, 6} marshals an INT32 array
......@@ -467,6 +519,25 @@ _dbus_message_data_load (DBusString *dest,
goto parse_failed;
}
}
else if (_dbus_string_starts_with_c_str (&line,
"REQUIRED_FIELDS"))
{
if (!append_string_field (dest, endian,
DBUS_HEADER_FIELD_INTERFACE,
DBUS_TYPE_STRING,
"org.freedesktop.BlahBlahInterface"))
goto parse_failed;
if (!append_string_field (dest, endian,
DBUS_HEADER_FIELD_MEMBER,
DBUS_TYPE_STRING,
"BlahBlahMethod"))
goto parse_failed;
if (!append_string_field (dest, endian,
DBUS_HEADER_FIELD_PATH,
DBUS_TYPE_OBJECT_PATH,
"/blah/blah/path"))
goto parse_failed;
}
else if (_dbus_string_starts_with_c_str (&line,
"BIG_ENDIAN"))
{
......@@ -648,6 +719,8 @@ _dbus_message_data_load (DBusString *dest,
code = DBUS_TYPE_DOUBLE;
else if (_dbus_string_starts_with_c_str (&line, "STRING"))
code = DBUS_TYPE_STRING;
else if (_dbus_string_starts_with_c_str (&line, "OBJECT_PATH"))
code = DBUS_TYPE_OBJECT_PATH;
else if (_dbus_string_starts_with_c_str (&line, "NAMED"))
code = DBUS_TYPE_NAMED;
else if (_dbus_string_starts_with_c_str (&line, "ARRAY"))
......@@ -1270,6 +1343,36 @@ _dbus_message_data_load (DBusString *dest,
PERFORM_UNALIGN (dest);
}
else if (_dbus_string_starts_with_c_str (&line,
"OBJECT_PATH"))
{
SAVE_FOR_UNALIGN (dest, 4);
int size_offset;
int old_len;
_dbus_string_delete_first_word (&line);
size_offset = _dbus_string_get_length (dest);
size_offset = _DBUS_ALIGN_VALUE (size_offset, 4);
if (!_dbus_marshal_uint32 (dest, endian, 0))
{
_dbus_warn ("Failed to append string size\n");
goto parse_failed;
}
old_len = _dbus_string_get_length (dest);
if (!append_quoted_string (dest, &line, 0, NULL))
{
_dbus_warn ("Failed to append quoted string\n");
goto parse_failed;
}
_dbus_marshal_set_uint32 (dest, endian, size_offset,
/* subtract 1 for nul */
_dbus_string_get_length (dest) - old_len - 1);
PERFORM_UNALIGN (dest);
}
else
goto parse_failed;
......
This diff is collapsed.
......@@ -58,11 +58,13 @@ struct DBusMessageIter
};
DBusMessage* dbus_message_new (int message_type);
DBusMessage* dbus_message_new_method_call (const char *interface,
const char *method,
const char *destination_service);
DBusMessage* dbus_message_new_method_call (const char *service,
const char *path,
const char *interface,
const char *method);
DBusMessage* dbus_message_new_method_return (DBusMessage *method_call);
DBusMessage* dbus_message_new_signal (const char *interface,
DBusMessage* dbus_message_new_signal (const char *path,
const char *interface,
const char *name);
DBusMessage* dbus_message_new_error (DBusMessage *reply_to,
const char *error_name,
......@@ -73,6 +75,9 @@ DBusMessage *dbus_message_copy (const DBusMessage *message);
void dbus_message_ref (DBusMessage *message);
void dbus_message_unref (DBusMessage *message);
int dbus_message_get_type (DBusMessage *message);
dbus_bool_t dbus_message_set_path (DBusMessage *message,
const char *object_path);
const char* dbus_message_get_path (DBusMessage *message);
dbus_bool_t dbus_message_set_interface (DBusMessage *message,
const char *interface);
const char* dbus_message_get_interface (DBusMessage *message);
......@@ -108,6 +113,9 @@ dbus_bool_t dbus_message_set_reply_serial (DBusMessage *message,
dbus_uint32_t reply_serial);
dbus_uint32_t dbus_message_get_reply_serial (DBusMessage *message);
dbus_bool_t dbus_message_get_path_decomposed (DBusMessage *message,
char ***path);
dbus_bool_t dbus_message_append_args (DBusMessage *message,
int first_arg_type,
...);
......
This diff is collapsed.
......@@ -71,17 +71,22 @@ extern "C" {
#define DBUS_HEADER_FLAG_NO_REPLY_EXPECTED 0x1
/* Header fields */
#define DBUS_HEADER_FIELD_INTERFACE "ifce"
#define DBUS_HEADER_FIELD_MEMBER "mebr"
#define DBUS_HEADER_FIELD_ERROR_NAME "ernm"
#define DBUS_HEADER_FIELD_SERVICE "srvc"
#define DBUS_HEADER_FIELD_REPLY "rply"
#define DBUS_HEADER_FIELD_SENDER "sndr"
#define DBUS_HEADER_FIELD_PATH "path"
#define DBUS_HEADER_FIELD_INTERFACE "ifce"
#define DBUS_HEADER_FIELD_MEMBER "mebr"
#define DBUS_HEADER_FIELD_ERROR_NAME "ernm"
#define DBUS_HEADER_FIELD_SERVICE "srvc"
#define DBUS_HEADER_FIELD_REPLY "rply"
#define DBUS_HEADER_FIELD_SENDER_SERVICE "sdrs"
/* Services */
#define DBUS_SERVICE_ORG_FREEDESKTOP_DBUS "org.freedesktop.DBus"
#define DBUS_SERVICE_ORG_FREEDESKTOP_BROADCAST "org.freedesktop.Broadcast"
/* Paths */
#define DBUS_PATH_ORG_FREEDESKTOP_DBUS "/org/freedesktop/DBus"
#define DBUS_PATH_ORG_FREEDESKTOP_LOCAL "/org/freedesktop/Local"
/* Service owner flags */
#define DBUS_SERVICE_FLAG_PROHIBIT_REPLACEMENT 0x1
#define DBUS_SERVICE_FLAG_REPLACE_EXISTING 0x2
......
......@@ -2845,6 +2845,74 @@ _dbus_string_validate_nul (const DBusString *str,
return TRUE;
}
/**
* Checks that the given range of the string is a valid object path
* name in the D-BUS protocol. This includes a length restriction,
* etc., see the specification. It does not validate UTF-8, that has
* to be done separately for now.
*
* @todo this is inconsistent with most of DBusString in that
* it allows a start,len range that isn't in the string.
*
* @todo change spec to disallow more things, such as spaces in the
* path name
*
* @param str the string
* @param start first byte index to check
* @param len number of bytes to check
* @returns #TRUE if the byte range exists and is a valid name
*/
dbus_bool_t
_dbus_string_validate_path (const DBusString *str,
int start,
int len)
{
const unsigned char *s;
const unsigned char *end;
const unsigned char *last_slash;