X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=bus%2Fsignals.c;h=dab7154a64d0103d42e8f48c5037ea2840995582;hb=04c58b9e5fbdf3acc7565f989e5fcd11f0c23c57;hp=62881b57d7b953bb054a3180c36de39925388d17;hpb=636a9a29f89326ca07d5bdbd41d874fa13910c17;p=platform%2Fupstream%2Fdbus.git diff --git a/bus/signals.c b/bus/signals.c index 62881b5..dab7154 100644 --- a/bus/signals.c +++ b/bus/signals.c @@ -64,7 +64,7 @@ bus_match_rule_new (DBusConnection *matches_go_to) rule->refcount = 1; rule->matches_go_to = matches_go_to; -#ifndef DBUS_BUILD_TESTS +#ifndef DBUS_ENABLE_EMBEDDED_TESTS _dbus_assert (rule->matches_go_to != NULL); #endif @@ -215,6 +215,20 @@ match_rule_to_string (BusMatchRule *rule) goto nomem; } + if (rule->flags & BUS_MATCH_CLIENT_IS_EAVESDROPPING) + { + if (_dbus_string_get_length (&str) > 0) + { + if (!_dbus_string_append (&str, ",")) + goto nomem; + } + + if (!_dbus_string_append_printf (&str, "eavesdrop='%s'", + (rule->flags & BUS_MATCH_CLIENT_IS_EAVESDROPPING) ? + "true" : "false")) + goto nomem; + } + if (rule->flags & BUS_MATCH_ARGS) { int i; @@ -354,6 +368,16 @@ bus_match_rule_set_destination (BusMatchRule *rule, return TRUE; } +void +bus_match_rule_set_client_is_eavesdropping (BusMatchRule *rule, + dbus_bool_t is_eavesdropping) +{ + if (is_eavesdropping) + rule->flags |= BUS_MATCH_CLIENT_IS_EAVESDROPPING; + else + rule->flags &= ~(BUS_MATCH_CLIENT_IS_EAVESDROPPING); +} + dbus_bool_t bus_match_rule_set_path (BusMatchRule *rule, const char *path, @@ -1030,6 +1054,31 @@ bus_match_rule_parse (DBusConnection *matches_go_to, goto failed; } } + else if (strcmp (key, "eavesdrop") == 0) + { + /* do not detect "eavesdrop" being used more than once in rule: + * 1) it's not possible, it's only in the flags + * 2) it might be used twice to disable eavesdropping when it's + * automatically added (eg dbus-monitor/bustle) */ + + /* we accept only "true|false" as possible values */ + if ((strcmp (value, "true") == 0)) + { + bus_match_rule_set_client_is_eavesdropping (rule, TRUE); + } + else if (strcmp (value, "false") == 0) + { + bus_match_rule_set_client_is_eavesdropping (rule, FALSE); + } + else + { + dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, + "eavesdrop='%s' is invalid, " + "it should be 'true' or 'false'\n", + value); + goto failed; + } + } else if (strncmp (key, "arg", 3) == 0) { if (!bus_match_rule_parse_arg_match (rule, key, &tmp_str, error)) @@ -1352,6 +1401,9 @@ match_rule_equal (BusMatchRule *a, strcmp (a->destination, b->destination) != 0) return FALSE; + /* we already compared the value of flags, and + * BUS_MATCH_CLIENT_IS_EAVESDROPPING does not have another struct member */ + if (a->flags & BUS_MATCH_ARGS) { int i; @@ -1619,6 +1671,7 @@ match_rule_matches (BusMatchRule *rule, DBusMessage *message, BusMatchFlags already_matched) { + dbus_bool_t wants_to_eavesdrop = FALSE; int flags; /* All features of the match rule are AND'd together, @@ -1633,6 +1686,9 @@ match_rule_matches (BusMatchRule *rule, /* Don't bother re-matching features we've already checked implicitly. */ flags = rule->flags & (~already_matched); + if (flags & BUS_MATCH_CLIENT_IS_EAVESDROPPING) + wants_to_eavesdrop = TRUE; + if (flags & BUS_MATCH_MESSAGE_TYPE) { _dbus_assert (rule->message_type != DBUS_MESSAGE_TYPE_INVALID); @@ -1686,6 +1742,24 @@ match_rule_matches (BusMatchRule *rule, } } + /* Note: this part is relevant for eavesdropper rules: + * Two cases: + * 1) rule has a destination to be matched + * (flag BUS_MATCH_DESTINATION present). Rule will match if: + * - rule->destination matches the addressed_recipient + * AND + * - wants_to_eavesdrop=TRUE + * + * Note: (the case in which addressed_recipient is the actual rule owner + * is handled elsewere in dispatch.c:bus_dispatch_matches(). + * + * 2) rule has no destination. Rule will match if: + * - message has no specified destination (ie broadcasts) + * (Note: this will rule out unicast method calls and unicast signals, + * fixing FDO#269748) + * OR + * - wants_to_eavesdrop=TRUE (destination-catch-all situation) + */ if (flags & BUS_MATCH_DESTINATION) { const char *destination; @@ -1694,6 +1768,12 @@ match_rule_matches (BusMatchRule *rule, destination = dbus_message_get_destination (message); if (destination == NULL) + /* broadcast, but this rule specified a destination: no match */ + return FALSE; + + /* rule owner does not intend to eavesdrop: we'll deliver only msgs + * directed to it, NOT MATCHING */ + if (!wants_to_eavesdrop) return FALSE; if (addressed_recipient == NULL) @@ -1707,6 +1787,19 @@ match_rule_matches (BusMatchRule *rule, if (!connection_is_primary_owner (addressed_recipient, rule->destination)) return FALSE; } + } else { /* no destination in rule */ + dbus_bool_t msg_is_broadcast; + + _dbus_assert (rule->destination == NULL); + + msg_is_broadcast = (dbus_message_get_destination (message) == NULL); + + if (!wants_to_eavesdrop && !msg_is_broadcast) + return FALSE; + + /* if we are here rule owner intends to eavesdrop + * OR + * message is being broadcasted */ } if (flags & BUS_MATCH_PATH) @@ -1887,12 +1980,10 @@ get_recipients_from_list (DBusList **rules, if (!_dbus_list_append (recipients_p, rule->matches_go_to)) return FALSE; } -#ifdef DBUS_ENABLE_VERBOSE_MODE else { _dbus_verbose ("Connection already receiving this message, so not adding again\n"); } -#endif /* DBUS_ENABLE_VERBOSE_MODE */ } link = _dbus_list_get_next_link (rules, link); @@ -1963,7 +2054,7 @@ bus_matchmaker_get_recipients (BusMatchmaker *matchmaker, return TRUE; } -#ifdef DBUS_BUILD_TESTS +#ifdef DBUS_ENABLE_EMBEDDED_TESTS #include "test.h" #include @@ -2718,5 +2809,5 @@ bus_signals_test (const DBusString *test_data_dir) return TRUE; } -#endif /* DBUS_BUILD_TESTS */ +#endif /* DBUS_ENABLE_EMBEDDED_TESTS */