diff options
| -rw-r--r-- | ChangeLog | 30 | ||||
| -rw-r--r-- | bus/config-parser.c | 120 | ||||
| -rw-r--r-- | bus/session.conf.in | 2 | ||||
| -rw-r--r-- | configure.in | 5 | ||||
| -rw-r--r-- | dbus/dbus-list.h | 3 | ||||
| -rw-r--r-- | dbus/dbus-sysdeps-unix.c | 206 | ||||
| -rw-r--r-- | dbus/dbus-sysdeps.h | 5 | ||||
| -rw-r--r-- | test/data/valid-config-files/many-rules.conf | 1 | 
8 files changed, 368 insertions, 4 deletions
| @@ -1,3 +1,33 @@ +2006-11-01  John (J5) Palmieri  <johnp@redhat.com> + +	* configure.in: expose DBUS_DATADIR +	 +	* bus/config-parser.c: add the standard_session_servicedirs element +	to the parser +	(bus_config_parser_content): process the standard_session_servicedirs +	element by getting the standard directories from sysdeps and merging +	them into the service directory list +	(test_default_session_servicedirs): make sure we get what we expect + +	* bus/session.conf.in: replace the servicedir tag with the  +	standard_session_servicedirs tag + +	* dbus/dbus-list.h: remove the typedef of DBusList and place it in +	dbus-sysdeps.h to avoid circular header dependencies + +	* dbus/dbus-sysdeps.h: add the typedef of DBusList + +	* dbus/dbus-sysdeps-unix.c (split_paths_and_append): utility function +	which takes a string of directories delimited by colons, parses them  +	out, appends a suffix and puts them in a list ignoring empty elements +	(_dbus_get_standard_session_servicedirs): returns the standard  +	directories for a session bus to look for service activation files +	on Unix which includes the XDG_DATA_HOME, XDG_DATA_DIRS and  +	DBUS_DATADIR directories + +	* test/data/valid-config-files/many-rules.conf: add the  +	standard_session_servicedirs tag to the valid config file tests +  2006-10-30  Havoc Pennington  <hp@redhat.com>  	* tools/dbus-launch.1, doc/TODO: capture intent to change the diff --git a/bus/config-parser.c b/bus/config-parser.c index b126eb0c..70bc441d 100644 --- a/bus/config-parser.c +++ b/bus/config-parser.c @@ -47,7 +47,8 @@ typedef enum    ELEMENT_INCLUDEDIR,    ELEMENT_TYPE,    ELEMENT_SELINUX, -  ELEMENT_ASSOCIATE +  ELEMENT_ASSOCIATE, +  ELEMENT_STANDARD_SESSION_SERVICEDIRS  } ElementType;  typedef enum @@ -161,6 +162,8 @@ element_type_to_name (ElementType type)        return "fork";      case ELEMENT_PIDFILE:        return "pidfile"; +    case ELEMENT_STANDARD_SESSION_SERVICEDIRS: +      return "standard_session_servicedirs";      case ELEMENT_SERVICEDIR:        return "servicedir";      case ELEMENT_INCLUDEDIR: @@ -800,6 +803,19 @@ start_busconfig_child (BusConfigParser   *parser,        return TRUE;      } +  else if (strcmp (element_name, "standard_session_servicedirs") == 0) +    { +      if (!check_no_attributes (parser, "standard_session_servicedirs", attribute_names, attribute_values, error)) +        return FALSE; + +      if (push_element (parser, ELEMENT_STANDARD_SESSION_SERVICEDIRS) == NULL) +        { +          BUS_SET_OOM (error); +          return FALSE; +        } + +      return TRUE; +    }    else if (strcmp (element_name, "servicedir") == 0)      {        if (!check_no_attributes (parser, "servicedir", attribute_names, attribute_values, error)) @@ -1927,6 +1943,7 @@ bus_config_parser_end_element (BusConfigParser   *parser,      case ELEMENT_FORK:      case ELEMENT_SELINUX:      case ELEMENT_ASSOCIATE: +    case ELEMENT_STANDARD_SESSION_SERVICEDIRS:        break;      } @@ -2335,6 +2352,19 @@ bus_config_parser_content (BusConfigParser   *parser,            }        }        break; +    case ELEMENT_STANDARD_SESSION_SERVICEDIRS: +      { +        DBusList *link; +        DBusList *dirs; +        dirs = NULL; + +        if (!_dbus_get_standard_session_servicedirs (&dirs)) +          goto nomem; + +        while ((link = _dbus_list_pop_first_link (&dirs))) +          service_dirs_append_link_unique_or_free (&parser->service_dirs, link); +      } +      break;      case ELEMENT_SERVICEDIR:        { @@ -3032,6 +3062,91 @@ process_test_equiv_subdir (const DBusString *test_base_dir,    return retval;  } + +static const char *test_service_dir_matches[] =  +        { +         "/testusr/testlocal/testshare/dbus-1/services", +         "/testusr/testshare/dbus-1/services", +         DBUS_DATADIR"/dbus-1/services", +         "/testhome/foo/.testlocal/testshare/dbus-1/services",          +         NULL +        }; + +static dbus_bool_t +test_default_session_servicedirs (void) +{ +  DBusList *dirs; +  DBusList *link; +  int i; + +  dirs = NULL; + +  printf ("Testing retriving the default session service directories\n"); +  if (!_dbus_get_standard_session_servicedirs (&dirs)) +    _dbus_assert_not_reached ("couldn't get stardard dirs"); + +  /* make sure our defaults end with share/dbus-1/service */ +  while ((link = _dbus_list_pop_first_link (&dirs))) +    { +      DBusString path; +       +      printf ("    default service dir: %s\n", (char *)link->data); +      _dbus_string_init_const (&path, (char *)link->data); +      if (!_dbus_string_ends_with_c_str (&path, "share/dbus-1/services")) +        { +          printf ("error with default session service directories\n"); +          return FALSE; +        } +  +      dbus_free (link->data); +      _dbus_list_free_link (link); +    } + +  if (!_dbus_setenv ("XDG_DATA_HOME", "/testhome/foo/.testlocal/testshare")) +    _dbus_assert_not_reached ("couldn't setenv XDG_DATA_HOME"); + +  if (!_dbus_setenv ("XDG_DATA_DIRS", ":/testusr/testlocal/testshare: :/testusr/testshare:")) +    _dbus_assert_not_reached ("couldn't setenv XDG_DATA_DIRS"); + +  if (!_dbus_get_standard_session_servicedirs (&dirs)) +    _dbus_assert_not_reached ("couldn't get stardard dirs"); + +  /* make sure we read and parse the env variable correctly */ +  i = 0; +  while ((link = _dbus_list_pop_first_link (&dirs))) +    { +      printf ("    test service dir: %s\n", (char *)link->data); +      if (test_service_dir_matches[i] == NULL) +        { +          printf ("more directories parsed than in match set\n"); +          return FALSE; +        } +  +      if (strcmp (test_service_dir_matches[i],  +                  (char *)link->data) != 0) +        { +          printf ("%s directory does not match %s in the match set\n",  +                  (char *)link->data, +                  test_service_dir_matches[i]); +          return FALSE; +        } + +      ++i; + +      dbus_free (link->data); +      _dbus_list_free_link (link); +    } +   +  if (test_service_dir_matches[i] != NULL) +    { +      printf ("extra data %s in the match set was not matched\n", +              test_service_dir_matches[i]); + +      return FALSE; +    } +     +  return TRUE; +}  dbus_bool_t  bus_config_parser_test (const DBusString *test_data_dir) @@ -3043,6 +3158,9 @@ bus_config_parser_test (const DBusString *test_data_dir)        return TRUE;      } +  if (!test_default_session_servicedirs()) +    return FALSE; +    if (!process_test_valid_subdir (test_data_dir, "valid-config-files", VALID))      return FALSE; diff --git a/bus/session.conf.in b/bus/session.conf.in index ac93b429..344efc54 100644 --- a/bus/session.conf.in +++ b/bus/session.conf.in @@ -10,7 +10,7 @@    <listen>unix:tmpdir=@DBUS_SESSION_SOCKET_DIR@</listen> -  <servicedir>@EXPANDED_DATADIR@/dbus-1/services</servicedir> +  <standard_session_servicedirs />    <policy context="default">      <!-- Allow everything to be sent --> diff --git a/configure.in b/configure.in index 2d5c713d..b4759b47 100644 --- a/configure.in +++ b/configure.in @@ -1118,6 +1118,11 @@ fi  AC_SUBST(DBUS_USER)  AC_DEFINE_UNQUOTED(DBUS_USER,"$DBUS_USER", [User for running the system BUS daemon]) +#### Direcotry to install data files into +DBUS_DATADIR=$EXPANDED_DATADIR +AC_SUBST(DBUS_DATADIR) +AC_DEFINE_UNQUOTED(DBUS_DATADIR,"$DBUS_DATADIR", [Directory for installing DBUS data files]) +  #### Directory to install dbus-daemon  if test -z "$with_dbus_daemondir" ; then      DBUS_DAEMONDIR=$EXPANDED_BINDIR diff --git a/dbus/dbus-list.h b/dbus/dbus-list.h index 77e878ce..61160496 100644 --- a/dbus/dbus-list.h +++ b/dbus/dbus-list.h @@ -27,11 +27,10 @@  #include <dbus/dbus-internals.h>  #include <dbus/dbus-memory.h>  #include <dbus/dbus-types.h> +#include <dbus/dbus-sysdeps.h>  DBUS_BEGIN_DECLS -typedef struct DBusList DBusList; -  struct DBusList  {    DBusList *prev; /**< Previous list node. */ diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index 75848b71..f4afad89 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -29,6 +29,8 @@  #include "dbus-protocol.h"  #include "dbus-transport.h"  #include "dbus-string.h" +#include "dbus-userdb.h" +#include "dbus-list.h"  #include <sys/types.h>  #include <stdlib.h>  #include <string.h> @@ -2528,4 +2530,208 @@ _dbus_read_local_machine_uuid (DBusGUID   *machine_id,    return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);  } +#define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services" + +static dbus_bool_t +split_paths_and_append (DBusString *dirs,  +                        const char *suffix,  +                        DBusList **dir_list) +{ +  /* split on colon (:) */ +   int start; +   int i; +   int len; +   char *cpath; +   const DBusString file_suffix; + +   start = 0; +   i = 0; + +   _dbus_string_init_const (&file_suffix, suffix); + +   len = _dbus_string_get_length (dirs); + +   while (_dbus_string_find (dirs, start, ":", &i)) +     { +       DBusString path; + +       if (!_dbus_string_init (&path)) +          goto oom; + +       if (!_dbus_string_copy_len (dirs, +                                   start, +                                   i - start, +                                   &path, +                                   0)) +          { +            _dbus_string_free (&path); +            goto oom; +          } + +        _dbus_string_chop_white (&path); + +        /* check for an empty path */ +        if (_dbus_string_get_length (&path) == 0) +          goto next; + +        if (!_dbus_concat_dir_and_file (&path, +                                        &file_suffix)) +          { +            _dbus_string_free (&path); +            goto oom; +          } + +        if (!_dbus_string_copy_data(&path, &cpath)) +          { +            _dbus_string_free (&path); +            goto oom; +          } + +        if (!_dbus_list_append (dir_list, cpath)) +          { +            _dbus_string_free (&path);               +            dbus_free (cpath); +            goto oom; +          } + +       next: +        _dbus_string_free (&path); +        start = i + 1; +    }  +       +  if (start != len) +    {  +      DBusString path; + +      if (!_dbus_string_init (&path)) +        goto oom; + +      if (!_dbus_string_copy_len (dirs, +                                  start, +                                  len - start, +                                  &path, +                                  0)) +        { +          _dbus_string_free (&path); +          goto oom; +        } + +      if (!_dbus_concat_dir_and_file (&path, +                                      &file_suffix)) +        { +          _dbus_string_free (&path); +          goto oom; +        } + +      if (!_dbus_string_copy_data(&path, &cpath)) +        { +          _dbus_string_free (&path); +          goto oom; +        } + +      if (!_dbus_list_append (dir_list, cpath)) +        { +          _dbus_string_free (&path);               +          dbus_free (cpath); +          goto oom; +        } + +      _dbus_string_free (&path);  +    } + +  return TRUE; + + oom: +  _dbus_list_foreach (dir_list, (DBusForeachFunction)dbus_free, NULL);  +  _dbus_list_clear (dir_list); +  return FALSE; +} + +/** + * Returns the standard directories for a session bus to look for service  + * activation files  + * + * On UNIX this should be the standard xdg freedesktop.org data directories: + * + * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share} + * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share} + * + * and + * + * DBUS_DATADIR + * + * @param dirs the directory list we are returning + * @returns #FALSE on OOM  + */ + +dbus_bool_t  +_dbus_get_standard_session_servicedirs (DBusList **dirs) +{ +  const char *xdg_data_home; +  const char *xdg_data_dirs; +  DBusString servicedir_path; + +  if (!_dbus_string_init (&servicedir_path)) +    return FALSE; + +  xdg_data_home = _dbus_getenv ("XDG_DATA_HOME"); +  xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS"); + +  if (xdg_data_dirs != NULL) +    { +      if (!_dbus_string_append (&servicedir_path, xdg_data_dirs)) +        goto oom; + +      if (!_dbus_string_append (&servicedir_path, ":")) +        goto oom; +    } +  else +    { +      if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:")) +        goto oom; +    } + +  /*  +   * add configured datadir to defaults +   * this may be the same as an xdg dir +   * however the config parser should take  +   * care of duplicates  +   */ +  if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":")) +        goto oom; + +  if (xdg_data_home != NULL) +    { +      if (!_dbus_string_append (&servicedir_path, xdg_data_home)) +        goto oom; +    } +  else +    { +      const DBusString *homedir; +      const DBusString local_share; + +      if (!_dbus_homedir_from_current_process (&homedir)) +        goto oom; +        +      if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir))) +        goto oom; + +      _dbus_string_init_const (&local_share, "/.local/share"); +      if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share)) +        goto oom; +    } + +  if (!split_paths_and_append (&servicedir_path,  +                               DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,  +                               dirs)) +    goto oom; + +  _dbus_string_free (&servicedir_path);   +  return TRUE; + + oom: +  _dbus_string_free (&servicedir_path); +  return FALSE; +} +  /* tests in dbus-sysdeps-util.c */ diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index eb395e05..e7b3eac0 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -59,6 +59,9 @@ DBUS_BEGIN_DECLS  /** An opaque string type */  typedef struct DBusString DBusString; +/** avoid circular includes with DBusList */ +typedef struct DBusList DBusList;  +  #if     __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)  #define _DBUS_GNUC_PRINTF( format_idx, arg_idx )    \    __attribute__((__format__ (__printf__, format_idx, arg_idx))) @@ -291,6 +294,8 @@ dbus_bool_t _dbus_string_get_dirname  (const DBusString *filename,                                         DBusString       *dirname);  dbus_bool_t _dbus_path_is_absolute    (const DBusString *filename); +dbus_bool_t _dbus_get_standard_session_servicedirs (DBusList **dirs); +  /** Opaque type for reading a directory listing */  typedef struct DBusDirIter DBusDirIter; diff --git a/test/data/valid-config-files/many-rules.conf b/test/data/valid-config-files/many-rules.conf index ab05909f..0a15e83c 100644 --- a/test/data/valid-config-files/many-rules.conf +++ b/test/data/valid-config-files/many-rules.conf @@ -5,6 +5,7 @@    <listen>unix:path=/foo/bar</listen>    <listen>tcp:port=1234</listen>    <includedir>basic.d</includedir> +  <standard_session_servicedirs />    <servicedir>/usr/share/foo</servicedir>    <include ignore_missing="yes">nonexistent.conf</include>    <policy context="default"> | 
