Commit 5640f7a5 authored by John Palmieri's avatar John Palmieri

* 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
parent d3440ebe
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
......
......@@ -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:
......@@ -798,6 +801,19 @@ start_busconfig_child (BusConfigParser *parser,
return FALSE;
}
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)
......@@ -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;
......
......@@ -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 -->
......
......@@ -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
......
......@@ -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. */
......
......@@ -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 */
......@@ -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;
......
......@@ -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">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment