dbus_bool_t need_bloom = FALSE;
const char *rule_sender;
+ const char *rule_arg0 = NULL;
int ret;
rule_cookie = match_rule_get_cookie (rule);
rule_sender = _match_rule_get_sender (rule);
+ if (_match_rule_get_args_len(rule) == 1)
+ rule_arg0 = _match_rule_get_args(rule, 0);
+
/*
* First check if it is org.freedesktop.DBus's NameOwnerChanged or any
* org.freedesktop.DBus combination that includes this,
int message_type = _match_rule_get_message_type (rule);
if ((DBUS_MESSAGE_TYPE_INVALID == message_type || DBUS_MESSAGE_TYPE_SIGNAL == message_type)
- && !strcmp_existing (_match_rule_get_member (rule), "NameOwnerChanged")
&& !strcmp_existing (_match_rule_get_interface (rule), DBUS_INTERFACE_DBUS)
&& !strcmp_existing (_match_rule_get_path (rule), DBUS_PATH_DBUS))
{
- ret = _kdbus_add_match_name_change (transport->kdbus,
- 0,
- rule_cookie,
- KDBUS_MATCH_ID_ANY,
- 0,
- KDBUS_MATCH_ID_ANY,
- 0);
- if (0 != ret)
+ if (!strcmp_existing (_match_rule_get_member (rule), "NameOwnerChanged"))
{
- _dbus_verbose ("Failed adding match rule for name removal for daemon, error: %d, %s\n",
- ret, _dbus_strerror (ret));
- return FALSE;
- }
+ ret = _kdbus_add_match_name_change (transport->kdbus,
+ 0,
+ rule_cookie,
+ KDBUS_MATCH_ID_ANY,
+ 0,
+ KDBUS_MATCH_ID_ANY,
+ 0,
+ rule_arg0);
+ if (0 != ret)
+ {
+ _dbus_verbose ("Failed adding match rule for name removal for daemon, error: %d, %s\n",
+ ret, _dbus_strerror (ret));
+ return FALSE;
+ }
+
+ _dbus_verbose ("Added match rule for kernel correctly.\n");
- ret = _kdbus_add_match_id_change (transport->kdbus,
- 0,
- rule_cookie,
- KDBUS_MATCH_ID_ANY,
- 0);
- if (0 != ret)
+ ret = _kdbus_add_match_id_change (transport->kdbus,
+ 0,
+ rule_cookie,
+ KDBUS_MATCH_ID_ANY,
+ 0,
+ rule_arg0);
+ if (0 != ret)
+ {
+ _dbus_verbose ("Failed adding match rule for adding id for daemon, error: %d, %s\n",
+ ret, _dbus_strerror (ret));
+ return FALSE;
+ }
+ }
+ else if (strcmp (_match_rule_get_member (rule), "NameAcquired") == 0)
{
- _dbus_verbose ("Failed adding match rule for adding id for daemon, error: %d, %s\n",
- ret, _dbus_strerror (ret));
- return FALSE;
+ ret = _kdbus_add_match_name_acquired (transport->kdbus,
+ 0,
+ rule_cookie,
+ KDBUS_MATCH_ID_ANY,
+ 0,
+ _kdbus_get_id (transport->kdbus),
+ 0,
+ rule_arg0);
+ if (0 != ret)
+ {
+ _dbus_verbose ("Failed adding match rule for name removal for daemon, error: %d, %s\n",
+ ret, _dbus_strerror (ret));
+ return FALSE;
+ }
+ }
+ else if (strcmp (_match_rule_get_member (rule), "NameLost") == 0)
+ {
+ ret = _kdbus_add_match_name_lost (transport->kdbus,
+ 0,
+ rule_cookie,
+ _kdbus_get_id (transport->kdbus),
+ 0,
+ KDBUS_MATCH_ID_ANY,
+ 0,
+ rule_arg0);
+ if (0 != ret)
+ {
+ _dbus_verbose ("Failed adding match rule for name removal for daemon, error: %d, %s\n",
+ ret, _dbus_strerror (ret));
+ return FALSE;
+ }
}
-
- _dbus_verbose ("Added match rule for kernel correctly.\n");
}
-
/* Sender=DBUS_SERVICE_DBUS matches (as opposed to wildcard sender) need no standard rule. */
if (rule_sender)
return TRUE;
}
int
-_kdbus_add_match_name_change (kdbus_t *kdbus,
- __u64 flags,
- __u64 cookie,
- __u64 old_id,
- __u64 old_id_flags,
- __u64 new_id,
- __u64 new_id_flags)
+_kdbus_add_match_name_acquired (kdbus_t *kdbus,
+ __u64 flags,
+ __u64 cookie,
+ __u64 old_id,
+ __u64 old_id_flags,
+ __u64 new_id,
+ __u64 new_id_flags,
+ const char *name)
{
struct kdbus_cmd_match *cmd;
struct kdbus_item *item;
int ret;
+ unsigned int len = 0;
+ if (name)
+ len = strlen(name) + 1;
cmd = _kdbus_new_cmd_match (kdbus,
- KDBUS_ITEM_SIZE (sizeof (struct kdbus_notify_name_change)),
+ KDBUS_ITEM_SIZE (sizeof (struct kdbus_notify_name_change) + len),
flags,
cookie);
if (NULL == cmd)
_kdbus_item_add_name_change (item,
old_id, old_id_flags,
new_id, new_id_flags);
+ item->size += len;
+ if (name)
+ memcpy(item->name_change.name, name, len);
ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
- if (0 == ret)
- {
- item->type = KDBUS_ITEM_NAME_ADD;
- ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
- if (0 == ret)
- {
- item->type = KDBUS_ITEM_NAME_REMOVE;
- ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
- }
- }
+ if (ret != 0)
+ goto err_name_acquired;
+ item->type = KDBUS_ITEM_NAME_ADD;
+ ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
+ if (ret != 0)
+ goto err_name_acquired;
+
+err_name_acquired:
if (0 != ret)
ret = errno;
-
_kdbus_free_cmd_match (cmd);
return ret;
}
int
-_kdbus_add_match_id_change (kdbus_t *kdbus,
+_kdbus_add_match_name_lost (kdbus_t *kdbus,
__u64 flags,
__u64 cookie,
- __u64 id,
- __u64 id_flags)
+ __u64 old_id,
+ __u64 old_id_flags,
+ __u64 new_id,
+ __u64 new_id_flags,
+ const char *name)
{
struct kdbus_cmd_match *cmd;
struct kdbus_item *item;
int ret;
+ unsigned int len = 0;
+
+ if (name)
+ len = strlen(name) + 1;
cmd = _kdbus_new_cmd_match (kdbus,
- KDBUS_ITEM_SIZE (sizeof (struct kdbus_notify_id_change)),
+ KDBUS_ITEM_SIZE (sizeof (struct kdbus_notify_name_change) + len),
flags,
cookie);
if (NULL == cmd)
return ENOMEM;
item = cmd->items;
- _kdbus_item_add_id_add (item, id, id_flags);
+ _kdbus_item_add_name_change (item,
+ old_id, old_id_flags,
+ new_id, new_id_flags);
+
+ item->size += len;
+ if (name)
+ memcpy(item->name_change.name, name, len);
ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
- if (0 == ret)
- {
- item->type = KDBUS_ITEM_ID_REMOVE;
- ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
- }
+ if (ret != 0)
+ goto err_name_remove;
+
+ item->type = KDBUS_ITEM_NAME_REMOVE;
+ ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
+ if (ret != 0)
+ goto err_name_remove;
+err_name_remove:
if (0 != ret)
ret = errno;
-
_kdbus_free_cmd_match (cmd);
return ret;
}
+int
+_kdbus_add_match_name_change (kdbus_t *kdbus,
+ __u64 flags,
+ __u64 cookie,
+ __u64 old_id,
+ __u64 old_id_flags,
+ __u64 new_id,
+ __u64 new_id_flags,
+ const char *name)
+{
+ struct kdbus_cmd_match *cmd;
+ struct kdbus_item *item;
+ int ret;
+ unsigned int len = 0;
+
+ if (name)
+ len = strlen(name) + 1;
+
+ /* name = NULL or Well-known Name */
+ if (name == NULL || (name[0] != ':' && _dbus_validate_bus_name (&name, 0, _dbus_string_get_length (&name)))) {
+ cmd = _kdbus_new_cmd_match (kdbus,
+ KDBUS_ITEM_SIZE (sizeof (struct kdbus_notify_name_change) + len),
+ flags,
+ cookie);
+ if (NULL == cmd)
+ return ENOMEM;
+
+ item = cmd->items;
+ _kdbus_item_add_name_change (item,
+ old_id, old_id_flags,
+ new_id, new_id_flags);
+
+ item->size += len;
+ if (name)
+ memcpy(item->name_change.name, name, len);
+
+ ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
+ if (0 == ret)
+ {
+ item->type = KDBUS_ITEM_NAME_ADD;
+ ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
+ if (0 == ret)
+ {
+ item->type = KDBUS_ITEM_NAME_REMOVE;
+ ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
+ }
+ }
+
+ if (0 != ret)
+ ret = errno;
+
+ _kdbus_free_cmd_match (cmd);
+ return ret;
+ }
+
+ return FALSE;
+}
+
+int
+_kdbus_add_match_id_change (kdbus_t *kdbus,
+ __u64 flags,
+ __u64 cookie,
+ __u64 id,
+ __u64 id_flags,
+ const char *name)
+{
+ struct kdbus_cmd_match *cmd;
+ struct kdbus_item *item;
+ int ret;
+
+ /* name = NULL or Unique Name */
+ if (name == NULL || (name[0] == ':' && _dbus_validate_bus_name (&name, 0, _dbus_string_get_length (&name)))) {
+ cmd = _kdbus_new_cmd_match (kdbus,
+ KDBUS_ITEM_SIZE (sizeof (struct kdbus_notify_id_change)),
+ flags,
+ cookie);
+ if (NULL == cmd)
+ return ENOMEM;
+
+ item = cmd->items;
+ _kdbus_item_add_id_add (item, id, id_flags);
+
+ if (name)
+ item->id_change.id = strtoull (name + 3, NULL, 10);
+
+ ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
+ if (0 == ret)
+ {
+ item->type = KDBUS_ITEM_ID_REMOVE;
+ ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
+ }
+
+ if (0 != ret)
+ ret = errno;
+
+ _kdbus_free_cmd_match (cmd);
+ return ret;
+ }
+ return FALSE;
+}
+
int _kdbus_add_match (kdbus_t *kdbus,
struct kdbus_cmd_match *cmd)
{