diff options
| author | Anders Carlsson <andersca@codefactory.se> | 2003-01-30 20:49:11 +0000 | 
|---|---|---|
| committer | Anders Carlsson <andersca@codefactory.se> | 2003-01-30 20:49:11 +0000 | 
| commit | 5ebb5748c2a7587c734eeed9c66f2a1fc0635d09 (patch) | |
| tree | afd7ab44b132db9424f4ce464f4029751521ebab | |
| parent | 7ba714ad7fe8256edfaad7d9a0f09aeb9611ca44 (diff) | |
2003-01-30  Anders Carlsson  <andersca@codefactory.se>
	* 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.
| -rw-r--r-- | ChangeLog | 38 | ||||
| -rw-r--r-- | dbus/Makefile.am | 2 | ||||
| -rw-r--r-- | dbus/dbus-address.c | 415 | ||||
| -rw-r--r-- | dbus/dbus-address.h | 48 | ||||
| -rw-r--r-- | dbus/dbus-connection.c | 18 | ||||
| -rw-r--r-- | dbus/dbus-message.c | 10 | ||||
| -rw-r--r-- | dbus/dbus-server-debug.c | 27 | ||||
| -rw-r--r-- | dbus/dbus-server.c | 64 | ||||
| -rw-r--r-- | dbus/dbus-string.c | 78 | ||||
| -rw-r--r-- | dbus/dbus-string.h | 5 | ||||
| -rw-r--r-- | dbus/dbus-test.c | 8 | ||||
| -rw-r--r-- | dbus/dbus-test.h | 1 | ||||
| -rw-r--r-- | dbus/dbus-transport-debug.c | 33 | ||||
| -rw-r--r-- | dbus/dbus-transport.c | 56 | 
14 files changed, 778 insertions, 25 deletions
@@ -1,3 +1,41 @@ +2003-01-30  Anders Carlsson  <andersca@codefactory.se> + +	* 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  <hp@pobox.com>  	* dbus/dbus-message.c: use message->byte_order instead of  diff --git a/dbus/Makefile.am b/dbus/Makefile.am index b97ed6b9..98090a62 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 00000000..5b65f2fd --- /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 <config.h> +#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 00000000..294eb2bc --- /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 <dbus/dbus.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef DBUS_ADDRESS_H +#define DBUS_ADDRESS_H + +#include <dbus/dbus-types.h> +#include <dbus/dbus-errors.h> + +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 4054f45f..3bc8d2da 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 85b49cbe..1c9c7ea2 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 b9305b75..57d68066 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 1407c477..51774318 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 f453dcb6..05d14ba1 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 e71f7fee..641eaf5e 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 337ef10b..f52504a2 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 ebc17bff..963c51d1 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 7a2250a2..f829fc29 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 d1f31702..8c923982 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;  }  /**  | 
