From 5ebb5748c2a7587c734eeed9c66f2a1fc0635d09 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Thu, 30 Jan 2003 20:49:11 +0000 Subject: [PATCH] 2003-01-30 Anders Carlsson * dbus/Makefile.am: Add dbus-address.[ch] * dbus/dbus-address.c: (dbus_address_entry_free), (dbus_address_entries_free), (create_entry), (dbus_address_entry_get_method), (dbus_address_entry_get_value), (dbus_parse_address), (_dbus_address_test): * dbus/dbus-address.h: New files for dealing with address parsing. * dbus/dbus-connection.c: Document timeout functions. * dbus/dbus-message.c: Document dbus_message_new_from_message. * dbus/dbus-server-debug.c: Document. * dbus/dbus-server.c: (dbus_server_listen): Parse address and use correct server implementation. * dbus/dbus-string.c: (_dbus_string_find_to), (_dbus_string_test): * dbus/dbus-string.h: New function with test. * dbus/dbus-test.c: (dbus_internal_symbol_do_not_use_run_tests): * dbus/dbus-test.h: Add address tests. * dbus/dbus-transport-debug.c: Document. * dbus/dbus-transport.c: (_dbus_transport_open): Parse address and use correct transport implementation. --- ChangeLog | 38 ++++ dbus/Makefile.am | 2 + dbus/dbus-address.c | 415 ++++++++++++++++++++++++++++++++++++++++++++ dbus/dbus-address.h | 48 +++++ dbus/dbus-connection.c | 18 ++ dbus/dbus-message.c | 10 ++ dbus/dbus-server-debug.c | 27 +++ dbus/dbus-server.c | 64 ++++++- dbus/dbus-string.c | 78 +++++++++ dbus/dbus-string.h | 5 + dbus/dbus-test.c | 8 +- dbus/dbus-test.h | 1 + dbus/dbus-transport-debug.c | 33 +++- dbus/dbus-transport.c | 56 ++++-- 14 files changed, 778 insertions(+), 25 deletions(-) create mode 100644 dbus/dbus-address.c create mode 100644 dbus/dbus-address.h diff --git a/ChangeLog b/ChangeLog index 2fced37..32f47bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,41 @@ +2003-01-30 Anders Carlsson + + * dbus/Makefile.am: + Add dbus-address.[ch] + + * dbus/dbus-address.c: (dbus_address_entry_free), + (dbus_address_entries_free), (create_entry), + (dbus_address_entry_get_method), (dbus_address_entry_get_value), + (dbus_parse_address), (_dbus_address_test): + * dbus/dbus-address.h: + New files for dealing with address parsing. + + * dbus/dbus-connection.c: + Document timeout functions. + + * dbus/dbus-message.c: + Document dbus_message_new_from_message. + + * dbus/dbus-server-debug.c: + Document. + + * dbus/dbus-server.c: (dbus_server_listen): + Parse address and use correct server implementation. + + * dbus/dbus-string.c: (_dbus_string_find_to), (_dbus_string_test): + * dbus/dbus-string.h: + New function with test. + + * dbus/dbus-test.c: (dbus_internal_symbol_do_not_use_run_tests): + * dbus/dbus-test.h: + Add address tests. + + * dbus/dbus-transport-debug.c: + Document. + + * dbus/dbus-transport.c: (_dbus_transport_open): + Parse address and use correct transport implementation. + 2003-01-30 Havoc Pennington * dbus/dbus-message.c: use message->byte_order instead of diff --git a/dbus/Makefile.am b/dbus/Makefile.am index b97ed6b..98090a6 100644 --- a/dbus/Makefile.am +++ b/dbus/Makefile.am @@ -7,6 +7,7 @@ lib_LTLIBRARIES=libdbus-1.la dbusinclude_HEADERS= \ dbus.h \ + dbus-address.h \ dbus-connection.h \ dbus-errors.h \ dbus-macros.h \ @@ -19,6 +20,7 @@ dbusinclude_HEADERS= \ dbus-types.h libdbus_1_la_SOURCES= \ + dbus-address.c \ dbus-auth.c \ dbus-auth.h \ dbus-connection.c \ diff --git a/dbus/dbus-address.c b/dbus/dbus-address.c new file mode 100644 index 0000000..5b65f2f --- /dev/null +++ b/dbus/dbus-address.c @@ -0,0 +1,415 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-address.c Server address parser. + * + * Copyright (C) 2003 CodeFactory AB + * + * 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 + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * 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 + * + */ + +#include +#include "dbus-address.h" +#include "dbus-internals.h" +#include "dbus-list.h" + +/** + * @defgroup DBusAddress address parsing + * @ingroup DBus + * @brief Parsing addresses to DBus servers. + * + * @{ + */ +struct DBusAddressEntry +{ + DBusString method; + + DBusList *keys; + DBusList *values; +}; + +static void +dbus_address_entry_free (DBusAddressEntry *entry) +{ + DBusList *link; + + _dbus_string_free (&entry->method); + + link = _dbus_list_get_first_link (&entry->keys); + while (link != NULL) + { + _dbus_string_free (link->data); + dbus_free (link->data); + + link = _dbus_list_get_next_link (&entry->keys, link); + } + + link = _dbus_list_get_first_link (&entry->values); + while (link != NULL) + { + _dbus_string_free (link->data); + dbus_free (link->data); + + link = _dbus_list_get_next_link (&entry->values, link); + } + + dbus_free (entry); +} + + +/** + * Frees a #NULL-terminated array of address entries. + * + * @param entries the array. + */ +void +dbus_address_entries_free (DBusAddressEntry **entries) +{ + int i; + + for (i = 0; entries[i] != NULL; i++) + dbus_address_entry_free (entries[i]); + dbus_free (entries); +} + +static DBusAddressEntry * +create_entry (void) +{ + DBusAddressEntry *entry; + + entry = dbus_new0 (DBusAddressEntry, 1); + + if (entry == NULL) + return NULL; + + if (!_dbus_string_init (&entry->method, _DBUS_INT_MAX)) + dbus_free (entry); + + return entry; +} + +/** + * Returns the method string of an address entry. + * + * @param entry the entry. + * @returns a string describing the method. This string + * must not be freed. + */ +const char * +dbus_address_entry_get_method (DBusAddressEntry *entry) +{ + const char *method; + + _dbus_string_get_const_data (&entry->method, &method); + + return method; +} + +/** + * Returns a value from a key of an entry. + * + * @param entry the entry. + * @param key the key. + * @returns the key value. This string must not be fred. + */ +const char * +dbus_address_entry_get_value (DBusAddressEntry *entry, + const char *key) +{ + DBusList *values, *keys; + + keys = _dbus_list_get_first_link (&entry->keys); + values = _dbus_list_get_first_link (&entry->values); + + while (keys != NULL) + { + _dbus_assert (values != NULL); + + if (_dbus_string_equal_c_str (keys->data, key)) + { + const char *str; + + _dbus_string_get_const_data (values->data, &str); + return str; + } + keys = _dbus_list_get_next_link (&entry->keys, keys); + values = _dbus_list_get_next_link (&entry->values, values); + } + + return NULL; +} + +/** + * Parses an address string of the form: + * + * method:key=value,key=value;method:key=value + * + * @param address the address. + * @param entry return location to an array of entries. + * @param array_len return location for array length. + * @param result return location for result code. + * @returns #TRUE on success, #FALSE otherwise. + */ +dbus_bool_t +dbus_parse_address (const char *address, + DBusAddressEntry ***entry, + int *array_len, + DBusResultCode *result) +{ + DBusString str; + int pos, end_pos, len, i; + DBusList *entries, *link; + DBusAddressEntry **entry_array; + + _dbus_string_init_const (&str, address); + + entries = NULL; + pos = 0; + len = _dbus_string_get_length (&str); + + while (pos < len) + { + DBusAddressEntry *entry; + + int found_pos; + + entry = create_entry (); + if (!entry) + { + dbus_set_result (result, DBUS_RESULT_NO_MEMORY); + + goto error; + } + + /* Append the entry */ + if (!_dbus_list_append (&entries, entry)) + { + dbus_set_result (result, DBUS_RESULT_NO_MEMORY); + dbus_address_entry_free (entry); + goto error; + } + + /* Look for a semi-colon */ + if (!_dbus_string_find (&str, pos, ";", &end_pos)) + end_pos = len; + + /* Look for the colon : */ + if (!_dbus_string_find_to (&str, pos, end_pos, ":", &found_pos)) + { + dbus_set_result (result, DBUS_RESULT_BAD_ADDRESS); + goto error; + } + + if (!_dbus_string_copy_len (&str, pos, found_pos - pos, &entry->method, 0)) + { + dbus_set_result (result, DBUS_RESULT_NO_MEMORY); + goto error; + } + + pos = found_pos + 1; + + while (pos < end_pos) + { + int comma_pos, equals_pos; + + if (!_dbus_string_find_to (&str, pos, end_pos, ",", &comma_pos)) + comma_pos = end_pos; + + if (!_dbus_string_find (&str, pos, "=", &equals_pos) || + equals_pos == pos || equals_pos + 1 == end_pos) + { + dbus_set_result (result, DBUS_RESULT_BAD_ADDRESS); + goto error; + } + else + { + DBusString *key; + DBusString *value; + + key = dbus_new0 (DBusString, 1); + + if (!key) + { + dbus_set_result (result, DBUS_RESULT_NO_MEMORY); + goto error; + } + + value = dbus_new0 (DBusString, 1); + if (!value) + { + dbus_set_result (result, DBUS_RESULT_NO_MEMORY); + dbus_free (key); + goto error; + } + + if (!_dbus_string_init (key, _DBUS_INT_MAX)) + { + dbus_set_result (result, DBUS_RESULT_NO_MEMORY); + dbus_free (key); + dbus_free (value); + + goto error; + } + + if (!_dbus_string_init (value, _DBUS_INT_MAX)) + { + dbus_set_result (result, DBUS_RESULT_NO_MEMORY); + _dbus_string_free (key); + + dbus_free (key); + dbus_free (value); + goto error; + } + + if (!_dbus_string_copy_len (&str, pos, equals_pos - pos, key, 0)) + { + dbus_set_result (result, DBUS_RESULT_NO_MEMORY); + _dbus_string_free (key); + _dbus_string_free (value); + + dbus_free (key); + dbus_free (value); + goto error; + } + + if (!_dbus_string_copy_len (&str, equals_pos + 1, comma_pos - equals_pos - 1, value, 0)) + { + dbus_set_result (result, DBUS_RESULT_NO_MEMORY); + _dbus_string_free (key); + _dbus_string_free (value); + + dbus_free (key); + dbus_free (value); + goto error; + } + + if (!_dbus_list_append (&entry->keys, key)) + { + dbus_set_result (result, DBUS_RESULT_NO_MEMORY); + _dbus_string_free (key); + _dbus_string_free (value); + + dbus_free (key); + dbus_free (value); + goto error; + } + + if (!_dbus_list_append (&entry->values, value)) + { + dbus_set_result (result, DBUS_RESULT_NO_MEMORY); + _dbus_string_free (value); + + dbus_free (value); + goto error; + } + } + + pos = comma_pos + 1; + } + + pos = end_pos + 1; + } + + *array_len = _dbus_list_get_length (&entries); + + entry_array = dbus_new (DBusAddressEntry *, *array_len + 1); + + if (!entry_array) + { + dbus_set_result (result, DBUS_RESULT_NO_MEMORY); + + goto error; + } + + entry_array [*array_len] = NULL; + + link = _dbus_list_get_first_link (&entries); + i = 0; + while (link != NULL) + { + entry_array[i] = link->data; + i++; + link = _dbus_list_get_next_link (&entries, link); + } + + _dbus_list_clear (&entries); + *entry = entry_array; + + dbus_set_result (result, DBUS_RESULT_SUCCESS); + return TRUE; + + error: + + link = _dbus_list_get_first_link (&entries); + while (link != NULL) + { + dbus_address_entry_free (link->data); + link = _dbus_list_get_next_link (&entries, link); + } + + return FALSE; + +} + + +/** @} */ + +#ifdef DBUS_BUILD_TESTS +#include "dbus-test.h" + +dbus_bool_t +_dbus_address_test (void) +{ + DBusAddressEntry **entries; + int len; + DBusResultCode result; + + if (!dbus_parse_address ("unix:path=/tmp/foo;debug:name=test,sliff=sloff;", + &entries, &len, &result)) + _dbus_assert_not_reached ("could not parse address"); + _dbus_assert (len == 2); + _dbus_assert (strcmp (dbus_address_entry_get_value (entries[0], "path"), "/tmp/foo") == 0); + _dbus_assert (strcmp (dbus_address_entry_get_value (entries[1], "name"), "test") == 0); + _dbus_assert (strcmp (dbus_address_entry_get_value (entries[1], "sliff"), "sloff") == 0); + + dbus_address_entries_free (entries); + + /* Different possible errors */ + if (dbus_parse_address ("foo", &entries, &len, &result)) + _dbus_assert_not_reached ("Parsed incorrect address."); + + if (dbus_parse_address ("foo:bar", &entries, &len, &result)) + _dbus_assert_not_reached ("Parsed incorrect address."); + + if (dbus_parse_address ("foo:bar,baz", &entries, &len, &result)) + _dbus_assert_not_reached ("Parsed incorrect address."); + + if (dbus_parse_address ("foo:bar=foo,baz", &entries, &len, &result)) + _dbus_assert_not_reached ("Parsed incorrect address."); + + if (dbus_parse_address ("foo:bar=foo;baz", &entries, &len, &result)) + _dbus_assert_not_reached ("Parsed incorrect address."); + + if (dbus_parse_address ("foo:=foo", &entries, &len, &result)) + _dbus_assert_not_reached ("Parsed incorrect address."); + + if (dbus_parse_address ("foo:foo=", &entries, &len, &result)) + _dbus_assert_not_reached ("Parsed incorrect address."); + + return TRUE; +} + +#endif diff --git a/dbus/dbus-address.h b/dbus/dbus-address.h new file mode 100644 index 0000000..294eb2b --- /dev/null +++ b/dbus/dbus-address.h @@ -0,0 +1,48 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-address.h Server address parser. + * + * Copyright (C) 2003 CodeFactory AB + * + * 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 + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * 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 + * + */ +#if !defined (DBUS_INSIDE_DBUS_H) && !defined (DBUS_COMPILATION) +#error "Only can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_ADDRESS_H +#define DBUS_ADDRESS_H + +#include +#include + +typedef struct DBusAddressEntry DBusAddressEntry; + +dbus_bool_t dbus_parse_address (const char *address, + DBusAddressEntry ***entry, + int *array_len, + DBusResultCode *result); +const char *dbus_address_entry_get_value (DBusAddressEntry *entry, + const char *key); +const char *dbus_address_entry_get_method (DBusAddressEntry *entry); +void dbus_address_entries_free (DBusAddressEntry **entries); + + + + +#endif /* DBUS_ADDRESS_H */ + diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 4054f45..3bc8d2d 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -223,6 +223,16 @@ _dbus_connection_remove_watch (DBusConnection *connection, watch); } +/** + * Adds a timeout using the connection's DBusAddTimeoutFunction if + * available. Otherwise records the timeout to be added when said + * function is available. Also re-adds the timeout if the + * DBusAddTimeoutFunction changes. May fail due to lack of memory. + * + * @param connection the connection. + * @param timeout the timeout to add. + * @returns #TRUE on success. + */ dbus_bool_t _dbus_connection_add_timeout (DBusConnection *connection, DBusTimeout *timeout) @@ -234,6 +244,14 @@ _dbus_connection_add_timeout (DBusConnection *connection, return FALSE; } +/** + * Removes a timeout using the connection's DBusRemoveTimeoutFunction + * if available. It's an error to call this function on a timeout + * that was not previously added. + * + * @param connection the connection. + * @param timeout the timeout to remove. + */ void _dbus_connection_remove_timeout (DBusConnection *connection, DBusTimeout *timeout) diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index 85b49cb..1c9c7ea 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -774,6 +774,12 @@ dbus_message_new_reply (const char *name, return message; } +/** + * Creates a new message that is an exact replica of the message + * specified, except that its refcount is set to 1. + * + * @param message the message. + * @returns the new message. DBusMessage * dbus_message_new_from_message (const DBusMessage *message) { @@ -1628,6 +1634,10 @@ dbus_message_get_sender (DBusMessage *message) * _DBUS_INT_MAX; and add 16 for paranoia, since a message * over 128M is pretty nuts anyhow. */ + +/** + * The maximum sane message size. + */ #define MAX_SANE_MESSAGE_SIZE (_DBUS_INT_MAX/16) /** diff --git a/dbus/dbus-server-debug.c b/dbus/dbus-server-debug.c index b9305b7..57d6806 100644 --- a/dbus/dbus-server-debug.c +++ b/dbus/dbus-server-debug.c @@ -40,8 +40,14 @@ * @{ */ +/** + * Default timeout interval when reading or writing. + */ #define DEFAULT_INTERVAL 10 +/** + * Opaque object representing a debug server implementation. + */ typedef struct DBusServerDebug DBusServerDebug; /** @@ -83,6 +89,12 @@ static DBusServerVTable debug_vtable = { debug_disconnect }; +/** + * Looks up a server by its name. + * + * @param server_name the server name. + * @returns the server, or #NULL if none exists. + */ DBusServer* _dbus_server_debug_lookup (const char *server_name) { @@ -92,6 +104,13 @@ _dbus_server_debug_lookup (const char *server_name) return _dbus_hash_table_lookup_string (server_hash, server_name); } +/** + * Creates a new debug server. + * + * @param server_name the name of the server. + * @param result address where a result code can be returned. + * @returns a new server, or #NULL on failure. + */ DBusServer* _dbus_server_debug_new (const char *server_name, DBusResultCode *result) @@ -200,6 +219,14 @@ handle_new_client (void *data) dbus_connection_unref (connection); } +/** + * Tells the server to accept a transport so the transport + * can send messages to it. + * + * @param server the server + * @param transport the transport + * @returns #TRUE on success. + */ dbus_bool_t _dbus_server_debug_accept_transport (DBusServer *server, DBusTransport *transport) diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c index 1407c47..5177431 100644 --- a/dbus/dbus-server.c +++ b/dbus/dbus-server.c @@ -25,6 +25,7 @@ #ifdef DBUS_BUILD_TESTS #include "dbus-server-debug.h" #endif +#include "dbus-address.h" /** * @defgroup DBusServer DBusServer @@ -134,6 +135,13 @@ _dbus_server_remove_watch (DBusServer *server, _dbus_watch_list_remove_watch (server->watches, watch); } +/** + * Adds a timeout for this server, chaining out to application-provided + * timeout handlers. + * + * @param server the server. + * @param timeout the timeout to add. + */ dbus_bool_t _dbus_server_add_timeout (DBusServer *server, DBusTimeout *timeout) @@ -141,6 +149,12 @@ _dbus_server_add_timeout (DBusServer *server, return _dbus_timeout_list_add_timeout (server->timeouts, timeout); } +/** + * Removes a timeout previously added with _dbus_server_add_timeout(). + * + * @param server the server. + * @param timeout the timeout to remove. + */ void _dbus_server_remove_timeout (DBusServer *server, DBusTimeout *timeout) @@ -187,15 +201,53 @@ dbus_server_listen (const char *address, DBusResultCode *result) { DBusServer *server; + DBusAddressEntry **entries; + int len, i; + + if (!dbus_parse_address (address, &entries, &len, result)) + return NULL; -#if 1 - /* For now just pretend the address is a unix domain socket path */ - server = _dbus_server_new_for_domain_socket (address, result); -#else - server = _dbus_server_debug_new (address, result); -#endif + server = NULL; + + for (i = 0; i < len; i++) + { + const char *method = dbus_address_entry_get_method (entries[i]); + + if (strcmp (method, "unix") == 0) + { + const char *path = dbus_address_entry_get_value (entries[i], "path"); + + if (path == NULL) + goto bad_address; + + server = _dbus_server_new_for_domain_socket (path, result); + + if (server) + break; + } + else if (strcmp (method, "debug") == 0) + { + const char *name = dbus_address_entry_get_value (entries[i], "name"); + + if (name == NULL) + goto bad_address; + + server = _dbus_server_debug_new (name, result); + + if (server) + break; + } + else goto bad_address; + } + dbus_address_entries_free (entries); return server; + + bad_address: + dbus_address_entries_free (entries); + dbus_set_result (result, DBUS_RESULT_BAD_ADDRESS); + + return NULL; } /** diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index f453dcb..05d14ba 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -1222,6 +1222,78 @@ _dbus_string_find (const DBusString *str, } /** + * Finds the given substring in the string, + * up to a certain position, + * returning #TRUE and filling in the byte index + * where the substring was found, if it was found. + * Returns #FALSE if the substring wasn't found. + * Sets *start to the length of the string if the substring + * is not found. + * + * @param str the string + * @param start where to start looking + * @param end where to stop looking + * @param substr the substring + * @param found return location for where it was found, or #NULL + * @returns #TRUE if found + */ +dbus_bool_t +_dbus_string_find_to (const DBusString *str, + int start, + int end, + const char *substr, + int *found) +{ + int i; + DBUS_CONST_STRING_PREAMBLE (str); + _dbus_assert (substr != NULL); + _dbus_assert (start <= real->len); + _dbus_assert (end <= real->len); + _dbus_assert (start < end); + + /* we always "find" an empty string */ + if (*substr == '\0') + { + if (found) + *found = 0; + return TRUE; + } + + i = start; + while (i < real->len && i < end) + { + if (real->str[i] == substr[0]) + { + int j = i + 1; + + while (j < real->len && j < end) + { + if (substr[j - i] == '\0') + break; + else if (real->str[j] != substr[j - i]) + break; + + ++j; + } + + if (substr[j - i] == '\0') + { + if (found) + *found = i; + return TRUE; + } + } + + ++i; + } + + if (found) + *found = end; + + return FALSE; +} + +/** * Finds a blank (space or tab) in the string. Returns #TRUE * if found, #FALSE otherwise. If a blank is not found sets * *found to the length of the string. @@ -2294,6 +2366,12 @@ _dbus_string_test (void) if (_dbus_string_find (&str, 0, "q", NULL)) _dbus_assert_not_reached ("Did find 'q'"); + + if (!_dbus_string_find_to (&str, 0, 2, "He", NULL)) + _dbus_assert_not_reached ("Didn't find 'He'"); + + if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL)) + _dbus_assert_not_reached ("Did find 'Hello'"); _dbus_string_free (&str); diff --git a/dbus/dbus-string.h b/dbus/dbus-string.h index e71f7fe..641eaf5 100644 --- a/dbus/dbus-string.h +++ b/dbus/dbus-string.h @@ -149,6 +149,11 @@ dbus_bool_t _dbus_string_find (const DBusString *str, const char *substr, int *found); +dbus_bool_t _dbus_string_find_to (const DBusString *str, + int start, + int end, + const char *substr, + int *found); dbus_bool_t _dbus_string_find_blank (const DBusString *str, int start, int *found); diff --git a/dbus/dbus-test.c b/dbus/dbus-test.c index 337ef10..f52504a 100644 --- a/dbus/dbus-test.c +++ b/dbus/dbus-test.c @@ -58,6 +58,10 @@ dbus_internal_symbol_do_not_use_run_tests (const char *test_data_dir) printf ("%s: running string tests\n", "dbus-test"); if (!_dbus_string_test ()) die ("strings"); + + printf ("%s: running address parse tests\n", "dbus-test"); + if (!_dbus_address_test ()) + die ("address parsing"); printf ("%s: running marshalling tests\n", "dbus-test"); if (!_dbus_marshal_test ()) @@ -66,11 +70,11 @@ dbus_internal_symbol_do_not_use_run_tests (const char *test_data_dir) printf ("%s: running message tests\n", "dbus-test"); if (!_dbus_message_test (test_data_dir)) die ("messages"); - + printf ("%s: running memory pool tests\n", "dbus-test"); if (!_dbus_mem_pool_test ()) die ("memory pools"); - + printf ("%s: running linked list tests\n", "dbus-test"); if (!_dbus_list_test ()) die ("lists"); diff --git a/dbus/dbus-test.h b/dbus/dbus-test.h index ebc17bf..963c51d 100644 --- a/dbus/dbus-test.h +++ b/dbus/dbus-test.h @@ -31,6 +31,7 @@ dbus_bool_t _dbus_list_test (void); dbus_bool_t _dbus_marshal_test (void); dbus_bool_t _dbus_mem_pool_test (void); dbus_bool_t _dbus_string_test (void); +dbus_bool_t _dbus_address_test (void); dbus_bool_t _dbus_message_test (const char *test_data_dir); void dbus_internal_symbol_do_not_use_run_tests (const char *test_data_dir); diff --git a/dbus/dbus-transport-debug.c b/dbus/dbus-transport-debug.c index 7a2250a..f829fc2 100644 --- a/dbus/dbus-transport-debug.c +++ b/dbus/dbus-transport-debug.c @@ -41,18 +41,28 @@ * @{ */ +/** + * Default timeout interval when reading or writing. + */ #define DEFAULT_INTERVAL 10 +/** + * Opaque object representing a debug transport. + * + */ typedef struct DBusTransportDebug DBusTransportDebug; +/** + * Implementation details of DBusTransportDebug. All members are private. + */ struct DBusTransportDebug { DBusTransport base; /**< Parent instance */ - DBusTimeout *write_timeout; - DBusTimeout *read_timeout; + DBusTimeout *write_timeout; /**< Timeout for reading. */ + DBusTimeout *read_timeout; /**< Timeout for writing. */ - DBusTransport *other_end; + DBusTransport *other_end; /**< The transport that this transport is connected to. */ }; static void @@ -142,7 +152,7 @@ do_writing (DBusTransport *transport) _dbus_connection_queue_received_message (((DBusTransportDebug *)transport)->other_end->connection, copy); - + dbus_message_unref (copy); } check_read_timeout (((DBusTransportDebug *)transport)->other_end); @@ -240,6 +250,13 @@ static DBusTransportVTable debug_vtable = { debug_live_messages_changed }; +/** + * Creates a new debug server transport. + * + * @param client the client transport that the server transport + * should use. + * @returns a new debug transport + */ DBusTransport* _dbus_transport_debug_server_new (DBusTransport *client) { @@ -267,6 +284,14 @@ _dbus_transport_debug_server_new (DBusTransport *client) return (DBusTransport *)debug_transport; } +/** + * Creates a new debug client transport. + * + * @param server_name name of the server transport that + * the client should try to connect to. + * @param result address where a result code can be returned. + * @returns a new transport, or #NULL on failure. + */ DBusTransport* _dbus_transport_debug_client_new (const char *server_name, DBusResultCode *result) diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c index d1f3170..8c92398 100644 --- a/dbus/dbus-transport.c +++ b/dbus/dbus-transport.c @@ -26,6 +26,7 @@ #include "dbus-connection-internal.h" #include "dbus-watch.h" #include "dbus-auth.h" +#include "dbus-address.h" #ifdef DBUS_BUILD_TESTS #include "dbus-transport-debug.h" #endif @@ -194,22 +195,51 @@ _dbus_transport_open (const char *address, DBusResultCode *result) { DBusTransport *transport; + DBusAddressEntry **entries; + int len, i; - /* FIXME parse the address - whatever format - * we decide addresses are in - and find the - * appropriate transport. - */ + if (!dbus_parse_address (address, &entries, &len, result)) + return NULL; -#if 1 - /* Pretend it's just a unix domain socket name for now */ - transport = _dbus_transport_new_for_domain_socket (address, - FALSE, - result); -#else - transport = _dbus_transport_debug_client_new (address, - result); -#endif + transport = NULL; + + for (i = 0; i < len; i++) + { + const char *method = dbus_address_entry_get_method (entries[i]); + + if (strcmp (method, "unix") == 0) + { + const char *path = dbus_address_entry_get_value (entries[i], "path"); + + if (path == NULL) + goto bad_address; + + transport = _dbus_transport_new_for_domain_socket (path, FALSE, result); + } + else if (strcmp (method, "debug") == 0) + { + const char *name = dbus_address_entry_get_value (entries[i], "name"); + + if (name == NULL) + goto bad_address; + + transport = _dbus_transport_debug_client_new (name, result); + } + else + goto bad_address; + + if (transport) + break; + } + + dbus_address_entries_free (entries); return transport; + + bad_address: + dbus_address_entries_free (entries); + dbus_set_result (result, DBUS_RESULT_BAD_ADDRESS); + + return NULL; } /** -- 2.7.4