summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-message.c
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@codefactory.se>2003-01-21 09:23:18 +0000
committerAnders Carlsson <andersca@codefactory.se>2003-01-21 09:23:18 +0000
commit4a85d321b4516c6a663e8bdd530ba59018c974df (patch)
tree2a78137703eb302a46b068654c31e8aaf8b8bf56 /dbus/dbus-message.c
parent84f2a1ad2f867f9397de449365f80c5c003296fa (diff)
2003-01-21 Anders Carlsson <andersca@codefactory.se>
* dbus/dbus-connection.c: (dbus_connection_send_message): Add a new client_serial parameter. (dbus_connection_send_message_with_reply): Remove a @todo since we've implemented the blocking function. (dbus_connection_send_message_with_reply_and_block): New function that sends a message and waits for a reply and then returns the reply. * dbus/dbus-connection.h: Add new functions. * dbus/dbus-errors.c: (dbus_result_to_string): * dbus/dbus-errors.h: Add new DBUS_RESULT. * dbus/dbus-message-internal.h: * dbus/dbus-message.c: (_dbus_message_get_reply_serial), (_dbus_message_set_sender), (dbus_message_write_header), (dbus_message_new_reply), (decode_header_data), (_dbus_message_loader_return_buffer), (_dbus_message_test): * dbus/dbus-message.h: Add new functions that set the reply serial and sender. Also marshal and demarshal them correctly and add test. * dbus/dbus-protocol.h: Add new DBUS_MESSAGE_TYPE_SENDER. * glib/dbus-glib.h: * glib/dbus-gmain.c: (watch_callback), (free_callback_data), (add_watch), (remove_watch), (add_timeout), (remove_timeout), (dbus_connection_hookup_with_g_main): * glib/test-dbus-glib.c: (main): Rewrite to use GIOChannel and remove the GSource crack. * test/echo-client.c: (main): * test/watch.c: (check_messages): Update for changed APIs
Diffstat (limited to 'dbus/dbus-message.c')
-rw-r--r--dbus/dbus-message.c115
1 files changed, 110 insertions, 5 deletions
diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c
index 5767bda6..e491a7db 100644
--- a/dbus/dbus-message.c
+++ b/dbus/dbus-message.c
@@ -62,6 +62,7 @@ struct DBusMessage
char *name; /**< Message name. */
char *service; /**< Message destination service. */
+ char *sender; /**< Message sender service. */
dbus_int32_t client_serial; /**< Client serial or -1 if not set */
dbus_int32_t reply_serial; /**< Reply serial or -1 if not set */
@@ -124,6 +125,35 @@ _dbus_message_set_client_serial (DBusMessage *message,
}
/**
+ * Returns the serial that the message is
+ * a reply to.
+ *
+ * @param message the message
+ * @returns the reply serial
+ */
+dbus_int32_t
+_dbus_message_get_reply_serial (DBusMessage *message)
+{
+ return message->client_serial;
+}
+
+/**
+ * Sets the message sender. This can only
+ * be done once on a message.
+ *
+ * @param message the message
+ * @param sender the sender
+ */
+void
+_dbus_message_set_sender (DBusMessage *message,
+ const char *sender)
+{
+ _dbus_assert (message->sender == NULL);
+
+ message->sender = _dbus_strdup (sender);
+}
+
+/**
* Adds a counter to be incremented immediately with the
* size of this message, and decremented by the size
* of this message when this message if finalized.
@@ -199,12 +229,24 @@ dbus_message_write_header (DBusMessage *message)
/* Marshal reply serial */
if (message->reply_serial != -1)
{
+ _dbus_string_align_length (&message->header, 4);
_dbus_string_append_len (&message->header, DBUS_HEADER_FIELD_REPLY, 4);
_dbus_string_append_byte (&message->header, DBUS_TYPE_INT32);
_dbus_marshal_int32 (&message->header, DBUS_COMPILER_BYTE_ORDER,
message->reply_serial);
}
+
+ /* Marshal sender */
+ if (message->sender)
+ {
+ _dbus_string_align_length (&message->header, 4);
+ _dbus_string_append_len (&message->header, DBUS_HEADER_FIELD_SENDER, 4);
+ _dbus_string_append_byte (&message->header, DBUS_TYPE_STRING);
+
+ _dbus_marshal_string (&message->header, DBUS_COMPILER_BYTE_ORDER,
+ message->sender);
+ }
/* Fill in the length */
_dbus_string_get_data_len (&message->header, &len_data, 4, 4);
@@ -302,6 +344,35 @@ dbus_message_new (const char *service,
return message;
}
+/**
+ * Constructs a message that is a reply to some other
+ * message. Returns #NULL if memory can't be allocated
+ * for the message.
+ *
+ * @param name the name of the message
+ * @param original_message the message which the created
+ * message is a reply to.
+ * @returns a new DBusMessage, free with dbus_message_unref()
+ * @see dbus_message_new(), dbus_message_unref()
+ */
+DBusMessage*
+dbus_message_new_reply (const char *name,
+ DBusMessage *original_message)
+{
+ DBusMessage *message;
+
+ _dbus_assert (original_message->sender != NULL);
+
+ message = dbus_message_new (original_message->sender, name);
+
+ if (message == NULL)
+ return NULL;
+
+ message->reply_serial = original_message->client_serial;
+
+ return message;
+}
+
/**
* Increments the reference count of a DBusMessage.
@@ -1126,6 +1197,11 @@ _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
#define DBUS_HEADER_FIELD_REPLY_AS_UINT32 \
FOUR_CHARS_TO_UINT32 ('r', 'p', 'l', 'y')
+/** DBUS_HEADER_FIELD_SENDER Packed into a dbus_uint32_t */
+#define DBUS_HEADER_FIELD_SENDER_AS_UINT32 \
+ FOUR_CHARS_TO_UINT32 ('s', 'n', 'd', 'r')
+
+
/* FIXME should be using DBusString for the stuff we demarshal. char*
* evil. Also, out of memory handling here seems suboptimal.
* Should probably report it as a distinct error from "corrupt message,"
@@ -1137,8 +1213,10 @@ decode_header_data (DBusString *data,
int header_len,
int byte_order,
dbus_int32_t *client_serial,
+ dbus_int32_t *reply_serial,
char **service,
- char **name)
+ char **name,
+ char **sender)
{
const char *field;
int pos, new_pos;
@@ -1148,6 +1226,7 @@ decode_header_data (DBusString *data,
*service = NULL;
*name = NULL;
+ *sender = NULL;
/* Now handle the fields */
while (pos < header_len)
@@ -1189,6 +1268,21 @@ decode_header_data (DBusString *data,
*name = _dbus_demarshal_string (data, byte_order, pos + 1, &new_pos);
/* FIXME check for demarshal failure SECURITY */
break;
+ case DBUS_HEADER_FIELD_SENDER_AS_UINT32:
+ if (*sender != NULL)
+ {
+ _dbus_verbose ("%s field provided twice\n",
+ DBUS_HEADER_FIELD_NAME);
+ goto failed;
+ }
+
+ *sender = _dbus_demarshal_string (data, byte_order, pos + 1, &new_pos);
+ /* FIXME check for demarshal failure SECURITY */
+ break;
+ case DBUS_HEADER_FIELD_REPLY_AS_UINT32:
+ *reply_serial = _dbus_demarshal_int32 (data, byte_order, pos + 1, &new_pos);
+
+ break;
default:
_dbus_verbose ("Ignoring an unknown header field: %c%c%c%c\n",
field[0], field[1], field[2], field[3]);
@@ -1268,23 +1362,29 @@ _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
if (_dbus_string_get_length (&loader->data) >= header_len + body_len)
{
- dbus_int32_t client_serial;
- char *service, *name;
+ dbus_int32_t client_serial, reply_serial;
+ char *service, *name, *sender;
/* FIXME right now if this doesn't have enough memory, the
* loader becomes corrupted. Instead we should just not
* parse this message for now.
*/
if (!decode_header_data (&loader->data, header_len, byte_order,
- &client_serial, &service, &name))
+ &client_serial, &reply_serial, &service, &name, &sender))
{
loader->corrupted = TRUE;
return;
}
+
message = dbus_message_new (service, name);
+ message->reply_serial = reply_serial;
+ message->client_serial = client_serial;
+ _dbus_message_set_sender (message, sender);
+
dbus_free (service);
dbus_free (name);
+ dbus_free (sender);
if (message == NULL)
break; /* ugh, postpone this I guess. */
@@ -1297,7 +1397,7 @@ _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
_dbus_assert (_dbus_string_get_length (&message->header) == 0);
_dbus_assert (_dbus_string_get_length (&message->body) == 0);
-
+
if (!_dbus_string_move_len (&loader->data, 0, header_len, &message->header, 0))
{
_dbus_list_remove_last (&loader->messages, message);
@@ -1486,6 +1586,8 @@ _dbus_message_test (void)
message = dbus_message_new ("org.freedesktop.DBus.Test", "testMessage");
message->client_serial = 1;
+ message->reply_serial = 0x12345678;
+
dbus_message_append_string (message, "Test string");
dbus_message_append_int32 (message, -0x12345678);
dbus_message_append_uint32 (message, 0xedd1e);
@@ -1529,6 +1631,9 @@ _dbus_message_test (void)
if (!message)
_dbus_assert_not_reached ("received a NULL message");
+ if (message->reply_serial != 0x12345678)
+ _dbus_assert_not_reached ("reply serial fields differ");
+
message_iter_test (message);
dbus_message_unref (message);